@dwelle/excalidraw 0.4.0-b39f4a9 → 0.4.0-b411b92

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.
@@ -2625,7 +2625,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2625
2625
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2626
2626
 
2627
2627
  "use strict";
2628
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nconst trackEvent = (category, action, label, value) => {\n try {\n // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n if (typeof window === \"undefined\" || ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"FAST_REFRESH\":\"false\",\"REACT_APP_MATOMO_URL\":\"\",\"REACT_APP_CDN_MATOMO_TRACKER_URL\":\"\",\"REACT_APP_MATOMO_SITE_ID\":\"\",\"REACT_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX\":\"\",\"PKG_NAME\":\"@dwelle/excalidraw\",\"PKG_VERSION\":\"0.4.0-b39f4a9\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).JEST_WORKER_ID) {\n return;\n }\n if (({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"FAST_REFRESH\":\"false\",\"REACT_APP_MATOMO_URL\":\"\",\"REACT_APP_CDN_MATOMO_TRACKER_URL\":\"\",\"REACT_APP_MATOMO_SITE_ID\":\"\",\"REACT_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX\":\"\",\"PKG_NAME\":\"@dwelle/excalidraw\",\"PKG_VERSION\":\"0.4.0-b39f4a9\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).REACT_APP_GOOGLE_ANALYTICS_ID && window.gtag) {\n window.gtag(\"event\", action, {\n event_category: category,\n event_label: label,\n value,\n });\n }\n if (window.sa_event) {\n window.sa_event(action, {\n category,\n label,\n value,\n });\n }\n if (window.fathom) {\n window.fathom.trackEvent(action, {\n category,\n label,\n value,\n });\n }\n }\n catch (error) {\n console.error(\"error during analytics\", error);\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vYW5hbHl0aWNzLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFBTyxNQUFNLFVBQVUsR0FBRyxDQUN4QixRQUFnQixFQUNoQixNQUFjLEVBQ2QsS0FBYyxFQUNkLEtBQWMsRUFDZCxFQUFFO0lBQ0YsSUFBSTtRQUNGLDJDQUEyQztRQUMzQyxrRUFBa0U7UUFFbEUsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksbWlDQUFXLENBQUMsY0FBYyxFQUFFO1lBQy9ELE9BQU87U0FDUjtRQUVELElBQUksbWlDQUFXLENBQUMsNkJBQTZCLElBQUksTUFBTSxDQUFDLElBQUksRUFBRTtZQUM1RCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7Z0JBQzNCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ25CLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO2dCQUN0QixRQUFRO2dCQUNSLEtBQUs7Z0JBQ0wsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO1lBQ2pCLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTtnQkFDL0IsUUFBUTtnQkFDUixLQUFLO2dCQUNMLEtBQUs7YUFDTixDQUFDLENBQUM7U0FDSjtLQUNGO0lBQUMsT0FBTyxLQUFLLEVBQUU7UUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQ2hEO0FBQ0gsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL2FuYWx5dGljcy50cz81ZjBjIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCB0cmFja0V2ZW50ID0gKFxuICBjYXRlZ29yeTogc3RyaW5nLFxuICBhY3Rpb246IHN0cmluZyxcbiAgbGFiZWw/OiBzdHJpbmcsXG4gIHZhbHVlPzogbnVtYmVyLFxuKSA9PiB7XG4gIHRyeSB7XG4gICAgLy8gVW5jb21tZW50IHRoZSBuZXh0IGxpbmUgdG8gdHJhY2sgbG9jYWxseVxuICAgIC8vIGNvbnNvbGUubG9nKFwiVHJhY2sgRXZlbnRcIiwgeyBjYXRlZ29yeSwgYWN0aW9uLCBsYWJlbCwgdmFsdWUgfSk7XG5cbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIiB8fCBwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5SRUFDVF9BUFBfR09PR0xFX0FOQUxZVElDU19JRCAmJiB3aW5kb3cuZ3RhZykge1xuICAgICAgd2luZG93Lmd0YWcoXCJldmVudFwiLCBhY3Rpb24sIHtcbiAgICAgICAgZXZlbnRfY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICBldmVudF9sYWJlbDogbGFiZWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHdpbmRvdy5zYV9ldmVudCkge1xuICAgICAgd2luZG93LnNhX2V2ZW50KGFjdGlvbiwge1xuICAgICAgICBjYXRlZ29yeSxcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHdpbmRvdy5mYXRob20pIHtcbiAgICAgIHdpbmRvdy5mYXRob20udHJhY2tFdmVudChhY3Rpb24sIHtcbiAgICAgICAgY2F0ZWdvcnksXG4gICAgICAgIGxhYmVsLFxuICAgICAgICB2YWx1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiZXJyb3IgZHVyaW5nIGFuYWx5dGljc1wiLCBlcnJvcik7XG4gIH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../analytics.ts\n");
2628
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nconst trackEvent = (category, action, label, value) => {\n try {\n // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n if (typeof window === \"undefined\" || ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"FAST_REFRESH\":\"false\",\"REACT_APP_MATOMO_URL\":\"\",\"REACT_APP_CDN_MATOMO_TRACKER_URL\":\"\",\"REACT_APP_MATOMO_SITE_ID\":\"\",\"REACT_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX\":\"\",\"PKG_NAME\":\"@dwelle/excalidraw\",\"PKG_VERSION\":\"0.4.0-b411b92\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).JEST_WORKER_ID) {\n return;\n }\n if (({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"FAST_REFRESH\":\"false\",\"REACT_APP_MATOMO_URL\":\"\",\"REACT_APP_CDN_MATOMO_TRACKER_URL\":\"\",\"REACT_APP_MATOMO_SITE_ID\":\"\",\"REACT_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX\":\"\",\"PKG_NAME\":\"@dwelle/excalidraw\",\"PKG_VERSION\":\"0.4.0-b411b92\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).REACT_APP_GOOGLE_ANALYTICS_ID && window.gtag) {\n window.gtag(\"event\", action, {\n event_category: category,\n event_label: label,\n value,\n });\n }\n if (window.sa_event) {\n window.sa_event(action, {\n category,\n label,\n value,\n });\n }\n if (window.fathom) {\n window.fathom.trackEvent(action, {\n category,\n label,\n value,\n });\n }\n }\n catch (error) {\n console.error(\"error during analytics\", error);\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vYW5hbHl0aWNzLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFBTyxNQUFNLFVBQVUsR0FBRyxDQUN4QixRQUFnQixFQUNoQixNQUFjLEVBQ2QsS0FBYyxFQUNkLEtBQWMsRUFDZCxFQUFFO0lBQ0YsSUFBSTtRQUNGLDJDQUEyQztRQUMzQyxrRUFBa0U7UUFFbEUsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksbWlDQUFXLENBQUMsY0FBYyxFQUFFO1lBQy9ELE9BQU87U0FDUjtRQUVELElBQUksbWlDQUFXLENBQUMsNkJBQTZCLElBQUksTUFBTSxDQUFDLElBQUksRUFBRTtZQUM1RCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7Z0JBQzNCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ25CLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO2dCQUN0QixRQUFRO2dCQUNSLEtBQUs7Z0JBQ0wsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO1lBQ2pCLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTtnQkFDL0IsUUFBUTtnQkFDUixLQUFLO2dCQUNMLEtBQUs7YUFDTixDQUFDLENBQUM7U0FDSjtLQUNGO0lBQUMsT0FBTyxLQUFLLEVBQUU7UUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQ2hEO0FBQ0gsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL2FuYWx5dGljcy50cz81ZjBjIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCB0cmFja0V2ZW50ID0gKFxuICBjYXRlZ29yeTogc3RyaW5nLFxuICBhY3Rpb246IHN0cmluZyxcbiAgbGFiZWw/OiBzdHJpbmcsXG4gIHZhbHVlPzogbnVtYmVyLFxuKSA9PiB7XG4gIHRyeSB7XG4gICAgLy8gVW5jb21tZW50IHRoZSBuZXh0IGxpbmUgdG8gdHJhY2sgbG9jYWxseVxuICAgIC8vIGNvbnNvbGUubG9nKFwiVHJhY2sgRXZlbnRcIiwgeyBjYXRlZ29yeSwgYWN0aW9uLCBsYWJlbCwgdmFsdWUgfSk7XG5cbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIiB8fCBwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5SRUFDVF9BUFBfR09PR0xFX0FOQUxZVElDU19JRCAmJiB3aW5kb3cuZ3RhZykge1xuICAgICAgd2luZG93Lmd0YWcoXCJldmVudFwiLCBhY3Rpb24sIHtcbiAgICAgICAgZXZlbnRfY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICBldmVudF9sYWJlbDogbGFiZWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHdpbmRvdy5zYV9ldmVudCkge1xuICAgICAgd2luZG93LnNhX2V2ZW50KGFjdGlvbiwge1xuICAgICAgICBjYXRlZ29yeSxcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHdpbmRvdy5mYXRob20pIHtcbiAgICAgIHdpbmRvdy5mYXRob20udHJhY2tFdmVudChhY3Rpb24sIHtcbiAgICAgICAgY2F0ZWdvcnksXG4gICAgICAgIGxhYmVsLFxuICAgICAgICB2YWx1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiZXJyb3IgZHVyaW5nIGFuYWx5dGljc1wiLCBlcnJvcik7XG4gIH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../analytics.ts\n");
2629
2629
 
2630
2630
  /***/ }),
2631
2631
 
@@ -2713,7 +2713,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2713
2713
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2714
2714
 
2715
2715
  "use strict";
2716
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ExcalidrawContainerContext\": () => (/* binding */ ExcalidrawContainerContext),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"useApp\": () => (/* binding */ useApp),\n/* harmony export */ \"useAppProps\": () => (/* binding */ useAppProps),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawActionManager\": () => (/* binding */ useExcalidrawActionManager),\n/* harmony export */ \"useExcalidrawAppState\": () => (/* binding */ useExcalidrawAppState),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"useExcalidrawElements\": () => (/* binding */ useExcalidrawElements),\n/* harmony export */ \"useExcalidrawSetAppState\": () => (/* binding */ useExcalidrawSetAppState)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.browser.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_library__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../data/library */ \"../../data/library.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_newElement__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../element/newElement */ \"../../element/newElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _gesture__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../gesture */ \"../../gesture.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _history__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../history */ \"../../history.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../renderer/renderElement */ \"../../renderer/renderElement.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _scene_zoom__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../scene/zoom */ \"../../scene/zoom.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ContextMenu */ \"../../components/ContextMenu.tsx\");\n/* harmony import */ var _LayerUI__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LayerUI */ \"../../components/LayerUI.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_41__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! ../actions/actionElementLock */ \"../../actions/actionElementLock.ts\");\n/* harmony import */ var _scene_Fonts__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! ../scene/Fonts */ \"../../scene/Fonts.ts\");\n/* harmony import */ var _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! ../actions/actionClipboard */ \"../../actions/actionClipboard.tsx\");\n/* harmony import */ var _actions_actionCanvas__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! ../actions/actionCanvas */ \"../../actions/actionCanvas.tsx\");\n/* harmony import */ var _jotai__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! ../jotai */ \"../../jotai.ts\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"../../components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(/*! ../actions/actionBoundText */ \"../../actions/actionBoundText.tsx\");\n/* harmony import */ var _BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(/*! ./BraveMeasureTextError */ \"../../components/BraveMeasureTextError.tsx\");\n/* harmony import */ var _emitter__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(/*! ../emitter */ \"../../emitter.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst AppContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nconst AppPropsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n isLandscape: false,\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nDeviceContext.displayName = \"DeviceContext\";\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\nExcalidrawContainerContext.displayName = \"ExcalidrawContainerContext\";\nconst ExcalidrawElementsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext([]);\nExcalidrawElementsContext.displayName = \"ExcalidrawElementsContext\";\nconst ExcalidrawAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 }));\nExcalidrawAppStateContext.displayName = \"ExcalidrawAppStateContext\";\nconst ExcalidrawSetAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(() => {\n console.warn(\"unitialized ExcalidrawSetAppStateContext context!\");\n});\nExcalidrawSetAppStateContext.displayName = \"ExcalidrawSetAppStateContext\";\nconst ExcalidrawActionManagerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nExcalidrawActionManagerContext.displayName = \"ExcalidrawActionManagerContext\";\nconst useApp = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppContext);\nconst useAppProps = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppPropsContext);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\nconst useExcalidrawElements = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawElementsContext);\nconst useExcalidrawAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawAppStateContext);\nconst useExcalidrawSetAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawSetAppStateContext);\nconst useExcalidrawActionManager = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawActionManagerContext);\nlet didTapTwice = false;\nlet tappedTwiceTimer = 0;\nlet cursorX = 0;\nlet cursorY = 0;\nlet isHoldingSpace = false;\nlet isPanning = false;\nlet isDraggingScrollBar = false;\nlet currentScrollBars = { horizontal: null, vertical: null };\nlet touchTimeout = 0;\nlet invalidateContextMenu = false;\n// remove this hack when we can sync render & resizeObserver (state update)\n// to rAF. See #5439\nlet THROTTLE_NEXT_RENDER = true;\nlet IS_PLAIN_PASTE = false;\nlet IS_PLAIN_PASTE_TIMER = 0;\nlet PLAIN_PASTE_TOAST_SHOWN = false;\nlet lastPointerUp = null;\nconst gesture = {\n pointers: new Map(),\n lastCenter: null,\n initialDistance: null,\n initialScale: null,\n};\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\n constructor(props) {\n var _a;\n super(props);\n this.canvas = null;\n this.rc = null;\n this.unmounted = false;\n this.device = deviceContextInitialValue;\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\n this.files = {};\n this.imageCache = new Map();\n this.lastPointerDown = null;\n this.lastPointerUp = null;\n this.lastScenePointer = null;\n this.onChangeEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_55__.Emitter();\n this.onPointerDownEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_55__.Emitter();\n this.onPointerUpEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_55__.Emitter();\n this.focusContainer = () => {\n var _a;\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n };\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n this.onInsertElements = (elements) => {\n this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null,\n });\n };\n this.onExportImage = (type, elements) => __awaiter(this, void 0, void 0, function* () {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"export\", type, \"ui\");\n const fileHandle = yield (0,_data__WEBPACK_IMPORTED_MODULE_13__.exportAsImage)(type, elements, this.state, this.files, {\n exportBackground: this.state.exportBackground,\n name: this.state.name,\n viewBackgroundColor: this.state.viewBackgroundColor,\n })\n .catch(_utils__WEBPACK_IMPORTED_MODULE_34__.muteFSAbortError)\n .catch((error) => {\n console.error(error);\n this.setState({ errorMessage: error.message });\n });\n if (this.state.exportEmbedScene &&\n fileHandle &&\n (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isImageFileHandle)(fileHandle)) {\n this.setState({ fileHandle });\n }\n });\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n if (this.unmounted || actionResult === false) {\n return;\n }\n let editingElement = null;\n if (actionResult.elements) {\n actionResult.elements.forEach((element) => {\n var _a;\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\n this.state.editingElement !== element &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n editingElement = element;\n }\n });\n this.scene.replaceAllElements(actionResult.elements);\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n }\n if (actionResult.files) {\n this.files = actionResult.replaceFiles\n ? actionResult.files\n : Object.assign(Object.assign({}, this.files), actionResult.files);\n this.addNewImagesToImageCache();\n }\n if (actionResult.appState || editingElement || this.state.contextMenu) {\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\n const theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.theme) || this.props.theme || _constants__WEBPACK_IMPORTED_MODULE_12__.THEME.LIGHT;\n let name = (_f = (_e = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : this.state.name;\n const errorMessage = (_h = (_g = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _g === void 0 ? void 0 : _g.errorMessage) !== null && _h !== void 0 ? _h : this.state.errorMessage;\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\n viewModeEnabled = this.props.viewModeEnabled;\n }\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\n zenModeEnabled = this.props.zenModeEnabled;\n }\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null;\n }\n if (typeof this.props.name !== \"undefined\") {\n name = this.props.name;\n }\n this.setState((state) => {\n var _a;\n // using Object.assign instead of spread to fool TS 4.2.2+ into\n // regarding the resulting type as not containing undefined\n // (which the following expression will never contain)\n return Object.assign(actionResult.appState || {}, {\n // NOTE this will prevent opening context menu using an action\n // or programmatically from the host, so it will need to be\n // rewritten later\n contextMenu: null,\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\n viewModeEnabled,\n zenModeEnabled,\n gridSize,\n theme,\n name,\n errorMessage,\n });\n }, () => {\n if (actionResult.syncHistory) {\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\n }\n });\n }\n });\n // Lifecycle\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isHoldingSpace = false;\n this.setState({ isBindingEnabled: true });\n });\n this.onUnload = () => {\n this.onBlur();\n };\n this.disableEvent = (event) => {\n event.preventDefault();\n };\n this.resetHistory = () => {\n this.history.clear();\n };\n /**\n * Resets scene & history.\n * ! Do not use to clear scene user action !\n */\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\n this.scene.replaceAllElements([]);\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\n this.resetHistory();\n });\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\n var _b;\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\n if (!launchParams.files.length) {\n return;\n }\n const fileHandle = launchParams.files[0];\n const blob = yield fileHandle.getFile();\n this.loadFileToCanvas(new File([blob], blob.name || \"\", { type: blob.type }), fileHandle);\n }));\n }\n if (this.props.theme) {\n this.setState({ theme: this.props.theme });\n }\n if (!this.state.isLoading) {\n this.setState({ isLoading: true });\n }\n let initialData = null;\n try {\n initialData = (yield this.props.initialData) || null;\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\n this.library\n .updateLibrary({\n libraryItems: initialData.libraryItems,\n merge: true,\n })\n .catch((error) => {\n console.error(error);\n });\n }\n }\n catch (error) {\n console.error(error);\n initialData = {\n appState: {\n errorMessage: error.message ||\n \"Encountered an error during importing or restoring scene data\",\n },\n };\n }\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null, { repairBindings: true });\n scene.appState = Object.assign(Object.assign({}, scene.appState), { theme: this.props.theme || scene.appState.theme, \n // we're falling back to current (pre-init) state when deciding\n // whether to open the library, to handle a case where we\n // update the state outside of initialData (e.g. when loading the app\n // with a library install link, which should auto-open the library)\n openSidebar: ((_b = scene.appState) === null || _b === void 0 ? void 0 : _b.openSidebar) || this.state.openSidebar, activeTool: scene.appState.activeTool.type === \"image\"\n ? Object.assign(Object.assign({}, scene.appState.activeTool), { type: \"selection\" }) : scene.appState.activeTool, isLoading: false, toast: this.state.toast });\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\n scene.appState = Object.assign(Object.assign({}, scene.appState), (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(scene.elements, Object.assign(Object.assign({}, scene.appState), { width: this.state.width, height: this.state.height, offsetTop: this.state.offsetTop, offsetLeft: this.state.offsetLeft }), null));\n }\n // FontFaceSet loadingdone event we listen on may not always fire\n // (looking at you Safari), so on init we manually load fonts for current\n // text elements on canvas, and rerender them once done. This also\n // seems faster even in browsers that do fire the loadingdone event.\n this.fonts.loadFontsForElements(scene.elements);\n if ((initialData === null || initialData === void 0 ? void 0 : initialData.scrollX) != null) {\n scene.appState.scrollX = initialData.scrollX;\n }\n if ((initialData === null || initialData === void 0 ? void 0 : initialData.scrollY) != null) {\n scene.appState.scrollY = initialData.scrollY;\n }\n this.resetHistory();\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\n });\n this.refreshDeviceState = (container) => {\n const { width, height } = container.getBoundingClientRect();\n const sidebarBreakpoint = this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH;\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isLandscape: width > height,\n isSmScreen: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH,\n isMobile: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT ||\n (height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE),\n canDeviceFitSidebar: width > sidebarBreakpoint,\n });\n };\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n this.scene\n .getElementsIncludingDeleted()\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\n this.setState({});\n });\n this.onFontsLoadingDone = (event) => {\n const loadedFontFaces = event.fontfaces;\n this.fonts.onFontsLoaded(loadedFontFaces);\n };\n this.renderScene = () => {\n const cursorButton = {};\n const pointerViewportCoords = {};\n const remoteSelectedElementIds = {};\n const pointerUsernames = {};\n const pointerUserStates = {};\n this.state.collaborators.forEach((user, socketId) => {\n if (user.selectedElementIds) {\n for (const id of Object.keys(user.selectedElementIds)) {\n if (!(id in remoteSelectedElementIds)) {\n remoteSelectedElementIds[id] = [];\n }\n remoteSelectedElementIds[id].push(socketId);\n }\n }\n if (!user.pointer) {\n return;\n }\n if (user.username) {\n pointerUsernames[socketId] = user.username;\n }\n if (user.userState) {\n pointerUserStates[socketId] = user.userState;\n }\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: user.pointer.x,\n sceneY: user.pointer.y,\n }, this.state);\n cursorButton[socketId] = user.button;\n });\n const renderingElements = this.scene\n .getNonDeletedElements()\n .filter((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\n if (\n // not placed on canvas yet (but in elements array)\n this.state.pendingImageElementId === element.id) {\n return false;\n }\n }\n // don't render text element that's being currently edited (it's\n // rendered on remote only)\n return (!this.state.editingElement ||\n this.state.editingElement.type !== \"text\" ||\n element.id !== this.state.editingElement.id);\n });\n const selectionColor = getComputedStyle(document.querySelector(\".excalidraw\")).getPropertyValue(\"--color-selection\");\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__.renderScene)({\n elements: renderingElements,\n appState: this.state,\n rc: this.rc,\n canvas: this.canvas,\n renderConfig: {\n canvasScale: window.devicePixelRatio,\n selectionColor,\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n canvasBackgroundColor: this.state.viewBackgroundColor,\n zoom: this.state.zoom,\n remotePointerViewportCoords: pointerViewportCoords,\n remotePointerButton: cursorButton,\n remoteSelectedElementIds,\n remotePointerUsernames: pointerUsernames,\n remotePointerUserStates: pointerUserStates,\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\n theme: this.state.theme,\n imageCache: this.imageCache,\n isExporting: false,\n renderScrollbars: !this.device.isMobile,\n },\n callback: ({ atLeastOneVisibleElement, scrollBars }) => {\n if (scrollBars) {\n currentScrollBars = scrollBars;\n }\n const scrolledOutside = \n // hide when editing text\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? false\n : !atLeastOneVisibleElement && renderingElements.length > 0;\n if (this.state.scrolledOutside !== scrolledOutside) {\n this.setState({ scrolledOutside });\n }\n this.scheduleImageRefresh();\n },\n }, THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true);\n if (!THROTTLE_NEXT_RENDER) {\n THROTTLE_NEXT_RENDER = true;\n }\n };\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\n this.setState((state) => {\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\n return null;\n }\n return { offsetTop, offsetLeft };\n });\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.SCROLL_TIMEOUT);\n // Copy/paste\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.cutAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.copyAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.cutAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, \"keyboard\");\n };\n this.copyAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, \"keyboard\");\n };\n this.onTapStart = (event) => {\n // fix for Apple Pencil Scribble\n // On Android, preventing the event would disable contextMenu on tap-hold\n if (!_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n if (!didTapTwice) {\n didTapTwice = true;\n clearTimeout(tappedTwiceTimer);\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_12__.TAP_TWICE_TIMEOUT);\n return;\n }\n // insert text only if we tapped twice with a single finger\n // event.touches.length === 1 will also prevent inserting text when user's zooming\n if (didTapTwice && event.touches.length === 1) {\n const [touch] = event.touches;\n // @ts-ignore\n this.handleCanvasDoubleClick({\n clientX: touch.clientX,\n clientY: touch.clientY,\n });\n didTapTwice = false;\n clearTimeout(tappedTwiceTimer);\n }\n if (_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n if (event.touches.length === 2) {\n this.setState({\n selectedElementIds: {},\n });\n }\n };\n this.onTapEnd = (event) => {\n this.resetContextMenuTimer();\n if (event.touches.length > 0) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n else {\n gesture.pointers.clear();\n }\n };\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\n var _c, _d;\n const isPlainPaste = !!(IS_PLAIN_PASTE && event);\n // #686\n const target = document.activeElement;\n const isExcalidrawActive = (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);\n if (event && !isExcalidrawActive) {\n return;\n }\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\n if (event &&\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\n return;\n }\n // must be called in the same frame (thus before any awaits) as the paste\n // event else some browsers (FF...) will clear the clipboardData\n // (something something security)\n let file = (_d = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _d === void 0 ? void 0 : _d.files[0];\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_11__.parseClipboard)(event, isPlainPaste);\n if (!file && data.text && !isPlainPaste) {\n const string = data.text.trim();\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\n // ignore SVG validation/normalization which will be done during image\n // initialization\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(string);\n }\n }\n // prefer spreadsheet data over image file (MS Office/Libre Office)\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file) && !data.spreadsheet) {\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n if (this.props.onPaste) {\n try {\n if ((yield this.props.onPaste(data, event)) === false) {\n return;\n }\n }\n catch (error) {\n console.error(error);\n }\n }\n if (data.errorMessage) {\n this.setState({ errorMessage: data.errorMessage });\n }\n else if (data.spreadsheet && !isPlainPaste) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true,\n },\n });\n }\n else if (data.elements) {\n // TODO remove formatting from elements if isPlainPaste\n this.addElementsFromPasteOrLibrary({\n elements: data.elements,\n files: data.files || null,\n position: \"cursor\",\n retainSeed: isPlainPaste,\n });\n }\n else if (data.text) {\n this.addTextFromPaste(data.text, isPlainPaste);\n }\n this.setActiveTool({ type: \"selection\" });\n event === null || event === void 0 ? void 0 : event.preventDefault();\n }));\n this.addElementsFromPasteOrLibrary = (opts) => {\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\n const clientX = typeof opts.position === \"object\"\n ? opts.position.clientX\n : opts.position === \"cursor\"\n ? cursorX\n : this.state.width / 2 + this.state.offsetLeft;\n const clientY = typeof opts.position === \"object\"\n ? opts.position.clientY\n : opts.position === \"cursor\"\n ? cursorY\n : this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const dx = x - elementsCenterX;\n const dy = y - elementsCenterY;\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\n const newElements = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.duplicateElements)(elements.map((element) => {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY,\n });\n }), {\n randomizeSeed: !opts.retainSeed,\n });\n const nextElements = [\n ...this.scene.getElementsIncludingDeleted(),\n ...newElements,\n ];\n this.scene.replaceAllElements(nextElements);\n newElements.forEach((newElement) => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(newElement) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(newElement)) {\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerElement)(newElement);\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.redrawTextBoundingBox)(newElement, container);\n }\n });\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n this.history.resumeRecording();\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { \n // keep sidebar (presumably the library) open if it's docked and\n // can fit.\n //\n // Note, we should close the sidebar only if we're dropping items\n // from library, not when pasting from clipboard. Alas.\n openSidebar: this.state.openSidebar &&\n this.device.canDeviceFitSidebar &&\n this.state.defaultSidebarDockedPreference\n ? this.state.openSidebar\n : null, selectedElementIds: newElements.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n return acc;\n }, {}), selectedGroupIds: {} }), this.scene.getNonDeletedElements()), () => {\n if (opts.files) {\n this.addNewImagesToImageCache();\n }\n });\n this.setActiveTool({ type: \"selection\" });\n };\n this.setAppState = (state, callback) => {\n this.setState(state, callback);\n };\n this.removePointer = (event) => {\n if (touchTimeout) {\n this.resetContextMenuTimer();\n }\n gesture.pointers.delete(event.pointerId);\n };\n this.toggleLock = (source = \"ui\") => {\n if (!this.state.activeTool.locked) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", \"toggleLock\", `${source} (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setState((prevState) => {\n return {\n activeTool: Object.assign(Object.assign(Object.assign({}, prevState.activeTool), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, prevState.activeTool.locked\n ? { type: \"selection\" }\n : prevState.activeTool)), { locked: !prevState.activeTool.locked }),\n };\n });\n };\n this.togglePenMode = () => {\n this.setState((prevState) => {\n return {\n penMode: !prevState.penMode,\n };\n });\n };\n this.onHandToolToggle = () => {\n this.actionManager.executeAction(_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_50__.actionToggleHandTool);\n };\n /**\n * Zooms on canvas viewport center\n */\n this.zoomCanvas = (\n /** decimal fraction between 0.1 (10% zoom) and 30 (3000% zoom) */\n value) => {\n this.setState(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: this.state.width / 2 + this.state.offsetLeft,\n viewportY: this.state.height / 2 + this.state.offsetTop,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(value),\n }, this.state)));\n };\n this.cancelInProgresAnimation = null;\n this.scrollToContent = (target = this.scene.getNonDeletedElements(), opts) => {\n var _a, _b;\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this);\n // convert provided target into ExcalidrawElement[] if necessary\n const targets = Array.isArray(target) ? target : [target];\n let zoom = this.state.zoom;\n let scrollX = this.state.scrollX;\n let scrollY = this.state.scrollY;\n if (opts === null || opts === void 0 ? void 0 : opts.fitToContent) {\n // compute an appropriate viewport location (scroll X, Y) and zoom level\n // that fit the target elements on the scene\n const { appState } = (0,_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_50__.zoomToFitElements)(targets, this.state, false);\n zoom = appState.zoom;\n scrollX = appState.scrollX;\n scrollY = appState.scrollY;\n }\n else {\n // compute only the viewport location, without any zoom adjustment\n const scroll = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(targets, this.state, this.canvas);\n scrollX = scroll.scrollX;\n scrollY = scroll.scrollY;\n }\n // when animating, we use RequestAnimationFrame to prevent the animation\n // from slowing down other processes\n if (opts === null || opts === void 0 ? void 0 : opts.animate) {\n const origScrollX = this.state.scrollX;\n const origScrollY = this.state.scrollY;\n // zoom animation could become problematic on scenes with large number\n // of elements, setting it to its final value to improve user experience.\n //\n // using zoomCanvas() to zoom on current viewport center\n this.zoomCanvas(zoom.value);\n const cancel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.easeToValuesRAF)([origScrollX, origScrollY], [scrollX, scrollY], (scrollX, scrollY) => this.setState({ scrollX, scrollY }), { duration: (_b = opts === null || opts === void 0 ? void 0 : opts.duration) !== null && _b !== void 0 ? _b : 500 });\n this.cancelInProgresAnimation = () => {\n cancel();\n this.cancelInProgresAnimation = null;\n };\n }\n else {\n this.setState({ scrollX, scrollY, zoom });\n }\n };\n /** use when changing scrollX/scrollY/zoom based on user interaction */\n this.translateCanvas = (state) => {\n var _a;\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this);\n this.setState(state);\n };\n this.setToast = (toast) => {\n this.setState({ toast });\n };\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\n try {\n const webShareTargetCache = yield caches.open(\"web-share-target\");\n const response = yield webShareTargetCache.match(\"shared-file\");\n if (response) {\n const blob = yield response.blob();\n const file = new File([blob], blob.name || \"\", { type: blob.type });\n this.loadFileToCanvas(file, null);\n yield webShareTargetCache.delete(\"shared-file\");\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_12__.APP_NAME, window.location.pathname);\n }\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n });\n /** adds supplied files to existing files in the appState */\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\n const filesMap = files.reduce((acc, fileData) => {\n acc.set(fileData.id, fileData);\n return acc;\n }, new Map());\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\n this.scene.getNonDeletedElements().forEach((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n filesMap.has(element.fileId)) {\n this.imageCache.delete(element.fileId);\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.scene.informMutation();\n this.addNewImagesToImageCache();\n });\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\n if (sceneData.commitToHistory) {\n this.history.resumeRecording();\n }\n if (sceneData.appState) {\n this.setState(sceneData.appState);\n }\n if (sceneData.elements) {\n this.scene.replaceAllElements(sceneData.elements);\n }\n if (sceneData.collaborators) {\n this.setState({ collaborators: sceneData.collaborators });\n }\n });\n this.onSceneUpdated = () => {\n this.setState({});\n };\n /**\n * @returns whether the menu was toggled on or off\n */\n this.toggleSidebar = ({ name, tab, force, }) => {\n var _a;\n let nextName;\n if (force === undefined) {\n nextName = ((_a = this.state.openSidebar) === null || _a === void 0 ? void 0 : _a.name) === name ? null : name;\n }\n else {\n nextName = force ? name : null;\n }\n this.setState({ openSidebar: nextName ? { name: nextName, tab } : null });\n return !!nextName;\n };\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n cursorX = event.clientX;\n cursorY = event.clientY;\n });\n // Input handling\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // normalize `event.key` when CapsLock is pressed #2372\n if (\"Proxy\" in window &&\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\n event = new Proxy(event, {\n get(ev, prop) {\n const value = ev[prop];\n if (typeof value === \"function\") {\n // fix for Proxies hijacking `this`\n return value.bind(ev);\n }\n return prop === \"key\"\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\n // it back\n event.shiftKey\n ? ev.key.toUpperCase()\n : ev.key.toLowerCase()\n : value;\n },\n });\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.V) {\n IS_PLAIN_PASTE = event.shiftKey;\n clearTimeout(IS_PLAIN_PASTE_TIMER);\n // reset (100ms to be safe that we it runs after the ensuing\n // paste event). Though, technically unnecessary to reset since we\n // (re)set the flag before each paste event.\n IS_PLAIN_PASTE_TIMER = window.setTimeout(() => {\n IS_PLAIN_PASTE = false;\n }, 100);\n }\n // prevent browser zoom in input fields\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.MINUS || event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.EQUAL) {\n event.preventDefault();\n return;\n }\n }\n // bail if\n if (\n // inside an input\n ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) &&\n // unless pressing escape (finalize action)\n event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\n // or unless using arrows (to move between buttons)\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\n this.setState({\n openDialog: \"help\",\n });\n return;\n }\n else if (event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.E &&\n event.shiftKey &&\n event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n this.setState({ openDialog: \"imageExport\" });\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_UP || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n let offset = (event.shiftKey ? this.state.width : this.state.height) /\n this.state.zoom.value;\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n offset = -offset;\n }\n if (event.shiftKey) {\n this.translateCanvas((state) => ({\n scrollX: state.scrollX + offset,\n }));\n }\n else {\n this.translateCanvas((state) => ({\n scrollY: state.scrollY + offset,\n }));\n }\n }\n if (this.actionManager.handleKeyDown(event)) {\n return;\n }\n if (this.state.viewModeEnabled) {\n return;\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: false });\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const step = (this.state.gridSize &&\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT\n : this.state.gridSize)) ||\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\n : _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT);\n let offsetX = 0;\n let offsetY = 0;\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\n offsetX = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\n offsetX = step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\n offsetY = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\n offsetY = step;\n }\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state, true);\n selectedElements.forEach((element) => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: element.x + offsetX,\n y: element.y + offsetY,\n });\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\n simultaneouslyUpdated: selectedElements,\n });\n });\n this.maybeSuggestBindingForAll(selectedElements);\n event.preventDefault();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElement)) {\n if (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !==\n selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElement, this.scene),\n });\n }\n }\n }\n else if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement) ||\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isValidTextContainer)(selectedElement)) {\n let container;\n if (!(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement)) {\n container = selectedElement;\n }\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(selectedElement, this.state);\n const sceneX = midPoint.x;\n const sceneY = midPoint.y;\n this.startTextEditing({\n sceneX,\n sceneY,\n container,\n });\n event.preventDefault();\n return;\n }\n }\n }\n else if (!event.ctrlKey &&\n !event.altKey &&\n !event.metaKey &&\n this.state.draggingElement === null) {\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\n if (shape) {\n if (this.state.activeTool.type !== shape) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", shape, `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setActiveTool({ type: shape });\n event.stopPropagation();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\n this.toggleLock(\"keyboard\");\n event.stopPropagation();\n }\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\n isHoldingSpace = true;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n event.preventDefault();\n }\n if ((event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) &&\n !event.altKey &&\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (this.state.activeTool.type === \"selection\" &&\n !selectedElements.length) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.activeTool.type) ||\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\n this.setState({ openPopup: \"elementBackground\" });\n event.stopPropagation();\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({ openPopup: \"elementStroke\" });\n event.stopPropagation();\n }\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\n (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.BACKSPACE || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.DELETE)) {\n _jotai__WEBPACK_IMPORTED_MODULE_51__.jotaiStore.set(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_52__.activeConfirmDialogAtom, \"clearCanvas\");\n }\n });\n this.onWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // prevent browser pinch zoom on DOM elements\n if (!(event.target instanceof HTMLCanvasElement) && event.ctrlKey) {\n event.preventDefault();\n }\n });\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (this.state.activeTool.type === \"selection\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n isHoldingSpace = false;\n }\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: true });\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\n this.setState({ suggestedBindings: [] });\n }\n });\n this.setActiveTool = (tool) => {\n const nextActiveTool = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, tool);\n if (nextActiveTool.type === \"hand\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (!isHoldingSpace) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\n this.focusContainer();\n }\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(nextActiveTool.type)) {\n this.setState({ suggestedBindings: [] });\n }\n if (nextActiveTool.type === \"image\") {\n this.onImageAction();\n }\n if (nextActiveTool.type !== \"selection\") {\n this.setState({\n activeTool: nextActiveTool,\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n else {\n this.setState({ activeTool: nextActiveTool });\n }\n };\n this.setCursor = (cursor) => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, cursor);\n };\n this.resetCursor = () => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n };\n /**\n * returns whether user is making a gesture with >= 2 fingers (points)\n * on o touch screen (not on a trackpad). Currently only relates to Darwin\n * (iOS/iPadOS,MacOS), but may work on other devices in the future if\n * GestureEvent is standardized.\n */\n this.isTouchScreenMultiTouchGesture = () => {\n // we don't want to deselect when using trackpad, and multi-point gestures\n // only work on touch screens, so checking for >= pointers means we're on a\n // touchscreen\n return gesture.pointers.size >= 2;\n };\n // fires only on Safari\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // we only want to deselect on touch screens because user may have selected\n // elements by mistake while zooming\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n selectedElementIds: {},\n });\n }\n gesture.initialScale = this.state.zoom.value;\n });\n // fires only on Safari\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // onGestureChange only has zoom factor but not the center.\n // If we're on iPad or iPhone, then we recognize multi-touch and will\n // zoom in at the right location in the touchmove handler\n // (handleCanvasPointerMove).\n //\n // On Macbook trackpad, we don't have those events so will zoom in at the\n // current location instead.\n //\n // As such, bail from this handler on touch devices.\n if (this.isTouchScreenMultiTouchGesture()) {\n return;\n }\n const initialScale = gesture.initialScale;\n if (initialScale) {\n this.setState((state) => (Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale),\n }, state))));\n }\n });\n // fires only on Safari\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // reselect elements only on touch screens (see onGestureStart)\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n gesture.initialScale = null;\n });\n this.startTextEditing = ({ sceneX, sceneY, insertAtParentCenter = true, container, }) => {\n var _a, _b;\n let shouldBindToContainer = false;\n let parentCenterPosition = insertAtParentCenter &&\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n if (container && parentCenterPosition) {\n shouldBindToContainer = true;\n }\n let existingTextElement = null;\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElements[0])) {\n existingTextElement = selectedElements[0];\n }\n else if (container) {\n existingTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(selectedElements[0]);\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n const fontFamily = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.fontFamily) || this.state.currentItemFontFamily;\n const lineHeight = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.lineHeight) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(fontFamily);\n const fontSize = this.state.currentItemFontSize;\n if (!existingTextElement &&\n shouldBindToContainer &&\n container &&\n !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isArrowElement)(container)) {\n const fontString = {\n fontSize,\n fontFamily,\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString), lineHeight);\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)(fontSize, lineHeight);\n const containerDims = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerDims)(container);\n const newHeight = Math.max(containerDims.height, minHeight);\n const newWidth = Math.max(containerDims.width, minWidth);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\n sceneX = container.x + newWidth / 2;\n sceneY = container.y + newHeight / 2;\n if (parentCenterPosition) {\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n }\n }\n const element = existingTextElement\n ? existingTextElement\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x: parentCenterPosition\n ? parentCenterPosition.elementCenterX\n : sceneX,\n y: parentCenterPosition\n ? parentCenterPosition.elementCenterY\n : sceneY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text: \"\",\n fontSize,\n fontFamily,\n textAlign: parentCenterPosition\n ? \"center\"\n : this.state.currentItemTextAlign,\n verticalAlign: parentCenterPosition\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.VERTICAL_ALIGN.MIDDLE\n : _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n containerId: shouldBindToContainer ? container === null || container === void 0 ? void 0 : container.id : undefined,\n groupIds: (_a = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _a !== void 0 ? _a : [],\n lineHeight,\n angle: (_b = container === null || container === void 0 ? void 0 : container.angle) !== null && _b !== void 0 ? _b : 0,\n });\n if (!existingTextElement && shouldBindToContainer && container) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, {\n boundElements: (container.boundElements || []).concat({\n type: \"text\",\n id: element.id,\n }),\n });\n }\n this.setState({ editingElement: element });\n if (!existingTextElement) {\n if (container && shouldBindToContainer) {\n const containerIndex = this.scene.getElementIndex(container.id);\n this.scene.insertElementAtIndex(element, containerIndex + 1);\n }\n else {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n }\n }\n this.setState({\n editingElement: element,\n });\n this.handleTextWysiwyg(element, {\n isExistingElement: !!existingTextElement,\n });\n };\n this.handleCanvasDoubleClick = (event) => {\n // case: double-clicking with arrow/line tool selected would both create\n // text and enter multiElement mode\n if (this.state.multiElement) {\n return;\n }\n // we should only be able to double click when mode is selection\n if (this.state.activeTool.type !== \"selection\") {\n return;\n }\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\n (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !== selectedElements[0].id)) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\n });\n return;\n }\n else if (this.state.editingLinearElement &&\n this.state.editingLinearElement.elementId === selectedElements[0].id) {\n return;\n }\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\n if (selectedGroupIds.length > 0) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n const selectedGroupId = hitElement &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\n if (selectedGroupId) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { editingGroupId: selectedGroupId, selectedElementIds: { [hitElement.id]: true }, selectedGroupIds: {} }), this.scene.getNonDeletedElements()));\n return;\n }\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n if (container) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(container) ||\n !(0,_utils__WEBPACK_IMPORTED_MODULE_34__.isTransparent)(container.backgroundColor) ||\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(container, this.state, [\n sceneX,\n sceneY,\n ])) {\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, this.state);\n sceneX = midPoint.x;\n sceneY = midPoint.y;\n }\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container,\n });\n }\n };\n this.getElementLinkAtPosition = (scenePointer, hitElement) => {\n // Reversing so we traverse the elements in decreasing order\n // of z-index\n const elements = this.scene.getNonDeletedElements().slice().reverse();\n let hitElementIndex = Infinity;\n return elements.find((element, index) => {\n if (hitElement && element.id === hitElement.id) {\n hitElementIndex = index;\n }\n return (element.link &&\n index <= hitElementIndex &&\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(element, this.state, [scenePointer.x, scenePointer.y], this.device.isMobile));\n });\n };\n this.redirectToLink = (event, isTouchScreen) => {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (!this.hitLinkElement ||\n // For touch screen allow dragging threshold else strict check\n (isTouchScreen && draggedDistance > _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) ||\n (!isTouchScreen && draggedDistance !== 0)) {\n return;\n }\n const lastPointerDownCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerDown, this.state);\n const lastPointerDownHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerDownCoords.x, lastPointerDownCoords.y], this.device.isMobile);\n const lastPointerUpCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerUp, this.state);\n const lastPointerUpHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerUpCoords.x, lastPointerUpCoords.y], this.device.isMobile);\n if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {\n const url = this.hitLinkElement.link;\n if (url) {\n let customEvent;\n if (this.props.onLinkOpen) {\n customEvent = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.wrapEvent)(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.EXCALIDRAW_LINK, event.nativeEvent);\n this.props.onLinkOpen(this.hitLinkElement, customEvent);\n }\n if (!(customEvent === null || customEvent === void 0 ? void 0 : customEvent.defaultPrevented)) {\n const target = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isLocalLink)(url) ? \"_self\" : \"_blank\";\n const newWindow = window.open(undefined, target);\n // https://mathiasbynens.github.io/rel-noopener/\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.normalizeLink)(url);\n }\n }\n }\n }\n };\n this.handleCanvasPointerMove = (event) => {\n var _a;\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\n if (gesture.pointers.has(event.pointerId)) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n }\n const initialScale = gesture.initialScale;\n if (gesture.pointers.size === 2 &&\n gesture.lastCenter &&\n initialScale &&\n gesture.initialDistance) {\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n const deltaX = center.x - gesture.lastCenter.x;\n const deltaY = center.y - gesture.lastCenter.y;\n gesture.lastCenter = center;\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n const scaleFactor = this.state.activeTool.type === \"freedraw\" && this.state.penMode\n ? 1\n : distance / gesture.initialDistance;\n const nextZoom = scaleFactor\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor)\n : this.state.zoom.value;\n this.setState((state) => {\n const zoomState = (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: center.x,\n viewportY: center.y,\n nextZoom,\n }, state);\n this.translateCanvas({\n zoom: zoomState.zoom,\n scrollX: zoomState.scrollX + deltaX / nextZoom,\n scrollY: zoomState.scrollY + deltaY / nextZoom,\n shouldCacheIgnoreZoom: true,\n });\n });\n this.resetShouldCacheIgnoreZoomDebounced();\n }\n else {\n gesture.lastCenter =\n gesture.initialDistance =\n gesture.initialScale =\n null;\n }\n if (isHoldingSpace ||\n isPanning ||\n isDraggingScrollBar ||\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state)) {\n return;\n }\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\n if (!this.state.draggingElement && !this.state.multiElement) {\n if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state);\n if (editingLinearElement &&\n editingLinearElement !== this.state.editingLinearElement) {\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({\n editingLinearElement,\n });\n });\n }\n if ((editingLinearElement === null || editingLinearElement === void 0 ? void 0 : editingLinearElement.lastUncommittedPoint) != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n else {\n // causes stack overflow if not sync\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({ suggestedBindings: [] });\n });\n }\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.activeTool.type)) {\n // Hovering with a selected tool or creating new linear element via click\n // and point\n const { draggingElement } = this.state;\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\n }\n else {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n }\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n const { x: rx, y: ry } = multiElement;\n const { points, lastCommittedPoint } = multiElement;\n const lastPoint = points[points.length - 1];\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n if (lastPoint === lastCommittedPoint) {\n // if we haven't yet created a temp point and we're beyond commit-zone\n // threshold, add a point\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\n });\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n // in this branch, we're inside the commit zone, and no uncommitted\n // point exists. Thus do nothing (don't add/remove points).\n }\n }\n else if (points.length > 2 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: points.slice(0, -1),\n });\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(scenePointerX, scenePointerY, this.state.gridSize);\n const [lastCommittedX, lastCommittedY] = (_a = multiElement === null || multiElement === void 0 ? void 0 : multiElement.lastCommittedPoint) !== null && _a !== void 0 ? _a : [0, 0];\n let dxFromLastCommitted = gridX - rx - lastCommittedX;\n let dyFromLastCommitted = gridY - ry - lastCommittedY;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event)) {\n ({ width: dxFromLastCommitted, height: dyFromLastCommitted } =\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(\n // actual coordinate of the last committed point\n lastCommittedX + rx, lastCommittedY + ry, \n // cursor-grid coordinate\n gridX, gridY));\n }\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n // update last uncommitted point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [\n ...points.slice(0, -1),\n [\n lastCommittedX + dxFromLastCommitted,\n lastCommittedY + dyFromLastCommitted,\n ],\n ],\n });\n }\n return;\n }\n const hasDeselectedButton = Boolean(event.buttons);\n if (hasDeselectedButton ||\n (this.state.activeTool.type !== \"selection\" &&\n this.state.activeTool.type !== \"text\" &&\n this.state.activeTool.type !== \"eraser\")) {\n return;\n }\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 &&\n !isOverScrollBar &&\n !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType &&\n elementWithTransformHandleType.transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\n return;\n }\n }\n else if (selectedElements.length > 1 && !isOverScrollBar) {\n const transformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType,\n }));\n return;\n }\n }\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n return;\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.showHyperlinkTooltip)(this.hitLinkElement, this.state);\n }\n else {\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.hideHyperlinkToolip)();\n if (hitElement &&\n hitElement.link &&\n this.state.selectedElementIds[hitElement.id] &&\n !this.state.contextMenu &&\n !this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: \"info\" });\n }\n else if (this.state.activeTool.type === \"text\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n }\n else if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.selectedLinearElement) {\n this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);\n }\n else if (\n // if using cmd/ctrl, we're not dragging\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((hitElement ||\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements)) &&\n !(hitElement === null || hitElement === void 0 ? void 0 : hitElement.locked)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n };\n this.handleEraser = (event, pointerDownState, scenePointer) => {\n const updateElementIds = (elements) => {\n elements.forEach((element) => {\n if (element.locked) {\n return;\n }\n idsToUpdate.push(element.id);\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[element.id] &&\n pointerDownState.elementIdsToErase[element.id].erase) {\n pointerDownState.elementIdsToErase[element.id].erase = false;\n }\n }\n else if (!pointerDownState.elementIdsToErase[element.id]) {\n pointerDownState.elementIdsToErase[element.id] = {\n erase: true,\n opacity: element.opacity,\n };\n }\n });\n };\n const idsToUpdate = [];\n const distance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);\n const threshold = 10 / this.state.zoom.value;\n const point = Object.assign({}, pointerDownState.lastCoords);\n let samplingInterval = 0;\n while (samplingInterval <= distance) {\n const hitElements = this.getElementsAtPosition(point.x, point.y);\n updateElementIds(hitElements);\n // Exit since we reached current point\n if (samplingInterval === distance) {\n break;\n }\n // Calculate next point in the line at a distance of sampling interval\n samplingInterval = Math.min(samplingInterval + threshold, distance);\n const distanceRatio = samplingInterval / distance;\n const nextX = (1 - distanceRatio) * point.x + distanceRatio * scenePointer.x;\n const nextY = (1 - distanceRatio) * point.y + distanceRatio * scenePointer.y;\n point.x = nextX;\n point.y = nextY;\n }\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n const id = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && idsToUpdate.includes(ele.containerId)\n ? ele.containerId\n : ele.id;\n if (idsToUpdate.includes(id)) {\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[id] &&\n pointerDownState.elementIdsToErase[id].erase === false) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[id].opacity,\n });\n }\n }\n else {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_READY_TO_ERASE_OPACITY,\n });\n }\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n pointerDownState.lastCoords.x = scenePointer.x;\n pointerDownState.lastCoords.y = scenePointer.y;\n };\n // set touch moving for mobile context menu\n this.handleTouchMove = (event) => {\n invalidateContextMenu = true;\n };\n this.handleCanvasPointerDown = (event) => {\n var _a, _b;\n // since contextMenu options are potentially evaluated on each render,\n // and an contextMenu action may depend on selection state, we must\n // close the contextMenu before we update the selection on pointerDown\n // (e.g. resetting selection)\n if (this.state.contextMenu) {\n this.setState({ contextMenu: null });\n }\n this.updateGestureOnPointerDown(event);\n // if dragging element is freedraw and another pointerdown event occurs\n // a second finger is on the screen\n // discard the freedraw element if it is very short because it is likely\n // just a spike, otherwise finalize the freedraw element when the second\n // finger is lifted\n if (event.pointerType === \"touch\" &&\n this.state.draggingElement &&\n this.state.draggingElement.type === \"freedraw\") {\n const element = this.state.draggingElement;\n this.updateScene(Object.assign(Object.assign({}, (element.points.length < 10\n ? {\n elements: this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== element.id),\n }\n : {})), { appState: {\n draggingElement: null,\n editingElement: null,\n startBoundElement: null,\n suggestedBindings: [],\n selectedElementIds: Object.keys(this.state.selectedElementIds)\n .filter((key) => key !== element.id)\n .reduce((obj, key) => {\n obj[key] = this.state.selectedElementIds[key];\n return obj;\n }, {}),\n } }));\n return;\n }\n // remove any active selection when we start to interact with canvas\n // (mainly, we care about removing selection outside the component which\n // would prevent our copy handling otherwise)\n const selection = document.getSelection();\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\n selection.removeAllRanges();\n }\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\n this.maybeCleanupAfterMissingPointerUp(event);\n //fires only once, if pen is detected, penMode is enabled\n //the user can disable this by toggling the penMode button\n if (!this.state.penDetected && event.pointerType === \"pen\") {\n this.setState((prevState) => {\n return {\n penMode: true,\n penDetected: true,\n };\n });\n }\n if (!this.device.isTouchScreen &&\n [\"pen\", \"touch\"].includes(event.pointerType)) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, { isTouchScreen: true });\n }\n if (isPanning) {\n return;\n }\n this.lastPointerDown = event;\n this.setState({\n lastPointerDownWith: event.pointerType,\n cursorButton: \"down\",\n });\n this.savePointer(event.clientX, event.clientY, \"down\");\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n }\n // only handle left mouse button or touch\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN &&\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.TOUCH) {\n return;\n }\n // don't select while panning\n if (gesture.pointers.size > 1) {\n return;\n }\n // State for the duration of a pointer interaction, which starts with a\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\n const pointerDownState = this.initialPointerDownState(event);\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\n return;\n }\n this.clearSelectionIfNotUsingSelection();\n this.updateBindingEnabledOnPointerMove(event);\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\n return;\n }\n const allowOnPointerDown = !this.state.penMode ||\n event.pointerType !== \"touch\" ||\n this.state.activeTool.type === \"selection\" ||\n this.state.activeTool.type === \"text\" ||\n this.state.activeTool.type === \"image\";\n if (!allowOnPointerDown) {\n return;\n }\n if (this.state.activeTool.type === \"text\") {\n this.handleTextOnPointerDown(event, pointerDownState);\n return;\n }\n else if (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\") {\n this.handleLinearElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"image\") {\n // reset image preview on pointerdown\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n // retrieve the latest element as the state may be stale\n const pendingImageElement = this.state.pendingImageElementId &&\n this.scene.getElement(this.state.pendingImageElementId);\n if (!pendingImageElement) {\n return;\n }\n this.setState({\n draggingElement: pendingImageElement,\n editingElement: pendingImageElement,\n pendingImageElementId: null,\n multiElement: null,\n });\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(pendingImageElement, {\n x,\n y,\n });\n }\n else if (this.state.activeTool.type === \"freedraw\") {\n this.handleFreeDrawElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"custom\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.activeTool.type !== \"eraser\" &&\n this.state.activeTool.type !== \"hand\") {\n this.createGenericElementOnPointerDown(this.state.activeTool.type, pointerDownState);\n }\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onPointerDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.activeTool, pointerDownState);\n this.onPointerDownEmitter.trigger(this.state.activeTool, pointerDownState, event);\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\n lastPointerUp = onPointerUp;\n if (!this.state.viewModeEnabled) {\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, onKeyDown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, onKeyUp);\n pointerDownState.eventListeners.onMove = onPointerMove;\n pointerDownState.eventListeners.onUp = onPointerUp;\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\n }\n };\n this.handleCanvasPointerUp = (event) => {\n this.lastPointerUp = event;\n if (this.device.isTouchScreen) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: event.clientX, clientY: event.clientY }, this.state);\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n this.redirectToLink(event, this.device.isTouchScreen);\n }\n this.removePointer(event);\n };\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\n // deal with opening context menu on touch devices\n if (event.pointerType === \"touch\") {\n invalidateContextMenu = false;\n if (touchTimeout) {\n // If there's already a touchTimeout, this means that there's another\n // touch down and we are doing another touch, so we shouldn't open the\n // context menu.\n invalidateContextMenu = true;\n }\n else {\n // open the context menu with the first touch's clientX and clientY\n // if the touch is not moving\n touchTimeout = window.setTimeout(() => {\n touchTimeout = 0;\n if (!invalidateContextMenu) {\n this.handleCanvasContextMenu(event);\n }\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.TOUCH_CTX_MENU_TIMEOUT);\n }\n }\n };\n this.resetContextMenuTimer = () => {\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n invalidateContextMenu = false;\n };\n // Returns whether the event is a panning\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\n if (!(gesture.pointers.size <= 1 &&\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.WHEEL ||\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state) ||\n this.state.viewModeEnabled)) ||\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return false;\n }\n isPanning = true;\n event.preventDefault();\n let nextPastePrevented = false;\n const isLinux = /Linux/.test(window.navigator.platform);\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n let { clientX: lastX, clientY: lastY } = event;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const deltaX = lastX - event.clientX;\n const deltaY = lastY - event.clientY;\n lastX = event.clientX;\n lastY = event.clientY;\n /*\n * Prevent paste event if we move while middle clicking on Linux.\n * See issue #1383.\n */\n if (isLinux &&\n !nextPastePrevented &&\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\n nextPastePrevented = true;\n /* Prevent the next paste event */\n const preventNextPaste = (event) => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n event.stopPropagation();\n };\n /*\n * Reenable next paste in case of disabled middle click paste for\n * any reason:\n * - right click paste\n * - empty clipboard\n */\n const enableNextPaste = () => {\n setTimeout(() => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }, 100);\n };\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }\n this.translateCanvas({\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\n });\n });\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\n lastPointerUp = null;\n isPanning = false;\n if (!isHoldingSpace) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n onPointerMove.flush();\n }));\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove, {\n passive: true,\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n return true;\n };\n this.clearSelectionIfNotUsingSelection = () => {\n if (this.state.activeTool.type !== \"selection\") {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n };\n /**\n * @returns whether the pointer event has been completely handled\n */\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\n var _a;\n if (this.state.activeTool.type === \"selection\") {\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType != null) {\n this.setState({\n resizingElement: elementWithTransformHandleType.element,\n });\n pointerDownState.resize.handleType =\n elementWithTransformHandleType.transformHandleType;\n }\n }\n else if (selectedElements.length > 1) {\n pointerDownState.resize.handleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n }\n if (pointerDownState.resize.handleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType: pointerDownState.resize.handleType,\n }));\n pointerDownState.resize.isResizing = true;\n pointerDownState.resize.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeOffsetXY)(pointerDownState.resize.handleType, selectedElements, pointerDownState.origin.x, pointerDownState.origin.y));\n if (selectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\n selectedElements[0].points.length === 2) {\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\n }\n }\n else {\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, this.history, pointerDownState.origin, linearElementEditor);\n if (ret.hitElement) {\n pointerDownState.hit.element = ret.hitElement;\n }\n if (ret.linearElementEditor) {\n this.setState({ selectedLinearElement: ret.linearElementEditor });\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: ret.linearElementEditor });\n }\n }\n if (ret.didAddPoint) {\n return true;\n }\n }\n // hitElement may already be set above, so check first\n pointerDownState.hit.element =\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n if (pointerDownState.hit.element) {\n // Early return if pointer is hitting link icon\n const hitLinkElement = this.getElementLinkAtPosition({\n x: pointerDownState.origin.x,\n y: pointerDownState.origin.y,\n }, pointerDownState.hit.element);\n if (hitLinkElement) {\n return false;\n }\n }\n // For overlapped elements one position may hit\n // multiple elements\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n const hitElement = pointerDownState.hit.element;\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n if ((hitElement === null || !someHitElementIsSelected) &&\n !event.shiftKey &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.clearSelection(hitElement);\n }\n if (this.state.editingLinearElement) {\n this.setState({\n selectedElementIds: {\n [this.state.editingLinearElement.elementId]: true,\n },\n });\n // If we click on something\n }\n else if (hitElement != null) {\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if (!this.state.selectedElementIds[hitElement.id]) {\n pointerDownState.hit.wasAddedToSelection = true;\n }\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\n // mark as not completely handled so as to allow dragging etc.\n return false;\n }\n // deselect if item is selected\n // if shift is not clicked, this will always return true\n // otherwise, it will trigger selection based on current\n // state of the box\n if (!this.state.selectedElementIds[hitElement.id]) {\n // if we are currently editing a group, exiting editing mode and deselect the group.\n if (this.state.editingGroupId &&\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n // Add hit element to selection. At this point if we're not holding\n // SHIFT the previously selected element(s) were deselected above\n // (make sure you use setState updater to use latest state)\n if (!someHitElementIsSelected &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.setState((prevState) => {\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }), showHyperlinkPopup: hitElement.link ? \"info\" : false }), this.scene.getNonDeletedElements());\n });\n pointerDownState.hit.wasAddedToSelection = true;\n }\n }\n }\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n }\n return false;\n };\n this.handleTextOnPointerDown = (event, pointerDownState) => {\n // if we're currently still editing text, clicking outside\n // should only finalize it, not create another (irrespective\n // of state.activeTool.locked)\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return;\n }\n let sceneX = pointerDownState.origin.x;\n let sceneY = pointerDownState.origin.y;\n const element = this.getElementAtPosition(sceneX, sceneY, {\n includeBoundTextElement: true,\n });\n let container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element)) {\n container = element;\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container,\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!this.state.activeTool.locked) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n };\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\n // Begin a mark capture. This does not have to update state yet.\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: null,\n simulatePressure: event.pressure === 0.5,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n const pressures = element.simulatePressure\n ? element.pressures\n : [...element.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [[0, 0]],\n pressures,\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n };\n this.createImageElement = ({ sceneX, sceneY, }) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\n type: \"image\",\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n roundness: null,\n opacity: this.state.currentItemOpacity,\n locked: false,\n });\n return element;\n };\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n // finalize if completing a loop\n if (multiElement.type === \"line\" &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\n // clicking inside commit zone → finalize arrow\n if (multiElement.points.length > 1 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\n }));\n // clicking outside commit zone → update reference for last committed\n // point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\n an arrow, we want it to be null for both. Otherwise, we want it to use the\n values from appState. */\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\n : [null, null];\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.state.currentItemRoundness === \"round\"\n ? { type: _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS }\n : null,\n startArrowhead,\n endArrowhead,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [...element.points, [0, 0]],\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n }\n };\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.state.currentItemRoundness === \"round\"\n ? {\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isUsingAdaptiveRadius)(elementType)\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.ADAPTIVE_RADIUS\n : _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS,\n }\n : null,\n locked: false,\n });\n if (element.type === \"selection\") {\n this.setState({\n selectionElement: element,\n draggingElement: element,\n });\n }\n else {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n multiElement: null,\n draggingElement: element,\n editingElement: element,\n });\n }\n };\n this.restoreReadyToEraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.id].opacity,\n });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.containerId].opacity,\n });\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n };\n this.eraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n return ele;\n });\n this.history.resumeRecording();\n this.scene.replaceAllElements(elements);\n };\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\n var _e, _f, _g, _h;\n // at this point this should be guaranteed image file, but we do this check\n // to satisfy TS down the line\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(imageFile)) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\n }\n const mimeType = imageFile.type;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.normalizeSVG)(yield imageFile.text()), imageFile.name);\n }\n catch (error) {\n console.warn(error);\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\n }\n }\n // generate image id (by default the file digest) before any\n // resizing/compression takes place to keep it more portable\n const fileId = yield (((_f = (_e = this.props).generateIdForFile) === null || _f === void 0 ? void 0 : _f.call(_e, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.generateIdFromFile)(imageFile));\n if (!fileId) {\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\n }\n const existingFileData = this.files[fileId];\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\n try {\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\n });\n }\n catch (error) {\n console.error(\"error trying to resing image file on insertion\", error);\n }\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\n }));\n }\n }\n if (showCursorImagePreview) {\n const dataURL = (_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL;\n // optimization so that we don't unnecessarily resize the original\n // full-size file for cursor preview\n // (it's much faster to convert the resized dataURL to File)\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.dataURLToFile)(dataURL);\n this.setImagePreviewCursor(resizedFile || imageFile);\n }\n const dataURL = ((_h = this.files[fileId]) === null || _h === void 0 ? void 0 : _h.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imageFile));\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\n fileId,\n }, false);\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n var _j;\n try {\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\n mimeType,\n id: fileId,\n dataURL,\n created: Date.now(),\n lastRetrieved: Date.now(),\n } });\n const cachedImageData = this.imageCache.get(fileId);\n if (!cachedImageData) {\n this.addNewImagesToImageCache();\n yield this.updateImageCache([imageElement]);\n }\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\n yield cachedImageData.image;\n }\n if (this.state.pendingImageElementId !== imageElement.id &&\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\n this.initializeImageDimensions(imageElement, true);\n }\n resolve(imageElement);\n }\n catch (error) {\n console.error(error);\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\n }\n finally {\n if (!showCursorImagePreview) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n }\n }));\n });\n /**\n * inserts image into elements array and rerenders\n */\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n imageElement,\n ]);\n try {\n yield this.initializeImage({\n imageFile,\n imageElement,\n showCursorImagePreview,\n });\n }\n catch (error) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n isDeleted: true,\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n this.setState({\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\n });\n }\n });\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\n // mustn't be larger than 128 px\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\n const cursorImageSizePx = 96;\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: cursorImageSizePx,\n });\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imagePreview);\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\n // a small canvas\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.loadHTMLImageElement)(previewDataURL);\n let height = Math.min(img.height, cursorImageSizePx);\n let width = height * (img.width / img.height);\n if (width > cursorImageSizePx) {\n width = cursorImageSizePx;\n height = width * (img.height / img.width);\n }\n const canvas = document.createElement(\"canvas\");\n canvas.height = height;\n canvas.width = width;\n const context = canvas.getContext(\"2d\");\n context.drawImage(img, 0, 0, width, height);\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg);\n }\n if (this.state.pendingImageElementId) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\n }\n });\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\n try {\n const clientX = this.state.width / 2 + this.state.offsetLeft;\n const clientY = this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_42__.fileOpen)({\n description: \"Image\",\n extensions: Object.keys(_constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_MIME_TYPES),\n });\n const imageElement = this.createImageElement({\n sceneX: x,\n sceneY: y,\n });\n if (insertOnCanvasDirectly) {\n this.insertImageElement(imageElement, imageFile);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: { [imageElement.id]: true },\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n else {\n this.setState({\n pendingImageElementId: imageElement.id,\n }, () => {\n this.insertImageElement(imageElement, imageFile, \n /* showCursorImagePreview */ true);\n });\n }\n }\n catch (error) {\n if (error.name !== \"AbortError\") {\n console.error(error);\n }\n else {\n console.warn(error);\n }\n this.setState({\n pendingImageElementId: null,\n editingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n });\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\n var _a;\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n if (!image || image instanceof Promise) {\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const placeholderSize = 100 / this.state.zoom.value;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x: imageElement.x - placeholderSize / 2,\n y: imageElement.y - placeholderSize / 2,\n width: placeholderSize,\n height: placeholderSize,\n });\n }\n return;\n }\n if (forceNaturalSize ||\n // if user-created bounding box is below threshold, assume the\n // intention was to click instead of drag, and use the image's\n // intrinsic size\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\n const minHeight = Math.max(this.state.height - 120, 160);\n // max 65% of canvas height, clamped to <300px, vh - 120px>\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\n const height = Math.min(image.naturalHeight, maxHeight);\n const width = height * (image.naturalWidth / image.naturalHeight);\n // add current imageElement width/height to account for previous centering\n // of the placeholder image\n const x = imageElement.x + imageElement.width / 2 - width / 2;\n const y = imageElement.y + imageElement.height / 2 - height / 2;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\n }\n };\n /** updates image cache, refreshing updated elements and/or setting status\n to error for images that fail during <img> element creation */\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.updateImageCache)({\n imageCache: this.imageCache,\n fileIds: elements.map((element) => element.fileId),\n files,\n });\n if (updatedFiles.size || erroredFiles.size) {\n for (const element of elements) {\n if (updatedFiles.has(element.fileId)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n }\n }\n if (erroredFiles.size) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n erroredFiles.has(element.fileId)) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n status: \"error\",\n });\n }\n return element;\n }));\n }\n return { updatedFiles, erroredFiles };\n });\n /** adds new images to imageCache and re-renders if needed */\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.getInitializedImageElements)(this.scene.getNonDeletedElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\n if (uncachedImageElements.length) {\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\n if (updatedFiles.size) {\n this.scene.informMutation();\n }\n }\n });\n /** generally you should use `addNewImagesToImageCache()` directly if you need\n * to render new images. This is just a failsafe */\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default()(() => {\n this.addNewImagesToImageCache();\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_RENDER_TIMEOUT);\n this.updateBindingEnabledOnPointerMove = (event) => {\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\n this.setState({ isBindingEnabled: shouldEnableBinding });\n }\n };\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\n this.setState({\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\n });\n };\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \n /** scene coords */\n pointerCoords, \n // During line creation the start binding hasn't been written yet\n // into `linearElement`\n oppositeBindingBoundElement) => {\n if (!pointerCoords.length) {\n return;\n }\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\n if (hoveredBindableElement != null &&\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\n acc.push(hoveredBindableElement);\n }\n return acc;\n }, []);\n this.setState({ suggestedBindings });\n };\n this.handleCanvasRef = (canvas) => {\n var _a, _b, _c;\n // canvas is null when unmounting\n if (canvas !== null) {\n this.canvas = canvas;\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__[\"default\"].canvas(this.canvas);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel, {\n passive: false,\n });\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n else {\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n };\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\n // must be retrieved first, in the same frame\n const { file, fileHandle } = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getFileFromEvent)(event);\n try {\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file)) {\n // first attempt to decode scene from the image if it's embedded\n // ---------------------------------------------------------------------\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_13__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n return;\n }\n catch (error) {\n if (error.name !== \"EncodingError\") {\n throw error;\n }\n }\n }\n // if no scene is embedded or we fail for whatever reason, fall back\n // to importing as regular image\n // ---------------------------------------------------------------------\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n }\n catch (error) {\n return this.setState({\n isLoading: false,\n errorMessage: error.message,\n });\n }\n const libraryJSON = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib);\n if (libraryJSON && typeof libraryJSON === \"string\") {\n try {\n const libraryItems = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.parseLibraryJSON)(libraryJSON);\n this.addElementsFromPasteOrLibrary({\n elements: (0,_data_library__WEBPACK_IMPORTED_MODULE_14__.distributeLibraryItemsOnSquareGrid)(libraryItems),\n position: event,\n files: null,\n });\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n return;\n }\n if (file) {\n // atetmpt to parse an excalidraw/excalidrawlib file\n yield this.loadFileToCanvas(file, fileHandle);\n }\n });\n this.loadFileToCanvas = (file, fileHandle) => __awaiter(this, void 0, void 0, function* () {\n file = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.normalizeFile)(file);\n try {\n const ret = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.loadSceneOrLibraryFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidraw) {\n this.setState({ isLoading: true });\n this.syncActionResult(Object.assign(Object.assign({}, ret.data), { appState: Object.assign(Object.assign({}, (ret.data.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n }\n else if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib) {\n yield this.library\n .updateLibrary({\n libraryItems: file,\n merge: true,\n openLibraryMenu: true,\n })\n .catch((error) => {\n console.error(error);\n this.setState({ errorMessage: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.importLibraryError\") });\n });\n }\n }\n catch (error) {\n this.setState({ isLoading: false, errorMessage: error.message });\n }\n });\n this.handleCanvasContextMenu = (event) => {\n event.preventDefault();\n if ((event.nativeEvent.pointerType === \"touch\" ||\n (event.nativeEvent.pointerType === \"pen\" &&\n // always allow if user uses a pen secondary button\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.SECONDARY)) &&\n this.state.activeTool.type !== \"selection\") {\n return;\n }\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const element = this.getElementAtPosition(x, y, {\n preferSelected: true,\n includeLockedElements: true,\n });\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const isHittignCommonBoundBox = this.isHittingCommonBoundingBoxOfSelectedElements({ x, y }, selectedElements);\n const type = element || isHittignCommonBoundBox ? \"element\" : \"canvas\";\n const container = this.excalidrawContainerRef.current;\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\n const left = event.clientX - offsetLeft;\n const top = event.clientY - offsetTop;\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"contextMenu\", \"openContextMenu\", type);\n this.setState(Object.assign(Object.assign({}, (element && !this.state.selectedElementIds[element.id]\n ? (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { selectedElementIds: { [element.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(element)\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(element, this.scene)\n : null }), this.scene.getNonDeletedElements())\n : this.state)), { showHyperlinkPopup: false }), () => {\n this.setState({\n contextMenu: { top, left, items: this.getContextMenuItems(type) },\n });\n });\n };\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\n var _a;\n const draggingElement = this.state.draggingElement;\n const pointerCoords = pointerDownState.lastCoords;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"selection\" &&\n this.state.activeTool.type !== \"eraser\") {\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.origin.x, pointerDownState.origin.y, pointerCoords.x, pointerCoords.y, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.x, pointerCoords.x), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.y, pointerCoords.y), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event));\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n const aspectRatio = image && !(image instanceof Promise)\n ? image.width / image.height\n : null;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.x, gridX), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.y, gridY), (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\n this.maybeSuggestBindingForAll([draggingElement]);\n }\n };\n this.maybeHandleResize = (pointerDownState, event) => {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const transformHandleType = pointerDownState.resize.handleType;\n this.setState({\n // TODO: rename this state field to \"isScaling\" to distinguish\n // it from the generic \"isResizing\" which includes scaling and\n // rotating\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\n isRotating: transformHandleType === \"rotation\",\n });\n const pointerCoords = pointerDownState.lastCoords;\n const [resizeX, resizeY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.y - pointerDownState.resize.offset.y, this.state.gridSize);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.transformElements)(pointerDownState, transformHandleType, selectedElements, pointerDownState.resize.arrowDirection, (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(selectedElements[0])\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\n this.maybeSuggestBindingForAll(selectedElements);\n return true;\n }\n return false;\n };\n this.getContextMenuItems = (type) => {\n const options = [];\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg);\n // canvas contextMenu\n // -------------------------------------------------------------------------\n if (type === \"canvas\") {\n if (this.state.viewModeEnabled) {\n return [\n ...options,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n }\n return [\n _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_49__.actionPaste,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg,\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll,\n _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_47__.actionUnlockAllElements,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n }\n // element contextMenu\n // -------------------------------------------------------------------------\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n if (this.state.viewModeEnabled) {\n return [_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options];\n }\n return [\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCut,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy,\n _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_49__.actionPaste,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n ...options,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText,\n _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_53__.actionWrapTextInContainer,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLinearEditor,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleElementLock,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected,\n ];\n };\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n if (isPanning) {\n return;\n }\n const { deltaX, deltaY } = event;\n // note that event.ctrlKey is necessary to handle pinch zooming\n if (event.metaKey || event.ctrlKey) {\n const sign = Math.sign(deltaY);\n const MAX_STEP = _constants__WEBPACK_IMPORTED_MODULE_12__.ZOOM_STEP * 100;\n const absDelta = Math.abs(deltaY);\n let delta = deltaY;\n if (absDelta > MAX_STEP) {\n delta = MAX_STEP * sign;\n }\n let newZoom = this.state.zoom.value - delta / 100;\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\n newZoom +=\n Math.log10(Math.max(1, this.state.zoom.value)) *\n -sign *\n // reduced amplification for small deltas (small movements on a trackpad)\n Math.min(1, absDelta / 20);\n this.translateCanvas((state) => (Object.assign(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom),\n }, state)), { shouldCacheIgnoreZoom: true })));\n this.resetShouldCacheIgnoreZoomDebounced();\n return;\n }\n // scroll horizontally when shift pressed\n if (event.shiftKey) {\n this.translateCanvas(({ zoom, scrollX }) => ({\n // on Mac, shift+wheel tends to result in deltaX\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\n }));\n return;\n }\n this.translateCanvas(({ zoom, scrollX, scrollY }) => ({\n scrollX: scrollX - deltaX / zoom.value,\n scrollY: scrollY - deltaY / zoom.value,\n }));\n });\n this.savePointer = (x, y, button) => {\n var _a, _b;\n if (!x || !y) {\n return;\n }\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\n // sometimes the pointer goes off screen\n }\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\n pointer,\n button,\n pointersMap: gesture.pointers,\n });\n };\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n if (!this.unmounted) {\n this.setState({ shouldCacheIgnoreZoom: false });\n }\n }, 300);\n this.updateDOMRect = (cb) => {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\n if (width === currentWidth &&\n height === currentHeight &&\n offsetLeft === currentOffsetLeft &&\n offsetTop === currentOffsetTop) {\n if (cb) {\n cb();\n }\n return;\n }\n this.setState({\n width,\n height,\n offsetLeft,\n offsetTop,\n }, () => {\n cb && cb();\n });\n }\n };\n this.refresh = () => {\n this.setState(Object.assign({}, this.getCanvasOffsets()));\n };\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)();\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight, showHyperlinkPopup: false, defaultSidebarDockedPreference: false });\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_56__.nanoid)();\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n if (excalidrawRef) {\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\n const api = {\n ready: true,\n readyPromise,\n updateScene: this.updateScene,\n updateLibrary: this.library.updateLibrary,\n addFiles: this.addFiles,\n resetScene: this.resetScene,\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\n history: {\n clear: this.resetHistory,\n },\n scrollToContent: this.scrollToContent,\n getSceneElements: this.getSceneElements,\n getAppState: () => this.state,\n getFiles: () => this.files,\n refresh: this.refresh,\n setToast: this.setToast,\n id: this.id,\n setActiveTool: this.setActiveTool,\n setCursor: this.setCursor,\n resetCursor: this.resetCursor,\n app: this,\n onChange: (cb) => this.onChangeEmitter.on(cb),\n onPointerDown: (cb) => this.onPointerDownEmitter.on(cb),\n onPointerUp: (cb) => this.onPointerUpEmitter.on(cb),\n toggleSidebar: this.toggleSidebar,\n };\n if (typeof excalidrawRef === \"function\") {\n excalidrawRef(api);\n }\n else {\n excalidrawRef.current = api;\n }\n readyPromise.resolve(api);\n }\n this.excalidrawContainerValue = {\n container: this.excalidrawContainerRef.current,\n id: this.id,\n };\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\n this.fonts = new _scene_Fonts__WEBPACK_IMPORTED_MODULE_48__.Fonts({\n scene: this.scene,\n onSceneUpdated: this.onSceneUpdated,\n });\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_8__.actions);\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createUndoAction)(this.history));\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createRedoAction)(this.history));\n }\n renderCanvas() {\n const canvasScale = window.devicePixelRatio;\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\n const canvasWidth = canvasDOMWidth * canvasScale;\n const canvasHeight = canvasDOMHeight * canvasScale;\n if (viewModeEnabled) {\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n cursor: _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n render() {\n var _a;\n const selectedElement = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const { renderTopRightUI, renderCustomStats } = this.props;\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw excalidraw-container\", {\n \"excalidraw--view-mode\": this.state.viewModeEnabled,\n \"excalidraw--zen-mode\": this.state.zenModeEnabled,\n \"excalidraw--mobile\": this.device.isMobile,\n }), ref: this.excalidrawContainerRef, onDrop: this.handleAppOnDrop, tabIndex: 0, onKeyDown: this.props.handleKeyboardGlobally ? undefined : this.onKeyDown }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppContext.Provider, Object.assign({ value: this }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppPropsContext.Provider, Object.assign({ value: this.props }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawContainerContext.Provider, Object.assign({ value: this.excalidrawContainerValue }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DeviceContext.Provider, Object.assign({ value: this.device }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawSetAppStateContext.Provider, Object.assign({ value: this.setAppState }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawAppStateContext.Provider, Object.assign({ value: this.state }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawElementsContext.Provider, Object.assign({ value: this.scene.getNonDeletedElements() }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ExcalidrawActionManagerContext.Provider, Object.assign({ value: this.actionManager }, { children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], Object.assign({ onExportImage: this.onExportImage, onHomeButtonClick: this.props.onHomeButtonClick || (() => { }), canvas: this.canvas, appState: this.state, files: this.files, setAppState: this.setAppState, actionManager: this.actionManager, elements: this.scene.getNonDeletedElements(), onLockToggle: this.toggleLock, onPenModeToggle: this.togglePenMode, onHandToolToggle: this.onHandToolToggle, langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, renderTopRightUI: renderTopRightUI, renderCustomStats: renderCustomStats, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\n this.state.zenModeEnabled, UIOptions: this.props.UIOptions, onImageAction: this.onImageAction, renderWelcomeScreen: !this.state.isLoading &&\n this.state.showWelcomeScreen &&\n this.state.activeTool.type === \"selection\" &&\n !this.scene.getElementsIncludingDeleted().length }, { children: this.props.children })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }), selectedElement.length === 1 &&\n !this.state.contextMenu &&\n this.state.showHyperlinkPopup && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.Hyperlink, { element: selectedElement[0], setAppState: this.setAppState, onLinkOpen: this.props.onLinkOpen }, selectedElement[0].id)), this.state.toast !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_37__.Toast, { message: this.state.toast.message, onClose: () => this.setToast(null), duration: this.state.toast.duration, closable: this.state.toast.closable })), this.state.contextMenu && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ContextMenu__WEBPACK_IMPORTED_MODULE_35__.ContextMenu, { items: this.state.contextMenu.items, top: this.state.contextMenu.top, left: this.state.contextMenu.left, actionManager: this.actionManager })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() })] })) })) })) })) })) })) })) })) })));\n }\n componentDidMount() {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n this.unmounted = false;\n this.excalidrawContainerValue.container =\n this.excalidrawContainerRef.current;\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT) {\n const setState = this.setState.bind(this);\n Object.defineProperties(window.h, {\n state: {\n configurable: true,\n get: () => {\n return this.state;\n },\n },\n setState: {\n configurable: true,\n value: (...args) => {\n return this.setState(...args);\n },\n },\n app: {\n configurable: true,\n value: this,\n },\n history: {\n configurable: true,\n value: this.history,\n },\n });\n }\n this.scene.addCallback(this.onSceneUpdated);\n this.addEventListeners();\n if (this.props.autoFocus && this.excalidrawContainerRef.current) {\n this.focusContainer();\n }\n if (this.excalidrawContainerRef.current &&\n // bounding rects don't work in tests so updating\n // the state on init would result in making the test enviro run\n // in mobile breakpoint (0 width/height), making everything fail\n \"development\" !== \"test\") {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\n this.resizeObserver = new ResizeObserver(() => {\n THROTTLE_NEXT_RENDER = false;\n // recompute device dimensions state\n // ---------------------------------------------------------------------\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n // refresh offsets\n // ---------------------------------------------------------------------\n this.updateDOMRect();\n });\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\n }\n else if (window.matchMedia) {\n const mdScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\n const smScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH}px)`);\n const canDeviceFitSidebarMediaQuery = window.matchMedia(`(min-width: ${\n // NOTE this won't update if a different breakpoint is supplied\n // after mount\n this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH}px)`);\n const handler = () => {\n this.excalidrawContainerRef.current.getBoundingClientRect();\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isSmScreen: smScreenQuery.matches,\n isMobile: mdScreenQuery.matches,\n canDeviceFitSidebar: canDeviceFitSidebarMediaQuery.matches,\n });\n };\n mdScreenQuery.addListener(handler);\n this.detachIsMobileMqHandler = () => mdScreenQuery.removeListener(handler);\n }\n const searchParams = new URLSearchParams(window.location.search.slice(1));\n if (searchParams.has(\"web-share-target\")) {\n // Obtain a file that was shared via the Web Share Target API.\n this.restoreFileFromShare();\n }\n else {\n this.updateDOMRect(this.initializeScene);\n }\n // note that this check seems to always pass in localhost\n if ((0,_constants__WEBPACK_IMPORTED_MODULE_12__.isBrave)() && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isMeasureTextSupported)()) {\n this.setState({\n errorMessage: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_54__[\"default\"], {}),\n });\n }\n });\n }\n componentWillUnmount() {\n var _a;\n this.files = {};\n this.imageCache.clear();\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n this.unmounted = true;\n this.removeEventListeners();\n this.scene.destroy();\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.clearRenderCache)();\n this.onChangeEmitter.destroy();\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n this.canvas = null;\n this.rc = null;\n // @ts-ignore\n this.excalidrawContainerRef.current = undefined;\n this.nearestScrollableContainer = undefined;\n this.excalidrawContainerValue = { container: null, id: \"unmounted\" };\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n }\n removeEventListeners() {\n var _a, _b, _c, _d, _e, _f, _g;\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel);\n (_b = this.nearestScrollableContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n (_f = (_e = document.fonts) === null || _e === void 0 ? void 0 : _e.removeEventListener) === null || _f === void 0 ? void 0 : _f.call(_e, \"loadingdone\", this.onFontsLoadingDone);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n (_g = this.detachIsMobileMqHandler) === null || _g === void 0 ? void 0 : _g.call(this);\n }\n addEventListeners() {\n var _a, _b, _c, _d, _e;\n this.removeEventListeners();\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer); // #3553\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel, { passive: false });\n if (this.props.handleKeyboardGlobally) {\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp, { passive: true });\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\n // rerender text elements on font load to fix #637 && #1553\n (_c = (_b = document.fonts) === null || _b === void 0 ? void 0 : _b.addEventListener) === null || _c === void 0 ? void 0 : _c.call(_b, \"loadingdone\", this.onFontsLoadingDone);\n // Safari-only desktop pinch zoom\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n if (this.state.viewModeEnabled) {\n return;\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n if (this.props.detectScroll) {\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n }\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_e = this.excalidrawContainerRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n }\n componentDidUpdate(prevProps, prevState) {\n var _a, _b, _c, _d, _e;\n if (!this.state.showWelcomeScreen &&\n !this.scene.getElementsIncludingDeleted().length) {\n this.setState({ showWelcomeScreen: true });\n }\n if (this.excalidrawContainerRef.current &&\n prevProps.UIOptions.dockedSidebarBreakpoint !==\n this.props.UIOptions.dockedSidebarBreakpoint) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (prevState.scrollX !== this.state.scrollX ||\n prevState.scrollY !== this.state.scrollY) {\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onScrollChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.scrollX, this.state.scrollY);\n }\n if (Object.keys(this.state.selectedElementIds).length &&\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n if (this.state.activeTool.type === \"eraser\" &&\n prevState.theme !== this.state.theme) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setEraserCursor)(this.canvas, this.state.theme);\n }\n // Hide hyperlink popup if shown when element type is not selection\n if (prevState.activeTool.type === \"selection\" &&\n this.state.activeTool.type !== \"selection\" &&\n this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n if (prevProps.langCode !== this.props.langCode) {\n this.updateLanguage();\n }\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\n }\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\n this.addEventListeners();\n this.deselectElements();\n }\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\n }\n if (prevProps.theme !== this.props.theme && this.props.theme) {\n this.setState({ theme: this.props.theme });\n }\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\n this.setState({\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null,\n });\n }\n if (!this.props.UIOptions.canvasActions &&\n this.state.openMenu === \"canvas\") {\n this.setState({\n openMenu: null,\n });\n }\n if (this.props.name && prevProps.name !== this.props.name) {\n this.setState({\n name: this.props.name,\n });\n }\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\n if (this.state.editingLinearElement &&\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\n // defer so that the commitToHistory flag isn't reset via current update\n setTimeout(() => {\n // execute only if the condition still holds when the deferred callback\n // executes (it can be scheduled multiple times depending on how\n // many times the component renders)\n this.state.editingLinearElement &&\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n if (this.state.selectedLinearElement &&\n !this.state.selectedElementIds[this.state.selectedLinearElement.elementId]) {\n // To make sure `selectedLinearElement` is in sync with `selectedElementIds`, however this shouldn't be needed once\n // we have a single API to update `selectedElementIds`\n this.setState({ selectedLinearElement: null });\n }\n const { multiElement } = prevState;\n if (prevState.activeTool !== this.state.activeTool &&\n multiElement != null &&\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(multiElement, this.state, this.scene, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)(_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1)));\n }\n this.renderScene();\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\n // Do not notify consumers if we're still loading the scene. Among other\n // potential issues, this fixes a case where the tab isn't focused during\n // init, which would trigger onChange with empty elements, which would then\n // override whatever is in localStorage currently.\n if (!this.state.isLoading) {\n (_e = (_d = this.props).onChange) === null || _e === void 0 ? void 0 : _e.call(_d, this.scene.getElementsIncludingDeleted(), this.state, this.files, this.props.id);\n this.onChangeEmitter.trigger(this.scene.getElementsIncludingDeleted(), this.state, this.files);\n }\n }\n static resetTapTwice() {\n didTapTwice = false;\n }\n addTextFromPaste(text, isPlainPaste = false) {\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const textElementProps = {\n x,\n y,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roundness: null,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text,\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: this.state.currentItemTextAlign,\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n locked: false,\n };\n const LINE_GAP = 10;\n let currentY = y;\n const lines = isPlainPaste ? [text] : text.split(\"\\n\");\n const textElements = lines.reduce((acc, line, idx) => {\n var _a;\n const text = line.trim();\n const lineHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(textElementProps.fontFamily);\n if (text.length) {\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)(Object.assign(Object.assign({}, textElementProps), { x, y: currentY, text,\n lineHeight }));\n acc.push(element);\n currentY += element.height + LINE_GAP;\n }\n else {\n const prevLine = (_a = lines[idx - 1]) === null || _a === void 0 ? void 0 : _a.trim();\n // add paragraph only if previous line was not empty, IOW don't add\n // more than one empty line\n if (prevLine) {\n currentY +=\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getLineHeightInPx)(textElementProps.fontSize, lineHeight) +\n LINE_GAP;\n }\n }\n return acc;\n }, []);\n if (textElements.length === 0) {\n return;\n }\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n ...textElements,\n ]);\n this.setState({\n selectedElementIds: Object.fromEntries(textElements.map((el) => [el.id, true])),\n });\n if (!isPlainPaste &&\n textElements.length > 1 &&\n PLAIN_PASTE_TOAST_SHOWN === false &&\n !this.device.isMobile) {\n this.setToast({\n message: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"toast.pasteAsSingleElement\", {\n shortcut: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getShortcutKey)(\"CtrlOrCmd+Shift+V\"),\n }),\n duration: 5000,\n });\n PLAIN_PASTE_TOAST_SHOWN = true;\n }\n this.history.resumeRecording();\n }\n handleTextWysiwyg(element, { isExistingElement = false, }) {\n const updateElement = (text, originalText, isDeleted) => {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted,\n originalText,\n });\n }\n return _element;\n }),\n ]);\n };\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\n id: element.id,\n canvas: this.canvas,\n getViewportCoords: (x, y) => {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: x,\n sceneY: y,\n }, this.state);\n return [\n viewportX - this.state.offsetLeft,\n viewportY - this.state.offsetTop,\n ];\n },\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\n updateElement(text, text, false);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\n }\n }),\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\n const isDeleted = !text.trim();\n updateElement(text, originalText, isDeleted);\n // select the created text element only if submitting via keyboard\n // (when submitting via click it should act as signal to deselect)\n if (!isDeleted && viaKeyboard) {\n const elementIdToSelect = element.containerId\n ? element.containerId\n : element.id;\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\n }));\n }\n if (isDeleted) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getNonDeletedElements(), [\n element,\n ]);\n }\n if (!isDeleted || isExistingElement) {\n this.history.resumeRecording();\n }\n this.setState({\n draggingElement: null,\n editingElement: null,\n });\n if (this.state.activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n this.focusContainer();\n }),\n element,\n excalidrawContainer: this.excalidrawContainerRef.current,\n app: this,\n });\n // deselect all other elements when inserting text\n this.deselectElements();\n // do an initial update to re-initialize element position since we were\n // modifying element's x/y for sake of editor (case: syncing to remote)\n updateElement(element.text, element.originalText, false);\n }\n deselectElements() {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n getTextElementAtPosition(x, y) {\n const element = this.getElementAtPosition(x, y, {\n includeBoundTextElement: true,\n });\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\n return element;\n }\n return null;\n }\n getElementAtPosition(x, y, opts) {\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement, opts === null || opts === void 0 ? void 0 : opts.includeLockedElements);\n if (allHitElements.length > 1) {\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\n for (let index = allHitElements.length - 1; index > -1; index--) {\n if (this.state.selectedElementIds[allHitElements[index].id]) {\n return allHitElements[index];\n }\n }\n }\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\n // If we're hitting element with highest z-index only on its bounding box\n // while also hitting other element figure, the latter should be considered.\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\n ? allHitElements[allHitElements.length - 2]\n : elementWithHighestZIndex;\n }\n if (allHitElements.length === 1) {\n return allHitElements[0];\n }\n return null;\n }\n getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {\n const elements = includeBoundTextElement && includeLockedElements\n ? this.scene.getNonDeletedElements()\n : this.scene\n .getNonDeletedElements()\n .filter((element) => (includeLockedElements || !element.locked) &&\n (includeBoundTextElement ||\n !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId)));\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\n }\n handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(linearElementEditor.elementId);\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(element);\n if (!element) {\n return;\n }\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\n let segmentMidPointHoveredCoords = null;\n if ((0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\n scenePointerX,\n scenePointerY,\n ])) {\n hoverPointIndex = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointIndexUnderCursor(element, this.state.zoom, scenePointerX, scenePointerY);\n segmentMidPointHoveredCoords =\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, { x: scenePointerX, y: scenePointerY }, this.state);\n if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n }\n else if ((0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_46__.shouldShowBoundingBox)([element], this.state) &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(element, this.state, scenePointerX, scenePointerY)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n else if (boundTextElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(boundTextElement, this.state, scenePointerX, scenePointerY)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { hoverPointIndex }),\n });\n }\n if (!_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.arePointsEqual(this.state.selectedLinearElement.segmentMidPointHoveredCoords, segmentMidPointHoveredCoords)) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { segmentMidPointHoveredCoords }),\n });\n }\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n maybeCleanupAfterMissingPointerUp(event) {\n if (lastPointerUp !== null) {\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\n // this can happen when a contextual menu or alert is triggered. In order to avoid\n // being in a weird state, we clean up on the next pointerdown\n lastPointerUp(event);\n }\n }\n updateGestureOnPointerDown(event) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n if (gesture.pointers.size === 2) {\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n gesture.initialScale = this.state.zoom.value;\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n }\n }\n initialPointerDownState(event) {\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return {\n origin,\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\n // we need to duplicate because we'll be updating this state\n lastCoords: Object.assign({}, origin),\n originalElements: this.scene\n .getNonDeletedElements()\n .reduce((acc, element) => {\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\n return acc;\n }, new Map()),\n resize: {\n handleType: false,\n isResizing: false,\n offset: { x: 0, y: 0 },\n arrowDirection: \"origin\",\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\n },\n hit: {\n element: null,\n allHitElements: [],\n wasAddedToSelection: false,\n hasBeenDuplicated: false,\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\n },\n drag: {\n hasOccurred: false,\n offset: null,\n },\n eventListeners: {\n onMove: null,\n onUp: null,\n onKeyUp: null,\n onKeyDown: null,\n },\n boxSelection: {\n hasOccurred: false,\n },\n elementIdsToErase: {},\n };\n }\n // Returns whether the event is a dragging a scrollbar\n handleDraggingScrollBar(event, pointerDownState) {\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\n return false;\n }\n isDraggingScrollBar = true;\n pointerDownState.lastCoords.x = event.clientX;\n pointerDownState.lastCoords.y = event.clientY;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\n });\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isDraggingScrollBar = false;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n lastPointerUp = null;\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n onPointerMove.flush();\n });\n lastPointerUp = onPointerUp;\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n return true;\n }\n isASelectedElement(hitElement) {\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\n }\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\n if (selectedElements.length < 2) {\n return false;\n }\n // How many pixels off the shape boundary we still consider a hit\n const threshold = 10 / this.state.zoom.value;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return (point.x > x1 - threshold &&\n point.x < x2 + threshold &&\n point.y > y1 - threshold &&\n point.y < y2 + threshold);\n }\n onKeyDownFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onKeyUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // Prevents focus from escaping excalidraw tab\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onPointerMoveFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n var _a;\n // We need to initialize dragOffsetXY only after we've updated\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\n // event handler should hopefully ensure we're already working with\n // the updated state.\n if (pointerDownState.drag.offset === null) {\n pointerDownState.drag.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getDragOffsetXY)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\n }\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\n return;\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.handleEraser(event, pointerDownState, pointerCoords);\n return;\n }\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n // for arrows/lines, don't start dragging until a given threshold\n // to ensure we don't create a 2-point arrow by mistake when\n // user clicks mouse in a way that it moves a tiny bit (thus\n // triggering pointermove)\n if (!pointerDownState.drag.hasOccurred &&\n (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\")) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) {\n return;\n }\n }\n if (pointerDownState.resize.isResizing) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n if (this.maybeHandleResize(pointerDownState, event)) {\n return true;\n }\n }\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n if (_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.shouldAddMidpoint(this.state.selectedLinearElement, pointerCoords, this.state)) {\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.addMidpoint(this.state.selectedLinearElement, pointerCoords, this.state);\n if (!ret) {\n return;\n }\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n if (this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { pointerDownState: ret.pointerDownState, selectedPointsIndices: ret.selectedPointsIndices }),\n });\n }\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), { pointerDownState: ret.pointerDownState, selectedPointsIndices: ret.selectedPointsIndices }),\n });\n }\n });\n return;\n }\n else if (linearElementEditor.pointerDownState.segmentMidpoint.value !== null &&\n !linearElementEditor.pointerDownState.segmentMidpoint.added) {\n return;\n }\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\n }, linearElementEditor);\n if (didDrag) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n pointerDownState.drag.hasOccurred = true;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), { isDragging: true }),\n });\n }\n if (!this.state.selectedLinearElement.isDragging) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { isDragging: true }),\n });\n }\n return;\n }\n }\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n const isSelectingPointsInLineEditor = this.state.editingLinearElement &&\n event.shiftKey &&\n this.state.editingLinearElement.elementId ===\n ((_a = pointerDownState.hit.element) === null || _a === void 0 ? void 0 : _a.id);\n if ((hasHitASelectedElement ||\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\n !isSelectingPointsInLineEditor) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.every((element) => element.locked)) {\n return;\n }\n // Marking that click was used for dragging to check\n // if elements should be deselected on pointerup\n pointerDownState.drag.hasOccurred = true;\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\n // it would have weird results (stuff jumping all over the screen)\n // Checking for editingElement to avoid jump while editing on mobile #6503\n if (selectedElements.length > 0 &&\n !pointerDownState.withCmdOrCtrl &&\n !this.state.editingElement) {\n const [dragX, dragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.drag.offset.x, pointerCoords.y - pointerDownState.drag.offset.y, this.state.gridSize);\n const [dragDistanceX, dragDistanceY] = [\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\n ];\n // We only drag in one direction if shift is pressed\n const lockDirection = event.shiftKey;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY, this.state);\n this.maybeSuggestBindingForAll(selectedElements);\n // We duplicate the selected element if alt is pressed on pointer move\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\n // Move the currently selected elements to the top of the z index stack, and\n // put the duplicates where the selected elements used to be.\n // (the origin point where the dragging started)\n pointerDownState.hit.hasBeenDuplicated = true;\n const nextElements = [];\n const elementsToAppend = [];\n const groupIdMap = new Map();\n const oldIdToDuplicatedId = new Map();\n const hitElement = pointerDownState.hit.element;\n const elements = this.scene.getElementsIncludingDeleted();\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\n for (const element of elements) {\n if (selectedElementIds.includes(element.id) ||\n // case: the state.selectedElementIds might not have been\n // updated yet by the time this mousemove event is fired\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n pointerDownState.hit.wasAddedToSelection)) {\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\n const [originDragX, originDragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x - pointerDownState.drag.offset.x, pointerDownState.origin.y - pointerDownState.drag.offset.y, this.state.gridSize);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\n x: duplicatedElement.x + (originDragX - dragX),\n y: duplicatedElement.y + (originDragY - dragY),\n });\n nextElements.push(duplicatedElement);\n elementsToAppend.push(element);\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\n }\n else {\n nextElements.push(element);\n }\n }\n const nextSceneElements = [...nextElements, ...elementsToAppend];\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\n this.scene.replaceAllElements(nextSceneElements);\n }\n return;\n }\n }\n // It is very important to read this.state within each move event,\n // otherwise we would read a stale one!\n const draggingElement = this.state.draggingElement;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"freedraw\") {\n const points = draggingElement.points;\n const dx = pointerCoords.x - draggingElement.x;\n const dy = pointerCoords.y - draggingElement.y;\n const lastPoint = points.length > 0 && points[points.length - 1];\n const discardPoint = lastPoint && lastPoint[0] === dx && lastPoint[1] === dy;\n if (!discardPoint) {\n const pressures = draggingElement.simulatePressure\n ? draggingElement.pressures\n : [...draggingElement.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n });\n }\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n pointerDownState.drag.hasOccurred = true;\n const points = draggingElement.points;\n let dx = gridX - draggingElement.x;\n let dy = gridY - draggingElement.y;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(draggingElement.x, draggingElement.y, pointerCoords.x, pointerCoords.y));\n }\n if (points.length === 1) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n });\n }\n else if (points.length === 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points.slice(0, -1), [dx, dy]],\n });\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n // When creating a linear element by dragging\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\n }\n }\n else {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n this.maybeDragNewGenericElement(pointerDownState, event);\n }\n if (this.state.activeTool.type === \"selection\") {\n pointerDownState.boxSelection.hasOccurred = true;\n const elements = this.scene.getNonDeletedElements();\n if (!event.shiftKey &&\n // allows for box-selecting points (without shift)\n !this.state.editingLinearElement &&\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\n [pointerDownState.hit.element.id]: true,\n } }), this.scene.getNonDeletedElements()));\n }\n else {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n }\n // box-select line editor points\n if (this.state.editingLinearElement) {\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\n // regular box-select\n }\n else {\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign(Object.assign({}, prevState.selectedElementIds), elementsWithinSelection.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {})), (pointerDownState.hit.element\n ? {\n // if using ctrl/cmd, select the hitElement only if we\n // haven't box-selected anything else\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\n }\n : null)), showHyperlinkPopup: elementsWithinSelection.length === 1 &&\n elementsWithinSelection[0].link\n ? \"info\"\n : false, \n // select linear element only when we haven't box-selected anything else\n selectedLinearElement: elementsWithinSelection.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(elementsWithinSelection[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(elementsWithinSelection[0], this.scene)\n : null }), this.scene.getNonDeletedElements()));\n }\n }\n });\n }\n // Returns whether the pointer move happened over either scrollbar\n handlePointerMoveOverScrollbars(event, pointerDownState) {\n if (pointerDownState.scrollbars.isOverHorizontal) {\n const x = event.clientX;\n const dx = x - pointerDownState.lastCoords.x;\n this.translateCanvas({\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\n });\n pointerDownState.lastCoords.x = x;\n return true;\n }\n if (pointerDownState.scrollbars.isOverVertical) {\n const y = event.clientY;\n const dy = y - pointerDownState.lastCoords.y;\n this.translateCanvas({\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\n });\n pointerDownState.lastCoords.y = y;\n return true;\n }\n return false;\n }\n onPointerUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\n var _a, _b, _c, _d, _e, _f;\n const { draggingElement, resizingElement, multiElement, activeTool, isResizing, isRotating, } = this.state;\n this.setState({\n isResizing: false,\n isRotating: false,\n resizingElement: null,\n selectionElement: null,\n cursorButton: \"up\",\n // text elements are reset on finalize, and resetting on pointerup\n // may cause issues with double taps\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? this.state.editingElement\n : null,\n });\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\n this.onPointerUpEmitter.trigger(this.state.activeTool, pointerDownState, childEvent);\n // Handle end of dragging a point of a linear element, might close a loop\n // and sets binding element\n if (this.state.editingLinearElement) {\n if (!pointerDownState.boxSelection.hasOccurred &&\n ((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\n this.state.editingLinearElement.elementId) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n else {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\n if (editingLinearElement !== this.state.editingLinearElement) {\n this.setState({\n editingLinearElement,\n suggestedBindings: [],\n });\n }\n }\n }\n else if (this.state.selectedLinearElement) {\n if (((_d = (_c = pointerDownState.hit) === null || _c === void 0 ? void 0 : _c.element) === null || _d === void 0 ? void 0 : _d.id) !==\n this.state.selectedLinearElement.elementId) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement to null if there is more than one element selected since we don't want to show linear element handles\n if (selectedELements.length > 1) {\n this.setState({ selectedLinearElement: null });\n }\n }\n else {\n const linearElementEditor = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state);\n const { startBindingElement, endBindingElement } = linearElementEditor;\n const element = this.scene.getElement(linearElementEditor.elementId);\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n if (linearElementEditor !== this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, linearElementEditor), { selectedPointsIndices: null }),\n suggestedBindings: [],\n });\n }\n }\n }\n lastPointerUp = null;\n if (pointerDownState.eventListeners.onMove) {\n pointerDownState.eventListeners.onMove.flush();\n }\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\n if (this.state.pendingImageElementId) {\n this.setState({ pendingImageElementId: null });\n }\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n const points = draggingElement.points;\n let dx = pointerCoords.x - draggingElement.x;\n let dy = pointerCoords.y - draggingElement.y;\n // Allows dots to avoid being flagged as infinitely small\n if (dx === points[0][0] && dy === points[0][1]) {\n dy += 0.0001;\n dx += 0.0001;\n }\n const pressures = draggingElement.simulatePressure\n ? []\n : [...draggingElement.pressures, childEvent.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n lastCommittedPoint: [dx, dy],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\n const imageElement = draggingElement;\n try {\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n catch (error) {\n console.error(error);\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== imageElement.id));\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n if (draggingElement.points.length > 1) {\n this.history.resumeRecording();\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n if (!pointerDownState.drag.hasOccurred &&\n draggingElement &&\n !multiElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [\n ...draggingElement.points,\n [\n pointerCoords.x - draggingElement.x,\n pointerCoords.y - draggingElement.y,\n ],\n ],\n });\n this.setState({\n multiElement: draggingElement,\n editingElement: this.state.draggingElement,\n });\n }\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\n }\n this.setState({ suggestedBindings: [], startBoundElement: null });\n if (!activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState((prevState) => ({\n draggingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, {\n type: \"selection\",\n }),\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(draggingElement, this.scene),\n }));\n }\n else {\n this.setState((prevState) => ({\n draggingElement: null,\n }));\n }\n }\n return;\n }\n if (activeTool.type !== \"selection\" &&\n draggingElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\n // remove invisible element which was added in onPointerDown\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\n this.setState({\n draggingElement: null,\n });\n return;\n }\n if (draggingElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\n }\n if (resizingElement) {\n this.history.resumeRecording();\n }\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== resizingElement.id));\n }\n // Code below handles selection when element(s) weren't\n // drag or added to selection on pointer down phase.\n const hitElement = pointerDownState.hit.element;\n if (((_e = this.state.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.elementId) !== (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement)) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement when no other element selected except\n // the one we've hit\n if (selectedELements.length === 1) {\n this.setState({\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene),\n });\n }\n }\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (draggedDistance === 0) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({\n clientX: this.lastPointerUp.clientX,\n clientY: this.lastPointerUp.clientY,\n }, this.state);\n const hitElements = this.getElementsAtPosition(scenePointer.x, scenePointer.y);\n hitElements.forEach((hitElement) => (pointerDownState.elementIdsToErase[hitElement.id] = {\n erase: true,\n opacity: hitElement.opacity,\n }));\n }\n this.eraseElements(pointerDownState);\n return;\n }\n else if (Object.keys(pointerDownState.elementIdsToErase).length) {\n this.restoreReadyToEraseElements(pointerDownState);\n }\n if (hitElement &&\n !pointerDownState.drag.hasOccurred &&\n !pointerDownState.hit.wasAddedToSelection &&\n // if we're editing a line, pointerup shouldn't switch selection if\n // box selected\n (!this.state.editingLinearElement ||\n !pointerDownState.boxSelection.hasOccurred)) {\n // when inside line editor, shift selects points instead\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\n if (this.state.selectedElementIds[hitElement.id]) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\n // We want to unselect all groups hitElement is part of\n // as well as all elements that are part of the groups\n // hitElement is part of\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), groupId))\n .map((element) => ({ [element.id]: false }))\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\n this.setState((_prevState) => ({\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\n .map((gId) => ({ [gId]: false }))\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\n }));\n // if not gragging a linear element point (outside editor)\n }\n else if (!((_f = this.state.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isDragging)) {\n // remove element from selection while\n // keeping prev elements selected\n this.setState((prevState) => {\n const newSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false });\n const newSelectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds }));\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds, \n // set selectedLinearElement only if thats the only element selected\n selectedLinearElement: newSelectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(newSelectedElements[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(newSelectedElements[0], this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements());\n });\n }\n }\n else {\n // add element to selection while\n // keeping prev elements selected\n this.setState((_prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\n }));\n }\n }\n else {\n this.setState((prevState) => {\n var _a;\n return (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement) &&\n // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.\n // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized\n ((_a = prevState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements())));\n });\n }\n }\n if (!pointerDownState.drag.hasOccurred &&\n !this.state.isResizing &&\n ((hitElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\n (!hitElement &&\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: null });\n }\n else {\n // Deselect selected elements\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n return;\n }\n if (!activeTool.locked &&\n activeTool.type !== \"freedraw\" &&\n draggingElement) {\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n }));\n }\n if (activeTool.type !== \"selection\" ||\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getNonDeletedElements(), this.state)) {\n this.history.resumeRecording();\n }\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state));\n }\n if (!activeTool.locked && activeTool.type !== \"freedraw\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n else {\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n });\n }\n });\n }\n maybeSuggestBindingForAll(selectedElements) {\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\n this.setState({ suggestedBindings });\n }\n clearSelection(hitElement) {\n this.setState((prevState) => ({\n selectedElementIds: {},\n selectedGroupIds: {},\n // Continue editing the same group if the user selected a different\n // element from it\n editingGroupId: prevState.editingGroupId &&\n hitElement != null &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\n ? prevState.editingGroupId\n : null,\n }));\n this.setState({\n selectedElementIds: {},\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n getTextWysiwygSnappedToCenterPosition(x, y, appState, container) {\n if (container) {\n let elementCenterX = container.x + container.width / 2;\n let elementCenterY = container.y + container.height / 2;\n const elementCenter = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, appState);\n if (elementCenter) {\n elementCenterX = elementCenter.x;\n elementCenterY = elementCenter.y;\n }\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_12__.TEXT_TO_CENTER_SNAP_THRESHOLD;\n if (isSnappedToCenter) {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\n return { viewportX, viewportY, elementCenterX, elementCenterY };\n }\n }\n }\n getCanvasOffsets() {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { left, top } = excalidrawContainer.getBoundingClientRect();\n return {\n offsetLeft: left,\n offsetTop: top,\n };\n }\n return {\n offsetLeft: 0,\n offsetTop: 0,\n };\n }\n updateLanguage() {\n return __awaiter(this, void 0, void 0, function* () {\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\n this.setAppState({});\n });\n }\n}\nApp.defaultProps = {\n // needed for tests to pass since we directly render App in many tests\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_UI_OPTIONS,\n};\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT) {\n window.h = window.h || {};\n Object.defineProperties(window.h, {\n elements: {\n configurable: true,\n get() {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.getElementsIncludingDeleted();\n },\n set(elements) {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.replaceAllElements(elements);\n },\n },\n });\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFDLElBQUksS0FBSyxXQUFXO1lBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQzdCO1lBQ0EsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDOUM7UUFDRCxJQUFJLFNBQVMsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDOUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxTQUFTLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztTQUNsRTtRQUVELElBQUksU0FBUyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtZQUM1RCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtRQUVELElBQUksU0FBUyxDQUFDLGNBQWMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRTtZQUMxRCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7U0FDaEU7UUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUU7WUFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDNUM7UUFFRCxJQUFJLFNBQVMsQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFl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UyxFQUFFLDJEQUFrQjtDQUM5QixDQUFDO0FBdXJNSixJQUNFLGFBQW9CLEtBQUssaURBQVE7SUFDakMsYUFBb0IsS0FBSyx3REFBZSxFQUN4QztJQUNBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsSUFBSyxFQUFrQixDQUFDO0lBRTNDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFO1FBQ2hDLFFBQVEsRUFBRTtZQUNSLFlBQVksRUFBRSxJQUFJO1lBQ2xCLEdBQUc7O2dCQUNELE9BQU8sVUFBSSxDQUFDLEdBQUcsMENBQUUsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUM7WUFDdkQsQ0FBQztZQUNELEdBQUcsQ0FBQyxRQUE2Qjs7Z0JBQy9CLE9BQU8sVUFBSSxDQUFDLEdBQUcsMENBQUUsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3RELENBQUM7U0FDRjtLQUNGLENBQUMsQ0FBQztDQUNKO0FBRUQsaUVBQWUsR0FBRyxFQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL2NvbXBvbmVudHMvQXBwLnRzeD8wMDcwIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCwgeyB1c2VDb250ZXh0IH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBmbHVzaFN5bmMgfSBmcm9tIFwicmVhY3QtZG9tXCI7XG5cbmltcG9ydCB7IFJvdWdoQ2FudmFzIH0gZnJvbSBcInJvdWdoanMvYmluL2NhbnZhc1wiO1xuaW1wb3J0IHJvdWdoIGZyb20gXCJyb3VnaGpzL2Jpbi9yb3VnaFwiO1xuaW1wb3J0IGNsc3ggZnJvbSBcImNsc3hcIjtcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gXCJuYW5vaWRcIjtcblxuaW1wb3J0IHtcbiAgYWN0aW9uQWRkVG9MaWJyYXJ5LFxuICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gIGFjdGlvbkJyaW5nVG9Gcm9udCxcbiAgYWN0aW9uQ29weSxcbiAgYWN0aW9uQ29weUFzUG5nLFxuICBhY3Rpb25Db3B5QXNTdmcsXG4gIGNvcHlUZXh0LFxuICBhY3Rpb25Db3B5U3R5bGVzLFxuICBhY3Rpb25DdXQsXG4gIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICBhY3Rpb25EdXBsaWNhdGVTZWxlY3Rpb24sXG4gIGFjdGlvbkZpbmFsaXplLFxuICBhY3Rpb25GbGlwSG9yaXpvbnRhbCxcbiAgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICBhY3Rpb25Hcm91cCxcbiAgYWN0aW9uUGFzdGVTdHlsZXMsXG4gIGFjdGlvblNlbGVjdEFsbCxcbiAgYWN0aW9uU2VuZEJhY2t3YXJkLFxuICBhY3Rpb25TZW5kVG9CYWNrLFxuICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gIGFjdGlvblVuYmluZFRleHQsXG4gIGFjdGlvbkJpbmRUZXh0LFxuICBhY3Rpb25Vbmdyb3VwLFxuICBhY3Rpb25MaW5rLFxuICBhY3Rpb25Ub2dnbGVFbGVtZW50TG9jayxcbiAgYWN0aW9uVG9nZ2xlTGluZWFyRWRpdG9yLFxufSBmcm9tIFwiLi4vYWN0aW9uc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVkb0FjdGlvbiwgY3JlYXRlVW5kb0FjdGlvbiB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvbkhpc3RvcnlcIjtcbmltcG9ydCB7IEFjdGlvbk1hbmFnZXIgfSBmcm9tIFwiLi4vYWN0aW9ucy9tYW5hZ2VyXCI7XG5pbXBvcnQgeyBhY3Rpb25zIH0gZnJvbSBcIi4uL2FjdGlvbnMvcmVnaXN0ZXJcIjtcbmltcG9ydCB7IEFjdGlvblJlc3VsdCB9IGZyb20gXCIuLi9hY3Rpb25zL3R5cGVzXCI7XG5pbXBvcnQgeyB0cmFja0V2ZW50IH0gZnJvbSBcIi4uL2FuYWx5dGljc1wiO1xuaW1wb3J0IHtcbiAgZ2V0RGVmYXVsdEFwcFN0YXRlLFxuICBpc0VyYXNlckFjdGl2ZSxcbiAgaXNIYW5kVG9vbEFjdGl2ZSxcbn0gZnJvbSBcIi4uL2FwcFN0YXRlXCI7XG5pbXBvcnQgeyBwYXJzZUNsaXBib2FyZCB9IGZyb20gXCIuLi9jbGlwYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFQUF9OQU1FLFxuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICBERUZBVUxUX1VJX09QVElPTlMsXG4gIERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gIERSQUdHSU5HX1RIUkVTSE9MRCxcbiAgRUxFTUVOVF9SRUFEWV9UT19FUkFTRV9PUEFDSVRZLFxuICBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRU5WLFxuICBFVkVOVCxcbiAgRVhQT1JUX0lNQUdFX1RZUEVTLFxuICBHUklEX1NJWkUsXG4gIElNQUdFX01JTUVfVFlQRVMsXG4gIElNQUdFX1JFTkRFUl9USU1FT1VULFxuICBpc0FuZHJvaWQsXG4gIGlzQnJhdmUsXG4gIExJTkVfQ09ORklSTV9USFJFU0hPTEQsXG4gIE1BWF9BTExPV0VEX0ZJTEVfQllURVMsXG4gIE1JTUVfVFlQRVMsXG4gIE1RX01BWF9IRUlHSFRfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfUE9SVFJBSVQsXG4gIE1RX1JJR0hUX1NJREVCQVJfTUlOX1dJRFRILFxuICBNUV9TTV9NQVhfV0lEVEgsXG4gIFBPSU5URVJfQlVUVE9OLFxuICBST1VORE5FU1MsXG4gIFNDUk9MTF9USU1FT1VULFxuICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgVEVYVF9UT19DRU5URVJfU05BUF9USFJFU0hPTEQsXG4gIFRIRU1FLFxuICBUT1VDSF9DVFhfTUVOVV9USU1FT1VULFxuICBWRVJUSUNBTF9BTElHTixcbiAgWk9PTV9TVEVQLFxufSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBleHBvcnRBc0ltYWdlLCBsb2FkRnJvbUJsb2IgfSBmcm9tIFwiLi4vZGF0YVwiO1xuaW1wb3J0IExpYnJhcnksIHsgZGlzdHJpYnV0ZUxpYnJhcnlJdGVtc09uU3F1YXJlR3JpZCB9IGZyb20gXCIuLi9kYXRhL2xpYnJhcnlcIjtcbmltcG9ydCB7IHJlc3RvcmUsIHJlc3RvcmVFbGVtZW50cyB9IGZyb20gXCIuLi9kYXRhL3Jlc3RvcmVcIjtcbmltcG9ydCB7XG4gIGRyYWdOZXdFbGVtZW50LFxuICBkcmFnU2VsZWN0ZWRFbGVtZW50cyxcbiAgZHVwbGljYXRlRWxlbWVudCxcbiAgZ2V0Q29tbW9uQm91bmRzLFxuICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQsXG4gIGdldERyYWdPZmZzZXRYWSxcbiAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLFxuICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyxcbiAgZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24sXG4gIGdldFJlc2l6ZU9mZnNldFhZLFxuICBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUsXG4gIGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzLFxuICBoaXRUZXN0LFxuICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQsXG4gIGlzSW52aXNpYmx5U21hbGxFbGVtZW50LFxuICBpc05vbkRlbGV0ZWRFbGVtZW50LFxuICBpc1RleHRFbGVtZW50LFxuICBuZXdFbGVtZW50LFxuICBuZXdMaW5lYXJFbGVtZW50LFxuICBuZXdUZXh0RWxlbWVudCxcbiAgbmV3SW1hZ2VFbGVtZW50LFxuICB0ZXh0V3lzaXd5ZyxcbiAgdHJhbnNmb3JtRWxlbWVudHMsXG4gIHVwZGF0ZVRleHRFbGVtZW50LFxuICByZWRyYXdUZXh0Qm91bmRpbmdCb3gsXG59IGZyb20gXCIuLi9lbGVtZW50XCI7XG5pbXBvcnQge1xuICBiaW5kT3JVbmJpbmRMaW5lYXJFbGVtZW50LFxuICBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzLFxuICBmaXhCaW5kaW5nc0FmdGVyRGVsZXRpb24sXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcsXG4gIGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyxcbiAgaXNCaW5kaW5nRW5hYmxlZCxcbiAgaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kLFxuICBtYXliZUJpbmRMaW5lYXJFbGVtZW50LFxuICBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50LFxuICB1bmJpbmRMaW5lYXJFbGVtZW50cyxcbiAgdXBkYXRlQm91bmRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvYmluZGluZ1wiO1xuaW1wb3J0IHsgTGluZWFyRWxlbWVudEVkaXRvciB9IGZyb20gXCIuLi9lbGVtZW50L2xpbmVhckVsZW1lbnRFZGl0b3JcIjtcbmltcG9ydCB7IG11dGF0ZUVsZW1lbnQsIG5ld0VsZW1lbnRXaXRoIH0gZnJvbSBcIi4uL2VsZW1lbnQvbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgZGVlcENvcHlFbGVtZW50LFxuICBkdXBsaWNhdGVFbGVtZW50cyxcbiAgbmV3RnJlZURyYXdFbGVtZW50LFxufSBmcm9tIFwiLi4vZWxlbWVudC9uZXdFbGVtZW50XCI7XG5pbXBvcnQge1xuICBoYXNCb3VuZFRleHRFbGVtZW50LFxuICBpc0Fycm93RWxlbWVudCxcbiAgaXNCaW5kaW5nRWxlbWVudCxcbiAgaXNCaW5kaW5nRWxlbWVudFR5cGUsXG4gIGlzQm91bmRUb0NvbnRhaW5lcixcbiAgaXNJbWFnZUVsZW1lbnQsXG4gIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQsXG4gIGlzTGluZWFyRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50VHlwZSxcbiAgaXNVc2luZ0FkYXB0aXZlUmFkaXVzLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlQ2hlY2tzXCI7XG5pbXBvcnQge1xuICBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50LFxuICBFeGNhbGlkcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0ZyZWVEcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50LFxuICBFeGNhbGlkcmF3TGluZWFyRWxlbWVudCxcbiAgRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICBOb25EZWxldGVkLFxuICBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEZpbGVJZCxcbiAgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3VGV4dENvbnRhaW5lcixcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IGdldENlbnRlciwgZ2V0RGlzdGFuY2UgfSBmcm9tIFwiLi4vZ2VzdHVyZVwiO1xuaW1wb3J0IHtcbiAgZWRpdEdyb3VwRm9yU2VsZWN0ZWRFbGVtZW50LFxuICBnZXRFbGVtZW50c0luR3JvdXAsXG4gIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQsXG4gIGdldFNlbGVjdGVkR3JvdXBJZHMsXG4gIGlzRWxlbWVudEluR3JvdXAsXG4gIGlzU2VsZWN0ZWRWaWFHcm91cCxcbiAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2dyb3Vwc1wiO1xuaW1wb3J0IEhpc3RvcnkgZnJvbSBcIi4uL2hpc3RvcnlcIjtcbmltcG9ydCB7IGRlZmF1bHRMYW5nLCBnZXRMYW5ndWFnZSwgbGFuZ3VhZ2VzLCBzZXRMYW5ndWFnZSwgdCB9IGZyb20gXCIuLi9pMThuXCI7XG5pbXBvcnQge1xuICBDT0RFUyxcbiAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcixcbiAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyxcbiAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUsXG4gIGlzQXJyb3dLZXksXG4gIEtFWVMsXG59IGZyb20gXCIuLi9rZXlzXCI7XG5pbXBvcnQgeyBkaXN0YW5jZTJkLCBnZXRHcmlkUG9pbnQsIGlzUGF0aEFMb29wIH0gZnJvbSBcIi4uL21hdGhcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lIH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlclNjZW5lXCI7XG5pbXBvcnQge1xuICBjbGVhclJlbmRlckNhY2hlLFxuICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50LFxufSBmcm9tIFwiLi4vcmVuZGVyZXIvcmVuZGVyRWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgY2FsY3VsYXRlU2Nyb2xsQ2VudGVyLFxuICBnZXRFbGVtZW50c0F0UG9zaXRpb24sXG4gIGdldEVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLFxuICBnZXROb3JtYWxpemVkWm9vbSxcbiAgZ2V0U2VsZWN0ZWRFbGVtZW50cyxcbiAgaGFzQmFja2dyb3VuZCxcbiAgaXNPdmVyU2Nyb2xsQmFycyxcbiAgaXNTb21lRWxlbWVudFNlbGVjdGVkLFxufSBmcm9tIFwiLi4vc2NlbmVcIjtcbmltcG9ydCBTY2VuZSBmcm9tIFwiLi4vc2NlbmUvU2NlbmVcIjtcbmltcG9ydCB7IFJlbmRlckNvbmZpZywgU2Nyb2xsQmFycyB9IGZyb20gXCIuLi9zY2VuZS90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0U3RhdGVGb3Jab29tIH0gZnJvbSBcIi4uL3NjZW5lL3pvb21cIjtcbmltcG9ydCB7IGZpbmRTaGFwZUJ5S2V5LCBTSEFQRVMgfSBmcm9tIFwiLi4vc2hhcGVzXCI7XG5pbXBvcnQge1xuICBBcHBDbGFzc1Byb3BlcnRpZXMsXG4gIEFwcFByb3BzLFxuICBBcHBTdGF0ZSxcbiAgQmluYXJ5RmlsZURhdGEsXG4gIERhdGFVUkwsXG4gIEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJLFxuICBCaW5hcnlGaWxlcyxcbiAgR2VzdHVyZSxcbiAgR2VzdHVyZUV2ZW50LFxuICBMaWJyYXJ5SXRlbXMsXG4gIFBvaW50ZXJEb3duU3RhdGUsXG4gIFNjZW5lRGF0YSxcbiAgRGV2aWNlLFxuICBTaWRlYmFyTmFtZSxcbiAgU2lkZWJhclRhYk5hbWUsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZGVib3VuY2UsXG4gIGRpc3RhbmNlLFxuICBnZXRGb250U3RyaW5nLFxuICBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcixcbiAgaXNJbnB1dExpa2UsXG4gIGlzVG9vbEljb24sXG4gIGlzV3JpdGFibGVFbGVtZW50LFxuICByZXNldEN1cnNvcixcbiAgcmVzb2x2YWJsZVByb21pc2UsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyxcbiAgc2V0Q3Vyc29yLFxuICBzZXRDdXJzb3JGb3JTaGFwZSxcbiAgdHVwbGVUb0Nvb3JzLFxuICB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMsXG4gIHdpdGhCYXRjaGVkVXBkYXRlcyxcbiAgd3JhcEV2ZW50LFxuICB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQsXG4gIHVwZGF0ZU9iamVjdCxcbiAgc2V0RXJhc2VyQ3Vyc29yLFxuICB1cGRhdGVBY3RpdmVUb29sLFxuICBnZXRTaG9ydGN1dEtleSxcbiAgaXNUcmFuc3BhcmVudCxcbiAgZWFzZVRvVmFsdWVzUkFGLFxuICBtdXRlRlNBYm9ydEVycm9yLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7XG4gIENvbnRleHRNZW51LFxuICBDb250ZXh0TWVudUl0ZW1zLFxuICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxufSBmcm9tIFwiLi9Db250ZXh0TWVudVwiO1xuaW1wb3J0IExheWVyVUkgZnJvbSBcIi4vTGF5ZXJVSVwiO1xuaW1wb3J0IHsgVG9hc3QgfSBmcm9tIFwiLi9Ub2FzdFwiO1xuaW1wb3J0IHsgYWN0aW9uVG9nZ2xlVmlld01vZGUgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25Ub2dnbGVWaWV3TW9kZVwiO1xuaW1wb3J0IHtcbiAgZGF0YVVSTFRvRmlsZSxcbiAgZ2VuZXJhdGVJZEZyb21GaWxlLFxuICBnZXREYXRhVVJMLFxuICBnZXRGaWxlRnJvbUV2ZW50LFxuICBpc0ltYWdlRmlsZUhhbmRsZSxcbiAgaXNTdXBwb3J0ZWRJbWFnZUZpbGUsXG4gIGxvYWRTY2VuZU9yTGlicmFyeUZyb21CbG9iLFxuICBub3JtYWxpemVGaWxlLFxuICBwYXJzZUxpYnJhcnlKU09OLFxuICByZXNpemVJbWFnZUZpbGUsXG4gIFNWR1N0cmluZ1RvRmlsZSxcbn0gZnJvbSBcIi4uL2RhdGEvYmxvYlwiO1xuaW1wb3J0IHtcbiAgZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzLFxuICBsb2FkSFRNTEltYWdlRWxlbWVudCxcbiAgbm9ybWFsaXplU1ZHLFxuICB1cGRhdGVJbWFnZUNhY2hlIGFzIF91cGRhdGVJbWFnZUNhY2hlLFxufSBmcm9tIFwiLi4vZWxlbWVudC9pbWFnZVwiO1xuaW1wb3J0IHRocm90dGxlIGZyb20gXCJsb2Rhc2gudGhyb3R0bGVcIjtcbmltcG9ydCB7IGZpbGVPcGVuLCBGaWxlU3lzdGVtSGFuZGxlIH0gZnJvbSBcIi4uL2RhdGEvZmlsZXN5c3RlbVwiO1xuaW1wb3J0IHtcbiAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0QXBwcm94TWluTGluZUhlaWdodCxcbiAgZ2V0QXBwcm94TWluTGluZVdpZHRoLFxuICBnZXRCb3VuZFRleHRFbGVtZW50LFxuICBnZXRDb250YWluZXJDZW50ZXIsXG4gIGdldENvbnRhaW5lckRpbXMsXG4gIGdldENvbnRhaW5lckVsZW1lbnQsXG4gIGdldERlZmF1bHRMaW5lSGVpZ2h0LFxuICBnZXRMaW5lSGVpZ2h0SW5QeCxcbiAgZ2V0VGV4dEJpbmRhYmxlQ29udGFpbmVyQXRQb3NpdGlvbixcbiAgaXNNZWFzdXJlVGV4dFN1cHBvcnRlZCxcbiAgaXNWYWxpZFRleHRDb250YWluZXIsXG59IGZyb20gXCIuLi9lbGVtZW50L3RleHRFbGVtZW50XCI7XG5pbXBvcnQgeyBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveCB9IGZyb20gXCIuLi9lbGVtZW50L2NvbGxpc2lvblwiO1xuaW1wb3J0IHtcbiAgbm9ybWFsaXplTGluayxcbiAgc2hvd0h5cGVybGlua1Rvb2x0aXAsXG4gIGhpZGVIeXBlcmxpbmtUb29saXAsXG4gIEh5cGVybGluayxcbiAgaXNQb2ludEhpdHRpbmdMaW5rSWNvbixcbiAgaXNMb2NhbExpbmssXG59IGZyb20gXCIuLi9lbGVtZW50L0h5cGVybGlua1wiO1xuaW1wb3J0IHsgc2hvdWxkU2hvd0JvdW5kaW5nQm94IH0gZnJvbSBcIi4uL2VsZW1lbnQvdHJhbnNmb3JtSGFuZGxlc1wiO1xuaW1wb3J0IHsgYWN0aW9uVW5sb2NrQWxsRWxlbWVudHMgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25FbGVtZW50TG9ja1wiO1xuaW1wb3J0IHsgRm9udHMgfSBmcm9tIFwiLi4vc2NlbmUvRm9udHNcIjtcbmltcG9ydCB7IGFjdGlvblBhc3RlIH0gZnJvbSBcIi4uL2FjdGlvbnMvYWN0aW9uQ2xpcGJvYXJkXCI7XG5pbXBvcnQge1xuICBhY3Rpb25Ub2dnbGVIYW5kVG9vbCxcbiAgem9vbVRvRml0RWxlbWVudHMsXG59IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvbkNhbnZhc1wiO1xuaW1wb3J0IHsgam90YWlTdG9yZSB9IGZyb20gXCIuLi9qb3RhaVwiO1xuaW1wb3J0IHsgYWN0aXZlQ29uZmlybURpYWxvZ0F0b20gfSBmcm9tIFwiLi9BY3RpdmVDb25maXJtRGlhbG9nXCI7XG5pbXBvcnQgeyBhY3Rpb25XcmFwVGV4dEluQ29udGFpbmVyIH0gZnJvbSBcIi4uL2FjdGlvbnMvYWN0aW9uQm91bmRUZXh0XCI7XG5pbXBvcnQgQnJhdmVNZWFzdXJlVGV4dEVycm9yIGZyb20gXCIuL0JyYXZlTWVhc3VyZVRleHRFcnJvclwiO1xuaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi9lbWl0dGVyXCI7XG5cbmNvbnN0IEFwcENvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PEFwcENsYXNzUHJvcGVydGllcz4obnVsbCEpO1xuY29uc3QgQXBwUHJvcHNDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxBcHBQcm9wcz4obnVsbCEpO1xuXG5jb25zdCBkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlID0ge1xuICBpc1NtU2NyZWVuOiBmYWxzZSxcbiAgaXNNb2JpbGU6IGZhbHNlLFxuICBpc1RvdWNoU2NyZWVuOiBmYWxzZSxcbiAgY2FuRGV2aWNlRml0U2lkZWJhcjogZmFsc2UsXG4gIGlzTGFuZHNjYXBlOiBmYWxzZSxcbn07XG5jb25zdCBEZXZpY2VDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxEZXZpY2U+KGRldmljZUNvbnRleHRJbml0aWFsVmFsdWUpO1xuRGV2aWNlQ29udGV4dC5kaXNwbGF5TmFtZSA9IFwiRGV2aWNlQ29udGV4dFwiO1xuXG5leHBvcnQgY29uc3QgRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PHtcbiAgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG4gIGlkPzogc3RyaW5nIHwgbnVsbDtcbn0+KHsgY29udGFpbmVyOiBudWxsLCBpZDogbnVsbCB9KTtcbkV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0LmRpc3BsYXlOYW1lID0gXCJFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dFwiO1xuXG5jb25zdCBFeGNhbGlkcmF3RWxlbWVudHNDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxcbiAgcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W11cbj4oW10pO1xuRXhjYWxpZHJhd0VsZW1lbnRzQ29udGV4dC5kaXNwbGF5TmFtZSA9IFwiRXhjYWxpZHJhd0VsZW1lbnRzQ29udGV4dFwiO1xuXG5jb25zdCBFeGNhbGlkcmF3QXBwU3RhdGVDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxBcHBTdGF0ZT4oe1xuICAuLi5nZXREZWZhdWx0QXBwU3RhdGUoKSxcbiAgd2lkdGg6IDAsXG4gIGhlaWdodDogMCxcbiAgb2Zmc2V0TGVmdDogMCxcbiAgb2Zmc2V0VG9wOiAwLFxufSk7XG5FeGNhbGlkcmF3QXBwU3RhdGVDb250ZXh0LmRpc3BsYXlOYW1lID0gXCJFeGNhbGlkcmF3QXBwU3RhdGVDb250ZXh0XCI7XG5cbmNvbnN0IEV4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PFxuICBSZWFjdC5Db21wb25lbnQ8YW55LCBBcHBTdGF0ZT5bXCJzZXRTdGF0ZVwiXVxuPigoKSA9PiB7XG4gIGNvbnNvbGUud2FybihcInVuaXRpYWxpemVkIEV4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHQgY29udGV4dCFcIik7XG59KTtcbkV4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHQuZGlzcGxheU5hbWUgPSBcIkV4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHRcIjtcblxuY29uc3QgRXhjYWxpZHJhd0FjdGlvbk1hbmFnZXJDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxBY3Rpb25NYW5hZ2VyPihcbiAgbnVsbCEsXG4pO1xuRXhjYWxpZHJhd0FjdGlvbk1hbmFnZXJDb250ZXh0LmRpc3BsYXlOYW1lID0gXCJFeGNhbGlkcmF3QWN0aW9uTWFuYWdlckNvbnRleHRcIjtcblxuZXhwb3J0IGNvbnN0IHVzZUFwcCA9ICgpID0+IHVzZUNvbnRleHQoQXBwQ29udGV4dCk7XG5leHBvcnQgY29uc3QgdXNlQXBwUHJvcHMgPSAoKSA9PiB1c2VDb250ZXh0KEFwcFByb3BzQ29udGV4dCk7XG5leHBvcnQgY29uc3QgdXNlRGV2aWNlID0gKCkgPT4gdXNlQ29udGV4dDxEZXZpY2U+KERldmljZUNvbnRleHQpO1xuZXhwb3J0IGNvbnN0IHVzZUV4Y2FsaWRyYXdDb250YWluZXIgPSAoKSA9PlxuICB1c2VDb250ZXh0KEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0KTtcbmV4cG9ydCBjb25zdCB1c2VFeGNhbGlkcmF3RWxlbWVudHMgPSAoKSA9PlxuICB1c2VDb250ZXh0KEV4Y2FsaWRyYXdFbGVtZW50c0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IHVzZUV4Y2FsaWRyYXdBcHBTdGF0ZSA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0FwcFN0YXRlQ29udGV4dCk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd1NldEFwcFN0YXRlID0gKCkgPT5cbiAgdXNlQ29udGV4dChFeGNhbGlkcmF3U2V0QXBwU3RhdGVDb250ZXh0KTtcbmV4cG9ydCBjb25zdCB1c2VFeGNhbGlkcmF3QWN0aW9uTWFuYWdlciA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0FjdGlvbk1hbmFnZXJDb250ZXh0KTtcblxubGV0IGRpZFRhcFR3aWNlOiBib29sZWFuID0gZmFsc2U7XG5sZXQgdGFwcGVkVHdpY2VUaW1lciA9IDA7XG5sZXQgY3Vyc29yWCA9IDA7XG5sZXQgY3Vyc29yWSA9IDA7XG5sZXQgaXNIb2xkaW5nU3BhY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBpc1Bhbm5pbmc6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBpc0RyYWdnaW5nU2Nyb2xsQmFyOiBib29sZWFuID0gZmFsc2U7XG5sZXQgY3VycmVudFNjcm9sbEJhcnM6IFNjcm9sbEJhcnMgPSB7IGhvcml6b250YWw6IG51bGwsIHZlcnRpY2FsOiBudWxsIH07XG5sZXQgdG91Y2hUaW1lb3V0ID0gMDtcbmxldCBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcblxuLy8gcmVtb3ZlIHRoaXMgaGFjayB3aGVuIHdlIGNhbiBzeW5jIHJlbmRlciAmIHJlc2l6ZU9ic2VydmVyIChzdGF0ZSB1cGRhdGUpXG4vLyB0byByQUYuIFNlZSAjNTQzOVxubGV0IFRIUk9UVExFX05FWFRfUkVOREVSID0gdHJ1ZTtcblxubGV0IElTX1BMQUlOX1BBU1RFID0gZmFsc2U7XG5sZXQgSVNfUExBSU5fUEFTVEVfVElNRVIgPSAwO1xubGV0IFBMQUlOX1BBU1RFX1RPQVNUX1NIT1dOID0gZmFsc2U7XG5cbmxldCBsYXN0UG9pbnRlclVwOiAoKGV2ZW50OiBhbnkpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5jb25zdCBnZXN0dXJlOiBHZXN0dXJlID0ge1xuICBwb2ludGVyczogbmV3IE1hcCgpLFxuICBsYXN0Q2VudGVyOiBudWxsLFxuICBpbml0aWFsRGlzdGFuY2U6IG51bGwsXG4gIGluaXRpYWxTY2FsZTogbnVsbCxcbn07XG5cbmNsYXNzIEFwcCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxBcHBQcm9wcywgQXBwU3RhdGU+IHtcbiAgY2FudmFzOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJjYW52YXNcIl0gPSBudWxsO1xuICByYzogUm91Z2hDYW52YXMgfCBudWxsID0gbnVsbDtcbiAgdW5tb3VudGVkOiBib29sZWFuID0gZmFsc2U7XG4gIGFjdGlvbk1hbmFnZXI6IEFjdGlvbk1hbmFnZXI7XG4gIGRldmljZTogRGV2aWNlID0gZGV2aWNlQ29udGV4dEluaXRpYWxWYWx1ZTtcbiAgZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXI/OiAoKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgZXhjYWxpZHJhd0NvbnRhaW5lclJlZiA9IFJlYWN0LmNyZWF0ZVJlZjxIVE1MRGl2RWxlbWVudD4oKTtcblxuICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wczogUGFydGlhbDxBcHBQcm9wcz4gPSB7XG4gICAgLy8gbmVlZGVkIGZvciB0ZXN0cyB0byBwYXNzIHNpbmNlIHdlIGRpcmVjdGx5IHJlbmRlciBBcHAgaW4gbWFueSB0ZXN0c1xuICAgIFVJT3B0aW9uczogREVGQVVMVF9VSV9PUFRJT05TLFxuICB9O1xuXG4gIHB1YmxpYyBzY2VuZTogU2NlbmU7XG4gIHByaXZhdGUgZm9udHM6IEZvbnRzO1xuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBuZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBEb2N1bWVudCB8IHVuZGVmaW5lZDtcbiAgcHVibGljIGxpYnJhcnk6IEFwcENsYXNzUHJvcGVydGllc1tcImxpYnJhcnlcIl07XG4gIHB1YmxpYyBsaWJyYXJ5SXRlbXNGcm9tU3RvcmFnZTogTGlicmFyeUl0ZW1zIHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBoaXN0b3J5OiBIaXN0b3J5O1xuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZToge1xuICAgIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICAgIGlkOiBzdHJpbmc7XG4gIH07XG5cbiAgcHVibGljIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHt9O1xuICBwdWJsaWMgaW1hZ2VDYWNoZTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiaW1hZ2VDYWNoZVwiXSA9IG5ldyBNYXAoKTtcblxuICBoaXRMaW5rRWxlbWVudD86IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudDtcbiAgbGFzdFBvaW50ZXJEb3duOiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+IHwgbnVsbCA9IG51bGw7XG4gIGxhc3RQb2ludGVyVXA6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MRWxlbWVudD4gfCBQb2ludGVyRXZlbnQgfCBudWxsID0gbnVsbDtcbiAgbGFzdFNjZW5lUG9pbnRlcjogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHwgbnVsbCA9IG51bGw7XG5cbiAgb25DaGFuZ2VFbWl0dGVyID0gbmV3IEVtaXR0ZXI8XG4gICAgW1xuICAgICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICAgICBmaWxlczogQmluYXJ5RmlsZXMsXG4gICAgXVxuICA+KCk7XG5cbiAgb25Qb2ludGVyRG93bkVtaXR0ZXIgPSBuZXcgRW1pdHRlcjxcbiAgICBbXG4gICAgICBhY3RpdmVUb29sOiBBcHBTdGF0ZVtcImFjdGl2ZVRvb2xcIl0sXG4gICAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgXVxuICA+KCk7XG5cbiAgb25Qb2ludGVyVXBFbWl0dGVyID0gbmV3IEVtaXR0ZXI8XG4gICAgW1xuICAgICAgYWN0aXZlVG9vbDogQXBwU3RhdGVbXCJhY3RpdmVUb29sXCJdLFxuICAgICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgXVxuICA+KCk7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IEFwcFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIGNvbnN0IGRlZmF1bHRBcHBTdGF0ZSA9IGdldERlZmF1bHRBcHBTdGF0ZSgpO1xuICAgIGNvbnN0IHtcbiAgICAgIGV4Y2FsaWRyYXdSZWYsXG4gICAgICB2aWV3TW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIHplbk1vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICBncmlkTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIHRoZW1lID0gZGVmYXVsdEFwcFN0YXRlLnRoZW1lLFxuICAgICAgbmFtZSA9IGRlZmF1bHRBcHBTdGF0ZS5uYW1lLFxuICAgIH0gPSBwcm9wcztcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgLi4uZGVmYXVsdEFwcFN0YXRlLFxuICAgICAgdGhlbWUsXG4gICAgICBpc0xvYWRpbmc6IHRydWUsXG4gICAgICAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSxcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgZ3JpZFNpemU6IGdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGwsXG4gICAgICBuYW1lLFxuICAgICAgd2lkdGg6IHdpbmRvdy5pbm5lcldpZHRoLFxuICAgICAgaGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlLFxuICAgICAgZGVmYXVsdFNpZGViYXJEb2NrZWRQcmVmZXJlbmNlOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgdGhpcy5pZCA9IG5hbm9pZCgpO1xuICAgIHRoaXMubGlicmFyeSA9IG5ldyBMaWJyYXJ5KHRoaXMpO1xuICAgIGlmIChleGNhbGlkcmF3UmVmKSB7XG4gICAgICBjb25zdCByZWFkeVByb21pc2UgPVxuICAgICAgICAoXCJjdXJyZW50XCIgaW4gZXhjYWxpZHJhd1JlZiAmJiBleGNhbGlkcmF3UmVmLmN1cnJlbnQ/LnJlYWR5UHJvbWlzZSkgfHxcbiAgICAgICAgcmVzb2x2YWJsZVByb21pc2U8RXhjYWxpZHJhd0ltcGVyYXRpdmVBUEk+KCk7XG5cbiAgICAgIGNvbnN0IGFwaTogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUEkgPSB7XG4gICAgICAgIHJlYWR5OiB0cnVlLFxuICAgICAgICByZWFkeVByb21pc2UsXG4gICAgICAgIHVwZGF0ZVNjZW5lOiB0aGlzLnVwZGF0ZVNjZW5lLFxuICAgICAgICB1cGRhdGVMaWJyYXJ5OiB0aGlzLmxpYnJhcnkudXBkYXRlTGlicmFyeSxcbiAgICAgICAgYWRkRmlsZXM6IHRoaXMuYWRkRmlsZXMsXG4gICAgICAgIHJlc2V0U2NlbmU6IHRoaXMucmVzZXRTY2VuZSxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQ6IHRoaXMuZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQsXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBjbGVhcjogdGhpcy5yZXNldEhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICAgIHNjcm9sbFRvQ29udGVudDogdGhpcy5zY3JvbGxUb0NvbnRlbnQsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHM6IHRoaXMuZ2V0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgZ2V0QXBwU3RhdGU6ICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAgIGdldEZpbGVzOiAoKSA9PiB0aGlzLmZpbGVzLFxuICAgICAgICByZWZyZXNoOiB0aGlzLnJlZnJlc2gsXG4gICAgICAgIHNldFRvYXN0OiB0aGlzLnNldFRvYXN0LFxuICAgICAgICBpZDogdGhpcy5pZCxcbiAgICAgICAgc2V0QWN0aXZlVG9vbDogdGhpcy5zZXRBY3RpdmVUb29sLFxuICAgICAgICBzZXRDdXJzb3I6IHRoaXMuc2V0Q3Vyc29yLFxuICAgICAgICByZXNldEN1cnNvcjogdGhpcy5yZXNldEN1cnNvcixcbiAgICAgICAgYXBwOiB0aGlzLFxuICAgICAgICBvbkNoYW5nZTogKGNiKSA9PiB0aGlzLm9uQ2hhbmdlRW1pdHRlci5vbihjYiksXG4gICAgICAgIG9uUG9pbnRlckRvd246IChjYikgPT4gdGhpcy5vblBvaW50ZXJEb3duRW1pdHRlci5vbihjYiksXG4gICAgICAgIG9uUG9pbnRlclVwOiAoY2IpID0+IHRoaXMub25Qb2ludGVyVXBFbWl0dGVyLm9uKGNiKSxcbiAgICAgICAgdG9nZ2xlU2lkZWJhcjogdGhpcy50b2dnbGVTaWRlYmFyLFxuICAgICAgfSBhcyBjb25zdDtcbiAgICAgIGlmICh0eXBlb2YgZXhjYWxpZHJhd1JlZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYoYXBpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYuY3VycmVudCA9IGFwaTtcbiAgICAgIH1cbiAgICAgIHJlYWR5UHJvbWlzZS5yZXNvbHZlKGFwaSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUgPSB7XG4gICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgfTtcblxuICAgIHRoaXMuc2NlbmUgPSBuZXcgU2NlbmUoKTtcbiAgICB0aGlzLmZvbnRzID0gbmV3IEZvbnRzKHtcbiAgICAgIHNjZW5lOiB0aGlzLnNjZW5lLFxuICAgICAgb25TY2VuZVVwZGF0ZWQ6IHRoaXMub25TY2VuZVVwZGF0ZWQsXG4gICAgfSk7XG4gICAgdGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIgPSBuZXcgQWN0aW9uTWFuYWdlcihcbiAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCxcbiAgICAgICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAoKSA9PiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcyxcbiAgICApO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFsbChhY3Rpb25zKTtcblxuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVVbmRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVSZWRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJDYW52YXMoKSB7XG4gICAgY29uc3QgY2FudmFzU2NhbGUgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICB9ID0gdGhpcy5zdGF0ZTtcbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhc0RPTVdpZHRoICogY2FudmFzU2NhbGU7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY2FudmFzRE9NSGVpZ2h0ICogY2FudmFzU2NhbGU7XG4gICAgaWYgKHZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPGNhbnZhc1xuICAgICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICAgICAgY3Vyc29yOiBDVVJTT1JfVFlQRS5HUkFCLFxuICAgICAgICAgIH19XG4gICAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJVcH1cbiAgICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgPlxuICAgICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICAgIDwvY2FudmFzPlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxjYW52YXNcbiAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgIH19XG4gICAgICAgIHdpZHRoPXtjYW52YXNXaWR0aH1cbiAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgIG9uQ29udGV4dE1lbnU9e3RoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnV9XG4gICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgIG9uRG91YmxlQ2xpY2s9e3RoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2t9XG4gICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJVcH1cbiAgICAgICAgb25Qb2ludGVyQ2FuY2VsPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgIG9uVG91Y2hNb3ZlPXt0aGlzLmhhbmRsZVRvdWNoTW92ZX1cbiAgICAgID5cbiAgICAgICAge3QoXCJsYWJlbHMuZHJhd2luZ0NhbnZhc1wiKX1cbiAgICAgIDwvY2FudmFzPlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVuZGVyKCkge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IHsgcmVuZGVyVG9wUmlnaHRVSSwgcmVuZGVyQ3VzdG9tU3RhdHMgfSA9IHRoaXMucHJvcHM7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdlxuICAgICAgICBjbGFzc05hbWU9e2Nsc3goXCJleGNhbGlkcmF3IGV4Y2FsaWRyYXctY29udGFpbmVyXCIsIHtcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLXZpZXctbW9kZVwiOiB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLXplbi1tb2RlXCI6IHRoaXMuc3RhdGUuemVuTW9kZUVuYWJsZWQsXG4gICAgICAgICAgXCJleGNhbGlkcmF3LS1tb2JpbGVcIjogdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgIH0pfVxuICAgICAgICByZWY9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZn1cbiAgICAgICAgb25Ecm9wPXt0aGlzLmhhbmRsZUFwcE9uRHJvcH1cbiAgICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICAgIG9uS2V5RG93bj17XG4gICAgICAgICAgdGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5ID8gdW5kZWZpbmVkIDogdGhpcy5vbktleURvd25cbiAgICAgICAgfVxuICAgICAgPlxuICAgICAgICA8QXBwQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dGhpc30+XG4gICAgICAgICAgPEFwcFByb3BzQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dGhpcy5wcm9wc30+XG4gICAgICAgICAgICA8RXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlfVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8RGV2aWNlQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dGhpcy5kZXZpY2V9PlxuICAgICAgICAgICAgICAgIDxFeGNhbGlkcmF3U2V0QXBwU3RhdGVDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLnNldEFwcFN0YXRlfT5cbiAgICAgICAgICAgICAgICAgIDxFeGNhbGlkcmF3QXBwU3RhdGVDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLnN0YXRlfT5cbiAgICAgICAgICAgICAgICAgICAgPEV4Y2FsaWRyYXdFbGVtZW50c0NvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKX1cbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxFeGNhbGlkcmF3QWN0aW9uTWFuYWdlckNvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLmFjdGlvbk1hbmFnZXJ9XG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPExheWVyVUlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb25FeHBvcnRJbWFnZT17dGhpcy5vbkV4cG9ydEltYWdlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkhvbWVCdXR0b25DbGljaz17XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkhvbWVCdXR0b25DbGljayB8fCAoKCkgPT4ge30pXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FudmFzPXt0aGlzLmNhbnZhc31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwU3RhdGU9e3RoaXMuc3RhdGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzPXt0aGlzLmZpbGVzfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRBcHBTdGF0ZT17dGhpcy5zZXRBcHBTdGF0ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uTWFuYWdlcj17dGhpcy5hY3Rpb25NYW5hZ2VyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cz17dGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgb25Mb2NrVG9nZ2xlPXt0aGlzLnRvZ2dsZUxvY2t9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9uUGVuTW9kZVRvZ2dsZT17dGhpcy50b2dnbGVQZW5Nb2RlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkhhbmRUb29sVG9nZ2xlPXt0aGlzLm9uSGFuZFRvb2xUb2dnbGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhbmdDb2RlPXtnZXRMYW5ndWFnZSgpLmNvZGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlclRvcFJpZ2h0VUk9e3JlbmRlclRvcFJpZ2h0VUl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlckN1c3RvbVN0YXRzPXtyZW5kZXJDdXN0b21TdGF0c31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0V4aXRaZW5Nb2RlQnRuPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8uemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnplbk1vZGVFbmFibGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgVUlPcHRpb25zPXt0aGlzLnByb3BzLlVJT3B0aW9uc31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgb25JbWFnZUFjdGlvbj17dGhpcy5vbkltYWdlQWN0aW9ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJXZWxjb21lU2NyZWVuPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhdGhpcy5zdGF0ZS5pc0xvYWRpbmcgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnNob3dXZWxjb21lU2NyZWVuICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy5jaGlsZHJlbn1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvTGF5ZXJVST5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy10ZXh0RWRpdG9yQ29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy1jb250ZXh0TWVudUNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB7c2VsZWN0ZWRFbGVtZW50Lmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAhdGhpcy5zdGF0ZS5jb250ZXh0TWVudSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEh5cGVybGlua1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5PXtzZWxlY3RlZEVsZW1lbnRbMF0uaWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50PXtzZWxlY3RlZEVsZW1lbnRbMF19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRBcHBTdGF0ZT17dGhpcy5zZXRBcHBTdGF0ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uTGlua09wZW49e3RoaXMucHJvcHMub25MaW5rT3Blbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICAgICAge3RoaXMuc3RhdGUudG9hc3QgIT09IG51bGwgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICA8VG9hc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlPXt0aGlzLnN0YXRlLnRvYXN0Lm1lc3NhZ2V9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbG9zZT17KCkgPT4gdGhpcy5zZXRUb2FzdChudWxsKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbj17dGhpcy5zdGF0ZS50b2FzdC5kdXJhdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zYWJsZT17dGhpcy5zdGF0ZS50b2FzdC5jbG9zYWJsZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5zdGF0ZS5jb250ZXh0TWVudSAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxDb250ZXh0TWVudVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zPXt0aGlzLnN0YXRlLmNvbnRleHRNZW51Lml0ZW1zfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcD17dGhpcy5zdGF0ZS5jb250ZXh0TWVudS50b3B9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdD17dGhpcy5zdGF0ZS5jb250ZXh0TWVudS5sZWZ0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbk1hbmFnZXI9e3RoaXMuYWN0aW9uTWFuYWdlcn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWFpbj57dGhpcy5yZW5kZXJDYW52YXMoKX08L21haW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9FeGNhbGlkcmF3QWN0aW9uTWFuYWdlckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvRXhjYWxpZHJhd0VsZW1lbnRzQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICAgICAgICAgIDwvRXhjYWxpZHJhd0FwcFN0YXRlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICAgICAgICA8L0V4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgICAgICAgIDwvRGV2aWNlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICAgIDwvRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgICAgPC9BcHBQcm9wc0NvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgIDwvQXBwQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZm9jdXNDb250YWluZXI6IEFwcENsYXNzUHJvcGVydGllc1tcImZvY3VzQ29udGFpbmVyXCJdID0gKCkgPT4ge1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5mb2N1cygpO1xuICB9O1xuXG4gIHB1YmxpYyBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50cyA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcbiAgfTtcblxuICBwdWJsaWMgb25JbnNlcnRFbGVtZW50cyA9IChlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXSkgPT4ge1xuICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgZWxlbWVudHMsXG4gICAgICBwb3NpdGlvbjogXCJjZW50ZXJcIixcbiAgICAgIGZpbGVzOiBudWxsLFxuICAgIH0pO1xuICB9O1xuXG4gIHB1YmxpYyBvbkV4cG9ydEltYWdlID0gYXN5bmMgKFxuICAgIHR5cGU6IGtleW9mIHR5cGVvZiBFWFBPUlRfSU1BR0VfVFlQRVMsXG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICApID0+IHtcbiAgICB0cmFja0V2ZW50KFwiZXhwb3J0XCIsIHR5cGUsIFwidWlcIik7XG4gICAgY29uc3QgZmlsZUhhbmRsZSA9IGF3YWl0IGV4cG9ydEFzSW1hZ2UoXG4gICAgICB0eXBlLFxuICAgICAgZWxlbWVudHMsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICAgdGhpcy5maWxlcyxcbiAgICAgIHtcbiAgICAgICAgZXhwb3J0QmFja2dyb3VuZDogdGhpcy5zdGF0ZS5leHBvcnRCYWNrZ3JvdW5kLFxuICAgICAgICBuYW1lOiB0aGlzLnN0YXRlLm5hbWUsXG4gICAgICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUudmlld0JhY2tncm91bmRDb2xvcixcbiAgICAgIH0sXG4gICAgKVxuICAgICAgLmNhdGNoKG11dGVGU0Fib3J0RXJyb3IpXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgfSk7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmV4cG9ydEVtYmVkU2NlbmUgJiZcbiAgICAgIGZpbGVIYW5kbGUgJiZcbiAgICAgIGlzSW1hZ2VGaWxlSGFuZGxlKGZpbGVIYW5kbGUpXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgZmlsZUhhbmRsZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzeW5jQWN0aW9uUmVzdWx0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChhY3Rpb25SZXN1bHQ6IEFjdGlvblJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHRoaXMudW5tb3VudGVkIHx8IGFjdGlvblJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgZWRpdGluZ0VsZW1lbnQ6IEFwcFN0YXRlW1wiZWRpdGluZ0VsZW1lbnRcIl0gfCBudWxsID0gbnVsbDtcbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuZWxlbWVudHMpIHtcbiAgICAgICAgYWN0aW9uUmVzdWx0LmVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50Py5pZCA9PT0gZWxlbWVudC5pZCAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCAhPT0gZWxlbWVudCAmJlxuICAgICAgICAgICAgaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGFjdGlvblJlc3VsdC5lbGVtZW50cyk7XG4gICAgICAgIGlmIChhY3Rpb25SZXN1bHQuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuZmlsZXMpIHtcbiAgICAgICAgdGhpcy5maWxlcyA9IGFjdGlvblJlc3VsdC5yZXBsYWNlRmlsZXNcbiAgICAgICAgICA/IGFjdGlvblJlc3VsdC5maWxlc1xuICAgICAgICAgIDogeyAuLi50aGlzLmZpbGVzLCAuLi5hY3Rpb25SZXN1bHQuZmlsZXMgfTtcbiAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFjdGlvblJlc3VsdC5hcHBTdGF0ZSB8fCBlZGl0aW5nRWxlbWVudCB8fCB0aGlzLnN0YXRlLmNvbnRleHRNZW51KSB7XG4gICAgICAgIGlmIChhY3Rpb25SZXN1bHQuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHZpZXdNb2RlRW5hYmxlZCA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LnZpZXdNb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IHplbk1vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uemVuTW9kZUVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGxldCBncmlkU2l6ZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LmdyaWRTaXplIHx8IG51bGw7XG4gICAgICAgIGNvbnN0IHRoZW1lID1cbiAgICAgICAgICBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy50aGVtZSB8fCB0aGlzLnByb3BzLnRoZW1lIHx8IFRIRU1FLkxJR0hUO1xuICAgICAgICBsZXQgbmFtZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/Lm5hbWUgPz8gdGhpcy5zdGF0ZS5uYW1lO1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgIGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LmVycm9yTWVzc2FnZSA/PyB0aGlzLnN0YXRlLmVycm9yTWVzc2FnZTtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgemVuTW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIGdyaWRTaXplID0gdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLm5hbWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBuYW1lID0gdGhpcy5wcm9wcy5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgICAvLyB1c2luZyBPYmplY3QuYXNzaWduIGluc3RlYWQgb2Ygc3ByZWFkIHRvIGZvb2wgVFMgNC4yLjIrIGludG9cbiAgICAgICAgICAgIC8vIHJlZ2FyZGluZyB0aGUgcmVzdWx0aW5nIHR5cGUgYXMgbm90IGNvbnRhaW5pbmcgdW5kZWZpbmVkXG4gICAgICAgICAgICAvLyAod2hpY2ggdGhlIGZvbGxvd2luZyBleHByZXNzaW9uIHdpbGwgbmV2ZXIgY29udGFpbilcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGFjdGlvblJlc3VsdC5hcHBTdGF0ZSB8fCB7fSwge1xuICAgICAgICAgICAgICAvLyBOT1RFIHRoaXMgd2lsbCBwcmV2ZW50IG9wZW5pbmcgY29udGV4dCBtZW51IHVzaW5nIGFuIGFjdGlvblxuICAgICAgICAgICAgICAvLyBvciBwcm9ncmFtbWF0aWNhbGx5IGZyb20gdGhlIGhvc3QsIHNvIGl0IHdpbGwgbmVlZCB0byBiZVxuICAgICAgICAgICAgICAvLyByZXdyaXR0ZW4gbGF0ZXJcbiAgICAgICAgICAgICAgY29udGV4dE1lbnU6IG51bGwsXG4gICAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50IHx8IGFjdGlvblJlc3VsdC5hcHBTdGF0ZT8uZWRpdGluZ0VsZW1lbnQgfHwgbnVsbCxcbiAgICAgICAgICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZCxcbiAgICAgICAgICAgICAgZ3JpZFNpemUsXG4gICAgICAgICAgICAgIHRoZW1lLFxuICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGlmIChhY3Rpb25SZXN1bHQuc3luY0hpc3RvcnkpIHtcbiAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnNldEN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIC8vIExpZmVjeWNsZVxuXG4gIHByaXZhdGUgb25CbHVyID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBwcml2YXRlIG9uVW5sb2FkID0gKCkgPT4ge1xuICAgIHRoaXMub25CbHVyKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRXZlbnQ6IEV2ZW50TGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRIaXN0b3J5ID0gKCkgPT4ge1xuICAgIHRoaXMuaGlzdG9yeS5jbGVhcigpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXNldHMgc2NlbmUgJiBoaXN0b3J5LlxuICAgKiAhIERvIG5vdCB1c2UgdG8gY2xlYXIgc2NlbmUgdXNlciBhY3Rpb24gIVxuICAgKi9cbiAgcHJpdmF0ZSByZXNldFNjZW5lID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChvcHRzPzogeyByZXNldExvYWRpbmdTdGF0ZTogYm9vbGVhbiB9KSA9PiB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgLi4uZ2V0RGVmYXVsdEFwcFN0YXRlKCksXG4gICAgICAgIGlzTG9hZGluZzogb3B0cz8ucmVzZXRMb2FkaW5nU3RhdGUgPyBmYWxzZSA6IHN0YXRlLmlzTG9hZGluZyxcbiAgICAgICAgdGhlbWU6IHRoaXMuc3RhdGUudGhlbWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0SGlzdG9yeSgpO1xuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplU2NlbmUgPSBhc3luYyAoKSA9PiB7XG4gICAgaWYgKFwibGF1bmNoUXVldWVcIiBpbiB3aW5kb3cgJiYgXCJMYXVuY2hQYXJhbXNcIiBpbiB3aW5kb3cpIHtcbiAgICAgICh3aW5kb3cgYXMgYW55KS5sYXVuY2hRdWV1ZS5zZXRDb25zdW1lcihcbiAgICAgICAgYXN5bmMgKGxhdW5jaFBhcmFtczogeyBmaWxlczogYW55W10gfSkgPT4ge1xuICAgICAgICAgIGlmICghbGF1bmNoUGFyYW1zLmZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBmaWxlSGFuZGxlID0gbGF1bmNoUGFyYW1zLmZpbGVzWzBdO1xuICAgICAgICAgIGNvbnN0IGJsb2I6IEJsb2IgPSBhd2FpdCBmaWxlSGFuZGxlLmdldEZpbGUoKTtcbiAgICAgICAgICB0aGlzLmxvYWRGaWxlVG9DYW52YXMoXG4gICAgICAgICAgICBuZXcgRmlsZShbYmxvYl0sIGJsb2IubmFtZSB8fCBcIlwiLCB7IHR5cGU6IGJsb2IudHlwZSB9KSxcbiAgICAgICAgICAgIGZpbGVIYW5kbGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJvcHMudGhlbWUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB0aGVtZTogdGhpcy5wcm9wcy50aGVtZSB9KTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnN0YXRlLmlzTG9hZGluZykge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogdHJ1ZSB9KTtcbiAgICB9XG4gICAgbGV0IGluaXRpYWxEYXRhID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgaW5pdGlhbERhdGEgPSAoYXdhaXQgdGhpcy5wcm9wcy5pbml0aWFsRGF0YSkgfHwgbnVsbDtcbiAgICAgIGlmIChpbml0aWFsRGF0YT8ubGlicmFyeUl0ZW1zKSB7XG4gICAgICAgIHRoaXMubGlicmFyeVxuICAgICAgICAgIC51cGRhdGVMaWJyYXJ5KHtcbiAgICAgICAgICAgIGxpYnJhcnlJdGVtczogaW5pdGlhbERhdGEubGlicmFyeUl0ZW1zLFxuICAgICAgICAgICAgbWVyZ2U6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIGluaXRpYWxEYXRhID0ge1xuICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgIGVycm9yTWVzc2FnZTpcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHxcbiAgICAgICAgICAgIFwiRW5jb3VudGVyZWQgYW4gZXJyb3IgZHVyaW5nIGltcG9ydGluZyBvciByZXN0b3Jpbmcgc2NlbmUgZGF0YVwiLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG4gICAgY29uc3Qgc2NlbmUgPSByZXN0b3JlKGluaXRpYWxEYXRhLCBudWxsLCBudWxsLCB7IHJlcGFpckJpbmRpbmdzOiB0cnVlIH0pO1xuICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICB0aGVtZTogdGhpcy5wcm9wcy50aGVtZSB8fCBzY2VuZS5hcHBTdGF0ZS50aGVtZSxcbiAgICAgIC8vIHdlJ3JlIGZhbGxpbmcgYmFjayB0byBjdXJyZW50IChwcmUtaW5pdCkgc3RhdGUgd2hlbiBkZWNpZGluZ1xuICAgICAgLy8gd2hldGhlciB0byBvcGVuIHRoZSBsaWJyYXJ5LCB0byBoYW5kbGUgYSBjYXNlIHdoZXJlIHdlXG4gICAgICAvLyB1cGRhdGUgdGhlIHN0YXRlIG91dHNpZGUgb2YgaW5pdGlhbERhdGEgKGUuZy4gd2hlbiBsb2FkaW5nIHRoZSBhcHBcbiAgICAgIC8vIHdpdGggYSBsaWJyYXJ5IGluc3RhbGwgbGluaywgd2hpY2ggc2hvdWxkIGF1dG8tb3BlbiB0aGUgbGlicmFyeSlcbiAgICAgIG9wZW5TaWRlYmFyOiBzY2VuZS5hcHBTdGF0ZT8ub3BlblNpZGViYXIgfHwgdGhpcy5zdGF0ZS5vcGVuU2lkZWJhcixcbiAgICAgIGFjdGl2ZVRvb2w6XG4gICAgICAgIHNjZW5lLmFwcFN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiXG4gICAgICAgICAgPyB7IC4uLnNjZW5lLmFwcFN0YXRlLmFjdGl2ZVRvb2wsIHR5cGU6IFwic2VsZWN0aW9uXCIgfVxuICAgICAgICAgIDogc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbCxcbiAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICB0b2FzdDogdGhpcy5zdGF0ZS50b2FzdCxcbiAgICB9O1xuICAgIGlmIChpbml0aWFsRGF0YT8uc2Nyb2xsVG9Db250ZW50KSB7XG4gICAgICBzY2VuZS5hcHBTdGF0ZSA9IHtcbiAgICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAgIC4uLmNhbGN1bGF0ZVNjcm9sbENlbnRlcihcbiAgICAgICAgICBzY2VuZS5lbGVtZW50cyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLnN0YXRlLndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnN0YXRlLmhlaWdodCxcbiAgICAgICAgICAgIG9mZnNldFRvcDogdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgICAgICAgICBvZmZzZXRMZWZ0OiB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBudWxsLFxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gRm9udEZhY2VTZXQgbG9hZGluZ2RvbmUgZXZlbnQgd2UgbGlzdGVuIG9uIG1heSBub3QgYWx3YXlzIGZpcmVcbiAgICAvLyAobG9va2luZyBhdCB5b3UgU2FmYXJpKSwgc28gb24gaW5pdCB3ZSBtYW51YWxseSBsb2FkIGZvbnRzIGZvciBjdXJyZW50XG4gICAgLy8gdGV4dCBlbGVtZW50cyBvbiBjYW52YXMsIGFuZCByZXJlbmRlciB0aGVtIG9uY2UgZG9uZS4gVGhpcyBhbHNvXG4gICAgLy8gc2VlbXMgZmFzdGVyIGV2ZW4gaW4gYnJvd3NlcnMgdGhhdCBkbyBmaXJlIHRoZSBsb2FkaW5nZG9uZSBldmVudC5cbiAgICB0aGlzLmZvbnRzLmxvYWRGb250c0ZvckVsZW1lbnRzKHNjZW5lLmVsZW1lbnRzKTtcblxuICAgIGlmIChpbml0aWFsRGF0YT8uc2Nyb2xsWCAhPSBudWxsKSB7XG4gICAgICBzY2VuZS5hcHBTdGF0ZS5zY3JvbGxYID0gaW5pdGlhbERhdGEuc2Nyb2xsWDtcbiAgICB9XG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxZICE9IG51bGwpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlLnNjcm9sbFkgPSBpbml0aWFsRGF0YS5zY3JvbGxZO1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgIC4uLnNjZW5lLFxuICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVmcmVzaERldmljZVN0YXRlID0gKGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQpID0+IHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBzaWRlYmFyQnJlYWtwb2ludCA9XG4gICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPSBudWxsXG4gICAgICAgID8gdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICAgICAgOiBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSDtcbiAgICB0aGlzLmRldmljZSA9IHVwZGF0ZU9iamVjdCh0aGlzLmRldmljZSwge1xuICAgICAgaXNMYW5kc2NhcGU6IHdpZHRoID4gaGVpZ2h0LFxuICAgICAgaXNTbVNjcmVlbjogd2lkdGggPCBNUV9TTV9NQVhfV0lEVEgsXG4gICAgICBpc01vYmlsZTpcbiAgICAgICAgd2lkdGggPCBNUV9NQVhfV0lEVEhfUE9SVFJBSVQgfHxcbiAgICAgICAgKGhlaWdodCA8IE1RX01BWF9IRUlHSFRfTEFORFNDQVBFICYmIHdpZHRoIDwgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSksXG4gICAgICBjYW5EZXZpY2VGaXRTaWRlYmFyOiB3aWR0aCA+IHNpZGViYXJCcmVha3BvaW50LFxuICAgIH0pO1xuICB9O1xuXG4gIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICB0aGlzLnVubW91bnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlLmNvbnRhaW5lciA9XG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcblxuICAgIGlmIChcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVFxuICAgICkge1xuICAgICAgY29uc3Qgc2V0U3RhdGUgPSB0aGlzLnNldFN0YXRlLmJpbmQodGhpcyk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh3aW5kb3cuaCwge1xuICAgICAgICBzdGF0ZToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXRlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHNldFN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiAoLi4uYXJnczogUGFyYW1ldGVyczx0eXBlb2Ygc2V0U3RhdGU+KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRTdGF0ZSguLi5hcmdzKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBhcHA6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6IHRoaXMsXG4gICAgICAgIH0sXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6IHRoaXMuaGlzdG9yeSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuc2NlbmUuYWRkQ2FsbGJhY2sodGhpcy5vblNjZW5lVXBkYXRlZCk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuXG4gICAgaWYgKHRoaXMucHJvcHMuYXV0b0ZvY3VzICYmIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KSB7XG4gICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQgJiZcbiAgICAgIC8vIGJvdW5kaW5nIHJlY3RzIGRvbid0IHdvcmsgaW4gdGVzdHMgc28gdXBkYXRpbmdcbiAgICAgIC8vIHRoZSBzdGF0ZSBvbiBpbml0IHdvdWxkIHJlc3VsdCBpbiBtYWtpbmcgdGhlIHRlc3QgZW52aXJvIHJ1blxuICAgICAgLy8gaW4gbW9iaWxlIGJyZWFrcG9pbnQgKDAgd2lkdGgvaGVpZ2h0KSwgbWFraW5nIGV2ZXJ5dGhpbmcgZmFpbFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwidGVzdFwiXG4gICAgKSB7XG4gICAgICB0aGlzLnJlZnJlc2hEZXZpY2VTdGF0ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCk7XG4gICAgfVxuXG4gICAgaWYgKFwiUmVzaXplT2JzZXJ2ZXJcIiBpbiB3aW5kb3cgJiYgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSBmYWxzZTtcbiAgICAgICAgLy8gcmVjb21wdXRlIGRldmljZSBkaW1lbnNpb25zIHN0YXRlXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnJlZnJlc2hEZXZpY2VTdGF0ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEpO1xuICAgICAgICAvLyByZWZyZXNoIG9mZnNldHNcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCgpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5vYnNlcnZlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKSB7XG4gICAgICBjb25zdCBtZFNjcmVlblF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9QT1JUUkFJVH1weCksIChtYXgtaGVpZ2h0OiAke01RX01BWF9IRUlHSFRfTEFORFNDQVBFfXB4KSBhbmQgKG1heC13aWR0aDogJHtNUV9NQVhfV0lEVEhfTEFORFNDQVBFfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3Qgc21TY3JlZW5RdWVyeSA9IHdpbmRvdy5tYXRjaE1lZGlhKFxuICAgICAgICBgKG1heC13aWR0aDogJHtNUV9TTV9NQVhfV0lEVEh9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBjYW5EZXZpY2VGaXRTaWRlYmFyTWVkaWFRdWVyeSA9IHdpbmRvdy5tYXRjaE1lZGlhKFxuICAgICAgICBgKG1pbi13aWR0aDogJHtcbiAgICAgICAgICAvLyBOT1RFIHRoaXMgd29uJ3QgdXBkYXRlIGlmIGEgZGlmZmVyZW50IGJyZWFrcG9pbnQgaXMgc3VwcGxpZWRcbiAgICAgICAgICAvLyBhZnRlciBtb3VudFxuICAgICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50ICE9IG51bGxcbiAgICAgICAgICAgID8gdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICAgICAgICAgIDogTVFfUklHSFRfU0lERUJBUl9NSU5fV0lEVEhcbiAgICAgICAgfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB0aGlzLmRldmljZSA9IHVwZGF0ZU9iamVjdCh0aGlzLmRldmljZSwge1xuICAgICAgICAgIGlzU21TY3JlZW46IHNtU2NyZWVuUXVlcnkubWF0Y2hlcyxcbiAgICAgICAgICBpc01vYmlsZTogbWRTY3JlZW5RdWVyeS5tYXRjaGVzLFxuICAgICAgICAgIGNhbkRldmljZUZpdFNpZGViYXI6IGNhbkRldmljZUZpdFNpZGViYXJNZWRpYVF1ZXJ5Lm1hdGNoZXMsXG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIG1kU2NyZWVuUXVlcnkuYWRkTGlzdGVuZXIoaGFuZGxlcik7XG4gICAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyID0gKCkgPT5cbiAgICAgICAgbWRTY3JlZW5RdWVyeS5yZW1vdmVMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc2xpY2UoMSkpO1xuXG4gICAgaWYgKHNlYXJjaFBhcmFtcy5oYXMoXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpKSB7XG4gICAgICAvLyBPYnRhaW4gYSBmaWxlIHRoYXQgd2FzIHNoYXJlZCB2aWEgdGhlIFdlYiBTaGFyZSBUYXJnZXQgQVBJLlxuICAgICAgdGhpcy5yZXN0b3JlRmlsZUZyb21TaGFyZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURPTVJlY3QodGhpcy5pbml0aWFsaXplU2NlbmUpO1xuICAgIH1cblxuICAgIC8vIG5vdGUgdGhhdCB0aGlzIGNoZWNrIHNlZW1zIHRvIGFsd2F5cyBwYXNzIGluIGxvY2FsaG9zdFxuICAgIGlmIChpc0JyYXZlKCkgJiYgIWlzTWVhc3VyZVRleHRTdXBwb3J0ZWQoKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVycm9yTWVzc2FnZTogPEJyYXZlTWVhc3VyZVRleHRFcnJvciAvPixcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICB0aGlzLmZpbGVzID0ge307XG4gICAgdGhpcy5pbWFnZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMudW5tb3VudGVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zY2VuZS5kZXN0cm95KCk7XG4gICAgY2xlYXJSZW5kZXJDYWNoZSgpO1xuXG4gICAgdGhpcy5vbkNoYW5nZUVtaXR0ZXIuZGVzdHJveSgpO1xuXG4gICAgdGhpcy5zY2VuZSA9IG5ldyBTY2VuZSgpO1xuICAgIHRoaXMuaGlzdG9yeSA9IG5ldyBIaXN0b3J5KCk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyID0gbmV3IEFjdGlvbk1hbmFnZXIoXG4gICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQsXG4gICAgICAoKSA9PiB0aGlzLnN0YXRlLFxuICAgICAgKCkgPT4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMsXG4gICAgKTtcbiAgICB0aGlzLmxpYnJhcnkgPSBuZXcgTGlicmFyeSh0aGlzKTtcbiAgICB0aGlzLmNhbnZhcyA9IG51bGw7XG4gICAgdGhpcy5yYyA9IG51bGw7XG5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZSA9IHsgY29udGFpbmVyOiBudWxsLCBpZDogXCJ1bm1vdW50ZWRcIiB9O1xuXG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgfVxuXG4gIHByaXZhdGUgb25SZXNpemUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIHRoaXMuc2NlbmVcbiAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgLmZvckVhY2goKGVsZW1lbnQpID0+IGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9KTtcblxuICBwcml2YXRlIHJlbW92ZUV2ZW50TGlzdGVuZXJzKCkge1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuV0hFRUwsXG4gICAgICB0aGlzLm9uV2hlZWwsXG4gICAgKTtcbiAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyPy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuU0NST0xMLFxuICAgICAgdGhpcy5vblNjcm9sbCxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgdGhpcy5vbktleURvd24sIGZhbHNlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuTU9VU0VfTU9WRSxcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uLFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCB0aGlzLm9uS2V5VXApO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlJFU0laRSwgdGhpcy5vblJlc2l6ZSwgZmFsc2UpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlVOTE9BRCwgdGhpcy5vblVubG9hZCwgZmFsc2UpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRoaXMub25CbHVyLCBmYWxzZSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUkFHX09WRVIsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUk9QLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmZvbnRzPy5yZW1vdmVFdmVudExpc3RlbmVyPy4oXG4gICAgICBcImxvYWRpbmdkb25lXCIsXG4gICAgICB0aGlzLm9uRm9udHNMb2FkaW5nRG9uZSxcbiAgICApO1xuXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgdGhpcy5kZXRhY2hJc01vYmlsZU1xSGFuZGxlcj8uKCk7XG4gIH1cblxuICBwcml2YXRlIG9uRm9udHNMb2FkaW5nRG9uZSA9IChldmVudDogRXZlbnQpID0+IHtcbiAgICBjb25zdCBsb2FkZWRGb250RmFjZXMgPSAoZXZlbnQgYXMgRm9udEZhY2VTZXRMb2FkRXZlbnQpLmZvbnRmYWNlcztcbiAgICB0aGlzLmZvbnRzLm9uRm9udHNMb2FkZWQobG9hZGVkRm9udEZhY2VzKTtcbiAgfTtcblxuICBwcml2YXRlIGFkZEV2ZW50TGlzdGVuZXJzKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRoaXMucmVtb3ZlUG9pbnRlcik7IC8vICMzNTUzXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DT1BZLCB0aGlzLm9uQ29weSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5XSEVFTCxcbiAgICAgIHRoaXMub25XaGVlbCxcbiAgICAgIHsgcGFzc2l2ZTogZmFsc2UgfSxcbiAgICApO1xuXG4gICAgaWYgKHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSkge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIH1cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCB0aGlzLm9uS2V5VXAsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuTU9VU0VfTU9WRSxcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uLFxuICAgICk7XG4gICAgLy8gcmVyZW5kZXIgdGV4dCBlbGVtZW50cyBvbiBmb250IGxvYWQgdG8gZml4ICM2MzcgJiYgIzE1NTNcbiAgICBkb2N1bWVudC5mb250cz8uYWRkRXZlbnRMaXN0ZW5lcj8uKFwibG9hZGluZ2RvbmVcIiwgdGhpcy5vbkZvbnRzTG9hZGluZ0RvbmUpO1xuXG4gICAgLy8gU2FmYXJpLW9ubHkgZGVza3RvcCBwaW5jaCB6b29tXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgaWYgKHRoaXMucHJvcHMuZGV0ZWN0U2Nyb2xsKSB7XG4gICAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gZ2V0TmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIoXG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICk7XG4gICAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlNDUk9MTCxcbiAgICAgICAgdGhpcy5vblNjcm9sbCxcbiAgICAgICk7XG4gICAgfVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlJFU0laRSwgdGhpcy5vblJlc2l6ZSwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlVOTE9BRCwgdGhpcy5vblVubG9hZCwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRoaXMub25CbHVyLCBmYWxzZSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUkFHX09WRVIsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUk9QLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuICB9XG5cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogQXBwUHJvcHMsIHByZXZTdGF0ZTogQXBwU3RhdGUpIHtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5zdGF0ZS5zaG93V2VsY29tZVNjcmVlbiAmJlxuICAgICAgIXRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubGVuZ3RoXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd1dlbGNvbWVTY3JlZW46IHRydWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQgJiZcbiAgICAgIHByZXZQcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnQgIT09XG4gICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50XG4gICAgKSB7XG4gICAgICB0aGlzLnJlZnJlc2hEZXZpY2VTdGF0ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLnNjcm9sbFggIT09IHRoaXMuc3RhdGUuc2Nyb2xsWCB8fFxuICAgICAgcHJldlN0YXRlLnNjcm9sbFkgIT09IHRoaXMuc3RhdGUuc2Nyb2xsWVxuICAgICkge1xuICAgICAgdGhpcy5wcm9wcz8ub25TY3JvbGxDaGFuZ2U/Lih0aGlzLnN0YXRlLnNjcm9sbFgsIHRoaXMuc3RhdGUuc2Nyb2xsWSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgT2JqZWN0LmtleXModGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMpLmxlbmd0aCAmJlxuICAgICAgaXNFcmFzZXJBY3RpdmUodGhpcy5zdGF0ZSlcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJlcmFzZXJcIiAmJlxuICAgICAgcHJldlN0YXRlLnRoZW1lICE9PSB0aGlzLnN0YXRlLnRoZW1lXG4gICAgKSB7XG4gICAgICBzZXRFcmFzZXJDdXJzb3IodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUudGhlbWUpO1xuICAgIH1cbiAgICAvLyBIaWRlIGh5cGVybGluayBwb3B1cCBpZiBzaG93biB3aGVuIGVsZW1lbnQgdHlwZSBpcyBub3Qgc2VsZWN0aW9uXG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgIHRoaXMuc3RhdGUuc2hvd0h5cGVybGlua1BvcHVwXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0h5cGVybGlua1BvcHVwOiBmYWxzZSB9KTtcbiAgICB9XG4gICAgaWYgKHByZXZQcm9wcy5sYW5nQ29kZSAhPT0gdGhpcy5wcm9wcy5sYW5nQ29kZSkge1xuICAgICAgdGhpcy51cGRhdGVMYW5ndWFnZSgpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpZXdNb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCB9KTtcbiAgICB9XG5cbiAgICBpZiAocHJldlN0YXRlLnZpZXdNb2RlRW5hYmxlZCAhPT0gdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB6ZW5Nb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudGhlbWUgIT09IHRoaXMucHJvcHMudGhlbWUgJiYgdGhpcy5wcm9wcy50aGVtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHRoZW1lOiB0aGlzLnByb3BzLnRoZW1lIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGdyaWRTaXplOiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAhdGhpcy5wcm9wcy5VSU9wdGlvbnMuY2FudmFzQWN0aW9ucyAmJlxuICAgICAgdGhpcy5zdGF0ZS5vcGVuTWVudSA9PT0gXCJjYW52YXNcIlxuICAgICkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG9wZW5NZW51OiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJvcHMubmFtZSAmJiBwcmV2UHJvcHMubmFtZSAhPT0gdGhpcy5wcm9wcy5uYW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgbmFtZTogdGhpcy5wcm9wcy5uYW1lLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNsYXNzTGlzdC50b2dnbGUoXG4gICAgICBcInRoZW1lLS1kYXJrXCIsXG4gICAgICB0aGlzLnN0YXRlLnRoZW1lID09PSBcImRhcmtcIixcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW3RoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkXVxuICAgICkge1xuICAgICAgLy8gZGVmZXIgc28gdGhhdCB0aGUgY29tbWl0VG9IaXN0b3J5IGZsYWcgaXNuJ3QgcmVzZXQgdmlhIGN1cnJlbnQgdXBkYXRlXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgLy8gZXhlY3V0ZSBvbmx5IGlmIHRoZSBjb25kaXRpb24gc3RpbGwgaG9sZHMgd2hlbiB0aGUgZGVmZXJyZWQgY2FsbGJhY2tcbiAgICAgICAgLy8gZXhlY3V0ZXMgKGl0IGNhbiBiZSBzY2hlZHVsZWQgbXVsdGlwbGUgdGltZXMgZGVwZW5kaW5nIG9uIGhvd1xuICAgICAgICAvLyBtYW55IHRpbWVzIHRoZSBjb21wb25lbnQgcmVuZGVycylcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuZWxlbWVudElkXVxuICAgICkge1xuICAgICAgLy8gVG8gbWFrZSBzdXJlIGBzZWxlY3RlZExpbmVhckVsZW1lbnRgIGlzIGluIHN5bmMgd2l0aCBgc2VsZWN0ZWRFbGVtZW50SWRzYCwgaG93ZXZlciB0aGlzIHNob3VsZG4ndCBiZSBuZWVkZWQgb25jZVxuICAgICAgLy8gd2UgaGF2ZSBhIHNpbmdsZSBBUEkgdG8gdXBkYXRlIGBzZWxlY3RlZEVsZW1lbnRJZHNgXG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBudWxsIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSBwcmV2U3RhdGU7XG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLmFjdGl2ZVRvb2wgIT09IHRoaXMuc3RhdGUuYWN0aXZlVG9vbCAmJlxuICAgICAgbXVsdGlFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgIGlzQmluZGluZ0VsZW1lbnQobXVsdGlFbGVtZW50LCBmYWxzZSlcbiAgICApIHtcbiAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRBdEluZGV4R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgICAgICAtMSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXJTY2VuZSgpO1xuICAgIHRoaXMuaGlzdG9yeS5yZWNvcmQodGhpcy5zdGF0ZSwgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSk7XG5cbiAgICAvLyBEbyBub3Qgbm90aWZ5IGNvbnN1bWVycyBpZiB3ZSdyZSBzdGlsbCBsb2FkaW5nIHRoZSBzY2VuZS4gQW1vbmcgb3RoZXJcbiAgICAvLyBwb3RlbnRpYWwgaXNzdWVzLCB0aGlzIGZpeGVzIGEgY2FzZSB3aGVyZSB0aGUgdGFiIGlzbid0IGZvY3VzZWQgZHVyaW5nXG4gICAgLy8gaW5pdCwgd2hpY2ggd291bGQgdHJpZ2dlciBvbkNoYW5nZSB3aXRoIGVtcHR5IGVsZW1lbnRzLCB3aGljaCB3b3VsZCB0aGVuXG4gICAgLy8gb3ZlcnJpZGUgd2hhdGV2ZXIgaXMgaW4gbG9jYWxTdG9yYWdlIGN1cnJlbnRseS5cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnByb3BzLm9uQ2hhbmdlPy4oXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuZmlsZXMsXG4gICAgICAgIHRoaXMucHJvcHMuaWQsXG4gICAgICApO1xuICAgICAgdGhpcy5vbkNoYW5nZUVtaXR0ZXIudHJpZ2dlcihcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5maWxlcyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTY2VuZSA9ICgpID0+IHtcbiAgICBjb25zdCBjdXJzb3JCdXR0b246IHtcbiAgICAgIFtpZDogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVmlld3BvcnRDb29yZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlcm5hbWVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlclN0YXRlczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgdGhpcy5zdGF0ZS5jb2xsYWJvcmF0b3JzLmZvckVhY2goKHVzZXIsIHNvY2tldElkKSA9PiB7XG4gICAgICBpZiAodXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICBpZiAoIShpZCBpbiByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0ucHVzaChzb2NrZXRJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghdXNlci5wb2ludGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICAgIHBvaW50ZXJVc2VybmFtZXNbc29ja2V0SWRdID0gdXNlci51c2VybmFtZTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJTdGF0ZSkge1xuICAgICAgICBwb2ludGVyVXNlclN0YXRlc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJTdGF0ZTtcbiAgICAgIH1cbiAgICAgIHBvaW50ZXJWaWV3cG9ydENvb3Jkc1tzb2NrZXRJZF0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgIHtcbiAgICAgICAgICBzY2VuZVg6IHVzZXIucG9pbnRlci54LFxuICAgICAgICAgIHNjZW5lWTogdXNlci5wb2ludGVyLnksXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY3Vyc29yQnV0dG9uW3NvY2tldElkXSA9IHVzZXIuYnV0dG9uO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVuZGVyaW5nRWxlbWVudHMgPSB0aGlzLnNjZW5lXG4gICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgLy8gbm90IHBsYWNlZCBvbiBjYW52YXMgeWV0IChidXQgaW4gZWxlbWVudHMgYXJyYXkpXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCA9PT0gZWxlbWVudC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBkb24ndCByZW5kZXIgdGV4dCBlbGVtZW50IHRoYXQncyBiZWluZyBjdXJyZW50bHkgZWRpdGVkIChpdCdzXG4gICAgICAgIC8vIHJlbmRlcmVkIG9uIHJlbW90ZSBvbmx5KVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC50eXBlICE9PSBcInRleHRcIiB8fFxuICAgICAgICAgIGVsZW1lbnQuaWQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQuaWRcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3Qgc2VsZWN0aW9uQ29sb3IgPSBnZXRDb21wdXRlZFN0eWxlKFxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5leGNhbGlkcmF3XCIpISxcbiAgICApLmdldFByb3BlcnR5VmFsdWUoXCItLWNvbG9yLXNlbGVjdGlvblwiKTtcblxuICAgIHJlbmRlclNjZW5lKFxuICAgICAge1xuICAgICAgICBlbGVtZW50czogcmVuZGVyaW5nRWxlbWVudHMsXG4gICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICByYzogdGhpcy5yYyEsXG4gICAgICAgIGNhbnZhczogdGhpcy5jYW52YXMhLFxuICAgICAgICByZW5kZXJDb25maWc6IHtcbiAgICAgICAgICBjYW52YXNTY2FsZTogd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICAgICAgc2VsZWN0aW9uQ29sb3IsXG4gICAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYLFxuICAgICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSxcbiAgICAgICAgICBjYW52YXNCYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUudmlld0JhY2tncm91bmRDb2xvcixcbiAgICAgICAgICB6b29tOiB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgcmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzOiBwb2ludGVyVmlld3BvcnRDb29yZHMsXG4gICAgICAgICAgcmVtb3RlUG9pbnRlckJ1dHRvbjogY3Vyc29yQnV0dG9uLFxuICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICByZW1vdGVQb2ludGVyVXNlcm5hbWVzOiBwb2ludGVyVXNlcm5hbWVzLFxuICAgICAgICAgIHJlbW90ZVBvaW50ZXJVc2VyU3RhdGVzOiBwb2ludGVyVXNlclN0YXRlcyxcbiAgICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRoaXMuc3RhdGUuc2hvdWxkQ2FjaGVJZ25vcmVab29tLFxuICAgICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgICAgIGltYWdlQ2FjaGU6IHRoaXMuaW1hZ2VDYWNoZSxcbiAgICAgICAgICBpc0V4cG9ydGluZzogZmFsc2UsXG4gICAgICAgICAgcmVuZGVyU2Nyb2xsYmFyczogIXRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgICB9LFxuICAgICAgICBjYWxsYmFjazogKHsgYXRMZWFzdE9uZVZpc2libGVFbGVtZW50LCBzY3JvbGxCYXJzIH0pID0+IHtcbiAgICAgICAgICBpZiAoc2Nyb2xsQmFycykge1xuICAgICAgICAgICAgY3VycmVudFNjcm9sbEJhcnMgPSBzY3JvbGxCYXJzO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBzY3JvbGxlZE91dHNpZGUgPVxuICAgICAgICAgICAgLy8gaGlkZSB3aGVuIGVkaXRpbmcgdGV4dFxuICAgICAgICAgICAgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICAgICAgICAgICA/IGZhbHNlXG4gICAgICAgICAgICAgIDogIWF0TGVhc3RPbmVWaXNpYmxlRWxlbWVudCAmJiByZW5kZXJpbmdFbGVtZW50cy5sZW5ndGggPiAwO1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNjcm9sbGVkT3V0c2lkZSAhPT0gc2Nyb2xsZWRPdXRzaWRlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2Nyb2xsZWRPdXRzaWRlIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuc2NoZWR1bGVJbWFnZVJlZnJlc2goKTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiAmJiB3aW5kb3cuRVhDQUxJRFJBV19USFJPVFRMRV9SRU5ERVIgPT09IHRydWUsXG4gICAgKTtcblxuICAgIGlmICghVEhST1RUTEVfTkVYVF9SRU5ERVIpIHtcbiAgICAgIFRIUk9UVExFX05FWFRfUkVOREVSID0gdHJ1ZTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvblNjcm9sbCA9IGRlYm91bmNlKCgpID0+IHtcbiAgICBjb25zdCB7IG9mZnNldFRvcCwgb2Zmc2V0TGVmdCB9ID0gdGhpcy5nZXRDYW52YXNPZmZzZXRzKCk7XG4gICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+IHtcbiAgICAgIGlmIChzdGF0ZS5vZmZzZXRMZWZ0ID09PSBvZmZzZXRMZWZ0ICYmIHN0YXRlLm9mZnNldFRvcCA9PT0gb2Zmc2V0VG9wKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH07XG4gICAgfSk7XG4gIH0sIFNDUk9MTF9USU1FT1VUKTtcblxuICAvLyBDb3B5L3Bhc3RlXG5cbiAgcHJpdmF0ZSBvbkN1dCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jdXRBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICBwcml2YXRlIG9uQ29weSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb3B5QWxsKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBjdXRBbGwgPSAoKSA9PiB7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uQ3V0LCBcImtleWJvYXJkXCIpO1xuICB9O1xuXG4gIHByaXZhdGUgY29weUFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25Db3B5LCBcImtleWJvYXJkXCIpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIHJlc2V0VGFwVHdpY2UoKSB7XG4gICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25UYXBTdGFydCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIC8vIGZpeCBmb3IgQXBwbGUgUGVuY2lsIFNjcmliYmxlXG4gICAgLy8gT24gQW5kcm9pZCwgcHJldmVudGluZyB0aGUgZXZlbnQgd291bGQgZGlzYWJsZSBjb250ZXh0TWVudSBvbiB0YXAtaG9sZFxuICAgIGlmICghaXNBbmRyb2lkKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIGlmICghZGlkVGFwVHdpY2UpIHtcbiAgICAgIGRpZFRhcFR3aWNlID0gdHJ1ZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICAgIHRhcHBlZFR3aWNlVGltZXIgPSB3aW5kb3cuc2V0VGltZW91dChcbiAgICAgICAgQXBwLnJlc2V0VGFwVHdpY2UsXG4gICAgICAgIFRBUF9UV0lDRV9USU1FT1VULFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gaW5zZXJ0IHRleHQgb25seSBpZiB3ZSB0YXBwZWQgdHdpY2Ugd2l0aCBhIHNpbmdsZSBmaW5nZXJcbiAgICAvLyBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSB3aWxsIGFsc28gcHJldmVudCBpbnNlcnRpbmcgdGV4dCB3aGVuIHVzZXIncyB6b29taW5nXG4gICAgaWYgKGRpZFRhcFR3aWNlICYmIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb25zdCBbdG91Y2hdID0gZXZlbnQudG91Y2hlcztcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHRoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2soe1xuICAgICAgICBjbGllbnRYOiB0b3VjaC5jbGllbnRYLFxuICAgICAgICBjbGllbnRZOiB0b3VjaC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgIH1cbiAgICBpZiAoaXNBbmRyb2lkKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvblRhcEVuZCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIHRoaXMucmVzZXRDb250ZXh0TWVudVRpbWVyKCk7XG4gICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuY2xlYXIoKTtcbiAgICB9XG4gIH07XG5cbiAgcHVibGljIHBhc3RlRnJvbUNsaXBib2FyZCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICBhc3luYyAoZXZlbnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbCkgPT4ge1xuICAgICAgY29uc3QgaXNQbGFpblBhc3RlID0gISEoSVNfUExBSU5fUEFTVEUgJiYgZXZlbnQpO1xuXG4gICAgICAvLyAjNjg2XG4gICAgICBjb25zdCB0YXJnZXQgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID1cbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKHRhcmdldCk7XG4gICAgICBpZiAoZXZlbnQgJiYgIWlzRXhjYWxpZHJhd0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVsZW1lbnRVbmRlckN1cnNvciA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoY3Vyc29yWCwgY3Vyc29yWSk7XG4gICAgICBpZiAoXG4gICAgICAgIGV2ZW50ICYmXG4gICAgICAgICghKGVsZW1lbnRVbmRlckN1cnNvciBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB8fFxuICAgICAgICAgIGlzV3JpdGFibGVFbGVtZW50KHRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBtdXN0IGJlIGNhbGxlZCBpbiB0aGUgc2FtZSBmcmFtZSAodGh1cyBiZWZvcmUgYW55IGF3YWl0cykgYXMgdGhlIHBhc3RlXG4gICAgICAvLyBldmVudCBlbHNlIHNvbWUgYnJvd3NlcnMgKEZGLi4uKSB3aWxsIGNsZWFyIHRoZSBjbGlwYm9hcmREYXRhXG4gICAgICAvLyAoc29tZXRoaW5nIHNvbWV0aGluZyBzZWN1cml0eSlcbiAgICAgIGxldCBmaWxlID0gZXZlbnQ/LmNsaXBib2FyZERhdGE/LmZpbGVzWzBdO1xuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcGFyc2VDbGlwYm9hcmQoZXZlbnQsIGlzUGxhaW5QYXN0ZSk7XG5cbiAgICAgIGlmICghZmlsZSAmJiBkYXRhLnRleHQgJiYgIWlzUGxhaW5QYXN0ZSkge1xuICAgICAgICBjb25zdCBzdHJpbmcgPSBkYXRhLnRleHQudHJpbSgpO1xuICAgICAgICBpZiAoc3RyaW5nLnN0YXJ0c1dpdGgoXCI8c3ZnXCIpICYmIHN0cmluZy5lbmRzV2l0aChcIjwvc3ZnPlwiKSkge1xuICAgICAgICAgIC8vIGlnbm9yZSBTVkcgdmFsaWRhdGlvbi9ub3JtYWxpemF0aW9uIHdoaWNoIHdpbGwgYmUgZG9uZSBkdXJpbmcgaW1hZ2VcbiAgICAgICAgICAvLyBpbml0aWFsaXphdGlvblxuICAgICAgICAgIGZpbGUgPSBTVkdTdHJpbmdUb0ZpbGUoc3RyaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBwcmVmZXIgc3ByZWFkc2hlZXQgZGF0YSBvdmVyIGltYWdlIGZpbGUgKE1TIE9mZmljZS9MaWJyZSBPZmZpY2UpXG4gICAgICBpZiAoaXNTdXBwb3J0ZWRJbWFnZUZpbGUoZmlsZSkgJiYgIWRhdGEuc3ByZWFkc2hlZXQpIHtcbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIHsgY2xpZW50WDogY3Vyc29yWCwgY2xpZW50WTogY3Vyc29yWSB9LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnByb3BzLm9uUGFzdGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoKGF3YWl0IHRoaXMucHJvcHMub25QYXN0ZShkYXRhLCBldmVudCkpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLmVycm9yTWVzc2FnZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBkYXRhLmVycm9yTWVzc2FnZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5zcHJlYWRzaGVldCAmJiAhaXNQbGFpblBhc3RlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHBhc3RlRGlhbG9nOiB7XG4gICAgICAgICAgICBkYXRhOiBkYXRhLnNwcmVhZHNoZWV0LFxuICAgICAgICAgICAgc2hvd246IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgLy8gVE9ETyByZW1vdmUgZm9ybWF0dGluZyBmcm9tIGVsZW1lbnRzIGlmIGlzUGxhaW5QYXN0ZVxuICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICBlbGVtZW50czogZGF0YS5lbGVtZW50cyxcbiAgICAgICAgICBmaWxlczogZGF0YS5maWxlcyB8fCBudWxsLFxuICAgICAgICAgIHBvc2l0aW9uOiBcImN1cnNvclwiLFxuICAgICAgICAgIHJldGFpblNlZWQ6IGlzUGxhaW5QYXN0ZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEudGV4dCkge1xuICAgICAgICB0aGlzLmFkZFRleHRGcm9tUGFzdGUoZGF0YS50ZXh0LCBpc1BsYWluUGFzdGUpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRBY3RpdmVUb29sKHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KTtcbiAgICAgIGV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBhZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSA9IChvcHRzOiB7XG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzIHwgbnVsbDtcbiAgICBwb3NpdGlvbjogeyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9IHwgXCJjdXJzb3JcIiB8IFwiY2VudGVyXCI7XG4gICAgcmV0YWluU2VlZD86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHJlc3RvcmVFbGVtZW50cyhvcHRzLmVsZW1lbnRzLCBudWxsKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoZWxlbWVudHMpO1xuXG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJYID0gZGlzdGFuY2UobWluWCwgbWF4WCkgLyAyO1xuICAgIGNvbnN0IGVsZW1lbnRzQ2VudGVyWSA9IGRpc3RhbmNlKG1pblksIG1heFkpIC8gMjtcblxuICAgIGNvbnN0IGNsaWVudFggPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFhcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWFxuICAgICAgICA6IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgIGNvbnN0IGNsaWVudFkgPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFlcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWVxuICAgICAgICA6IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGR4ID0geCAtIGVsZW1lbnRzQ2VudGVyWDtcbiAgICBjb25zdCBkeSA9IHkgLSBlbGVtZW50c0NlbnRlclk7XG5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChkeCwgZHksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3QgbmV3RWxlbWVudHMgPSBkdXBsaWNhdGVFbGVtZW50cyhcbiAgICAgIGVsZW1lbnRzLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlbWVudCwge1xuICAgICAgICAgIHg6IGVsZW1lbnQueCArIGdyaWRYIC0gbWluWCxcbiAgICAgICAgICB5OiBlbGVtZW50LnkgKyBncmlkWSAtIG1pblksXG4gICAgICAgIH0pO1xuICAgICAgfSksXG4gICAgICB7XG4gICAgICAgIHJhbmRvbWl6ZVNlZWQ6ICFvcHRzLnJldGFpblNlZWQsXG4gICAgICB9LFxuICAgICk7XG5cbiAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgLi4ubmV3RWxlbWVudHMsXG4gICAgXTtcblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRFbGVtZW50cyk7XG5cbiAgICBuZXdFbGVtZW50cy5mb3JFYWNoKChuZXdFbGVtZW50KSA9PiB7XG4gICAgICBpZiAoaXNUZXh0RWxlbWVudChuZXdFbGVtZW50KSAmJiBpc0JvdW5kVG9Db250YWluZXIobmV3RWxlbWVudCkpIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gZ2V0Q29udGFpbmVyRWxlbWVudChuZXdFbGVtZW50KTtcbiAgICAgICAgcmVkcmF3VGV4dEJvdW5kaW5nQm94KG5ld0VsZW1lbnQsIGNvbnRhaW5lcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4ub3B0cy5maWxlcyB9O1xuICAgIH1cblxuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB7XG4gICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICAvLyBrZWVwIHNpZGViYXIgKHByZXN1bWFibHkgdGhlIGxpYnJhcnkpIG9wZW4gaWYgaXQncyBkb2NrZWQgYW5kXG4gICAgICAgICAgLy8gY2FuIGZpdC5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIE5vdGUsIHdlIHNob3VsZCBjbG9zZSB0aGUgc2lkZWJhciBvbmx5IGlmIHdlJ3JlIGRyb3BwaW5nIGl0ZW1zXG4gICAgICAgICAgLy8gZnJvbSBsaWJyYXJ5LCBub3Qgd2hlbiBwYXN0aW5nIGZyb20gY2xpcGJvYXJkLiBBbGFzLlxuICAgICAgICAgIG9wZW5TaWRlYmFyOlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5vcGVuU2lkZWJhciAmJlxuICAgICAgICAgICAgdGhpcy5kZXZpY2UuY2FuRGV2aWNlRml0U2lkZWJhciAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5kZWZhdWx0U2lkZWJhckRvY2tlZFByZWZlcmVuY2VcbiAgICAgICAgICAgICAgPyB0aGlzLnN0YXRlLm9wZW5TaWRlYmFyXG4gICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld0VsZW1lbnRzLnJlZHVjZShcbiAgICAgICAgICAgIChhY2M6IFJlY29yZDxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdLCB0cnVlPiwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIWlzQm91bmRUb0NvbnRhaW5lcihlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIGFjY1tlbGVtZW50LmlkXSA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgKSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5zZXRBY3RpdmVUb29sKHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KTtcbiAgfTtcblxuICBwcml2YXRlIGFkZFRleHRGcm9tUGFzdGUodGV4dDogc3RyaW5nLCBpc1BsYWluUGFzdGUgPSBmYWxzZSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCB0ZXh0RWxlbWVudFByb3BzID0ge1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VuZG5lc3M6IG51bGwsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHRleHQsXG4gICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB0ZXh0QWxpZ246IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgY29uc3QgTElORV9HQVAgPSAxMDtcbiAgICBsZXQgY3VycmVudFkgPSB5O1xuXG4gICAgY29uc3QgbGluZXMgPSBpc1BsYWluUGFzdGUgPyBbdGV4dF0gOiB0ZXh0LnNwbGl0KFwiXFxuXCIpO1xuICAgIGNvbnN0IHRleHRFbGVtZW50cyA9IGxpbmVzLnJlZHVjZShcbiAgICAgIChhY2M6IEV4Y2FsaWRyYXdUZXh0RWxlbWVudFtdLCBsaW5lLCBpZHgpID0+IHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGxpbmUudHJpbSgpO1xuXG4gICAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBnZXREZWZhdWx0TGluZUhlaWdodCh0ZXh0RWxlbWVudFByb3BzLmZvbnRGYW1pbHkpO1xuICAgICAgICBpZiAodGV4dC5sZW5ndGgpIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgICAgICAgLi4udGV4dEVsZW1lbnRQcm9wcyxcbiAgICAgICAgICAgIHgsXG4gICAgICAgICAgICB5OiBjdXJyZW50WSxcbiAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICBsaW5lSGVpZ2h0LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGFjYy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgIGN1cnJlbnRZICs9IGVsZW1lbnQuaGVpZ2h0ICsgTElORV9HQVA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgcHJldkxpbmUgPSBsaW5lc1tpZHggLSAxXT8udHJpbSgpO1xuICAgICAgICAgIC8vIGFkZCBwYXJhZ3JhcGggb25seSBpZiBwcmV2aW91cyBsaW5lIHdhcyBub3QgZW1wdHksIElPVyBkb24ndCBhZGRcbiAgICAgICAgICAvLyBtb3JlIHRoYW4gb25lIGVtcHR5IGxpbmVcbiAgICAgICAgICBpZiAocHJldkxpbmUpIHtcbiAgICAgICAgICAgIGN1cnJlbnRZICs9XG4gICAgICAgICAgICAgIGdldExpbmVIZWlnaHRJblB4KHRleHRFbGVtZW50UHJvcHMuZm9udFNpemUsIGxpbmVIZWlnaHQpICtcbiAgICAgICAgICAgICAgTElORV9HQVA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICBbXSxcbiAgICApO1xuXG4gICAgaWYgKHRleHRFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgLi4udGV4dEVsZW1lbnRzLFxuICAgIF0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgdGV4dEVsZW1lbnRzLm1hcCgoZWwpID0+IFtlbC5pZCwgdHJ1ZV0pLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIGlmIChcbiAgICAgICFpc1BsYWluUGFzdGUgJiZcbiAgICAgIHRleHRFbGVtZW50cy5sZW5ndGggPiAxICYmXG4gICAgICBQTEFJTl9QQVNURV9UT0FTVF9TSE9XTiA9PT0gZmFsc2UgJiZcbiAgICAgICF0aGlzLmRldmljZS5pc01vYmlsZVxuICAgICkge1xuICAgICAgdGhpcy5zZXRUb2FzdCh7XG4gICAgICAgIG1lc3NhZ2U6IHQoXCJ0b2FzdC5wYXN0ZUFzU2luZ2xlRWxlbWVudFwiLCB7XG4gICAgICAgICAgc2hvcnRjdXQ6IGdldFNob3J0Y3V0S2V5KFwiQ3RybE9yQ21kK1NoaWZ0K1ZcIiksXG4gICAgICAgIH0pLFxuICAgICAgICBkdXJhdGlvbjogNTAwMCxcbiAgICAgIH0pO1xuICAgICAgUExBSU5fUEFTVEVfVE9BU1RfU0hPV04gPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgfVxuXG4gIHNldEFwcFN0YXRlOiBSZWFjdC5Db21wb25lbnQ8YW55LCBBcHBTdGF0ZT5bXCJzZXRTdGF0ZVwiXSA9IChcbiAgICBzdGF0ZSxcbiAgICBjYWxsYmFjayxcbiAgKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSwgY2FsbGJhY2spO1xuICB9O1xuXG4gIHJlbW92ZVBvaW50ZXIgPSAoZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MRWxlbWVudD4gfCBQb2ludGVyRXZlbnQpID0+IHtcbiAgICBpZiAodG91Y2hUaW1lb3V0KSB7XG4gICAgICB0aGlzLnJlc2V0Q29udGV4dE1lbnVUaW1lcigpO1xuICAgIH1cblxuICAgIGdlc3R1cmUucG9pbnRlcnMuZGVsZXRlKGV2ZW50LnBvaW50ZXJJZCk7XG4gIH07XG5cbiAgdG9nZ2xlTG9jayA9IChzb3VyY2U6IFwia2V5Ym9hcmRcIiB8IFwidWlcIiA9IFwidWlcIikgPT4ge1xuICAgIGlmICghdGhpcy5zdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgdHJhY2tFdmVudChcbiAgICAgICAgXCJ0b29sYmFyXCIsXG4gICAgICAgIFwidG9nZ2xlTG9ja1wiLFxuICAgICAgICBgJHtzb3VyY2V9ICgke3RoaXMuZGV2aWNlLmlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwifSlgLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBhY3RpdmVUb29sOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICAgICAgLi4udXBkYXRlQWN0aXZlVG9vbChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbC5sb2NrZWRcbiAgICAgICAgICAgICAgPyB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfVxuICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgICAgICksXG4gICAgICAgICAgbG9ja2VkOiAhcHJldlN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICB0b2dnbGVQZW5Nb2RlID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGVuTW9kZTogIXByZXZTdGF0ZS5wZW5Nb2RlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICBvbkhhbmRUb29sVG9nZ2xlID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvblRvZ2dsZUhhbmRUb29sKTtcbiAgfTtcblxuICAvKipcbiAgICogWm9vbXMgb24gY2FudmFzIHZpZXdwb3J0IGNlbnRlclxuICAgKi9cbiAgem9vbUNhbnZhcyA9IChcbiAgICAvKiogZGVjaW1hbCBmcmFjdGlvbiBiZXR3ZWVuIDAuMSAoMTAlIHpvb20pIGFuZCAzMCAoMzAwMCUgem9vbSkgKi9cbiAgICB2YWx1ZTogbnVtYmVyLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC4uLmdldFN0YXRlRm9yWm9vbShcbiAgICAgICAge1xuICAgICAgICAgIHZpZXdwb3J0WDogdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgICAgdmlld3BvcnRZOiB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgICBuZXh0Wm9vbTogZ2V0Tm9ybWFsaXplZFpvb20odmFsdWUpLFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGNhbmNlbEluUHJvZ3Jlc0FuaW1hdGlvbjogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cbiAgc2Nyb2xsVG9Db250ZW50ID0gKFxuICAgIHRhcmdldDpcbiAgICAgIHwgRXhjYWxpZHJhd0VsZW1lbnRcbiAgICAgIHwgcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXSA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgb3B0cz86IHsgZml0VG9Db250ZW50PzogYm9vbGVhbjsgYW5pbWF0ZT86IGJvb2xlYW47IGR1cmF0aW9uPzogbnVtYmVyIH0sXG4gICkgPT4ge1xuICAgIHRoaXMuY2FuY2VsSW5Qcm9ncmVzQW5pbWF0aW9uPy4oKTtcblxuICAgIC8vIGNvbnZlcnQgcHJvdmlkZWQgdGFyZ2V0IGludG8gRXhjYWxpZHJhd0VsZW1lbnRbXSBpZiBuZWNlc3NhcnlcbiAgICBjb25zdCB0YXJnZXRzID0gQXJyYXkuaXNBcnJheSh0YXJnZXQpID8gdGFyZ2V0IDogW3RhcmdldF07XG5cbiAgICBsZXQgem9vbSA9IHRoaXMuc3RhdGUuem9vbTtcbiAgICBsZXQgc2Nyb2xsWCA9IHRoaXMuc3RhdGUuc2Nyb2xsWDtcbiAgICBsZXQgc2Nyb2xsWSA9IHRoaXMuc3RhdGUuc2Nyb2xsWTtcblxuICAgIGlmIChvcHRzPy5maXRUb0NvbnRlbnQpIHtcbiAgICAgIC8vIGNvbXB1dGUgYW4gYXBwcm9wcmlhdGUgdmlld3BvcnQgbG9jYXRpb24gKHNjcm9sbCBYLCBZKSBhbmQgem9vbSBsZXZlbFxuICAgICAgLy8gdGhhdCBmaXQgdGhlIHRhcmdldCBlbGVtZW50cyBvbiB0aGUgc2NlbmVcbiAgICAgIGNvbnN0IHsgYXBwU3RhdGUgfSA9IHpvb21Ub0ZpdEVsZW1lbnRzKHRhcmdldHMsIHRoaXMuc3RhdGUsIGZhbHNlKTtcbiAgICAgIHpvb20gPSBhcHBTdGF0ZS56b29tO1xuICAgICAgc2Nyb2xsWCA9IGFwcFN0YXRlLnNjcm9sbFg7XG4gICAgICBzY3JvbGxZID0gYXBwU3RhdGUuc2Nyb2xsWTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gY29tcHV0ZSBvbmx5IHRoZSB2aWV3cG9ydCBsb2NhdGlvbiwgd2l0aG91dCBhbnkgem9vbSBhZGp1c3RtZW50XG4gICAgICBjb25zdCBzY3JvbGwgPSBjYWxjdWxhdGVTY3JvbGxDZW50ZXIodGFyZ2V0cywgdGhpcy5zdGF0ZSwgdGhpcy5jYW52YXMpO1xuICAgICAgc2Nyb2xsWCA9IHNjcm9sbC5zY3JvbGxYO1xuICAgICAgc2Nyb2xsWSA9IHNjcm9sbC5zY3JvbGxZO1xuICAgIH1cblxuICAgIC8vIHdoZW4gYW5pbWF0aW5nLCB3ZSB1c2UgUmVxdWVzdEFuaW1hdGlvbkZyYW1lIHRvIHByZXZlbnQgdGhlIGFuaW1hdGlvblxuICAgIC8vIGZyb20gc2xvd2luZyBkb3duIG90aGVyIHByb2Nlc3Nlc1xuICAgIGlmIChvcHRzPy5hbmltYXRlKSB7XG4gICAgICBjb25zdCBvcmlnU2Nyb2xsWCA9IHRoaXMuc3RhdGUuc2Nyb2xsWDtcbiAgICAgIGNvbnN0IG9yaWdTY3JvbGxZID0gdGhpcy5zdGF0ZS5zY3JvbGxZO1xuXG4gICAgICAvLyB6b29tIGFuaW1hdGlvbiBjb3VsZCBiZWNvbWUgcHJvYmxlbWF0aWMgb24gc2NlbmVzIHdpdGggbGFyZ2UgbnVtYmVyXG4gICAgICAvLyBvZiBlbGVtZW50cywgc2V0dGluZyBpdCB0byBpdHMgZmluYWwgdmFsdWUgdG8gaW1wcm92ZSB1c2VyIGV4cGVyaWVuY2UuXG4gICAgICAvL1xuICAgICAgLy8gdXNpbmcgem9vbUNhbnZhcygpIHRvIHpvb20gb24gY3VycmVudCB2aWV3cG9ydCBjZW50ZXJcbiAgICAgIHRoaXMuem9vbUNhbnZhcyh6b29tLnZhbHVlKTtcblxuICAgICAgY29uc3QgY2FuY2VsID0gZWFzZVRvVmFsdWVzUkFGKFxuICAgICAgICBbb3JpZ1Njcm9sbFgsIG9yaWdTY3JvbGxZXSxcbiAgICAgICAgW3Njcm9sbFgsIHNjcm9sbFldLFxuICAgICAgICAoc2Nyb2xsWCwgc2Nyb2xsWSkgPT4gdGhpcy5zZXRTdGF0ZSh7IHNjcm9sbFgsIHNjcm9sbFkgfSksXG4gICAgICAgIHsgZHVyYXRpb246IG9wdHM/LmR1cmF0aW9uID8/IDUwMCB9LFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2FuY2VsSW5Qcm9ncmVzQW5pbWF0aW9uID0gKCkgPT4ge1xuICAgICAgICBjYW5jZWwoKTtcbiAgICAgICAgdGhpcy5jYW5jZWxJblByb2dyZXNBbmltYXRpb24gPSBudWxsO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNjcm9sbFgsIHNjcm9sbFksIHpvb20gfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiB1c2Ugd2hlbiBjaGFuZ2luZyBzY3JvbGxYL3Njcm9sbFkvem9vbSBiYXNlZCBvbiB1c2VyIGludGVyYWN0aW9uICovXG4gIHByaXZhdGUgdHJhbnNsYXRlQ2FudmFzOiBSZWFjdC5Db21wb25lbnQ8YW55LCBBcHBTdGF0ZT5bXCJzZXRTdGF0ZVwiXSA9IChcbiAgICBzdGF0ZSxcbiAgKSA9PiB7XG4gICAgdGhpcy5jYW5jZWxJblByb2dyZXNBbmltYXRpb24/LigpO1xuICAgIHRoaXMuc2V0U3RhdGUoc3RhdGUpO1xuICB9O1xuXG4gIHNldFRvYXN0ID0gKFxuICAgIHRvYXN0OiB7XG4gICAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgICBjbG9zYWJsZT86IGJvb2xlYW47XG4gICAgICBkdXJhdGlvbj86IG51bWJlcjtcbiAgICB9IHwgbnVsbCxcbiAgKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHRvYXN0IH0pO1xuICB9O1xuXG4gIHJlc3RvcmVGaWxlRnJvbVNoYXJlID0gYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB3ZWJTaGFyZVRhcmdldENhY2hlID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUubWF0Y2goXCJzaGFyZWQtZmlsZVwiKTtcbiAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICBjb25zdCBibG9iID0gYXdhaXQgcmVzcG9uc2UuYmxvYigpO1xuICAgICAgICBjb25zdCBmaWxlID0gbmV3IEZpbGUoW2Jsb2JdLCBibG9iLm5hbWUgfHwgXCJcIiwgeyB0eXBlOiBibG9iLnR5cGUgfSk7XG4gICAgICAgIHRoaXMubG9hZEZpbGVUb0NhbnZhcyhmaWxlLCBudWxsKTtcbiAgICAgICAgYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5kZWxldGUoXCJzaGFyZWQtZmlsZVwiKTtcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsIEFQUF9OQU1FLCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiBhZGRzIHN1cHBsaWVkIGZpbGVzIHRvIGV4aXN0aW5nIGZpbGVzIGluIHRoZSBhcHBTdGF0ZSAqL1xuICBwdWJsaWMgYWRkRmlsZXM6IEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJW1wiYWRkRmlsZXNcIl0gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGZpbGVzKSA9PiB7XG4gICAgICBjb25zdCBmaWxlc01hcCA9IGZpbGVzLnJlZHVjZSgoYWNjLCBmaWxlRGF0YSkgPT4ge1xuICAgICAgICBhY2Muc2V0KGZpbGVEYXRhLmlkLCBmaWxlRGF0YSk7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCBuZXcgTWFwPEZpbGVJZCwgQmluYXJ5RmlsZURhdGE+KCkpO1xuXG4gICAgICB0aGlzLmZpbGVzID0geyAuLi50aGlzLmZpbGVzLCAuLi5PYmplY3QuZnJvbUVudHJpZXMoZmlsZXNNYXApIH07XG5cbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgIGZpbGVzTWFwLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmRlbGV0ZShlbGVtZW50LmZpbGVJZCk7XG4gICAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG5cbiAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgfSxcbiAgKTtcblxuICBwdWJsaWMgdXBkYXRlU2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgPEsgZXh0ZW5kcyBrZXlvZiBBcHBTdGF0ZT4oc2NlbmVEYXRhOiB7XG4gICAgICBlbGVtZW50cz86IFNjZW5lRGF0YVtcImVsZW1lbnRzXCJdO1xuICAgICAgYXBwU3RhdGU/OiBQaWNrPEFwcFN0YXRlLCBLPiB8IG51bGw7XG4gICAgICBjb2xsYWJvcmF0b3JzPzogU2NlbmVEYXRhW1wiY29sbGFib3JhdG9yc1wiXTtcbiAgICAgIGNvbW1pdFRvSGlzdG9yeT86IFNjZW5lRGF0YVtcImNvbW1pdFRvSGlzdG9yeVwiXTtcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoc2NlbmVEYXRhLmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuYXBwU3RhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShzY2VuZURhdGEuYXBwU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NlbmVEYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKHNjZW5lRGF0YS5lbGVtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuY29sbGFib3JhdG9ycykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29sbGFib3JhdG9yczogc2NlbmVEYXRhLmNvbGxhYm9yYXRvcnMgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uU2NlbmVVcGRhdGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBtZW51IHdhcyB0b2dnbGVkIG9uIG9yIG9mZlxuICAgKi9cbiAgcHVibGljIHRvZ2dsZVNpZGViYXIgPSAoe1xuICAgIG5hbWUsXG4gICAgdGFiLFxuICAgIGZvcmNlLFxuICB9OiB7XG4gICAgbmFtZTogU2lkZWJhck5hbWU7XG4gICAgdGFiPzogU2lkZWJhclRhYk5hbWU7XG4gICAgZm9yY2U/OiBib29sZWFuO1xuICB9KTogYm9vbGVhbiA9PiB7XG4gICAgbGV0IG5leHROYW1lO1xuICAgIGlmIChmb3JjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBuZXh0TmFtZSA9IHRoaXMuc3RhdGUub3BlblNpZGViYXI/Lm5hbWUgPT09IG5hbWUgPyBudWxsIDogbmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dE5hbWUgPSBmb3JjZSA/IG5hbWUgOiBudWxsO1xuICAgIH1cbiAgICB0aGlzLnNldFN0YXRlKHsgb3BlblNpZGViYXI6IG5leHROYW1lID8geyBuYW1lOiBuZXh0TmFtZSwgdGFiIH0gOiBudWxsIH0pO1xuXG4gICAgcmV0dXJuICEhbmV4dE5hbWU7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjdXJzb3JYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGN1cnNvclkgPSBldmVudC5jbGllbnRZO1xuICAgIH0sXG4gICk7XG5cbiAgLy8gSW5wdXQgaGFuZGxpbmdcbiAgcHJpdmF0ZSBvbktleURvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBSZWFjdC5LZXlib2FyZEV2ZW50IHwgS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gbm9ybWFsaXplIGBldmVudC5rZXlgIHdoZW4gQ2Fwc0xvY2sgaXMgcHJlc3NlZCAjMjM3MlxuXG4gICAgICBpZiAoXG4gICAgICAgIFwiUHJveHlcIiBpbiB3aW5kb3cgJiZcbiAgICAgICAgKCghZXZlbnQuc2hpZnRLZXkgJiYgL15bQS1aXSQvLnRlc3QoZXZlbnQua2V5KSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXkgJiYgL15bYS16XSQvLnRlc3QoZXZlbnQua2V5KSkpXG4gICAgICApIHtcbiAgICAgICAgZXZlbnQgPSBuZXcgUHJveHkoZXZlbnQsIHtcbiAgICAgICAgICBnZXQoZXY6IGFueSwgcHJvcCkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBldltwcm9wXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAvLyBmaXggZm9yIFByb3hpZXMgaGlqYWNraW5nIGB0aGlzYFxuICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYmluZChldik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvcCA9PT0gXCJrZXlcIlxuICAgICAgICAgICAgICA/IC8vIENhcHNMb2NrIGludmVydHMgY2FwaXRhbGl6YXRpb24gYmFzZWQgb24gU2hpZnRLZXksIHNvIGludmVydFxuICAgICAgICAgICAgICAgIC8vIGl0IGJhY2tcbiAgICAgICAgICAgICAgICBldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICAgID8gZXYua2V5LnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgICAgICA6IGV2LmtleS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgIDogdmFsdWU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiBldmVudC5rZXkudG9Mb3dlckNhc2UoKSA9PT0gS0VZUy5WKSB7XG4gICAgICAgIElTX1BMQUlOX1BBU1RFID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgIGNsZWFyVGltZW91dChJU19QTEFJTl9QQVNURV9USU1FUik7XG4gICAgICAgIC8vIHJlc2V0ICgxMDBtcyB0byBiZSBzYWZlIHRoYXQgd2UgaXQgcnVucyBhZnRlciB0aGUgZW5zdWluZ1xuICAgICAgICAvLyBwYXN0ZSBldmVudCkuIFRob3VnaCwgdGVjaG5pY2FsbHkgdW5uZWNlc3NhcnkgdG8gcmVzZXQgc2luY2Ugd2VcbiAgICAgICAgLy8gKHJlKXNldCB0aGUgZmxhZyBiZWZvcmUgZWFjaCBwYXN0ZSBldmVudC5cbiAgICAgICAgSVNfUExBSU5fUEFTVEVfVElNRVIgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgSVNfUExBSU5fUEFTVEUgPSBmYWxzZTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICAgIH1cblxuICAgICAgLy8gcHJldmVudCBicm93c2VyIHpvb20gaW4gaW5wdXQgZmllbGRzXG4gICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gQ09ERVMuTUlOVVMgfHwgZXZlbnQuY29kZSA9PT0gQ09ERVMuRVFVQUwpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBiYWlsIGlmXG4gICAgICBpZiAoXG4gICAgICAgIC8vIGluc2lkZSBhbiBpbnB1dFxuICAgICAgICAoaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSAmJlxuICAgICAgICAgIC8vIHVubGVzcyBwcmVzc2luZyBlc2NhcGUgKGZpbmFsaXplIGFjdGlvbilcbiAgICAgICAgICBldmVudC5rZXkgIT09IEtFWVMuRVNDQVBFKSB8fFxuICAgICAgICAvLyBvciB1bmxlc3MgdXNpbmcgYXJyb3dzICh0byBtb3ZlIGJldHdlZW4gYnV0dG9ucylcbiAgICAgICAgKGlzQXJyb3dLZXkoZXZlbnQua2V5KSAmJiBpc0lucHV0TGlrZShldmVudC50YXJnZXQpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5RVUVTVElPTl9NQVJLKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIG9wZW5EaWFsb2c6IFwiaGVscFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXZlbnQua2V5LnRvTG93ZXJDYXNlKCkgPT09IEtFWVMuRSAmJlxuICAgICAgICBldmVudC5zaGlmdEtleSAmJlxuICAgICAgICBldmVudFtLRVlTLkNUUkxfT1JfQ01EXVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuRGlhbG9nOiBcImltYWdlRXhwb3J0XCIgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5QQUdFX1VQIHx8IGV2ZW50LmtleSA9PT0gS0VZUy5QQUdFX0RPV04pIHtcbiAgICAgICAgbGV0IG9mZnNldCA9XG4gICAgICAgICAgKGV2ZW50LnNoaWZ0S2V5ID8gdGhpcy5zdGF0ZS53aWR0aCA6IHRoaXMuc3RhdGUuaGVpZ2h0KSAvXG4gICAgICAgICAgdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlBBR0VfRE9XTikge1xuICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgdGhpcy50cmFuc2xhdGVDYW52YXMoKHN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgc2Nyb2xsWDogc3RhdGUuc2Nyb2xsWCArIG9mZnNldCxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy50cmFuc2xhdGVDYW52YXMoKHN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgc2Nyb2xsWTogc3RhdGUuc2Nyb2xsWSArIG9mZnNldCxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYWN0aW9uTWFuYWdlci5oYW5kbGVLZXlEb3duKGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiB0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IGZhbHNlIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAgICh0aGlzLnN0YXRlLmdyaWRTaXplICYmXG4gICAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgPyBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmdyaWRTaXplKSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgID8gRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5UXG4gICAgICAgICAgICA6IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCk7XG5cbiAgICAgICAgbGV0IG9mZnNldFggPSAwO1xuICAgICAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19MRUZUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19SSUdIVCkge1xuICAgICAgICAgIG9mZnNldFggPSBzdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19VUCkge1xuICAgICAgICAgIG9mZnNldFkgPSAtc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfRE9XTikge1xuICAgICAgICAgIG9mZnNldFkgPSBzdGVwO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICk7XG5cbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgICAgICB4OiBlbGVtZW50LnggKyBvZmZzZXRYLFxuICAgICAgICAgICAgeTogZWxlbWVudC55ICsgb2Zmc2V0WSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCwge1xuICAgICAgICAgICAgc2ltdWx0YW5lb3VzbHlVcGRhdGVkOiBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVOVEVSKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcbiAgICAgICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgICAgICAgIGlmIChpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50KSkge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT1cbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0uaWRcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgIGlzVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50KSB8fFxuICAgICAgICAgICAgaXNWYWxpZFRleHRDb250YWluZXIoc2VsZWN0ZWRFbGVtZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgbGV0IGNvbnRhaW5lcjtcbiAgICAgICAgICAgIGlmICghaXNUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgIGNvbnRhaW5lciA9IHNlbGVjdGVkRWxlbWVudCBhcyBFeGNhbGlkcmF3VGV4dENvbnRhaW5lcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG1pZFBvaW50ID0gZ2V0Q29udGFpbmVyQ2VudGVyKHNlbGVjdGVkRWxlbWVudCwgdGhpcy5zdGF0ZSk7XG4gICAgICAgICAgICBjb25zdCBzY2VuZVggPSBtaWRQb2ludC54O1xuICAgICAgICAgICAgY29uc3Qgc2NlbmVZID0gbWlkUG9pbnQueTtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgICAgICAgIHNjZW5lWCxcbiAgICAgICAgICAgICAgc2NlbmVZLFxuICAgICAgICAgICAgICBjb250YWluZXIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAhZXZlbnQuY3RybEtleSAmJlxuICAgICAgICAhZXZlbnQuYWx0S2V5ICYmXG4gICAgICAgICFldmVudC5tZXRhS2V5ICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50ID09PSBudWxsXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBmaW5kU2hhcGVCeUtleShldmVudC5rZXkpO1xuICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IHNoYXBlKSB7XG4gICAgICAgICAgICB0cmFja0V2ZW50KFxuICAgICAgICAgICAgICBcInRvb2xiYXJcIixcbiAgICAgICAgICAgICAgc2hhcGUsXG4gICAgICAgICAgICAgIGBrZXlib2FyZCAoJHt0aGlzLmRldmljZS5pc01vYmlsZSA/IFwibW9iaWxlXCIgOiBcImRlc2t0b3BcIn0pYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0QWN0aXZlVG9vbCh7IHR5cGU6IHNoYXBlIH0pO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5RKSB7XG4gICAgICAgICAgdGhpcy50b2dnbGVMb2NrKFwia2V5Ym9hcmRcIik7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuU1BBQ0UgJiYgZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAwKSB7XG4gICAgICAgIGlzSG9sZGluZ1NwYWNlID0gdHJ1ZTtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAoZXZlbnQua2V5ID09PSBLRVlTLkcgfHwgZXZlbnQua2V5ID09PSBLRVlTLlMpICYmXG4gICAgICAgICFldmVudC5hbHRLZXkgJiZcbiAgICAgICAgIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgICAhc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGhcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIGV2ZW50LmtleSA9PT0gS0VZUy5HICYmXG4gICAgICAgICAgKGhhc0JhY2tncm91bmQodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUpIHx8XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLnNvbWUoKGVsZW1lbnQpID0+IGhhc0JhY2tncm91bmQoZWxlbWVudC50eXBlKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwiZWxlbWVudEJhY2tncm91bmRcIiB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlMpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgb3BlblBvcHVwOiBcImVsZW1lbnRTdHJva2VcIiB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmXG4gICAgICAgIChldmVudC5rZXkgPT09IEtFWVMuQkFDS1NQQUNFIHx8IGV2ZW50LmtleSA9PT0gS0VZUy5ERUxFVEUpXG4gICAgICApIHtcbiAgICAgICAgam90YWlTdG9yZS5zZXQoYWN0aXZlQ29uZmlybURpYWxvZ0F0b20sIFwiY2xlYXJDYW52YXNcIik7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uV2hlZWwgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBXaGVlbEV2ZW50KSA9PiB7XG4gICAgLy8gcHJldmVudCBicm93c2VyIHBpbmNoIHpvb20gb24gRE9NIGVsZW1lbnRzXG4gICAgaWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpICYmIGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9KTtcblxuICBwcml2YXRlIG9uS2V5VXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSkge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmICF0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgIH1cbiAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgID8gYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50cyhzZWxlY3RlZEVsZW1lbnRzKVxuICAgICAgICA6IHVuYmluZExpbmVhckVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgc2V0QWN0aXZlVG9vbCA9IChcbiAgICB0b29sOlxuICAgICAgfCB7XG4gICAgICAgICAgdHlwZTogdHlwZW9mIFNIQVBFU1tudW1iZXJdW1widmFsdWVcIl0gfCBcImVyYXNlclwiIHwgXCJoYW5kXCI7XG4gICAgICAgICAgbG9ja2VkPzogYm9vbGVhbjtcbiAgICAgICAgfVxuICAgICAgfCB7IHR5cGU6IFwiY3VzdG9tXCI7IGN1c3RvbVR5cGU6IHN0cmluZzsgbG9ja2VkPzogYm9vbGVhbiB9LFxuICApID0+IHtcbiAgICBjb25zdCBuZXh0QWN0aXZlVG9vbCA9IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgdG9vbCk7XG4gICAgaWYgKG5leHRBY3RpdmVUb29sLnR5cGUgPT09IFwiaGFuZFwiKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgIH0gZWxzZSBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgfVxuICAgIGlmIChpc1Rvb2xJY29uKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgfVxuICAgIGlmICghaXNMaW5lYXJFbGVtZW50VHlwZShuZXh0QWN0aXZlVG9vbC50eXBlKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICB9XG4gICAgaWYgKG5leHRBY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgdGhpcy5vbkltYWdlQWN0aW9uKCk7XG4gICAgfVxuICAgIGlmIChuZXh0QWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgYWN0aXZlVG9vbDogbmV4dEFjdGl2ZVRvb2wsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgYWN0aXZlVG9vbDogbmV4dEFjdGl2ZVRvb2wgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc2V0Q3Vyc29yID0gKGN1cnNvcjogc3RyaW5nKSA9PiB7XG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBjdXJzb3IpO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRDdXJzb3IgPSAoKSA9PiB7XG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICB9O1xuICAvKipcbiAgICogcmV0dXJucyB3aGV0aGVyIHVzZXIgaXMgbWFraW5nIGEgZ2VzdHVyZSB3aXRoID49IDIgZmluZ2VycyAocG9pbnRzKVxuICAgKiBvbiBvIHRvdWNoIHNjcmVlbiAobm90IG9uIGEgdHJhY2twYWQpLiBDdXJyZW50bHkgb25seSByZWxhdGVzIHRvIERhcndpblxuICAgKiAoaU9TL2lQYWRPUyxNYWNPUyksIGJ1dCBtYXkgd29yayBvbiBvdGhlciBkZXZpY2VzIGluIHRoZSBmdXR1cmUgaWZcbiAgICogR2VzdHVyZUV2ZW50IGlzIHN0YW5kYXJkaXplZC5cbiAgICovXG4gIHByaXZhdGUgaXNUb3VjaFNjcmVlbk11bHRpVG91Y2hHZXN0dXJlID0gKCkgPT4ge1xuICAgIC8vIHdlIGRvbid0IHdhbnQgdG8gZGVzZWxlY3Qgd2hlbiB1c2luZyB0cmFja3BhZCwgYW5kIG11bHRpLXBvaW50IGdlc3R1cmVzXG4gICAgLy8gb25seSB3b3JrIG9uIHRvdWNoIHNjcmVlbnMsIHNvIGNoZWNraW5nIGZvciA+PSBwb2ludGVycyBtZWFucyB3ZSdyZSBvbiBhXG4gICAgLy8gdG91Y2hzY3JlZW5cbiAgICByZXR1cm4gZ2VzdHVyZS5wb2ludGVycy5zaXplID49IDI7XG4gIH07XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVTdGFydCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAvLyB3ZSBvbmx5IHdhbnQgdG8gZGVzZWxlY3Qgb24gdG91Y2ggc2NyZWVucyBiZWNhdXNlIHVzZXIgbWF5IGhhdmUgc2VsZWN0ZWRcbiAgICAvLyBlbGVtZW50cyBieSBtaXN0YWtlIHdoaWxlIHpvb21pbmdcbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gIH0pO1xuXG4gIC8vIGZpcmVzIG9ubHkgb24gU2FmYXJpXG4gIHByaXZhdGUgb25HZXN0dXJlQ2hhbmdlID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIG9uR2VzdHVyZUNoYW5nZSBvbmx5IGhhcyB6b29tIGZhY3RvciBidXQgbm90IHRoZSBjZW50ZXIuXG4gICAgLy8gSWYgd2UncmUgb24gaVBhZCBvciBpUGhvbmUsIHRoZW4gd2UgcmVjb2duaXplIG11bHRpLXRvdWNoIGFuZCB3aWxsXG4gICAgLy8gem9vbSBpbiBhdCB0aGUgcmlnaHQgbG9jYXRpb24gaW4gdGhlIHRvdWNobW92ZSBoYW5kbGVyXG4gICAgLy8gKGhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlKS5cbiAgICAvL1xuICAgIC8vIE9uIE1hY2Jvb2sgdHJhY2twYWQsIHdlIGRvbid0IGhhdmUgdGhvc2UgZXZlbnRzIHNvIHdpbGwgem9vbSBpbiBhdCB0aGVcbiAgICAvLyBjdXJyZW50IGxvY2F0aW9uIGluc3RlYWQuXG4gICAgLy9cbiAgICAvLyBBcyBzdWNoLCBiYWlsIGZyb20gdGhpcyBoYW5kbGVyIG9uIHRvdWNoIGRldmljZXMuXG4gICAgaWYgKHRoaXMuaXNUb3VjaFNjcmVlbk11bHRpVG91Y2hHZXN0dXJlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoaW5pdGlhbFNjYWxlKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgLi4uZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY3Vyc29yWCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY3Vyc29yWSxcbiAgICAgICAgICAgIG5leHRab29tOiBnZXROb3JtYWxpemVkWm9vbShpbml0aWFsU2NhbGUgKiBldmVudC5zY2FsZSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGZpcmVzIG9ubHkgb24gU2FmYXJpXG4gIHByaXZhdGUgb25HZXN0dXJlRW5kID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAvLyByZXNlbGVjdCBlbGVtZW50cyBvbmx5IG9uIHRvdWNoIHNjcmVlbnMgKHNlZSBvbkdlc3R1cmVTdGFydClcbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gbnVsbDtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0V3lzaXd5ZyhcbiAgICBlbGVtZW50OiBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gICAge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQgPSBmYWxzZSxcbiAgICB9OiB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudCA9IChcbiAgICAgIHRleHQ6IHN0cmluZyxcbiAgICAgIG9yaWdpbmFsVGV4dDogc3RyaW5nLFxuICAgICAgaXNEZWxldGVkOiBib29sZWFuLFxuICAgICkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoX2VsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoX2VsZW1lbnQuaWQgPT09IGVsZW1lbnQuaWQgJiYgaXNUZXh0RWxlbWVudChfZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVUZXh0RWxlbWVudChfZWxlbWVudCwge1xuICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICBpc0RlbGV0ZWQsXG4gICAgICAgICAgICAgIG9yaWdpbmFsVGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX2VsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgfTtcblxuICAgIHRleHRXeXNpd3lnKHtcbiAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgY2FudmFzOiB0aGlzLmNhbnZhcyxcbiAgICAgIGdldFZpZXdwb3J0Q29vcmRzOiAoeCwgeSkgPT4ge1xuICAgICAgICBjb25zdCB7IHg6IHZpZXdwb3J0WCwgeTogdmlld3BvcnRZIH0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2NlbmVYOiB4LFxuICAgICAgICAgICAgc2NlbmVZOiB5LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICB2aWV3cG9ydFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgICAgdmlld3BvcnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgICAgIF07XG4gICAgICB9LFxuICAgICAgb25DaGFuZ2U6IHdpdGhCYXRjaGVkVXBkYXRlcygodGV4dCkgPT4ge1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIHRleHQsIGZhbHNlKTtcbiAgICAgICAgaWYgKGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICAgIG9uU3VibWl0OiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKHsgdGV4dCwgdmlhS2V5Ym9hcmQsIG9yaWdpbmFsVGV4dCB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGlzRGVsZXRlZCA9ICF0ZXh0LnRyaW0oKTtcbiAgICAgICAgdXBkYXRlRWxlbWVudCh0ZXh0LCBvcmlnaW5hbFRleHQsIGlzRGVsZXRlZCk7XG4gICAgICAgIC8vIHNlbGVjdCB0aGUgY3JlYXRlZCB0ZXh0IGVsZW1lbnQgb25seSBpZiBzdWJtaXR0aW5nIHZpYSBrZXlib2FyZFxuICAgICAgICAvLyAod2hlbiBzdWJtaXR0aW5nIHZpYSBjbGljayBpdCBzaG91bGQgYWN0IGFzIHNpZ25hbCB0byBkZXNlbGVjdClcbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgJiYgdmlhS2V5Ym9hcmQpIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50SWRUb1NlbGVjdCA9IGVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgICAgID8gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgOiBlbGVtZW50LmlkO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICBbZWxlbWVudElkVG9TZWxlY3RdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVsZXRlZCkge1xuICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbih0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCBbXG4gICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIF0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNEZWxldGVkIHx8IGlzRXhpc3RpbmdFbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgICB9KSxcbiAgICAgIGVsZW1lbnQsXG4gICAgICBleGNhbGlkcmF3Q29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCxcbiAgICAgIGFwcDogdGhpcyxcbiAgICB9KTtcbiAgICAvLyBkZXNlbGVjdCBhbGwgb3RoZXIgZWxlbWVudHMgd2hlbiBpbnNlcnRpbmcgdGV4dFxuICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuXG4gICAgLy8gZG8gYW4gaW5pdGlhbCB1cGRhdGUgdG8gcmUtaW5pdGlhbGl6ZSBlbGVtZW50IHBvc2l0aW9uIHNpbmNlIHdlIHdlcmVcbiAgICAvLyBtb2RpZnlpbmcgZWxlbWVudCdzIHgveSBmb3Igc2FrZSBvZiBlZGl0b3IgKGNhc2U6IHN5bmNpbmcgdG8gcmVtb3RlKVxuICAgIHVwZGF0ZUVsZW1lbnQoZWxlbWVudC50ZXh0LCBlbGVtZW50Lm9yaWdpbmFsVGV4dCwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXNlbGVjdEVsZW1lbnRzKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdUZXh0RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcbiAgICBpZiAoZWxlbWVudCAmJiBpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmICFlbGVtZW50LmlzRGVsZXRlZCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIG9wdHM/OiB7XG4gICAgICAvKiogaWYgdHJ1ZSwgcmV0dXJucyB0aGUgZmlyc3Qgc2VsZWN0ZWQgZWxlbWVudCAod2l0aCBoaWdoZXN0IHotaW5kZXgpXG4gICAgICAgIG9mIGFsbCBoaXQgZWxlbWVudHMgKi9cbiAgICAgIHByZWZlclNlbGVjdGVkPzogYm9vbGVhbjtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50PzogYm9vbGVhbjtcbiAgICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50cz86IGJvb2xlYW47XG4gICAgfSxcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBhbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBvcHRzPy5pbmNsdWRlQm91bmRUZXh0RWxlbWVudCxcbiAgICAgIG9wdHM/LmluY2x1ZGVMb2NrZWRFbGVtZW50cyxcbiAgICApO1xuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICBpZiAob3B0cz8ucHJlZmVyU2VsZWN0ZWQpIHtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSBhbGxIaXRFbGVtZW50cy5sZW5ndGggLSAxOyBpbmRleCA+IC0xOyBpbmRleC0tKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2FsbEhpdEVsZW1lbnRzW2luZGV4XS5pZF0pIHtcbiAgICAgICAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1tpbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXggPVxuICAgICAgICBhbGxIaXRFbGVtZW50c1thbGxIaXRFbGVtZW50cy5sZW5ndGggLSAxXTtcbiAgICAgIC8vIElmIHdlJ3JlIGhpdHRpbmcgZWxlbWVudCB3aXRoIGhpZ2hlc3Qgei1pbmRleCBvbmx5IG9uIGl0cyBib3VuZGluZyBib3hcbiAgICAgIC8vIHdoaWxlIGFsc28gaGl0dGluZyBvdGhlciBlbGVtZW50IGZpZ3VyZSwgdGhlIGxhdHRlciBzaG91bGQgYmUgY29uc2lkZXJlZC5cbiAgICAgIHJldHVybiBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgIGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIClcbiAgICAgICAgPyBhbGxIaXRFbGVtZW50c1thbGxIaXRFbGVtZW50cy5sZW5ndGggLSAyXVxuICAgICAgICA6IGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleDtcbiAgICB9XG4gICAgaWYgKGFsbEhpdEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGFsbEhpdEVsZW1lbnRzWzBdO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBpbmNsdWRlTG9ja2VkRWxlbWVudHM6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD5bXSB7XG4gICAgY29uc3QgZWxlbWVudHMgPVxuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQgJiYgaW5jbHVkZUxvY2tlZEVsZW1lbnRzXG4gICAgICAgID8gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICA6IHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgICAgKGVsZW1lbnQpID0+XG4gICAgICAgICAgICAgICAgKGluY2x1ZGVMb2NrZWRFbGVtZW50cyB8fCAhZWxlbWVudC5sb2NrZWQpICYmXG4gICAgICAgICAgICAgICAgKGluY2x1ZGVCb3VuZFRleHRFbGVtZW50IHx8XG4gICAgICAgICAgICAgICAgICAhKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgZWxlbWVudC5jb250YWluZXJJZCkpLFxuICAgICAgICAgICAgKTtcblxuICAgIHJldHVybiBnZXRFbGVtZW50c0F0UG9zaXRpb24oZWxlbWVudHMsIChlbGVtZW50KSA9PlxuICAgICAgaGl0VGVzdChlbGVtZW50LCB0aGlzLnN0YXRlLCB4LCB5KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFRleHRFZGl0aW5nID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICAgIGluc2VydEF0UGFyZW50Q2VudGVyID0gdHJ1ZSxcbiAgICBjb250YWluZXIsXG4gIH06IHtcbiAgICAvKiogWCBwb3NpdGlvbiB0byBpbnNlcnQgdGV4dCBhdCAqL1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIC8qKiBZIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVZOiBudW1iZXI7XG4gICAgLyoqIHdoZXRoZXIgdG8gYXR0ZW1wdCB0byBpbnNlcnQgYXQgZWxlbWVudCBjZW50ZXIgaWYgYXBwbGljYWJsZSAqL1xuICAgIGluc2VydEF0UGFyZW50Q2VudGVyPzogYm9vbGVhbjtcbiAgICBjb250YWluZXI/OiBFeGNhbGlkcmF3VGV4dENvbnRhaW5lciB8IG51bGw7XG4gIH0pID0+IHtcbiAgICBsZXQgc2hvdWxkQmluZFRvQ29udGFpbmVyID0gZmFsc2U7XG5cbiAgICBsZXQgcGFyZW50Q2VudGVyUG9zaXRpb24gPVxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgJiZcbiAgICAgIHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIGNvbnRhaW5lcixcbiAgICAgICk7XG4gICAgaWYgKGNvbnRhaW5lciAmJiBwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgc2hvdWxkQmluZFRvQ29udGFpbmVyID0gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGV4aXN0aW5nVGV4dEVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd1RleHRFbGVtZW50PiB8IG51bGwgPSBudWxsO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBpZiAoaXNUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSkge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcbiAgICAgIH0gZWxzZSBpZiAoY29udGFpbmVyKSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSBnZXRCb3VuZFRleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcbiAgICB9XG5cbiAgICBjb25zdCBmb250RmFtaWx5ID1cbiAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQ/LmZvbnRGYW1pbHkgfHwgdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHk7XG5cbiAgICBjb25zdCBsaW5lSGVpZ2h0ID1cbiAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQ/LmxpbmVIZWlnaHQgfHwgZ2V0RGVmYXVsdExpbmVIZWlnaHQoZm9udEZhbWlseSk7XG4gICAgY29uc3QgZm9udFNpemUgPSB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemU7XG5cbiAgICBpZiAoXG4gICAgICAhZXhpc3RpbmdUZXh0RWxlbWVudCAmJlxuICAgICAgc2hvdWxkQmluZFRvQ29udGFpbmVyICYmXG4gICAgICBjb250YWluZXIgJiZcbiAgICAgICFpc0Fycm93RWxlbWVudChjb250YWluZXIpXG4gICAgKSB7XG4gICAgICBjb25zdCBmb250U3RyaW5nID0ge1xuICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgZm9udEZhbWlseSxcbiAgICAgIH07XG4gICAgICBjb25zdCBtaW5XaWR0aCA9IGdldEFwcHJveE1pbkxpbmVXaWR0aChcbiAgICAgICAgZ2V0Rm9udFN0cmluZyhmb250U3RyaW5nKSxcbiAgICAgICAgbGluZUhlaWdodCxcbiAgICAgICk7XG4gICAgICBjb25zdCBtaW5IZWlnaHQgPSBnZXRBcHByb3hNaW5MaW5lSGVpZ2h0KGZvbnRTaXplLCBsaW5lSGVpZ2h0KTtcbiAgICAgIGNvbnN0IGNvbnRhaW5lckRpbXMgPSBnZXRDb250YWluZXJEaW1zKGNvbnRhaW5lcik7XG4gICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1heChjb250YWluZXJEaW1zLmhlaWdodCwgbWluSGVpZ2h0KTtcbiAgICAgIGNvbnN0IG5ld1dpZHRoID0gTWF0aC5tYXgoY29udGFpbmVyRGltcy53aWR0aCwgbWluV2lkdGgpO1xuICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBuZXdIZWlnaHQsIHdpZHRoOiBuZXdXaWR0aCB9KTtcbiAgICAgIHNjZW5lWCA9IGNvbnRhaW5lci54ICsgbmV3V2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gY29udGFpbmVyLnkgKyBuZXdIZWlnaHQgLyAyO1xuICAgICAgaWYgKHBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICAgIHBhcmVudENlbnRlclBvc2l0aW9uID0gdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICAgIHNjZW5lWCxcbiAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXIsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnQgPSBleGlzdGluZ1RleHRFbGVtZW50XG4gICAgICA/IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgIDogbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgICAgIHg6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJYXG4gICAgICAgICAgICA6IHNjZW5lWCxcbiAgICAgICAgICB5OiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBwYXJlbnRDZW50ZXJQb3NpdGlvbi5lbGVtZW50Q2VudGVyWVxuICAgICAgICAgICAgOiBzY2VuZVksXG4gICAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgICAgdGV4dDogXCJcIixcbiAgICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgICBmb250RmFtaWx5LFxuICAgICAgICAgIHRleHRBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gXCJjZW50ZXJcIlxuICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtVGV4dEFsaWduLFxuICAgICAgICAgIHZlcnRpY2FsQWxpZ246IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IFZFUlRJQ0FMX0FMSUdOLk1JRERMRVxuICAgICAgICAgICAgOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgICAgICAgIGNvbnRhaW5lcklkOiBzaG91bGRCaW5kVG9Db250YWluZXIgPyBjb250YWluZXI/LmlkIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGdyb3VwSWRzOiBjb250YWluZXI/Lmdyb3VwSWRzID8/IFtdLFxuICAgICAgICAgIGxpbmVIZWlnaHQsXG4gICAgICAgICAgYW5nbGU6IGNvbnRhaW5lcj8uYW5nbGUgPz8gMCxcbiAgICAgICAgfSk7XG5cbiAgICBpZiAoIWV4aXN0aW5nVGV4dEVsZW1lbnQgJiYgc2hvdWxkQmluZFRvQ29udGFpbmVyICYmIGNvbnRhaW5lcikge1xuICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHtcbiAgICAgICAgYm91bmRFbGVtZW50czogKGNvbnRhaW5lci5ib3VuZEVsZW1lbnRzIHx8IFtdKS5jb25jYXQoe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgICBpZiAoIWV4aXN0aW5nVGV4dEVsZW1lbnQpIHtcbiAgICAgIGlmIChjb250YWluZXIgJiYgc2hvdWxkQmluZFRvQ29udGFpbmVyKSB7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lckluZGV4ID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50SW5kZXgoY29udGFpbmVyLmlkKTtcbiAgICAgICAgdGhpcy5zY2VuZS5pbnNlcnRFbGVtZW50QXRJbmRleChlbGVtZW50LCBjb250YWluZXJJbmRleCArIDEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlVGV4dFd5c2l3eWcoZWxlbWVudCwge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ6ICEhZXhpc3RpbmdUZXh0RWxlbWVudCxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Nb3VzZUV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gY2FzZTogZG91YmxlLWNsaWNraW5nIHdpdGggYXJyb3cvbGluZSB0b29sIHNlbGVjdGVkIHdvdWxkIGJvdGggY3JlYXRlXG4gICAgLy8gdGV4dCBhbmQgZW50ZXIgbXVsdGlFbGVtZW50IG1vZGVcbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gd2Ugc2hvdWxkIG9ubHkgYmUgYWJsZSB0byBkb3VibGUgY2xpY2sgd2hlbiBtb2RlIGlzIHNlbGVjdGlvblxuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiZcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgIT09IHNlbGVjdGVkRWxlbWVudHNbMF0uaWQpXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICApLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCA9PT0gc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG5cbiAgICBsZXQgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgZXZlbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWRzID0gZ2V0U2VsZWN0ZWRHcm91cElkcyh0aGlzLnN0YXRlKTtcblxuICAgIGlmIChzZWxlY3RlZEdyb3VwSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcblxuICAgICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkID1cbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50KGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cElkcyk7XG5cbiAgICAgIGlmIChzZWxlY3RlZEdyb3VwSWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IHNlbGVjdGVkR3JvdXBJZCxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50IS5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBnZXRUZXh0QmluZGFibGVDb250YWluZXJBdFBvc2l0aW9uKFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICk7XG4gICAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBoYXNCb3VuZFRleHRFbGVtZW50KGNvbnRhaW5lcikgfHxcbiAgICAgICAgICAhaXNUcmFuc3BhcmVudChjb250YWluZXIuYmFja2dyb3VuZENvbG9yKSB8fFxuICAgICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KGNvbnRhaW5lciwgdGhpcy5zdGF0ZSwgW1xuICAgICAgICAgICAgc2NlbmVYLFxuICAgICAgICAgICAgc2NlbmVZLFxuICAgICAgICAgIF0pXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IG1pZFBvaW50ID0gZ2V0Q29udGFpbmVyQ2VudGVyKGNvbnRhaW5lciwgdGhpcy5zdGF0ZSk7XG5cbiAgICAgICAgICBzY2VuZVggPSBtaWRQb2ludC54O1xuICAgICAgICAgIHNjZW5lWSA9IG1pZFBvaW50Lnk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICAgICAgY29udGFpbmVyLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uID0gKFxuICAgIHNjZW5lUG9pbnRlcjogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBoaXRFbGVtZW50OiBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsLFxuICApOiBFeGNhbGlkcmF3RWxlbWVudCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgLy8gUmV2ZXJzaW5nIHNvIHdlIHRyYXZlcnNlIHRoZSBlbGVtZW50cyBpbiBkZWNyZWFzaW5nIG9yZGVyXG4gICAgLy8gb2Ygei1pbmRleFxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICBsZXQgaGl0RWxlbWVudEluZGV4ID0gSW5maW5pdHk7XG5cbiAgICByZXR1cm4gZWxlbWVudHMuZmluZCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChoaXRFbGVtZW50ICYmIGVsZW1lbnQuaWQgPT09IGhpdEVsZW1lbnQuaWQpIHtcbiAgICAgICAgaGl0RWxlbWVudEluZGV4ID0gaW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gKFxuICAgICAgICBlbGVtZW50LmxpbmsgJiZcbiAgICAgICAgaW5kZXggPD0gaGl0RWxlbWVudEluZGV4ICYmXG4gICAgICAgIGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXIueCwgc2NlbmVQb2ludGVyLnldLFxuICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVkaXJlY3RUb0xpbmsgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgaXNUb3VjaFNjcmVlbjogYm9vbGVhbixcbiAgKSA9PiB7XG4gICAgY29uc3QgZHJhZ2dlZERpc3RhbmNlID0gZGlzdGFuY2UyZChcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRYLFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFksXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5oaXRMaW5rRWxlbWVudCB8fFxuICAgICAgLy8gRm9yIHRvdWNoIHNjcmVlbiBhbGxvdyBkcmFnZ2luZyB0aHJlc2hvbGQgZWxzZSBzdHJpY3QgY2hlY2tcbiAgICAgIChpc1RvdWNoU2NyZWVuICYmIGRyYWdnZWREaXN0YW5jZSA+IERSQUdHSU5HX1RIUkVTSE9MRCkgfHxcbiAgICAgICghaXNUb3VjaFNjcmVlbiAmJiBkcmFnZ2VkRGlzdGFuY2UgIT09IDApXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxhc3RQb2ludGVyRG93bkNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duISxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlckRvd25IaXR0aW5nTGlua0ljb24gPSBpc1BvaW50SGl0dGluZ0xpbmtJY29uKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICBbbGFzdFBvaW50ZXJEb3duQ29vcmRzLngsIGxhc3RQb2ludGVyRG93bkNvb3Jkcy55XSxcbiAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJVcENvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJVcEhpdHRpbmdMaW5rSWNvbiA9IGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIFtsYXN0UG9pbnRlclVwQ29vcmRzLngsIGxhc3RQb2ludGVyVXBDb29yZHMueV0sXG4gICAgICB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICApO1xuICAgIGlmIChsYXN0UG9pbnRlckRvd25IaXR0aW5nTGlua0ljb24gJiYgbGFzdFBvaW50ZXJVcEhpdHRpbmdMaW5rSWNvbikge1xuICAgICAgY29uc3QgdXJsID0gdGhpcy5oaXRMaW5rRWxlbWVudC5saW5rO1xuICAgICAgaWYgKHVybCkge1xuICAgICAgICBsZXQgY3VzdG9tRXZlbnQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTGlua09wZW4pIHtcbiAgICAgICAgICBjdXN0b21FdmVudCA9IHdyYXBFdmVudChFVkVOVC5FWENBTElEUkFXX0xJTkssIGV2ZW50Lm5hdGl2ZUV2ZW50KTtcbiAgICAgICAgICB0aGlzLnByb3BzLm9uTGlua09wZW4odGhpcy5oaXRMaW5rRWxlbWVudCwgY3VzdG9tRXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY3VzdG9tRXZlbnQ/LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBpc0xvY2FsTGluayh1cmwpID8gXCJfc2VsZlwiIDogXCJfYmxhbmtcIjtcbiAgICAgICAgICBjb25zdCBuZXdXaW5kb3cgPSB3aW5kb3cub3Blbih1bmRlZmluZWQsIHRhcmdldCk7XG4gICAgICAgICAgLy8gaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmdpdGh1Yi5pby9yZWwtbm9vcGVuZXIvXG4gICAgICAgICAgaWYgKG5ld1dpbmRvdykge1xuICAgICAgICAgICAgbmV3V2luZG93Lm9wZW5lciA9IG51bGw7XG4gICAgICAgICAgICBuZXdXaW5kb3cubG9jYXRpb24gPSBub3JtYWxpemVMaW5rKHVybCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgdGhpcy5zdGF0ZS5jdXJzb3JCdXR0b24pO1xuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuaGFzKGV2ZW50LnBvaW50ZXJJZCkpIHtcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2V0KGV2ZW50LnBvaW50ZXJJZCwge1xuICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbFNjYWxlID0gZ2VzdHVyZS5pbml0aWFsU2NhbGU7XG4gICAgaWYgKFxuICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAyICYmXG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgJiZcbiAgICAgIGluaXRpYWxTY2FsZSAmJlxuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2VcbiAgICApIHtcbiAgICAgIGNvbnN0IGNlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGNlbnRlci54IC0gZ2VzdHVyZS5sYXN0Q2VudGVyLng7XG4gICAgICBjb25zdCBkZWx0YVkgPSBjZW50ZXIueSAtIGdlc3R1cmUubGFzdENlbnRlci55O1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID0gY2VudGVyO1xuXG4gICAgICBjb25zdCBkaXN0YW5jZSA9IGdldERpc3RhbmNlKEFycmF5LmZyb20oZ2VzdHVyZS5wb2ludGVycy52YWx1ZXMoKSkpO1xuICAgICAgY29uc3Qgc2NhbGVGYWN0b3IgPVxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJmcmVlZHJhd1wiICYmIHRoaXMuc3RhdGUucGVuTW9kZVxuICAgICAgICAgID8gMVxuICAgICAgICAgIDogZGlzdGFuY2UgLyBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZTtcblxuICAgICAgY29uc3QgbmV4dFpvb20gPSBzY2FsZUZhY3RvclxuICAgICAgICA/IGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIHNjYWxlRmFjdG9yKVxuICAgICAgICA6IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+IHtcbiAgICAgICAgY29uc3Qgem9vbVN0YXRlID0gZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY2VudGVyLngsXG4gICAgICAgICAgICB2aWV3cG9ydFk6IGNlbnRlci55LFxuICAgICAgICAgICAgbmV4dFpvb20sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcyh7XG4gICAgICAgICAgem9vbTogem9vbVN0YXRlLnpvb20sXG4gICAgICAgICAgc2Nyb2xsWDogem9vbVN0YXRlLnNjcm9sbFggKyBkZWx0YVggLyBuZXh0Wm9vbSxcbiAgICAgICAgICBzY3JvbGxZOiB6b29tU3RhdGUuc2Nyb2xsWSArIGRlbHRhWSAvIG5leHRab29tLFxuICAgICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9XG4gICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBpc0hvbGRpbmdTcGFjZSB8fFxuICAgICAgaXNQYW5uaW5nIHx8XG4gICAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyIHx8XG4gICAgICBpc0hhbmRUb29sQWN0aXZlKHRoaXMuc3RhdGUpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMgPSBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICk7XG4gICAgY29uc3QgaXNPdmVyU2Nyb2xsQmFyID0gaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMuaXNPdmVyRWl0aGVyO1xuICAgIGlmICghdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHsgeDogc2NlbmVQb2ludGVyWCwgeTogc2NlbmVQb2ludGVyWSB9ID0gc2NlbmVQb2ludGVyO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICkge1xuICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJNb3ZlKFxuICAgICAgICBldmVudCxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnRcbiAgICAgICkge1xuICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgcmVhZGluZyBmcm9tIHByZXZpb3VzIHN0YXRlIHdoaWNoIGlzIG5vdCBwb3NzaWJsZSB3aXRoXG4gICAgICAgIC8vIGF1dG9tYXRpYyBiYXRjaGluZyBpbiBSZWFjdCAxOCBoZW5jZSB1c2luZyBmbHVzaCBzeW5jIHRvIHN5bmNocm9ub3VzbHlcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBzdGF0ZS4gQ2hlY2sgaHR0cHM6Ly9naXRodWIuY29tL2V4Y2FsaWRyYXcvZXhjYWxpZHJhdy9wdWxsLzU1MDggZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgZmx1c2hTeW5jKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudD8ubGFzdFVuY29tbWl0dGVkUG9pbnQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gY2F1c2VzIHN0YWNrIG92ZXJmbG93IGlmIG5vdCBzeW5jXG4gICAgICAgIGZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzQmluZGluZ0VsZW1lbnRUeXBlKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlKSkge1xuICAgICAgLy8gSG92ZXJpbmcgd2l0aCBhIHNlbGVjdGVkIHRvb2wgb3IgY3JlYXRpbmcgbmV3IGxpbmVhciBlbGVtZW50IHZpYSBjbGlja1xuICAgICAgLy8gYW5kIHBvaW50XG4gICAgICBjb25zdCB7IGRyYWdnaW5nRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXJdLFxuICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICBjb25zdCB7IHBvaW50cywgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG4gICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuXG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG5cbiAgICAgIGlmIChsYXN0UG9pbnQgPT09IGxhc3RDb21taXR0ZWRQb2ludCkge1xuICAgICAgICAvLyBpZiB3ZSBoYXZlbid0IHlldCBjcmVhdGVkIGEgdGVtcCBwb2ludCBhbmQgd2UncmUgYmV5b25kIGNvbW1pdC16b25lXG4gICAgICAgIC8vIHRocmVzaG9sZCwgYWRkIGEgcG9pbnRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgICBsYXN0UG9pbnRbMF0sXG4gICAgICAgICAgICBsYXN0UG9pbnRbMV0sXG4gICAgICAgICAgKSA+PSBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtzY2VuZVBvaW50ZXJYIC0gcngsIHNjZW5lUG9pbnRlclkgLSByeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgICAgLy8gaW4gdGhpcyBicmFuY2gsIHdlJ3JlIGluc2lkZSB0aGUgY29tbWl0IHpvbmUsIGFuZCBubyB1bmNvbW1pdHRlZFxuICAgICAgICAgIC8vIHBvaW50IGV4aXN0cy4gVGh1cyBkbyBub3RoaW5nIChkb24ndCBhZGQvcmVtb3ZlIHBvaW50cykuXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHBvaW50cy5sZW5ndGggPiAyICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogcG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBbbGFzdENvbW1pdHRlZFgsIGxhc3RDb21taXR0ZWRZXSA9XG4gICAgICAgICAgbXVsdGlFbGVtZW50Py5sYXN0Q29tbWl0dGVkUG9pbnQgPz8gWzAsIDBdO1xuXG4gICAgICAgIGxldCBkeEZyb21MYXN0Q29tbWl0dGVkID0gZ3JpZFggLSByeCAtIGxhc3RDb21taXR0ZWRYO1xuICAgICAgICBsZXQgZHlGcm9tTGFzdENvbW1pdHRlZCA9IGdyaWRZIC0gcnkgLSBsYXN0Q29tbWl0dGVkWTtcblxuICAgICAgICBpZiAoc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpKSB7XG4gICAgICAgICAgKHsgd2lkdGg6IGR4RnJvbUxhc3RDb21taXR0ZWQsIGhlaWdodDogZHlGcm9tTGFzdENvbW1pdHRlZCB9ID1cbiAgICAgICAgICAgIGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZShcbiAgICAgICAgICAgICAgLy8gYWN0dWFsIGNvb3JkaW5hdGUgb2YgdGhlIGxhc3QgY29tbWl0dGVkIHBvaW50XG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRYICsgcngsXG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRZICsgcnksXG4gICAgICAgICAgICAgIC8vIGN1cnNvci1ncmlkIGNvb3JkaW5hdGVcbiAgICAgICAgICAgICAgZ3JpZFgsXG4gICAgICAgICAgICAgIGdyaWRZLFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNQYXRoQUxvb3AocG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB1cGRhdGUgbGFzdCB1bmNvbW1pdHRlZCBwb2ludFxuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFggKyBkeEZyb21MYXN0Q29tbWl0dGVkLFxuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWSArIGR5RnJvbUxhc3RDb21taXR0ZWQsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaGFzRGVzZWxlY3RlZEJ1dHRvbiA9IEJvb2xlYW4oZXZlbnQuYnV0dG9ucyk7XG4gICAgaWYgKFxuICAgICAgaGFzRGVzZWxlY3RlZEJ1dHRvbiB8fFxuICAgICAgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInRleHRcIiAmJlxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIilcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSk7XG4gICAgaWYgKFxuICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICFpc092ZXJTY3JvbGxCYXIgJiZcbiAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50XG4gICAgKSB7XG4gICAgICBjb25zdCBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgPSBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUoXG4gICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgKTtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICYmXG4gICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS50cmFuc2Zvcm1IYW5kbGVUeXBlXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudChlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUpLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEgJiYgIWlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyksXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKHRyYW5zZm9ybUhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICk7XG4gICAgdGhpcy5oaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgaGl0RWxlbWVudCxcbiAgICApO1xuICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5oaXRMaW5rRWxlbWVudC5pZF1cbiAgICApIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICBzaG93SHlwZXJsaW5rVG9vbHRpcCh0aGlzLmhpdExpbmtFbGVtZW50LCB0aGlzLnN0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlkZUh5cGVybGlua1Rvb2xpcCgpO1xuICAgICAgaWYgKFxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgIGhpdEVsZW1lbnQubGluayAmJlxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5jb250ZXh0TWVudSAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXBcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0h5cGVybGlua1BvcHVwOiBcImluZm9cIiB9KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBpc1RleHRFbGVtZW50KGhpdEVsZW1lbnQpID8gQ1VSU09SX1RZUEUuVEVYVCA6IENVUlNPUl9UWVBFLkNST1NTSEFJUixcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGFuZGxlSG92ZXJTZWxlY3RlZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgLy8gaWYgdXNpbmcgY21kL2N0cmwsIHdlJ3JlIG5vdCBkcmFnZ2luZ1xuICAgICAgICAhZXZlbnRbS0VZUy5DVFJMX09SX0NNRF1cbiAgICAgICkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKGhpdEVsZW1lbnQgfHxcbiAgICAgICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgICkpICYmXG4gICAgICAgICAgIWhpdEVsZW1lbnQ/LmxvY2tlZFxuICAgICAgICApIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUVyYXNlciA9IChcbiAgICBldmVudDogUG9pbnRlckV2ZW50LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgc2NlbmVQb2ludGVyOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0sXG4gICkgPT4ge1xuICAgIGNvbnN0IHVwZGF0ZUVsZW1lbnRJZHMgPSAoZWxlbWVudHM6IEV4Y2FsaWRyYXdFbGVtZW50W10pID0+IHtcbiAgICAgIGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKGVsZW1lbnQubG9ja2VkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWRzVG9VcGRhdGUucHVzaChlbGVtZW50LmlkKTtcbiAgICAgICAgaWYgKGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0gJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0uZXJhc2VcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0uZXJhc2UgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIXBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0pIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdID0ge1xuICAgICAgICAgICAgZXJhc2U6IHRydWUsXG4gICAgICAgICAgICBvcGFjaXR5OiBlbGVtZW50Lm9wYWNpdHksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGlkc1RvVXBkYXRlOiBBcnJheTxzdHJpbmc+ID0gW107XG5cbiAgICBjb25zdCBkaXN0YW5jZSA9IGRpc3RhbmNlMmQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55LFxuICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICApO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IHBvaW50ID0geyAuLi5wb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMgfTtcbiAgICBsZXQgc2FtcGxpbmdJbnRlcnZhbCA9IDA7XG4gICAgd2hpbGUgKHNhbXBsaW5nSW50ZXJ2YWwgPD0gZGlzdGFuY2UpIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24ocG9pbnQueCwgcG9pbnQueSk7XG4gICAgICB1cGRhdGVFbGVtZW50SWRzKGhpdEVsZW1lbnRzKTtcblxuICAgICAgLy8gRXhpdCBzaW5jZSB3ZSByZWFjaGVkIGN1cnJlbnQgcG9pbnRcbiAgICAgIGlmIChzYW1wbGluZ0ludGVydmFsID09PSBkaXN0YW5jZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gQ2FsY3VsYXRlIG5leHQgcG9pbnQgaW4gdGhlIGxpbmUgYXQgYSBkaXN0YW5jZSBvZiBzYW1wbGluZyBpbnRlcnZhbFxuICAgICAgc2FtcGxpbmdJbnRlcnZhbCA9IE1hdGgubWluKHNhbXBsaW5nSW50ZXJ2YWwgKyB0aHJlc2hvbGQsIGRpc3RhbmNlKTtcblxuICAgICAgY29uc3QgZGlzdGFuY2VSYXRpbyA9IHNhbXBsaW5nSW50ZXJ2YWwgLyBkaXN0YW5jZTtcbiAgICAgIGNvbnN0IG5leHRYID1cbiAgICAgICAgKDEgLSBkaXN0YW5jZVJhdGlvKSAqIHBvaW50LnggKyBkaXN0YW5jZVJhdGlvICogc2NlbmVQb2ludGVyLng7XG4gICAgICBjb25zdCBuZXh0WSA9XG4gICAgICAgICgxIC0gZGlzdGFuY2VSYXRpbykgKiBwb2ludC55ICsgZGlzdGFuY2VSYXRpbyAqIHNjZW5lUG9pbnRlci55O1xuICAgICAgcG9pbnQueCA9IG5leHRYO1xuICAgICAgcG9pbnQueSA9IG5leHRZO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZSkgPT4ge1xuICAgICAgY29uc3QgaWQgPVxuICAgICAgICBpc0JvdW5kVG9Db250YWluZXIoZWxlKSAmJiBpZHNUb1VwZGF0ZS5pbmNsdWRlcyhlbGUuY29udGFpbmVySWQpXG4gICAgICAgICAgPyBlbGUuY29udGFpbmVySWRcbiAgICAgICAgICA6IGVsZS5pZDtcbiAgICAgIGlmIChpZHNUb1VwZGF0ZS5pbmNsdWRlcyhpZCkpIHtcbiAgICAgICAgaWYgKGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaWRdICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2lkXS5lcmFzZSA9PT0gZmFsc2VcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICAgICAgb3BhY2l0eTogcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtpZF0ub3BhY2l0eSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgICBvcGFjaXR5OiBFTEVNRU5UX1JFQURZX1RPX0VSQVNFX09QQUNJVFksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG5cbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHNjZW5lUG9pbnRlci54O1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gc2NlbmVQb2ludGVyLnk7XG4gIH07XG4gIC8vIHNldCB0b3VjaCBtb3ZpbmcgZm9yIG1vYmlsZSBjb250ZXh0IG1lbnVcbiAgcHJpdmF0ZSBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQ6IFJlYWN0LlRvdWNoRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+KSA9PiB7XG4gICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gdHJ1ZTtcbiAgfTtcblxuICBoYW5kbGVIb3ZlclNlbGVjdGVkTGluZWFyRWxlbWVudChcbiAgICBsaW5lYXJFbGVtZW50RWRpdG9yOiBMaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgIHNjZW5lUG9pbnRlclg6IG51bWJlcixcbiAgICBzY2VuZVBvaW50ZXJZOiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldEVsZW1lbnQoXG4gICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLmVsZW1lbnRJZCxcbiAgICApO1xuXG4gICAgY29uc3QgYm91bmRUZXh0RWxlbWVudCA9IGdldEJvdW5kVGV4dEVsZW1lbnQoZWxlbWVudCk7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICBsZXQgaG92ZXJQb2ludEluZGV4ID0gLTE7XG4gICAgICBsZXQgc2VnbWVudE1pZFBvaW50SG92ZXJlZENvb3JkcyA9IG51bGw7XG4gICAgICBpZiAoXG4gICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KGVsZW1lbnQsIHRoaXMuc3RhdGUsIFtcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIF0pXG4gICAgICApIHtcbiAgICAgICAgaG92ZXJQb2ludEluZGV4ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEluZGV4VW5kZXJDdXJzb3IoXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICApO1xuICAgICAgICBzZWdtZW50TWlkUG9pbnRIb3ZlcmVkQ29vcmRzID1cbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFNlZ21lbnRNaWRwb2ludEhpdENvb3JkcyhcbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICAgICB7IHg6IHNjZW5lUG9pbnRlclgsIHk6IHNjZW5lUG9pbnRlclkgfSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcblxuICAgICAgICBpZiAoaG92ZXJQb2ludEluZGV4ID49IDAgfHwgc2VnbWVudE1pZFBvaW50SG92ZXJlZENvb3Jkcykge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgc2hvdWxkU2hvd0JvdW5kaW5nQm94KFtlbGVtZW50XSwgdGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgYm91bmRUZXh0RWxlbWVudCAmJlxuICAgICAgICBoaXRUZXN0KGJvdW5kVGV4dEVsZW1lbnQsIHRoaXMuc3RhdGUsIHNjZW5lUG9pbnRlclgsIHNjZW5lUG9pbnRlclkpXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5ob3ZlclBvaW50SW5kZXggIT09IGhvdmVyUG9pbnRJbmRleFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBob3ZlclBvaW50SW5kZXgsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIUxpbmVhckVsZW1lbnRFZGl0b3IuYXJlUG9pbnRzRXF1YWwoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuc2VnbWVudE1pZFBvaW50SG92ZXJlZENvb3JkcyxcbiAgICAgICAgICBzZWdtZW50TWlkUG9pbnRIb3ZlcmVkQ29vcmRzLFxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHNlZ21lbnRNaWRQb2ludEhvdmVyZWRDb29yZHMsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIHNpbmNlIGNvbnRleHRNZW51IG9wdGlvbnMgYXJlIHBvdGVudGlhbGx5IGV2YWx1YXRlZCBvbiBlYWNoIHJlbmRlcixcbiAgICAvLyBhbmQgYW4gY29udGV4dE1lbnUgYWN0aW9uIG1heSBkZXBlbmQgb24gc2VsZWN0aW9uIHN0YXRlLCB3ZSBtdXN0XG4gICAgLy8gY2xvc2UgdGhlIGNvbnRleHRNZW51IGJlZm9yZSB3ZSB1cGRhdGUgdGhlIHNlbGVjdGlvbiBvbiBwb2ludGVyRG93blxuICAgIC8vIChlLmcuIHJlc2V0dGluZyBzZWxlY3Rpb24pXG4gICAgaWYgKHRoaXMuc3RhdGUuY29udGV4dE1lbnUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb250ZXh0TWVudTogbnVsbCB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKGV2ZW50KTtcblxuICAgIC8vIGlmIGRyYWdnaW5nIGVsZW1lbnQgaXMgZnJlZWRyYXcgYW5kIGFub3RoZXIgcG9pbnRlcmRvd24gZXZlbnQgb2NjdXJzXG4gICAgLy8gYSBzZWNvbmQgZmluZ2VyIGlzIG9uIHRoZSBzY3JlZW5cbiAgICAvLyBkaXNjYXJkIHRoZSBmcmVlZHJhdyBlbGVtZW50IGlmIGl0IGlzIHZlcnkgc2hvcnQgYmVjYXVzZSBpdCBpcyBsaWtlbHlcbiAgICAvLyBqdXN0IGEgc3Bpa2UsIG90aGVyd2lzZSBmaW5hbGl6ZSB0aGUgZnJlZWRyYXcgZWxlbWVudCB3aGVuIHRoZSBzZWNvbmRcbiAgICAvLyBmaW5nZXIgaXMgbGlmdGVkXG4gICAgaWYgKFxuICAgICAgZXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgJiZcbiAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50LnR5cGUgPT09IFwiZnJlZWRyYXdcIlxuICAgICkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50IGFzIEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnQ7XG4gICAgICB0aGlzLnVwZGF0ZVNjZW5lKHtcbiAgICAgICAgLi4uKGVsZW1lbnQucG9pbnRzLmxlbmd0aCA8IDEwXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIGVsZW1lbnRzOiB0aGlzLnNjZW5lXG4gICAgICAgICAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSBlbGVtZW50LmlkKSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHt9KSxcbiAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogT2JqZWN0LmtleXModGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMpXG4gICAgICAgICAgICAuZmlsdGVyKChrZXkpID0+IGtleSAhPT0gZWxlbWVudC5pZClcbiAgICAgICAgICAgIC5yZWR1Y2UoKG9iajogeyBbaWQ6IHN0cmluZ106IGJvb2xlYW4gfSwga2V5KSA9PiB7XG4gICAgICAgICAgICAgIG9ialtrZXldID0gdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNba2V5XTtcbiAgICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgICAgIH0sIHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBhbnkgYWN0aXZlIHNlbGVjdGlvbiB3aGVuIHdlIHN0YXJ0IHRvIGludGVyYWN0IHdpdGggY2FudmFzXG4gICAgLy8gKG1haW5seSwgd2UgY2FyZSBhYm91dCByZW1vdmluZyBzZWxlY3Rpb24gb3V0c2lkZSB0aGUgY29tcG9uZW50IHdoaWNoXG4gICAgLy8gIHdvdWxkIHByZXZlbnQgb3VyIGNvcHkgaGFuZGxpbmcgb3RoZXJ3aXNlKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWxlY3Rpb24/LmFuY2hvck5vZGUpIHtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICB9XG4gICAgdGhpcy5tYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyhldmVudCk7XG4gICAgdGhpcy5tYXliZUNsZWFudXBBZnRlck1pc3NpbmdQb2ludGVyVXAoZXZlbnQpO1xuXG4gICAgLy9maXJlcyBvbmx5IG9uY2UsIGlmIHBlbiBpcyBkZXRlY3RlZCwgcGVuTW9kZSBpcyBlbmFibGVkXG4gICAgLy90aGUgdXNlciBjYW4gZGlzYWJsZSB0aGlzIGJ5IHRvZ2dsaW5nIHRoZSBwZW5Nb2RlIGJ1dHRvblxuICAgIGlmICghdGhpcy5zdGF0ZS5wZW5EZXRlY3RlZCAmJiBldmVudC5wb2ludGVyVHlwZSA9PT0gXCJwZW5cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGVuTW9kZTogdHJ1ZSxcbiAgICAgICAgICBwZW5EZXRlY3RlZDogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICF0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuICYmXG4gICAgICBbXCJwZW5cIiwgXCJ0b3VjaFwiXS5pbmNsdWRlcyhldmVudC5wb2ludGVyVHlwZSlcbiAgICApIHtcbiAgICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7IGlzVG91Y2hTY3JlZW46IHRydWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubGFzdFBvaW50ZXJEb3duID0gZXZlbnQ7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBsYXN0UG9pbnRlckRvd25XaXRoOiBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgIGN1cnNvckJ1dHRvbjogXCJkb3duXCIsXG4gICAgfSk7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcImRvd25cIik7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVDYW52YXNQYW5Vc2luZ1doZWVsT3JTcGFjZURyYWcoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gb25seSBoYW5kbGUgbGVmdCBtb3VzZSBidXR0b24gb3IgdG91Y2hcbiAgICBpZiAoXG4gICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiZcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uVE9VQ0hcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkb24ndCBzZWxlY3Qgd2hpbGUgcGFubmluZ1xuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPiAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU3RhdGUgZm9yIHRoZSBkdXJhdGlvbiBvZiBhIHBvaW50ZXIgaW50ZXJhY3Rpb24sIHdoaWNoIHN0YXJ0cyB3aXRoIGFcbiAgICAvLyBwb2ludGVyRG93biBldmVudCwgZW5kcyB3aXRoIGEgcG9pbnRlclVwIGV2ZW50IChvciBhbm90aGVyIHBvaW50ZXJEb3duKVxuICAgIGNvbnN0IHBvaW50ZXJEb3duU3RhdGUgPSB0aGlzLmluaXRpYWxQb2ludGVyRG93blN0YXRlKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZURyYWdnaW5nU2Nyb2xsQmFyKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2xlYXJTZWxlY3Rpb25JZk5vdFVzaW5nU2VsZWN0aW9uKCk7XG4gICAgdGhpcy51cGRhdGVCaW5kaW5nRW5hYmxlZE9uUG9pbnRlck1vdmUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlU2VsZWN0aW9uT25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhbGxvd09uUG9pbnRlckRvd24gPVxuICAgICAgIXRoaXMuc3RhdGUucGVuTW9kZSB8fFxuICAgICAgZXZlbnQucG9pbnRlclR5cGUgIT09IFwidG91Y2hcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInRleHRcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIjtcblxuICAgIGlmICghYWxsb3dPblBvaW50ZXJEb3duKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInRleHRcIikge1xuICAgICAgdGhpcy5oYW5kbGVUZXh0T25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImFycm93XCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImxpbmVcIlxuICAgICkge1xuICAgICAgdGhpcy5oYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgIC8vIHJlc2V0IGltYWdlIHByZXZpZXcgb24gcG9pbnRlcmRvd25cbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQ1JPU1NIQUlSKTtcblxuICAgICAgLy8gcmV0cmlldmUgdGhlIGxhdGVzdCBlbGVtZW50IGFzIHRoZSBzdGF0ZSBtYXkgYmUgc3RhbGVcbiAgICAgIGNvbnN0IHBlbmRpbmdJbWFnZUVsZW1lbnQgPVxuICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCAmJlxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnQodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpO1xuXG4gICAgICBpZiAoIXBlbmRpbmdJbWFnZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBwZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogcGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBudWxsLFxuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgICAgbXV0YXRlRWxlbWVudChwZW5kaW5nSW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlRnJlZURyYXdFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiaGFuZFwiXG4gICAgKSB7XG4gICAgICB0aGlzLmNyZWF0ZUdlbmVyaWNFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMucHJvcHM/Lm9uUG9pbnRlckRvd24/Lih0aGlzLnN0YXRlLmFjdGl2ZVRvb2wsIHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIHRoaXMub25Qb2ludGVyRG93bkVtaXR0ZXIudHJpZ2dlcihcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICBldmVudCxcbiAgICApO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9XG4gICAgICB0aGlzLm9uUG9pbnRlck1vdmVGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyVXAgPVxuICAgICAgdGhpcy5vblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvbktleURvd24gPSB0aGlzLm9uS2V5RG93bkZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgY29uc3Qgb25LZXlVcCA9IHRoaXMub25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBsYXN0UG9pbnRlclVwID0gb25Qb2ludGVyVXA7XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgb25LZXlEb3duKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCBvbktleVVwKTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlID0gb25Qb2ludGVyTW92ZTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCA9IG9uUG9pbnRlclVwO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleVVwID0gb25LZXlVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duID0gb25LZXlEb3duO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJVcCA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgdGhpcy5sYXN0UG9pbnRlclVwID0gZXZlbnQ7XG4gICAgaWYgKHRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4pIHtcbiAgICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgeyBjbGllbnRYOiBldmVudC5jbGllbnRYLCBjbGllbnRZOiBldmVudC5jbGllbnRZIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICAgICk7XG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50TGlua0F0UG9zaXRpb24oXG4gICAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLmhpdExpbmtFbGVtZW50LmlkXVxuICAgICkge1xuICAgICAgdGhpcy5yZWRpcmVjdFRvTGluayhldmVudCwgdGhpcy5kZXZpY2UuaXNUb3VjaFNjcmVlbik7XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmVQb2ludGVyKGV2ZW50KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBkZWFsIHdpdGggb3BlbmluZyBjb250ZXh0IG1lbnUgb24gdG91Y2ggZGV2aWNlc1xuICAgIGlmIChldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiKSB7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcblxuICAgICAgaWYgKHRvdWNoVGltZW91dCkge1xuICAgICAgICAvLyBJZiB0aGVyZSdzIGFscmVhZHkgYSB0b3VjaFRpbWVvdXQsIHRoaXMgbWVhbnMgdGhhdCB0aGVyZSdzIGFub3RoZXJcbiAgICAgICAgLy8gdG91Y2ggZG93biBhbmQgd2UgYXJlIGRvaW5nIGFub3RoZXIgdG91Y2gsIHNvIHdlIHNob3VsZG4ndCBvcGVuIHRoZVxuICAgICAgICAvLyBjb250ZXh0IG1lbnUuXG4gICAgICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvcGVuIHRoZSBjb250ZXh0IG1lbnUgd2l0aCB0aGUgZmlyc3QgdG91Y2gncyBjbGllbnRYIGFuZCBjbGllbnRZXG4gICAgICAgIC8vIGlmIHRoZSB0b3VjaCBpcyBub3QgbW92aW5nXG4gICAgICAgIHRvdWNoVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgICAgICAgIGlmICghaW52YWxpZGF0ZUNvbnRleHRNZW51KSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51KGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIFRPVUNIX0NUWF9NRU5VX1RJTUVPVVQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHJlc2V0Q29udGV4dE1lbnVUaW1lciA9ICgpID0+IHtcbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVDbGVhbnVwQWZ0ZXJNaXNzaW5nUG9pbnRlclVwKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBpZiAobGFzdFBvaW50ZXJVcCAhPT0gbnVsbCkge1xuICAgICAgLy8gVW5mb3J0dW5hdGVseSwgc29tZXRpbWVzIHdlIGRvbid0IGdldCBhIHBvaW50ZXJ1cCBhZnRlciBhIHBvaW50ZXJkb3duLFxuICAgICAgLy8gdGhpcyBjYW4gaGFwcGVuIHdoZW4gYSBjb250ZXh0dWFsIG1lbnUgb3IgYWxlcnQgaXMgdHJpZ2dlcmVkLiBJbiBvcmRlciB0byBhdm9pZFxuICAgICAgLy8gYmVpbmcgaW4gYSB3ZWlyZCBzdGF0ZSwgd2UgY2xlYW4gdXAgb24gdGhlIG5leHQgcG9pbnRlcmRvd25cbiAgICAgIGxhc3RQb2ludGVyVXAoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBwYW5uaW5nXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUGFuVXNpbmdXaGVlbE9yU3BhY2VEcmFnID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAoXG4gICAgICAhKFxuICAgICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPD0gMSAmJlxuICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5XSEVFTCB8fFxuICAgICAgICAgIChldmVudC5idXR0b24gPT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiYgaXNIb2xkaW5nU3BhY2UpIHx8XG4gICAgICAgICAgaXNIYW5kVG9vbEFjdGl2ZSh0aGlzLnN0YXRlKSB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKVxuICAgICAgKSB8fFxuICAgICAgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBsZXQgbmV4dFBhc3RlUHJldmVudGVkID0gZmFsc2U7XG4gICAgY29uc3QgaXNMaW51eCA9IC9MaW51eC8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtKTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgIGxldCB7IGNsaWVudFg6IGxhc3RYLCBjbGllbnRZOiBsYXN0WSB9ID0gZXZlbnQ7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgZGVsdGFYID0gbGFzdFggLSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZGVsdGFZID0gbGFzdFkgLSBldmVudC5jbGllbnRZO1xuICAgICAgbGFzdFggPSBldmVudC5jbGllbnRYO1xuICAgICAgbGFzdFkgPSBldmVudC5jbGllbnRZO1xuXG4gICAgICAvKlxuICAgICAgICogUHJldmVudCBwYXN0ZSBldmVudCBpZiB3ZSBtb3ZlIHdoaWxlIG1pZGRsZSBjbGlja2luZyBvbiBMaW51eC5cbiAgICAgICAqIFNlZSBpc3N1ZSAjMTM4My5cbiAgICAgICAqL1xuICAgICAgaWYgKFxuICAgICAgICBpc0xpbnV4ICYmXG4gICAgICAgICFuZXh0UGFzdGVQcmV2ZW50ZWQgJiZcbiAgICAgICAgKE1hdGguYWJzKGRlbHRhWCkgPiAxIHx8IE1hdGguYWJzKGRlbHRhWSkgPiAxKVxuICAgICAgKSB7XG4gICAgICAgIG5leHRQYXN0ZVByZXZlbnRlZCA9IHRydWU7XG5cbiAgICAgICAgLyogUHJldmVudCB0aGUgbmV4dCBwYXN0ZSBldmVudCAqL1xuICAgICAgICBjb25zdCBwcmV2ZW50TmV4dFBhc3RlID0gKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLypcbiAgICAgICAgICogUmVlbmFibGUgbmV4dCBwYXN0ZSBpbiBjYXNlIG9mIGRpc2FibGVkIG1pZGRsZSBjbGljayBwYXN0ZSBmb3JcbiAgICAgICAgICogYW55IHJlYXNvbjpcbiAgICAgICAgICogLSByaWdodCBjbGljayBwYXN0ZVxuICAgICAgICAgKiAtIGVtcHR5IGNsaXBib2FyZFxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZW5hYmxlTmV4dFBhc3RlID0gKCkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIGVuYWJsZU5leHRQYXN0ZSk7XG4gICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcyh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGRlbHRhWCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZGVsdGFZIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgY29uc3QgdGVhcmRvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgICAobGFzdFBvaW50ZXJVcCA9ICgpID0+IHtcbiAgICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICAgIGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICAgICAgb25Qb2ludGVyTW92ZS5mbHVzaCgpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0ZWFyZG93bik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlLCB7XG4gICAgICBwYXNzaXZlOiB0cnVlLFxuICAgIH0pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRlYXJkb3duKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgIH0pO1xuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMikge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID0gZ2V0Q2VudGVyKGdlc3R1cmUucG9pbnRlcnMpO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZSA9IGdldERpc3RhbmNlKFxuICAgICAgICBBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxQb2ludGVyRG93blN0YXRlKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBQb2ludGVyRG93blN0YXRlIHtcbiAgICBjb25zdCBvcmlnaW4gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgb3JpZ2luLFxuICAgICAgd2l0aENtZE9yQ3RybDogZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0sXG4gICAgICBvcmlnaW5JbkdyaWQ6IHR1cGxlVG9Db29ycyhcbiAgICAgICAgZ2V0R3JpZFBvaW50KG9yaWdpbi54LCBvcmlnaW4ueSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSksXG4gICAgICApLFxuICAgICAgc2Nyb2xsYmFyczogaXNPdmVyU2Nyb2xsQmFycyhcbiAgICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgIGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICksXG4gICAgICAvLyB3ZSBuZWVkIHRvIGR1cGxpY2F0ZSBiZWNhdXNlIHdlJ2xsIGJlIHVwZGF0aW5nIHRoaXMgc3RhdGVcbiAgICAgIGxhc3RDb29yZHM6IHsgLi4ub3JpZ2luIH0sXG4gICAgICBvcmlnaW5hbEVsZW1lbnRzOiB0aGlzLnNjZW5lXG4gICAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICAucmVkdWNlKChhY2MsIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBhY2Muc2V0KGVsZW1lbnQuaWQsIGRlZXBDb3B5RWxlbWVudChlbGVtZW50KSk7XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwgbmV3IE1hcCgpIGFzIFBvaW50ZXJEb3duU3RhdGVbXCJvcmlnaW5hbEVsZW1lbnRzXCJdKSxcbiAgICAgIHJlc2l6ZToge1xuICAgICAgICBoYW5kbGVUeXBlOiBmYWxzZSxcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIG9mZnNldDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgIGFycm93RGlyZWN0aW9uOiBcIm9yaWdpblwiLFxuICAgICAgICBjZW50ZXI6IHsgeDogKG1heFggKyBtaW5YKSAvIDIsIHk6IChtYXhZICsgbWluWSkgLyAyIH0sXG4gICAgICB9LFxuICAgICAgaGl0OiB7XG4gICAgICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGFsbEhpdEVsZW1lbnRzOiBbXSxcbiAgICAgICAgd2FzQWRkZWRUb1NlbGVjdGlvbjogZmFsc2UsXG4gICAgICAgIGhhc0JlZW5EdXBsaWNhdGVkOiBmYWxzZSxcbiAgICAgICAgaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHM6XG4gICAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgKSxcbiAgICAgIH0sXG4gICAgICBkcmFnOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGV2ZW50TGlzdGVuZXJzOiB7XG4gICAgICAgIG9uTW92ZTogbnVsbCxcbiAgICAgICAgb25VcDogbnVsbCxcbiAgICAgICAgb25LZXlVcDogbnVsbCxcbiAgICAgICAgb25LZXlEb3duOiBudWxsLFxuICAgICAgfSxcbiAgICAgIGJveFNlbGVjdGlvbjoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZWxlbWVudElkc1RvRXJhc2U6IHt9LFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgZHJhZ2dpbmcgYSBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVEcmFnZ2luZ1Njcm9sbEJhcihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoXG4gICAgICAhKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJFaXRoZXIgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gdHJ1ZTtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IGV2ZW50LmNsaWVudFg7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gZmFsc2U7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIG9uUG9pbnRlck1vdmUuZmx1c2goKTtcbiAgICB9KTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24gPSAoKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIGV2ZW50IGhhcyBiZWVuIGNvbXBsZXRlbHkgaGFuZGxlZFxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9XG4gICAgICAgICAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgICApO1xuICAgICAgICBpZiAoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICE9IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHJlc2l6aW5nRWxlbWVudDogZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLmVsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9XG4gICAgICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlOiBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5pc1Jlc2l6aW5nID0gdHJ1ZTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldFJlc2l6ZU9mZnNldFhZKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkgJiZcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLnBvaW50cy5sZW5ndGggPT09IDJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuYXJyb3dEaXJlY3Rpb24gPSBnZXRSZXNpemVBcnJvd0RpcmVjdGlvbihcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IGxpbmVhckVsZW1lbnRFZGl0b3IgPVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fCB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudDtcbiAgICAgICAgICBjb25zdCByZXQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJEb3duKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJldC5oaXRFbGVtZW50KSB7XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID0gcmV0LmhpdEVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQubGluZWFyRWxlbWVudEVkaXRvcikge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkTGluZWFyRWxlbWVudDogcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgfSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudDogcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQuZGlkQWRkUG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoaXRFbGVtZW50IG1heSBhbHJlYWR5IGJlIHNldCBhYm92ZSwgc28gY2hlY2sgZmlyc3RcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA/P1xuICAgICAgICAgIHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApO1xuXG4gICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgLy8gRWFybHkgcmV0dXJuIGlmIHBvaW50ZXIgaXMgaGl0dGluZyBsaW5rIGljb25cbiAgICAgICAgICBjb25zdCBoaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB4OiBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgICB5OiBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoaGl0TGlua0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3Igb3ZlcmxhcHBlZCBlbGVtZW50cyBvbmUgcG9zaXRpb24gbWF5IGhpdFxuICAgICAgICAvLyBtdWx0aXBsZSBlbGVtZW50c1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgY29uc3Qgc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PlxuICAgICAgICAgICAgdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChoaXRFbGVtZW50ID09PSBudWxsIHx8ICFzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQpICYmXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIElmIHdlIGNsaWNrIG9uIHNvbWV0aGluZ1xuICAgICAgICB9IGVsc2UgaWYgKGhpdEVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgIC8vIG9uIENNRC9DVFJMLCBkcmlsbCBkb3duIHRvIGhpdCBlbGVtZW50IHJlZ2FyZGxlc3Mgb2YgZ3JvdXBzIGV0Yy5cbiAgICAgICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIC4uLmVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudChwcmV2U3RhdGUsIGhpdEVsZW1lbnQpLFxuICAgICAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAvLyBtYXJrIGFzIG5vdCBjb21wbGV0ZWx5IGhhbmRsZWQgc28gYXMgdG8gYWxsb3cgZHJhZ2dpbmcgZXRjLlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlc2VsZWN0IGlmIGl0ZW0gaXMgc2VsZWN0ZWRcbiAgICAgICAgICAvLyBpZiBzaGlmdCBpcyBub3QgY2xpY2tlZCwgdGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZVxuICAgICAgICAgIC8vIG90aGVyd2lzZSwgaXQgd2lsbCB0cmlnZ2VyIHNlbGVjdGlvbiBiYXNlZCBvbiBjdXJyZW50XG4gICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGJveFxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBjdXJyZW50bHkgZWRpdGluZyBhIGdyb3VwLCBleGl0aW5nIGVkaXRpbmcgbW9kZSBhbmQgZGVzZWxlY3QgdGhlIGdyb3VwLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgICAgICAgICFpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBoaXQgZWxlbWVudCB0byBzZWxlY3Rpb24uIEF0IHRoaXMgcG9pbnQgaWYgd2UncmUgbm90IGhvbGRpbmdcbiAgICAgICAgICAgIC8vIFNISUZUIHRoZSBwcmV2aW91c2x5IHNlbGVjdGVkIGVsZW1lbnQocykgd2VyZSBkZXNlbGVjdGVkIGFib3ZlXG4gICAgICAgICAgICAvLyAobWFrZSBzdXJlIHlvdSB1c2Ugc2V0U3RhdGUgdXBkYXRlciB0byB1c2UgbGF0ZXN0IHN0YXRlKVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkICYmXG4gICAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6IGhpdEVsZW1lbnQubGluayA/IFwiaW5mb1wiIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgaXNBU2VsZWN0ZWRFbGVtZW50KGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBoaXRFbGVtZW50ICE9IG51bGwgJiYgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF07XG4gIH1cblxuICBwcml2YXRlIGlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgIHBvaW50OiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIb3cgbWFueSBwaXhlbHMgb2ZmIHRoZSBzaGFwZSBib3VuZGFyeSB3ZSBzdGlsbCBjb25zaWRlciBhIGhpdFxuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvaW50LnggPiB4MSAtIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueCA8IHgyICsgdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55ID4geTEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnkgPCB5MiArIHRocmVzaG9sZFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRleHRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGlmIHdlJ3JlIGN1cnJlbnRseSBzdGlsbCBlZGl0aW5nIHRleHQsIGNsaWNraW5nIG91dHNpZGVcbiAgICAvLyBzaG91bGQgb25seSBmaW5hbGl6ZSBpdCwgbm90IGNyZWF0ZSBhbm90aGVyIChpcnJlc3BlY3RpdmVcbiAgICAvLyBvZiBzdGF0ZS5hY3RpdmVUb29sLmxvY2tlZClcbiAgICBpZiAoaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgc2NlbmVYID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueDtcbiAgICBsZXQgc2NlbmVZID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZLCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGxldCBjb250YWluZXIgPSBnZXRUZXh0QmluZGFibGVDb250YWluZXJBdFBvc2l0aW9uKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICBzY2VuZVgsXG4gICAgICBzY2VuZVksXG4gICAgKTtcblxuICAgIGlmIChoYXNCb3VuZFRleHRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICBjb250YWluZXIgPSBlbGVtZW50IGFzIEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyO1xuICAgICAgc2NlbmVYID0gZWxlbWVudC54ICsgZWxlbWVudC53aWR0aCAvIDI7XG4gICAgICBzY2VuZVkgPSBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCAvIDI7XG4gICAgfVxuICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICBzY2VuZVgsXG4gICAgICBzY2VuZVksXG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICAgIGNvbnRhaW5lcixcbiAgICB9KTtcblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICBpZiAoIXRoaXMuc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUZyZWVEcmF3RWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkgPT4ge1xuICAgIC8vIEJlZ2luIGEgbWFyayBjYXB0dXJlLiBUaGlzIGRvZXMgbm90IGhhdmUgdG8gdXBkYXRlIHN0YXRlIHlldC5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgbnVsbCxcbiAgICApO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ZyZWVEcmF3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHJvdW5kbmVzczogbnVsbCxcbiAgICAgIHNpbXVsYXRlUHJlc3N1cmU6IGV2ZW50LnByZXNzdXJlID09PSAwLjUsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIGNvbnN0IHByZXNzdXJlcyA9IGVsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgPyBlbGVtZW50LnByZXNzdXJlc1xuICAgICAgOiBbLi4uZWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgcG9pbnRzOiBbWzAsIDBdXSxcbiAgICAgIHByZXNzdXJlcyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlSW1hZ2VFbGVtZW50ID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICB9OiB7XG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgc2NlbmVZOiBudW1iZXI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChzY2VuZVgsIHNjZW5lWSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3SW1hZ2VFbGVtZW50KHtcbiAgICAgIHR5cGU6IFwiaW1hZ2VcIixcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICByb3VuZG5lc3M6IG51bGwsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3TGluZWFyRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgLy8gZmluYWxpemUgaWYgY29tcGxldGluZyBhIGxvb3BcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnR5cGUgPT09IFwibGluZVwiICYmXG4gICAgICAgIGlzUGF0aEFMb29wKG11bHRpRWxlbWVudC5wb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSlcbiAgICAgICkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDpcbiAgICAgICAgICAgIG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSwgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIC8vIGNsaWNraW5nIGluc2lkZSBjb21taXQgem9uZSDihpIgZmluYWxpemUgYXJyb3dcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggPiAxICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSByeCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFttdWx0aUVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgLy8gY2xpY2tpbmcgb3V0c2lkZSBjb21taXQgem9uZSDihpIgdXBkYXRlIHJlZmVyZW5jZSBmb3IgbGFzdCBjb21taXR0ZWRcbiAgICAgIC8vIHBvaW50XG4gICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgIH0pO1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvKiBJZiBhcnJvdyBpcyBwcmUtYXJyb3doZWFkcywgaXQgd2lsbCBoYXZlIHVuZGVmaW5lZCBmb3IgYm90aCBzdGFydCBhbmQgZW5kIGFycm93aGVhZHMuXG4gICAgICBJZiBzbywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBzdGFydCBhbmQgXCJhcnJvd1wiIGZvciBlbmQuIElmIHRoZSBsaW5lYXIgaXRlbSBpcyBub3RcbiAgICAgIGFuIGFycm93LCB3ZSB3YW50IGl0IHRvIGJlIG51bGwgZm9yIGJvdGguIE90aGVyd2lzZSwgd2Ugd2FudCBpdCB0byB1c2UgdGhlXG4gICAgICB2YWx1ZXMgZnJvbSBhcHBTdGF0ZS4gKi9cblxuICAgICAgY29uc3QgeyBjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IFtzdGFydEFycm93aGVhZCwgZW5kQXJyb3doZWFkXSA9XG4gICAgICAgIGVsZW1lbnRUeXBlID09PSBcImFycm93XCJcbiAgICAgICAgICA/IFtjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZF1cbiAgICAgICAgICA6IFtudWxsLCBudWxsXTtcblxuICAgICAgY29uc3QgZWxlbWVudCA9IG5ld0xpbmVhckVsZW1lbnQoe1xuICAgICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgICAgeDogZ3JpZFgsXG4gICAgICAgIHk6IGdyaWRZLFxuICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgcm91bmRuZXNzOlxuICAgICAgICAgIHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VuZG5lc3MgPT09IFwicm91bmRcIlxuICAgICAgICAgICAgPyB7IHR5cGU6IFJPVU5ETkVTUy5QUk9QT1JUSU9OQUxfUkFESVVTIH1cbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgc3RhcnRBcnJvd2hlYWQsXG4gICAgICAgIGVuZEFycm93aGVhZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgcG9pbnRzOiBbLi4uZWxlbWVudC5wb2ludHMsIFswLCAwXV0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICApO1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICByb3VuZG5lc3M6XG4gICAgICAgIHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VuZG5lc3MgPT09IFwicm91bmRcIlxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICB0eXBlOiBpc1VzaW5nQWRhcHRpdmVSYWRpdXMoZWxlbWVudFR5cGUpXG4gICAgICAgICAgICAgICAgPyBST1VORE5FU1MuQURBUFRJVkVfUkFESVVTXG4gICAgICAgICAgICAgICAgOiBST1VORE5FU1MuUFJPUE9SVElPTkFMX1JBRElVUyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IG51bGwsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gUHJldmVudHMgZm9jdXMgZnJvbSBlc2NhcGluZyBleGNhbGlkcmF3IHRhYlxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkFMVCAmJiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzVGhyb3R0bGVkKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGluaXRpYWxpemUgZHJhZ09mZnNldFhZIG9ubHkgYWZ0ZXIgd2UndmUgdXBkYXRlZFxuICAgICAgLy8gYHN0YXRlLnNlbGVjdGVkRWxlbWVudElkc2Agb24gcG9pbnRlckRvd24uIERvaW5nIGl0IGhlcmUgaW4gcG9pbnRlck1vdmVcbiAgICAgIC8vIGV2ZW50IGhhbmRsZXIgc2hvdWxkIGhvcGVmdWxseSBlbnN1cmUgd2UncmUgYWxyZWFkeSB3b3JraW5nIHdpdGhcbiAgICAgIC8vIHRoZSB1cGRhdGVkIHN0YXRlLlxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPT09IG51bGwpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXREcmFnT2Zmc2V0WFkoXG4gICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG5cbiAgICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgICB0aGlzLmhhbmRsZUVyYXNlcihldmVudCwgcG9pbnRlckRvd25TdGF0ZSwgcG9pbnRlckNvb3Jkcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLy8gZm9yIGFycm93cy9saW5lcywgZG9uJ3Qgc3RhcnQgZHJhZ2dpbmcgdW50aWwgYSBnaXZlbiB0aHJlc2hvbGRcbiAgICAgIC8vIHRvIGVuc3VyZSB3ZSBkb24ndCBjcmVhdGUgYSAyLXBvaW50IGFycm93IGJ5IG1pc3Rha2Ugd2hlblxuICAgICAgLy8gdXNlciBjbGlja3MgbW91c2UgaW4gYSB3YXkgdGhhdCBpdCBtb3ZlcyBhIHRpbnkgYml0ICh0aHVzXG4gICAgICAvLyB0cmlnZ2VyaW5nIHBvaW50ZXJtb3ZlKVxuICAgICAgaWYgKFxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJhcnJvd1wiIHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwibGluZVwiKVxuICAgICAgKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSA8IERSQUdHSU5HX1RIUkVTSE9MRFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5pc1Jlc2l6aW5nKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGxpbmVhckVsZW1lbnRFZGl0b3IgPVxuICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHwgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3Iuc2hvdWxkQWRkTWlkcG9pbnQoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgcmV0ID0gTGluZWFyRWxlbWVudEVkaXRvci5hZGRNaWRwb2ludChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIXJldCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFNpbmNlIHdlIGFyZSByZWFkaW5nIGZyb20gcHJldmlvdXMgc3RhdGUgd2hpY2ggaXMgbm90IHBvc3NpYmxlIHdpdGhcbiAgICAgICAgICAvLyBhdXRvbWF0aWMgYmF0Y2hpbmcgaW4gUmVhY3QgMTggaGVuY2UgdXNpbmcgZmx1c2ggc3luYyB0byBzeW5jaHJvbm91c2x5XG4gICAgICAgICAgLy8gdXBkYXRlIHRoZSBzdGF0ZS4gQ2hlY2sgaHR0cHM6Ly9naXRodWIuY29tL2V4Y2FsaWRyYXcvZXhjYWxpZHJhdy9wdWxsLzU1MDggZm9yIG1vcmUgZGV0YWlscy5cblxuICAgICAgICAgIGZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGU6IHJldC5wb2ludGVyRG93blN0YXRlLFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzOiByZXQuc2VsZWN0ZWRQb2ludHNJbmRpY2VzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlOiByZXQucG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogcmV0LnNlbGVjdGVkUG9pbnRzSW5kaWNlcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJEb3duU3RhdGUuc2VnbWVudE1pZHBvaW50LnZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgIWxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlckRvd25TdGF0ZS5zZWdtZW50TWlkcG9pbnQuYWRkZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGlkRHJhZyA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnREcmFnZ2luZyhcbiAgICAgICAgICBldmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKGVsZW1lbnQsIHBvaW50c1NjZW5lQ29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBwb2ludHNTY2VuZUNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICApO1xuICAgICAgICBpZiAoZGlkRHJhZykge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0hpdEFTZWxlY3RlZEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKFxuICAgICAgICAoZWxlbWVudCkgPT4gdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpc1NlbGVjdGluZ1BvaW50c0luTGluZUVkaXRvciA9XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgPT09XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudD8uaWQ7XG4gICAgICBpZiAoXG4gICAgICAgIChoYXNIaXRBU2VsZWN0ZWRFbGVtZW50IHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpICYmXG4gICAgICAgICFpc1NlbGVjdGluZ1BvaW50c0luTGluZUVkaXRvclxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMuZXZlcnkoKGVsZW1lbnQpID0+IGVsZW1lbnQubG9ja2VkKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBNYXJraW5nIHRoYXQgY2xpY2sgd2FzIHVzZWQgZm9yIGRyYWdnaW5nIHRvIGNoZWNrXG4gICAgICAgIC8vIGlmIGVsZW1lbnRzIHNob3VsZCBiZSBkZXNlbGVjdGVkIG9uIHBvaW50ZXJ1cFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICAvLyBwcmV2ZW50IGRyYWdnaW5nIGV2ZW4gaWYgd2UncmUgbm8gbG9uZ2VyIGhvbGRpbmcgY21kL2N0cmwgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGl0IHdvdWxkIGhhdmUgd2VpcmQgcmVzdWx0cyAoc3R1ZmYganVtcGluZyBhbGwgb3ZlciB0aGUgc2NyZWVuKVxuICAgICAgICAvLyBDaGVja2luZyBmb3IgZWRpdGluZ0VsZW1lbnQgdG8gYXZvaWQganVtcCB3aGlsZSBlZGl0aW5nIG9uIG1vYmlsZSAjNjUwM1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCAmJlxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50XG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IFtkcmFnWCwgZHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgW2RyYWdEaXN0YW5jZVgsIGRyYWdEaXN0YW5jZVldID0gW1xuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCksXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55KSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgLy8gV2Ugb25seSBkcmFnIGluIG9uZSBkaXJlY3Rpb24gaWYgc2hpZnQgaXMgcHJlc3NlZFxuICAgICAgICAgIGNvbnN0IGxvY2tEaXJlY3Rpb24gPSBldmVudC5zaGlmdEtleTtcbiAgICAgICAgICBkcmFnU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ1gsXG4gICAgICAgICAgICBkcmFnWSxcbiAgICAgICAgICAgIGxvY2tEaXJlY3Rpb24sXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2VYLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgICAvLyBXZSBkdXBsaWNhdGUgdGhlIHNlbGVjdGVkIGVsZW1lbnQgaWYgYWx0IGlzIHByZXNzZWQgb24gcG9pbnRlciBtb3ZlXG4gICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSAmJiAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQpIHtcbiAgICAgICAgICAgIC8vIE1vdmUgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBlbGVtZW50cyB0byB0aGUgdG9wIG9mIHRoZSB6IGluZGV4IHN0YWNrLCBhbmRcbiAgICAgICAgICAgIC8vIHB1dCB0aGUgZHVwbGljYXRlcyB3aGVyZSB0aGUgc2VsZWN0ZWQgZWxlbWVudHMgdXNlZCB0byBiZS5cbiAgICAgICAgICAgIC8vICh0aGUgb3JpZ2luIHBvaW50IHdoZXJlIHRoZSBkcmFnZ2luZyBzdGFydGVkKVxuXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHNUb0FwcGVuZCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudElkczogQXJyYXk8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXT4gPVxuICAgICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlLCB0cnVlKS5tYXAoXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQpID0+IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzLmluY2x1ZGVzKGVsZW1lbnQuaWQpIHx8XG4gICAgICAgICAgICAgICAgLy8gY2FzZTogdGhlIHN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyBtaWdodCBub3QgaGF2ZSBiZWVuXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlZCB5ZXQgYnkgdGhlIHRpbWUgdGhpcyBtb3VzZW1vdmUgZXZlbnQgaXMgZmlyZWRcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24pXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZWRFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgICAgICAgICAgICBncm91cElkTWFwLFxuICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtvcmlnaW5EcmFnWCwgb3JpZ2luRHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChkdXBsaWNhdGVkRWxlbWVudCwge1xuICAgICAgICAgICAgICAgICAgeDogZHVwbGljYXRlZEVsZW1lbnQueCArIChvcmlnaW5EcmFnWCAtIGRyYWdYKSxcbiAgICAgICAgICAgICAgICAgIHk6IGR1cGxpY2F0ZWRFbGVtZW50LnkgKyAob3JpZ2luRHJhZ1kgLSBkcmFnWSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZHVwbGljYXRlZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBkdXBsaWNhdGVkRWxlbWVudC5pZCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5leHRTY2VuZUVsZW1lbnRzID0gWy4uLm5leHRFbGVtZW50cywgLi4uZWxlbWVudHNUb0FwcGVuZF07XG4gICAgICAgICAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0RWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICAgXCJkdXBsaWNhdGVzU2VydmVBc09sZFwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRTY2VuZUVsZW1lbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEl0IGlzIHZlcnkgaW1wb3J0YW50IHRvIHJlYWQgdGhpcy5zdGF0ZSB3aXRoaW4gZWFjaCBtb3ZlIGV2ZW50LFxuICAgICAgLy8gb3RoZXJ3aXNlIHdlIHdvdWxkIHJlYWQgYSBzdGFsZSBvbmUhXG4gICAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgY29uc3QgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgY29uc3QgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHMubGVuZ3RoID4gMCAmJiBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCBkaXNjYXJkUG9pbnQgPVxuICAgICAgICAgIGxhc3RQb2ludCAmJiBsYXN0UG9pbnRbMF0gPT09IGR4ICYmIGxhc3RQb2ludFsxXSA9PT0gZHk7XG5cbiAgICAgICAgaWYgKCFkaXNjYXJkUG9pbnQpIHtcbiAgICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgICAgPyBkcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzXG4gICAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNMaW5lYXJFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgbGV0IGR4ID0gZ3JpZFggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gZ3JpZFkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBpZiAoc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpICYmIHBvaW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAoeyB3aWR0aDogZHgsIGhlaWdodDogZHkgfSA9IGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZShcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudC54LFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LnksXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cy5zbGljZSgwLCAtMSksIFtkeCwgZHldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpKSB7XG4gICAgICAgICAgLy8gV2hlbiBjcmVhdGluZyBhIGxpbmVhciBlbGVtZW50IGJ5IGRyYWdnaW5nXG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIFtwb2ludGVyQ29vcmRzXSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgICAvLyBhbGxvd3MgZm9yIGJveC1zZWxlY3RpbmcgcG9pbnRzICh3aXRob3V0IHNoaWZ0KVxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKGVsZW1lbnRzLCB0aGlzLnN0YXRlKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsICYmIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBib3gtc2VsZWN0IGxpbmUgZWRpdG9yIHBvaW50c1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlQm94U2VsZWN0aW9uKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gcmVndWxhciBib3gtc2VsZWN0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24gPSBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbihcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5lbGVtZW50c1dpdGhpblNlbGVjdGlvbi5yZWR1Y2UoXG4gICAgICAgICAgICAgICAgICAgIChhY2M6IFJlY29yZDxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdLCB0cnVlPiwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGFjY1tlbGVtZW50LmlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgLi4uKHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB1c2luZyBjdHJsL2NtZCwgc2VsZWN0IHRoZSBoaXRFbGVtZW50IG9ubHkgaWYgd2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmVuJ3QgYm94LXNlbGVjdGVkIGFueXRoaW5nIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LmlkXTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIWVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDogbnVsbCksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6XG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdLmxpbmtcbiAgICAgICAgICAgICAgICAgICAgPyBcImluZm9cIlxuICAgICAgICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgICAgIC8vIHNlbGVjdCBsaW5lYXIgZWxlbWVudCBvbmx5IHdoZW4gd2UgaGF2ZW4ndCBib3gtc2VsZWN0ZWQgYW55dGhpbmcgZWxzZVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDpcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdKVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgbW92ZSBoYXBwZW5lZCBvdmVyIGVpdGhlciBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJIb3Jpem9udGFsKSB7XG4gICAgICBjb25zdCB4ID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGR4ID0geCAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54O1xuICAgICAgdGhpcy50cmFuc2xhdGVDYW52YXMoe1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFggLSBkeCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSB4O1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJWZXJ0aWNhbCkge1xuICAgICAgY29uc3QgeSA9IGV2ZW50LmNsaWVudFk7XG4gICAgICBjb25zdCBkeSA9IHkgLSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueTtcbiAgICAgIHRoaXMudHJhbnNsYXRlQ2FudmFzKHtcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZHkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0geTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoY2hpbGRFdmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgcmVzaXppbmdFbGVtZW50LFxuICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgIGFjdGl2ZVRvb2wsXG4gICAgICAgIGlzUmVzaXppbmcsXG4gICAgICAgIGlzUm90YXRpbmcsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgaXNSb3RhdGluZzogZmFsc2UsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogbnVsbCxcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIC8vIHRleHQgZWxlbWVudHMgYXJlIHJlc2V0IG9uIGZpbmFsaXplLCBhbmQgcmVzZXR0aW5nIG9uIHBvaW50ZXJ1cFxuICAgICAgICAvLyBtYXkgY2F1c2UgaXNzdWVzIHdpdGggZG91YmxlIHRhcHNcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgbXVsdGlFbGVtZW50IHx8IGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgICAgID8gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudFxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoY2hpbGRFdmVudC5jbGllbnRYLCBjaGlsZEV2ZW50LmNsaWVudFksIFwidXBcIik7XG5cbiAgICAgIHRoaXMub25Qb2ludGVyVXBFbWl0dGVyLnRyaWdnZXIoXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICk7XG5cbiAgICAgIC8vIEhhbmRsZSBlbmQgb2YgZHJhZ2dpbmcgYSBwb2ludCBvZiBhIGxpbmVhciBlbGVtZW50LCBtaWdodCBjbG9zZSBhIGxvb3BcbiAgICAgIC8vIGFuZCBzZXRzIGJpbmRpbmcgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Py5lbGVtZW50Py5pZCAhPT1cbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlclVwKFxuICAgICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50ICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQ/LmVsZW1lbnQ/LmlkICE9PVxuICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmVsZW1lbnRJZFxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEVMZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCB0byBudWxsIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgZWxlbWVudCBzZWxlY3RlZCBzaW5jZSB3ZSBkb24ndCB3YW50IHRvIHNob3cgbGluZWFyIGVsZW1lbnQgaGFuZGxlc1xuICAgICAgICAgIGlmIChzZWxlY3RlZEVMZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGxpbmVhckVsZW1lbnRFZGl0b3IgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJVcChcbiAgICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHsgc3RhcnRCaW5kaW5nRWxlbWVudCwgZW5kQmluZGluZ0VsZW1lbnQgfSA9XG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yO1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnQobGluZWFyRWxlbWVudEVkaXRvci5lbGVtZW50SWQpO1xuICAgICAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBiaW5kT3JVbmJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBzdGFydEJpbmRpbmdFbGVtZW50LFxuICAgICAgICAgICAgICBlbmRCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGxpbmVhckVsZW1lbnRFZGl0b3IgIT09IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgLi4ubGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgICAgICAgICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6IG51bGwsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcblxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlLmZsdXNoKCk7XG4gICAgICB9XG5cbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5QT0lOVEVSX01PVkUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuUE9JTlRFUl9VUCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vblVwISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuS0VZRE9XTixcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleURvd24hLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5LRVlVUCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleVVwISxcbiAgICAgICk7XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBudWxsIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50Py50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgbGV0IGR4ID0gcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGxldCBkeSA9IHBvaW50ZXJDb29yZHMueSAtIGRyYWdnaW5nRWxlbWVudC55O1xuXG4gICAgICAgIC8vIEFsbG93cyBkb3RzIHRvIGF2b2lkIGJlaW5nIGZsYWdnZWQgYXMgaW5maW5pdGVseSBzbWFsbFxuICAgICAgICBpZiAoZHggPT09IHBvaW50c1swXVswXSAmJiBkeSA9PT0gcG9pbnRzWzBdWzFdKSB7XG4gICAgICAgICAgZHkgKz0gMC4wMDAxO1xuICAgICAgICAgIGR4ICs9IDAuMDAwMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByZXNzdXJlcyA9IGRyYWdnaW5nRWxlbWVudC5zaW11bGF0ZVByZXNzdXJlXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogWy4uLmRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXMsIGNoaWxkRXZlbnQucHJlc3N1cmVdO1xuXG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgcHJlc3N1cmVzLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDogW2R4LCBkeV0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoaXNJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSBkcmFnZ2luZ0VsZW1lbnQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICAgIHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgICAuZmlsdGVyKChlbCkgPT4gZWwuaWQgIT09IGltYWdlRWxlbWVudC5pZCksXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNMaW5lYXJFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCEucG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQgJiZcbiAgICAgICAgICAhbXVsdGlFbGVtZW50XG4gICAgICAgICkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgICAgLi4uZHJhZ2dpbmdFbGVtZW50LnBvaW50cyxcbiAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54LFxuICAgICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSAtIGRyYWdnaW5nRWxlbWVudC55LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIG11bHRpRWxlbWVudDogZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJiAhbXVsdGlFbGVtZW50KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKSAmJlxuICAgICAgICAgICAgaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIGZhbHNlKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSwgc3RhcnRCb3VuZEVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICAgICAgaWYgKCFhY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFtkcmFnZ2luZ0VsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQgJiZcbiAgICAgICAgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgKSB7XG4gICAgICAgIC8vIHJlbW92ZSBpbnZpc2libGUgZWxlbWVudCB3aGljaCB3YXMgYWRkZWQgaW4gb25Qb2ludGVyRG93blxuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWREaW1lbnNpb25zKGRyYWdnaW5nRWxlbWVudCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNpemluZ0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50ICYmIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KHJlc2l6aW5nRWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgICAgICAuZmlsdGVyKChlbCkgPT4gZWwuaWQgIT09IHJlc2l6aW5nRWxlbWVudC5pZCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvZGUgYmVsb3cgaGFuZGxlcyBzZWxlY3Rpb24gd2hlbiBlbGVtZW50KHMpIHdlcmVuJ3RcbiAgICAgIC8vIGRyYWcgb3IgYWRkZWQgdG8gc2VsZWN0aW9uIG9uIHBvaW50ZXIgZG93biBwaGFzZS5cbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50O1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudD8uZWxlbWVudElkICE9PSBoaXRFbGVtZW50Py5pZCAmJlxuICAgICAgICBpc0xpbmVhckVsZW1lbnQoaGl0RWxlbWVudClcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVMZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIC8vIHNldCBzZWxlY3RlZExpbmVhckVsZW1lbnQgd2hlbiBubyBvdGhlciBlbGVtZW50IHNlbGVjdGVkIGV4Y2VwdFxuICAgICAgICAvLyB0aGUgb25lIHdlJ3ZlIGhpdFxuICAgICAgICBpZiAoc2VsZWN0ZWRFTGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNFcmFzZXJBY3RpdmUodGhpcy5zdGF0ZSkpIHtcbiAgICAgICAgY29uc3QgZHJhZ2dlZERpc3RhbmNlID0gZGlzdGFuY2UyZChcbiAgICAgICAgICB0aGlzLmxhc3RQb2ludGVyRG93biEuY2xpZW50WCxcbiAgICAgICAgICB0aGlzLmxhc3RQb2ludGVyRG93biEuY2xpZW50WSxcbiAgICAgICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRZLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChkcmFnZ2VkRGlzdGFuY2UgPT09IDApIHtcbiAgICAgICAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNsaWVudFg6IHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WCxcbiAgICAgICAgICAgICAgY2xpZW50WTogdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRZLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBoaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGhpdEVsZW1lbnRzLmZvckVhY2goXG4gICAgICAgICAgICAoaGl0RWxlbWVudCkgPT5cbiAgICAgICAgICAgICAgKHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaGl0RWxlbWVudC5pZF0gPSB7XG4gICAgICAgICAgICAgICAgZXJhc2U6IHRydWUsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogaGl0RWxlbWVudC5vcGFjaXR5LFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXJhc2VFbGVtZW50cyhwb2ludGVyRG93blN0YXRlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIGlmIChPYmplY3Qua2V5cyhwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlKS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5yZXN0b3JlUmVhZHlUb0VyYXNlRWxlbWVudHMocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uICYmXG4gICAgICAgIC8vIGlmIHdlJ3JlIGVkaXRpbmcgYSBsaW5lLCBwb2ludGVydXAgc2hvdWxkbid0IHN3aXRjaCBzZWxlY3Rpb24gaWZcbiAgICAgICAgLy8gYm94IHNlbGVjdGVkXG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZClcbiAgICAgICkge1xuICAgICAgICAvLyB3aGVuIGluc2lkZSBsaW5lIGVkaXRvciwgc2hpZnQgc2VsZWN0cyBwb2ludHMgaW5zdGVhZFxuICAgICAgICBpZiAoY2hpbGRFdmVudC5zaGlmdEtleSAmJiAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSkge1xuICAgICAgICAgICAgaWYgKGlzU2VsZWN0ZWRWaWFHcm91cCh0aGlzLnN0YXRlLCBoaXRFbGVtZW50KSkge1xuICAgICAgICAgICAgICAvLyBXZSB3YW50IHRvIHVuc2VsZWN0IGFsbCBncm91cHMgaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIC8vIGFzIHdlbGwgYXMgYWxsIGVsZW1lbnRzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGdyb3Vwc1xuICAgICAgICAgICAgICAvLyBoaXRFbGVtZW50IGlzIHBhcnQgb2ZcbiAgICAgICAgICAgICAgY29uc3QgaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzID0gaGl0RWxlbWVudC5ncm91cElkc1xuICAgICAgICAgICAgICAgIC5mbGF0TWFwKChncm91cElkKSA9PlxuICAgICAgICAgICAgICAgICAgZ2V0RWxlbWVudHNJbkdyb3VwKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICAgICAgICBncm91cElkLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLm1hcCgoZWxlbWVudCkgPT4gKHsgW2VsZW1lbnQuaWRdOiBmYWxzZSB9KSlcbiAgICAgICAgICAgICAgICAucmVkdWNlKChwcmV2SWQsIGFjYykgPT4gKHsgLi4ucHJldklkLCAuLi5hY2MgfSksIHt9KTtcblxuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaGl0RWxlbWVudC5ncm91cElkc1xuICAgICAgICAgICAgICAgICAgICAubWFwKChnSWQpID0+ICh7IFtnSWRdOiBmYWxzZSB9KSlcbiAgICAgICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldiwgYWNjKSA9PiAoeyAuLi5wcmV2LCAuLi5hY2MgfSksIHt9KSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5pZHNPZlNlbGVjdGVkRWxlbWVudHNUaGF0QXJlSW5Hcm91cHMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAvLyBpZiBub3QgZ3JhZ2dpbmcgYSBsaW5lYXIgZWxlbWVudCBwb2ludCAob3V0c2lkZSBlZGl0b3IpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudD8uaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgICAvLyByZW1vdmUgZWxlbWVudCBmcm9tIHNlbGVjdGlvbiB3aGlsZVxuICAgICAgICAgICAgICAvLyBrZWVwaW5nIHByZXYgZWxlbWVudHMgc2VsZWN0ZWRcblxuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdTZWxlY3RlZEVsZW1lbnRJZHMgPSB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQhLmlkXTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdTZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgICB7IC4uLnByZXZTdGF0ZSwgc2VsZWN0ZWRFbGVtZW50SWRzOiBuZXdTZWxlY3RlZEVsZW1lbnRJZHMgfSxcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBuZXdTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCBzZWxlY3RlZExpbmVhckVsZW1lbnQgb25seSBpZiB0aGF0cyB0aGUgb25seSBlbGVtZW50IHNlbGVjdGVkXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDpcbiAgICAgICAgICAgICAgICAgICAgICBuZXdTZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICAgICAgIGlzTGluZWFyRWxlbWVudChuZXdTZWxlY3RlZEVsZW1lbnRzWzBdKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdTZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIDogcHJldlN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBhZGQgZWxlbWVudCB0byBzZWxlY3Rpb24gd2hpbGVcbiAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgLi4uc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2hpdEVsZW1lbnQuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OlxuICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KGhpdEVsZW1lbnQpICYmXG4gICAgICAgICAgICAgICAgICAvLyBEb24ndCBzZXQgYHNlbGVjdGVkTGluZWFyRWxlbWVudGAgaWYgaXRzIHNhbWUgYXMgdGhlIGhpdEVsZW1lbnQsIHRoaXMgaXMgbWFpbmx5IHRvIHByZXZlbnQgcmVzZXR0aW5nIHRoZSBgaG92ZXJQb2ludEluZGV4YCB0byAtMS5cbiAgICAgICAgICAgICAgICAgIC8vIEZ1dHVyZSB3ZSBzaG91bGQgdXBkYXRlIHRoZSBBUEkgdG8gdGFrZSBjYXJlIG9mIHNldHRpbmcgdGhlIGNvcnJlY3QgYGhvdmVyUG9pbnRJbmRleGAgd2hlbiBpbml0aWFsaXplZFxuICAgICAgICAgICAgICAgICAgcHJldlN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudD8uZWxlbWVudElkICE9PSBoaXRFbGVtZW50LmlkXG4gICAgICAgICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoaGl0RWxlbWVudCwgdGhpcy5zY2VuZSlcbiAgICAgICAgICAgICAgICAgICAgOiBwcmV2U3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICF0aGlzLnN0YXRlLmlzUmVzaXppbmcgJiZcbiAgICAgICAgKChoaXRFbGVtZW50ICYmXG4gICAgICAgICAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApKSB8fFxuICAgICAgICAgICghaGl0RWxlbWVudCAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpKVxuICAgICAgKSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdMaW5lYXJFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIERlc2VsZWN0IHNlbGVjdGVkIGVsZW1lbnRzXG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIWFjdGl2ZVRvb2wubG9ja2VkICYmXG4gICAgICAgIGFjdGl2ZVRvb2wudHlwZSAhPT0gXCJmcmVlZHJhd1wiICYmXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICBbZHJhZ2dpbmdFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiIHx8XG4gICAgICAgIGlzU29tZUVsZW1lbnRTZWxlY3RlZCh0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCB0aGlzLnN0YXRlKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCB8fCBpc1Jlc2l6aW5nIHx8IGlzUm90YXRpbmcpIHtcbiAgICAgICAgKGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgICA/IGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgICA6IHVuYmluZExpbmVhckVsZW1lbnRzKShcbiAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWFjdGl2ZVRvb2wubG9ja2VkICYmIGFjdGl2ZVRvb2wudHlwZSAhPT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzdG9yZVJlYWR5VG9FcmFzZUVsZW1lbnRzID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0gJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdLmVyYXNlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgIG9wYWNpdHk6IHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5vcGFjaXR5LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGlzQm91bmRUb0NvbnRhaW5lcihlbGUpICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgb3BhY2l0eTogcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdLm9wYWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGVsZW1lbnRzKTtcbiAgfTtcblxuICBwcml2YXRlIGVyYXNlRWxlbWVudHMgPSAocG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0gJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdLmVyYXNlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwgeyBpc0RlbGV0ZWQ6IHRydWUgfSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBpc0JvdW5kVG9Db250YWluZXIoZWxlKSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0gJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdLmVyYXNlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwgeyBpc0RlbGV0ZWQ6IHRydWUgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGVsZW1lbnRzKTtcbiAgfTtcblxuICBwcml2YXRlIGluaXRpYWxpemVJbWFnZSA9IGFzeW5jICh7XG4gICAgaW1hZ2VGaWxlLFxuICAgIGltYWdlRWxlbWVudDogX2ltYWdlRWxlbWVudCxcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ID0gZmFsc2UsXG4gIH06IHtcbiAgICBpbWFnZUZpbGU6IEZpbGU7XG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50O1xuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgLy8gYXQgdGhpcyBwb2ludCB0aGlzIHNob3VsZCBiZSBndWFyYW50ZWVkIGltYWdlIGZpbGUsIGJ1dCB3ZSBkbyB0aGlzIGNoZWNrXG4gICAgLy8gdG8gc2F0aXNmeSBUUyBkb3duIHRoZSBsaW5lXG4gICAgaWYgKCFpc1N1cHBvcnRlZEltYWdlRmlsZShpbWFnZUZpbGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy51bnN1cHBvcnRlZEZpbGVUeXBlXCIpKTtcbiAgICB9XG4gICAgY29uc3QgbWltZVR5cGUgPSBpbWFnZUZpbGUudHlwZTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgXCJ3YWl0XCIpO1xuXG4gICAgaWYgKG1pbWVUeXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW1hZ2VGaWxlID0gU1ZHU3RyaW5nVG9GaWxlKFxuICAgICAgICAgIGF3YWl0IG5vcm1hbGl6ZVNWRyhhd2FpdCBpbWFnZUZpbGUudGV4dCgpKSxcbiAgICAgICAgICBpbWFnZUZpbGUubmFtZSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMuc3ZnSW1hZ2VJbnNlcnRFcnJvclwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZ2VuZXJhdGUgaW1hZ2UgaWQgKGJ5IGRlZmF1bHQgdGhlIGZpbGUgZGlnZXN0KSBiZWZvcmUgYW55XG4gICAgLy8gcmVzaXppbmcvY29tcHJlc3Npb24gdGFrZXMgcGxhY2UgdG8ga2VlcCBpdCBtb3JlIHBvcnRhYmxlXG4gICAgY29uc3QgZmlsZUlkID0gYXdhaXQgKCh0aGlzLnByb3BzLmdlbmVyYXRlSWRGb3JGaWxlPy4oXG4gICAgICBpbWFnZUZpbGUsXG4gICAgKSBhcyBQcm9taXNlPEZpbGVJZD4pIHx8IGdlbmVyYXRlSWRGcm9tRmlsZShpbWFnZUZpbGUpKTtcblxuICAgIGlmICghZmlsZUlkKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiQ291bGRuJ3QgZ2VuZXJhdGUgZmlsZSBpZCBvciB0aGUgc3VwcGxpZWQgYGdlbmVyYXRlSWRGb3JGaWxlYCBkaWRuJ3QgcmVzb2x2ZSB0byBvbmUuXCIsXG4gICAgICApO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdGaWxlRGF0YSA9IHRoaXMuZmlsZXNbZmlsZUlkXTtcbiAgICBpZiAoIWV4aXN0aW5nRmlsZURhdGE/LmRhdGFVUkwpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgICAgICBtYXhXaWR0aE9ySGVpZ2h0OiBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiZXJyb3IgdHJ5aW5nIHRvIHJlc2luZyBpbWFnZSBmaWxlIG9uIGluc2VydGlvblwiLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbWFnZUZpbGUuc2l6ZSA+IE1BWF9BTExPV0VEX0ZJTEVfQllURVMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIHQoXCJlcnJvcnMuZmlsZVRvb0JpZ1wiLCB7XG4gICAgICAgICAgICBtYXhTaXplOiBgJHtNYXRoLnRydW5jKE1BWF9BTExPV0VEX0ZJTEVfQllURVMgLyAxMDI0IC8gMTAyNCl9TUJgLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICBjb25zdCBkYXRhVVJMID0gdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMO1xuICAgICAgLy8gb3B0aW1pemF0aW9uIHNvIHRoYXQgd2UgZG9uJ3QgdW5uZWNlc3NhcmlseSByZXNpemUgdGhlIG9yaWdpbmFsXG4gICAgICAvLyBmdWxsLXNpemUgZmlsZSBmb3IgY3Vyc29yIHByZXZpZXdcbiAgICAgIC8vIChpdCdzIG11Y2ggZmFzdGVyIHRvIGNvbnZlcnQgdGhlIHJlc2l6ZWQgZGF0YVVSTCB0byBGaWxlKVxuICAgICAgY29uc3QgcmVzaXplZEZpbGUgPSBkYXRhVVJMICYmIGRhdGFVUkxUb0ZpbGUoZGF0YVVSTCk7XG5cbiAgICAgIHRoaXMuc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yKHJlc2l6ZWRGaWxlIHx8IGltYWdlRmlsZSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YVVSTCA9XG4gICAgICB0aGlzLmZpbGVzW2ZpbGVJZF0/LmRhdGFVUkwgfHwgKGF3YWl0IGdldERhdGFVUkwoaW1hZ2VGaWxlKSk7XG5cbiAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSBtdXRhdGVFbGVtZW50KFxuICAgICAgX2ltYWdlRWxlbWVudCxcbiAgICAgIHtcbiAgICAgICAgZmlsZUlkLFxuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICkgYXMgTm9uRGVsZXRlZDxJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ+O1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50Pj4oXG4gICAgICBhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5maWxlcyA9IHtcbiAgICAgICAgICAgIC4uLnRoaXMuZmlsZXMsXG4gICAgICAgICAgICBbZmlsZUlkXToge1xuICAgICAgICAgICAgICBtaW1lVHlwZSxcbiAgICAgICAgICAgICAgaWQ6IGZpbGVJZCxcbiAgICAgICAgICAgICAgZGF0YVVSTCxcbiAgICAgICAgICAgICAgY3JlYXRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgbGFzdFJldHJpZXZlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjYWNoZWRJbWFnZURhdGEgPSB0aGlzLmltYWdlQ2FjaGUuZ2V0KGZpbGVJZCk7XG4gICAgICAgICAgaWYgKCFjYWNoZWRJbWFnZURhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUltYWdlQ2FjaGUoW2ltYWdlRWxlbWVudF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2FjaGVkSW1hZ2VEYXRhPy5pbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIGF3YWl0IGNhY2hlZEltYWdlRGF0YS5pbWFnZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQgIT09IGltYWdlRWxlbWVudC5pZCAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ/LmlkICE9PSBpbWFnZUVsZW1lbnQuaWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQsIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGltYWdlRWxlbWVudCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSkpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmICghc2hvd0N1cnNvckltYWdlUHJldmlldykge1xuICAgICAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBpbnNlcnRzIGltYWdlIGludG8gZWxlbWVudHMgYXJyYXkgYW5kIHJlcmVuZGVyc1xuICAgKi9cbiAgcHJpdmF0ZSBpbnNlcnRJbWFnZUVsZW1lbnQgPSBhc3luYyAoXG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICAgIGltYWdlRmlsZTogRmlsZSxcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3PzogYm9vbGVhbixcbiAgKSA9PiB7XG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIGltYWdlRWxlbWVudCxcbiAgICBdKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXRpYWxpemVJbWFnZSh7XG4gICAgICAgIGltYWdlRmlsZSxcbiAgICAgICAgaW1hZ2VFbGVtZW50LFxuICAgICAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgaXNEZWxldGVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIHx8IHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHNldEltYWdlUHJldmlld0N1cnNvciA9IGFzeW5jIChpbWFnZUZpbGU6IEZpbGUpID0+IHtcbiAgICAvLyBtdXN0bid0IGJlIGxhcmdlciB0aGFuIDEyOCBweFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9DU1NfQmFzaWNfVXNlcl9JbnRlcmZhY2UvVXNpbmdfVVJMX3ZhbHVlc19mb3JfdGhlX2N1cnNvcl9wcm9wZXJ0eVxuICAgIGNvbnN0IGN1cnNvckltYWdlU2l6ZVB4ID0gOTY7XG5cbiAgICBjb25zdCBpbWFnZVByZXZpZXcgPSBhd2FpdCByZXNpemVJbWFnZUZpbGUoaW1hZ2VGaWxlLCB7XG4gICAgICBtYXhXaWR0aE9ySGVpZ2h0OiBjdXJzb3JJbWFnZVNpemVQeCxcbiAgICB9KTtcblxuICAgIGxldCBwcmV2aWV3RGF0YVVSTCA9IGF3YWl0IGdldERhdGFVUkwoaW1hZ2VQcmV2aWV3KTtcblxuICAgIC8vIFNWRyBjYW5ub3QgYmUgcmVzaXplZCB2aWEgYHJlc2l6ZUltYWdlRmlsZWAgc28gd2UgcmVzaXplIGJ5IHJlbmRlcmluZyB0b1xuICAgIC8vIGEgc21hbGwgY2FudmFzXG4gICAgaWYgKGltYWdlRmlsZS50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgY29uc3QgaW1nID0gYXdhaXQgbG9hZEhUTUxJbWFnZUVsZW1lbnQocHJldmlld0RhdGFVUkwpO1xuXG4gICAgICBsZXQgaGVpZ2h0ID0gTWF0aC5taW4oaW1nLmhlaWdodCwgY3Vyc29ySW1hZ2VTaXplUHgpO1xuICAgICAgbGV0IHdpZHRoID0gaGVpZ2h0ICogKGltZy53aWR0aCAvIGltZy5oZWlnaHQpO1xuXG4gICAgICBpZiAod2lkdGggPiBjdXJzb3JJbWFnZVNpemVQeCkge1xuICAgICAgICB3aWR0aCA9IGN1cnNvckltYWdlU2l6ZVB4O1xuICAgICAgICBoZWlnaHQgPSB3aWR0aCAqIChpbWcuaGVpZ2h0IC8gaW1nLndpZHRoKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICBjYW52YXMud2lkdGggPSB3aWR0aDtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpITtcblxuICAgICAgY29udGV4dC5kcmF3SW1hZ2UoaW1nLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgcHJldmlld0RhdGFVUkwgPSBjYW52YXMudG9EYXRhVVJMKE1JTUVfVFlQRVMuc3ZnKSBhcyBEYXRhVVJMO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBgdXJsKCR7cHJldmlld0RhdGFVUkx9KSA0IDQsIGF1dG9gKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbkltYWdlQWN0aW9uID0gYXN5bmMgKFxuICAgIHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseSB9ID0geyBpbnNlcnRPbkNhbnZhc0RpcmVjdGx5OiBmYWxzZSB9LFxuICApID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY2xpZW50WCA9IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgICAgY29uc3QgY2xpZW50WSA9IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgeyBjbGllbnRYLCBjbGllbnRZIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZUZpbGUgPSBhd2FpdCBmaWxlT3Blbih7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkltYWdlXCIsXG4gICAgICAgIGV4dGVuc2lvbnM6IE9iamVjdC5rZXlzKFxuICAgICAgICAgIElNQUdFX01JTUVfVFlQRVMsXG4gICAgICAgICkgYXMgKGtleW9mIHR5cGVvZiBJTUFHRV9NSU1FX1RZUEVTKVtdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHtcbiAgICAgICAgc2NlbmVYOiB4LFxuICAgICAgICBzY2VuZVk6IHksXG4gICAgICB9KTtcblxuICAgICAgaWYgKGluc2VydE9uQ2FudmFzRGlyZWN0bHkpIHtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBpbWFnZUZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IGltYWdlRWxlbWVudC5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KFxuICAgICAgICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgICAgICAgIGltYWdlRmlsZSxcbiAgICAgICAgICAgICAgLyogc2hvd0N1cnNvckltYWdlUHJldmlldyAqLyB0cnVlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkFib3J0RXJyb3JcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICB9XG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zID0gKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBmb3JjZU5hdHVyYWxTaXplID0gZmFsc2UsXG4gICkgPT4ge1xuICAgIGNvbnN0IGltYWdlID1cbiAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50KSAmJlxuICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChpbWFnZUVsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG5cbiAgICBpZiAoIWltYWdlIHx8IGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgaWYgKFxuICAgICAgICBpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyU2l6ZSA9IDEwMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgICB4OiBpbWFnZUVsZW1lbnQueCAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgeTogaW1hZ2VFbGVtZW50LnkgLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHdpZHRoOiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgICAgaGVpZ2h0OiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgZm9yY2VOYXR1cmFsU2l6ZSB8fFxuICAgICAgLy8gaWYgdXNlci1jcmVhdGVkIGJvdW5kaW5nIGJveCBpcyBiZWxvdyB0aHJlc2hvbGQsIGFzc3VtZSB0aGVcbiAgICAgIC8vIGludGVudGlvbiB3YXMgdG8gY2xpY2sgaW5zdGVhZCBvZiBkcmFnLCBhbmQgdXNlIHRoZSBpbWFnZSdzXG4gICAgICAvLyBpbnRyaW5zaWMgc2l6ZVxuICAgICAgKGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICkge1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5oZWlnaHQgLSAxMjAsIDE2MCk7XG4gICAgICAvLyBtYXggNjUlIG9mIGNhbnZhcyBoZWlnaHQsIGNsYW1wZWQgdG8gPDMwMHB4LCB2aCAtIDEyMHB4PlxuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gTWF0aC5taW4oXG4gICAgICAgIG1pbkhlaWdodCxcbiAgICAgICAgTWF0aC5mbG9vcih0aGlzLnN0YXRlLmhlaWdodCAqIDAuNSkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1pbihpbWFnZS5uYXR1cmFsSGVpZ2h0LCBtYXhIZWlnaHQpO1xuICAgICAgY29uc3Qgd2lkdGggPSBoZWlnaHQgKiAoaW1hZ2UubmF0dXJhbFdpZHRoIC8gaW1hZ2UubmF0dXJhbEhlaWdodCk7XG5cbiAgICAgIC8vIGFkZCBjdXJyZW50IGltYWdlRWxlbWVudCB3aWR0aC9oZWlnaHQgdG8gYWNjb3VudCBmb3IgcHJldmlvdXMgY2VudGVyaW5nXG4gICAgICAvLyBvZiB0aGUgcGxhY2Vob2xkZXIgaW1hZ2VcbiAgICAgIGNvbnN0IHggPSBpbWFnZUVsZW1lbnQueCArIGltYWdlRWxlbWVudC53aWR0aCAvIDIgLSB3aWR0aCAvIDI7XG4gICAgICBjb25zdCB5ID0gaW1hZ2VFbGVtZW50LnkgKyBpbWFnZUVsZW1lbnQuaGVpZ2h0IC8gMiAtIGhlaWdodCAvIDI7XG5cbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7IHgsIHksIHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiB1cGRhdGVzIGltYWdlIGNhY2hlLCByZWZyZXNoaW5nIHVwZGF0ZWQgZWxlbWVudHMgYW5kL29yIHNldHRpbmcgc3RhdHVzXG4gICAgICB0byBlcnJvciBmb3IgaW1hZ2VzIHRoYXQgZmFpbCBkdXJpbmcgPGltZz4gZWxlbWVudCBjcmVhdGlvbiAqL1xuICBwcml2YXRlIHVwZGF0ZUltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdLFxuICAgIGZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgeyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9ID0gYXdhaXQgX3VwZGF0ZUltYWdlQ2FjaGUoe1xuICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgZmlsZUlkczogZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiBlbGVtZW50LmZpbGVJZCksXG4gICAgICBmaWxlcyxcbiAgICB9KTtcbiAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUgfHwgZXJyb3JlZEZpbGVzLnNpemUpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICBpZiAodXBkYXRlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZCkpIHtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgICAgZXJyb3JlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGVtZW50LCB7XG4gICAgICAgICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdXBkYXRlZEZpbGVzLCBlcnJvcmVkRmlsZXMgfTtcbiAgfTtcblxuICAvKiogYWRkcyBuZXcgaW1hZ2VzIHRvIGltYWdlQ2FjaGUgYW5kIHJlLXJlbmRlcnMgaWYgbmVlZGVkICovXG4gIHByaXZhdGUgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudHM6IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdID0gZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICApLFxuICAgIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHRoaXMuZmlsZXMsXG4gICkgPT4ge1xuICAgIGNvbnN0IHVuY2FjaGVkSW1hZ2VFbGVtZW50cyA9IGltYWdlRWxlbWVudHMuZmlsdGVyKFxuICAgICAgKGVsZW1lbnQpID0+ICFlbGVtZW50LmlzRGVsZXRlZCAmJiAhdGhpcy5pbWFnZUNhY2hlLmhhcyhlbGVtZW50LmZpbGVJZCksXG4gICAgKTtcblxuICAgIGlmICh1bmNhY2hlZEltYWdlRWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcyB9ID0gYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFxuICAgICAgICB1bmNhY2hlZEltYWdlRWxlbWVudHMsXG4gICAgICAgIGZpbGVzLFxuICAgICAgKTtcbiAgICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSkge1xuICAgICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKiBnZW5lcmFsbHkgeW91IHNob3VsZCB1c2UgYGFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpYCBkaXJlY3RseSBpZiB5b3UgbmVlZFxuICAgKiAgdG8gcmVuZGVyIG5ldyBpbWFnZXMuIFRoaXMgaXMganVzdCBhIGZhaWxzYWZlICAqL1xuICBwcml2YXRlIHNjaGVkdWxlSW1hZ2VSZWZyZXNoID0gdGhyb3R0bGUoKCkgPT4ge1xuICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gIH0sIElNQUdFX1JFTkRFUl9USU1FT1VUKTtcblxuICBwcml2YXRlIHVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgY29uc3Qgc2hvdWxkRW5hYmxlQmluZGluZyA9IHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQoZXZlbnQpO1xuICAgIGlmICh0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQgIT09IHNob3VsZEVuYWJsZUJpbmRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBzaG91bGRFbmFibGVCaW5kaW5nIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvciA9IChwb2ludGVyQ29vcmRzOiB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgfSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6XG4gICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCA/IFtob3ZlcmVkQmluZGFibGVFbGVtZW50XSA6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMgPSAoXG4gICAgbGluZWFyRWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgLyoqIHNjZW5lIGNvb3JkcyAqL1xuICAgIHBvaW50ZXJDb29yZHM6IHtcbiAgICAgIHg6IG51bWJlcjtcbiAgICAgIHk6IG51bWJlcjtcbiAgICB9W10sXG4gICAgLy8gRHVyaW5nIGxpbmUgY3JlYXRpb24gdGhlIHN0YXJ0IGJpbmRpbmcgaGFzbid0IGJlZW4gd3JpdHRlbiB5ZXRcbiAgICAvLyBpbnRvIGBsaW5lYXJFbGVtZW50YFxuICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD86IEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQgfCBudWxsLFxuICApOiB2b2lkID0+IHtcbiAgICBpZiAoIXBvaW50ZXJDb29yZHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBwb2ludGVyQ29vcmRzLnJlZHVjZShcbiAgICAgIChhY2M6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudD5bXSwgY29vcmRzKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgICAgY29vcmRzLFxuICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgICAhaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kKFxuICAgICAgICAgICAgbGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD8uaWQsXG4gICAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50LFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjLnB1c2goaG92ZXJlZEJpbmRhYmxlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICBbXSxcbiAgICApO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IGdldEVsaWdpYmxlRWxlbWVudHNGb3JCaW5kaW5nKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgLy8gQ29udGludWUgZWRpdGluZyB0aGUgc2FtZSBncm91cCBpZiB0aGUgdXNlciBzZWxlY3RlZCBhIGRpZmZlcmVudFxuICAgICAgLy8gZWxlbWVudCBmcm9tIGl0XG4gICAgICBlZGl0aW5nR3JvdXBJZDpcbiAgICAgICAgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgIGhpdEVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICBpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZClcbiAgICAgICAgICA/IHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZFxuICAgICAgICAgIDogbnVsbCxcbiAgICB9KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNSZWYgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCkgPT4ge1xuICAgIC8vIGNhbnZhcyBpcyBudWxsIHdoZW4gdW5tb3VudGluZ1xuICAgIGlmIChjYW52YXMgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgICAgdGhpcy5yYyA9IHJvdWdoLmNhbnZhcyh0aGlzLmNhbnZhcyk7XG5cbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwsIHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsKTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVBcHBPbkRyb3AgPSBhc3luYyAoZXZlbnQ6IFJlYWN0LkRyYWdFdmVudDxIVE1MRGl2RWxlbWVudD4pID0+IHtcbiAgICAvLyBtdXN0IGJlIHJldHJpZXZlZCBmaXJzdCwgaW4gdGhlIHNhbWUgZnJhbWVcbiAgICBjb25zdCB7IGZpbGUsIGZpbGVIYW5kbGUgfSA9IGF3YWl0IGdldEZpbGVGcm9tRXZlbnQoZXZlbnQpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICAvLyBmaXJzdCBhdHRlbXB0IHRvIGRlY29kZSBzY2VuZSBmcm9tIHRoZSBpbWFnZSBpZiBpdCdzIGVtYmVkZGVkXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGlmIChmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnBuZyB8fCBmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzY2VuZSA9IGF3YWl0IGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAuLi4oc2NlbmUuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJFbmNvZGluZ0Vycm9yXCIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm8gc2NlbmUgaXMgZW1iZWRkZWQgb3Igd2UgZmFpbCBmb3Igd2hhdGV2ZXIgcmVhc29uLCBmYWxsIGJhY2tcbiAgICAgICAgLy8gdG8gaW1wb3J0aW5nIGFzIHJlZ3VsYXIgaW1hZ2VcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBsaWJyYXJ5SlNPTiA9IGV2ZW50LmRhdGFUcmFuc2Zlci5nZXREYXRhKE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYik7XG4gICAgaWYgKGxpYnJhcnlKU09OICYmIHR5cGVvZiBsaWJyYXJ5SlNPTiA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbGlicmFyeUl0ZW1zID0gcGFyc2VMaWJyYXJ5SlNPTihsaWJyYXJ5SlNPTik7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkaXN0cmlidXRlTGlicmFyeUl0ZW1zT25TcXVhcmVHcmlkKGxpYnJhcnlJdGVtcyksXG4gICAgICAgICAgcG9zaXRpb246IGV2ZW50LFxuICAgICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZmlsZSkge1xuICAgICAgLy8gYXRldG1wdCB0byBwYXJzZSBhbiBleGNhbGlkcmF3L2V4Y2FsaWRyYXdsaWIgZmlsZVxuICAgICAgYXdhaXQgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUsIGZpbGVIYW5kbGUpO1xuICAgIH1cbiAgfTtcblxuICBsb2FkRmlsZVRvQ2FudmFzID0gYXN5bmMgKFxuICAgIGZpbGU6IEZpbGUsXG4gICAgZmlsZUhhbmRsZTogRmlsZVN5c3RlbUhhbmRsZSB8IG51bGwsXG4gICkgPT4ge1xuICAgIGZpbGUgPSBhd2FpdCBub3JtYWxpemVGaWxlKGZpbGUpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXQgPSBhd2FpdCBsb2FkU2NlbmVPckxpYnJhcnlGcm9tQmxvYihcbiAgICAgICAgZmlsZSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICk7XG4gICAgICBpZiAocmV0LnR5cGUgPT09IE1JTUVfVFlQRVMuZXhjYWxpZHJhdykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgIC4uLnJldC5kYXRhLFxuICAgICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgICAuLi4ocmV0LmRhdGEuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHJldC50eXBlID09PSBNSU1FX1RZUEVTLmV4Y2FsaWRyYXdsaWIpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5saWJyYXJ5XG4gICAgICAgICAgLnVwZGF0ZUxpYnJhcnkoe1xuICAgICAgICAgICAgbGlicmFyeUl0ZW1zOiBmaWxlLFxuICAgICAgICAgICAgbWVyZ2U6IHRydWUsXG4gICAgICAgICAgICBvcGVuTGlicmFyeU1lbnU6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IHQoXCJlcnJvcnMuaW1wb3J0TGlicmFyeUVycm9yXCIpIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IGZhbHNlLCBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAoXG4gICAgICAoZXZlbnQubmF0aXZlRXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIiB8fFxuICAgICAgICAoZXZlbnQubmF0aXZlRXZlbnQucG9pbnRlclR5cGUgPT09IFwicGVuXCIgJiZcbiAgICAgICAgICAvLyBhbHdheXMgYWxsb3cgaWYgdXNlciB1c2VzIGEgcGVuIHNlY29uZGFyeSBidXR0b25cbiAgICAgICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLlNFQ09OREFSWSkpICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIlxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBwcmVmZXJTZWxlY3RlZDogdHJ1ZSxcbiAgICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50czogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBpc0hpdHRpZ25Db21tb25Cb3VuZEJveCA9XG4gICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB7IHgsIHkgfSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICk7XG5cbiAgICBjb25zdCB0eXBlID0gZWxlbWVudCB8fCBpc0hpdHRpZ25Db21tb25Cb3VuZEJveCA/IFwiZWxlbWVudFwiIDogXCJjYW52YXNcIjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ITtcbiAgICBjb25zdCB7IHRvcDogb2Zmc2V0VG9wLCBsZWZ0OiBvZmZzZXRMZWZ0IH0gPVxuICAgICAgY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGxlZnQgPSBldmVudC5jbGllbnRYIC0gb2Zmc2V0TGVmdDtcbiAgICBjb25zdCB0b3AgPSBldmVudC5jbGllbnRZIC0gb2Zmc2V0VG9wO1xuXG4gICAgdHJhY2tFdmVudChcImNvbnRleHRNZW51XCIsIFwib3BlbkNvbnRleHRNZW51XCIsIHR5cGUpO1xuXG4gICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgIHtcbiAgICAgICAgLi4uKGVsZW1lbnQgJiYgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2VsZW1lbnQuaWRdXG4gICAgICAgICAgPyBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2VsZW1lbnQuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBpc0xpbmVhckVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoZWxlbWVudCwgdGhpcy5zY2VuZSlcbiAgICAgICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IHRoaXMuc3RhdGUpLFxuICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgY29udGV4dE1lbnU6IHsgdG9wLCBsZWZ0LCBpdGVtczogdGhpcy5nZXRDb250ZXh0TWVudUl0ZW1zKHR5cGUpIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICApO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQsXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGRyYWdnaW5nRWxlbWVudCA9IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50O1xuICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHM7XG4gICAgaWYgKCFkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgZHJhZ2dpbmdFbGVtZW50LnR5cGUgPT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcImVyYXNlclwiXG4gICAgKSB7XG4gICAgICBkcmFnTmV3RWxlbWVudChcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsIHBvaW50ZXJDb29yZHMueCksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksIHBvaW50ZXJDb29yZHMueSksXG4gICAgICAgIHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGltYWdlID1cbiAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpICYmXG4gICAgICAgIHRoaXMuaW1hZ2VDYWNoZS5nZXQoZHJhZ2dpbmdFbGVtZW50LmZpbGVJZCk/LmltYWdlO1xuICAgICAgY29uc3QgYXNwZWN0UmF0aW8gPVxuICAgICAgICBpbWFnZSAmJiAhKGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSlcbiAgICAgICAgICA/IGltYWdlLndpZHRoIC8gaW1hZ2UuaGVpZ2h0XG4gICAgICAgICAgOiBudWxsO1xuXG4gICAgICBkcmFnTmV3RWxlbWVudChcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueSxcbiAgICAgICAgZ3JpZFgsXG4gICAgICAgIGdyaWRZLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC54LCBncmlkWCksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksIGdyaWRZKSxcbiAgICAgICAgaXNJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICAgIGFzcGVjdFJhdGlvLFxuICAgICAgKTtcblxuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKFtkcmFnZ2luZ0VsZW1lbnRdKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZUhhbmRsZVJlc2l6ZSA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IHRyYW5zZm9ybUhhbmRsZVR5cGUgPSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLy8gVE9ETzogcmVuYW1lIHRoaXMgc3RhdGUgZmllbGQgdG8gXCJpc1NjYWxpbmdcIiB0byBkaXN0aW5ndWlzaFxuICAgICAgLy8gaXQgZnJvbSB0aGUgZ2VuZXJpYyBcImlzUmVzaXppbmdcIiB3aGljaCBpbmNsdWRlcyBzY2FsaW5nIGFuZFxuICAgICAgLy8gcm90YXRpbmdcbiAgICAgIGlzUmVzaXppbmc6IHRyYW5zZm9ybUhhbmRsZVR5cGUgJiYgdHJhbnNmb3JtSGFuZGxlVHlwZSAhPT0gXCJyb3RhdGlvblwiLFxuICAgICAgaXNSb3RhdGluZzogdHJhbnNmb3JtSGFuZGxlVHlwZSA9PT0gXCJyb3RhdGlvblwiLFxuICAgIH0pO1xuICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHM7XG4gICAgY29uc3QgW3Jlc2l6ZVgsIHJlc2l6ZVldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0LngsXG4gICAgICBwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQueSxcbiAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICB0cmFuc2Zvcm1FbGVtZW50cyhcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuYXJyb3dEaXJlY3Rpb24sXG4gICAgICAgIHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmIGlzSW1hZ2VFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICAgPyAhc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudClcbiAgICAgICAgICA6IHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICByZXNpemVYLFxuICAgICAgICByZXNpemVZLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5jZW50ZXIueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuY2VudGVyLnksXG4gICAgICApXG4gICAgKSB7XG4gICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgZ2V0Q29udGV4dE1lbnVJdGVtcyA9IChcbiAgICB0eXBlOiBcImNhbnZhc1wiIHwgXCJlbGVtZW50XCIsXG4gICk6IENvbnRleHRNZW51SXRlbXMgPT4ge1xuICAgIGNvbnN0IG9wdGlvbnM6IENvbnRleHRNZW51SXRlbXMgPSBbXTtcblxuICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNQbmcsIGFjdGlvbkNvcHlBc1N2Zyk7XG5cbiAgICAvLyBjYW52YXMgY29udGV4dE1lbnVcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICBpZiAodHlwZSA9PT0gXCJjYW52YXNcIikge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICAgICAgICAgIGFjdGlvblRvZ2dsZVZpZXdNb2RlLFxuICAgICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgICBdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW1xuICAgICAgICBhY3Rpb25QYXN0ZSxcbiAgICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgICAgYWN0aW9uQ29weUFzUG5nLFxuICAgICAgICBhY3Rpb25Db3B5QXNTdmcsXG4gICAgICAgIGNvcHlUZXh0LFxuICAgICAgICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxuICAgICAgICBhY3Rpb25TZWxlY3RBbGwsXG4gICAgICAgIGFjdGlvblVubG9ja0FsbEVsZW1lbnRzLFxuICAgICAgICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxuICAgICAgICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgICAgICAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgYWN0aW9uVG9nZ2xlVmlld01vZGUsXG4gICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgXTtcbiAgICB9XG5cbiAgICAvLyBlbGVtZW50IGNvbnRleHRNZW51XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgb3B0aW9ucy5wdXNoKGNvcHlUZXh0KTtcblxuICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIFthY3Rpb25Db3B5LCAuLi5vcHRpb25zXTtcbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgYWN0aW9uQ3V0LFxuICAgICAgYWN0aW9uQ29weSxcbiAgICAgIGFjdGlvblBhc3RlLFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxuICAgICAgYWN0aW9uQ29weVN0eWxlcyxcbiAgICAgIGFjdGlvblBhc3RlU3R5bGVzLFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvbkdyb3VwLFxuICAgICAgYWN0aW9uVW5iaW5kVGV4dCxcbiAgICAgIGFjdGlvbkJpbmRUZXh0LFxuICAgICAgYWN0aW9uV3JhcFRleHRJbkNvbnRhaW5lcixcbiAgICAgIGFjdGlvblVuZ3JvdXAsXG4gICAgICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxuICAgICAgYWN0aW9uQWRkVG9MaWJyYXJ5LFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgICAgIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgICAgIGFjdGlvblNlbmRUb0JhY2ssXG4gICAgICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gICAgICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxuICAgICAgYWN0aW9uRmxpcEhvcml6b250YWwsXG4gICAgICBhY3Rpb25GbGlwVmVydGljYWwsXG4gICAgICBDT05URVhUX01FTlVfU0VQQVJBVE9SLFxuICAgICAgYWN0aW9uVG9nZ2xlTGluZWFyRWRpdG9yLFxuICAgICAgYWN0aW9uTGluayxcbiAgICAgIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgICAgIGFjdGlvblRvZ2dsZUVsZW1lbnRMb2NrLFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICAgIF07XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVXaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmIChpc1Bhbm5pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGRlbHRhWCwgZGVsdGFZIH0gPSBldmVudDtcbiAgICAvLyBub3RlIHRoYXQgZXZlbnQuY3RybEtleSBpcyBuZWNlc3NhcnkgdG8gaGFuZGxlIHBpbmNoIHpvb21pbmdcbiAgICBpZiAoZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5KSB7XG4gICAgICBjb25zdCBzaWduID0gTWF0aC5zaWduKGRlbHRhWSk7XG4gICAgICBjb25zdCBNQVhfU1RFUCA9IFpPT01fU1RFUCAqIDEwMDtcbiAgICAgIGNvbnN0IGFic0RlbHRhID0gTWF0aC5hYnMoZGVsdGFZKTtcbiAgICAgIGxldCBkZWx0YSA9IGRlbHRhWTtcbiAgICAgIGlmIChhYnNEZWx0YSA+IE1BWF9TVEVQKSB7XG4gICAgICAgIGRlbHRhID0gTUFYX1NURVAgKiBzaWduO1xuICAgICAgfVxuXG4gICAgICBsZXQgbmV3Wm9vbSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZSAtIGRlbHRhIC8gMTAwO1xuICAgICAgLy8gaW5jcmVhc2Ugem9vbSBzdGVwcyB0aGUgbW9yZSB6b29tZWQtaW4gd2UgYXJlIChhcHBsaWVzIHRvID4xMDAlIG9ubHkpXG4gICAgICBuZXdab29tICs9XG4gICAgICAgIE1hdGgubG9nMTAoTWF0aC5tYXgoMSwgdGhpcy5zdGF0ZS56b29tLnZhbHVlKSkgKlxuICAgICAgICAtc2lnbiAqXG4gICAgICAgIC8vIHJlZHVjZWQgYW1wbGlmaWNhdGlvbiBmb3Igc21hbGwgZGVsdGFzIChzbWFsbCBtb3ZlbWVudHMgb24gYSB0cmFja3BhZClcbiAgICAgICAgTWF0aC5taW4oMSwgYWJzRGVsdGEgLyAyMCk7XG5cbiAgICAgIHRoaXMudHJhbnNsYXRlQ2FudmFzKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgLi4uZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY3Vyc29yWCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY3Vyc29yWSxcbiAgICAgICAgICAgIG5leHRab29tOiBnZXROb3JtYWxpemVkWm9vbShuZXdab29tKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc2Nyb2xsIGhvcml6b250YWxseSB3aGVuIHNoaWZ0IHByZXNzZWRcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIHRoaXMudHJhbnNsYXRlQ2FudmFzKCh7IHpvb20sIHNjcm9sbFggfSkgPT4gKHtcbiAgICAgICAgLy8gb24gTWFjLCBzaGlmdCt3aGVlbCB0ZW5kcyB0byByZXN1bHQgaW4gZGVsdGFYXG4gICAgICAgIHNjcm9sbFg6IHNjcm9sbFggLSAoZGVsdGFZIHx8IGRlbHRhWCkgLyB6b29tLnZhbHVlLFxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudHJhbnNsYXRlQ2FudmFzKCh7IHpvb20sIHNjcm9sbFgsIHNjcm9sbFkgfSkgPT4gKHtcbiAgICAgIHNjcm9sbFg6IHNjcm9sbFggLSBkZWx0YVggLyB6b29tLnZhbHVlLFxuICAgICAgc2Nyb2xsWTogc2Nyb2xsWSAtIGRlbHRhWSAvIHpvb20udmFsdWUsXG4gICAgfSkpO1xuICB9KTtcblxuICBwcml2YXRlIGdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICAgY29udGFpbmVyPzogRXhjYWxpZHJhd1RleHRDb250YWluZXIgfCBudWxsLFxuICApIHtcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBsZXQgZWxlbWVudENlbnRlclggPSBjb250YWluZXIueCArIGNvbnRhaW5lci53aWR0aCAvIDI7XG4gICAgICBsZXQgZWxlbWVudENlbnRlclkgPSBjb250YWluZXIueSArIGNvbnRhaW5lci5oZWlnaHQgLyAyO1xuXG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyID0gZ2V0Q29udGFpbmVyQ2VudGVyKGNvbnRhaW5lciwgYXBwU3RhdGUpO1xuICAgICAgaWYgKGVsZW1lbnRDZW50ZXIpIHtcbiAgICAgICAgZWxlbWVudENlbnRlclggPSBlbGVtZW50Q2VudGVyLng7XG4gICAgICAgIGVsZW1lbnRDZW50ZXJZID0gZWxlbWVudENlbnRlci55O1xuICAgICAgfVxuICAgICAgY29uc3QgZGlzdGFuY2VUb0NlbnRlciA9IE1hdGguaHlwb3QoXG4gICAgICAgIHggLSBlbGVtZW50Q2VudGVyWCxcbiAgICAgICAgeSAtIGVsZW1lbnRDZW50ZXJZLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzU25hcHBlZFRvQ2VudGVyID1cbiAgICAgICAgZGlzdGFuY2VUb0NlbnRlciA8IFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xEO1xuICAgICAgaWYgKGlzU25hcHBlZFRvQ2VudGVyKSB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7IHNjZW5lWDogZWxlbWVudENlbnRlclgsIHNjZW5lWTogZWxlbWVudENlbnRlclkgfSxcbiAgICAgICAgICBhcHBTdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgdmlld3BvcnRYLCB2aWV3cG9ydFksIGVsZW1lbnRDZW50ZXJYLCBlbGVtZW50Q2VudGVyWSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2F2ZVBvaW50ZXIgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIGJ1dHRvbjogXCJ1cFwiIHwgXCJkb3duXCIpID0+IHtcbiAgICBpZiAoIXggfHwgIXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKGlzTmFOKHBvaW50ZXIueCkgfHwgaXNOYU4ocG9pbnRlci55KSkge1xuICAgICAgLy8gc29tZXRpbWVzIHRoZSBwb2ludGVyIGdvZXMgb2ZmIHNjcmVlblxuICAgIH1cblxuICAgIHRoaXMucHJvcHMub25Qb2ludGVyVXBkYXRlPy4oe1xuICAgICAgcG9pbnRlcixcbiAgICAgIGJ1dHRvbixcbiAgICAgIHBvaW50ZXJzTWFwOiBnZXN0dXJlLnBvaW50ZXJzLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQgPSBkZWJvdW5jZSgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLnVubW91bnRlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3VsZENhY2hlSWdub3JlWm9vbTogZmFsc2UgfSk7XG4gICAgfVxuICB9LCAzMDApO1xuXG4gIHByaXZhdGUgdXBkYXRlRE9NUmVjdCA9IChjYj86ICgpID0+IHZvaWQpID0+IHtcbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICBjb25zdCBleGNhbGlkcmF3Q29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IG9mZnNldExlZnQsXG4gICAgICAgIHRvcDogb2Zmc2V0VG9wLFxuICAgICAgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoOiBjdXJyZW50V2lkdGgsXG4gICAgICAgIGhlaWdodDogY3VycmVudEhlaWdodCxcbiAgICAgICAgb2Zmc2V0VG9wOiBjdXJyZW50T2Zmc2V0VG9wLFxuICAgICAgICBvZmZzZXRMZWZ0OiBjdXJyZW50T2Zmc2V0TGVmdCxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHdpZHRoID09PSBjdXJyZW50V2lkdGggJiZcbiAgICAgICAgaGVpZ2h0ID09PSBjdXJyZW50SGVpZ2h0ICYmXG4gICAgICAgIG9mZnNldExlZnQgPT09IGN1cnJlbnRPZmZzZXRMZWZ0ICYmXG4gICAgICAgIG9mZnNldFRvcCA9PT0gY3VycmVudE9mZnNldFRvcFxuICAgICAgKSB7XG4gICAgICAgIGlmIChjYikge1xuICAgICAgICAgIGNiKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIG9mZnNldExlZnQsXG4gICAgICAgICAgb2Zmc2V0VG9wLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY2IgJiYgY2IoKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyByZWZyZXNoID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSB9KTtcbiAgfTtcblxuICBwcml2YXRlIGdldENhbnZhc09mZnNldHMoKTogUGljazxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXRMZWZ0OiBsZWZ0LFxuICAgICAgICBvZmZzZXRUb3A6IHRvcCxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRMZWZ0OiAwLFxuICAgICAgb2Zmc2V0VG9wOiAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUxhbmd1YWdlKCkge1xuICAgIGNvbnN0IGN1cnJlbnRMYW5nID1cbiAgICAgIGxhbmd1YWdlcy5maW5kKChsYW5nKSA9PiBsYW5nLmNvZGUgPT09IHRoaXMucHJvcHMubGFuZ0NvZGUpIHx8XG4gICAgICBkZWZhdWx0TGFuZztcbiAgICBhd2FpdCBzZXRMYW5ndWFnZShjdXJyZW50TGFuZyk7XG4gICAgdGhpcy5zZXRBcHBTdGF0ZSh7fSk7XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRFU1QgSE9PS1Ncbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgaDoge1xuICAgICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgICBzdGF0ZTogQXBwU3RhdGU7XG4gICAgICBzZXRTdGF0ZTogUmVhY3QuQ29tcG9uZW50PGFueSwgQXBwU3RhdGU+W1wic2V0U3RhdGVcIl07XG4gICAgICBhcHA6IEluc3RhbmNlVHlwZTx0eXBlb2YgQXBwPjtcbiAgICAgIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gICAgfTtcbiAgfVxufVxuXG5pZiAoXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4pIHtcbiAgd2luZG93LmggPSB3aW5kb3cuaCB8fCAoe30gYXMgV2luZG93W1wiaFwiXSk7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICBlbGVtZW50czoge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHA/LnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpO1xuICAgICAgfSxcbiAgICAgIHNldChlbGVtZW50czogRXhjYWxpZHJhd0VsZW1lbnRbXSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHA/LnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBBcHA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
2716
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ExcalidrawContainerContext\": () => (/* binding */ ExcalidrawContainerContext),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"useApp\": () => (/* binding */ useApp),\n/* harmony export */ \"useAppProps\": () => (/* binding */ useAppProps),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawActionManager\": () => (/* binding */ useExcalidrawActionManager),\n/* harmony export */ \"useExcalidrawAppState\": () => (/* binding */ useExcalidrawAppState),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"useExcalidrawElements\": () => (/* binding */ useExcalidrawElements),\n/* harmony export */ \"useExcalidrawSetAppState\": () => (/* binding */ useExcalidrawSetAppState)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.browser.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_library__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../data/library */ \"../../data/library.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_newElement__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../element/newElement */ \"../../element/newElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _gesture__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../gesture */ \"../../gesture.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _history__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../history */ \"../../history.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../renderer/renderElement */ \"../../renderer/renderElement.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _scene_zoom__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../scene/zoom */ \"../../scene/zoom.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ContextMenu */ \"../../components/ContextMenu.tsx\");\n/* harmony import */ var _LayerUI__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LayerUI */ \"../../components/LayerUI.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_41__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\n/* harmony import */ var _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! ../actions/actionElementLock */ \"../../actions/actionElementLock.ts\");\n/* harmony import */ var _scene_Fonts__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! ../scene/Fonts */ \"../../scene/Fonts.ts\");\n/* harmony import */ var _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! ../actions/actionClipboard */ \"../../actions/actionClipboard.tsx\");\n/* harmony import */ var _actions_actionCanvas__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! ../actions/actionCanvas */ \"../../actions/actionCanvas.tsx\");\n/* harmony import */ var _jotai__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! ../jotai */ \"../../jotai.ts\");\n/* harmony import */ var _ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! ./ActiveConfirmDialog */ \"../../components/ActiveConfirmDialog.tsx\");\n/* harmony import */ var _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(/*! ../actions/actionBoundText */ \"../../actions/actionBoundText.tsx\");\n/* harmony import */ var _BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(/*! ./BraveMeasureTextError */ \"../../components/BraveMeasureTextError.tsx\");\n/* harmony import */ var _emitter__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(/*! ../emitter */ \"../../emitter.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst AppContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nconst AppPropsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n isLandscape: false,\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nDeviceContext.displayName = \"DeviceContext\";\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\nExcalidrawContainerContext.displayName = \"ExcalidrawContainerContext\";\nconst ExcalidrawElementsContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext([]);\nExcalidrawElementsContext.displayName = \"ExcalidrawElementsContext\";\nconst ExcalidrawAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 }));\nExcalidrawAppStateContext.displayName = \"ExcalidrawAppStateContext\";\nconst ExcalidrawSetAppStateContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(() => {\n console.warn(\"unitialized ExcalidrawSetAppStateContext context!\");\n});\nExcalidrawSetAppStateContext.displayName = \"ExcalidrawSetAppStateContext\";\nconst ExcalidrawActionManagerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(null);\nExcalidrawActionManagerContext.displayName = \"ExcalidrawActionManagerContext\";\nconst useApp = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppContext);\nconst useAppProps = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(AppPropsContext);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\nconst useExcalidrawElements = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawElementsContext);\nconst useExcalidrawAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawAppStateContext);\nconst useExcalidrawSetAppState = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawSetAppStateContext);\nconst useExcalidrawActionManager = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawActionManagerContext);\nlet didTapTwice = false;\nlet tappedTwiceTimer = 0;\nlet cursorX = 0;\nlet cursorY = 0;\nlet isHoldingSpace = false;\nlet isPanning = false;\nlet isDraggingScrollBar = false;\nlet currentScrollBars = { horizontal: null, vertical: null };\nlet touchTimeout = 0;\nlet invalidateContextMenu = false;\n// remove this hack when we can sync render & resizeObserver (state update)\n// to rAF. See #5439\nlet THROTTLE_NEXT_RENDER = true;\nlet IS_PLAIN_PASTE = false;\nlet IS_PLAIN_PASTE_TIMER = 0;\nlet PLAIN_PASTE_TOAST_SHOWN = false;\nlet lastPointerUp = null;\nconst gesture = {\n pointers: new Map(),\n lastCenter: null,\n initialDistance: null,\n initialScale: null,\n};\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\n constructor(props) {\n var _a;\n super(props);\n this.canvas = null;\n this.rc = null;\n this.unmounted = false;\n this.device = deviceContextInitialValue;\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\n this.files = {};\n this.imageCache = new Map();\n this.lastPointerDown = null;\n this.lastPointerUp = null;\n this.lastScenePointer = null;\n this.onChangeEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_55__.Emitter();\n this.onPointerDownEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_55__.Emitter();\n this.onPointerUpEmitter = new _emitter__WEBPACK_IMPORTED_MODULE_55__.Emitter();\n this.focusContainer = () => {\n var _a;\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n };\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n this.onInsertElements = (elements) => {\n this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null,\n });\n };\n this.onExportImage = (type, elements) => __awaiter(this, void 0, void 0, function* () {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"export\", type, \"ui\");\n const fileHandle = yield (0,_data__WEBPACK_IMPORTED_MODULE_13__.exportAsImage)(type, elements, this.state, this.files, {\n exportBackground: this.state.exportBackground,\n name: this.state.name,\n viewBackgroundColor: this.state.viewBackgroundColor,\n })\n .catch(_utils__WEBPACK_IMPORTED_MODULE_34__.muteFSAbortError)\n .catch((error) => {\n console.error(error);\n this.setState({ errorMessage: error.message });\n });\n if (this.state.exportEmbedScene &&\n fileHandle &&\n (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isImageFileHandle)(fileHandle)) {\n this.setState({ fileHandle });\n }\n });\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n if (this.unmounted || actionResult === false) {\n return;\n }\n let editingElement = null;\n if (actionResult.elements) {\n actionResult.elements.forEach((element) => {\n var _a;\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\n this.state.editingElement !== element &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n editingElement = element;\n }\n });\n this.scene.replaceAllElements(actionResult.elements);\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n }\n if (actionResult.files) {\n this.files = actionResult.replaceFiles\n ? actionResult.files\n : Object.assign(Object.assign({}, this.files), actionResult.files);\n this.addNewImagesToImageCache();\n }\n if (actionResult.appState || editingElement || this.state.contextMenu) {\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\n const theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.theme) || this.props.theme || _constants__WEBPACK_IMPORTED_MODULE_12__.THEME.LIGHT;\n let name = (_f = (_e = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : this.state.name;\n const errorMessage = (_h = (_g = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _g === void 0 ? void 0 : _g.errorMessage) !== null && _h !== void 0 ? _h : this.state.errorMessage;\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\n viewModeEnabled = this.props.viewModeEnabled;\n }\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\n zenModeEnabled = this.props.zenModeEnabled;\n }\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null;\n }\n if (typeof this.props.name !== \"undefined\") {\n name = this.props.name;\n }\n this.setState((state) => {\n var _a;\n // using Object.assign instead of spread to fool TS 4.2.2+ into\n // regarding the resulting type as not containing undefined\n // (which the following expression will never contain)\n return Object.assign(actionResult.appState || {}, {\n // NOTE this will prevent opening context menu using an action\n // or programmatically from the host, so it will need to be\n // rewritten later\n contextMenu: null,\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\n viewModeEnabled,\n zenModeEnabled,\n gridSize,\n theme,\n name,\n errorMessage,\n });\n }, () => {\n if (actionResult.syncHistory) {\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\n }\n });\n }\n });\n // Lifecycle\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isHoldingSpace = false;\n this.setState({ isBindingEnabled: true });\n });\n this.onUnload = () => {\n this.onBlur();\n };\n this.disableEvent = (event) => {\n event.preventDefault();\n };\n this.resetHistory = () => {\n this.history.clear();\n };\n /**\n * Resets scene & history.\n * ! Do not use to clear scene user action !\n */\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\n this.scene.replaceAllElements([]);\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\n this.resetHistory();\n });\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\n var _b;\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\n if (!launchParams.files.length) {\n return;\n }\n const fileHandle = launchParams.files[0];\n const blob = yield fileHandle.getFile();\n this.loadFileToCanvas(new File([blob], blob.name || \"\", { type: blob.type }), fileHandle);\n }));\n }\n if (this.props.theme) {\n this.setState({ theme: this.props.theme });\n }\n if (!this.state.isLoading) {\n this.setState({ isLoading: true });\n }\n let initialData = null;\n try {\n initialData = (yield this.props.initialData) || null;\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\n this.library\n .updateLibrary({\n libraryItems: initialData.libraryItems,\n merge: true,\n })\n .catch((error) => {\n console.error(error);\n });\n }\n }\n catch (error) {\n console.error(error);\n initialData = {\n appState: {\n errorMessage: error.message ||\n \"Encountered an error during importing or restoring scene data\",\n },\n };\n }\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null, { repairBindings: true });\n scene.appState = Object.assign(Object.assign({}, scene.appState), { theme: this.props.theme || scene.appState.theme, \n // we're falling back to current (pre-init) state when deciding\n // whether to open the library, to handle a case where we\n // update the state outside of initialData (e.g. when loading the app\n // with a library install link, which should auto-open the library)\n openSidebar: ((_b = scene.appState) === null || _b === void 0 ? void 0 : _b.openSidebar) || this.state.openSidebar, activeTool: scene.appState.activeTool.type === \"image\"\n ? Object.assign(Object.assign({}, scene.appState.activeTool), { type: \"selection\" }) : scene.appState.activeTool, isLoading: false, toast: this.state.toast });\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\n scene.appState = Object.assign(Object.assign({}, scene.appState), (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(scene.elements, Object.assign(Object.assign({}, scene.appState), { width: this.state.width, height: this.state.height, offsetTop: this.state.offsetTop, offsetLeft: this.state.offsetLeft }), null));\n }\n // FontFaceSet loadingdone event we listen on may not always fire\n // (looking at you Safari), so on init we manually load fonts for current\n // text elements on canvas, and rerender them once done. This also\n // seems faster even in browsers that do fire the loadingdone event.\n this.fonts.loadFontsForElements(scene.elements);\n if ((initialData === null || initialData === void 0 ? void 0 : initialData.scrollX) != null) {\n scene.appState.scrollX = initialData.scrollX;\n }\n if ((initialData === null || initialData === void 0 ? void 0 : initialData.scrollY) != null) {\n scene.appState.scrollY = initialData.scrollY;\n }\n this.resetHistory();\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\n });\n this.refreshDeviceState = (container) => {\n const { width, height } = container.getBoundingClientRect();\n const sidebarBreakpoint = this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH;\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isLandscape: width > height,\n isSmScreen: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH,\n isMobile: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT ||\n (height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE),\n canDeviceFitSidebar: width > sidebarBreakpoint,\n });\n };\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n this.scene\n .getElementsIncludingDeleted()\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\n this.setState({});\n });\n this.onFontsLoadingDone = (event) => {\n const loadedFontFaces = event.fontfaces;\n this.fonts.onFontsLoaded(loadedFontFaces);\n };\n this.renderScene = () => {\n const cursorButton = {};\n const pointerViewportCoords = {};\n const remoteSelectedElementIds = {};\n const pointerUsernames = {};\n const pointerUserStates = {};\n this.state.collaborators.forEach((user, socketId) => {\n if (user.selectedElementIds) {\n for (const id of Object.keys(user.selectedElementIds)) {\n if (!(id in remoteSelectedElementIds)) {\n remoteSelectedElementIds[id] = [];\n }\n remoteSelectedElementIds[id].push(socketId);\n }\n }\n if (!user.pointer) {\n return;\n }\n if (user.username) {\n pointerUsernames[socketId] = user.username;\n }\n if (user.userState) {\n pointerUserStates[socketId] = user.userState;\n }\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: user.pointer.x,\n sceneY: user.pointer.y,\n }, this.state);\n cursorButton[socketId] = user.button;\n });\n const renderingElements = this.scene\n .getNonDeletedElements()\n .filter((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\n if (\n // not placed on canvas yet (but in elements array)\n this.state.pendingImageElementId === element.id) {\n return false;\n }\n }\n // don't render text element that's being currently edited (it's\n // rendered on remote only)\n return (!this.state.editingElement ||\n this.state.editingElement.type !== \"text\" ||\n element.id !== this.state.editingElement.id);\n });\n const selectionColor = getComputedStyle(document.querySelector(\".excalidraw\")).getPropertyValue(\"--color-selection\");\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__.renderScene)({\n elements: renderingElements,\n appState: this.state,\n rc: this.rc,\n canvas: this.canvas,\n renderConfig: {\n canvasScale: window.devicePixelRatio,\n selectionColor,\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n canvasBackgroundColor: this.state.viewBackgroundColor,\n zoom: this.state.zoom,\n remotePointerViewportCoords: pointerViewportCoords,\n remotePointerButton: cursorButton,\n remoteSelectedElementIds,\n remotePointerUsernames: pointerUsernames,\n remotePointerUserStates: pointerUserStates,\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\n theme: this.state.theme,\n imageCache: this.imageCache,\n isExporting: false,\n renderScrollbars: !this.device.isMobile,\n },\n callback: ({ atLeastOneVisibleElement, scrollBars }) => {\n if (scrollBars) {\n currentScrollBars = scrollBars;\n }\n const scrolledOutside = \n // hide when editing text\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? false\n : !atLeastOneVisibleElement && renderingElements.length > 0;\n if (this.state.scrolledOutside !== scrolledOutside) {\n this.setState({ scrolledOutside });\n }\n this.scheduleImageRefresh();\n },\n }, THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true);\n if (!THROTTLE_NEXT_RENDER) {\n THROTTLE_NEXT_RENDER = true;\n }\n };\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\n this.setState((state) => {\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\n return null;\n }\n return { offsetTop, offsetLeft };\n });\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.SCROLL_TIMEOUT);\n // Copy/paste\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.cutAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.copyAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.cutAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, \"keyboard\");\n };\n this.copyAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, \"keyboard\");\n };\n this.onTapStart = (event) => {\n // fix for Apple Pencil Scribble\n // On Android, preventing the event would disable contextMenu on tap-hold\n if (!_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n if (!didTapTwice) {\n didTapTwice = true;\n clearTimeout(tappedTwiceTimer);\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_12__.TAP_TWICE_TIMEOUT);\n return;\n }\n // insert text only if we tapped twice with a single finger\n // event.touches.length === 1 will also prevent inserting text when user's zooming\n if (didTapTwice && event.touches.length === 1) {\n const [touch] = event.touches;\n // @ts-ignore\n this.handleCanvasDoubleClick({\n clientX: touch.clientX,\n clientY: touch.clientY,\n });\n didTapTwice = false;\n clearTimeout(tappedTwiceTimer);\n }\n if (_constants__WEBPACK_IMPORTED_MODULE_12__.isAndroid) {\n event.preventDefault();\n }\n if (event.touches.length === 2) {\n this.setState({\n selectedElementIds: {},\n });\n }\n };\n this.onTapEnd = (event) => {\n this.resetContextMenuTimer();\n if (event.touches.length > 0) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n else {\n gesture.pointers.clear();\n }\n };\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\n var _c, _d;\n const isPlainPaste = !!(IS_PLAIN_PASTE && event);\n // #686\n const target = document.activeElement;\n const isExcalidrawActive = (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);\n if (event && !isExcalidrawActive) {\n return;\n }\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\n if (event &&\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\n return;\n }\n // must be called in the same frame (thus before any awaits) as the paste\n // event else some browsers (FF...) will clear the clipboardData\n // (something something security)\n let file = (_d = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _d === void 0 ? void 0 : _d.files[0];\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_11__.parseClipboard)(event, isPlainPaste);\n if (!file && data.text && !isPlainPaste) {\n const string = data.text.trim();\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\n // ignore SVG validation/normalization which will be done during image\n // initialization\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(string);\n }\n }\n // prefer spreadsheet data over image file (MS Office/Libre Office)\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file) && !data.spreadsheet) {\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n if (this.props.onPaste) {\n try {\n if ((yield this.props.onPaste(data, event)) === false) {\n return;\n }\n }\n catch (error) {\n console.error(error);\n }\n }\n if (data.errorMessage) {\n this.setState({ errorMessage: data.errorMessage });\n }\n else if (data.spreadsheet && !isPlainPaste) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true,\n },\n });\n }\n else if (data.elements) {\n // TODO remove formatting from elements if isPlainPaste\n this.addElementsFromPasteOrLibrary({\n elements: data.elements,\n files: data.files || null,\n position: \"cursor\",\n retainSeed: isPlainPaste,\n });\n }\n else if (data.text) {\n this.addTextFromPaste(data.text, isPlainPaste);\n }\n this.setActiveTool({ type: \"selection\" });\n event === null || event === void 0 ? void 0 : event.preventDefault();\n }));\n this.addElementsFromPasteOrLibrary = (opts) => {\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\n const clientX = typeof opts.position === \"object\"\n ? opts.position.clientX\n : opts.position === \"cursor\"\n ? cursorX\n : this.state.width / 2 + this.state.offsetLeft;\n const clientY = typeof opts.position === \"object\"\n ? opts.position.clientY\n : opts.position === \"cursor\"\n ? cursorY\n : this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const dx = x - elementsCenterX;\n const dy = y - elementsCenterY;\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\n const newElements = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.duplicateElements)(elements.map((element) => {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY,\n });\n }), {\n randomizeSeed: !opts.retainSeed,\n });\n const nextElements = [\n ...this.scene.getElementsIncludingDeleted(),\n ...newElements,\n ];\n this.scene.replaceAllElements(nextElements);\n newElements.forEach((newElement) => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(newElement) && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(newElement)) {\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerElement)(newElement);\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.redrawTextBoundingBox)(newElement, container);\n }\n });\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n this.history.resumeRecording();\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { \n // keep sidebar (presumably the library) open if it's docked and\n // can fit.\n //\n // Note, we should close the sidebar only if we're dropping items\n // from library, not when pasting from clipboard. Alas.\n openSidebar: this.state.openSidebar &&\n this.device.canDeviceFitSidebar &&\n this.state.defaultSidebarDockedPreference\n ? this.state.openSidebar\n : null, selectedElementIds: newElements.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n return acc;\n }, {}), selectedGroupIds: {} }), this.scene.getNonDeletedElements()), () => {\n if (opts.files) {\n this.addNewImagesToImageCache();\n }\n });\n this.setActiveTool({ type: \"selection\" });\n };\n this.setAppState = (state, callback) => {\n this.setState(state, callback);\n };\n this.removePointer = (event) => {\n if (touchTimeout) {\n this.resetContextMenuTimer();\n }\n gesture.pointers.delete(event.pointerId);\n };\n this.toggleLock = (source = \"ui\") => {\n if (!this.state.activeTool.locked) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", \"toggleLock\", `${source} (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setState((prevState) => {\n return {\n activeTool: Object.assign(Object.assign(Object.assign({}, prevState.activeTool), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, prevState.activeTool.locked\n ? { type: \"selection\" }\n : prevState.activeTool)), { locked: !prevState.activeTool.locked }),\n };\n });\n };\n this.togglePenMode = () => {\n this.setState((prevState) => {\n return {\n penMode: !prevState.penMode,\n };\n });\n };\n this.onHandToolToggle = () => {\n this.actionManager.executeAction(_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_50__.actionToggleHandTool);\n };\n /**\n * Zooms on canvas viewport center\n */\n this.zoomCanvas = (\n /** decimal fraction between 0.1 (10% zoom) and 30 (3000% zoom) */\n value) => {\n this.setState(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: this.state.width / 2 + this.state.offsetLeft,\n viewportY: this.state.height / 2 + this.state.offsetTop,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(value),\n }, this.state)));\n };\n this.cancelInProgresAnimation = null;\n this.scrollToContent = (target = this.scene.getNonDeletedElements(), opts) => {\n var _a, _b;\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this);\n // convert provided target into ExcalidrawElement[] if necessary\n const targets = Array.isArray(target) ? target : [target];\n let zoom = this.state.zoom;\n let scrollX = this.state.scrollX;\n let scrollY = this.state.scrollY;\n if (opts === null || opts === void 0 ? void 0 : opts.fitToContent) {\n // compute an appropriate viewport location (scroll X, Y) and zoom level\n // that fit the target elements on the scene\n const { appState } = (0,_actions_actionCanvas__WEBPACK_IMPORTED_MODULE_50__.zoomToFitElements)(targets, this.state, false);\n zoom = appState.zoom;\n scrollX = appState.scrollX;\n scrollY = appState.scrollY;\n }\n else {\n // compute only the viewport location, without any zoom adjustment\n const scroll = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(targets, this.state, this.canvas);\n scrollX = scroll.scrollX;\n scrollY = scroll.scrollY;\n }\n // when animating, we use RequestAnimationFrame to prevent the animation\n // from slowing down other processes\n if (opts === null || opts === void 0 ? void 0 : opts.animate) {\n const origScrollX = this.state.scrollX;\n const origScrollY = this.state.scrollY;\n // zoom animation could become problematic on scenes with large number\n // of elements, setting it to its final value to improve user experience.\n //\n // using zoomCanvas() to zoom on current viewport center\n this.zoomCanvas(zoom.value);\n const cancel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.easeToValuesRAF)([origScrollX, origScrollY], [scrollX, scrollY], (scrollX, scrollY) => this.setState({ scrollX, scrollY }), { duration: (_b = opts === null || opts === void 0 ? void 0 : opts.duration) !== null && _b !== void 0 ? _b : 500 });\n this.cancelInProgresAnimation = () => {\n cancel();\n this.cancelInProgresAnimation = null;\n };\n }\n else {\n this.setState({ scrollX, scrollY, zoom });\n }\n };\n /** use when changing scrollX/scrollY/zoom based on user interaction */\n this.translateCanvas = (state) => {\n var _a;\n (_a = this.cancelInProgresAnimation) === null || _a === void 0 ? void 0 : _a.call(this);\n this.setState(state);\n };\n this.setToast = (toast) => {\n this.setState({ toast });\n };\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\n try {\n const webShareTargetCache = yield caches.open(\"web-share-target\");\n const response = yield webShareTargetCache.match(\"shared-file\");\n if (response) {\n const blob = yield response.blob();\n const file = new File([blob], blob.name || \"\", { type: blob.type });\n this.loadFileToCanvas(file, null);\n yield webShareTargetCache.delete(\"shared-file\");\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_12__.APP_NAME, window.location.pathname);\n }\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n });\n /** adds supplied files to existing files in the appState */\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\n const filesMap = files.reduce((acc, fileData) => {\n acc.set(fileData.id, fileData);\n return acc;\n }, new Map());\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\n this.scene.getNonDeletedElements().forEach((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n filesMap.has(element.fileId)) {\n this.imageCache.delete(element.fileId);\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.scene.informMutation();\n this.addNewImagesToImageCache();\n });\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\n if (sceneData.commitToHistory) {\n this.history.resumeRecording();\n }\n if (sceneData.appState) {\n this.setState(sceneData.appState);\n }\n if (sceneData.elements) {\n this.scene.replaceAllElements(sceneData.elements);\n }\n if (sceneData.collaborators) {\n this.setState({ collaborators: sceneData.collaborators });\n }\n });\n this.onSceneUpdated = () => {\n this.setState({});\n };\n /**\n * @returns whether the menu was toggled on or off\n */\n this.toggleSidebar = ({ name, tab, force, }) => {\n var _a;\n let nextName;\n if (force === undefined) {\n nextName = ((_a = this.state.openSidebar) === null || _a === void 0 ? void 0 : _a.name) === name ? null : name;\n }\n else {\n nextName = force ? name : null;\n }\n this.setState({ openSidebar: nextName ? { name: nextName, tab } : null });\n return !!nextName;\n };\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n cursorX = event.clientX;\n cursorY = event.clientY;\n });\n // Input handling\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // normalize `event.key` when CapsLock is pressed #2372\n if (\"Proxy\" in window &&\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\n event = new Proxy(event, {\n get(ev, prop) {\n const value = ev[prop];\n if (typeof value === \"function\") {\n // fix for Proxies hijacking `this`\n return value.bind(ev);\n }\n return prop === \"key\"\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\n // it back\n event.shiftKey\n ? ev.key.toUpperCase()\n : ev.key.toLowerCase()\n : value;\n },\n });\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.V) {\n IS_PLAIN_PASTE = event.shiftKey;\n clearTimeout(IS_PLAIN_PASTE_TIMER);\n // reset (100ms to be safe that we it runs after the ensuing\n // paste event). Though, technically unnecessary to reset since we\n // (re)set the flag before each paste event.\n IS_PLAIN_PASTE_TIMER = window.setTimeout(() => {\n IS_PLAIN_PASTE = false;\n }, 100);\n }\n // prevent browser zoom in input fields\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.MINUS || event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.EQUAL) {\n event.preventDefault();\n return;\n }\n }\n // bail if\n if (\n // inside an input\n ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) &&\n // unless pressing escape (finalize action)\n event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\n // or unless using arrows (to move between buttons)\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\n this.setState({\n openDialog: \"help\",\n });\n return;\n }\n else if (event.key.toLowerCase() === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.E &&\n event.shiftKey &&\n event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n this.setState({ openDialog: \"imageExport\" });\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_UP || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n let offset = (event.shiftKey ? this.state.width : this.state.height) /\n this.state.zoom.value;\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.PAGE_DOWN) {\n offset = -offset;\n }\n if (event.shiftKey) {\n this.translateCanvas((state) => ({\n scrollX: state.scrollX + offset,\n }));\n }\n else {\n this.translateCanvas((state) => ({\n scrollY: state.scrollY + offset,\n }));\n }\n }\n if (this.actionManager.handleKeyDown(event)) {\n return;\n }\n if (this.state.viewModeEnabled) {\n return;\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: false });\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const step = (this.state.gridSize &&\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT\n : this.state.gridSize)) ||\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\n : _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT);\n let offsetX = 0;\n let offsetY = 0;\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\n offsetX = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\n offsetX = step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\n offsetY = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\n offsetY = step;\n }\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state, true);\n selectedElements.forEach((element) => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: element.x + offsetX,\n y: element.y + offsetY,\n });\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\n simultaneouslyUpdated: selectedElements,\n });\n });\n this.maybeSuggestBindingForAll(selectedElements);\n event.preventDefault();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElement)) {\n if (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !==\n selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElement, this.scene),\n });\n }\n }\n }\n else if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement) ||\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isValidTextContainer)(selectedElement)) {\n let container;\n if (!(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElement)) {\n container = selectedElement;\n }\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(selectedElement, this.state);\n const sceneX = midPoint.x;\n const sceneY = midPoint.y;\n this.startTextEditing({\n sceneX,\n sceneY,\n container,\n });\n event.preventDefault();\n return;\n }\n }\n }\n else if (!event.ctrlKey &&\n !event.altKey &&\n !event.metaKey &&\n this.state.draggingElement === null) {\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\n if (shape) {\n if (this.state.activeTool.type !== shape) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", shape, `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setActiveTool({ type: shape });\n event.stopPropagation();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\n this.toggleLock(\"keyboard\");\n event.stopPropagation();\n }\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\n isHoldingSpace = true;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n event.preventDefault();\n }\n if ((event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) &&\n !event.altKey &&\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (this.state.activeTool.type === \"selection\" &&\n !selectedElements.length) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.activeTool.type) ||\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\n this.setState({ openPopup: \"elementBackground\" });\n event.stopPropagation();\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({ openPopup: \"elementStroke\" });\n event.stopPropagation();\n }\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\n (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.BACKSPACE || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.DELETE)) {\n _jotai__WEBPACK_IMPORTED_MODULE_51__.jotaiStore.set(_ActiveConfirmDialog__WEBPACK_IMPORTED_MODULE_52__.activeConfirmDialogAtom, \"clearCanvas\");\n }\n });\n this.onWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // prevent browser pinch zoom on DOM elements\n if (!(event.target instanceof HTMLCanvasElement) && event.ctrlKey) {\n event.preventDefault();\n }\n });\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (this.state.activeTool.type === \"selection\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n isHoldingSpace = false;\n }\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: true });\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\n this.setState({ suggestedBindings: [] });\n }\n });\n this.setActiveTool = (tool) => {\n const nextActiveTool = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, tool);\n if (nextActiveTool.type === \"hand\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (!isHoldingSpace) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\n this.focusContainer();\n }\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(nextActiveTool.type)) {\n this.setState({ suggestedBindings: [] });\n }\n if (nextActiveTool.type === \"image\") {\n this.onImageAction();\n }\n if (nextActiveTool.type !== \"selection\") {\n this.setState({\n activeTool: nextActiveTool,\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n else {\n this.setState({ activeTool: nextActiveTool });\n }\n };\n this.setCursor = (cursor) => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, cursor);\n };\n this.resetCursor = () => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n };\n /**\n * returns whether user is making a gesture with >= 2 fingers (points)\n * on o touch screen (not on a trackpad). Currently only relates to Darwin\n * (iOS/iPadOS,MacOS), but may work on other devices in the future if\n * GestureEvent is standardized.\n */\n this.isTouchScreenMultiTouchGesture = () => {\n // we don't want to deselect when using trackpad, and multi-point gestures\n // only work on touch screens, so checking for >= pointers means we're on a\n // touchscreen\n return gesture.pointers.size >= 2;\n };\n // fires only on Safari\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // we only want to deselect on touch screens because user may have selected\n // elements by mistake while zooming\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n selectedElementIds: {},\n });\n }\n gesture.initialScale = this.state.zoom.value;\n });\n // fires only on Safari\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // onGestureChange only has zoom factor but not the center.\n // If we're on iPad or iPhone, then we recognize multi-touch and will\n // zoom in at the right location in the touchmove handler\n // (handleCanvasPointerMove).\n //\n // On Macbook trackpad, we don't have those events so will zoom in at the\n // current location instead.\n //\n // As such, bail from this handler on touch devices.\n if (this.isTouchScreenMultiTouchGesture()) {\n return;\n }\n const initialScale = gesture.initialScale;\n if (initialScale) {\n this.setState((state) => (Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale),\n }, state))));\n }\n });\n // fires only on Safari\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // reselect elements only on touch screens (see onGestureStart)\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n gesture.initialScale = null;\n });\n this.startTextEditing = ({ sceneX, sceneY, insertAtParentCenter = true, container, }) => {\n var _a, _b;\n let shouldBindToContainer = false;\n let parentCenterPosition = insertAtParentCenter &&\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n if (container && parentCenterPosition) {\n shouldBindToContainer = true;\n }\n let existingTextElement = null;\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElements[0])) {\n existingTextElement = selectedElements[0];\n }\n else if (container) {\n existingTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(selectedElements[0]);\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n const fontFamily = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.fontFamily) || this.state.currentItemFontFamily;\n const lineHeight = (existingTextElement === null || existingTextElement === void 0 ? void 0 : existingTextElement.lineHeight) || (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(fontFamily);\n const fontSize = this.state.currentItemFontSize;\n if (!existingTextElement &&\n shouldBindToContainer &&\n container &&\n !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isArrowElement)(container)) {\n const fontString = {\n fontSize,\n fontFamily,\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString), lineHeight);\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)(fontSize, lineHeight);\n const containerDims = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerDims)(container);\n const newHeight = Math.max(containerDims.height, minHeight);\n const newWidth = Math.max(containerDims.width, minWidth);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\n sceneX = container.x + newWidth / 2;\n sceneY = container.y + newHeight / 2;\n if (parentCenterPosition) {\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, container);\n }\n }\n const element = existingTextElement\n ? existingTextElement\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x: parentCenterPosition\n ? parentCenterPosition.elementCenterX\n : sceneX,\n y: parentCenterPosition\n ? parentCenterPosition.elementCenterY\n : sceneY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text: \"\",\n fontSize,\n fontFamily,\n textAlign: parentCenterPosition\n ? \"center\"\n : this.state.currentItemTextAlign,\n verticalAlign: parentCenterPosition\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.VERTICAL_ALIGN.MIDDLE\n : _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n containerId: shouldBindToContainer ? container === null || container === void 0 ? void 0 : container.id : undefined,\n groupIds: (_a = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _a !== void 0 ? _a : [],\n lineHeight,\n angle: (_b = container === null || container === void 0 ? void 0 : container.angle) !== null && _b !== void 0 ? _b : 0,\n });\n if (!existingTextElement && shouldBindToContainer && container) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, {\n boundElements: (container.boundElements || []).concat({\n type: \"text\",\n id: element.id,\n }),\n });\n }\n this.setState({ editingElement: element });\n if (!existingTextElement) {\n if (container && shouldBindToContainer) {\n const containerIndex = this.scene.getElementIndex(container.id);\n this.scene.insertElementAtIndex(element, containerIndex + 1);\n }\n else {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n }\n }\n this.setState({\n editingElement: element,\n });\n this.handleTextWysiwyg(element, {\n isExistingElement: !!existingTextElement,\n });\n };\n this.handleCanvasDoubleClick = (event) => {\n // case: double-clicking with arrow/line tool selected would both create\n // text and enter multiElement mode\n if (this.state.multiElement) {\n return;\n }\n // we should only be able to double click when mode is selection\n if (this.state.activeTool.type !== \"selection\") {\n return;\n }\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\n (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !== selectedElements[0].id)) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\n });\n return;\n }\n else if (this.state.editingLinearElement &&\n this.state.editingLinearElement.elementId === selectedElements[0].id) {\n return;\n }\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\n if (selectedGroupIds.length > 0) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n const selectedGroupId = hitElement &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\n if (selectedGroupId) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { editingGroupId: selectedGroupId, selectedElementIds: { [hitElement.id]: true }, selectedGroupIds: {} }), this.scene.getNonDeletedElements()));\n return;\n }\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\n const container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n if (container) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(container) ||\n !(0,_utils__WEBPACK_IMPORTED_MODULE_34__.isTransparent)(container.backgroundColor) ||\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(container, this.state, [\n sceneX,\n sceneY,\n ])) {\n const midPoint = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, this.state);\n sceneX = midPoint.x;\n sceneY = midPoint.y;\n }\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container,\n });\n }\n };\n this.getElementLinkAtPosition = (scenePointer, hitElement) => {\n // Reversing so we traverse the elements in decreasing order\n // of z-index\n const elements = this.scene.getNonDeletedElements().slice().reverse();\n let hitElementIndex = Infinity;\n return elements.find((element, index) => {\n if (hitElement && element.id === hitElement.id) {\n hitElementIndex = index;\n }\n return (element.link &&\n index <= hitElementIndex &&\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(element, this.state, [scenePointer.x, scenePointer.y], this.device.isMobile));\n });\n };\n this.redirectToLink = (event, isTouchScreen) => {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (!this.hitLinkElement ||\n // For touch screen allow dragging threshold else strict check\n (isTouchScreen && draggedDistance > _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) ||\n (!isTouchScreen && draggedDistance !== 0)) {\n return;\n }\n const lastPointerDownCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerDown, this.state);\n const lastPointerDownHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerDownCoords.x, lastPointerDownCoords.y], this.device.isMobile);\n const lastPointerUpCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerUp, this.state);\n const lastPointerUpHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerUpCoords.x, lastPointerUpCoords.y], this.device.isMobile);\n if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {\n const url = this.hitLinkElement.link;\n if (url) {\n let customEvent;\n if (this.props.onLinkOpen) {\n customEvent = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.wrapEvent)(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.EXCALIDRAW_LINK, event.nativeEvent);\n this.props.onLinkOpen(this.hitLinkElement, customEvent);\n }\n if (!(customEvent === null || customEvent === void 0 ? void 0 : customEvent.defaultPrevented)) {\n const target = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isLocalLink)(url) ? \"_self\" : \"_blank\";\n const newWindow = window.open(undefined, target);\n // https://mathiasbynens.github.io/rel-noopener/\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.normalizeLink)(url);\n }\n }\n }\n }\n };\n this.handleCanvasPointerMove = (event) => {\n var _a;\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\n if (gesture.pointers.has(event.pointerId)) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n }\n const initialScale = gesture.initialScale;\n if (gesture.pointers.size === 2 &&\n gesture.lastCenter &&\n initialScale &&\n gesture.initialDistance) {\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n const deltaX = center.x - gesture.lastCenter.x;\n const deltaY = center.y - gesture.lastCenter.y;\n gesture.lastCenter = center;\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n const scaleFactor = this.state.activeTool.type === \"freedraw\" && this.state.penMode\n ? 1\n : distance / gesture.initialDistance;\n const nextZoom = scaleFactor\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor)\n : this.state.zoom.value;\n this.setState((state) => {\n const zoomState = (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: center.x,\n viewportY: center.y,\n nextZoom,\n }, state);\n this.translateCanvas({\n zoom: zoomState.zoom,\n scrollX: zoomState.scrollX + deltaX / nextZoom,\n scrollY: zoomState.scrollY + deltaY / nextZoom,\n shouldCacheIgnoreZoom: true,\n });\n });\n this.resetShouldCacheIgnoreZoomDebounced();\n }\n else {\n gesture.lastCenter =\n gesture.initialDistance =\n gesture.initialScale =\n null;\n }\n if (isHoldingSpace ||\n isPanning ||\n isDraggingScrollBar ||\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state)) {\n return;\n }\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\n if (!this.state.draggingElement && !this.state.multiElement) {\n if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state);\n if (editingLinearElement &&\n editingLinearElement !== this.state.editingLinearElement) {\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({\n editingLinearElement,\n });\n });\n }\n if ((editingLinearElement === null || editingLinearElement === void 0 ? void 0 : editingLinearElement.lastUncommittedPoint) != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n else {\n // causes stack overflow if not sync\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({ suggestedBindings: [] });\n });\n }\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.activeTool.type)) {\n // Hovering with a selected tool or creating new linear element via click\n // and point\n const { draggingElement } = this.state;\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\n }\n else {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n }\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n const { x: rx, y: ry } = multiElement;\n const { points, lastCommittedPoint } = multiElement;\n const lastPoint = points[points.length - 1];\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n if (lastPoint === lastCommittedPoint) {\n // if we haven't yet created a temp point and we're beyond commit-zone\n // threshold, add a point\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\n });\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n // in this branch, we're inside the commit zone, and no uncommitted\n // point exists. Thus do nothing (don't add/remove points).\n }\n }\n else if (points.length > 2 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: points.slice(0, -1),\n });\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(scenePointerX, scenePointerY, this.state.gridSize);\n const [lastCommittedX, lastCommittedY] = (_a = multiElement === null || multiElement === void 0 ? void 0 : multiElement.lastCommittedPoint) !== null && _a !== void 0 ? _a : [0, 0];\n let dxFromLastCommitted = gridX - rx - lastCommittedX;\n let dyFromLastCommitted = gridY - ry - lastCommittedY;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event)) {\n ({ width: dxFromLastCommitted, height: dyFromLastCommitted } =\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(\n // actual coordinate of the last committed point\n lastCommittedX + rx, lastCommittedY + ry, \n // cursor-grid coordinate\n gridX, gridY));\n }\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n // update last uncommitted point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [\n ...points.slice(0, -1),\n [\n lastCommittedX + dxFromLastCommitted,\n lastCommittedY + dyFromLastCommitted,\n ],\n ],\n });\n }\n return;\n }\n const hasDeselectedButton = Boolean(event.buttons);\n if (hasDeselectedButton ||\n (this.state.activeTool.type !== \"selection\" &&\n this.state.activeTool.type !== \"text\" &&\n this.state.activeTool.type !== \"eraser\")) {\n return;\n }\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 &&\n !isOverScrollBar &&\n !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType &&\n elementWithTransformHandleType.transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\n return;\n }\n }\n else if (selectedElements.length > 1 && !isOverScrollBar) {\n const transformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType,\n }));\n return;\n }\n }\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n return;\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.showHyperlinkTooltip)(this.hitLinkElement, this.state);\n }\n else {\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.hideHyperlinkToolip)();\n if (hitElement &&\n hitElement.link &&\n this.state.selectedElementIds[hitElement.id] &&\n !this.state.contextMenu &&\n !this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: \"info\" });\n }\n else if (this.state.activeTool.type === \"text\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n }\n else if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.selectedLinearElement) {\n this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);\n }\n else if (\n // if using cmd/ctrl, we're not dragging\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if ((hitElement ||\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements)) &&\n !(hitElement === null || hitElement === void 0 ? void 0 : hitElement.locked)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n };\n this.handleEraser = (event, pointerDownState, scenePointer) => {\n const updateElementIds = (elements) => {\n elements.forEach((element) => {\n if (element.locked) {\n return;\n }\n idsToUpdate.push(element.id);\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[element.id] &&\n pointerDownState.elementIdsToErase[element.id].erase) {\n pointerDownState.elementIdsToErase[element.id].erase = false;\n }\n }\n else if (!pointerDownState.elementIdsToErase[element.id]) {\n pointerDownState.elementIdsToErase[element.id] = {\n erase: true,\n opacity: element.opacity,\n };\n }\n });\n };\n const idsToUpdate = [];\n const distance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);\n const threshold = 10 / this.state.zoom.value;\n const point = Object.assign({}, pointerDownState.lastCoords);\n let samplingInterval = 0;\n while (samplingInterval <= distance) {\n const hitElements = this.getElementsAtPosition(point.x, point.y);\n updateElementIds(hitElements);\n // Exit since we reached current point\n if (samplingInterval === distance) {\n break;\n }\n // Calculate next point in the line at a distance of sampling interval\n samplingInterval = Math.min(samplingInterval + threshold, distance);\n const distanceRatio = samplingInterval / distance;\n const nextX = (1 - distanceRatio) * point.x + distanceRatio * scenePointer.x;\n const nextY = (1 - distanceRatio) * point.y + distanceRatio * scenePointer.y;\n point.x = nextX;\n point.y = nextY;\n }\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n const id = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && idsToUpdate.includes(ele.containerId)\n ? ele.containerId\n : ele.id;\n if (idsToUpdate.includes(id)) {\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[id] &&\n pointerDownState.elementIdsToErase[id].erase === false) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[id].opacity,\n });\n }\n }\n else {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_READY_TO_ERASE_OPACITY,\n });\n }\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n pointerDownState.lastCoords.x = scenePointer.x;\n pointerDownState.lastCoords.y = scenePointer.y;\n };\n // set touch moving for mobile context menu\n this.handleTouchMove = (event) => {\n invalidateContextMenu = true;\n };\n this.handleCanvasPointerDown = (event) => {\n var _a, _b;\n // since contextMenu options are potentially evaluated on each render,\n // and an contextMenu action may depend on selection state, we must\n // close the contextMenu before we update the selection on pointerDown\n // (e.g. resetting selection)\n if (this.state.contextMenu) {\n this.setState({ contextMenu: null });\n }\n this.updateGestureOnPointerDown(event);\n // if dragging element is freedraw and another pointerdown event occurs\n // a second finger is on the screen\n // discard the freedraw element if it is very short because it is likely\n // just a spike, otherwise finalize the freedraw element when the second\n // finger is lifted\n if (event.pointerType === \"touch\" &&\n this.state.draggingElement &&\n this.state.draggingElement.type === \"freedraw\") {\n const element = this.state.draggingElement;\n this.updateScene(Object.assign(Object.assign({}, (element.points.length < 10\n ? {\n elements: this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== element.id),\n }\n : {})), { appState: {\n draggingElement: null,\n editingElement: null,\n startBoundElement: null,\n suggestedBindings: [],\n selectedElementIds: Object.keys(this.state.selectedElementIds)\n .filter((key) => key !== element.id)\n .reduce((obj, key) => {\n obj[key] = this.state.selectedElementIds[key];\n return obj;\n }, {}),\n } }));\n return;\n }\n // remove any active selection when we start to interact with canvas\n // (mainly, we care about removing selection outside the component which\n // would prevent our copy handling otherwise)\n const selection = document.getSelection();\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\n selection.removeAllRanges();\n }\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\n this.maybeCleanupAfterMissingPointerUp(event);\n //fires only once, if pen is detected, penMode is enabled\n //the user can disable this by toggling the penMode button\n if (!this.state.penDetected && event.pointerType === \"pen\") {\n this.setState((prevState) => {\n return {\n penMode: true,\n penDetected: true,\n };\n });\n }\n if (!this.device.isTouchScreen &&\n [\"pen\", \"touch\"].includes(event.pointerType)) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, { isTouchScreen: true });\n }\n if (isPanning) {\n return;\n }\n this.lastPointerDown = event;\n this.setState({\n lastPointerDownWith: event.pointerType,\n cursorButton: \"down\",\n });\n this.savePointer(event.clientX, event.clientY, \"down\");\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n }\n // only handle left mouse button or touch\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN &&\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.TOUCH) {\n return;\n }\n // don't select while panning\n if (gesture.pointers.size > 1) {\n return;\n }\n // State for the duration of a pointer interaction, which starts with a\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\n const pointerDownState = this.initialPointerDownState(event);\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\n return;\n }\n this.clearSelectionIfNotUsingSelection();\n this.updateBindingEnabledOnPointerMove(event);\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\n return;\n }\n const allowOnPointerDown = !this.state.penMode ||\n event.pointerType !== \"touch\" ||\n this.state.activeTool.type === \"selection\" ||\n this.state.activeTool.type === \"text\" ||\n this.state.activeTool.type === \"image\";\n if (!allowOnPointerDown) {\n return;\n }\n if (this.state.activeTool.type === \"text\") {\n this.handleTextOnPointerDown(event, pointerDownState);\n return;\n }\n else if (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\") {\n this.handleLinearElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"image\") {\n // reset image preview on pointerdown\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n // retrieve the latest element as the state may be stale\n const pendingImageElement = this.state.pendingImageElementId &&\n this.scene.getElement(this.state.pendingImageElementId);\n if (!pendingImageElement) {\n return;\n }\n this.setState({\n draggingElement: pendingImageElement,\n editingElement: pendingImageElement,\n pendingImageElementId: null,\n multiElement: null,\n });\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(pendingImageElement, {\n x,\n y,\n });\n }\n else if (this.state.activeTool.type === \"freedraw\") {\n this.handleFreeDrawElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type !== \"eraser\" &&\n this.state.activeTool.type !== \"hand\" &&\n this.state.activeTool.type !== \"custom\") {\n this.createGenericElementOnPointerDown(this.state.activeTool.type, pointerDownState);\n }\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onPointerDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.activeTool, pointerDownState);\n this.onPointerDownEmitter.trigger(this.state.activeTool, pointerDownState, event);\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\n lastPointerUp = onPointerUp;\n if (!this.state.viewModeEnabled) {\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, onKeyDown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, onKeyUp);\n pointerDownState.eventListeners.onMove = onPointerMove;\n pointerDownState.eventListeners.onUp = onPointerUp;\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\n }\n };\n this.handleCanvasPointerUp = (event) => {\n this.lastPointerUp = event;\n if (this.device.isTouchScreen) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: event.clientX, clientY: event.clientY }, this.state);\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n this.redirectToLink(event, this.device.isTouchScreen);\n }\n this.removePointer(event);\n };\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\n // deal with opening context menu on touch devices\n if (event.pointerType === \"touch\") {\n invalidateContextMenu = false;\n if (touchTimeout) {\n // If there's already a touchTimeout, this means that there's another\n // touch down and we are doing another touch, so we shouldn't open the\n // context menu.\n invalidateContextMenu = true;\n }\n else {\n // open the context menu with the first touch's clientX and clientY\n // if the touch is not moving\n touchTimeout = window.setTimeout(() => {\n touchTimeout = 0;\n if (!invalidateContextMenu) {\n this.handleCanvasContextMenu(event);\n }\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.TOUCH_CTX_MENU_TIMEOUT);\n }\n }\n };\n this.resetContextMenuTimer = () => {\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n invalidateContextMenu = false;\n };\n // Returns whether the event is a panning\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\n if (!(gesture.pointers.size <= 1 &&\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.WHEEL ||\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isHandToolActive)(this.state) ||\n this.state.viewModeEnabled)) ||\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return false;\n }\n isPanning = true;\n event.preventDefault();\n let nextPastePrevented = false;\n const isLinux = /Linux/.test(window.navigator.platform);\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n let { clientX: lastX, clientY: lastY } = event;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const deltaX = lastX - event.clientX;\n const deltaY = lastY - event.clientY;\n lastX = event.clientX;\n lastY = event.clientY;\n /*\n * Prevent paste event if we move while middle clicking on Linux.\n * See issue #1383.\n */\n if (isLinux &&\n !nextPastePrevented &&\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\n nextPastePrevented = true;\n /* Prevent the next paste event */\n const preventNextPaste = (event) => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n event.stopPropagation();\n };\n /*\n * Reenable next paste in case of disabled middle click paste for\n * any reason:\n * - right click paste\n * - empty clipboard\n */\n const enableNextPaste = () => {\n setTimeout(() => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }, 100);\n };\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }\n this.translateCanvas({\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\n });\n });\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\n lastPointerUp = null;\n isPanning = false;\n if (!isHoldingSpace) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n onPointerMove.flush();\n }));\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove, {\n passive: true,\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n return true;\n };\n this.clearSelectionIfNotUsingSelection = () => {\n if (this.state.activeTool.type !== \"selection\") {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n };\n /**\n * @returns whether the pointer event has been completely handled\n */\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\n var _a;\n if (this.state.activeTool.type === \"selection\") {\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType != null) {\n this.setState({\n resizingElement: elementWithTransformHandleType.element,\n });\n pointerDownState.resize.handleType =\n elementWithTransformHandleType.transformHandleType;\n }\n }\n else if (selectedElements.length > 1) {\n pointerDownState.resize.handleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n }\n if (pointerDownState.resize.handleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType: pointerDownState.resize.handleType,\n }));\n pointerDownState.resize.isResizing = true;\n pointerDownState.resize.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeOffsetXY)(pointerDownState.resize.handleType, selectedElements, pointerDownState.origin.x, pointerDownState.origin.y));\n if (selectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\n selectedElements[0].points.length === 2) {\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\n }\n }\n else {\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, this.history, pointerDownState.origin, linearElementEditor);\n if (ret.hitElement) {\n pointerDownState.hit.element = ret.hitElement;\n }\n if (ret.linearElementEditor) {\n this.setState({ selectedLinearElement: ret.linearElementEditor });\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: ret.linearElementEditor });\n }\n }\n if (ret.didAddPoint) {\n return true;\n }\n }\n // hitElement may already be set above, so check first\n pointerDownState.hit.element =\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n if (pointerDownState.hit.element) {\n // Early return if pointer is hitting link icon\n const hitLinkElement = this.getElementLinkAtPosition({\n x: pointerDownState.origin.x,\n y: pointerDownState.origin.y,\n }, pointerDownState.hit.element);\n if (hitLinkElement) {\n return false;\n }\n }\n // For overlapped elements one position may hit\n // multiple elements\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n const hitElement = pointerDownState.hit.element;\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n if ((hitElement === null || !someHitElementIsSelected) &&\n !event.shiftKey &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.clearSelection(hitElement);\n }\n if (this.state.editingLinearElement) {\n this.setState({\n selectedElementIds: {\n [this.state.editingLinearElement.elementId]: true,\n },\n });\n // If we click on something\n }\n else if (hitElement != null) {\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if (!this.state.selectedElementIds[hitElement.id]) {\n pointerDownState.hit.wasAddedToSelection = true;\n }\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\n // mark as not completely handled so as to allow dragging etc.\n return false;\n }\n // deselect if item is selected\n // if shift is not clicked, this will always return true\n // otherwise, it will trigger selection based on current\n // state of the box\n if (!this.state.selectedElementIds[hitElement.id]) {\n // if we are currently editing a group, exiting editing mode and deselect the group.\n if (this.state.editingGroupId &&\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n // Add hit element to selection. At this point if we're not holding\n // SHIFT the previously selected element(s) were deselected above\n // (make sure you use setState updater to use latest state)\n if (!someHitElementIsSelected &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.setState((prevState) => {\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }), showHyperlinkPopup: hitElement.link ? \"info\" : false }), this.scene.getNonDeletedElements());\n });\n pointerDownState.hit.wasAddedToSelection = true;\n }\n }\n }\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n }\n return false;\n };\n this.handleTextOnPointerDown = (event, pointerDownState) => {\n // if we're currently still editing text, clicking outside\n // should only finalize it, not create another (irrespective\n // of state.activeTool.locked)\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return;\n }\n let sceneX = pointerDownState.origin.x;\n let sceneY = pointerDownState.origin.y;\n const element = this.getElementAtPosition(sceneX, sceneY, {\n includeBoundTextElement: true,\n });\n let container = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getTextBindableContainerAtPosition)(this.scene.getNonDeletedElements(), this.state, sceneX, sceneY);\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element)) {\n container = element;\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n insertAtParentCenter: !event.altKey,\n container,\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!this.state.activeTool.locked) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n };\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\n // Begin a mark capture. This does not have to update state yet.\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: null,\n simulatePressure: event.pressure === 0.5,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n const pressures = element.simulatePressure\n ? element.pressures\n : [...element.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [[0, 0]],\n pressures,\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n };\n this.createImageElement = ({ sceneX, sceneY, }) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\n type: \"image\",\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n roundness: null,\n opacity: this.state.currentItemOpacity,\n locked: false,\n });\n return element;\n };\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n // finalize if completing a loop\n if (multiElement.type === \"line\" &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\n // clicking inside commit zone → finalize arrow\n if (multiElement.points.length > 1 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\n }));\n // clicking outside commit zone → update reference for last committed\n // point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\n an arrow, we want it to be null for both. Otherwise, we want it to use the\n values from appState. */\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\n : [null, null];\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.state.currentItemRoundness === \"round\"\n ? { type: _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS }\n : null,\n startArrowhead,\n endArrowhead,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [...element.points, [0, 0]],\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n }\n };\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n roundness: this.state.currentItemRoundness === \"round\"\n ? {\n type: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isUsingAdaptiveRadius)(elementType)\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.ADAPTIVE_RADIUS\n : _constants__WEBPACK_IMPORTED_MODULE_12__.ROUNDNESS.PROPORTIONAL_RADIUS,\n }\n : null,\n locked: false,\n });\n if (element.type === \"selection\") {\n this.setState({\n selectionElement: element,\n draggingElement: element,\n });\n }\n else {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n multiElement: null,\n draggingElement: element,\n editingElement: element,\n });\n }\n };\n this.restoreReadyToEraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.id].opacity,\n });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.containerId].opacity,\n });\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n };\n this.eraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n return ele;\n });\n this.history.resumeRecording();\n this.scene.replaceAllElements(elements);\n };\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\n var _e, _f, _g, _h;\n // at this point this should be guaranteed image file, but we do this check\n // to satisfy TS down the line\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(imageFile)) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\n }\n const mimeType = imageFile.type;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.normalizeSVG)(yield imageFile.text()), imageFile.name);\n }\n catch (error) {\n console.warn(error);\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\n }\n }\n // generate image id (by default the file digest) before any\n // resizing/compression takes place to keep it more portable\n const fileId = yield (((_f = (_e = this.props).generateIdForFile) === null || _f === void 0 ? void 0 : _f.call(_e, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.generateIdFromFile)(imageFile));\n if (!fileId) {\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\n }\n const existingFileData = this.files[fileId];\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\n try {\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\n });\n }\n catch (error) {\n console.error(\"error trying to resing image file on insertion\", error);\n }\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\n }));\n }\n }\n if (showCursorImagePreview) {\n const dataURL = (_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL;\n // optimization so that we don't unnecessarily resize the original\n // full-size file for cursor preview\n // (it's much faster to convert the resized dataURL to File)\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.dataURLToFile)(dataURL);\n this.setImagePreviewCursor(resizedFile || imageFile);\n }\n const dataURL = ((_h = this.files[fileId]) === null || _h === void 0 ? void 0 : _h.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imageFile));\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\n fileId,\n }, false);\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n var _j;\n try {\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\n mimeType,\n id: fileId,\n dataURL,\n created: Date.now(),\n lastRetrieved: Date.now(),\n } });\n const cachedImageData = this.imageCache.get(fileId);\n if (!cachedImageData) {\n this.addNewImagesToImageCache();\n yield this.updateImageCache([imageElement]);\n }\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\n yield cachedImageData.image;\n }\n if (this.state.pendingImageElementId !== imageElement.id &&\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\n this.initializeImageDimensions(imageElement, true);\n }\n resolve(imageElement);\n }\n catch (error) {\n console.error(error);\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\n }\n finally {\n if (!showCursorImagePreview) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n }\n }));\n });\n /**\n * inserts image into elements array and rerenders\n */\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n imageElement,\n ]);\n try {\n yield this.initializeImage({\n imageFile,\n imageElement,\n showCursorImagePreview,\n });\n }\n catch (error) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n isDeleted: true,\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n this.setState({\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\n });\n }\n });\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\n // mustn't be larger than 128 px\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\n const cursorImageSizePx = 96;\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: cursorImageSizePx,\n });\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imagePreview);\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\n // a small canvas\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.loadHTMLImageElement)(previewDataURL);\n let height = Math.min(img.height, cursorImageSizePx);\n let width = height * (img.width / img.height);\n if (width > cursorImageSizePx) {\n width = cursorImageSizePx;\n height = width * (img.height / img.width);\n }\n const canvas = document.createElement(\"canvas\");\n canvas.height = height;\n canvas.width = width;\n const context = canvas.getContext(\"2d\");\n context.drawImage(img, 0, 0, width, height);\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg);\n }\n if (this.state.pendingImageElementId) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\n }\n });\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\n try {\n const clientX = this.state.width / 2 + this.state.offsetLeft;\n const clientY = this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_42__.fileOpen)({\n description: \"Image\",\n extensions: Object.keys(_constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_MIME_TYPES),\n });\n const imageElement = this.createImageElement({\n sceneX: x,\n sceneY: y,\n });\n if (insertOnCanvasDirectly) {\n this.insertImageElement(imageElement, imageFile);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: { [imageElement.id]: true },\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n else {\n this.setState({\n pendingImageElementId: imageElement.id,\n }, () => {\n this.insertImageElement(imageElement, imageFile, \n /* showCursorImagePreview */ true);\n });\n }\n }\n catch (error) {\n if (error.name !== \"AbortError\") {\n console.error(error);\n }\n else {\n console.warn(error);\n }\n this.setState({\n pendingImageElementId: null,\n editingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n });\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\n var _a;\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n if (!image || image instanceof Promise) {\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const placeholderSize = 100 / this.state.zoom.value;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x: imageElement.x - placeholderSize / 2,\n y: imageElement.y - placeholderSize / 2,\n width: placeholderSize,\n height: placeholderSize,\n });\n }\n return;\n }\n if (forceNaturalSize ||\n // if user-created bounding box is below threshold, assume the\n // intention was to click instead of drag, and use the image's\n // intrinsic size\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\n const minHeight = Math.max(this.state.height - 120, 160);\n // max 65% of canvas height, clamped to <300px, vh - 120px>\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\n const height = Math.min(image.naturalHeight, maxHeight);\n const width = height * (image.naturalWidth / image.naturalHeight);\n // add current imageElement width/height to account for previous centering\n // of the placeholder image\n const x = imageElement.x + imageElement.width / 2 - width / 2;\n const y = imageElement.y + imageElement.height / 2 - height / 2;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\n }\n };\n /** updates image cache, refreshing updated elements and/or setting status\n to error for images that fail during <img> element creation */\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.updateImageCache)({\n imageCache: this.imageCache,\n fileIds: elements.map((element) => element.fileId),\n files,\n });\n if (updatedFiles.size || erroredFiles.size) {\n for (const element of elements) {\n if (updatedFiles.has(element.fileId)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n }\n }\n if (erroredFiles.size) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n erroredFiles.has(element.fileId)) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n status: \"error\",\n });\n }\n return element;\n }));\n }\n return { updatedFiles, erroredFiles };\n });\n /** adds new images to imageCache and re-renders if needed */\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.getInitializedImageElements)(this.scene.getNonDeletedElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\n if (uncachedImageElements.length) {\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\n if (updatedFiles.size) {\n this.scene.informMutation();\n }\n }\n });\n /** generally you should use `addNewImagesToImageCache()` directly if you need\n * to render new images. This is just a failsafe */\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default()(() => {\n this.addNewImagesToImageCache();\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_RENDER_TIMEOUT);\n this.updateBindingEnabledOnPointerMove = (event) => {\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\n this.setState({ isBindingEnabled: shouldEnableBinding });\n }\n };\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\n this.setState({\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\n });\n };\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \n /** scene coords */\n pointerCoords, \n // During line creation the start binding hasn't been written yet\n // into `linearElement`\n oppositeBindingBoundElement) => {\n if (!pointerCoords.length) {\n return;\n }\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\n if (hoveredBindableElement != null &&\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\n acc.push(hoveredBindableElement);\n }\n return acc;\n }, []);\n this.setState({ suggestedBindings });\n };\n this.handleCanvasRef = (canvas) => {\n var _a, _b, _c;\n // canvas is null when unmounting\n if (canvas !== null) {\n this.canvas = canvas;\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__[\"default\"].canvas(this.canvas);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel, {\n passive: false,\n });\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n else {\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n };\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\n // must be retrieved first, in the same frame\n const { file, fileHandle } = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getFileFromEvent)(event);\n try {\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file)) {\n // first attempt to decode scene from the image if it's embedded\n // ---------------------------------------------------------------------\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_13__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n return;\n }\n catch (error) {\n if (error.name !== \"EncodingError\") {\n throw error;\n }\n }\n }\n // if no scene is embedded or we fail for whatever reason, fall back\n // to importing as regular image\n // ---------------------------------------------------------------------\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n }\n catch (error) {\n return this.setState({\n isLoading: false,\n errorMessage: error.message,\n });\n }\n const libraryJSON = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib);\n if (libraryJSON && typeof libraryJSON === \"string\") {\n try {\n const libraryItems = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.parseLibraryJSON)(libraryJSON);\n this.addElementsFromPasteOrLibrary({\n elements: (0,_data_library__WEBPACK_IMPORTED_MODULE_14__.distributeLibraryItemsOnSquareGrid)(libraryItems),\n position: event,\n files: null,\n });\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n return;\n }\n if (file) {\n // atetmpt to parse an excalidraw/excalidrawlib file\n yield this.loadFileToCanvas(file, fileHandle);\n }\n });\n this.loadFileToCanvas = (file, fileHandle) => __awaiter(this, void 0, void 0, function* () {\n file = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.normalizeFile)(file);\n try {\n const ret = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.loadSceneOrLibraryFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidraw) {\n this.setState({ isLoading: true });\n this.syncActionResult(Object.assign(Object.assign({}, ret.data), { appState: Object.assign(Object.assign({}, (ret.data.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n }\n else if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib) {\n yield this.library\n .updateLibrary({\n libraryItems: file,\n merge: true,\n openLibraryMenu: true,\n })\n .catch((error) => {\n console.error(error);\n this.setState({ errorMessage: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.importLibraryError\") });\n });\n }\n }\n catch (error) {\n this.setState({ isLoading: false, errorMessage: error.message });\n }\n });\n this.handleCanvasContextMenu = (event) => {\n event.preventDefault();\n if ((event.nativeEvent.pointerType === \"touch\" ||\n (event.nativeEvent.pointerType === \"pen\" &&\n // always allow if user uses a pen secondary button\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.SECONDARY)) &&\n this.state.activeTool.type !== \"selection\") {\n return;\n }\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const element = this.getElementAtPosition(x, y, {\n preferSelected: true,\n includeLockedElements: true,\n });\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const isHittignCommonBoundBox = this.isHittingCommonBoundingBoxOfSelectedElements({ x, y }, selectedElements);\n const type = element || isHittignCommonBoundBox ? \"element\" : \"canvas\";\n const container = this.excalidrawContainerRef.current;\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\n const left = event.clientX - offsetLeft;\n const top = event.clientY - offsetTop;\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"contextMenu\", \"openContextMenu\", type);\n this.setState(Object.assign(Object.assign({}, (element && !this.state.selectedElementIds[element.id]\n ? (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { selectedElementIds: { [element.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(element)\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(element, this.scene)\n : null }), this.scene.getNonDeletedElements())\n : this.state)), { showHyperlinkPopup: false }), () => {\n this.setState({\n contextMenu: { top, left, items: this.getContextMenuItems(type) },\n });\n });\n };\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\n var _a;\n const draggingElement = this.state.draggingElement;\n const pointerCoords = pointerDownState.lastCoords;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"selection\" &&\n this.state.activeTool.type !== \"eraser\") {\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.origin.x, pointerDownState.origin.y, pointerCoords.x, pointerCoords.y, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.x, pointerCoords.x), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.y, pointerCoords.y), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event));\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n const aspectRatio = image && !(image instanceof Promise)\n ? image.width / image.height\n : null;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.x, gridX), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.y, gridY), (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\n this.maybeSuggestBindingForAll([draggingElement]);\n }\n };\n this.maybeHandleResize = (pointerDownState, event) => {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const transformHandleType = pointerDownState.resize.handleType;\n this.setState({\n // TODO: rename this state field to \"isScaling\" to distinguish\n // it from the generic \"isResizing\" which includes scaling and\n // rotating\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\n isRotating: transformHandleType === \"rotation\",\n });\n const pointerCoords = pointerDownState.lastCoords;\n const [resizeX, resizeY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.y - pointerDownState.resize.offset.y, this.state.gridSize);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.transformElements)(pointerDownState, transformHandleType, selectedElements, pointerDownState.resize.arrowDirection, (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(selectedElements[0])\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\n this.maybeSuggestBindingForAll(selectedElements);\n return true;\n }\n return false;\n };\n this.getContextMenuItems = (type) => {\n const options = [];\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng, _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg);\n // canvas contextMenu\n // -------------------------------------------------------------------------\n if (type === \"canvas\") {\n if (this.state.viewModeEnabled) {\n return [\n ...options,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n }\n return [\n _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_49__.actionPaste,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg,\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll,\n _actions_actionElementLock__WEBPACK_IMPORTED_MODULE_47__.actionUnlockAllElements,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n }\n // element contextMenu\n // -------------------------------------------------------------------------\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n if (this.state.viewModeEnabled) {\n return [_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options];\n }\n return [\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCut,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy,\n _actions_actionClipboard__WEBPACK_IMPORTED_MODULE_49__.actionPaste,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n ...options,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText,\n _actions_actionBoundText__WEBPACK_IMPORTED_MODULE_53__.actionWrapTextInContainer,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLinearEditor,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleElementLock,\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__.CONTEXT_MENU_SEPARATOR,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected,\n ];\n };\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n if (isPanning) {\n return;\n }\n const { deltaX, deltaY } = event;\n // note that event.ctrlKey is necessary to handle pinch zooming\n if (event.metaKey || event.ctrlKey) {\n const sign = Math.sign(deltaY);\n const MAX_STEP = _constants__WEBPACK_IMPORTED_MODULE_12__.ZOOM_STEP * 100;\n const absDelta = Math.abs(deltaY);\n let delta = deltaY;\n if (absDelta > MAX_STEP) {\n delta = MAX_STEP * sign;\n }\n let newZoom = this.state.zoom.value - delta / 100;\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\n newZoom +=\n Math.log10(Math.max(1, this.state.zoom.value)) *\n -sign *\n // reduced amplification for small deltas (small movements on a trackpad)\n Math.min(1, absDelta / 20);\n this.translateCanvas((state) => (Object.assign(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom),\n }, state)), { shouldCacheIgnoreZoom: true })));\n this.resetShouldCacheIgnoreZoomDebounced();\n return;\n }\n // scroll horizontally when shift pressed\n if (event.shiftKey) {\n this.translateCanvas(({ zoom, scrollX }) => ({\n // on Mac, shift+wheel tends to result in deltaX\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\n }));\n return;\n }\n this.translateCanvas(({ zoom, scrollX, scrollY }) => ({\n scrollX: scrollX - deltaX / zoom.value,\n scrollY: scrollY - deltaY / zoom.value,\n }));\n });\n this.savePointer = (x, y, button) => {\n var _a, _b;\n if (!x || !y) {\n return;\n }\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\n // sometimes the pointer goes off screen\n }\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\n pointer,\n button,\n pointersMap: gesture.pointers,\n });\n };\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n if (!this.unmounted) {\n this.setState({ shouldCacheIgnoreZoom: false });\n }\n }, 300);\n this.updateDOMRect = (cb) => {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\n if (width === currentWidth &&\n height === currentHeight &&\n offsetLeft === currentOffsetLeft &&\n offsetTop === currentOffsetTop) {\n if (cb) {\n cb();\n }\n return;\n }\n this.setState({\n width,\n height,\n offsetLeft,\n offsetTop,\n }, () => {\n cb && cb();\n });\n }\n };\n this.refresh = () => {\n this.setState(Object.assign({}, this.getCanvasOffsets()));\n };\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)();\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight, showHyperlinkPopup: false, defaultSidebarDockedPreference: false });\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_56__.nanoid)();\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n if (excalidrawRef) {\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\n const api = {\n ready: true,\n readyPromise,\n updateScene: this.updateScene,\n updateLibrary: this.library.updateLibrary,\n addFiles: this.addFiles,\n resetScene: this.resetScene,\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\n history: {\n clear: this.resetHistory,\n },\n scrollToContent: this.scrollToContent,\n getSceneElements: this.getSceneElements,\n getAppState: () => this.state,\n getFiles: () => this.files,\n refresh: this.refresh,\n setToast: this.setToast,\n id: this.id,\n setActiveTool: this.setActiveTool,\n setCursor: this.setCursor,\n resetCursor: this.resetCursor,\n app: this,\n onChange: (cb) => this.onChangeEmitter.on(cb),\n onPointerDown: (cb) => this.onPointerDownEmitter.on(cb),\n onPointerUp: (cb) => this.onPointerUpEmitter.on(cb),\n toggleSidebar: this.toggleSidebar,\n };\n if (typeof excalidrawRef === \"function\") {\n excalidrawRef(api);\n }\n else {\n excalidrawRef.current = api;\n }\n readyPromise.resolve(api);\n }\n this.excalidrawContainerValue = {\n container: this.excalidrawContainerRef.current,\n id: this.id,\n };\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\n this.fonts = new _scene_Fonts__WEBPACK_IMPORTED_MODULE_48__.Fonts({\n scene: this.scene,\n onSceneUpdated: this.onSceneUpdated,\n });\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_8__.actions);\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createUndoAction)(this.history));\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createRedoAction)(this.history));\n }\n renderCanvas() {\n const canvasScale = window.devicePixelRatio;\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\n const canvasWidth = canvasDOMWidth * canvasScale;\n const canvasHeight = canvasDOMHeight * canvasScale;\n if (viewModeEnabled) {\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n cursor: _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n render() {\n var _a;\n const selectedElement = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const { renderTopRightUI, renderCustomStats } = this.props;\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw excalidraw-container\", {\n \"excalidraw--view-mode\": this.state.viewModeEnabled,\n \"excalidraw--zen-mode\": this.state.zenModeEnabled,\n \"excalidraw--mobile\": this.device.isMobile,\n }), ref: this.excalidrawContainerRef, onDrop: this.handleAppOnDrop, tabIndex: 0, onKeyDown: this.props.handleKeyboardGlobally ? undefined : this.onKeyDown }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppContext.Provider, Object.assign({ value: this }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(AppPropsContext.Provider, Object.assign({ value: this.props }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawContainerContext.Provider, Object.assign({ value: this.excalidrawContainerValue }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DeviceContext.Provider, Object.assign({ value: this.device }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawSetAppStateContext.Provider, Object.assign({ value: this.setAppState }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawAppStateContext.Provider, Object.assign({ value: this.state }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawElementsContext.Provider, Object.assign({ value: this.scene.getNonDeletedElements() }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ExcalidrawActionManagerContext.Provider, Object.assign({ value: this.actionManager }, { children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], Object.assign({ onExportImage: this.onExportImage, onHomeButtonClick: this.props.onHomeButtonClick || (() => { }), canvas: this.canvas, appState: this.state, files: this.files, setAppState: this.setAppState, actionManager: this.actionManager, elements: this.scene.getNonDeletedElements(), onLockToggle: this.toggleLock, onPenModeToggle: this.togglePenMode, onHandToolToggle: this.onHandToolToggle, langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, renderTopRightUI: renderTopRightUI, renderCustomStats: renderCustomStats, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\n this.state.zenModeEnabled, UIOptions: this.props.UIOptions, onImageAction: this.onImageAction, renderWelcomeScreen: !this.state.isLoading &&\n this.state.showWelcomeScreen &&\n this.state.activeTool.type === \"selection\" &&\n !this.scene.getElementsIncludingDeleted().length }, { children: this.props.children })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }), selectedElement.length === 1 &&\n !this.state.contextMenu &&\n this.state.showHyperlinkPopup && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.Hyperlink, { element: selectedElement[0], setAppState: this.setAppState, onLinkOpen: this.props.onLinkOpen }, selectedElement[0].id)), this.state.toast !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_37__.Toast, { message: this.state.toast.message, onClose: () => this.setToast(null), duration: this.state.toast.duration, closable: this.state.toast.closable })), this.state.contextMenu && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_ContextMenu__WEBPACK_IMPORTED_MODULE_35__.ContextMenu, { items: this.state.contextMenu.items, top: this.state.contextMenu.top, left: this.state.contextMenu.left, actionManager: this.actionManager })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() })] })) })) })) })) })) })) })) })) })));\n }\n componentDidMount() {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n this.unmounted = false;\n this.excalidrawContainerValue.container =\n this.excalidrawContainerRef.current;\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT) {\n const setState = this.setState.bind(this);\n Object.defineProperties(window.h, {\n state: {\n configurable: true,\n get: () => {\n return this.state;\n },\n },\n setState: {\n configurable: true,\n value: (...args) => {\n return this.setState(...args);\n },\n },\n app: {\n configurable: true,\n value: this,\n },\n history: {\n configurable: true,\n value: this.history,\n },\n });\n }\n this.scene.addCallback(this.onSceneUpdated);\n this.addEventListeners();\n if (this.props.autoFocus && this.excalidrawContainerRef.current) {\n this.focusContainer();\n }\n if (this.excalidrawContainerRef.current &&\n // bounding rects don't work in tests so updating\n // the state on init would result in making the test enviro run\n // in mobile breakpoint (0 width/height), making everything fail\n \"development\" !== \"test\") {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\n this.resizeObserver = new ResizeObserver(() => {\n THROTTLE_NEXT_RENDER = false;\n // recompute device dimensions state\n // ---------------------------------------------------------------------\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n // refresh offsets\n // ---------------------------------------------------------------------\n this.updateDOMRect();\n });\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\n }\n else if (window.matchMedia) {\n const mdScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\n const smScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH}px)`);\n const canDeviceFitSidebarMediaQuery = window.matchMedia(`(min-width: ${\n // NOTE this won't update if a different breakpoint is supplied\n // after mount\n this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH}px)`);\n const handler = () => {\n this.excalidrawContainerRef.current.getBoundingClientRect();\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isSmScreen: smScreenQuery.matches,\n isMobile: mdScreenQuery.matches,\n canDeviceFitSidebar: canDeviceFitSidebarMediaQuery.matches,\n });\n };\n mdScreenQuery.addListener(handler);\n this.detachIsMobileMqHandler = () => mdScreenQuery.removeListener(handler);\n }\n const searchParams = new URLSearchParams(window.location.search.slice(1));\n if (searchParams.has(\"web-share-target\")) {\n // Obtain a file that was shared via the Web Share Target API.\n this.restoreFileFromShare();\n }\n else {\n this.updateDOMRect(this.initializeScene);\n }\n // note that this check seems to always pass in localhost\n if ((0,_constants__WEBPACK_IMPORTED_MODULE_12__.isBrave)() && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.isMeasureTextSupported)()) {\n this.setState({\n errorMessage: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_BraveMeasureTextError__WEBPACK_IMPORTED_MODULE_54__[\"default\"], {}),\n });\n }\n });\n }\n componentWillUnmount() {\n var _a;\n this.files = {};\n this.imageCache.clear();\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n this.unmounted = true;\n this.removeEventListeners();\n this.scene.destroy();\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.clearRenderCache)();\n this.onChangeEmitter.destroy();\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n this.canvas = null;\n this.rc = null;\n // @ts-ignore\n this.excalidrawContainerRef.current = undefined;\n this.nearestScrollableContainer = undefined;\n this.excalidrawContainerValue = { container: null, id: \"unmounted\" };\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n }\n removeEventListeners() {\n var _a, _b, _c, _d, _e, _f, _g;\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel);\n (_b = this.nearestScrollableContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n (_f = (_e = document.fonts) === null || _e === void 0 ? void 0 : _e.removeEventListener) === null || _f === void 0 ? void 0 : _f.call(_e, \"loadingdone\", this.onFontsLoadingDone);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n (_g = this.detachIsMobileMqHandler) === null || _g === void 0 ? void 0 : _g.call(this);\n }\n addEventListeners() {\n var _a, _b, _c, _d, _e;\n this.removeEventListeners();\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer); // #3553\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel, { passive: false });\n if (this.props.handleKeyboardGlobally) {\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp, { passive: true });\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\n // rerender text elements on font load to fix #637 && #1553\n (_c = (_b = document.fonts) === null || _b === void 0 ? void 0 : _b.addEventListener) === null || _c === void 0 ? void 0 : _c.call(_b, \"loadingdone\", this.onFontsLoadingDone);\n // Safari-only desktop pinch zoom\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n if (this.state.viewModeEnabled) {\n return;\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n if (this.props.detectScroll) {\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n }\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_e = this.excalidrawContainerRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n }\n componentDidUpdate(prevProps, prevState) {\n var _a, _b, _c, _d, _e;\n if (!this.state.showWelcomeScreen &&\n !this.scene.getElementsIncludingDeleted().length) {\n this.setState({ showWelcomeScreen: true });\n }\n if (this.excalidrawContainerRef.current &&\n prevProps.UIOptions.dockedSidebarBreakpoint !==\n this.props.UIOptions.dockedSidebarBreakpoint) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (prevState.scrollX !== this.state.scrollX ||\n prevState.scrollY !== this.state.scrollY) {\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onScrollChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.scrollX, this.state.scrollY);\n }\n if (Object.keys(this.state.selectedElementIds).length &&\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n if (this.state.activeTool.type === \"eraser\" &&\n prevState.theme !== this.state.theme) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setEraserCursor)(this.canvas, this.state.theme);\n }\n // Hide hyperlink popup if shown when element type is not selection\n if (prevState.activeTool.type === \"selection\" &&\n this.state.activeTool.type !== \"selection\" &&\n this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n if (prevProps.langCode !== this.props.langCode) {\n this.updateLanguage();\n }\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\n }\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\n this.addEventListeners();\n this.deselectElements();\n }\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\n }\n if (prevProps.theme !== this.props.theme && this.props.theme) {\n this.setState({ theme: this.props.theme });\n }\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\n this.setState({\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null,\n });\n }\n if (!this.props.UIOptions.canvasActions &&\n this.state.openMenu === \"canvas\") {\n this.setState({\n openMenu: null,\n });\n }\n if (this.props.name && prevProps.name !== this.props.name) {\n this.setState({\n name: this.props.name,\n });\n }\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\n if (this.state.editingLinearElement &&\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\n // defer so that the commitToHistory flag isn't reset via current update\n setTimeout(() => {\n // execute only if the condition still holds when the deferred callback\n // executes (it can be scheduled multiple times depending on how\n // many times the component renders)\n this.state.editingLinearElement &&\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n if (this.state.selectedLinearElement &&\n !this.state.selectedElementIds[this.state.selectedLinearElement.elementId]) {\n // To make sure `selectedLinearElement` is in sync with `selectedElementIds`, however this shouldn't be needed once\n // we have a single API to update `selectedElementIds`\n this.setState({ selectedLinearElement: null });\n }\n const { multiElement } = prevState;\n if (prevState.activeTool !== this.state.activeTool &&\n multiElement != null &&\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(multiElement, this.state, this.scene, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)(_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1)));\n }\n this.renderScene();\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\n // Do not notify consumers if we're still loading the scene. Among other\n // potential issues, this fixes a case where the tab isn't focused during\n // init, which would trigger onChange with empty elements, which would then\n // override whatever is in localStorage currently.\n if (!this.state.isLoading) {\n (_e = (_d = this.props).onChange) === null || _e === void 0 ? void 0 : _e.call(_d, this.scene.getElementsIncludingDeleted(), this.state, this.files, this.props.id);\n this.onChangeEmitter.trigger(this.scene.getElementsIncludingDeleted(), this.state, this.files);\n }\n }\n static resetTapTwice() {\n didTapTwice = false;\n }\n addTextFromPaste(text, isPlainPaste = false) {\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const textElementProps = {\n x,\n y,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roundness: null,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n text,\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: this.state.currentItemTextAlign,\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n locked: false,\n };\n const LINE_GAP = 10;\n let currentY = y;\n const lines = isPlainPaste ? [text] : text.split(\"\\n\");\n const textElements = lines.reduce((acc, line, idx) => {\n var _a;\n const text = line.trim();\n const lineHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getDefaultLineHeight)(textElementProps.fontFamily);\n if (text.length) {\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)(Object.assign(Object.assign({}, textElementProps), { x, y: currentY, text,\n lineHeight }));\n acc.push(element);\n currentY += element.height + LINE_GAP;\n }\n else {\n const prevLine = (_a = lines[idx - 1]) === null || _a === void 0 ? void 0 : _a.trim();\n // add paragraph only if previous line was not empty, IOW don't add\n // more than one empty line\n if (prevLine) {\n currentY +=\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getLineHeightInPx)(textElementProps.fontSize, lineHeight) +\n LINE_GAP;\n }\n }\n return acc;\n }, []);\n if (textElements.length === 0) {\n return;\n }\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n ...textElements,\n ]);\n this.setState({\n selectedElementIds: Object.fromEntries(textElements.map((el) => [el.id, true])),\n });\n if (!isPlainPaste &&\n textElements.length > 1 &&\n PLAIN_PASTE_TOAST_SHOWN === false &&\n !this.device.isMobile) {\n this.setToast({\n message: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"toast.pasteAsSingleElement\", {\n shortcut: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getShortcutKey)(\"CtrlOrCmd+Shift+V\"),\n }),\n duration: 5000,\n });\n PLAIN_PASTE_TOAST_SHOWN = true;\n }\n this.history.resumeRecording();\n }\n handleTextWysiwyg(element, { isExistingElement = false, }) {\n const updateElement = (text, originalText, isDeleted) => {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted,\n originalText,\n });\n }\n return _element;\n }),\n ]);\n };\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\n id: element.id,\n canvas: this.canvas,\n getViewportCoords: (x, y) => {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: x,\n sceneY: y,\n }, this.state);\n return [\n viewportX - this.state.offsetLeft,\n viewportY - this.state.offsetTop,\n ];\n },\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\n updateElement(text, text, false);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\n }\n }),\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\n const isDeleted = !text.trim();\n updateElement(text, originalText, isDeleted);\n // select the created text element only if submitting via keyboard\n // (when submitting via click it should act as signal to deselect)\n if (!isDeleted && viaKeyboard) {\n const elementIdToSelect = element.containerId\n ? element.containerId\n : element.id;\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\n }));\n }\n if (isDeleted) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getNonDeletedElements(), [\n element,\n ]);\n }\n if (!isDeleted || isExistingElement) {\n this.history.resumeRecording();\n }\n this.setState({\n draggingElement: null,\n editingElement: null,\n });\n if (this.state.activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n this.focusContainer();\n }),\n element,\n excalidrawContainer: this.excalidrawContainerRef.current,\n app: this,\n });\n // deselect all other elements when inserting text\n this.deselectElements();\n // do an initial update to re-initialize element position since we were\n // modifying element's x/y for sake of editor (case: syncing to remote)\n updateElement(element.text, element.originalText, false);\n }\n deselectElements() {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n getTextElementAtPosition(x, y) {\n const element = this.getElementAtPosition(x, y, {\n includeBoundTextElement: true,\n });\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\n return element;\n }\n return null;\n }\n getElementAtPosition(x, y, opts) {\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement, opts === null || opts === void 0 ? void 0 : opts.includeLockedElements);\n if (allHitElements.length > 1) {\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\n for (let index = allHitElements.length - 1; index > -1; index--) {\n if (this.state.selectedElementIds[allHitElements[index].id]) {\n return allHitElements[index];\n }\n }\n }\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\n // If we're hitting element with highest z-index only on its bounding box\n // while also hitting other element figure, the latter should be considered.\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\n ? allHitElements[allHitElements.length - 2]\n : elementWithHighestZIndex;\n }\n if (allHitElements.length === 1) {\n return allHitElements[0];\n }\n return null;\n }\n getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {\n const elements = includeBoundTextElement && includeLockedElements\n ? this.scene.getNonDeletedElements()\n : this.scene\n .getNonDeletedElements()\n .filter((element) => (includeLockedElements || !element.locked) &&\n (includeBoundTextElement ||\n !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId)));\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\n }\n handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(linearElementEditor.elementId);\n const boundTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(element);\n if (!element) {\n return;\n }\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\n let segmentMidPointHoveredCoords = null;\n if ((0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\n scenePointerX,\n scenePointerY,\n ])) {\n hoverPointIndex = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointIndexUnderCursor(element, this.state.zoom, scenePointerX, scenePointerY);\n segmentMidPointHoveredCoords =\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, { x: scenePointerX, y: scenePointerY }, this.state);\n if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n }\n else if ((0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_46__.shouldShowBoundingBox)([element], this.state) &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(element, this.state, scenePointerX, scenePointerY)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n else if (boundTextElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(boundTextElement, this.state, scenePointerX, scenePointerY)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { hoverPointIndex }),\n });\n }\n if (!_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.arePointsEqual(this.state.selectedLinearElement.segmentMidPointHoveredCoords, segmentMidPointHoveredCoords)) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { segmentMidPointHoveredCoords }),\n });\n }\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n maybeCleanupAfterMissingPointerUp(event) {\n if (lastPointerUp !== null) {\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\n // this can happen when a contextual menu or alert is triggered. In order to avoid\n // being in a weird state, we clean up on the next pointerdown\n lastPointerUp(event);\n }\n }\n updateGestureOnPointerDown(event) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n if (gesture.pointers.size === 2) {\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n gesture.initialScale = this.state.zoom.value;\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n }\n }\n initialPointerDownState(event) {\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return {\n origin,\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\n // we need to duplicate because we'll be updating this state\n lastCoords: Object.assign({}, origin),\n originalElements: this.scene\n .getNonDeletedElements()\n .reduce((acc, element) => {\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\n return acc;\n }, new Map()),\n resize: {\n handleType: false,\n isResizing: false,\n offset: { x: 0, y: 0 },\n arrowDirection: \"origin\",\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\n },\n hit: {\n element: null,\n allHitElements: [],\n wasAddedToSelection: false,\n hasBeenDuplicated: false,\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\n },\n drag: {\n hasOccurred: false,\n offset: null,\n },\n eventListeners: {\n onMove: null,\n onUp: null,\n onKeyUp: null,\n onKeyDown: null,\n },\n boxSelection: {\n hasOccurred: false,\n },\n elementIdsToErase: {},\n };\n }\n // Returns whether the event is a dragging a scrollbar\n handleDraggingScrollBar(event, pointerDownState) {\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\n return false;\n }\n isDraggingScrollBar = true;\n pointerDownState.lastCoords.x = event.clientX;\n pointerDownState.lastCoords.y = event.clientY;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\n });\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isDraggingScrollBar = false;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n lastPointerUp = null;\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n onPointerMove.flush();\n });\n lastPointerUp = onPointerUp;\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n return true;\n }\n isASelectedElement(hitElement) {\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\n }\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\n if (selectedElements.length < 2) {\n return false;\n }\n // How many pixels off the shape boundary we still consider a hit\n const threshold = 10 / this.state.zoom.value;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return (point.x > x1 - threshold &&\n point.x < x2 + threshold &&\n point.y > y1 - threshold &&\n point.y < y2 + threshold);\n }\n onKeyDownFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onKeyUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // Prevents focus from escaping excalidraw tab\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onPointerMoveFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n var _a;\n // We need to initialize dragOffsetXY only after we've updated\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\n // event handler should hopefully ensure we're already working with\n // the updated state.\n if (pointerDownState.drag.offset === null) {\n pointerDownState.drag.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getDragOffsetXY)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\n }\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\n return;\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.handleEraser(event, pointerDownState, pointerCoords);\n return;\n }\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n // for arrows/lines, don't start dragging until a given threshold\n // to ensure we don't create a 2-point arrow by mistake when\n // user clicks mouse in a way that it moves a tiny bit (thus\n // triggering pointermove)\n if (!pointerDownState.drag.hasOccurred &&\n (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\")) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) {\n return;\n }\n }\n if (pointerDownState.resize.isResizing) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n if (this.maybeHandleResize(pointerDownState, event)) {\n return true;\n }\n }\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n if (_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.shouldAddMidpoint(this.state.selectedLinearElement, pointerCoords, this.state)) {\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.addMidpoint(this.state.selectedLinearElement, pointerCoords, this.state);\n if (!ret) {\n return;\n }\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n if (this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { pointerDownState: ret.pointerDownState, selectedPointsIndices: ret.selectedPointsIndices }),\n });\n }\n if (this.state.editingLinearElement) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), { pointerDownState: ret.pointerDownState, selectedPointsIndices: ret.selectedPointsIndices }),\n });\n }\n });\n return;\n }\n else if (linearElementEditor.pointerDownState.segmentMidpoint.value !== null &&\n !linearElementEditor.pointerDownState.segmentMidpoint.added) {\n return;\n }\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\n }, linearElementEditor);\n if (didDrag) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n pointerDownState.drag.hasOccurred = true;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), { isDragging: true }),\n });\n }\n if (!this.state.selectedLinearElement.isDragging) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { isDragging: true }),\n });\n }\n return;\n }\n }\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n const isSelectingPointsInLineEditor = this.state.editingLinearElement &&\n event.shiftKey &&\n this.state.editingLinearElement.elementId ===\n ((_a = pointerDownState.hit.element) === null || _a === void 0 ? void 0 : _a.id);\n if ((hasHitASelectedElement ||\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\n !isSelectingPointsInLineEditor) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.every((element) => element.locked)) {\n return;\n }\n // Marking that click was used for dragging to check\n // if elements should be deselected on pointerup\n pointerDownState.drag.hasOccurred = true;\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\n // it would have weird results (stuff jumping all over the screen)\n // Checking for editingElement to avoid jump while editing on mobile #6503\n if (selectedElements.length > 0 &&\n !pointerDownState.withCmdOrCtrl &&\n !this.state.editingElement) {\n const [dragX, dragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.drag.offset.x, pointerCoords.y - pointerDownState.drag.offset.y, this.state.gridSize);\n const [dragDistanceX, dragDistanceY] = [\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\n ];\n // We only drag in one direction if shift is pressed\n const lockDirection = event.shiftKey;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY, this.state);\n this.maybeSuggestBindingForAll(selectedElements);\n // We duplicate the selected element if alt is pressed on pointer move\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\n // Move the currently selected elements to the top of the z index stack, and\n // put the duplicates where the selected elements used to be.\n // (the origin point where the dragging started)\n pointerDownState.hit.hasBeenDuplicated = true;\n const nextElements = [];\n const elementsToAppend = [];\n const groupIdMap = new Map();\n const oldIdToDuplicatedId = new Map();\n const hitElement = pointerDownState.hit.element;\n const elements = this.scene.getElementsIncludingDeleted();\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\n for (const element of elements) {\n if (selectedElementIds.includes(element.id) ||\n // case: the state.selectedElementIds might not have been\n // updated yet by the time this mousemove event is fired\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n pointerDownState.hit.wasAddedToSelection)) {\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\n const [originDragX, originDragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x - pointerDownState.drag.offset.x, pointerDownState.origin.y - pointerDownState.drag.offset.y, this.state.gridSize);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\n x: duplicatedElement.x + (originDragX - dragX),\n y: duplicatedElement.y + (originDragY - dragY),\n });\n nextElements.push(duplicatedElement);\n elementsToAppend.push(element);\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\n }\n else {\n nextElements.push(element);\n }\n }\n const nextSceneElements = [...nextElements, ...elementsToAppend];\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\n this.scene.replaceAllElements(nextSceneElements);\n }\n return;\n }\n }\n // It is very important to read this.state within each move event,\n // otherwise we would read a stale one!\n const draggingElement = this.state.draggingElement;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"freedraw\") {\n const points = draggingElement.points;\n const dx = pointerCoords.x - draggingElement.x;\n const dy = pointerCoords.y - draggingElement.y;\n const lastPoint = points.length > 0 && points[points.length - 1];\n const discardPoint = lastPoint && lastPoint[0] === dx && lastPoint[1] === dy;\n if (!discardPoint) {\n const pressures = draggingElement.simulatePressure\n ? draggingElement.pressures\n : [...draggingElement.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n });\n }\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n pointerDownState.drag.hasOccurred = true;\n const points = draggingElement.points;\n let dx = gridX - draggingElement.x;\n let dy = gridY - draggingElement.y;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(draggingElement.x, draggingElement.y, pointerCoords.x, pointerCoords.y));\n }\n if (points.length === 1) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n });\n }\n else if (points.length === 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points.slice(0, -1), [dx, dy]],\n });\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n // When creating a linear element by dragging\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\n }\n }\n else {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n this.maybeDragNewGenericElement(pointerDownState, event);\n }\n if (this.state.activeTool.type === \"selection\") {\n pointerDownState.boxSelection.hasOccurred = true;\n const elements = this.scene.getNonDeletedElements();\n if (!event.shiftKey &&\n // allows for box-selecting points (without shift)\n !this.state.editingLinearElement &&\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\n [pointerDownState.hit.element.id]: true,\n } }), this.scene.getNonDeletedElements()));\n }\n else {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n }\n // box-select line editor points\n if (this.state.editingLinearElement) {\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\n // regular box-select\n }\n else {\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign(Object.assign({}, prevState.selectedElementIds), elementsWithinSelection.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {})), (pointerDownState.hit.element\n ? {\n // if using ctrl/cmd, select the hitElement only if we\n // haven't box-selected anything else\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\n }\n : null)), showHyperlinkPopup: elementsWithinSelection.length === 1 &&\n elementsWithinSelection[0].link\n ? \"info\"\n : false, \n // select linear element only when we haven't box-selected anything else\n selectedLinearElement: elementsWithinSelection.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(elementsWithinSelection[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(elementsWithinSelection[0], this.scene)\n : null }), this.scene.getNonDeletedElements()));\n }\n }\n });\n }\n // Returns whether the pointer move happened over either scrollbar\n handlePointerMoveOverScrollbars(event, pointerDownState) {\n if (pointerDownState.scrollbars.isOverHorizontal) {\n const x = event.clientX;\n const dx = x - pointerDownState.lastCoords.x;\n this.translateCanvas({\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\n });\n pointerDownState.lastCoords.x = x;\n return true;\n }\n if (pointerDownState.scrollbars.isOverVertical) {\n const y = event.clientY;\n const dy = y - pointerDownState.lastCoords.y;\n this.translateCanvas({\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\n });\n pointerDownState.lastCoords.y = y;\n return true;\n }\n return false;\n }\n onPointerUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\n var _a, _b, _c, _d, _e, _f;\n const { draggingElement, resizingElement, multiElement, activeTool, isResizing, isRotating, } = this.state;\n this.setState({\n isResizing: false,\n isRotating: false,\n resizingElement: null,\n selectionElement: null,\n cursorButton: \"up\",\n // text elements are reset on finalize, and resetting on pointerup\n // may cause issues with double taps\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? this.state.editingElement\n : null,\n });\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\n this.onPointerUpEmitter.trigger(this.state.activeTool, pointerDownState, childEvent);\n // Handle end of dragging a point of a linear element, might close a loop\n // and sets binding element\n if (this.state.editingLinearElement) {\n if (!pointerDownState.boxSelection.hasOccurred &&\n ((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\n this.state.editingLinearElement.elementId) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n else {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\n if (editingLinearElement !== this.state.editingLinearElement) {\n this.setState({\n editingLinearElement,\n suggestedBindings: [],\n });\n }\n }\n }\n else if (this.state.selectedLinearElement) {\n if (((_d = (_c = pointerDownState.hit) === null || _c === void 0 ? void 0 : _c.element) === null || _d === void 0 ? void 0 : _d.id) !==\n this.state.selectedLinearElement.elementId) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement to null if there is more than one element selected since we don't want to show linear element handles\n if (selectedELements.length > 1) {\n this.setState({ selectedLinearElement: null });\n }\n }\n else {\n const linearElementEditor = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state);\n const { startBindingElement, endBindingElement } = linearElementEditor;\n const element = this.scene.getElement(linearElementEditor.elementId);\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n if (linearElementEditor !== this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, linearElementEditor), { selectedPointsIndices: null }),\n suggestedBindings: [],\n });\n }\n }\n }\n lastPointerUp = null;\n if (pointerDownState.eventListeners.onMove) {\n pointerDownState.eventListeners.onMove.flush();\n }\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\n if (this.state.pendingImageElementId) {\n this.setState({ pendingImageElementId: null });\n }\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n const points = draggingElement.points;\n let dx = pointerCoords.x - draggingElement.x;\n let dy = pointerCoords.y - draggingElement.y;\n // Allows dots to avoid being flagged as infinitely small\n if (dx === points[0][0] && dy === points[0][1]) {\n dy += 0.0001;\n dx += 0.0001;\n }\n const pressures = draggingElement.simulatePressure\n ? []\n : [...draggingElement.pressures, childEvent.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n lastCommittedPoint: [dx, dy],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\n const imageElement = draggingElement;\n try {\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n catch (error) {\n console.error(error);\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== imageElement.id));\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n if (draggingElement.points.length > 1) {\n this.history.resumeRecording();\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n if (!pointerDownState.drag.hasOccurred &&\n draggingElement &&\n !multiElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [\n ...draggingElement.points,\n [\n pointerCoords.x - draggingElement.x,\n pointerCoords.y - draggingElement.y,\n ],\n ],\n });\n this.setState({\n multiElement: draggingElement,\n editingElement: this.state.draggingElement,\n });\n }\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\n }\n this.setState({ suggestedBindings: [], startBoundElement: null });\n if (!activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState((prevState) => ({\n draggingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, {\n type: \"selection\",\n }),\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(draggingElement, this.scene),\n }));\n }\n else {\n this.setState((prevState) => ({\n draggingElement: null,\n }));\n }\n }\n return;\n }\n if (activeTool.type !== \"selection\" &&\n draggingElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\n // remove invisible element which was added in onPointerDown\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\n this.setState({\n draggingElement: null,\n });\n return;\n }\n if (draggingElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\n }\n if (resizingElement) {\n this.history.resumeRecording();\n }\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== resizingElement.id));\n }\n // Code below handles selection when element(s) weren't\n // drag or added to selection on pointer down phase.\n const hitElement = pointerDownState.hit.element;\n if (((_e = this.state.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.elementId) !== (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement)) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement when no other element selected except\n // the one we've hit\n if (selectedELements.length === 1) {\n this.setState({\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene),\n });\n }\n }\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (draggedDistance === 0) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({\n clientX: this.lastPointerUp.clientX,\n clientY: this.lastPointerUp.clientY,\n }, this.state);\n const hitElements = this.getElementsAtPosition(scenePointer.x, scenePointer.y);\n hitElements.forEach((hitElement) => (pointerDownState.elementIdsToErase[hitElement.id] = {\n erase: true,\n opacity: hitElement.opacity,\n }));\n }\n this.eraseElements(pointerDownState);\n return;\n }\n else if (Object.keys(pointerDownState.elementIdsToErase).length) {\n this.restoreReadyToEraseElements(pointerDownState);\n }\n if (hitElement &&\n !pointerDownState.drag.hasOccurred &&\n !pointerDownState.hit.wasAddedToSelection &&\n // if we're editing a line, pointerup shouldn't switch selection if\n // box selected\n (!this.state.editingLinearElement ||\n !pointerDownState.boxSelection.hasOccurred)) {\n // when inside line editor, shift selects points instead\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\n if (this.state.selectedElementIds[hitElement.id]) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\n // We want to unselect all groups hitElement is part of\n // as well as all elements that are part of the groups\n // hitElement is part of\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), groupId))\n .map((element) => ({ [element.id]: false }))\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\n this.setState((_prevState) => ({\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\n .map((gId) => ({ [gId]: false }))\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\n }));\n // if not gragging a linear element point (outside editor)\n }\n else if (!((_f = this.state.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isDragging)) {\n // remove element from selection while\n // keeping prev elements selected\n this.setState((prevState) => {\n const newSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false });\n const newSelectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds }));\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds, \n // set selectedLinearElement only if thats the only element selected\n selectedLinearElement: newSelectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(newSelectedElements[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(newSelectedElements[0], this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements());\n });\n }\n }\n else {\n // add element to selection while\n // keeping prev elements selected\n this.setState((_prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\n }));\n }\n }\n else {\n this.setState((prevState) => {\n var _a;\n return (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement) &&\n // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.\n // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized\n ((_a = prevState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements())));\n });\n }\n }\n if (!pointerDownState.drag.hasOccurred &&\n !this.state.isResizing &&\n ((hitElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\n (!hitElement &&\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: null });\n }\n else {\n // Deselect selected elements\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n return;\n }\n if (!activeTool.locked &&\n activeTool.type !== \"freedraw\" &&\n draggingElement) {\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n }));\n }\n if (activeTool.type !== \"selection\" ||\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getNonDeletedElements(), this.state)) {\n this.history.resumeRecording();\n }\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state));\n }\n if (!activeTool.locked && activeTool.type !== \"freedraw\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n else {\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n });\n }\n });\n }\n maybeSuggestBindingForAll(selectedElements) {\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\n this.setState({ suggestedBindings });\n }\n clearSelection(hitElement) {\n this.setState((prevState) => ({\n selectedElementIds: {},\n selectedGroupIds: {},\n // Continue editing the same group if the user selected a different\n // element from it\n editingGroupId: prevState.editingGroupId &&\n hitElement != null &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\n ? prevState.editingGroupId\n : null,\n }));\n this.setState({\n selectedElementIds: {},\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n getTextWysiwygSnappedToCenterPosition(x, y, appState, container) {\n if (container) {\n let elementCenterX = container.x + container.width / 2;\n let elementCenterY = container.y + container.height / 2;\n const elementCenter = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getContainerCenter)(container, appState);\n if (elementCenter) {\n elementCenterX = elementCenter.x;\n elementCenterY = elementCenter.y;\n }\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_12__.TEXT_TO_CENTER_SNAP_THRESHOLD;\n if (isSnappedToCenter) {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\n return { viewportX, viewportY, elementCenterX, elementCenterY };\n }\n }\n }\n getCanvasOffsets() {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { left, top } = excalidrawContainer.getBoundingClientRect();\n return {\n offsetLeft: left,\n offsetTop: top,\n };\n }\n return {\n offsetLeft: 0,\n offsetTop: 0,\n };\n }\n updateLanguage() {\n return __awaiter(this, void 0, void 0, function* () {\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\n this.setAppState({});\n });\n }\n}\nApp.defaultProps = {\n // needed for tests to pass since we directly render App in many tests\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_UI_OPTIONS,\n};\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT) {\n window.h = window.h || {};\n Object.defineProperties(window.h, {\n elements: {\n configurable: true,\n get() {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.getElementsIncludingDeleted();\n },\n set(elements) {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.replaceAllElements(elements);\n },\n },\n });\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LHdEQUFlLEVBQ3hDO0lBQ0EsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxJQUFLLEVBQWtCLENBQUM7SUFFM0MsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7UUFDaEMsUUFBUSxFQUFFO1lBQ1IsWUFBWSxFQUFFLElBQUk7WUFDbEIsR0FBRzs7Z0JBQ0QsT0FBTyxVQUFJLENBQUMsR0FBRywwQ0FBRSxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztZQUN2RCxDQUFDO1lBQ0QsR0FBRyxDQUFDLFFBQTZCOztnQkFDL0IsT0FBTyxVQUFJLENBQUMsR0FBRywwQ0FBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdEQsQ0FBQztTQUNGO0tBQ0YsQ0FBQyxDQUFDO0NBQ0o7QUFFRCxpRUFBZSxHQUFHLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vY29tcG9uZW50cy9BcHAudHN4PzAwNzAiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHVzZUNvbnRleHQgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IGZsdXNoU3luYyB9IGZyb20gXCJyZWFjdC1kb21cIjtcblxuaW1wb3J0IHsgUm91Z2hDYW52YXMgfSBmcm9tIFwicm91Z2hqcy9iaW4vY2FudmFzXCI7XG5pbXBvcnQgcm91Z2ggZnJvbSBcInJvdWdoanMvYmluL3JvdWdoXCI7XG5pbXBvcnQgY2xzeCBmcm9tIFwiY2xzeFwiO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSBcIm5hbm9pZFwiO1xuXG5pbXBvcnQge1xuICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICBhY3Rpb25Db3B5LFxuICBhY3Rpb25Db3B5QXNQbmcsXG4gIGFjdGlvbkNvcHlBc1N2ZyxcbiAgY29weVRleHQsXG4gIGFjdGlvbkNvcHlTdHlsZXMsXG4gIGFjdGlvbkN1dCxcbiAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgYWN0aW9uRmluYWxpemUsXG4gIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICBhY3Rpb25GbGlwVmVydGljYWwsXG4gIGFjdGlvbkdyb3VwLFxuICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgYWN0aW9uU2VsZWN0QWxsLFxuICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gIGFjdGlvblNlbmRUb0JhY2ssXG4gIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgYWN0aW9uVW5iaW5kVGV4dCxcbiAgYWN0aW9uQmluZFRleHQsXG4gIGFjdGlvblVuZ3JvdXAsXG4gIGFjdGlvbkxpbmssXG4gIGFjdGlvblRvZ2dsZUVsZW1lbnRMb2NrLFxuICBhY3Rpb25Ub2dnbGVMaW5lYXJFZGl0b3IsXG59IGZyb20gXCIuLi9hY3Rpb25zXCI7XG5pbXBvcnQgeyBjcmVhdGVSZWRvQWN0aW9uLCBjcmVhdGVVbmRvQWN0aW9uIH0gZnJvbSBcIi4uL2FjdGlvbnMvYWN0aW9uSGlzdG9yeVwiO1xuaW1wb3J0IHsgQWN0aW9uTWFuYWdlciB9IGZyb20gXCIuLi9hY3Rpb25zL21hbmFnZXJcIjtcbmltcG9ydCB7IGFjdGlvbnMgfSBmcm9tIFwiLi4vYWN0aW9ucy9yZWdpc3RlclwiO1xuaW1wb3J0IHsgQWN0aW9uUmVzdWx0IH0gZnJvbSBcIi4uL2FjdGlvbnMvdHlwZXNcIjtcbmltcG9ydCB7IHRyYWNrRXZlbnQgfSBmcm9tIFwiLi4vYW5hbHl0aWNzXCI7XG5pbXBvcnQge1xuICBnZXREZWZhdWx0QXBwU3RhdGUsXG4gIGlzRXJhc2VyQWN0aXZlLFxuICBpc0hhbmRUb29sQWN0aXZlLFxufSBmcm9tIFwiLi4vYXBwU3RhdGVcIjtcbmltcG9ydCB7IHBhcnNlQ2xpcGJvYXJkIH0gZnJvbSBcIi4uL2NsaXBib2FyZFwiO1xuaW1wb3J0IHtcbiAgQVBQX05BTUUsXG4gIENVUlNPUl9UWVBFLFxuICBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gIERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgRFJBR0dJTkdfVEhSRVNIT0xELFxuICBFTEVNRU5UX1JFQURZX1RPX0VSQVNFX09QQUNJVFksXG4gIEVMRU1FTlRfU0hJRlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5ULFxuICBFTlYsXG4gIEVWRU5ULFxuICBFWFBPUlRfSU1BR0VfVFlQRVMsXG4gIEdSSURfU0laRSxcbiAgSU1BR0VfTUlNRV9UWVBFUyxcbiAgSU1BR0VfUkVOREVSX1RJTUVPVVQsXG4gIGlzQW5kcm9pZCxcbiAgaXNCcmF2ZSxcbiAgTElORV9DT05GSVJNX1RIUkVTSE9MRCxcbiAgTUFYX0FMTE9XRURfRklMRV9CWVRFUyxcbiAgTUlNRV9UWVBFUyxcbiAgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9QT1JUUkFJVCxcbiAgTVFfUklHSFRfU0lERUJBUl9NSU5fV0lEVEgsXG4gIE1RX1NNX01BWF9XSURUSCxcbiAgUE9JTlRFUl9CVVRUT04sXG4gIFJPVU5ETkVTUyxcbiAgU0NST0xMX1RJTUVPVVQsXG4gIFRBUF9UV0lDRV9USU1FT1VULFxuICBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRCxcbiAgVEhFTUUsXG4gIFRPVUNIX0NUWF9NRU5VX1RJTUVPVVQsXG4gIFZFUlRJQ0FMX0FMSUdOLFxuICBaT09NX1NURVAsXG59IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGV4cG9ydEFzSW1hZ2UsIGxvYWRGcm9tQmxvYiB9IGZyb20gXCIuLi9kYXRhXCI7XG5pbXBvcnQgTGlicmFyeSwgeyBkaXN0cmlidXRlTGlicmFyeUl0ZW1zT25TcXVhcmVHcmlkIH0gZnJvbSBcIi4uL2RhdGEvbGlicmFyeVwiO1xuaW1wb3J0IHsgcmVzdG9yZSwgcmVzdG9yZUVsZW1lbnRzIH0gZnJvbSBcIi4uL2RhdGEvcmVzdG9yZVwiO1xuaW1wb3J0IHtcbiAgZHJhZ05ld0VsZW1lbnQsXG4gIGRyYWdTZWxlY3RlZEVsZW1lbnRzLFxuICBkdXBsaWNhdGVFbGVtZW50LFxuICBnZXRDb21tb25Cb3VuZHMsXG4gIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCxcbiAgZ2V0RHJhZ09mZnNldFhZLFxuICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gIGdldE5vcm1hbGl6ZWREaW1lbnNpb25zLFxuICBnZXRSZXNpemVBcnJvd0RpcmVjdGlvbixcbiAgZ2V0UmVzaXplT2Zmc2V0WFksXG4gIGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZSxcbiAgZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMsXG4gIGhpdFRlc3QsXG4gIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudCxcbiAgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQsXG4gIGlzTm9uRGVsZXRlZEVsZW1lbnQsXG4gIGlzVGV4dEVsZW1lbnQsXG4gIG5ld0VsZW1lbnQsXG4gIG5ld0xpbmVhckVsZW1lbnQsXG4gIG5ld1RleHRFbGVtZW50LFxuICBuZXdJbWFnZUVsZW1lbnQsXG4gIHRleHRXeXNpd3lnLFxuICB0cmFuc2Zvcm1FbGVtZW50cyxcbiAgdXBkYXRlVGV4dEVsZW1lbnQsXG4gIHJlZHJhd1RleHRCb3VuZGluZ0JveCxcbn0gZnJvbSBcIi4uL2VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGJpbmRPclVuYmluZExpbmVhckVsZW1lbnQsXG4gIGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMsXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbixcbiAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uLFxuICBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyxcbiAgZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nLFxuICBpc0JpbmRpbmdFbmFibGVkLFxuICBpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQsXG4gIG1heWJlQmluZExpbmVhckVsZW1lbnQsXG4gIHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQsXG4gIHVuYmluZExpbmVhckVsZW1lbnRzLFxuICB1cGRhdGVCb3VuZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZWxlbWVudC9iaW5kaW5nXCI7XG5pbXBvcnQgeyBMaW5lYXJFbGVtZW50RWRpdG9yIH0gZnJvbSBcIi4uL2VsZW1lbnQvbGluZWFyRWxlbWVudEVkaXRvclwiO1xuaW1wb3J0IHsgbXV0YXRlRWxlbWVudCwgbmV3RWxlbWVudFdpdGggfSBmcm9tIFwiLi4vZWxlbWVudC9tdXRhdGVFbGVtZW50XCI7XG5pbXBvcnQge1xuICBkZWVwQ29weUVsZW1lbnQsXG4gIGR1cGxpY2F0ZUVsZW1lbnRzLFxuICBuZXdGcmVlRHJhd0VsZW1lbnQsXG59IGZyb20gXCIuLi9lbGVtZW50L25ld0VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGhhc0JvdW5kVGV4dEVsZW1lbnQsXG4gIGlzQXJyb3dFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50VHlwZSxcbiAgaXNCb3VuZFRvQ29udGFpbmVyLFxuICBpc0ltYWdlRWxlbWVudCxcbiAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50LFxuICBpc0xpbmVhckVsZW1lbnRUeXBlLFxuICBpc1VzaW5nQWRhcHRpdmVSYWRpdXMsXG59IGZyb20gXCIuLi9lbGVtZW50L3R5cGVDaGVja3NcIjtcbmltcG9ydCB7XG4gIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50LFxuICBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gIE5vbkRlbGV0ZWQsXG4gIEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgRmlsZUlkLFxuICBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0Q2VudGVyLCBnZXREaXN0YW5jZSB9IGZyb20gXCIuLi9nZXN0dXJlXCI7XG5pbXBvcnQge1xuICBlZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQsXG4gIGdldEVsZW1lbnRzSW5Hcm91cCxcbiAgZ2V0U2VsZWN0ZWRHcm91cElkRm9yRWxlbWVudCxcbiAgZ2V0U2VsZWN0ZWRHcm91cElkcyxcbiAgaXNFbGVtZW50SW5Hcm91cCxcbiAgaXNTZWxlY3RlZFZpYUdyb3VwLFxuICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZ3JvdXBzXCI7XG5pbXBvcnQgSGlzdG9yeSBmcm9tIFwiLi4vaGlzdG9yeVwiO1xuaW1wb3J0IHsgZGVmYXVsdExhbmcsIGdldExhbmd1YWdlLCBsYW5ndWFnZXMsIHNldExhbmd1YWdlLCB0IH0gZnJvbSBcIi4uL2kxOG5cIjtcbmltcG9ydCB7XG4gIENPREVTLFxuICBzaG91bGRSZXNpemVGcm9tQ2VudGVyLFxuICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvLFxuICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZSxcbiAgaXNBcnJvd0tleSxcbiAgS0VZUyxcbn0gZnJvbSBcIi4uL2tleXNcIjtcbmltcG9ydCB7IGRpc3RhbmNlMmQsIGdldEdyaWRQb2ludCwgaXNQYXRoQUxvb3AgfSBmcm9tIFwiLi4vbWF0aFwiO1xuaW1wb3J0IHsgcmVuZGVyU2NlbmUgfSBmcm9tIFwiLi4vcmVuZGVyZXIvcmVuZGVyU2NlbmVcIjtcbmltcG9ydCB7XG4gIGNsZWFyUmVuZGVyQ2FjaGUsXG4gIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQsXG59IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJFbGVtZW50XCI7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVTY3JvbGxDZW50ZXIsXG4gIGdldEVsZW1lbnRzQXRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24sXG4gIGdldE5vcm1hbGl6ZWRab29tLFxuICBnZXRTZWxlY3RlZEVsZW1lbnRzLFxuICBoYXNCYWNrZ3JvdW5kLFxuICBpc092ZXJTY3JvbGxCYXJzLFxuICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQsXG59IGZyb20gXCIuLi9zY2VuZVwiO1xuaW1wb3J0IFNjZW5lIGZyb20gXCIuLi9zY2VuZS9TY2VuZVwiO1xuaW1wb3J0IHsgUmVuZGVyQ29uZmlnLCBTY3JvbGxCYXJzIH0gZnJvbSBcIi4uL3NjZW5lL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRTdGF0ZUZvclpvb20gfSBmcm9tIFwiLi4vc2NlbmUvem9vbVwiO1xuaW1wb3J0IHsgZmluZFNoYXBlQnlLZXksIFNIQVBFUyB9IGZyb20gXCIuLi9zaGFwZXNcIjtcbmltcG9ydCB7XG4gIEFwcENsYXNzUHJvcGVydGllcyxcbiAgQXBwUHJvcHMsXG4gIEFwcFN0YXRlLFxuICBCaW5hcnlGaWxlRGF0YSxcbiAgRGF0YVVSTCxcbiAgRXhjYWxpZHJhd0ltcGVyYXRpdmVBUEksXG4gIEJpbmFyeUZpbGVzLFxuICBHZXN0dXJlLFxuICBHZXN0dXJlRXZlbnQsXG4gIExpYnJhcnlJdGVtcyxcbiAgUG9pbnRlckRvd25TdGF0ZSxcbiAgU2NlbmVEYXRhLFxuICBEZXZpY2UsXG4gIFNpZGViYXJOYW1lLFxuICBTaWRlYmFyVGFiTmFtZSxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBkZWJvdW5jZSxcbiAgZGlzdGFuY2UsXG4gIGdldEZvbnRTdHJpbmcsXG4gIGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLFxuICBpc0lucHV0TGlrZSxcbiAgaXNUb29sSWNvbixcbiAgaXNXcml0YWJsZUVsZW1lbnQsXG4gIHJlc2V0Q3Vyc29yLFxuICByZXNvbHZhYmxlUHJvbWlzZSxcbiAgc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzLFxuICBzZXRDdXJzb3IsXG4gIHNldEN1cnNvckZvclNoYXBlLFxuICB0dXBsZVRvQ29vcnMsXG4gIHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyxcbiAgd2l0aEJhdGNoZWRVcGRhdGVzLFxuICB3cmFwRXZlbnQsXG4gIHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCxcbiAgdXBkYXRlT2JqZWN0LFxuICBzZXRFcmFzZXJDdXJzb3IsXG4gIHVwZGF0ZUFjdGl2ZVRvb2wsXG4gIGdldFNob3J0Y3V0S2V5LFxuICBpc1RyYW5zcGFyZW50LFxuICBlYXNlVG9WYWx1ZXNSQUYsXG4gIG11dGVGU0Fib3J0RXJyb3IsXG59IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgQ29udGV4dE1lbnUsXG4gIENvbnRleHRNZW51SXRlbXMsXG4gIENPTlRFWFRfTUVOVV9TRVBBUkFUT1IsXG59IGZyb20gXCIuL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgTGF5ZXJVSSBmcm9tIFwiLi9MYXllclVJXCI7XG5pbXBvcnQgeyBUb2FzdCB9IGZyb20gXCIuL1RvYXN0XCI7XG5pbXBvcnQgeyBhY3Rpb25Ub2dnbGVWaWV3TW9kZSB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvblRvZ2dsZVZpZXdNb2RlXCI7XG5pbXBvcnQge1xuICBkYXRhVVJMVG9GaWxlLFxuICBnZW5lcmF0ZUlkRnJvbUZpbGUsXG4gIGdldERhdGFVUkwsXG4gIGdldEZpbGVGcm9tRXZlbnQsXG4gIGlzSW1hZ2VGaWxlSGFuZGxlLFxuICBpc1N1cHBvcnRlZEltYWdlRmlsZSxcbiAgbG9hZFNjZW5lT3JMaWJyYXJ5RnJvbUJsb2IsXG4gIG5vcm1hbGl6ZUZpbGUsXG4gIHBhcnNlTGlicmFyeUpTT04sXG4gIHJlc2l6ZUltYWdlRmlsZSxcbiAgU1ZHU3RyaW5nVG9GaWxlLFxufSBmcm9tIFwiLi4vZGF0YS9ibG9iXCI7XG5pbXBvcnQge1xuICBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMsXG4gIGxvYWRIVE1MSW1hZ2VFbGVtZW50LFxuICBub3JtYWxpemVTVkcsXG4gIHVwZGF0ZUltYWdlQ2FjaGUgYXMgX3VwZGF0ZUltYWdlQ2FjaGUsXG59IGZyb20gXCIuLi9lbGVtZW50L2ltYWdlXCI7XG5pbXBvcnQgdGhyb3R0bGUgZnJvbSBcImxvZGFzaC50aHJvdHRsZVwiO1xuaW1wb3J0IHsgZmlsZU9wZW4sIEZpbGVTeXN0ZW1IYW5kbGUgfSBmcm9tIFwiLi4vZGF0YS9maWxlc3lzdGVtXCI7XG5pbXBvcnQge1xuICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uLFxuICBnZXRBcHByb3hNaW5MaW5lSGVpZ2h0LFxuICBnZXRBcHByb3hNaW5MaW5lV2lkdGgsXG4gIGdldEJvdW5kVGV4dEVsZW1lbnQsXG4gIGdldENvbnRhaW5lckNlbnRlcixcbiAgZ2V0Q29udGFpbmVyRGltcyxcbiAgZ2V0Q29udGFpbmVyRWxlbWVudCxcbiAgZ2V0RGVmYXVsdExpbmVIZWlnaHQsXG4gIGdldExpbmVIZWlnaHRJblB4LFxuICBnZXRUZXh0QmluZGFibGVDb250YWluZXJBdFBvc2l0aW9uLFxuICBpc01lYXN1cmVUZXh0U3VwcG9ydGVkLFxuICBpc1ZhbGlkVGV4dENvbnRhaW5lcixcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdGV4dEVsZW1lbnRcIjtcbmltcG9ydCB7IGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94IH0gZnJvbSBcIi4uL2VsZW1lbnQvY29sbGlzaW9uXCI7XG5pbXBvcnQge1xuICBub3JtYWxpemVMaW5rLFxuICBzaG93SHlwZXJsaW5rVG9vbHRpcCxcbiAgaGlkZUh5cGVybGlua1Rvb2xpcCxcbiAgSHlwZXJsaW5rLFxuICBpc1BvaW50SGl0dGluZ0xpbmtJY29uLFxuICBpc0xvY2FsTGluayxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvSHlwZXJsaW5rXCI7XG5pbXBvcnQgeyBzaG91bGRTaG93Qm91bmRpbmdCb3ggfSBmcm9tIFwiLi4vZWxlbWVudC90cmFuc2Zvcm1IYW5kbGVzXCI7XG5pbXBvcnQgeyBhY3Rpb25VbmxvY2tBbGxFbGVtZW50cyB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvbkVsZW1lbnRMb2NrXCI7XG5pbXBvcnQgeyBGb250cyB9IGZyb20gXCIuLi9zY2VuZS9Gb250c1wiO1xuaW1wb3J0IHsgYWN0aW9uUGFzdGUgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25DbGlwYm9hcmRcIjtcbmltcG9ydCB7XG4gIGFjdGlvblRvZ2dsZUhhbmRUb29sLFxuICB6b29tVG9GaXRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2FjdGlvbnMvYWN0aW9uQ2FudmFzXCI7XG5pbXBvcnQgeyBqb3RhaVN0b3JlIH0gZnJvbSBcIi4uL2pvdGFpXCI7XG5pbXBvcnQgeyBhY3RpdmVDb25maXJtRGlhbG9nQXRvbSB9IGZyb20gXCIuL0FjdGl2ZUNvbmZpcm1EaWFsb2dcIjtcbmltcG9ydCB7IGFjdGlvbldyYXBUZXh0SW5Db250YWluZXIgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25Cb3VuZFRleHRcIjtcbmltcG9ydCBCcmF2ZU1lYXN1cmVUZXh0RXJyb3IgZnJvbSBcIi4vQnJhdmVNZWFzdXJlVGV4dEVycm9yXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL2VtaXR0ZXJcIjtcblxuY29uc3QgQXBwQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8QXBwQ2xhc3NQcm9wZXJ0aWVzPihudWxsISk7XG5jb25zdCBBcHBQcm9wc0NvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PEFwcFByb3BzPihudWxsISk7XG5cbmNvbnN0IGRldmljZUNvbnRleHRJbml0aWFsVmFsdWUgPSB7XG4gIGlzU21TY3JlZW46IGZhbHNlLFxuICBpc01vYmlsZTogZmFsc2UsXG4gIGlzVG91Y2hTY3JlZW46IGZhbHNlLFxuICBjYW5EZXZpY2VGaXRTaWRlYmFyOiBmYWxzZSxcbiAgaXNMYW5kc2NhcGU6IGZhbHNlLFxufTtcbmNvbnN0IERldmljZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PERldmljZT4oZGV2aWNlQ29udGV4dEluaXRpYWxWYWx1ZSk7XG5EZXZpY2VDb250ZXh0LmRpc3BsYXlOYW1lID0gXCJEZXZpY2VDb250ZXh0XCI7XG5cbmV4cG9ydCBjb25zdCBFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8e1xuICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgaWQ/OiBzdHJpbmcgfCBudWxsO1xufT4oeyBjb250YWluZXI6IG51bGwsIGlkOiBudWxsIH0pO1xuRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuZGlzcGxheU5hbWUgPSBcIkV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0XCI7XG5cbmNvbnN0IEV4Y2FsaWRyYXdFbGVtZW50c0NvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PFxuICByZWFkb25seSBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnRbXVxuPihbXSk7XG5FeGNhbGlkcmF3RWxlbWVudHNDb250ZXh0LmRpc3BsYXlOYW1lID0gXCJFeGNhbGlkcmF3RWxlbWVudHNDb250ZXh0XCI7XG5cbmNvbnN0IEV4Y2FsaWRyYXdBcHBTdGF0ZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PEFwcFN0YXRlPih7XG4gIC4uLmdldERlZmF1bHRBcHBTdGF0ZSgpLFxuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwLFxuICBvZmZzZXRMZWZ0OiAwLFxuICBvZmZzZXRUb3A6IDAsXG59KTtcbkV4Y2FsaWRyYXdBcHBTdGF0ZUNvbnRleHQuZGlzcGxheU5hbWUgPSBcIkV4Y2FsaWRyYXdBcHBTdGF0ZUNvbnRleHRcIjtcblxuY29uc3QgRXhjYWxpZHJhd1NldEFwcFN0YXRlQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8XG4gIFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdXG4+KCgpID0+IHtcbiAgY29uc29sZS53YXJuKFwidW5pdGlhbGl6ZWQgRXhjYWxpZHJhd1NldEFwcFN0YXRlQ29udGV4dCBjb250ZXh0IVwiKTtcbn0pO1xuRXhjYWxpZHJhd1NldEFwcFN0YXRlQ29udGV4dC5kaXNwbGF5TmFtZSA9IFwiRXhjYWxpZHJhd1NldEFwcFN0YXRlQ29udGV4dFwiO1xuXG5jb25zdCBFeGNhbGlkcmF3QWN0aW9uTWFuYWdlckNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PEFjdGlvbk1hbmFnZXI+KFxuICBudWxsISxcbik7XG5FeGNhbGlkcmF3QWN0aW9uTWFuYWdlckNvbnRleHQuZGlzcGxheU5hbWUgPSBcIkV4Y2FsaWRyYXdBY3Rpb25NYW5hZ2VyQ29udGV4dFwiO1xuXG5leHBvcnQgY29uc3QgdXNlQXBwID0gKCkgPT4gdXNlQ29udGV4dChBcHBDb250ZXh0KTtcbmV4cG9ydCBjb25zdCB1c2VBcHBQcm9wcyA9ICgpID0+IHVzZUNvbnRleHQoQXBwUHJvcHNDb250ZXh0KTtcbmV4cG9ydCBjb25zdCB1c2VEZXZpY2UgPSAoKSA9PiB1c2VDb250ZXh0PERldmljZT4oRGV2aWNlQ29udGV4dCk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd0NvbnRhaW5lciA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQpO1xuZXhwb3J0IGNvbnN0IHVzZUV4Y2FsaWRyYXdFbGVtZW50cyA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0VsZW1lbnRzQ29udGV4dCk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd0FwcFN0YXRlID0gKCkgPT5cbiAgdXNlQ29udGV4dChFeGNhbGlkcmF3QXBwU3RhdGVDb250ZXh0KTtcbmV4cG9ydCBjb25zdCB1c2VFeGNhbGlkcmF3U2V0QXBwU3RhdGUgPSAoKSA9PlxuICB1c2VDb250ZXh0KEV4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHQpO1xuZXhwb3J0IGNvbnN0IHVzZUV4Y2FsaWRyYXdBY3Rpb25NYW5hZ2VyID0gKCkgPT5cbiAgdXNlQ29udGV4dChFeGNhbGlkcmF3QWN0aW9uTWFuYWdlckNvbnRleHQpO1xuXG5sZXQgZGlkVGFwVHdpY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCB0YXBwZWRUd2ljZVRpbWVyID0gMDtcbmxldCBjdXJzb3JYID0gMDtcbmxldCBjdXJzb3JZID0gMDtcbmxldCBpc0hvbGRpbmdTcGFjZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzUGFubmluZzogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzRHJhZ2dpbmdTY3JvbGxCYXI6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBjdXJyZW50U2Nyb2xsQmFyczogU2Nyb2xsQmFycyA9IHsgaG9yaXpvbnRhbDogbnVsbCwgdmVydGljYWw6IG51bGwgfTtcbmxldCB0b3VjaFRpbWVvdXQgPSAwO1xubGV0IGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG4vLyByZW1vdmUgdGhpcyBoYWNrIHdoZW4gd2UgY2FuIHN5bmMgcmVuZGVyICYgcmVzaXplT2JzZXJ2ZXIgKHN0YXRlIHVwZGF0ZSlcbi8vIHRvIHJBRi4gU2VlICM1NDM5XG5sZXQgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSB0cnVlO1xuXG5sZXQgSVNfUExBSU5fUEFTVEUgPSBmYWxzZTtcbmxldCBJU19QTEFJTl9QQVNURV9USU1FUiA9IDA7XG5sZXQgUExBSU5fUEFTVEVfVE9BU1RfU0hPV04gPSBmYWxzZTtcblxubGV0IGxhc3RQb2ludGVyVXA6ICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbmNvbnN0IGdlc3R1cmU6IEdlc3R1cmUgPSB7XG4gIHBvaW50ZXJzOiBuZXcgTWFwKCksXG4gIGxhc3RDZW50ZXI6IG51bGwsXG4gIGluaXRpYWxEaXN0YW5jZTogbnVsbCxcbiAgaW5pdGlhbFNjYWxlOiBudWxsLFxufTtcblxuY2xhc3MgQXBwIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PEFwcFByb3BzLCBBcHBTdGF0ZT4ge1xuICBjYW52YXM6IEFwcENsYXNzUHJvcGVydGllc1tcImNhbnZhc1wiXSA9IG51bGw7XG4gIHJjOiBSb3VnaENhbnZhcyB8IG51bGwgPSBudWxsO1xuICB1bm1vdW50ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYWN0aW9uTWFuYWdlcjogQWN0aW9uTWFuYWdlcjtcbiAgZGV2aWNlOiBEZXZpY2UgPSBkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlO1xuICBkZXRhY2hJc01vYmlsZU1xSGFuZGxlcj86ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBleGNhbGlkcmF3Q29udGFpbmVyUmVmID0gUmVhY3QuY3JlYXRlUmVmPEhUTUxEaXZFbGVtZW50PigpO1xuXG4gIHB1YmxpYyBzdGF0aWMgZGVmYXVsdFByb3BzOiBQYXJ0aWFsPEFwcFByb3BzPiA9IHtcbiAgICAvLyBuZWVkZWQgZm9yIHRlc3RzIHRvIHBhc3Mgc2luY2Ugd2UgZGlyZWN0bHkgcmVuZGVyIEFwcCBpbiBtYW55IHRlc3RzXG4gICAgVUlPcHRpb25zOiBERUZBVUxUX1VJX09QVElPTlMsXG4gIH07XG5cbiAgcHVibGljIHNjZW5lOiBTY2VuZTtcbiAgcHJpdmF0ZSBmb250czogRm9udHM7XG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyOiBIVE1MRWxlbWVudCB8IERvY3VtZW50IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgbGlicmFyeTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wibGlicmFyeVwiXTtcbiAgcHVibGljIGxpYnJhcnlJdGVtc0Zyb21TdG9yYWdlOiBMaWJyYXJ5SXRlbXMgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyBpZDogc3RyaW5nO1xuICBwcml2YXRlIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gIHByaXZhdGUgZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlOiB7XG4gICAgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG4gICAgaWQ6IHN0cmluZztcbiAgfTtcblxuICBwdWJsaWMgZmlsZXM6IEJpbmFyeUZpbGVzID0ge307XG4gIHB1YmxpYyBpbWFnZUNhY2hlOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJpbWFnZUNhY2hlXCJdID0gbmV3IE1hcCgpO1xuXG4gIGhpdExpbmtFbGVtZW50PzogTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50O1xuICBsYXN0UG9pbnRlckRvd246IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4gfCBudWxsID0gbnVsbDtcbiAgbGFzdFBvaW50ZXJVcDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxFbGVtZW50PiB8IFBvaW50ZXJFdmVudCB8IG51bGwgPSBudWxsO1xuICBsYXN0U2NlbmVQb2ludGVyOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcblxuICBvbkNoYW5nZUVtaXR0ZXIgPSBuZXcgRW1pdHRlcjxcbiAgICBbXG4gICAgICBlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXSxcbiAgICAgIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgICAgIGZpbGVzOiBCaW5hcnlGaWxlcyxcbiAgICBdXG4gID4oKTtcblxuICBvblBvaW50ZXJEb3duRW1pdHRlciA9IG5ldyBFbWl0dGVyPFxuICAgIFtcbiAgICAgIGFjdGl2ZVRvb2w6IEFwcFN0YXRlW1wiYWN0aXZlVG9vbFwiXSxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBdXG4gID4oKTtcblxuICBvblBvaW50ZXJVcEVtaXR0ZXIgPSBuZXcgRW1pdHRlcjxcbiAgICBbXG4gICAgICBhY3RpdmVUb29sOiBBcHBTdGF0ZVtcImFjdGl2ZVRvb2xcIl0sXG4gICAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBdXG4gID4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQXBwUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG4gICAgY29uc3Qge1xuICAgICAgZXhjYWxpZHJhd1JlZixcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgemVuTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIGdyaWRNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgdGhlbWUgPSBkZWZhdWx0QXBwU3RhdGUudGhlbWUsXG4gICAgICBuYW1lID0gZGVmYXVsdEFwcFN0YXRlLm5hbWUsXG4gICAgfSA9IHByb3BzO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi5kZWZhdWx0QXBwU3RhdGUsXG4gICAgICB0aGVtZSxcbiAgICAgIGlzTG9hZGluZzogdHJ1ZSxcbiAgICAgIC4uLnRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpLFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICBncmlkU2l6ZTogZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIG5hbWUsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICAgIHNob3dIeXBlcmxpbmtQb3B1cDogZmFsc2UsXG4gICAgICBkZWZhdWx0U2lkZWJhckRvY2tlZFByZWZlcmVuY2U6IGZhbHNlLFxuICAgIH07XG5cbiAgICB0aGlzLmlkID0gbmFub2lkKCk7XG4gICAgdGhpcy5saWJyYXJ5ID0gbmV3IExpYnJhcnkodGhpcyk7XG4gICAgaWYgKGV4Y2FsaWRyYXdSZWYpIHtcbiAgICAgIGNvbnN0IHJlYWR5UHJvbWlzZSA9XG4gICAgICAgIChcImN1cnJlbnRcIiBpbiBleGNhbGlkcmF3UmVmICYmIGV4Y2FsaWRyYXdSZWYuY3VycmVudD8ucmVhZHlQcm9taXNlKSB8fFxuICAgICAgICByZXNvbHZhYmxlUHJvbWlzZTxFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQST4oKTtcblxuICAgICAgY29uc3QgYXBpOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSA9IHtcbiAgICAgICAgcmVhZHk6IHRydWUsXG4gICAgICAgIHJlYWR5UHJvbWlzZSxcbiAgICAgICAgdXBkYXRlU2NlbmU6IHRoaXMudXBkYXRlU2NlbmUsXG4gICAgICAgIHVwZGF0ZUxpYnJhcnk6IHRoaXMubGlicmFyeS51cGRhdGVMaWJyYXJ5LFxuICAgICAgICBhZGRGaWxlczogdGhpcy5hZGRGaWxlcyxcbiAgICAgICAgcmVzZXRTY2VuZTogdGhpcy5yZXNldFNjZW5lLFxuICAgICAgICBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZDogdGhpcy5nZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNsZWFyOiB0aGlzLnJlc2V0SGlzdG9yeSxcbiAgICAgICAgfSxcbiAgICAgICAgc2Nyb2xsVG9Db250ZW50OiB0aGlzLnNjcm9sbFRvQ29udGVudCxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50czogdGhpcy5nZXRTY2VuZUVsZW1lbnRzLFxuICAgICAgICBnZXRBcHBTdGF0ZTogKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICAgZ2V0RmlsZXM6ICgpID0+IHRoaXMuZmlsZXMsXG4gICAgICAgIHJlZnJlc2g6IHRoaXMucmVmcmVzaCxcbiAgICAgICAgc2V0VG9hc3Q6IHRoaXMuc2V0VG9hc3QsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICBzZXRBY3RpdmVUb29sOiB0aGlzLnNldEFjdGl2ZVRvb2wsXG4gICAgICAgIHNldEN1cnNvcjogdGhpcy5zZXRDdXJzb3IsXG4gICAgICAgIHJlc2V0Q3Vyc29yOiB0aGlzLnJlc2V0Q3Vyc29yLFxuICAgICAgICBhcHA6IHRoaXMsXG4gICAgICAgIG9uQ2hhbmdlOiAoY2IpID0+IHRoaXMub25DaGFuZ2VFbWl0dGVyLm9uKGNiKSxcbiAgICAgICAgb25Qb2ludGVyRG93bjogKGNiKSA9PiB0aGlzLm9uUG9pbnRlckRvd25FbWl0dGVyLm9uKGNiKSxcbiAgICAgICAgb25Qb2ludGVyVXA6IChjYikgPT4gdGhpcy5vblBvaW50ZXJVcEVtaXR0ZXIub24oY2IpLFxuICAgICAgICB0b2dnbGVTaWRlYmFyOiB0aGlzLnRvZ2dsZVNpZGViYXIsXG4gICAgICB9IGFzIGNvbnN0O1xuICAgICAgaWYgKHR5cGVvZiBleGNhbGlkcmF3UmVmID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZXhjYWxpZHJhd1JlZihhcGkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhjYWxpZHJhd1JlZi5jdXJyZW50ID0gYXBpO1xuICAgICAgfVxuICAgICAgcmVhZHlQcm9taXNlLnJlc29sdmUoYXBpKTtcbiAgICB9XG5cbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZSA9IHtcbiAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQsXG4gICAgICBpZDogdGhpcy5pZCxcbiAgICB9O1xuXG4gICAgdGhpcy5zY2VuZSA9IG5ldyBTY2VuZSgpO1xuICAgIHRoaXMuZm9udHMgPSBuZXcgRm9udHMoe1xuICAgICAgc2NlbmU6IHRoaXMuc2NlbmUsXG4gICAgICBvblNjZW5lVXBkYXRlZDogdGhpcy5vblNjZW5lVXBkYXRlZCxcbiAgICB9KTtcbiAgICB0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeSgpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlciA9IG5ldyBBY3Rpb25NYW5hZ2VyKFxuICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0LFxuICAgICAgKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICgpID0+IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLFxuICAgICk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWxsKGFjdGlvbnMpO1xuXG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVVuZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVJlZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNhbnZhcygpIHtcbiAgICBjb25zdCBjYW52YXNTY2FsZSA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgIH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY2FudmFzRE9NV2lkdGggKiBjYW52YXNTY2FsZTtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjYW52YXNET01IZWlnaHQgKiBjYW52YXNTY2FsZTtcbiAgICBpZiAodmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Y2FudmFzXG4gICAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgICAgICBjdXJzb3I6IENVUlNPUl9UWVBFLkdSQUIsXG4gICAgICAgICAgfX1cbiAgICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlclVwfVxuICAgICAgICAgIG9uUG9pbnRlckNhbmNlbD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICAgIG9uVG91Y2hNb3ZlPXt0aGlzLmhhbmRsZVRvdWNoTW92ZX1cbiAgICAgICAgICBvblBvaW50ZXJEb3duPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJEb3dufVxuICAgICAgICA+XG4gICAgICAgICAge3QoXCJsYWJlbHMuZHJhd2luZ0NhbnZhc1wiKX1cbiAgICAgICAgPC9jYW52YXM+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgPGNhbnZhc1xuICAgICAgICBjbGFzc05hbWU9XCJleGNhbGlkcmF3X19jYW52YXNcIlxuICAgICAgICBzdHlsZT17e1xuICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgICAgfX1cbiAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICBoZWlnaHQ9e2NhbnZhc0hlaWdodH1cbiAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgb25Eb3VibGVDbGljaz17dGhpcy5oYW5kbGVDYW52YXNEb3VibGVDbGlja31cbiAgICAgICAgb25Qb2ludGVyTW92ZT17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyTW92ZX1cbiAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlclVwfVxuICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgPlxuICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgPC9jYW52YXM+XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZW5kZXIoKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgeyByZW5kZXJUb3BSaWdodFVJLCByZW5kZXJDdXN0b21TdGF0cyB9ID0gdGhpcy5wcm9wcztcblxuICAgIHJldHVybiAoXG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT17Y2xzeChcImV4Y2FsaWRyYXcgZXhjYWxpZHJhdy1jb250YWluZXJcIiwge1xuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tdmlldy1tb2RlXCI6IHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkLFxuICAgICAgICAgIFwiZXhjYWxpZHJhdy0temVuLW1vZGVcIjogdGhpcy5zdGF0ZS56ZW5Nb2RlRW5hYmxlZCxcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLW1vYmlsZVwiOiB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICAgICAgfSl9XG4gICAgICAgIHJlZj17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmfVxuICAgICAgICBvbkRyb3A9e3RoaXMuaGFuZGxlQXBwT25Ecm9wfVxuICAgICAgICB0YWJJbmRleD17MH1cbiAgICAgICAgb25LZXlEb3duPXtcbiAgICAgICAgICB0aGlzLnByb3BzLmhhbmRsZUtleWJvYXJkR2xvYmFsbHkgPyB1bmRlZmluZWQgOiB0aGlzLm9uS2V5RG93blxuICAgICAgICB9XG4gICAgICA+XG4gICAgICAgIDxBcHBDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzfT5cbiAgICAgICAgICA8QXBwUHJvcHNDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLnByb3BzfT5cbiAgICAgICAgICAgIDxFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlclxuICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWV9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxEZXZpY2VDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLmRldmljZX0+XG4gICAgICAgICAgICAgICAgPEV4Y2FsaWRyYXdTZXRBcHBTdGF0ZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3RoaXMuc2V0QXBwU3RhdGV9PlxuICAgICAgICAgICAgICAgICAgPEV4Y2FsaWRyYXdBcHBTdGF0ZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3RoaXMuc3RhdGV9PlxuICAgICAgICAgICAgICAgICAgICA8RXhjYWxpZHJhd0VsZW1lbnRzQ29udGV4dC5Qcm92aWRlclxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPEV4Y2FsaWRyYXdBY3Rpb25NYW5hZ2VyQ29udGV4dC5Qcm92aWRlclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuYWN0aW9uTWFuYWdlcn1cbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8TGF5ZXJVSVxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkV4cG9ydEltYWdlPXt0aGlzLm9uRXhwb3J0SW1hZ2V9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9uSG9tZUJ1dHRvbkNsaWNrPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uSG9tZUJ1dHRvbkNsaWNrIHx8ICgoKSA9PiB7fSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYW52YXM9e3RoaXMuY2FudmFzfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXM9e3RoaXMuZmlsZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25NYW5hZ2VyPXt0aGlzLmFjdGlvbk1hbmFnZXJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzPXt0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkxvY2tUb2dnbGU9e3RoaXMudG9nZ2xlTG9ja31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgb25QZW5Nb2RlVG9nZ2xlPXt0aGlzLnRvZ2dsZVBlbk1vZGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9uSGFuZFRvb2xUb2dnbGU9e3RoaXMub25IYW5kVG9vbFRvZ2dsZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZ0NvZGU9e2dldExhbmd1YWdlKCkuY29kZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyVG9wUmlnaHRVST17cmVuZGVyVG9wUmlnaHRVSX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tU3RhdHM9e3JlbmRlckN1c3RvbVN0YXRzfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93RXhpdFplbk1vZGVCdG49e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzPy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuemVuTW9kZUVuYWJsZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBVSU9wdGlvbnM9e3RoaXMucHJvcHMuVUlPcHRpb25zfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBvbkltYWdlQWN0aW9uPXt0aGlzLm9uSW1hZ2VBY3Rpb259XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcldlbGNvbWVTY3JlZW49e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICF0aGlzLnN0YXRlLmlzTG9hZGluZyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuc2hvd1dlbGNvbWVTY3JlZW4gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICF0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLmNoaWxkcmVufVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9MYXllclVJPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJleGNhbGlkcmF3LXRleHRFZGl0b3JDb250YWluZXJcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJleGNhbGlkcmF3LWNvbnRleHRNZW51Q29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtzZWxlY3RlZEVsZW1lbnQubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICF0aGlzLnN0YXRlLmNvbnRleHRNZW51ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuc2hvd0h5cGVybGlua1BvcHVwICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8SHlwZXJsaW5rXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9e3NlbGVjdGVkRWxlbWVudFswXS5pZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ9e3NlbGVjdGVkRWxlbWVudFswXX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25MaW5rT3Blbj17dGhpcy5wcm9wcy5vbkxpbmtPcGVufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5zdGF0ZS50b2FzdCAhPT0gbnVsbCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxUb2FzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U9e3RoaXMuc3RhdGUudG9hc3QubWVzc2FnZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsb3NlPXsoKSA9PiB0aGlzLnNldFRvYXN0KG51bGwpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uPXt0aGlzLnN0YXRlLnRvYXN0LmR1cmF0aW9ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NhYmxlPXt0aGlzLnN0YXRlLnRvYXN0LmNsb3NhYmxlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnN0YXRlLmNvbnRleHRNZW51ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPENvbnRleHRNZW51XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXM9e3RoaXMuc3RhdGUuY29udGV4dE1lbnUuaXRlbXN9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9wPXt0aGlzLnN0YXRlLmNvbnRleHRNZW51LnRvcH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0PXt0aGlzLnN0YXRlLmNvbnRleHRNZW51LmxlZnR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uTWFuYWdlcj17dGhpcy5hY3Rpb25NYW5hZ2VyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYWluPnt0aGlzLnJlbmRlckNhbnZhcygpfTwvbWFpbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L0V4Y2FsaWRyYXdBY3Rpb25NYW5hZ2VyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICAgICAgICAgICAgPC9FeGNhbGlkcmF3RWxlbWVudHNDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgICAgICAgICAgICAgPC9FeGNhbGlkcmF3QXBwU3RhdGVDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgICAgICAgICAgIDwvRXhjYWxpZHJhd1NldEFwcFN0YXRlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICAgICAgPC9EZXZpY2VDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgICAgICAgPC9FeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICA8L0FwcFByb3BzQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgPC9BcHBDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBmb2N1c0NvbnRhaW5lcjogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiZm9jdXNDb250YWluZXJcIl0gPSAoKSA9PiB7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmZvY3VzKCk7XG4gIH07XG5cbiAgcHVibGljIGdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkID0gKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpO1xuICB9O1xuXG4gIHB1YmxpYyBnZXRTY2VuZUVsZW1lbnRzID0gKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuICB9O1xuXG4gIHB1YmxpYyBvbkluc2VydEVsZW1lbnRzID0gKGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdKSA9PiB7XG4gICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICBlbGVtZW50cyxcbiAgICAgIHBvc2l0aW9uOiBcImNlbnRlclwiLFxuICAgICAgZmlsZXM6IG51bGwsXG4gICAgfSk7XG4gIH07XG5cbiAgcHVibGljIG9uRXhwb3J0SW1hZ2UgPSBhc3luYyAoXG4gICAgdHlwZToga2V5b2YgdHlwZW9mIEVYUE9SVF9JTUFHRV9UWVBFUyxcbiAgICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICkgPT4ge1xuICAgIHRyYWNrRXZlbnQoXCJleHBvcnRcIiwgdHlwZSwgXCJ1aVwiKTtcbiAgICBjb25zdCBmaWxlSGFuZGxlID0gYXdhaXQgZXhwb3J0QXNJbWFnZShcbiAgICAgIHR5cGUsXG4gICAgICBlbGVtZW50cyxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICB0aGlzLmZpbGVzLFxuICAgICAge1xuICAgICAgICBleHBvcnRCYWNrZ3JvdW5kOiB0aGlzLnN0YXRlLmV4cG9ydEJhY2tncm91bmQsXG4gICAgICAgIG5hbWU6IHRoaXMuc3RhdGUubmFtZSxcbiAgICAgICAgdmlld0JhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yLFxuICAgICAgfSxcbiAgICApXG4gICAgICAuY2F0Y2gobXV0ZUZTQWJvcnRFcnJvcilcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgICB9KTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZXhwb3J0RW1iZWRTY2VuZSAmJlxuICAgICAgZmlsZUhhbmRsZSAmJlxuICAgICAgaXNJbWFnZUZpbGVIYW5kbGUoZmlsZUhhbmRsZSlcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBmaWxlSGFuZGxlIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHN5bmNBY3Rpb25SZXN1bHQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGFjdGlvblJlc3VsdDogQWN0aW9uUmVzdWx0KSA9PiB7XG4gICAgICBpZiAodGhpcy51bm1vdW50ZWQgfHwgYWN0aW9uUmVzdWx0ID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBlZGl0aW5nRWxlbWVudDogQXBwU3RhdGVbXCJlZGl0aW5nRWxlbWVudFwiXSB8IG51bGwgPSBudWxsO1xuICAgICAgaWYgKGFjdGlvblJlc3VsdC5lbGVtZW50cykge1xuICAgICAgICBhY3Rpb25SZXN1bHQuZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQ/LmlkID09PSBlbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50ICE9PSBlbGVtZW50ICYmXG4gICAgICAgICAgICBpc05vbkRlbGV0ZWRFbGVtZW50KGVsZW1lbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBlZGl0aW5nRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKTtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGFjdGlvblJlc3VsdC5maWxlcykge1xuICAgICAgICB0aGlzLmZpbGVzID0gYWN0aW9uUmVzdWx0LnJlcGxhY2VGaWxlc1xuICAgICAgICAgID8gYWN0aW9uUmVzdWx0LmZpbGVzXG4gICAgICAgICAgOiB7IC4uLnRoaXMuZmlsZXMsIC4uLmFjdGlvblJlc3VsdC5maWxlcyB9O1xuICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmFwcFN0YXRlIHx8IGVkaXRpbmdFbGVtZW50IHx8IHRoaXMuc3RhdGUuY29udGV4dE1lbnUpIHtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmlld01vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udmlld01vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgemVuTW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy56ZW5Nb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IGdyaWRTaXplID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uZ3JpZFNpemUgfHwgbnVsbDtcbiAgICAgICAgY29uc3QgdGhlbWUgPVxuICAgICAgICAgIGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LnRoZW1lIHx8IHRoaXMucHJvcHMudGhlbWUgfHwgVEhFTUUuTElHSFQ7XG4gICAgICAgIGxldCBuYW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8ubmFtZSA/PyB0aGlzLnN0YXRlLm5hbWU7XG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uZXJyb3JNZXNzYWdlID8/IHRoaXMuc3RhdGUuZXJyb3JNZXNzYWdlO1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdmlld01vZGVFbmFibGVkID0gdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZCA9IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgZ3JpZFNpemUgPSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMubmFtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIG5hbWUgPSB0aGlzLnByb3BzLm5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIC8vIHVzaW5nIE9iamVjdC5hc3NpZ24gaW5zdGVhZCBvZiBzcHJlYWQgdG8gZm9vbCBUUyA0LjIuMisgaW50b1xuICAgICAgICAgICAgLy8gcmVnYXJkaW5nIHRoZSByZXN1bHRpbmcgdHlwZSBhcyBub3QgY29udGFpbmluZyB1bmRlZmluZWRcbiAgICAgICAgICAgIC8vICh3aGljaCB0aGUgZm9sbG93aW5nIGV4cHJlc3Npb24gd2lsbCBuZXZlciBjb250YWluKVxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oYWN0aW9uUmVzdWx0LmFwcFN0YXRlIHx8IHt9LCB7XG4gICAgICAgICAgICAgIC8vIE5PVEUgdGhpcyB3aWxsIHByZXZlbnQgb3BlbmluZyBjb250ZXh0IG1lbnUgdXNpbmcgYW4gYWN0aW9uXG4gICAgICAgICAgICAgIC8vIG9yIHByb2dyYW1tYXRpY2FsbHkgZnJvbSB0aGUgaG9zdCwgc28gaXQgd2lsbCBuZWVkIHRvIGJlXG4gICAgICAgICAgICAgIC8vIHJld3JpdHRlbiBsYXRlclxuICAgICAgICAgICAgICBjb250ZXh0TWVudTogbnVsbCxcbiAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgfHwgYWN0aW9uUmVzdWx0LmFwcFN0YXRlPy5lZGl0aW5nRWxlbWVudCB8fCBudWxsLFxuICAgICAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgICAgICAgICBncmlkU2l6ZSxcbiAgICAgICAgICAgICAgdGhlbWUsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgIGVycm9yTWVzc2FnZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5zeW5jSGlzdG9yeSkge1xuICAgICAgICAgICAgICB0aGlzLmhpc3Rvcnkuc2V0Q3VycmVudFN0YXRlKFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgLy8gTGlmZWN5Y2xlXG5cbiAgcHJpdmF0ZSBvbkJsdXIgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25VbmxvYWQgPSAoKSA9PiB7XG4gICAgdGhpcy5vbkJsdXIoKTtcbiAgfTtcblxuICBwcml2YXRlIGRpc2FibGVFdmVudDogRXZlbnRMaXN0ZW5lciA9IChldmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEhpc3RvcnkgPSAoKSA9PiB7XG4gICAgdGhpcy5oaXN0b3J5LmNsZWFyKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlc2V0cyBzY2VuZSAmIGhpc3RvcnkuXG4gICAqICEgRG8gbm90IHVzZSB0byBjbGVhciBzY2VuZSB1c2VyIGFjdGlvbiAhXG4gICAqL1xuICBwcml2YXRlIHJlc2V0U2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKG9wdHM/OiB7IHJlc2V0TG9hZGluZ1N0YXRlOiBib29sZWFuIH0pID0+IHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXREZWZhdWx0QXBwU3RhdGUoKSxcbiAgICAgICAgaXNMb2FkaW5nOiBvcHRzPy5yZXNldExvYWRpbmdTdGF0ZSA/IGZhbHNlIDogc3RhdGUuaXNMb2FkaW5nLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGluaXRpYWxpemVTY2VuZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAoXCJsYXVuY2hRdWV1ZVwiIGluIHdpbmRvdyAmJiBcIkxhdW5jaFBhcmFtc1wiIGluIHdpbmRvdykge1xuICAgICAgKHdpbmRvdyBhcyBhbnkpLmxhdW5jaFF1ZXVlLnNldENvbnN1bWVyKFxuICAgICAgICBhc3luYyAobGF1bmNoUGFyYW1zOiB7IGZpbGVzOiBhbnlbXSB9KSA9PiB7XG4gICAgICAgICAgaWYgKCFsYXVuY2hQYXJhbXMuZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpbGVIYW5kbGUgPSBsYXVuY2hQYXJhbXMuZmlsZXNbMF07XG4gICAgICAgICAgY29uc3QgYmxvYjogQmxvYiA9IGF3YWl0IGZpbGVIYW5kbGUuZ2V0RmlsZSgpO1xuICAgICAgICAgIHRoaXMubG9hZEZpbGVUb0NhbnZhcyhcbiAgICAgICAgICAgIG5ldyBGaWxlKFtibG9iXSwgYmxvYi5uYW1lIHx8IFwiXCIsIHsgdHlwZTogYmxvYi50eXBlIH0pLFxuICAgICAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9wcy50aGVtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHRoZW1lOiB0aGlzLnByb3BzLnRoZW1lIH0pO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgIH1cbiAgICBsZXQgaW5pdGlhbERhdGEgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBpbml0aWFsRGF0YSA9IChhd2FpdCB0aGlzLnByb3BzLmluaXRpYWxEYXRhKSB8fCBudWxsO1xuICAgICAgaWYgKGluaXRpYWxEYXRhPy5saWJyYXJ5SXRlbXMpIHtcbiAgICAgICAgdGhpcy5saWJyYXJ5XG4gICAgICAgICAgLnVwZGF0ZUxpYnJhcnkoe1xuICAgICAgICAgICAgbGlicmFyeUl0ZW1zOiBpbml0aWFsRGF0YS5saWJyYXJ5SXRlbXMsXG4gICAgICAgICAgICBtZXJnZTogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgaW5pdGlhbERhdGEgPSB7XG4gICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgZXJyb3JNZXNzYWdlOlxuICAgICAgICAgICAgZXJyb3IubWVzc2FnZSB8fFxuICAgICAgICAgICAgXCJFbmNvdW50ZXJlZCBhbiBlcnJvciBkdXJpbmcgaW1wb3J0aW5nIG9yIHJlc3RvcmluZyBzY2VuZSBkYXRhXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBzY2VuZSA9IHJlc3RvcmUoaW5pdGlhbERhdGEsIG51bGwsIG51bGwsIHsgcmVwYWlyQmluZGluZ3M6IHRydWUgfSk7XG4gICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgIHRoZW1lOiB0aGlzLnByb3BzLnRoZW1lIHx8IHNjZW5lLmFwcFN0YXRlLnRoZW1lLFxuICAgICAgLy8gd2UncmUgZmFsbGluZyBiYWNrIHRvIGN1cnJlbnQgKHByZS1pbml0KSBzdGF0ZSB3aGVuIGRlY2lkaW5nXG4gICAgICAvLyB3aGV0aGVyIHRvIG9wZW4gdGhlIGxpYnJhcnksIHRvIGhhbmRsZSBhIGNhc2Ugd2hlcmUgd2VcbiAgICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGUgb3V0c2lkZSBvZiBpbml0aWFsRGF0YSAoZS5nLiB3aGVuIGxvYWRpbmcgdGhlIGFwcFxuICAgICAgLy8gd2l0aCBhIGxpYnJhcnkgaW5zdGFsbCBsaW5rLCB3aGljaCBzaG91bGQgYXV0by1vcGVuIHRoZSBsaWJyYXJ5KVxuICAgICAgb3BlblNpZGViYXI6IHNjZW5lLmFwcFN0YXRlPy5vcGVuU2lkZWJhciB8fCB0aGlzLnN0YXRlLm9wZW5TaWRlYmFyLFxuICAgICAgYWN0aXZlVG9vbDpcbiAgICAgICAgc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCJcbiAgICAgICAgICA/IHsgLi4uc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbCwgdHlwZTogXCJzZWxlY3Rpb25cIiB9XG4gICAgICAgICAgOiBzY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgIHRvYXN0OiB0aGlzLnN0YXRlLnRvYXN0LFxuICAgIH07XG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxUb0NvbnRlbnQpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICAgIHNjZW5lLmVsZW1lbnRzLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAgICAgd2lkdGg6IHRoaXMuc3RhdGUud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuc3RhdGUuaGVpZ2h0LFxuICAgICAgICAgICAgb2Zmc2V0VG9wOiB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgICAgIG9mZnNldExlZnQ6IHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBGb250RmFjZVNldCBsb2FkaW5nZG9uZSBldmVudCB3ZSBsaXN0ZW4gb24gbWF5IG5vdCBhbHdheXMgZmlyZVxuICAgIC8vIChsb29raW5nIGF0IHlvdSBTYWZhcmkpLCBzbyBvbiBpbml0IHdlIG1hbnVhbGx5IGxvYWQgZm9udHMgZm9yIGN1cnJlbnRcbiAgICAvLyB0ZXh0IGVsZW1lbnRzIG9uIGNhbnZhcywgYW5kIHJlcmVuZGVyIHRoZW0gb25jZSBkb25lLiBUaGlzIGFsc29cbiAgICAvLyBzZWVtcyBmYXN0ZXIgZXZlbiBpbiBicm93c2VycyB0aGF0IGRvIGZpcmUgdGhlIGxvYWRpbmdkb25lIGV2ZW50LlxuICAgIHRoaXMuZm9udHMubG9hZEZvbnRzRm9yRWxlbWVudHMoc2NlbmUuZWxlbWVudHMpO1xuXG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxYICE9IG51bGwpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlLnNjcm9sbFggPSBpbml0aWFsRGF0YS5zY3JvbGxYO1xuICAgIH1cbiAgICBpZiAoaW5pdGlhbERhdGE/LnNjcm9sbFkgIT0gbnVsbCkge1xuICAgICAgc2NlbmUuYXBwU3RhdGUuc2Nyb2xsWSA9IGluaXRpYWxEYXRhLnNjcm9sbFk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgLi4uc2NlbmUsXG4gICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWZyZXNoRGV2aWNlU3RhdGUgPSAoY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCkgPT4ge1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHNpZGViYXJCcmVha3BvaW50ID1cbiAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50ICE9IG51bGxcbiAgICAgICAgPyB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICAgICA6IE1RX1JJR0hUX1NJREVCQVJfTUlOX1dJRFRIO1xuICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7XG4gICAgICBpc0xhbmRzY2FwZTogd2lkdGggPiBoZWlnaHQsXG4gICAgICBpc1NtU2NyZWVuOiB3aWR0aCA8IE1RX1NNX01BWF9XSURUSCxcbiAgICAgIGlzTW9iaWxlOlxuICAgICAgICB3aWR0aCA8IE1RX01BWF9XSURUSF9QT1JUUkFJVCB8fFxuICAgICAgICAoaGVpZ2h0IDwgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUgJiYgd2lkdGggPCBNUV9NQVhfV0lEVEhfTEFORFNDQVBFKSxcbiAgICAgIGNhbkRldmljZUZpdFNpZGViYXI6IHdpZHRoID4gc2lkZWJhckJyZWFrcG9pbnQsXG4gICAgfSk7XG4gIH07XG5cbiAgcHVibGljIGFzeW5jIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgIHRoaXMudW5tb3VudGVkID0gZmFsc2U7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUuY29udGFpbmVyID1cbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuXG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5URVNUIHx8XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4gICAgKSB7XG4gICAgICBjb25zdCBzZXRTdGF0ZSA9IHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2V0U3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6ICguLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiBzZXRTdGF0ZT4pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKC4uLmFyZ3MpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFwcDoge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcyxcbiAgICAgICAgfSxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcy5oaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5hZGRDYWxsYmFjayh0aGlzLm9uU2NlbmVVcGRhdGVkKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICBpZiAodGhpcy5wcm9wcy5hdXRvRm9jdXMgJiYgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCAmJlxuICAgICAgLy8gYm91bmRpbmcgcmVjdHMgZG9uJ3Qgd29yayBpbiB0ZXN0cyBzbyB1cGRhdGluZ1xuICAgICAgLy8gdGhlIHN0YXRlIG9uIGluaXQgd291bGQgcmVzdWx0IGluIG1ha2luZyB0aGUgdGVzdCBlbnZpcm8gcnVuXG4gICAgICAvLyBpbiBtb2JpbGUgYnJlYWtwb2ludCAoMCB3aWR0aC9oZWlnaHQpLCBtYWtpbmcgZXZlcnl0aGluZyBmYWlsXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJ0ZXN0XCJcbiAgICApIHtcbiAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoXCJSZXNpemVPYnNlcnZlclwiIGluIHdpbmRvdyAmJiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiA9IGZhbHNlO1xuICAgICAgICAvLyByZWNvbXB1dGUgZGV2aWNlIGRpbWVuc2lvbnMgc3RhdGVcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISk7XG4gICAgICAgIC8vIHJlZnJlc2ggb2Zmc2V0c1xuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy51cGRhdGVET01SZWN0KCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/Lm9ic2VydmUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH0gZWxzZSBpZiAod2luZG93Lm1hdGNoTWVkaWEpIHtcbiAgICAgIGNvbnN0IG1kU2NyZWVuUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtYXgtd2lkdGg6ICR7TVFfTUFYX1dJRFRIX1BPUlRSQUlUfXB4KSwgKG1heC1oZWlnaHQ6ICR7TVFfTUFYX0hFSUdIVF9MQU5EU0NBUEV9cHgpIGFuZCAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9MQU5EU0NBUEV9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBzbVNjcmVlblF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX1NNX01BWF9XSURUSH1weClgLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGNhbkRldmljZUZpdFNpZGViYXJNZWRpYVF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWluLXdpZHRoOiAke1xuICAgICAgICAgIC8vIE5PVEUgdGhpcyB3b24ndCB1cGRhdGUgaWYgYSBkaWZmZXJlbnQgYnJlYWtwb2ludCBpcyBzdXBwbGllZFxuICAgICAgICAgIC8vIGFmdGVyIG1vdW50XG4gICAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnQgIT0gbnVsbFxuICAgICAgICAgICAgPyB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICAgICAgICAgOiBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSFxuICAgICAgICB9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7XG4gICAgICAgICAgaXNTbVNjcmVlbjogc21TY3JlZW5RdWVyeS5tYXRjaGVzLFxuICAgICAgICAgIGlzTW9iaWxlOiBtZFNjcmVlblF1ZXJ5Lm1hdGNoZXMsXG4gICAgICAgICAgY2FuRGV2aWNlRml0U2lkZWJhcjogY2FuRGV2aWNlRml0U2lkZWJhck1lZGlhUXVlcnkubWF0Y2hlcyxcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgbWRTY3JlZW5RdWVyeS5hZGRMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXIgPSAoKSA9PlxuICAgICAgICBtZFNjcmVlblF1ZXJ5LnJlbW92ZUxpc3RlbmVyKGhhbmRsZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaC5zbGljZSgxKSk7XG5cbiAgICBpZiAoc2VhcmNoUGFyYW1zLmhhcyhcIndlYi1zaGFyZS10YXJnZXRcIikpIHtcbiAgICAgIC8vIE9idGFpbiBhIGZpbGUgdGhhdCB3YXMgc2hhcmVkIHZpYSB0aGUgV2ViIFNoYXJlIFRhcmdldCBBUEkuXG4gICAgICB0aGlzLnJlc3RvcmVGaWxlRnJvbVNoYXJlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCh0aGlzLmluaXRpYWxpemVTY2VuZSk7XG4gICAgfVxuXG4gICAgLy8gbm90ZSB0aGF0IHRoaXMgY2hlY2sgc2VlbXMgdG8gYWx3YXlzIHBhc3MgaW4gbG9jYWxob3N0XG4gICAgaWYgKGlzQnJhdmUoKSAmJiAhaXNNZWFzdXJlVGV4dFN1cHBvcnRlZCgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZXJyb3JNZXNzYWdlOiA8QnJhdmVNZWFzdXJlVGV4dEVycm9yIC8+LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgIHRoaXMuZmlsZXMgPSB7fTtcbiAgICB0aGlzLmltYWdlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy51bm1vdW50ZWQgPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNjZW5lLmRlc3Ryb3koKTtcbiAgICBjbGVhclJlbmRlckNhY2hlKCk7XG5cbiAgICB0aGlzLm9uQ2hhbmdlRW1pdHRlci5kZXN0cm95KCk7XG5cbiAgICB0aGlzLnNjZW5lID0gbmV3IFNjZW5lKCk7XG4gICAgdGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIgPSBuZXcgQWN0aW9uTWFuYWdlcihcbiAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCxcbiAgICAgICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAoKSA9PiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcyxcbiAgICApO1xuICAgIHRoaXMubGlicmFyeSA9IG5ldyBMaWJyYXJ5KHRoaXMpO1xuICAgIHRoaXMuY2FudmFzID0gbnVsbDtcbiAgICB0aGlzLnJjID0gbnVsbDtcblxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlID0geyBjb250YWluZXI6IG51bGwsIGlkOiBcInVubW91bnRlZFwiIH07XG5cbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICB9XG5cbiAgcHJpdmF0ZSBvblJlc2l6ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgdGhpcy5zY2VuZVxuICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5XSEVFTCxcbiAgICAgIHRoaXMub25XaGVlbCxcbiAgICApO1xuICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRSQUdfT1ZFUixcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRST1AsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuZm9udHM/LnJlbW92ZUV2ZW50TGlzdGVuZXI/LihcbiAgICAgIFwibG9hZGluZ2RvbmVcIixcbiAgICAgIHRoaXMub25Gb250c0xvYWRpbmdEb25lLFxuICAgICk7XG5cbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG5cbiAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyPy4oKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Gb250c0xvYWRpbmdEb25lID0gKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgIGNvbnN0IGxvYWRlZEZvbnRGYWNlcyA9IChldmVudCBhcyBGb250RmFjZVNldExvYWRFdmVudCkuZm9udGZhY2VzO1xuICAgIHRoaXMuZm9udHMub25Gb250c0xvYWRlZChsb2FkZWRGb250RmFjZXMpO1xuICB9O1xuXG4gIHByaXZhdGUgYWRkRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTsgLy8gIzM1NTNcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULldIRUVMLFxuICAgICAgdGhpcy5vbldoZWVsLFxuICAgICAgeyBwYXNzaXZlOiBmYWxzZSB9LFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5KSB7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIHRoaXMub25LZXlEb3duLCBmYWxzZSk7XG4gICAgfVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgKTtcbiAgICAvLyByZXJlbmRlciB0ZXh0IGVsZW1lbnRzIG9uIGZvbnQgbG9hZCB0byBmaXggIzYzNyAmJiAjMTU1M1xuICAgIGRvY3VtZW50LmZvbnRzPy5hZGRFdmVudExpc3RlbmVyPy4oXCJsb2FkaW5nZG9uZVwiLCB0aGlzLm9uRm9udHNMb2FkaW5nRG9uZSk7XG5cbiAgICAvLyBTYWZhcmktb25seSBkZXNrdG9wIHBpbmNoIHpvb21cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ1VULCB0aGlzLm9uQ3V0KTtcbiAgICBpZiAodGhpcy5wcm9wcy5kZXRlY3RTY3JvbGwpIHtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIgPSBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcihcbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgKTtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuU0NST0xMLFxuICAgICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICAgKTtcbiAgICB9XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRSQUdfT1ZFUixcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRST1AsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gIH1cblxuICBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzOiBBcHBQcm9wcywgcHJldlN0YXRlOiBBcHBTdGF0ZSkge1xuICAgIGlmIChcbiAgICAgICF0aGlzLnN0YXRlLnNob3dXZWxjb21lU2NyZWVuICYmXG4gICAgICAhdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5sZW5ndGhcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93V2VsY29tZVNjcmVlbjogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCAmJlxuICAgICAgcHJldlByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPT1cbiAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICApIHtcbiAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuc2Nyb2xsWCAhPT0gdGhpcy5zdGF0ZS5zY3JvbGxYIHx8XG4gICAgICBwcmV2U3RhdGUuc2Nyb2xsWSAhPT0gdGhpcy5zdGF0ZS5zY3JvbGxZXG4gICAgKSB7XG4gICAgICB0aGlzLnByb3BzPy5vblNjcm9sbENoYW5nZT8uKHRoaXMuc3RhdGUuc2Nyb2xsWCwgdGhpcy5zdGF0ZS5zY3JvbGxZKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBPYmplY3Qua2V5cyh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcykubGVuZ3RoICYmXG4gICAgICBpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKVxuICAgICkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiICYmXG4gICAgICBwcmV2U3RhdGUudGhlbWUgIT09IHRoaXMuc3RhdGUudGhlbWVcbiAgICApIHtcbiAgICAgIHNldEVyYXNlckN1cnNvcih0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS50aGVtZSk7XG4gICAgfVxuICAgIC8vIEhpZGUgaHlwZXJsaW5rIHBvcHVwIGlmIHNob3duIHdoZW4gZWxlbWVudCB0eXBlIGlzIG5vdCBzZWxlY3Rpb25cbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXBcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlIH0pO1xuICAgIH1cbiAgICBpZiAocHJldlByb3BzLmxhbmdDb2RlICE9PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxhbmd1YWdlKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlld01vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMudmlld01vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2U3RhdGUudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHplbk1vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy50aGVtZSAhPT0gdGhpcy5wcm9wcy50aGVtZSAmJiB0aGlzLnByb3BzLnRoZW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdGhlbWU6IHRoaXMucHJvcHMudGhlbWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZ3JpZFNpemU6IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICF0aGlzLnByb3BzLlVJT3B0aW9ucy5jYW52YXNBY3Rpb25zICYmXG4gICAgICB0aGlzLnN0YXRlLm9wZW5NZW51ID09PSBcImNhbnZhc1wiXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgb3Blbk1lbnU6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9wcy5uYW1lICYmIHByZXZQcm9wcy5uYW1lICE9PSB0aGlzLnByb3BzLm5hbWUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBuYW1lOiB0aGlzLnByb3BzLm5hbWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY2xhc3NMaXN0LnRvZ2dsZShcbiAgICAgIFwidGhlbWUtLWRhcmtcIixcbiAgICAgIHRoaXMuc3RhdGUudGhlbWUgPT09IFwiZGFya1wiLFxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdXG4gICAgKSB7XG4gICAgICAvLyBkZWZlciBzbyB0aGF0IHRoZSBjb21taXRUb0hpc3RvcnkgZmxhZyBpc24ndCByZXNldCB2aWEgY3VycmVudCB1cGRhdGVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAvLyBleGVjdXRlIG9ubHkgaWYgdGhlIGNvbmRpdGlvbiBzdGlsbCBob2xkcyB3aGVuIHRoZSBkZWZlcnJlZCBjYWxsYmFja1xuICAgICAgICAvLyBleGVjdXRlcyAoaXQgY2FuIGJlIHNjaGVkdWxlZCBtdWx0aXBsZSB0aW1lcyBkZXBlbmRpbmcgb24gaG93XG4gICAgICAgIC8vIG1hbnkgdGltZXMgdGhlIGNvbXBvbmVudCByZW5kZXJzKVxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5lbGVtZW50SWRdXG4gICAgKSB7XG4gICAgICAvLyBUbyBtYWtlIHN1cmUgYHNlbGVjdGVkTGluZWFyRWxlbWVudGAgaXMgaW4gc3luYyB3aXRoIGBzZWxlY3RlZEVsZW1lbnRJZHNgLCBob3dldmVyIHRoaXMgc2hvdWxkbid0IGJlIG5lZWRlZCBvbmNlXG4gICAgICAvLyB3ZSBoYXZlIGEgc2luZ2xlIEFQSSB0byB1cGRhdGUgYHNlbGVjdGVkRWxlbWVudElkc2BcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG51bGwgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHByZXZTdGF0ZTtcbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbCAhPT0gdGhpcy5zdGF0ZS5hY3RpdmVUb29sICYmXG4gICAgICBtdWx0aUVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKSAmJlxuICAgICAgaXNCaW5kaW5nRWxlbWVudChtdWx0aUVsZW1lbnQsIGZhbHNlKVxuICAgICkge1xuICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEF0SW5kZXhHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgICAgIC0xLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlclNjZW5lKCk7XG4gICAgdGhpcy5oaXN0b3J5LnJlY29yZCh0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKTtcblxuICAgIC8vIERvIG5vdCBub3RpZnkgY29uc3VtZXJzIGlmIHdlJ3JlIHN0aWxsIGxvYWRpbmcgdGhlIHNjZW5lLiBBbW9uZyBvdGhlclxuICAgIC8vIHBvdGVudGlhbCBpc3N1ZXMsIHRoaXMgZml4ZXMgYSBjYXNlIHdoZXJlIHRoZSB0YWIgaXNuJ3QgZm9jdXNlZCBkdXJpbmdcbiAgICAvLyBpbml0LCB3aGljaCB3b3VsZCB0cmlnZ2VyIG9uQ2hhbmdlIHdpdGggZW1wdHkgZWxlbWVudHMsIHdoaWNoIHdvdWxkIHRoZW5cbiAgICAvLyBvdmVycmlkZSB3aGF0ZXZlciBpcyBpbiBsb2NhbFN0b3JhZ2UgY3VycmVudGx5LlxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMucHJvcHMub25DaGFuZ2U/LihcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5maWxlcyxcbiAgICAgICAgdGhpcy5wcm9wcy5pZCxcbiAgICAgICk7XG4gICAgICB0aGlzLm9uQ2hhbmdlRW1pdHRlci50cmlnZ2VyKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmZpbGVzLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclNjZW5lID0gKCkgPT4ge1xuICAgIGNvbnN0IGN1cnNvckJ1dHRvbjoge1xuICAgICAgW2lkOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgfSA9IHt9O1xuICAgIGNvbnN0IHBvaW50ZXJWaWV3cG9ydENvb3JkczogUmVuZGVyQ29uZmlnW1wicmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzXCJdID1cbiAgICAgIHt9O1xuICAgIGNvbnN0IHJlbW90ZVNlbGVjdGVkRWxlbWVudElkczogUmVuZGVyQ29uZmlnW1wicmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzXCJdID1cbiAgICAgIHt9O1xuICAgIGNvbnN0IHBvaW50ZXJVc2VybmFtZXM6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGNvbnN0IHBvaW50ZXJVc2VyU3RhdGVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICB0aGlzLnN0YXRlLmNvbGxhYm9yYXRvcnMuZm9yRWFjaCgodXNlciwgc29ja2V0SWQpID0+IHtcbiAgICAgIGlmICh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIE9iamVjdC5rZXlzKHVzZXIuc2VsZWN0ZWRFbGVtZW50SWRzKSkge1xuICAgICAgICAgIGlmICghKGlkIGluIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0gPSBbXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzW2lkXS5wdXNoKHNvY2tldElkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCF1c2VyLnBvaW50ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXIudXNlcm5hbWUpIHtcbiAgICAgICAgcG9pbnRlclVzZXJuYW1lc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJuYW1lO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXIudXNlclN0YXRlKSB7XG4gICAgICAgIHBvaW50ZXJVc2VyU3RhdGVzW3NvY2tldElkXSA9IHVzZXIudXNlclN0YXRlO1xuICAgICAgfVxuICAgICAgcG9pbnRlclZpZXdwb3J0Q29vcmRzW3NvY2tldElkXSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAge1xuICAgICAgICAgIHNjZW5lWDogdXNlci5wb2ludGVyLngsXG4gICAgICAgICAgc2NlbmVZOiB1c2VyLnBvaW50ZXIueSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBjdXJzb3JCdXR0b25bc29ja2V0SWRdID0gdXNlci5idXR0b247XG4gICAgfSk7XG5cbiAgICBjb25zdCByZW5kZXJpbmdFbGVtZW50cyA9IHRoaXMuc2NlbmVcbiAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgLmZpbHRlcigoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoaXNJbWFnZUVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAvLyBub3QgcGxhY2VkIG9uIGNhbnZhcyB5ZXQgKGJ1dCBpbiBlbGVtZW50cyBhcnJheSlcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkID09PSBlbGVtZW50LmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGRvbid0IHJlbmRlciB0ZXh0IGVsZW1lbnQgdGhhdCdzIGJlaW5nIGN1cnJlbnRseSBlZGl0ZWQgKGl0J3NcbiAgICAgICAgLy8gcmVuZGVyZWQgb24gcmVtb3RlIG9ubHkpXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50LnR5cGUgIT09IFwidGV4dFwiIHx8XG4gICAgICAgICAgZWxlbWVudC5pZCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC5pZFxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBzZWxlY3Rpb25Db2xvciA9IGdldENvbXB1dGVkU3R5bGUoXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmV4Y2FsaWRyYXdcIikhLFxuICAgICkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY29sb3Itc2VsZWN0aW9uXCIpO1xuXG4gICAgcmVuZGVyU2NlbmUoXG4gICAgICB7XG4gICAgICAgIGVsZW1lbnRzOiByZW5kZXJpbmdFbGVtZW50cyxcbiAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHJjOiB0aGlzLnJjISxcbiAgICAgICAgY2FudmFzOiB0aGlzLmNhbnZhcyEsXG4gICAgICAgIHJlbmRlckNvbmZpZzoge1xuICAgICAgICAgIGNhbnZhc1NjYWxlOiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgICBzZWxlY3Rpb25Db2xvcixcbiAgICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFgsXG4gICAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZLFxuICAgICAgICAgIGNhbnZhc0JhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgIHpvb206IHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICByZW1vdGVQb2ludGVyVmlld3BvcnRDb29yZHM6IHBvaW50ZXJWaWV3cG9ydENvb3JkcyxcbiAgICAgICAgICByZW1vdGVQb2ludGVyQnV0dG9uOiBjdXJzb3JCdXR0b24sXG4gICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHBvaW50ZXJVc2VybmFtZXMsXG4gICAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJTdGF0ZXM6IHBvaW50ZXJVc2VyU3RhdGVzLFxuICAgICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdGhpcy5zdGF0ZS5zaG91bGRDYWNoZUlnbm9yZVpvb20sXG4gICAgICAgICAgdGhlbWU6IHRoaXMuc3RhdGUudGhlbWUsXG4gICAgICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgICAgIGlzRXhwb3J0aW5nOiBmYWxzZSxcbiAgICAgICAgICByZW5kZXJTY3JvbGxiYXJzOiAhdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgIH0sXG4gICAgICAgIGNhbGxiYWNrOiAoeyBhdExlYXN0T25lVmlzaWJsZUVsZW1lbnQsIHNjcm9sbEJhcnMgfSkgPT4ge1xuICAgICAgICAgIGlmIChzY3JvbGxCYXJzKSB7XG4gICAgICAgICAgICBjdXJyZW50U2Nyb2xsQmFycyA9IHNjcm9sbEJhcnM7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHNjcm9sbGVkT3V0c2lkZSA9XG4gICAgICAgICAgICAvLyBoaWRlIHdoZW4gZWRpdGluZyB0ZXh0XG4gICAgICAgICAgICBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgICAgICAgID8gZmFsc2VcbiAgICAgICAgICAgICAgOiAhYXRMZWFzdE9uZVZpc2libGVFbGVtZW50ICYmIHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCA+IDA7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2Nyb2xsZWRPdXRzaWRlICE9PSBzY3JvbGxlZE91dHNpZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzY3JvbGxlZE91dHNpZGUgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5zY2hlZHVsZUltYWdlUmVmcmVzaCgpO1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIFRIUk9UVExFX05FWFRfUkVOREVSICYmIHdpbmRvdy5FWENBTElEUkFXX1RIUk9UVExFX1JFTkRFUiA9PT0gdHJ1ZSxcbiAgICApO1xuXG4gICAgaWYgKCFUSFJPVFRMRV9ORVhUX1JFTkRFUikge1xuICAgICAgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSB0cnVlO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uU2Nyb2xsID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGNvbnN0IHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSB0aGlzLmdldENhbnZhc09mZnNldHMoKTtcbiAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgaWYgKHN0YXRlLm9mZnNldExlZnQgPT09IG9mZnNldExlZnQgJiYgc3RhdGUub2Zmc2V0VG9wID09PSBvZmZzZXRUb3ApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBvZmZzZXRUb3AsIG9mZnNldExlZnQgfTtcbiAgICB9KTtcbiAgfSwgU0NST0xMX1RJTUVPVVQpO1xuXG4gIC8vIENvcHkvcGFzdGVcblxuICBwcml2YXRlIG9uQ3V0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1dEFsbCgpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25Db3B5ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICBwcml2YXRlIGN1dEFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25DdXQsIFwia2V5Ym9hcmRcIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb3B5QWxsID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkNvcHksIFwia2V5Ym9hcmRcIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVzZXRUYXBUd2ljZSgpIHtcbiAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblRhcFN0YXJ0ID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XG4gICAgLy8gZml4IGZvciBBcHBsZSBQZW5jaWwgU2NyaWJibGVcbiAgICAvLyBPbiBBbmRyb2lkLCBwcmV2ZW50aW5nIHRoZSBldmVudCB3b3VsZCBkaXNhYmxlIGNvbnRleHRNZW51IG9uIHRhcC1ob2xkXG4gICAgaWYgKCFpc0FuZHJvaWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFkaWRUYXBUd2ljZSkge1xuICAgICAgZGlkVGFwVHdpY2UgPSB0cnVlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgICAgdGFwcGVkVHdpY2VUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KFxuICAgICAgICBBcHAucmVzZXRUYXBUd2ljZSxcbiAgICAgICAgVEFQX1RXSUNFX1RJTUVPVVQsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBpbnNlcnQgdGV4dCBvbmx5IGlmIHdlIHRhcHBlZCB0d2ljZSB3aXRoIGEgc2luZ2xlIGZpbmdlclxuICAgIC8vIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxIHdpbGwgYWxzbyBwcmV2ZW50IGluc2VydGluZyB0ZXh0IHdoZW4gdXNlcidzIHpvb21pbmdcbiAgICBpZiAoZGlkVGFwVHdpY2UgJiYgZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGNvbnN0IFt0b3VjaF0gPSBldmVudC50b3VjaGVzO1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5oYW5kbGVDYW52YXNEb3VibGVDbGljayh7XG4gICAgICAgIGNsaWVudFg6IHRvdWNoLmNsaWVudFgsXG4gICAgICAgIGNsaWVudFk6IHRvdWNoLmNsaWVudFksXG4gICAgICB9KTtcbiAgICAgIGRpZFRhcFR3aWNlID0gZmFsc2U7XG4gICAgICBjbGVhclRpbWVvdXQodGFwcGVkVHdpY2VUaW1lcik7XG4gICAgfVxuICAgIGlmIChpc0FuZHJvaWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uVGFwRW5kID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XG4gICAgdGhpcy5yZXNldENvbnRleHRNZW51VGltZXIoKTtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5wb2ludGVycy5jbGVhcigpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgcGFzdGVGcm9tQ2xpcGJvYXJkID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIGFzeW5jIChldmVudDogQ2xpcGJvYXJkRXZlbnQgfCBudWxsKSA9PiB7XG4gICAgICBjb25zdCBpc1BsYWluUGFzdGUgPSAhIShJU19QTEFJTl9QQVNURSAmJiBldmVudCk7XG5cbiAgICAgIC8vICM2ODZcbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPVxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnModGFyZ2V0KTtcbiAgICAgIGlmIChldmVudCAmJiAhaXNFeGNhbGlkcmF3QWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWxlbWVudFVuZGVyQ3Vyc29yID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChjdXJzb3JYLCBjdXJzb3JZKTtcbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnQgJiZcbiAgICAgICAgKCEoZWxlbWVudFVuZGVyQ3Vyc29yIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHx8XG4gICAgICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG11c3QgYmUgY2FsbGVkIGluIHRoZSBzYW1lIGZyYW1lICh0aHVzIGJlZm9yZSBhbnkgYXdhaXRzKSBhcyB0aGUgcGFzdGVcbiAgICAgIC8vIGV2ZW50IGVsc2Ugc29tZSBicm93c2VycyAoRkYuLi4pIHdpbGwgY2xlYXIgdGhlIGNsaXBib2FyZERhdGFcbiAgICAgIC8vIChzb21ldGhpbmcgc29tZXRoaW5nIHNlY3VyaXR5KVxuICAgICAgbGV0IGZpbGUgPSBldmVudD8uY2xpcGJvYXJkRGF0YT8uZmlsZXNbMF07XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBwYXJzZUNsaXBib2FyZChldmVudCwgaXNQbGFpblBhc3RlKTtcblxuICAgICAgaWYgKCFmaWxlICYmIGRhdGEudGV4dCAmJiAhaXNQbGFpblBhc3RlKSB7XG4gICAgICAgIGNvbnN0IHN0cmluZyA9IGRhdGEudGV4dC50cmltKCk7XG4gICAgICAgIGlmIChzdHJpbmcuc3RhcnRzV2l0aChcIjxzdmdcIikgJiYgc3RyaW5nLmVuZHNXaXRoKFwiPC9zdmc+XCIpKSB7XG4gICAgICAgICAgLy8gaWdub3JlIFNWRyB2YWxpZGF0aW9uL25vcm1hbGl6YXRpb24gd2hpY2ggd2lsbCBiZSBkb25lIGR1cmluZyBpbWFnZVxuICAgICAgICAgIC8vIGluaXRpYWxpemF0aW9uXG4gICAgICAgICAgZmlsZSA9IFNWR1N0cmluZ1RvRmlsZShzdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHByZWZlciBzcHJlYWRzaGVldCBkYXRhIG92ZXIgaW1hZ2UgZmlsZSAoTVMgT2ZmaWNlL0xpYnJlIE9mZmljZSlcbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSAmJiAhZGF0YS5zcHJlYWRzaGVldCkge1xuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucHJvcHMub25QYXN0ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICgoYXdhaXQgdGhpcy5wcm9wcy5vblBhc3RlKGRhdGEsIGV2ZW50KSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGEuZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGRhdGEuZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnNwcmVhZHNoZWV0ICYmICFpc1BsYWluUGFzdGUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcGFzdGVEaWFsb2c6IHtcbiAgICAgICAgICAgIGRhdGE6IGRhdGEuc3ByZWFkc2hlZXQsXG4gICAgICAgICAgICBzaG93bjogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5lbGVtZW50cykge1xuICAgICAgICAvLyBUT0RPIHJlbW92ZSBmb3JtYXR0aW5nIGZyb20gZWxlbWVudHMgaWYgaXNQbGFpblBhc3RlXG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkYXRhLmVsZW1lbnRzLFxuICAgICAgICAgIGZpbGVzOiBkYXRhLmZpbGVzIHx8IG51bGwsXG4gICAgICAgICAgcG9zaXRpb246IFwiY3Vyc29yXCIsXG4gICAgICAgICAgcmV0YWluU2VlZDogaXNQbGFpblBhc3RlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS50ZXh0KSB7XG4gICAgICAgIHRoaXMuYWRkVGV4dEZyb21QYXN0ZShkYXRhLnRleHQsIGlzUGxhaW5QYXN0ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGl2ZVRvb2woeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pO1xuICAgICAgZXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5ID0gKG9wdHM6IHtcbiAgICBlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXTtcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsO1xuICAgIHBvc2l0aW9uOiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0gfCBcImN1cnNvclwiIHwgXCJjZW50ZXJcIjtcbiAgICByZXRhaW5TZWVkPzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gcmVzdG9yZUVsZW1lbnRzKG9wdHMuZWxlbWVudHMsIG51bGwpO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhlbGVtZW50cyk7XG5cbiAgICBjb25zdCBlbGVtZW50c0NlbnRlclggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSAvIDI7XG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJZID0gZGlzdGFuY2UobWluWSwgbWF4WSkgLyAyO1xuXG4gICAgY29uc3QgY2xpZW50WCA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WFxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JYXG4gICAgICAgIDogdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgY29uc3QgY2xpZW50WSA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WVxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JZXG4gICAgICAgIDogdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3QgZHggPSB4IC0gZWxlbWVudHNDZW50ZXJYO1xuICAgIGNvbnN0IGR5ID0geSAtIGVsZW1lbnRzQ2VudGVyWTtcblxuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KGR4LCBkeSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBuZXdFbGVtZW50cyA9IGR1cGxpY2F0ZUVsZW1lbnRzKFxuICAgICAgZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGVtZW50LCB7XG4gICAgICAgICAgeDogZWxlbWVudC54ICsgZ3JpZFggLSBtaW5YLFxuICAgICAgICAgIHk6IGVsZW1lbnQueSArIGdyaWRZIC0gbWluWSxcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIHtcbiAgICAgICAgcmFuZG9taXplU2VlZDogIW9wdHMucmV0YWluU2VlZCxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAuLi5uZXdFbGVtZW50cyxcbiAgICBdO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMobmV4dEVsZW1lbnRzKTtcblxuICAgIG5ld0VsZW1lbnRzLmZvckVhY2goKG5ld0VsZW1lbnQpID0+IHtcbiAgICAgIGlmIChpc1RleHRFbGVtZW50KG5ld0VsZW1lbnQpICYmIGlzQm91bmRUb0NvbnRhaW5lcihuZXdFbGVtZW50KSkge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBnZXRDb250YWluZXJFbGVtZW50KG5ld0VsZW1lbnQpO1xuICAgICAgICByZWRyYXdUZXh0Qm91bmRpbmdCb3gobmV3RWxlbWVudCwgY29udGFpbmVyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChvcHRzLmZpbGVzKSB7XG4gICAgICB0aGlzLmZpbGVzID0geyAuLi50aGlzLmZpbGVzLCAuLi5vcHRzLmZpbGVzIH07XG4gICAgfVxuXG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuXG4gICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgIHtcbiAgICAgICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgICAgIC8vIGtlZXAgc2lkZWJhciAocHJlc3VtYWJseSB0aGUgbGlicmFyeSkgb3BlbiBpZiBpdCdzIGRvY2tlZCBhbmRcbiAgICAgICAgICAvLyBjYW4gZml0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gTm90ZSwgd2Ugc2hvdWxkIGNsb3NlIHRoZSBzaWRlYmFyIG9ubHkgaWYgd2UncmUgZHJvcHBpbmcgaXRlbXNcbiAgICAgICAgICAvLyBmcm9tIGxpYnJhcnksIG5vdCB3aGVuIHBhc3RpbmcgZnJvbSBjbGlwYm9hcmQuIEFsYXMuXG4gICAgICAgICAgb3BlblNpZGViYXI6XG4gICAgICAgICAgICB0aGlzLnN0YXRlLm9wZW5TaWRlYmFyICYmXG4gICAgICAgICAgICB0aGlzLmRldmljZS5jYW5EZXZpY2VGaXRTaWRlYmFyICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRlZmF1bHRTaWRlYmFyRG9ja2VkUHJlZmVyZW5jZVxuICAgICAgICAgICAgICA/IHRoaXMuc3RhdGUub3BlblNpZGViYXJcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogbmV3RWxlbWVudHMucmVkdWNlKFxuICAgICAgICAgICAgKGFjYzogUmVjb3JkPEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0sIHRydWU+LCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNCb3VuZFRvQ29udGFpbmVyKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgYWNjW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICksXG4gICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICApLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLnNldEFjdGl2ZVRvb2woeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgYWRkVGV4dEZyb21QYXN0ZSh0ZXh0OiBzdHJpbmcsIGlzUGxhaW5QYXN0ZSA9IGZhbHNlKSB7XG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IHRleHRFbGVtZW50UHJvcHMgPSB7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdW5kbmVzczogbnVsbCxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgdGV4dCxcbiAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIHRleHRBbGlnbjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVRleHRBbGlnbixcbiAgICAgIHZlcnRpY2FsQWxpZ246IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH07XG5cbiAgICBjb25zdCBMSU5FX0dBUCA9IDEwO1xuICAgIGxldCBjdXJyZW50WSA9IHk7XG5cbiAgICBjb25zdCBsaW5lcyA9IGlzUGxhaW5QYXN0ZSA/IFt0ZXh0XSA6IHRleHQuc3BsaXQoXCJcXG5cIik7XG4gICAgY29uc3QgdGV4dEVsZW1lbnRzID0gbGluZXMucmVkdWNlKFxuICAgICAgKGFjYzogRXhjYWxpZHJhd1RleHRFbGVtZW50W10sIGxpbmUsIGlkeCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gbGluZS50cmltKCk7XG5cbiAgICAgICAgY29uc3QgbGluZUhlaWdodCA9IGdldERlZmF1bHRMaW5lSGVpZ2h0KHRleHRFbGVtZW50UHJvcHMuZm9udEZhbWlseSk7XG4gICAgICAgIGlmICh0ZXh0Lmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdUZXh0RWxlbWVudCh7XG4gICAgICAgICAgICAuLi50ZXh0RWxlbWVudFByb3BzLFxuICAgICAgICAgICAgeCxcbiAgICAgICAgICAgIHk6IGN1cnJlbnRZLFxuICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgIGxpbmVIZWlnaHQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYWNjLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgY3VycmVudFkgKz0gZWxlbWVudC5oZWlnaHQgKyBMSU5FX0dBUDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBwcmV2TGluZSA9IGxpbmVzW2lkeCAtIDFdPy50cmltKCk7XG4gICAgICAgICAgLy8gYWRkIHBhcmFncmFwaCBvbmx5IGlmIHByZXZpb3VzIGxpbmUgd2FzIG5vdCBlbXB0eSwgSU9XIGRvbid0IGFkZFxuICAgICAgICAgIC8vIG1vcmUgdGhhbiBvbmUgZW1wdHkgbGluZVxuICAgICAgICAgIGlmIChwcmV2TGluZSkge1xuICAgICAgICAgICAgY3VycmVudFkgKz1cbiAgICAgICAgICAgICAgZ2V0TGluZUhlaWdodEluUHgodGV4dEVsZW1lbnRQcm9wcy5mb250U2l6ZSwgbGluZUhlaWdodCkgK1xuICAgICAgICAgICAgICBMSU5FX0dBUDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIFtdLFxuICAgICk7XG5cbiAgICBpZiAodGV4dEVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAuLi50ZXh0RWxlbWVudHMsXG4gICAgXSk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICB0ZXh0RWxlbWVudHMubWFwKChlbCkgPT4gW2VsLmlkLCB0cnVlXSksXG4gICAgICApLFxuICAgIH0pO1xuXG4gICAgaWYgKFxuICAgICAgIWlzUGxhaW5QYXN0ZSAmJlxuICAgICAgdGV4dEVsZW1lbnRzLmxlbmd0aCA+IDEgJiZcbiAgICAgIFBMQUlOX1BBU1RFX1RPQVNUX1NIT1dOID09PSBmYWxzZSAmJlxuICAgICAgIXRoaXMuZGV2aWNlLmlzTW9iaWxlXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFRvYXN0KHtcbiAgICAgICAgbWVzc2FnZTogdChcInRvYXN0LnBhc3RlQXNTaW5nbGVFbGVtZW50XCIsIHtcbiAgICAgICAgICBzaG9ydGN1dDogZ2V0U2hvcnRjdXRLZXkoXCJDdHJsT3JDbWQrU2hpZnQrVlwiKSxcbiAgICAgICAgfSksXG4gICAgICAgIGR1cmF0aW9uOiA1MDAwLFxuICAgICAgfSk7XG4gICAgICBQTEFJTl9QQVNURV9UT0FTVF9TSE9XTiA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICB9XG5cbiAgc2V0QXBwU3RhdGU6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdID0gKFxuICAgIHN0YXRlLFxuICAgIGNhbGxiYWNrLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHN0YXRlLCBjYWxsYmFjayk7XG4gIH07XG5cbiAgcmVtb3ZlUG9pbnRlciA9IChldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxFbGVtZW50PiB8IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgIGlmICh0b3VjaFRpbWVvdXQpIHtcbiAgICAgIHRoaXMucmVzZXRDb250ZXh0TWVudVRpbWVyKCk7XG4gICAgfVxuXG4gICAgZ2VzdHVyZS5wb2ludGVycy5kZWxldGUoZXZlbnQucG9pbnRlcklkKTtcbiAgfTtcblxuICB0b2dnbGVMb2NrID0gKHNvdXJjZTogXCJrZXlib2FyZFwiIHwgXCJ1aVwiID0gXCJ1aVwiKSA9PiB7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICB0cmFja0V2ZW50KFxuICAgICAgICBcInRvb2xiYXJcIixcbiAgICAgICAgXCJ0b2dnbGVMb2NrXCIsXG4gICAgICAgIGAke3NvdXJjZX0gKCR7dGhpcy5kZXZpY2UuaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCJ9KWAsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFjdGl2ZVRvb2w6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuYWN0aXZlVG9vbCxcbiAgICAgICAgICAuLi51cGRhdGVBY3RpdmVUb29sKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHByZXZTdGF0ZS5hY3RpdmVUb29sLmxvY2tlZFxuICAgICAgICAgICAgICA/IHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9XG4gICAgICAgICAgICAgIDogcHJldlN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBsb2NrZWQ6ICFwcmV2U3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIHRvZ2dsZVBlbk1vZGUgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwZW5Nb2RlOiAhcHJldlN0YXRlLnBlbk1vZGUsXG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIG9uSGFuZFRvb2xUb2dnbGUgPSAoKSA9PiB7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uVG9nZ2xlSGFuZFRvb2wpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBab29tcyBvbiBjYW52YXMgdmlld3BvcnQgY2VudGVyXG4gICAqL1xuICB6b29tQ2FudmFzID0gKFxuICAgIC8qKiBkZWNpbWFsIGZyYWN0aW9uIGJldHdlZW4gMC4xICgxMCUgem9vbSkgYW5kIDMwICgzMDAwJSB6b29tKSAqL1xuICAgIHZhbHVlOiBudW1iZXIsXG4gICkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLi4uZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICB7XG4gICAgICAgICAgdmlld3BvcnRYOiB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB2aWV3cG9ydFk6IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICAgIG5leHRab29tOiBnZXROb3JtYWxpemVkWm9vbSh2YWx1ZSksXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgY2FuY2VsSW5Qcm9ncmVzQW5pbWF0aW9uOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBzY3JvbGxUb0NvbnRlbnQgPSAoXG4gICAgdGFyZ2V0OlxuICAgICAgfCBFeGNhbGlkcmF3RWxlbWVudFxuICAgICAgfCByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICBvcHRzPzogeyBmaXRUb0NvbnRlbnQ/OiBib29sZWFuOyBhbmltYXRlPzogYm9vbGVhbjsgZHVyYXRpb24/OiBudW1iZXIgfSxcbiAgKSA9PiB7XG4gICAgdGhpcy5jYW5jZWxJblByb2dyZXNBbmltYXRpb24/LigpO1xuXG4gICAgLy8gY29udmVydCBwcm92aWRlZCB0YXJnZXQgaW50byBFeGNhbGlkcmF3RWxlbWVudFtdIGlmIG5lY2Vzc2FyeVxuICAgIGNvbnN0IHRhcmdldHMgPSBBcnJheS5pc0FycmF5KHRhcmdldCkgPyB0YXJnZXQgOiBbdGFyZ2V0XTtcblxuICAgIGxldCB6b29tID0gdGhpcy5zdGF0ZS56b29tO1xuICAgIGxldCBzY3JvbGxYID0gdGhpcy5zdGF0ZS5zY3JvbGxYO1xuICAgIGxldCBzY3JvbGxZID0gdGhpcy5zdGF0ZS5zY3JvbGxZO1xuXG4gICAgaWYgKG9wdHM/LmZpdFRvQ29udGVudCkge1xuICAgICAgLy8gY29tcHV0ZSBhbiBhcHByb3ByaWF0ZSB2aWV3cG9ydCBsb2NhdGlvbiAoc2Nyb2xsIFgsIFkpIGFuZCB6b29tIGxldmVsXG4gICAgICAvLyB0aGF0IGZpdCB0aGUgdGFyZ2V0IGVsZW1lbnRzIG9uIHRoZSBzY2VuZVxuICAgICAgY29uc3QgeyBhcHBTdGF0ZSB9ID0gem9vbVRvRml0RWxlbWVudHModGFyZ2V0cywgdGhpcy5zdGF0ZSwgZmFsc2UpO1xuICAgICAgem9vbSA9IGFwcFN0YXRlLnpvb207XG4gICAgICBzY3JvbGxYID0gYXBwU3RhdGUuc2Nyb2xsWDtcbiAgICAgIHNjcm9sbFkgPSBhcHBTdGF0ZS5zY3JvbGxZO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjb21wdXRlIG9ubHkgdGhlIHZpZXdwb3J0IGxvY2F0aW9uLCB3aXRob3V0IGFueSB6b29tIGFkanVzdG1lbnRcbiAgICAgIGNvbnN0IHNjcm9sbCA9IGNhbGN1bGF0ZVNjcm9sbENlbnRlcih0YXJnZXRzLCB0aGlzLnN0YXRlLCB0aGlzLmNhbnZhcyk7XG4gICAgICBzY3JvbGxYID0gc2Nyb2xsLnNjcm9sbFg7XG4gICAgICBzY3JvbGxZID0gc2Nyb2xsLnNjcm9sbFk7XG4gICAgfVxuXG4gICAgLy8gd2hlbiBhbmltYXRpbmcsIHdlIHVzZSBSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgdG8gcHJldmVudCB0aGUgYW5pbWF0aW9uXG4gICAgLy8gZnJvbSBzbG93aW5nIGRvd24gb3RoZXIgcHJvY2Vzc2VzXG4gICAgaWYgKG9wdHM/LmFuaW1hdGUpIHtcbiAgICAgIGNvbnN0IG9yaWdTY3JvbGxYID0gdGhpcy5zdGF0ZS5zY3JvbGxYO1xuICAgICAgY29uc3Qgb3JpZ1Njcm9sbFkgPSB0aGlzLnN0YXRlLnNjcm9sbFk7XG5cbiAgICAgIC8vIHpvb20gYW5pbWF0aW9uIGNvdWxkIGJlY29tZSBwcm9ibGVtYXRpYyBvbiBzY2VuZXMgd2l0aCBsYXJnZSBudW1iZXJcbiAgICAgIC8vIG9mIGVsZW1lbnRzLCBzZXR0aW5nIGl0IHRvIGl0cyBmaW5hbCB2YWx1ZSB0byBpbXByb3ZlIHVzZXIgZXhwZXJpZW5jZS5cbiAgICAgIC8vXG4gICAgICAvLyB1c2luZyB6b29tQ2FudmFzKCkgdG8gem9vbSBvbiBjdXJyZW50IHZpZXdwb3J0IGNlbnRlclxuICAgICAgdGhpcy56b29tQ2FudmFzKHpvb20udmFsdWUpO1xuXG4gICAgICBjb25zdCBjYW5jZWwgPSBlYXNlVG9WYWx1ZXNSQUYoXG4gICAgICAgIFtvcmlnU2Nyb2xsWCwgb3JpZ1Njcm9sbFldLFxuICAgICAgICBbc2Nyb2xsWCwgc2Nyb2xsWV0sXG4gICAgICAgIChzY3JvbGxYLCBzY3JvbGxZKSA9PiB0aGlzLnNldFN0YXRlKHsgc2Nyb2xsWCwgc2Nyb2xsWSB9KSxcbiAgICAgICAgeyBkdXJhdGlvbjogb3B0cz8uZHVyYXRpb24gPz8gNTAwIH0sXG4gICAgICApO1xuICAgICAgdGhpcy5jYW5jZWxJblByb2dyZXNBbmltYXRpb24gPSAoKSA9PiB7XG4gICAgICAgIGNhbmNlbCgpO1xuICAgICAgICB0aGlzLmNhbmNlbEluUHJvZ3Jlc0FuaW1hdGlvbiA9IG51bGw7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2Nyb2xsWCwgc2Nyb2xsWSwgem9vbSB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIHVzZSB3aGVuIGNoYW5naW5nIHNjcm9sbFgvc2Nyb2xsWS96b29tIGJhc2VkIG9uIHVzZXIgaW50ZXJhY3Rpb24gKi9cbiAgcHJpdmF0ZSB0cmFuc2xhdGVDYW52YXM6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdID0gKFxuICAgIHN0YXRlLFxuICApID0+IHtcbiAgICB0aGlzLmNhbmNlbEluUHJvZ3Jlc0FuaW1hdGlvbj8uKCk7XG4gICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSk7XG4gIH07XG5cbiAgc2V0VG9hc3QgPSAoXG4gICAgdG9hc3Q6IHtcbiAgICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICAgIGNsb3NhYmxlPzogYm9vbGVhbjtcbiAgICAgIGR1cmF0aW9uPzogbnVtYmVyO1xuICAgIH0gfCBudWxsLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgdG9hc3QgfSk7XG4gIH07XG5cbiAgcmVzdG9yZUZpbGVGcm9tU2hhcmUgPSBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUgPSBhd2FpdCBjYWNoZXMub3BlbihcIndlYi1zaGFyZS10YXJnZXRcIik7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5tYXRjaChcInNoYXJlZC1maWxlXCIpO1xuICAgICAgaWYgKHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBhd2FpdCByZXNwb25zZS5ibG9iKCk7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBuZXcgRmlsZShbYmxvYl0sIGJsb2IubmFtZSB8fCBcIlwiLCB7IHR5cGU6IGJsb2IudHlwZSB9KTtcbiAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUsIG51bGwpO1xuICAgICAgICBhd2FpdCB3ZWJTaGFyZVRhcmdldENhY2hlLmRlbGV0ZShcInNoYXJlZC1maWxlXCIpO1xuICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgQVBQX05BTUUsIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIGFkZHMgc3VwcGxpZWQgZmlsZXMgdG8gZXhpc3RpbmcgZmlsZXMgaW4gdGhlIGFwcFN0YXRlICovXG4gIHB1YmxpYyBhZGRGaWxlczogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUElbXCJhZGRGaWxlc1wiXSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZmlsZXMpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVzTWFwID0gZmlsZXMucmVkdWNlKChhY2MsIGZpbGVEYXRhKSA9PiB7XG4gICAgICAgIGFjYy5zZXQoZmlsZURhdGEuaWQsIGZpbGVEYXRhKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIG5ldyBNYXA8RmlsZUlkLCBCaW5hcnlGaWxlRGF0YT4oKSk7XG5cbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLk9iamVjdC5mcm9tRW50cmllcyhmaWxlc01hcCkgfTtcblxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgZmlsZXNNYXAuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZGVsZXRlKGVsZW1lbnQuZmlsZUlkKTtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcblxuICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICB9LFxuICApO1xuXG4gIHB1YmxpYyB1cGRhdGVTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICA8SyBleHRlbmRzIGtleW9mIEFwcFN0YXRlPihzY2VuZURhdGE6IHtcbiAgICAgIGVsZW1lbnRzPzogU2NlbmVEYXRhW1wiZWxlbWVudHNcIl07XG4gICAgICBhcHBTdGF0ZT86IFBpY2s8QXBwU3RhdGUsIEs+IHwgbnVsbDtcbiAgICAgIGNvbGxhYm9yYXRvcnM/OiBTY2VuZURhdGFbXCJjb2xsYWJvcmF0b3JzXCJdO1xuICAgICAgY29tbWl0VG9IaXN0b3J5PzogU2NlbmVEYXRhW1wiY29tbWl0VG9IaXN0b3J5XCJdO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChzY2VuZURhdGEuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5hcHBTdGF0ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHNjZW5lRGF0YS5hcHBTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoc2NlbmVEYXRhLmVsZW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5jb2xsYWJvcmF0b3JzKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb2xsYWJvcmF0b3JzOiBzY2VuZURhdGEuY29sbGFib3JhdG9ycyB9KTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25TY2VuZVVwZGF0ZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIG1lbnUgd2FzIHRvZ2dsZWQgb24gb3Igb2ZmXG4gICAqL1xuICBwdWJsaWMgdG9nZ2xlU2lkZWJhciA9ICh7XG4gICAgbmFtZSxcbiAgICB0YWIsXG4gICAgZm9yY2UsXG4gIH06IHtcbiAgICBuYW1lOiBTaWRlYmFyTmFtZTtcbiAgICB0YWI/OiBTaWRlYmFyVGFiTmFtZTtcbiAgICBmb3JjZT86IGJvb2xlYW47XG4gIH0pOiBib29sZWFuID0+IHtcbiAgICBsZXQgbmV4dE5hbWU7XG4gICAgaWYgKGZvcmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5leHROYW1lID0gdGhpcy5zdGF0ZS5vcGVuU2lkZWJhcj8ubmFtZSA9PT0gbmFtZSA/IG51bGwgOiBuYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0TmFtZSA9IGZvcmNlID8gbmFtZSA6IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuU2lkZWJhcjogbmV4dE5hbWUgPyB7IG5hbWU6IG5leHROYW1lLCB0YWIgfSA6IG51bGwgfSk7XG5cbiAgICByZXR1cm4gISFuZXh0TmFtZTtcbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbiA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIGN1cnNvclggPSBldmVudC5jbGllbnRYO1xuICAgICAgY3Vyc29yWSA9IGV2ZW50LmNsaWVudFk7XG4gICAgfSxcbiAgKTtcblxuICAvLyBJbnB1dCBoYW5kbGluZ1xuICBwcml2YXRlIG9uS2V5RG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IFJlYWN0LktleWJvYXJkRXZlbnQgfCBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBub3JtYWxpemUgYGV2ZW50LmtleWAgd2hlbiBDYXBzTG9jayBpcyBwcmVzc2VkICMyMzcyXG5cbiAgICAgIGlmIChcbiAgICAgICAgXCJQcm94eVwiIGluIHdpbmRvdyAmJlxuICAgICAgICAoKCFldmVudC5zaGlmdEtleSAmJiAvXltBLVpdJC8udGVzdChldmVudC5rZXkpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleSAmJiAvXlthLXpdJC8udGVzdChldmVudC5rZXkpKSlcbiAgICAgICkge1xuICAgICAgICBldmVudCA9IG5ldyBQcm94eShldmVudCwge1xuICAgICAgICAgIGdldChldjogYW55LCBwcm9wKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGV2W3Byb3BdO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgIC8vIGZpeCBmb3IgUHJveGllcyBoaWphY2tpbmcgYHRoaXNgXG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5iaW5kKGV2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwcm9wID09PSBcImtleVwiXG4gICAgICAgICAgICAgID8gLy8gQ2Fwc0xvY2sgaW52ZXJ0cyBjYXBpdGFsaXphdGlvbiBiYXNlZCBvbiBTaGlmdEtleSwgc28gaW52ZXJ0XG4gICAgICAgICAgICAgICAgLy8gaXQgYmFja1xuICAgICAgICAgICAgICAgIGV2ZW50LnNoaWZ0S2V5XG4gICAgICAgICAgICAgICAgPyBldi5rZXkudG9VcHBlckNhc2UoKVxuICAgICAgICAgICAgICAgIDogZXYua2V5LnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmIGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpID09PSBLRVlTLlYpIHtcbiAgICAgICAgSVNfUExBSU5fUEFTVEUgPSBldmVudC5zaGlmdEtleTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KElTX1BMQUlOX1BBU1RFX1RJTUVSKTtcbiAgICAgICAgLy8gcmVzZXQgKDEwMG1zIHRvIGJlIHNhZmUgdGhhdCB3ZSBpdCBydW5zIGFmdGVyIHRoZSBlbnN1aW5nXG4gICAgICAgIC8vIHBhc3RlIGV2ZW50KS4gVGhvdWdoLCB0ZWNobmljYWxseSB1bm5lY2Vzc2FyeSB0byByZXNldCBzaW5jZSB3ZVxuICAgICAgICAvLyAocmUpc2V0IHRoZSBmbGFnIGJlZm9yZSBlYWNoIHBhc3RlIGV2ZW50LlxuICAgICAgICBJU19QTEFJTl9QQVNURV9USU1FUiA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBJU19QTEFJTl9QQVNURSA9IGZhbHNlO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgfVxuXG4gICAgICAvLyBwcmV2ZW50IGJyb3dzZXIgem9vbSBpbiBpbnB1dCBmaWVsZHNcbiAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiBpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpKSB7XG4gICAgICAgIGlmIChldmVudC5jb2RlID09PSBDT0RFUy5NSU5VUyB8fCBldmVudC5jb2RlID09PSBDT0RFUy5FUVVBTCkge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGJhaWwgaWZcbiAgICAgIGlmIChcbiAgICAgICAgLy8gaW5zaWRlIGFuIGlucHV0XG4gICAgICAgIChpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpICYmXG4gICAgICAgICAgLy8gdW5sZXNzIHByZXNzaW5nIGVzY2FwZSAoZmluYWxpemUgYWN0aW9uKVxuICAgICAgICAgIGV2ZW50LmtleSAhPT0gS0VZUy5FU0NBUEUpIHx8XG4gICAgICAgIC8vIG9yIHVubGVzcyB1c2luZyBhcnJvd3MgKHRvIG1vdmUgYmV0d2VlbiBidXR0b25zKVxuICAgICAgICAoaXNBcnJvd0tleShldmVudC5rZXkpICYmIGlzSW5wdXRMaWtlKGV2ZW50LnRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlFVRVNUSU9OX01BUkspIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgb3BlbkRpYWxvZzogXCJoZWxwXCIsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBldmVudC5rZXkudG9Mb3dlckNhc2UoKSA9PT0gS0VZUy5FICYmXG4gICAgICAgIGV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgIGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5EaWFsb2c6IFwiaW1hZ2VFeHBvcnRcIiB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlBBR0VfVVAgfHwgZXZlbnQua2V5ID09PSBLRVlTLlBBR0VfRE9XTikge1xuICAgICAgICBsZXQgb2Zmc2V0ID1cbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXkgPyB0aGlzLnN0YXRlLndpZHRoIDogdGhpcy5zdGF0ZS5oZWlnaHQpIC9cbiAgICAgICAgICB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUEFHRV9ET1dOKSB7XG4gICAgICAgICAgb2Zmc2V0ID0gLW9mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcygoc3RhdGUpID0+ICh7XG4gICAgICAgICAgICBzY3JvbGxYOiBzdGF0ZS5zY3JvbGxYICsgb2Zmc2V0LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcygoc3RhdGUpID0+ICh7XG4gICAgICAgICAgICBzY3JvbGxZOiBzdGF0ZS5zY3JvbGxZICsgb2Zmc2V0LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hY3Rpb25NYW5hZ2VyLmhhbmRsZUtleURvd24oZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmIHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9XG4gICAgICAgICAgKHRoaXMuc3RhdGUuZ3JpZFNpemUgJiZcbiAgICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICA/IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVFxuICAgICAgICAgICAgICA6IHRoaXMuc3RhdGUuZ3JpZFNpemUpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgPyBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgIDogRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5UKTtcblxuICAgICAgICBsZXQgb2Zmc2V0WCA9IDA7XG4gICAgICAgIGxldCBvZmZzZXRZID0gMDtcblxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0xFRlQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1JJR0hUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IHN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1VQKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19ET1dOKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IHN0ZXA7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHg6IGVsZW1lbnQueCArIG9mZnNldFgsXG4gICAgICAgICAgICB5OiBlbGVtZW50LnkgKyBvZmZzZXRZLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdXBkYXRlQm91bmRFbGVtZW50cyhlbGVtZW50LCB7XG4gICAgICAgICAgICBzaW11bHRhbmVvdXNseVVwZGF0ZWQ6IHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuRU5URVIpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuICAgICAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSkge1xuICAgICAgICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PVxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgaXNUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnQpIHx8XG4gICAgICAgICAgICBpc1ZhbGlkVGV4dENvbnRhaW5lcihzZWxlY3RlZEVsZW1lbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBsZXQgY29udGFpbmVyO1xuICAgICAgICAgICAgaWYgKCFpc1RleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgY29udGFpbmVyID0gc2VsZWN0ZWRFbGVtZW50IGFzIEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWlkUG9pbnQgPSBnZXRDb250YWluZXJDZW50ZXIoc2VsZWN0ZWRFbGVtZW50LCB0aGlzLnN0YXRlKTtcbiAgICAgICAgICAgIGNvbnN0IHNjZW5lWCA9IG1pZFBvaW50Lng7XG4gICAgICAgICAgICBjb25zdCBzY2VuZVkgPSBtaWRQb2ludC55O1xuICAgICAgICAgICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgICAgICAgICAgc2NlbmVYLFxuICAgICAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgICAgIGNvbnRhaW5lcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICFldmVudC5jdHJsS2V5ICYmXG4gICAgICAgICFldmVudC5hbHRLZXkgJiZcbiAgICAgICAgIWV2ZW50Lm1ldGFLZXkgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgPT09IG51bGxcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzaGFwZSA9IGZpbmRTaGFwZUJ5S2V5KGV2ZW50LmtleSk7XG4gICAgICAgIGlmIChzaGFwZSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gc2hhcGUpIHtcbiAgICAgICAgICAgIHRyYWNrRXZlbnQoXG4gICAgICAgICAgICAgIFwidG9vbGJhclwiLFxuICAgICAgICAgICAgICBzaGFwZSxcbiAgICAgICAgICAgICAgYGtleWJvYXJkICgke3RoaXMuZGV2aWNlLmlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwifSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZXRBY3RpdmVUb29sKHsgdHlwZTogc2hhcGUgfSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlEpIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZUxvY2soXCJrZXlib2FyZFwiKTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSAmJiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDApIHtcbiAgICAgICAgaXNIb2xkaW5nU3BhY2UgPSB0cnVlO1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIChldmVudC5rZXkgPT09IEtFWVMuRyB8fCBldmVudC5rZXkgPT09IEtFWVMuUykgJiZcbiAgICAgICAgIWV2ZW50LmFsdEtleSAmJlxuICAgICAgICAhZXZlbnRbS0VZUy5DVFJMX09SX0NNRF1cbiAgICAgICkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICAgICFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkcgJiZcbiAgICAgICAgICAoaGFzQmFja2dyb3VuZCh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSkgfHxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT4gaGFzQmFja2dyb3VuZChlbGVtZW50LnR5cGUpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5Qb3B1cDogXCJlbGVtZW50QmFja2dyb3VuZFwiIH0pO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUykge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwiZWxlbWVudFN0cm9rZVwiIH0pO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiZcbiAgICAgICAgKGV2ZW50LmtleSA9PT0gS0VZUy5CQUNLU1BBQ0UgfHwgZXZlbnQua2V5ID09PSBLRVlTLkRFTEVURSlcbiAgICAgICkge1xuICAgICAgICBqb3RhaVN0b3JlLnNldChhY3RpdmVDb25maXJtRGlhbG9nQXRvbSwgXCJjbGVhckNhbnZhc1wiKTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25XaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICAvLyBwcmV2ZW50IGJyb3dzZXIgcGluY2ggem9vbSBvbiBET00gZWxlbWVudHNcbiAgICBpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkgJiYgZXZlbnQuY3RybEtleSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgb25LZXlVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gICAgfVxuICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpXG4gICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBzZXRBY3RpdmVUb29sID0gKFxuICAgIHRvb2w6XG4gICAgICB8IHtcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgU0hBUEVTW251bWJlcl1bXCJ2YWx1ZVwiXSB8IFwiZXJhc2VyXCIgfCBcImhhbmRcIjtcbiAgICAgICAgICBsb2NrZWQ/OiBib29sZWFuO1xuICAgICAgICB9XG4gICAgICB8IHsgdHlwZTogXCJjdXN0b21cIjsgY3VzdG9tVHlwZTogc3RyaW5nOyBsb2NrZWQ/OiBib29sZWFuIH0sXG4gICkgPT4ge1xuICAgIGNvbnN0IG5leHRBY3RpdmVUb29sID0gdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB0b29sKTtcbiAgICBpZiAobmV4dEFjdGl2ZVRvb2wudHlwZSA9PT0gXCJoYW5kXCIpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgfSBlbHNlIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgaWYgKGlzVG9vbEljb24oZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG4gICAgaWYgKCFpc0xpbmVhckVsZW1lbnRUeXBlKG5leHRBY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgICBpZiAobmV4dEFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICB0aGlzLm9uSW1hZ2VBY3Rpb24oKTtcbiAgICB9XG4gICAgaWYgKG5leHRBY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiBuZXh0QWN0aXZlVG9vbCxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBhY3RpdmVUb29sOiBuZXh0QWN0aXZlVG9vbCB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRDdXJzb3IgPSAoY3Vyc29yOiBzdHJpbmcpID0+IHtcbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIGN1cnNvcik7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEN1cnNvciA9ICgpID0+IHtcbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gIH07XG4gIC8qKlxuICAgKiByZXR1cm5zIHdoZXRoZXIgdXNlciBpcyBtYWtpbmcgYSBnZXN0dXJlIHdpdGggPj0gMiBmaW5nZXJzIChwb2ludHMpXG4gICAqIG9uIG8gdG91Y2ggc2NyZWVuIChub3Qgb24gYSB0cmFja3BhZCkuIEN1cnJlbnRseSBvbmx5IHJlbGF0ZXMgdG8gRGFyd2luXG4gICAqIChpT1MvaVBhZE9TLE1hY09TKSwgYnV0IG1heSB3b3JrIG9uIG90aGVyIGRldmljZXMgaW4gdGhlIGZ1dHVyZSBpZlxuICAgKiBHZXN0dXJlRXZlbnQgaXMgc3RhbmRhcmRpemVkLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUgPSAoKSA9PiB7XG4gICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBkZXNlbGVjdCB3aGVuIHVzaW5nIHRyYWNrcGFkLCBhbmQgbXVsdGktcG9pbnQgZ2VzdHVyZXNcbiAgICAvLyBvbmx5IHdvcmsgb24gdG91Y2ggc2NyZWVucywgc28gY2hlY2tpbmcgZm9yID49IHBvaW50ZXJzIG1lYW5zIHdlJ3JlIG9uIGFcbiAgICAvLyB0b3VjaHNjcmVlblxuICAgIHJldHVybiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPj0gMjtcbiAgfTtcblxuICAvLyBmaXJlcyBvbmx5IG9uIFNhZmFyaVxuICBwcml2YXRlIG9uR2VzdHVyZVN0YXJ0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIHdlIG9ubHkgd2FudCB0byBkZXNlbGVjdCBvbiB0b3VjaCBzY3JlZW5zIGJlY2F1c2UgdXNlciBtYXkgaGF2ZSBzZWxlY3RlZFxuICAgIC8vIGVsZW1lbnRzIGJ5IG1pc3Rha2Ugd2hpbGUgem9vbWluZ1xuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgfSk7XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVDaGFuZ2UgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gb25HZXN0dXJlQ2hhbmdlIG9ubHkgaGFzIHpvb20gZmFjdG9yIGJ1dCBub3QgdGhlIGNlbnRlci5cbiAgICAvLyBJZiB3ZSdyZSBvbiBpUGFkIG9yIGlQaG9uZSwgdGhlbiB3ZSByZWNvZ25pemUgbXVsdGktdG91Y2ggYW5kIHdpbGxcbiAgICAvLyB6b29tIGluIGF0IHRoZSByaWdodCBsb2NhdGlvbiBpbiB0aGUgdG91Y2htb3ZlIGhhbmRsZXJcbiAgICAvLyAoaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUpLlxuICAgIC8vXG4gICAgLy8gT24gTWFjYm9vayB0cmFja3BhZCwgd2UgZG9uJ3QgaGF2ZSB0aG9zZSBldmVudHMgc28gd2lsbCB6b29tIGluIGF0IHRoZVxuICAgIC8vIGN1cnJlbnQgbG9jYXRpb24gaW5zdGVhZC5cbiAgICAvL1xuICAgIC8vIEFzIHN1Y2gsIGJhaWwgZnJvbSB0aGlzIGhhbmRsZXIgb24gdG91Y2ggZGV2aWNlcy5cbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChpbml0aWFsU2NhbGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXRTdGF0ZUZvclpvb20oXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmlld3BvcnRYOiBjdXJzb3JYLFxuICAgICAgICAgICAgdmlld3BvcnRZOiBjdXJzb3JZLFxuICAgICAgICAgICAgbmV4dFpvb206IGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIGV2ZW50LnNjYWxlKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVFbmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIC8vIHJlc2VsZWN0IGVsZW1lbnRzIG9ubHkgb24gdG91Y2ggc2NyZWVucyAoc2VlIG9uR2VzdHVyZVN0YXJ0KVxuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSBudWxsO1xuICB9KTtcblxuICBwcml2YXRlIGhhbmRsZVRleHRXeXNpd3lnKFxuICAgIGVsZW1lbnQ6IEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgICB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudCA9IGZhbHNlLFxuICAgIH06IHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50PzogYm9vbGVhbjtcbiAgICB9LFxuICApIHtcbiAgICBjb25zdCB1cGRhdGVFbGVtZW50ID0gKFxuICAgICAgdGV4dDogc3RyaW5nLFxuICAgICAgb3JpZ2luYWxUZXh0OiBzdHJpbmcsXG4gICAgICBpc0RlbGV0ZWQ6IGJvb2xlYW4sXG4gICAgKSA9PiB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChfZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChfZWxlbWVudC5pZCA9PT0gZWxlbWVudC5pZCAmJiBpc1RleHRFbGVtZW50KF9lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVRleHRFbGVtZW50KF9lbGVtZW50LCB7XG4gICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgIGlzRGVsZXRlZCxcbiAgICAgICAgICAgICAgb3JpZ2luYWxUZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBfZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICBdKTtcbiAgICB9O1xuXG4gICAgdGV4dFd5c2l3eWcoe1xuICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICBjYW52YXM6IHRoaXMuY2FudmFzLFxuICAgICAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4LCB5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgICAgICBzY2VuZVk6IHksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHZpZXdwb3J0WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB2aWV3cG9ydFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgXTtcbiAgICAgIH0sXG4gICAgICBvbkNoYW5nZTogd2l0aEJhdGNoZWRVcGRhdGVzKCh0ZXh0KSA9PiB7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgdGV4dCwgZmFsc2UpO1xuICAgICAgICBpZiAoaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgb25TdWJtaXQ6IHdpdGhCYXRjaGVkVXBkYXRlcygoeyB0ZXh0LCB2aWFLZXlib2FyZCwgb3JpZ2luYWxUZXh0IH0pID0+IHtcbiAgICAgICAgY29uc3QgaXNEZWxldGVkID0gIXRleHQudHJpbSgpO1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIG9yaWdpbmFsVGV4dCwgaXNEZWxldGVkKTtcbiAgICAgICAgLy8gc2VsZWN0IHRoZSBjcmVhdGVkIHRleHQgZWxlbWVudCBvbmx5IGlmIHN1Ym1pdHRpbmcgdmlhIGtleWJvYXJkXG4gICAgICAgIC8vICh3aGVuIHN1Ym1pdHRpbmcgdmlhIGNsaWNrIGl0IHNob3VsZCBhY3QgYXMgc2lnbmFsIHRvIGRlc2VsZWN0KVxuICAgICAgICBpZiAoIWlzRGVsZXRlZCAmJiB2aWFLZXlib2FyZCkge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRJZFRvU2VsZWN0ID0gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgPyBlbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgICAgICA6IGVsZW1lbnQuaWQ7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgIFtlbGVtZW50SWRUb1NlbGVjdF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWxldGVkKSB7XG4gICAgICAgICAgZml4QmluZGluZ3NBZnRlckRlbGV0aW9uKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIFtcbiAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgfHwgaXNFeGlzdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICAgIH0pLFxuICAgICAgZWxlbWVudCxcbiAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgYXBwOiB0aGlzLFxuICAgIH0pO1xuICAgIC8vIGRlc2VsZWN0IGFsbCBvdGhlciBlbGVtZW50cyB3aGVuIGluc2VydGluZyB0ZXh0XG4gICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG5cbiAgICAvLyBkbyBhbiBpbml0aWFsIHVwZGF0ZSB0byByZS1pbml0aWFsaXplIGVsZW1lbnQgcG9zaXRpb24gc2luY2Ugd2Ugd2VyZVxuICAgIC8vIG1vZGlmeWluZyBlbGVtZW50J3MgeC95IGZvciBzYWtlIG9mIGVkaXRvciAoY2FzZTogc3luY2luZyB0byByZW1vdGUpXG4gICAgdXBkYXRlRWxlbWVudChlbGVtZW50LnRleHQsIGVsZW1lbnQub3JpZ2luYWxUZXh0LCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIGRlc2VsZWN0RWxlbWVudHMoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd1RleHRFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiB0cnVlLFxuICAgIH0pO1xuICAgIGlmIChlbGVtZW50ICYmIGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgIWVsZW1lbnQuaXNEZWxldGVkKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgb3B0cz86IHtcbiAgICAgIC8qKiBpZiB0cnVlLCByZXR1cm5zIHRoZSBmaXJzdCBzZWxlY3RlZCBlbGVtZW50ICh3aXRoIGhpZ2hlc3Qgei1pbmRleClcbiAgICAgICAgb2YgYWxsIGhpdCBlbGVtZW50cyAqL1xuICAgICAgcHJlZmVyU2VsZWN0ZWQ/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUxvY2tlZEVsZW1lbnRzPzogYm9vbGVhbjtcbiAgICB9LFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGFsbEhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIG9wdHM/LmluY2x1ZGVCb3VuZFRleHRFbGVtZW50LFxuICAgICAgb3B0cz8uaW5jbHVkZUxvY2tlZEVsZW1lbnRzLFxuICAgICk7XG4gICAgaWYgKGFsbEhpdEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGlmIChvcHRzPy5wcmVmZXJTZWxlY3RlZCkge1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IGFsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDE7IGluZGV4ID4gLTE7IGluZGV4LS0pIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbYWxsSGl0RWxlbWVudHNbaW5kZXhdLmlkXSkge1xuICAgICAgICAgICAgcmV0dXJuIGFsbEhpdEVsZW1lbnRzW2luZGV4XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleCA9XG4gICAgICAgIGFsbEhpdEVsZW1lbnRzW2FsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgLy8gSWYgd2UncmUgaGl0dGluZyBlbGVtZW50IHdpdGggaGlnaGVzdCB6LWluZGV4IG9ubHkgb24gaXRzIGJvdW5kaW5nIGJveFxuICAgICAgLy8gd2hpbGUgYWxzbyBoaXR0aW5nIG90aGVyIGVsZW1lbnQgZmlndXJlLCB0aGUgbGF0dGVyIHNob3VsZCBiZSBjb25zaWRlcmVkLlxuICAgICAgcmV0dXJuIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgKVxuICAgICAgICA/IGFsbEhpdEVsZW1lbnRzW2FsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDJdXG4gICAgICAgIDogZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4O1xuICAgIH1cbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbMF07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogYm9vbGVhbiA9IGZhbHNlLFxuICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50czogYm9vbGVhbiA9IGZhbHNlLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdIHtcbiAgICBjb25zdCBlbGVtZW50cyA9XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudCAmJiBpbmNsdWRlTG9ja2VkRWxlbWVudHNcbiAgICAgICAgPyB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgIDogdGhpcy5zY2VuZVxuICAgICAgICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAoZWxlbWVudCkgPT5cbiAgICAgICAgICAgICAgICAoaW5jbHVkZUxvY2tlZEVsZW1lbnRzIHx8ICFlbGVtZW50LmxvY2tlZCkgJiZcbiAgICAgICAgICAgICAgICAoaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQgfHxcbiAgICAgICAgICAgICAgICAgICEoaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiBlbGVtZW50LmNvbnRhaW5lcklkKSksXG4gICAgICAgICAgICApO1xuXG4gICAgcmV0dXJuIGdldEVsZW1lbnRzQXRQb3NpdGlvbihlbGVtZW50cywgKGVsZW1lbnQpID0+XG4gICAgICBoaXRUZXN0KGVsZW1lbnQsIHRoaXMuc3RhdGUsIHgsIHkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0VGV4dEVkaXRpbmcgPSAoe1xuICAgIHNjZW5lWCxcbiAgICBzY2VuZVksXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgPSB0cnVlLFxuICAgIGNvbnRhaW5lcixcbiAgfToge1xuICAgIC8qKiBYIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgLyoqIFkgcG9zaXRpb24gdG8gaW5zZXJ0IHRleHQgYXQgKi9cbiAgICBzY2VuZVk6IG51bWJlcjtcbiAgICAvKiogd2hldGhlciB0byBhdHRlbXB0IHRvIGluc2VydCBhdCBlbGVtZW50IGNlbnRlciBpZiBhcHBsaWNhYmxlICovXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI/OiBib29sZWFuO1xuICAgIGNvbnRhaW5lcj86IEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyIHwgbnVsbDtcbiAgfSkgPT4ge1xuICAgIGxldCBzaG91bGRCaW5kVG9Db250YWluZXIgPSBmYWxzZTtcblxuICAgIGxldCBwYXJlbnRDZW50ZXJQb3NpdGlvbiA9XG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlciAmJlxuICAgICAgdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgY29udGFpbmVyLFxuICAgICAgKTtcbiAgICBpZiAoY29udGFpbmVyICYmIHBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICBzaG91bGRCaW5kVG9Db250YWluZXIgPSB0cnVlO1xuICAgIH1cbiAgICBsZXQgZXhpc3RpbmdUZXh0RWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3VGV4dEVsZW1lbnQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGlmIChpc1RleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuICAgICAgfSBlbHNlIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IGdldEJvdW5kVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5nZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5nZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvbnRGYW1pbHkgPVxuICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudD8uZm9udEZhbWlseSB8fCB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseTtcblxuICAgIGNvbnN0IGxpbmVIZWlnaHQgPVxuICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudD8ubGluZUhlaWdodCB8fCBnZXREZWZhdWx0TGluZUhlaWdodChmb250RmFtaWx5KTtcbiAgICBjb25zdCBmb250U2l6ZSA9IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250U2l6ZTtcblxuICAgIGlmIChcbiAgICAgICFleGlzdGluZ1RleHRFbGVtZW50ICYmXG4gICAgICBzaG91bGRCaW5kVG9Db250YWluZXIgJiZcbiAgICAgIGNvbnRhaW5lciAmJlxuICAgICAgIWlzQXJyb3dFbGVtZW50KGNvbnRhaW5lcilcbiAgICApIHtcbiAgICAgIGNvbnN0IGZvbnRTdHJpbmcgPSB7XG4gICAgICAgIGZvbnRTaXplLFxuICAgICAgICBmb250RmFtaWx5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1pbldpZHRoID0gZ2V0QXBwcm94TWluTGluZVdpZHRoKFxuICAgICAgICBnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpLFxuICAgICAgICBsaW5lSGVpZ2h0LFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG1pbkhlaWdodCA9IGdldEFwcHJveE1pbkxpbmVIZWlnaHQoZm9udFNpemUsIGxpbmVIZWlnaHQpO1xuICAgICAgY29uc3QgY29udGFpbmVyRGltcyA9IGdldENvbnRhaW5lckRpbXMoY29udGFpbmVyKTtcbiAgICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KGNvbnRhaW5lckRpbXMuaGVpZ2h0LCBtaW5IZWlnaHQpO1xuICAgICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLm1heChjb250YWluZXJEaW1zLndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IG5ld0hlaWdodCwgd2lkdGg6IG5ld1dpZHRoIH0pO1xuICAgICAgc2NlbmVYID0gY29udGFpbmVyLnggKyBuZXdXaWR0aCAvIDI7XG4gICAgICBzY2VuZVkgPSBjb250YWluZXIueSArIG5ld0hlaWdodCAvIDI7XG4gICAgICBpZiAocGFyZW50Q2VudGVyUG9zaXRpb24pIHtcbiAgICAgICAgcGFyZW50Q2VudGVyUG9zaXRpb24gPSB0aGlzLmdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgICAgICAgc2NlbmVYLFxuICAgICAgICAgIHNjZW5lWSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZWxlbWVudCA9IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgID8gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgOiBuZXdUZXh0RWxlbWVudCh7XG4gICAgICAgICAgeDogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlclhcbiAgICAgICAgICAgIDogc2NlbmVYLFxuICAgICAgICAgIHk6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJZXG4gICAgICAgICAgICA6IHNjZW5lWSxcbiAgICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgICB0ZXh0OiBcIlwiLFxuICAgICAgICAgIGZvbnRTaXplLFxuICAgICAgICAgIGZvbnRGYW1pbHksXG4gICAgICAgICAgdGV4dEFsaWduOiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBcImNlbnRlclwiXG4gICAgICAgICAgICA6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICAgICAgdmVydGljYWxBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gVkVSVElDQUxfQUxJR04uTUlERExFXG4gICAgICAgICAgICA6IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgICAgICAgY29udGFpbmVySWQ6IHNob3VsZEJpbmRUb0NvbnRhaW5lciA/IGNvbnRhaW5lcj8uaWQgOiB1bmRlZmluZWQsXG4gICAgICAgICAgZ3JvdXBJZHM6IGNvbnRhaW5lcj8uZ3JvdXBJZHMgPz8gW10sXG4gICAgICAgICAgbGluZUhlaWdodCxcbiAgICAgICAgICBhbmdsZTogY29udGFpbmVyPy5hbmdsZSA/PyAwLFxuICAgICAgICB9KTtcblxuICAgIGlmICghZXhpc3RpbmdUZXh0RWxlbWVudCAmJiBzaG91bGRCaW5kVG9Db250YWluZXIgJiYgY29udGFpbmVyKSB7XG4gICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwge1xuICAgICAgICBib3VuZEVsZW1lbnRzOiAoY29udGFpbmVyLmJvdW5kRWxlbWVudHMgfHwgW10pLmNvbmNhdCh7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nRWxlbWVudDogZWxlbWVudCB9KTtcblxuICAgIGlmICghZXhpc3RpbmdUZXh0RWxlbWVudCkge1xuICAgICAgaWYgKGNvbnRhaW5lciAmJiBzaG91bGRCaW5kVG9Db250YWluZXIpIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVySW5kZXggPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRJbmRleChjb250YWluZXIuaWQpO1xuICAgICAgICB0aGlzLnNjZW5lLmluc2VydEVsZW1lbnRBdEluZGV4KGVsZW1lbnQsIGNvbnRhaW5lckluZGV4ICsgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICBdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgIH0pO1xuXG4gICAgdGhpcy5oYW5kbGVUZXh0V3lzaXd5ZyhlbGVtZW50LCB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudDogISFleGlzdGluZ1RleHRFbGVtZW50LFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2sgPSAoXG4gICAgZXZlbnQ6IFJlYWN0Lk1vdXNlRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICAvLyBjYXNlOiBkb3VibGUtY2xpY2tpbmcgd2l0aCBhcnJvdy9saW5lIHRvb2wgc2VsZWN0ZWQgd291bGQgYm90aCBjcmVhdGVcbiAgICAvLyB0ZXh0IGFuZCBlbnRlciBtdWx0aUVsZW1lbnQgbW9kZVxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyB3ZSBzaG91bGQgb25seSBiZSBhYmxlIHRvIGRvdWJsZSBjbGljayB3aGVuIG1vZGUgaXMgc2VsZWN0aW9uXG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmIGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSkge1xuICAgICAgaWYgKFxuICAgICAgICBldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJlxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT0gc2VsZWN0ZWRFbGVtZW50c1swXS5pZClcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkID09PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcblxuICAgIGxldCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICBldmVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkR3JvdXBJZHMgPSBnZXRTZWxlY3RlZEdyb3VwSWRzKHRoaXMuc3RhdGUpO1xuXG4gICAgaWYgKHNlbGVjdGVkR3JvdXBJZHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuXG4gICAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWQgPVxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQoaGl0RWxlbWVudCwgdGhpcy5zdGF0ZS5zZWxlY3RlZEdyb3VwSWRzKTtcblxuICAgICAgaWYgKHNlbGVjdGVkR3JvdXBJZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogc2VsZWN0ZWRHcm91cElkLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2hpdEVsZW1lbnQhLmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiAhdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGdldFRleHRCaW5kYWJsZUNvbnRhaW5lckF0UG9zaXRpb24oXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgKTtcbiAgICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGhhc0JvdW5kVGV4dEVsZW1lbnQoY29udGFpbmVyKSB8fFxuICAgICAgICAgICFpc1RyYW5zcGFyZW50KGNvbnRhaW5lci5iYWNrZ3JvdW5kQ29sb3IpIHx8XG4gICAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goY29udGFpbmVyLCB0aGlzLnN0YXRlLCBbXG4gICAgICAgICAgICBzY2VuZVgsXG4gICAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgbWlkUG9pbnQgPSBnZXRDb250YWluZXJDZW50ZXIoY29udGFpbmVyLCB0aGlzLnN0YXRlKTtcblxuICAgICAgICAgIHNjZW5lWCA9IG1pZFBvaW50Lng7XG4gICAgICAgICAgc2NlbmVZID0gbWlkUG9pbnQueTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyOiAhZXZlbnQuYWx0S2V5LFxuICAgICAgICBjb250YWluZXIsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50TGlua0F0UG9zaXRpb24gPSAoXG4gICAgc2NlbmVQb2ludGVyOiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIGhpdEVsZW1lbnQ6IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwsXG4gICk6IEV4Y2FsaWRyYXdFbGVtZW50IHwgdW5kZWZpbmVkID0+IHtcbiAgICAvLyBSZXZlcnNpbmcgc28gd2UgdHJhdmVyc2UgdGhlIGVsZW1lbnRzIGluIGRlY3JlYXNpbmcgb3JkZXJcbiAgICAvLyBvZiB6LWluZGV4XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIGxldCBoaXRFbGVtZW50SW5kZXggPSBJbmZpbml0eTtcblxuICAgIHJldHVybiBlbGVtZW50cy5maW5kKChlbGVtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGhpdEVsZW1lbnQgJiYgZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudC5pZCkge1xuICAgICAgICBoaXRFbGVtZW50SW5kZXggPSBpbmRleDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAoXG4gICAgICAgIGVsZW1lbnQubGluayAmJlxuICAgICAgICBpbmRleCA8PSBoaXRFbGVtZW50SW5kZXggJiZcbiAgICAgICAgaXNQb2ludEhpdHRpbmdMaW5rSWNvbihcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgW3NjZW5lUG9pbnRlci54LCBzY2VuZVBvaW50ZXIueV0sXG4gICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWRpcmVjdFRvTGluayA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBpc1RvdWNoU2NyZWVuOiBib29sZWFuLFxuICApID0+IHtcbiAgICBjb25zdCBkcmFnZ2VkRGlzdGFuY2UgPSBkaXN0YW5jZTJkKFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFgsXG4gICAgICB0aGlzLmxhc3RQb2ludGVyRG93biEuY2xpZW50WSxcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WCxcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICApO1xuICAgIGlmIChcbiAgICAgICF0aGlzLmhpdExpbmtFbGVtZW50IHx8XG4gICAgICAvLyBGb3IgdG91Y2ggc2NyZWVuIGFsbG93IGRyYWdnaW5nIHRocmVzaG9sZCBlbHNlIHN0cmljdCBjaGVja1xuICAgICAgKGlzVG91Y2hTY3JlZW4gJiYgZHJhZ2dlZERpc3RhbmNlID4gRFJBR0dJTkdfVEhSRVNIT0xEKSB8fFxuICAgICAgKCFpc1RvdWNoU2NyZWVuICYmIGRyYWdnZWREaXN0YW5jZSAhPT0gMClcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGFzdFBvaW50ZXJEb3duQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IGxhc3RQb2ludGVyRG93bkhpdHRpbmdMaW5rSWNvbiA9IGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIFtsYXN0UG9pbnRlckRvd25Db29yZHMueCwgbGFzdFBvaW50ZXJEb3duQ29vcmRzLnldLFxuICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlclVwQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgdGhpcy5sYXN0UG9pbnRlclVwISxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlclVwSGl0dGluZ0xpbmtJY29uID0gaXNQb2ludEhpdHRpbmdMaW5rSWNvbihcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICAgW2xhc3RQb2ludGVyVXBDb29yZHMueCwgbGFzdFBvaW50ZXJVcENvb3Jkcy55XSxcbiAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICk7XG4gICAgaWYgKGxhc3RQb2ludGVyRG93bkhpdHRpbmdMaW5rSWNvbiAmJiBsYXN0UG9pbnRlclVwSGl0dGluZ0xpbmtJY29uKSB7XG4gICAgICBjb25zdCB1cmwgPSB0aGlzLmhpdExpbmtFbGVtZW50Lmxpbms7XG4gICAgICBpZiAodXJsKSB7XG4gICAgICAgIGxldCBjdXN0b21FdmVudDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25MaW5rT3Blbikge1xuICAgICAgICAgIGN1c3RvbUV2ZW50ID0gd3JhcEV2ZW50KEVWRU5ULkVYQ0FMSURSQVdfTElOSywgZXZlbnQubmF0aXZlRXZlbnQpO1xuICAgICAgICAgIHRoaXMucHJvcHMub25MaW5rT3Blbih0aGlzLmhpdExpbmtFbGVtZW50LCBjdXN0b21FdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjdXN0b21FdmVudD8uZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGlzTG9jYWxMaW5rKHVybCkgPyBcIl9zZWxmXCIgOiBcIl9ibGFua1wiO1xuICAgICAgICAgIGNvbnN0IG5ld1dpbmRvdyA9IHdpbmRvdy5vcGVuKHVuZGVmaW5lZCwgdGFyZ2V0KTtcbiAgICAgICAgICAvLyBodHRwczovL21hdGhpYXNieW5lbnMuZ2l0aHViLmlvL3JlbC1ub29wZW5lci9cbiAgICAgICAgICBpZiAobmV3V2luZG93KSB7XG4gICAgICAgICAgICBuZXdXaW5kb3cub3BlbmVyID0gbnVsbDtcbiAgICAgICAgICAgIG5ld1dpbmRvdy5sb2NhdGlvbiA9IG5vcm1hbGl6ZUxpbmsodXJsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCB0aGlzLnN0YXRlLmN1cnNvckJ1dHRvbik7XG5cbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5oYXMoZXZlbnQucG9pbnRlcklkKSkge1xuICAgICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoXG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIgJiZcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciAmJlxuICAgICAgaW5pdGlhbFNjYWxlICYmXG4gICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZVxuICAgICkge1xuICAgICAgY29uc3QgY2VudGVyID0gZ2V0Q2VudGVyKGdlc3R1cmUucG9pbnRlcnMpO1xuICAgICAgY29uc3QgZGVsdGFYID0gY2VudGVyLnggLSBnZXN0dXJlLmxhc3RDZW50ZXIueDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGNlbnRlci55IC0gZ2VzdHVyZS5sYXN0Q2VudGVyLnk7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPSBjZW50ZXI7XG5cbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZ2V0RGlzdGFuY2UoQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSk7XG4gICAgICBjb25zdCBzY2FsZUZhY3RvciA9XG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImZyZWVkcmF3XCIgJiYgdGhpcy5zdGF0ZS5wZW5Nb2RlXG4gICAgICAgICAgPyAxXG4gICAgICAgICAgOiBkaXN0YW5jZSAvIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlO1xuXG4gICAgICBjb25zdCBuZXh0Wm9vbSA9IHNjYWxlRmFjdG9yXG4gICAgICAgID8gZ2V0Tm9ybWFsaXplZFpvb20oaW5pdGlhbFNjYWxlICogc2NhbGVGYWN0b3IpXG4gICAgICAgIDogdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgICBjb25zdCB6b29tU3RhdGUgPSBnZXRTdGF0ZUZvclpvb20oXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmlld3BvcnRYOiBjZW50ZXIueCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY2VudGVyLnksXG4gICAgICAgICAgICBuZXh0Wm9vbSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMudHJhbnNsYXRlQ2FudmFzKHtcbiAgICAgICAgICB6b29tOiB6b29tU3RhdGUuem9vbSxcbiAgICAgICAgICBzY3JvbGxYOiB6b29tU3RhdGUuc2Nyb2xsWCArIGRlbHRhWCAvIG5leHRab29tLFxuICAgICAgICAgIHNjcm9sbFk6IHpvb21TdGF0ZS5zY3JvbGxZICsgZGVsdGFZIC8gbmV4dFpvb20sXG4gICAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZSA9XG4gICAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID1cbiAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGlzSG9sZGluZ1NwYWNlIHx8XG4gICAgICBpc1Bhbm5pbmcgfHxcbiAgICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgfHxcbiAgICAgIGlzSGFuZFRvb2xBY3RpdmUodGhpcy5zdGF0ZSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycyA9IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgKTtcbiAgICBjb25zdCBpc092ZXJTY3JvbGxCYXIgPSBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycy5pc092ZXJFaXRoZXI7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3QgeyB4OiBzY2VuZVBvaW50ZXJYLCB5OiBzY2VuZVBvaW50ZXJZIH0gPSBzY2VuZVBvaW50ZXI7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5pc0RyYWdnaW5nXG4gICAgKSB7XG4gICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlck1vdmUoXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcblxuICAgICAgaWYgKFxuICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudFxuICAgICAgKSB7XG4gICAgICAgIC8vIFNpbmNlIHdlIGFyZSByZWFkaW5nIGZyb20gcHJldmlvdXMgc3RhdGUgd2hpY2ggaXMgbm90IHBvc3NpYmxlIHdpdGhcbiAgICAgICAgLy8gYXV0b21hdGljIGJhdGNoaW5nIGluIFJlYWN0IDE4IGhlbmNlIHVzaW5nIGZsdXNoIHN5bmMgdG8gc3luY2hyb25vdXNseVxuICAgICAgICAvLyB1cGRhdGUgdGhlIHN0YXRlLiBDaGVjayBodHRwczovL2dpdGh1Yi5jb20vZXhjYWxpZHJhdy9leGNhbGlkcmF3L3B1bGwvNTUwOCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICBmbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50Py5sYXN0VW5jb21taXR0ZWRQb2ludCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjYXVzZXMgc3RhY2sgb3ZlcmZsb3cgaWYgbm90IHN5bmNcbiAgICAgICAgZmx1c2hTeW5jKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNCaW5kaW5nRWxlbWVudFR5cGUodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgICAvLyBIb3ZlcmluZyB3aXRoIGEgc2VsZWN0ZWQgdG9vbCBvciBjcmVhdGluZyBuZXcgbGluZWFyIGVsZW1lbnQgdmlhIGNsaWNrXG4gICAgICAvLyBhbmQgcG9pbnRcbiAgICAgIGNvbnN0IHsgZHJhZ2dpbmdFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCBmYWxzZSkpIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgW3NjZW5lUG9pbnRlcl0sXG4gICAgICAgICAgdGhpcy5zdGF0ZS5zdGFydEJvdW5kRWxlbWVudCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IHsgeDogcngsIHk6IHJ5IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIGNvbnN0IHsgcG9pbnRzLCBsYXN0Q29tbWl0dGVkUG9pbnQgfSA9IG11bHRpRWxlbWVudDtcbiAgICAgIGNvbnN0IGxhc3RQb2ludCA9IHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV07XG5cbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcblxuICAgICAgaWYgKGxhc3RQb2ludCA9PT0gbGFzdENvbW1pdHRlZFBvaW50KSB7XG4gICAgICAgIC8vIGlmIHdlIGhhdmVuJ3QgeWV0IGNyZWF0ZWQgYSB0ZW1wIHBvaW50IGFuZCB3ZSdyZSBiZXlvbmQgY29tbWl0LXpvbmVcbiAgICAgICAgLy8gdGhyZXNob2xkLCBhZGQgYSBwb2ludFxuICAgICAgICBpZiAoXG4gICAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSByeSxcbiAgICAgICAgICAgIGxhc3RQb2ludFswXSxcbiAgICAgICAgICAgIGxhc3RQb2ludFsxXSxcbiAgICAgICAgICApID49IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICAgKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW3NjZW5lUG9pbnRlclggLSByeCwgc2NlbmVQb2ludGVyWSAtIHJ5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgICAvLyBpbiB0aGlzIGJyYW5jaCwgd2UncmUgaW5zaWRlIHRoZSBjb21taXQgem9uZSwgYW5kIG5vIHVuY29tbWl0dGVkXG4gICAgICAgICAgLy8gcG9pbnQgZXhpc3RzLiBUaHVzIGRvIG5vdGhpbmcgKGRvbid0IGFkZC9yZW1vdmUgcG9pbnRzKS5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgcG9pbnRzLmxlbmd0aCA+IDIgJiZcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50ICYmXG4gICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCAtIHJ4LFxuICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSByeSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMF0sXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzFdLFxuICAgICAgICApIDwgTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBwb2ludHMuc2xpY2UoMCwgLTEpLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IFtsYXN0Q29tbWl0dGVkWCwgbGFzdENvbW1pdHRlZFldID1cbiAgICAgICAgICBtdWx0aUVsZW1lbnQ/Lmxhc3RDb21taXR0ZWRQb2ludCA/PyBbMCwgMF07XG5cbiAgICAgICAgbGV0IGR4RnJvbUxhc3RDb21taXR0ZWQgPSBncmlkWCAtIHJ4IC0gbGFzdENvbW1pdHRlZFg7XG4gICAgICAgIGxldCBkeUZyb21MYXN0Q29tbWl0dGVkID0gZ3JpZFkgLSByeSAtIGxhc3RDb21taXR0ZWRZO1xuXG4gICAgICAgIGlmIChzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCkpIHtcbiAgICAgICAgICAoeyB3aWR0aDogZHhGcm9tTGFzdENvbW1pdHRlZCwgaGVpZ2h0OiBkeUZyb21MYXN0Q29tbWl0dGVkIH0gPVxuICAgICAgICAgICAgZ2V0TG9ja2VkTGluZWFyQ3Vyc29yQWxpZ25TaXplKFxuICAgICAgICAgICAgICAvLyBhY3R1YWwgY29vcmRpbmF0ZSBvZiB0aGUgbGFzdCBjb21taXR0ZWQgcG9pbnRcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFggKyByeCxcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFkgKyByeSxcbiAgICAgICAgICAgICAgLy8gY3Vyc29yLWdyaWQgY29vcmRpbmF0ZVxuICAgICAgICAgICAgICBncmlkWCxcbiAgICAgICAgICAgICAgZ3JpZFksXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1BhdGhBTG9vcChwb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVwZGF0ZSBsYXN0IHVuY29tbWl0dGVkIHBvaW50XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAuLi5wb2ludHMuc2xpY2UoMCwgLTEpLFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWCArIGR4RnJvbUxhc3RDb21taXR0ZWQsXG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRZICsgZHlGcm9tTGFzdENvbW1pdHRlZCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNEZXNlbGVjdGVkQnV0dG9uID0gQm9vbGVhbihldmVudC5idXR0b25zKTtcbiAgICBpZiAoXG4gICAgICBoYXNEZXNlbGVjdGVkQnV0dG9uIHx8XG4gICAgICAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwidGV4dFwiICYmXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcImVyYXNlclwiKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICBpZiAoXG4gICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgIWlzT3ZlclNjcm9sbEJhciAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnRcbiAgICApIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgJiZcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGVcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSAmJiAhaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAodHJhbnNmb3JtSGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcbiAgICB0aGlzLmhpdExpbmtFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50TGlua0F0UG9zaXRpb24oXG4gICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICBoaXRFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLmhpdExpbmtFbGVtZW50LmlkXVxuICAgICkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgIHNob3dIeXBlcmxpbmtUb29sdGlwKHRoaXMuaGl0TGlua0VsZW1lbnQsIHRoaXMuc3RhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWRlSHlwZXJsaW5rVG9vbGlwKCk7XG4gICAgICBpZiAoXG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgaGl0RWxlbWVudC5saW5rICYmXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdICYmXG4gICAgICAgICF0aGlzLnN0YXRlLmNvbnRleHRNZW51ICYmXG4gICAgICAgICF0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IFwiaW5mb1wiIH0pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGlzVGV4dEVsZW1lbnQoaGl0RWxlbWVudCkgPyBDVVJTT1JfVFlQRS5URVhUIDogQ1VSU09SX1RZUEUuQ1JPU1NIQUlSLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgfSBlbHNlIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVIb3ZlclNlbGVjdGVkTGluZWFyRWxlbWVudChcbiAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAvLyBpZiB1c2luZyBjbWQvY3RybCwgd2UncmUgbm90IGRyYWdnaW5nXG4gICAgICAgICFldmVudFtLRVlTLkNUUkxfT1JfQ01EXVxuICAgICAgKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAoaGl0RWxlbWVudCB8fFxuICAgICAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgKSkgJiZcbiAgICAgICAgICAhaGl0RWxlbWVudD8ubG9ja2VkXG4gICAgICAgICkge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlRXJhc2VyID0gKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBzY2VuZVBvaW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSxcbiAgKSA9PiB7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudElkcyA9IChlbGVtZW50czogRXhjYWxpZHJhd0VsZW1lbnRbXSkgPT4ge1xuICAgICAgZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoZWxlbWVudC5sb2NrZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZHNUb1VwZGF0ZS5wdXNoKGVsZW1lbnQuaWQpO1xuICAgICAgICBpZiAoZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXSAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXS5lcmFzZVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXS5lcmFzZSA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXSkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0gPSB7XG4gICAgICAgICAgICBlcmFzZTogdHJ1ZSxcbiAgICAgICAgICAgIG9wYWNpdHk6IGVsZW1lbnQub3BhY2l0eSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgY29uc3QgaWRzVG9VcGRhdGU6IEFycmF5PHN0cmluZz4gPSBbXTtcblxuICAgIGNvbnN0IGRpc3RhbmNlID0gZGlzdGFuY2UyZChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnksXG4gICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICk7XG4gICAgY29uc3QgdGhyZXNob2xkID0gMTAgLyB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgY29uc3QgcG9pbnQgPSB7IC4uLnBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcyB9O1xuICAgIGxldCBzYW1wbGluZ0ludGVydmFsID0gMDtcbiAgICB3aGlsZSAoc2FtcGxpbmdJbnRlcnZhbCA8PSBkaXN0YW5jZSkge1xuICAgICAgY29uc3QgaGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihwb2ludC54LCBwb2ludC55KTtcbiAgICAgIHVwZGF0ZUVsZW1lbnRJZHMoaGl0RWxlbWVudHMpO1xuXG4gICAgICAvLyBFeGl0IHNpbmNlIHdlIHJlYWNoZWQgY3VycmVudCBwb2ludFxuICAgICAgaWYgKHNhbXBsaW5nSW50ZXJ2YWwgPT09IGRpc3RhbmNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBDYWxjdWxhdGUgbmV4dCBwb2ludCBpbiB0aGUgbGluZSBhdCBhIGRpc3RhbmNlIG9mIHNhbXBsaW5nIGludGVydmFsXG4gICAgICBzYW1wbGluZ0ludGVydmFsID0gTWF0aC5taW4oc2FtcGxpbmdJbnRlcnZhbCArIHRocmVzaG9sZCwgZGlzdGFuY2UpO1xuXG4gICAgICBjb25zdCBkaXN0YW5jZVJhdGlvID0gc2FtcGxpbmdJbnRlcnZhbCAvIGRpc3RhbmNlO1xuICAgICAgY29uc3QgbmV4dFggPVxuICAgICAgICAoMSAtIGRpc3RhbmNlUmF0aW8pICogcG9pbnQueCArIGRpc3RhbmNlUmF0aW8gKiBzY2VuZVBvaW50ZXIueDtcbiAgICAgIGNvbnN0IG5leHRZID1cbiAgICAgICAgKDEgLSBkaXN0YW5jZVJhdGlvKSAqIHBvaW50LnkgKyBkaXN0YW5jZVJhdGlvICogc2NlbmVQb2ludGVyLnk7XG4gICAgICBwb2ludC54ID0gbmV4dFg7XG4gICAgICBwb2ludC55ID0gbmV4dFk7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlKSA9PiB7XG4gICAgICBjb25zdCBpZCA9XG4gICAgICAgIGlzQm91bmRUb0NvbnRhaW5lcihlbGUpICYmIGlkc1RvVXBkYXRlLmluY2x1ZGVzKGVsZS5jb250YWluZXJJZClcbiAgICAgICAgICA/IGVsZS5jb250YWluZXJJZFxuICAgICAgICAgIDogZWxlLmlkO1xuICAgICAgaWYgKGlkc1RvVXBkYXRlLmluY2x1ZGVzKGlkKSkge1xuICAgICAgICBpZiAoZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtpZF0gJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaWRdLmVyYXNlID09PSBmYWxzZVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2lkXS5vcGFjaXR5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IEVMRU1FTlRfUkVBRFlfVE9fRVJBU0VfT1BBQ0lUWSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGVsZW1lbnRzKTtcblxuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gc2NlbmVQb2ludGVyLng7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBzY2VuZVBvaW50ZXIueTtcbiAgfTtcbiAgLy8gc2V0IHRvdWNoIG1vdmluZyBmb3IgbW9iaWxlIGNvbnRleHQgbWVudVxuICBwcml2YXRlIGhhbmRsZVRvdWNoTW92ZSA9IChldmVudDogUmVhY3QuVG91Y2hFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4pID0+IHtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICB9O1xuXG4gIGhhbmRsZUhvdmVyU2VsZWN0ZWRMaW5lYXJFbGVtZW50KFxuICAgIGxpbmVhckVsZW1lbnRFZGl0b3I6IExpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgc2NlbmVQb2ludGVyWDogbnVtYmVyLFxuICAgIHNjZW5lUG9pbnRlclk6IG51bWJlcixcbiAgKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChcbiAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IuZWxlbWVudElkLFxuICAgICk7XG5cbiAgICBjb25zdCBib3VuZFRleHRFbGVtZW50ID0gZ2V0Qm91bmRUZXh0RWxlbWVudChlbGVtZW50KTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgIGxldCBob3ZlclBvaW50SW5kZXggPSAtMTtcbiAgICAgIGxldCBzZWdtZW50TWlkUG9pbnRIb3ZlcmVkQ29vcmRzID0gbnVsbDtcbiAgICAgIGlmIChcbiAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goZWxlbWVudCwgdGhpcy5zdGF0ZSwgW1xuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgXSlcbiAgICAgICkge1xuICAgICAgICBob3ZlclBvaW50SW5kZXggPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50SW5kZXhVbmRlckN1cnNvcihcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICk7XG4gICAgICAgIHNlZ21lbnRNaWRQb2ludEhvdmVyZWRDb29yZHMgPVxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0U2VnbWVudE1pZHBvaW50SGl0Q29vcmRzKFxuICAgICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgICAgICAgIHsgeDogc2NlbmVQb2ludGVyWCwgeTogc2NlbmVQb2ludGVyWSB9LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgIGlmIChob3ZlclBvaW50SW5kZXggPj0gMCB8fCBzZWdtZW50TWlkUG9pbnRIb3ZlcmVkQ29vcmRzKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBzaG91bGRTaG93Qm91bmRpbmdCb3goW2VsZW1lbnRdLCB0aGlzLnN0YXRlKSAmJlxuICAgICAgICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBib3VuZFRleHRFbGVtZW50ICYmXG4gICAgICAgIGhpdFRlc3QoYm91bmRUZXh0RWxlbWVudCwgdGhpcy5zdGF0ZSwgc2NlbmVQb2ludGVyWCwgc2NlbmVQb2ludGVyWSlcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmhvdmVyUG9pbnRJbmRleCAhPT0gaG92ZXJQb2ludEluZGV4XG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIGhvdmVyUG9pbnRJbmRleCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhTGluZWFyRWxlbWVudEVkaXRvci5hcmVQb2ludHNFcXVhbChcbiAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5zZWdtZW50TWlkUG9pbnRIb3ZlcmVkQ29vcmRzLFxuICAgICAgICAgIHNlZ21lbnRNaWRQb2ludEhvdmVyZWRDb29yZHMsXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgc2VnbWVudE1pZFBvaW50SG92ZXJlZENvb3JkcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gc2luY2UgY29udGV4dE1lbnUgb3B0aW9ucyBhcmUgcG90ZW50aWFsbHkgZXZhbHVhdGVkIG9uIGVhY2ggcmVuZGVyLFxuICAgIC8vIGFuZCBhbiBjb250ZXh0TWVudSBhY3Rpb24gbWF5IGRlcGVuZCBvbiBzZWxlY3Rpb24gc3RhdGUsIHdlIG11c3RcbiAgICAvLyBjbG9zZSB0aGUgY29udGV4dE1lbnUgYmVmb3JlIHdlIHVwZGF0ZSB0aGUgc2VsZWN0aW9uIG9uIHBvaW50ZXJEb3duXG4gICAgLy8gKGUuZy4gcmVzZXR0aW5nIHNlbGVjdGlvbilcbiAgICBpZiAodGhpcy5zdGF0ZS5jb250ZXh0TWVudSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvbnRleHRNZW51OiBudWxsIH0pO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlR2VzdHVyZU9uUG9pbnRlckRvd24oZXZlbnQpO1xuXG4gICAgLy8gaWYgZHJhZ2dpbmcgZWxlbWVudCBpcyBmcmVlZHJhdyBhbmQgYW5vdGhlciBwb2ludGVyZG93biBldmVudCBvY2N1cnNcbiAgICAvLyBhIHNlY29uZCBmaW5nZXIgaXMgb24gdGhlIHNjcmVlblxuICAgIC8vIGRpc2NhcmQgdGhlIGZyZWVkcmF3IGVsZW1lbnQgaWYgaXQgaXMgdmVyeSBzaG9ydCBiZWNhdXNlIGl0IGlzIGxpa2VseVxuICAgIC8vIGp1c3QgYSBzcGlrZSwgb3RoZXJ3aXNlIGZpbmFsaXplIHRoZSBmcmVlZHJhdyBlbGVtZW50IHdoZW4gdGhlIHNlY29uZFxuICAgIC8vIGZpbmdlciBpcyBsaWZ0ZWRcbiAgICBpZiAoXG4gICAgICBldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiICYmXG4gICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJmcmVlZHJhd1wiXG4gICAgKSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgYXMgRXhjYWxpZHJhd0ZyZWVEcmF3RWxlbWVudDtcbiAgICAgIHRoaXMudXBkYXRlU2NlbmUoe1xuICAgICAgICAuLi4oZWxlbWVudC5wb2ludHMubGVuZ3RoIDwgMTBcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgZWxlbWVudHM6IHRoaXMuc2NlbmVcbiAgICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgICAgICAuZmlsdGVyKChlbCkgPT4gZWwuaWQgIT09IGVsZW1lbnQuaWQpLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDoge30pLFxuICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBlZGl0aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdGFydEJvdW5kRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBPYmplY3Qua2V5cyh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcylcbiAgICAgICAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5ICE9PSBlbGVtZW50LmlkKVxuICAgICAgICAgICAgLnJlZHVjZSgob2JqOiB7IFtpZDogc3RyaW5nXTogYm9vbGVhbiB9LCBrZXkpID0+IHtcbiAgICAgICAgICAgICAgb2JqW2tleV0gPSB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1trZXldO1xuICAgICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICAgICAgfSwge30pLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGFueSBhY3RpdmUgc2VsZWN0aW9uIHdoZW4gd2Ugc3RhcnQgdG8gaW50ZXJhY3Qgd2l0aCBjYW52YXNcbiAgICAvLyAobWFpbmx5LCB3ZSBjYXJlIGFib3V0IHJlbW92aW5nIHNlbGVjdGlvbiBvdXRzaWRlIHRoZSBjb21wb25lbnQgd2hpY2hcbiAgICAvLyAgd291bGQgcHJldmVudCBvdXIgY29weSBoYW5kbGluZyBvdGhlcndpc2UpXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKHNlbGVjdGlvbj8uYW5jaG9yTm9kZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIH1cbiAgICB0aGlzLm1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzKGV2ZW50KTtcbiAgICB0aGlzLm1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChldmVudCk7XG5cbiAgICAvL2ZpcmVzIG9ubHkgb25jZSwgaWYgcGVuIGlzIGRldGVjdGVkLCBwZW5Nb2RlIGlzIGVuYWJsZWRcbiAgICAvL3RoZSB1c2VyIGNhbiBkaXNhYmxlIHRoaXMgYnkgdG9nZ2xpbmcgdGhlIHBlbk1vZGUgYnV0dG9uXG4gICAgaWYgKCF0aGlzLnN0YXRlLnBlbkRldGVjdGVkICYmIGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInBlblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwZW5Nb2RlOiB0cnVlLFxuICAgICAgICAgIHBlbkRldGVjdGVkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgIXRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4gJiZcbiAgICAgIFtcInBlblwiLCBcInRvdWNoXCJdLmluY2x1ZGVzKGV2ZW50LnBvaW50ZXJUeXBlKVxuICAgICkge1xuICAgICAgdGhpcy5kZXZpY2UgPSB1cGRhdGVPYmplY3QodGhpcy5kZXZpY2UsIHsgaXNUb3VjaFNjcmVlbjogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAoaXNQYW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0UG9pbnRlckRvd24gPSBldmVudDtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGxhc3RQb2ludGVyRG93bldpdGg6IGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgY3Vyc29yQnV0dG9uOiBcImRvd25cIixcbiAgICB9KTtcbiAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwiZG93blwiKTtcblxuICAgIGlmICh0aGlzLmhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyhldmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBvbmx5IGhhbmRsZSBsZWZ0IG1vdXNlIGJ1dHRvbiBvciB0b3VjaFxuICAgIGlmIChcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uTUFJTiAmJlxuICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5UT1VDSFxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRvbid0IHNlbGVjdCB3aGlsZSBwYW5uaW5nXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA+IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGF0ZSBmb3IgdGhlIGR1cmF0aW9uIG9mIGEgcG9pbnRlciBpbnRlcmFjdGlvbiwgd2hpY2ggc3RhcnRzIHdpdGggYVxuICAgIC8vIHBvaW50ZXJEb3duIGV2ZW50LCBlbmRzIHdpdGggYSBwb2ludGVyVXAgZXZlbnQgKG9yIGFub3RoZXIgcG9pbnRlckRvd24pXG4gICAgY29uc3QgcG9pbnRlckRvd25TdGF0ZSA9IHRoaXMuaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFsbG93T25Qb2ludGVyRG93biA9XG4gICAgICAhdGhpcy5zdGF0ZS5wZW5Nb2RlIHx8XG4gICAgICBldmVudC5wb2ludGVyVHlwZSAhPT0gXCJ0b3VjaFwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiO1xuXG4gICAgaWYgKCFhbGxvd09uUG9pbnRlckRvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICB0aGlzLmhhbmRsZVRleHRPblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwibGluZVwiXG4gICAgKSB7XG4gICAgICB0aGlzLmhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgLy8gcmVzZXQgaW1hZ2UgcHJldmlldyBvbiBwb2ludGVyZG93blxuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5DUk9TU0hBSVIpO1xuXG4gICAgICAvLyByZXRyaWV2ZSB0aGUgbGF0ZXN0IGVsZW1lbnQgYXMgdGhlIHN0YXRlIG1heSBiZSBzdGFsZVxuICAgICAgY29uc3QgcGVuZGluZ0ltYWdlRWxlbWVudCA9XG4gICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkICYmXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudCh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCk7XG5cbiAgICAgIGlmICghcGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IHBlbmRpbmdJbWFnZUVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBwZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwsXG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgICBtdXRhdGVFbGVtZW50KHBlbmRpbmdJbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgdGhpcy5oYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiaGFuZFwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJjdXN0b21cIlxuICAgICkge1xuICAgICAgdGhpcy5jcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb3BzPy5vblBvaW50ZXJEb3duPy4odGhpcy5zdGF0ZS5hY3RpdmVUb29sLCBwb2ludGVyRG93blN0YXRlKTtcbiAgICB0aGlzLm9uUG9pbnRlckRvd25FbWl0dGVyLnRyaWdnZXIoXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgZXZlbnQsXG4gICAgKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPVxuICAgICAgdGhpcy5vblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID1cbiAgICAgIHRoaXMub25Qb2ludGVyVXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25LZXlEb3duID0gdGhpcy5vbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIGNvbnN0IG9uS2V5VXAgPSB0aGlzLm9uS2V5VXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgaWYgKCF0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIG9uS2V5RG93bik7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgb25LZXlVcCk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSA9IG9uUG9pbnRlck1vdmU7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAgPSBvblBvaW50ZXJVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCA9IG9uS2V5VXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biA9IG9uS2V5RG93bjtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyVXAgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMubGFzdFBvaW50ZXJVcCA9IGV2ZW50O1xuICAgIGlmICh0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuKSB7XG4gICAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WDogZXZlbnQuY2xpZW50WCwgY2xpZW50WTogZXZlbnQuY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICApO1xuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5oaXRMaW5rRWxlbWVudC5pZF1cbiAgICApIHtcbiAgICAgIHRoaXMucmVkaXJlY3RUb0xpbmsoZXZlbnQsIHRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4pO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlUG9pbnRlcihldmVudCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCA9PiB7XG4gICAgLy8gZGVhbCB3aXRoIG9wZW5pbmcgY29udGV4dCBtZW51IG9uIHRvdWNoIGRldmljZXNcbiAgICBpZiAoZXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIikge1xuICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbiAgICAgIGlmICh0b3VjaFRpbWVvdXQpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUncyBhbHJlYWR5IGEgdG91Y2hUaW1lb3V0LCB0aGlzIG1lYW5zIHRoYXQgdGhlcmUncyBhbm90aGVyXG4gICAgICAgIC8vIHRvdWNoIGRvd24gYW5kIHdlIGFyZSBkb2luZyBhbm90aGVyIHRvdWNoLCBzbyB3ZSBzaG91bGRuJ3Qgb3BlbiB0aGVcbiAgICAgICAgLy8gY29udGV4dCBtZW51LlxuICAgICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb3BlbiB0aGUgY29udGV4dCBtZW51IHdpdGggdGhlIGZpcnN0IHRvdWNoJ3MgY2xpZW50WCBhbmQgY2xpZW50WVxuICAgICAgICAvLyBpZiB0aGUgdG91Y2ggaXMgbm90IG1vdmluZ1xuICAgICAgICB0b3VjaFRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICAgICAgICBpZiAoIWludmFsaWRhdGVDb250ZXh0TWVudSkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudShldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBUT1VDSF9DVFhfTUVOVV9USU1FT1VUKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldENvbnRleHRNZW51VGltZXIgPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgaWYgKGxhc3RQb2ludGVyVXAgIT09IG51bGwpIHtcbiAgICAgIC8vIFVuZm9ydHVuYXRlbHksIHNvbWV0aW1lcyB3ZSBkb24ndCBnZXQgYSBwb2ludGVydXAgYWZ0ZXIgYSBwb2ludGVyZG93bixcbiAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29udGV4dHVhbCBtZW51IG9yIGFsZXJ0IGlzIHRyaWdnZXJlZC4gSW4gb3JkZXIgdG8gYXZvaWRcbiAgICAgIC8vIGJlaW5nIGluIGEgd2VpcmQgc3RhdGUsIHdlIGNsZWFuIHVwIG9uIHRoZSBuZXh0IHBvaW50ZXJkb3duXG4gICAgICBsYXN0UG9pbnRlclVwKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgcGFubmluZ1xuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKFxuICAgICAgIShcbiAgICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplIDw9IDEgJiZcbiAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uV0hFRUwgfHxcbiAgICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmIGlzSG9sZGluZ1NwYWNlKSB8fFxuICAgICAgICAgIGlzSGFuZFRvb2xBY3RpdmUodGhpcy5zdGF0ZSkgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZClcbiAgICAgICkgfHxcbiAgICAgIGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaXNQYW5uaW5nID0gdHJ1ZTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgbGV0IG5leHRQYXN0ZVByZXZlbnRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGlzTGludXggPSAvTGludXgvLnRlc3Qod2luZG93Lm5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICBsZXQgeyBjbGllbnRYOiBsYXN0WCwgY2xpZW50WTogbGFzdFkgfSA9IGV2ZW50O1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGxhc3RYIC0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGxhc3RZIC0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGxhc3RYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGxhc3RZID0gZXZlbnQuY2xpZW50WTtcblxuICAgICAgLypcbiAgICAgICAqIFByZXZlbnQgcGFzdGUgZXZlbnQgaWYgd2UgbW92ZSB3aGlsZSBtaWRkbGUgY2xpY2tpbmcgb24gTGludXguXG4gICAgICAgKiBTZWUgaXNzdWUgIzEzODMuXG4gICAgICAgKi9cbiAgICAgIGlmIChcbiAgICAgICAgaXNMaW51eCAmJlxuICAgICAgICAhbmV4dFBhc3RlUHJldmVudGVkICYmXG4gICAgICAgIChNYXRoLmFicyhkZWx0YVgpID4gMSB8fCBNYXRoLmFicyhkZWx0YVkpID4gMSlcbiAgICAgICkge1xuICAgICAgICBuZXh0UGFzdGVQcmV2ZW50ZWQgPSB0cnVlO1xuXG4gICAgICAgIC8qIFByZXZlbnQgdGhlIG5leHQgcGFzdGUgZXZlbnQgKi9cbiAgICAgICAgY29uc3QgcHJldmVudE5leHRQYXN0ZSA9IChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIFJlZW5hYmxlIG5leHQgcGFzdGUgaW4gY2FzZSBvZiBkaXNhYmxlZCBtaWRkbGUgY2xpY2sgcGFzdGUgZm9yXG4gICAgICAgICAqIGFueSByZWFzb246XG4gICAgICAgICAqIC0gcmlnaHQgY2xpY2sgcGFzdGVcbiAgICAgICAgICogLSBlbXB0eSBjbGlwYm9hcmRcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGVuYWJsZU5leHRQYXN0ZSA9ICgpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgZW5hYmxlTmV4dFBhc3RlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy50cmFuc2xhdGVDYW52YXMoe1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFggLSBkZWx0YVggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGRlbHRhWSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNvbnN0IHRlYXJkb3duID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgICAgKGxhc3RQb2ludGVyVXAgPSAoKSA9PiB7XG4gICAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuICAgICAgICBpc1Bhbm5pbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKCFpc0hvbGRpbmdTcGFjZSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGVhcmRvd24pO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0ZWFyZG93bik7XG4gICAgICAgIG9uUG9pbnRlck1vdmUuZmx1c2goKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSwge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVHZXN0dXJlT25Qb2ludGVyRG93bihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICB9KTtcblxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIpIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPSBnZXREaXN0YW5jZShcbiAgICAgICAgQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsUG9pbnRlckRvd25TdGF0ZShcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogUG9pbnRlckRvd25TdGF0ZSB7XG4gICAgY29uc3Qgb3JpZ2luID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9yaWdpbixcbiAgICAgIHdpdGhDbWRPckN0cmw6IGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdLFxuICAgICAgb3JpZ2luSW5HcmlkOiB0dXBsZVRvQ29vcnMoXG4gICAgICAgIGdldEdyaWRQb2ludChvcmlnaW4ueCwgb3JpZ2luLnksIHRoaXMuc3RhdGUuZ3JpZFNpemUpLFxuICAgICAgKSxcbiAgICAgIHNjcm9sbGJhcnM6IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICAgIGN1cnJlbnRTY3JvbGxCYXJzLFxuICAgICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgICApLFxuICAgICAgLy8gd2UgbmVlZCB0byBkdXBsaWNhdGUgYmVjYXVzZSB3ZSdsbCBiZSB1cGRhdGluZyB0aGlzIHN0YXRlXG4gICAgICBsYXN0Q29vcmRzOiB7IC4uLm9yaWdpbiB9LFxuICAgICAgb3JpZ2luYWxFbGVtZW50czogdGhpcy5zY2VuZVxuICAgICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgLnJlZHVjZSgoYWNjLCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgYWNjLnNldChlbGVtZW50LmlkLCBkZWVwQ29weUVsZW1lbnQoZWxlbWVudCkpO1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIG5ldyBNYXAoKSBhcyBQb2ludGVyRG93blN0YXRlW1wib3JpZ2luYWxFbGVtZW50c1wiXSksXG4gICAgICByZXNpemU6IHtcbiAgICAgICAgaGFuZGxlVHlwZTogZmFsc2UsXG4gICAgICAgIGlzUmVzaXppbmc6IGZhbHNlLFxuICAgICAgICBvZmZzZXQ6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICBhcnJvd0RpcmVjdGlvbjogXCJvcmlnaW5cIixcbiAgICAgICAgY2VudGVyOiB7IHg6IChtYXhYICsgbWluWCkgLyAyLCB5OiAobWF4WSArIG1pblkpIC8gMiB9LFxuICAgICAgfSxcbiAgICAgIGhpdDoge1xuICAgICAgICBlbGVtZW50OiBudWxsLFxuICAgICAgICBhbGxIaXRFbGVtZW50czogW10sXG4gICAgICAgIHdhc0FkZGVkVG9TZWxlY3Rpb246IGZhbHNlLFxuICAgICAgICBoYXNCZWVuRHVwbGljYXRlZDogZmFsc2UsXG4gICAgICAgIGhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzOlxuICAgICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICksXG4gICAgICB9LFxuICAgICAgZHJhZzoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICAgIG9mZnNldDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBldmVudExpc3RlbmVyczoge1xuICAgICAgICBvbk1vdmU6IG51bGwsXG4gICAgICAgIG9uVXA6IG51bGwsXG4gICAgICAgIG9uS2V5VXA6IG51bGwsXG4gICAgICAgIG9uS2V5RG93bjogbnVsbCxcbiAgICAgIH0sXG4gICAgICBib3hTZWxlY3Rpb246IHtcbiAgICAgICAgaGFzT2NjdXJyZWQ6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGVsZW1lbnRJZHNUb0VyYXNlOiB7fSxcbiAgICB9O1xuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBldmVudCBpcyBhIGRyYWdnaW5nIGEgc2Nyb2xsYmFyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKFxuICAgICAgIShwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyRWl0aGVyICYmICF0aGlzLnN0YXRlLm11bHRpRWxlbWVudClcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaXNEcmFnZ2luZ1Njcm9sbEJhciA9IHRydWU7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBldmVudC5jbGllbnRYO1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gZXZlbnQuY2xpZW50WTtcbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID0gd2l0aEJhdGNoZWRVcGRhdGVzVGhyb3R0bGVkKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyVXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgICAgaXNEcmFnZ2luZ1Njcm9sbEJhciA9IGZhbHNlO1xuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgICBvblBvaW50ZXJNb3ZlLmZsdXNoKCk7XG4gICAgfSk7XG5cbiAgICBsYXN0UG9pbnRlclVwID0gb25Qb2ludGVyVXA7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb25JZk5vdFVzaW5nU2VsZWN0aW9uID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHJldHVybnMgd2hldGhlciB0aGUgcG9pbnRlciBldmVudCBoYXMgYmVlbiBjb21wbGV0ZWx5IGhhbmRsZWRcbiAgICovXG4gIHByaXZhdGUgaGFuZGxlU2VsZWN0aW9uT25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgPVxuICAgICAgICAgIGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICByZXNpemluZ0VsZW1lbnQ6IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS5lbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUgPVxuICAgICAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUgPSBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyhcbiAgICAgICAgICBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyksXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoe1xuICAgICAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZTogcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXRSZXNpemVPZmZzZXRYWShcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pICYmXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXS5wb2ludHMubGVuZ3RoID09PSAyXG4gICAgICAgICkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uID0gZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCBsaW5lYXJFbGVtZW50RWRpdG9yID1cbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHwgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ7XG4gICAgICAgICAgY29uc3QgcmV0ID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyRG93bihcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChyZXQuaGl0RWxlbWVudCkge1xuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA9IHJldC5oaXRFbGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmV0LmxpbmVhckVsZW1lbnRFZGl0b3IpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHJldC5saW5lYXJFbGVtZW50RWRpdG9yIH0pO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IHJldC5saW5lYXJFbGVtZW50RWRpdG9yIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmV0LmRpZEFkZFBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaGl0RWxlbWVudCBtYXkgYWxyZWFkeSBiZSBzZXQgYWJvdmUsIHNvIGNoZWNrIGZpcnN0XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPz9cbiAgICAgICAgICB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKTtcblxuICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgIC8vIEVhcmx5IHJldHVybiBpZiBwb2ludGVyIGlzIGhpdHRpbmcgbGluayBpY29uXG4gICAgICAgICAgY29uc3QgaGl0TGlua0VsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRMaW5rQXRQb3NpdGlvbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgeDogcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgICAgeTogcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGhpdExpbmtFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIG92ZXJsYXBwZWQgZWxlbWVudHMgb25lIHBvc2l0aW9uIG1heSBoaXRcbiAgICAgICAgLy8gbXVsdGlwbGUgZWxlbWVudHNcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT5cbiAgICAgICAgICAgIHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAoaGl0RWxlbWVudCA9PT0gbnVsbCB8fCAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkKSAmJlxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICBbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBJZiB3ZSBjbGljayBvbiBzb21ldGhpbmdcbiAgICAgICAgfSBlbHNlIGlmIChoaXRFbGVtZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAvLyBvbiBDTUQvQ1RSTCwgZHJpbGwgZG93biB0byBoaXQgZWxlbWVudCByZWdhcmRsZXNzIG9mIGdyb3VwcyBldGMuXG4gICAgICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICAuLi5lZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQocHJldlN0YXRlLCBoaXRFbGVtZW50KSxcbiAgICAgICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgLy8gbWFyayBhcyBub3QgY29tcGxldGVseSBoYW5kbGVkIHNvIGFzIHRvIGFsbG93IGRyYWdnaW5nIGV0Yy5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBkZXNlbGVjdCBpZiBpdGVtIGlzIHNlbGVjdGVkXG4gICAgICAgICAgLy8gaWYgc2hpZnQgaXMgbm90IGNsaWNrZWQsIHRoaXMgd2lsbCBhbHdheXMgcmV0dXJuIHRydWVcbiAgICAgICAgICAvLyBvdGhlcndpc2UsIGl0IHdpbGwgdHJpZ2dlciBzZWxlY3Rpb24gYmFzZWQgb24gY3VycmVudFxuICAgICAgICAgIC8vIHN0YXRlIG9mIHRoZSBib3hcbiAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgY3VycmVudGx5IGVkaXRpbmcgYSBncm91cCwgZXhpdGluZyBlZGl0aW5nIG1vZGUgYW5kIGRlc2VsZWN0IHRoZSBncm91cC5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICAgICAgICAhaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBZGQgaGl0IGVsZW1lbnQgdG8gc2VsZWN0aW9uLiBBdCB0aGlzIHBvaW50IGlmIHdlJ3JlIG5vdCBob2xkaW5nXG4gICAgICAgICAgICAvLyBTSElGVCB0aGUgcHJldmlvdXNseSBzZWxlY3RlZCBlbGVtZW50KHMpIHdlcmUgZGVzZWxlY3RlZCBhYm92ZVxuICAgICAgICAgICAgLy8gKG1ha2Ugc3VyZSB5b3UgdXNlIHNldFN0YXRlIHVwZGF0ZXIgdG8gdXNlIGxhdGVzdCBzdGF0ZSlcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgIXNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCAmJlxuICAgICAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2hvd0h5cGVybGlua1BvcHVwOiBoaXRFbGVtZW50LmxpbmsgPyBcImluZm9cIiA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIGlzQVNlbGVjdGVkRWxlbWVudChoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGl0RWxlbWVudCAhPSBudWxsICYmIHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICBwb2ludDogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSG93IG1hbnkgcGl4ZWxzIG9mZiB0aGUgc2hhcGUgYm91bmRhcnkgd2Ugc3RpbGwgY29uc2lkZXIgYSBoaXRcbiAgICBjb25zdCB0aHJlc2hvbGQgPSAxMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHJldHVybiAoXG4gICAgICBwb2ludC54ID4geDEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnggPCB4MiArIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueSA+IHkxIC0gdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55IDwgeTIgKyB0aHJlc2hvbGRcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBpZiB3ZSdyZSBjdXJyZW50bHkgc3RpbGwgZWRpdGluZyB0ZXh0LCBjbGlja2luZyBvdXRzaWRlXG4gICAgLy8gc2hvdWxkIG9ubHkgZmluYWxpemUgaXQsIG5vdCBjcmVhdGUgYW5vdGhlciAoaXJyZXNwZWN0aXZlXG4gICAgLy8gb2Ygc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpXG4gICAgaWYgKGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHNjZW5lWCA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLng7XG4gICAgbGV0IHNjZW5lWSA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSwge1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBsZXQgY29udGFpbmVyID0gZ2V0VGV4dEJpbmRhYmxlQ29udGFpbmVyQXRQb3NpdGlvbihcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICAgc2NlbmVYLFxuICAgICAgc2NlbmVZLFxuICAgICk7XG5cbiAgICBpZiAoaGFzQm91bmRUZXh0RWxlbWVudChlbGVtZW50KSkge1xuICAgICAgY29udGFpbmVyID0gZWxlbWVudCBhcyBFeGNhbGlkcmF3VGV4dENvbnRhaW5lcjtcbiAgICAgIHNjZW5lWCA9IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgLyAyO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgc2NlbmVYLFxuICAgICAgc2NlbmVZLFxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI6ICFldmVudC5hbHRLZXksXG4gICAgICBjb250YWluZXIsXG4gICAgfSk7XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICAvLyBCZWdpbiBhIG1hcmsgY2FwdHVyZS4gVGhpcyBkb2VzIG5vdCBoYXZlIHRvIHVwZGF0ZSBzdGF0ZSB5ZXQuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIG51bGwsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdGcmVlRHJhd0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICByb3VuZG5lc3M6IG51bGwsXG4gICAgICBzaW11bGF0ZVByZXNzdXJlOiBldmVudC5wcmVzc3VyZSA9PT0gMC41LFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBwcmVzc3VyZXMgPSBlbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgID8gZWxlbWVudC5wcmVzc3VyZXNcbiAgICAgIDogWy4uLmVsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHBvaW50czogW1swLCAwXV0sXG4gICAgICBwcmVzc3VyZXMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUltYWdlRWxlbWVudCA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgfToge1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIHNjZW5lWTogbnVtYmVyO1xuICB9KSA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoc2NlbmVYLCBzY2VuZVksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ltYWdlRWxlbWVudCh7XG4gICAgICB0eXBlOiBcImltYWdlXCIsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgcm91bmRuZXNzOiBudWxsLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0xpbmVhckVsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIC8vIGZpbmFsaXplIGlmIGNvbXBsZXRpbmcgYSBsb29wXG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC50eXBlID09PSBcImxpbmVcIiAmJlxuICAgICAgICBpc1BhdGhBTG9vcChtdWx0aUVsZW1lbnQucG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgICApIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnksIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICAvLyBjbGlja2luZyBpbnNpZGUgY29tbWl0IHpvbmUg4oaSIGZpbmFsaXplIGFycm93XG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoID4gMSAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54IC0gcngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbbXVsdGlFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIC8vIGNsaWNraW5nIG91dHNpZGUgY29tbWl0IHpvbmUg4oaSIHVwZGF0ZSByZWZlcmVuY2UgZm9yIGxhc3QgY29tbWl0dGVkXG4gICAgICAvLyBwb2ludFxuICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICB9KTtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLyogSWYgYXJyb3cgaXMgcHJlLWFycm93aGVhZHMsIGl0IHdpbGwgaGF2ZSB1bmRlZmluZWQgZm9yIGJvdGggc3RhcnQgYW5kIGVuZCBhcnJvd2hlYWRzLlxuICAgICAgSWYgc28sIHdlIHdhbnQgaXQgdG8gYmUgbnVsbCBmb3Igc3RhcnQgYW5kIFwiYXJyb3dcIiBmb3IgZW5kLiBJZiB0aGUgbGluZWFyIGl0ZW0gaXMgbm90XG4gICAgICBhbiBhcnJvdywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBib3RoLiBPdGhlcndpc2UsIHdlIHdhbnQgaXQgdG8gdXNlIHRoZVxuICAgICAgdmFsdWVzIGZyb20gYXBwU3RhdGUuICovXG5cbiAgICAgIGNvbnN0IHsgY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCBbc3RhcnRBcnJvd2hlYWQsIGVuZEFycm93aGVhZF0gPVxuICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiXG4gICAgICAgICAgPyBbY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWRdXG4gICAgICAgICAgOiBbbnVsbCwgbnVsbF07XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdMaW5lYXJFbGVtZW50KHtcbiAgICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICAgIHg6IGdyaWRYLFxuICAgICAgICB5OiBncmlkWSxcbiAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgIHJvdW5kbmVzczpcbiAgICAgICAgICB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91bmRuZXNzID09PSBcInJvdW5kXCJcbiAgICAgICAgICAgID8geyB0eXBlOiBST1VORE5FU1MuUFJPUE9SVElPTkFMX1JBRElVUyB9XG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICAgIHN0YXJ0QXJyb3doZWFkLFxuICAgICAgICBlbmRBcnJvd2hlYWQsXG4gICAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgIHBvaW50czogWy4uLmVsZW1lbnQucG9pbnRzLCBbMCwgMF1dLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgKTtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIHN0YXJ0Qm91bmRFbGVtZW50OiBib3VuZEVsZW1lbnQsXG4gICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUdlbmVyaWNFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdFbGVtZW50KHtcbiAgICAgIHR5cGU6IGVsZW1lbnRUeXBlLFxuICAgICAgeDogZ3JpZFgsXG4gICAgICB5OiBncmlkWSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgcm91bmRuZXNzOlxuICAgICAgICB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91bmRuZXNzID09PSBcInJvdW5kXCJcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgdHlwZTogaXNVc2luZ0FkYXB0aXZlUmFkaXVzKGVsZW1lbnRUeXBlKVxuICAgICAgICAgICAgICAgID8gUk9VTkRORVNTLkFEQVBUSVZFX1JBRElVU1xuICAgICAgICAgICAgICAgIDogUk9VTkRORVNTLlBST1BPUlRJT05BTF9SQURJVVMsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiBudWxsLFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3Rpb25FbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgbXVsdGlFbGVtZW50OiBudWxsLFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25LZXlEb3duRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG9uS2V5VXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIC8vIFByZXZlbnRzIGZvY3VzIGZyb20gZXNjYXBpbmcgZXhjYWxpZHJhdyB0YWJcbiAgICAgIGV2ZW50LmtleSA9PT0gS0VZUy5BTFQgJiYgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyTW92ZUZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKSB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgLy8gV2UgbmVlZCB0byBpbml0aWFsaXplIGRyYWdPZmZzZXRYWSBvbmx5IGFmdGVyIHdlJ3ZlIHVwZGF0ZWRcbiAgICAgIC8vIGBzdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNgIG9uIHBvaW50ZXJEb3duLiBEb2luZyBpdCBoZXJlIGluIHBvaW50ZXJNb3ZlXG4gICAgICAvLyBldmVudCBoYW5kbGVyIHNob3VsZCBob3BlZnVsbHkgZW5zdXJlIHdlJ3JlIGFscmVhZHkgd29ya2luZyB3aXRoXG4gICAgICAvLyB0aGUgdXBkYXRlZCBzdGF0ZS5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0ID09PSBudWxsKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPSB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgZ2V0RHJhZ09mZnNldFhZKFxuICAgICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5oYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuXG4gICAgICBpZiAoaXNFcmFzZXJBY3RpdmUodGhpcy5zdGF0ZSkpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVFcmFzZXIoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUsIHBvaW50ZXJDb29yZHMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIC8vIGZvciBhcnJvd3MvbGluZXMsIGRvbid0IHN0YXJ0IGRyYWdnaW5nIHVudGlsIGEgZ2l2ZW4gdGhyZXNob2xkXG4gICAgICAvLyB0byBlbnN1cmUgd2UgZG9uJ3QgY3JlYXRlIGEgMi1wb2ludCBhcnJvdyBieSBtaXN0YWtlIHdoZW5cbiAgICAgIC8vIHVzZXIgY2xpY2tzIG1vdXNlIGluIGEgd2F5IHRoYXQgaXQgbW92ZXMgYSB0aW55IGJpdCAodGh1c1xuICAgICAgLy8gdHJpZ2dlcmluZyBwb2ludGVybW92ZSlcbiAgICAgIGlmIChcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImxpbmVcIilcbiAgICAgICkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICkgPCBEUkFHR0lOR19USFJFU0hPTERcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZykge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBsaW5lYXJFbGVtZW50RWRpdG9yID1cbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50O1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLnNob3VsZEFkZE1pZHBvaW50KFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHJldCA9IExpbmVhckVsZW1lbnRFZGl0b3IuYWRkTWlkcG9pbnQoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFyZXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgcmVhZGluZyBmcm9tIHByZXZpb3VzIHN0YXRlIHdoaWNoIGlzIG5vdCBwb3NzaWJsZSB3aXRoXG4gICAgICAgICAgLy8gYXV0b21hdGljIGJhdGNoaW5nIGluIFJlYWN0IDE4IGhlbmNlIHVzaW5nIGZsdXNoIHN5bmMgdG8gc3luY2hyb25vdXNseVxuICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGUuIENoZWNrIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC81NTA4IGZvciBtb3JlIGRldGFpbHMuXG5cbiAgICAgICAgICBmbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlOiByZXQucG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogcmV0LnNlbGVjdGVkUG9pbnRzSW5kaWNlcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgICAuLi50aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZTogcmV0LnBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6IHJldC5zZWxlY3RlZFBvaW50c0luZGljZXMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5wb2ludGVyRG93blN0YXRlLnNlZ21lbnRNaWRwb2ludC52YWx1ZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICFsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJEb3duU3RhdGUuc2VnbWVudE1pZHBvaW50LmFkZGVkXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRpZERyYWcgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50RHJhZ2dpbmcoXG4gICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgIChlbGVtZW50LCBwb2ludHNTY2VuZUNvb3JkcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgcG9pbnRzU2NlbmVDb29yZHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGRpZERyYWcpIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmlzRHJhZ2dpbmdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBoYXNIaXRBU2VsZWN0ZWRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZShcbiAgICAgICAgKGVsZW1lbnQpID0+IHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaXNTZWxlY3RpbmdQb2ludHNJbkxpbmVFZGl0b3IgPVxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgIGV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkID09PVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ/LmlkO1xuICAgICAgaWYgKFxuICAgICAgICAoaGFzSGl0QVNlbGVjdGVkRWxlbWVudCB8fFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSAmJlxuICAgICAgICAhaXNTZWxlY3RpbmdQb2ludHNJbkxpbmVFZGl0b3JcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmV2ZXJ5KChlbGVtZW50KSA9PiBlbGVtZW50LmxvY2tlZCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gTWFya2luZyB0aGF0IGNsaWNrIHdhcyB1c2VkIGZvciBkcmFnZ2luZyB0byBjaGVja1xuICAgICAgICAvLyBpZiBlbGVtZW50cyBzaG91bGQgYmUgZGVzZWxlY3RlZCBvbiBwb2ludGVydXBcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgLy8gcHJldmVudCBkcmFnZ2luZyBldmVuIGlmIHdlJ3JlIG5vIGxvbmdlciBob2xkaW5nIGNtZC9jdHJsIG90aGVyd2lzZVxuICAgICAgICAvLyBpdCB3b3VsZCBoYXZlIHdlaXJkIHJlc3VsdHMgKHN0dWZmIGp1bXBpbmcgYWxsIG92ZXIgdGhlIHNjcmVlbilcbiAgICAgICAgLy8gQ2hlY2tpbmcgZm9yIGVkaXRpbmdFbGVtZW50IHRvIGF2b2lkIGp1bXAgd2hpbGUgZWRpdGluZyBvbiBtb2JpbGUgIzY1MDNcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLndpdGhDbWRPckN0cmwgJiZcbiAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudFxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBbZHJhZ1gsIGRyYWdZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IFtkcmFnRGlzdGFuY2VYLCBkcmFnRGlzdGFuY2VZXSA9IFtcbiAgICAgICAgICAgIE1hdGguYWJzKHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngpLFxuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSksXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIC8vIFdlIG9ubHkgZHJhZyBpbiBvbmUgZGlyZWN0aW9uIGlmIHNoaWZ0IGlzIHByZXNzZWRcbiAgICAgICAgICBjb25zdCBsb2NrRGlyZWN0aW9uID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgICAgZHJhZ1NlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdYLFxuICAgICAgICAgICAgZHJhZ1ksXG4gICAgICAgICAgICBsb2NrRGlyZWN0aW9uLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWCxcbiAgICAgICAgICAgIGRyYWdEaXN0YW5jZVksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgICAgICAgLy8gV2UgZHVwbGljYXRlIHRoZSBzZWxlY3RlZCBlbGVtZW50IGlmIGFsdCBpcyBwcmVzc2VkIG9uIHBvaW50ZXIgbW92ZVxuICAgICAgICAgIGlmIChldmVudC5hbHRLZXkgJiYgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0JlZW5EdXBsaWNhdGVkKSB7XG4gICAgICAgICAgICAvLyBNb3ZlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZWxlbWVudHMgdG8gdGhlIHRvcCBvZiB0aGUgeiBpbmRleCBzdGFjaywgYW5kXG4gICAgICAgICAgICAvLyBwdXQgdGhlIGR1cGxpY2F0ZXMgd2hlcmUgdGhlIHNlbGVjdGVkIGVsZW1lbnRzIHVzZWQgdG8gYmUuXG4gICAgICAgICAgICAvLyAodGhlIG9yaWdpbiBwb2ludCB3aGVyZSB0aGUgZHJhZ2dpbmcgc3RhcnRlZClcblxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzVG9BcHBlbmQgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwSWRNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBvbGRJZFRvRHVwbGljYXRlZElkID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRJZHM6IEFycmF5PEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0+ID1cbiAgICAgICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSwgdHJ1ZSkubWFwKFxuICAgICAgICAgICAgICAgIChlbGVtZW50KSA9PiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkcy5pbmNsdWRlcyhlbGVtZW50LmlkKSB8fFxuICAgICAgICAgICAgICAgIC8vIGNhc2U6IHRoZSBzdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMgbWlnaHQgbm90IGhhdmUgYmVlblxuICAgICAgICAgICAgICAgIC8vIHVwZGF0ZWQgeWV0IGJ5IHRoZSB0aW1lIHRoaXMgbW91c2Vtb3ZlIGV2ZW50IGlzIGZpcmVkXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQuaWQgPT09IGhpdEVsZW1lbnQ/LmlkICYmXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkdXBsaWNhdGVkRWxlbWVudCA9IGR1cGxpY2F0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkLFxuICAgICAgICAgICAgICAgICAgZ3JvdXBJZE1hcCxcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3JpZ2luRHJhZ1gsIG9yaWdpbkRyYWdZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHVwbGljYXRlZEVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICAgIHg6IGR1cGxpY2F0ZWRFbGVtZW50LnggKyAob3JpZ2luRHJhZ1ggLSBkcmFnWCksXG4gICAgICAgICAgICAgICAgICB5OiBkdXBsaWNhdGVkRWxlbWVudC55ICsgKG9yaWdpbkRyYWdZIC0gZHJhZ1kpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG5leHRFbGVtZW50cy5wdXNoKGR1cGxpY2F0ZWRFbGVtZW50KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZC5zZXQoZWxlbWVudC5pZCwgZHVwbGljYXRlZEVsZW1lbnQuaWQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5leHRFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBuZXh0U2NlbmVFbGVtZW50cyA9IFsuLi5uZXh0RWxlbWVudHMsIC4uLmVsZW1lbnRzVG9BcHBlbmRdO1xuICAgICAgICAgICAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbihcbiAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLFxuICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLFxuICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbihcbiAgICAgICAgICAgICAgbmV4dFNjZW5lRWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICAgIFwiZHVwbGljYXRlc1NlcnZlQXNPbGRcIixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhuZXh0U2NlbmVFbGVtZW50cyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJdCBpcyB2ZXJ5IGltcG9ydGFudCB0byByZWFkIHRoaXMuc3RhdGUgd2l0aGluIGVhY2ggbW92ZSBldmVudCxcbiAgICAgIC8vIG90aGVyd2lzZSB3ZSB3b3VsZCByZWFkIGEgc3RhbGUgb25lIVxuICAgICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGNvbnN0IGR4ID0gcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGNvbnN0IGR5ID0gcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzLmxlbmd0aCA+IDAgJiYgcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3QgZGlzY2FyZFBvaW50ID1cbiAgICAgICAgICBsYXN0UG9pbnQgJiYgbGFzdFBvaW50WzBdID09PSBkeCAmJiBsYXN0UG9pbnRbMV0gPT09IGR5O1xuXG4gICAgICAgIGlmICghZGlzY2FyZFBvaW50KSB7XG4gICAgICAgICAgY29uc3QgcHJlc3N1cmVzID0gZHJhZ2dpbmdFbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgICAgICAgID8gZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlc1xuICAgICAgICAgICAgOiBbLi4uZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlcywgZXZlbnQucHJlc3N1cmVdO1xuXG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgICAgcHJlc3N1cmVzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IGdyaWRYIC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGxldCBkeSA9IGdyaWRZIC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSAmJiBwb2ludHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgKHsgd2lkdGg6IGR4LCBoZWlnaHQ6IGR5IH0gPSBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUoXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudC55LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMuc2xpY2UoMCwgLTEpLCBbZHgsIGR5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIGZhbHNlKSkge1xuICAgICAgICAgIC8vIFdoZW4gY3JlYXRpbmcgYSBsaW5lYXIgZWxlbWVudCBieSBkcmFnZ2luZ1xuICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBbcG9pbnRlckNvb3Jkc10sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgLy8gYWxsb3dzIGZvciBib3gtc2VsZWN0aW5nIHBvaW50cyAod2l0aG91dCBzaGlmdClcbiAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgIGlzU29tZUVsZW1lbnRTZWxlY3RlZChlbGVtZW50cywgdGhpcy5zdGF0ZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCAmJiBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gYm94LXNlbGVjdCBsaW5lIGVkaXRvciBwb2ludHNcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZUJveFNlbGVjdGlvbihcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHJlZ3VsYXIgYm94LXNlbGVjdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uID0gZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24oXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ucmVkdWNlKFxuICAgICAgICAgICAgICAgICAgICAoYWNjOiBSZWNvcmQ8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXSwgdHJ1ZT4sIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICBhY2NbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgIC4uLihwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50XG4gICAgICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdXNpbmcgY3RybC9jbWQsIHNlbGVjdCB0aGUgaGl0RWxlbWVudCBvbmx5IGlmIHdlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBoYXZlbid0IGJveC1zZWxlY3RlZCBhbnl0aGluZyBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudC5pZF06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICFlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA6IG51bGwpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2hvd0h5cGVybGlua1BvcHVwOlxuICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvblswXS5saW5rXG4gICAgICAgICAgICAgICAgICAgID8gXCJpbmZvXCJcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAvLyBzZWxlY3QgbGluZWFyIGVsZW1lbnQgb25seSB3aGVuIHdlIGhhdmVuJ3QgYm94LXNlbGVjdGVkIGFueXRoaW5nIGVsc2VcbiAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgIGlzTGluZWFyRWxlbWVudChlbGVtZW50c1dpdGhpblNlbGVjdGlvblswXSlcbiAgICAgICAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIG1vdmUgaGFwcGVuZWQgb3ZlciBlaXRoZXIgc2Nyb2xsYmFyXG4gIHByaXZhdGUgaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhcbiAgICBldmVudDogUG9pbnRlckV2ZW50LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVySG9yaXpvbnRhbCkge1xuICAgICAgY29uc3QgeCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBkeCA9IHggLSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueDtcbiAgICAgIHRoaXMudHJhbnNsYXRlQ2FudmFzKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZHggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0geDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyVmVydGljYWwpIHtcbiAgICAgIGNvbnN0IHkgPSBldmVudC5jbGllbnRZO1xuICAgICAgY29uc3QgZHkgPSB5IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnk7XG4gICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcyh7XG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGR5IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGNoaWxkRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudCxcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICBhY3RpdmVUb29sLFxuICAgICAgICBpc1Jlc2l6aW5nLFxuICAgICAgICBpc1JvdGF0aW5nLFxuICAgICAgfSA9IHRoaXMuc3RhdGU7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIGlzUm90YXRpbmc6IGZhbHNlLFxuICAgICAgICByZXNpemluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICAvLyB0ZXh0IGVsZW1lbnRzIGFyZSByZXNldCBvbiBmaW5hbGl6ZSwgYW5kIHJlc2V0dGluZyBvbiBwb2ludGVydXBcbiAgICAgICAgLy8gbWF5IGNhdXNlIGlzc3VlcyB3aXRoIGRvdWJsZSB0YXBzXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgIG11bHRpRWxlbWVudCB8fCBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnRcbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGNoaWxkRXZlbnQuY2xpZW50WCwgY2hpbGRFdmVudC5jbGllbnRZLCBcInVwXCIpO1xuXG4gICAgICB0aGlzLm9uUG9pbnRlclVwRW1pdHRlci50cmlnZ2VyKFxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICApO1xuXG4gICAgICAvLyBIYW5kbGUgZW5kIG9mIGRyYWdnaW5nIGEgcG9pbnQgb2YgYSBsaW5lYXIgZWxlbWVudCwgbWlnaHQgY2xvc2UgYSBsb29wXG4gICAgICAvLyBhbmQgc2V0cyBiaW5kaW5nIGVsZW1lbnRcbiAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJVcChcbiAgICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Py5lbGVtZW50Py5pZCAhPT1cbiAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5lbGVtZW50SWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFTGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHNldCBzZWxlY3RlZExpbmVhckVsZW1lbnQgdG8gbnVsbCBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGVsZW1lbnQgc2VsZWN0ZWQgc2luY2Ugd2UgZG9uJ3Qgd2FudCB0byBzaG93IGxpbmVhciBlbGVtZW50IGhhbmRsZXNcbiAgICAgICAgICBpZiAoc2VsZWN0ZWRFTGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBsaW5lYXJFbGVtZW50RWRpdG9yID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyVXAoXG4gICAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCB7IHN0YXJ0QmluZGluZ0VsZW1lbnQsIGVuZEJpbmRpbmdFbGVtZW50IH0gPVxuICAgICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvcjtcbiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50KGxpbmVhckVsZW1lbnRFZGl0b3IuZWxlbWVudElkKTtcbiAgICAgICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgICAgYmluZE9yVW5iaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgc3RhcnRCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgZW5kQmluZGluZ0VsZW1lbnQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChsaW5lYXJFbGVtZW50RWRpdG9yICE9PSB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLmxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzOiBudWxsLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZS5mbHVzaCgpO1xuICAgICAgfVxuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuUE9JTlRFUl9NT1ZFLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWURPV04sXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuS0VZVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCEsXG4gICAgICApO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogbnVsbCB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudD8udHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICAvLyBBbGxvd3MgZG90cyB0byBhdm9pZCBiZWluZyBmbGFnZ2VkIGFzIGluZmluaXRlbHkgc21hbGxcbiAgICAgICAgaWYgKGR4ID09PSBwb2ludHNbMF1bMF0gJiYgZHkgPT09IHBvaW50c1swXVsxXSkge1xuICAgICAgICAgIGR5ICs9IDAuMDAwMTtcbiAgICAgICAgICBkeCArPSAwLjAwMDE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBjaGlsZEV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IFtkeCwgZHldLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICB7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSBpbWFnZUVsZW1lbnQuaWQpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQhLnBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgICAgIW11bHRpRWxlbWVudFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAgIC4uLmRyYWdnaW5nRWxlbWVudC5wb2ludHMsXG4gICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQ6IGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiYgIW11bHRpRWxlbWVudCkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCBmYWxzZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10sIHN0YXJ0Qm91bmRFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICAgIGlmICghYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbZHJhZ2dpbmdFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICkge1xuICAgICAgICAvLyByZW1vdmUgaW52aXNpYmxlIGVsZW1lbnQgd2hpY2ggd2FzIGFkZGVkIGluIG9uUG9pbnRlckRvd25cbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5zbGljZSgwLCAtMSksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyhkcmFnZ2luZ0VsZW1lbnQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCAmJiBpc0ludmlzaWJseVNtYWxsRWxlbWVudChyZXNpemluZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSByZXNpemluZ0VsZW1lbnQuaWQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDb2RlIGJlbG93IGhhbmRsZXMgc2VsZWN0aW9uIHdoZW4gZWxlbWVudChzKSB3ZXJlbid0XG4gICAgICAvLyBkcmFnIG9yIGFkZGVkIHRvIHNlbGVjdGlvbiBvbiBwb2ludGVyIGRvd24gcGhhc2UuXG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgaXNMaW5lYXJFbGVtZW50KGhpdEVsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFTGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IHdoZW4gbm8gb3RoZXIgZWxlbWVudCBzZWxlY3RlZCBleGNlcHRcbiAgICAgICAgLy8gdGhlIG9uZSB3ZSd2ZSBoaXRcbiAgICAgICAgaWYgKHNlbGVjdGVkRUxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICAgIGNvbnN0IGRyYWdnZWREaXN0YW5jZSA9IGRpc3RhbmNlMmQoXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFgsXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFksXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRYLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZHJhZ2dlZERpc3RhbmNlID09PSAwKSB7XG4gICAgICAgICAgY29uc3Qgc2NlbmVQb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjbGllbnRYOiB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICAgICAgICAgIGNsaWVudFk6IHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgaGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBoaXRFbGVtZW50cy5mb3JFYWNoKFxuICAgICAgICAgICAgKGhpdEVsZW1lbnQpID0+XG4gICAgICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2hpdEVsZW1lbnQuaWRdID0ge1xuICAgICAgICAgICAgICAgIGVyYXNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IGhpdEVsZW1lbnQub3BhY2l0eSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVyYXNlRWxlbWVudHMocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LmtleXMocG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZSkubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucmVzdG9yZVJlYWR5VG9FcmFzZUVsZW1lbnRzKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiAmJlxuICAgICAgICAvLyBpZiB3ZSdyZSBlZGl0aW5nIGEgbGluZSwgcG9pbnRlcnVwIHNob3VsZG4ndCBzd2l0Y2ggc2VsZWN0aW9uIGlmXG4gICAgICAgIC8vIGJveCBzZWxlY3RlZFxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQpXG4gICAgICApIHtcbiAgICAgICAgLy8gd2hlbiBpbnNpZGUgbGluZSBlZGl0b3IsIHNoaWZ0IHNlbGVjdHMgcG9pbnRzIGluc3RlYWRcbiAgICAgICAgaWYgKGNoaWxkRXZlbnQuc2hpZnRLZXkgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIGlmIChpc1NlbGVjdGVkVmlhR3JvdXAodGhpcy5zdGF0ZSwgaGl0RWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgLy8gV2Ugd2FudCB0byB1bnNlbGVjdCBhbGwgZ3JvdXBzIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICAvLyBhcyB3ZWxsIGFzIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBncm91cHNcbiAgICAgICAgICAgICAgLy8gaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIGNvbnN0IGlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyA9IGhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAuZmxhdE1hcCgoZ3JvdXBJZCkgPT5cbiAgICAgICAgICAgICAgICAgIGdldEVsZW1lbnRzSW5Hcm91cChcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBJZCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5tYXAoKGVsZW1lbnQpID0+ICh7IFtlbGVtZW50LmlkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldklkLCBhY2MpID0+ICh7IC4uLnByZXZJZCwgLi4uYWNjIH0pLCB7fSk7XG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZ0lkKSA9PiAoeyBbZ0lkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXYsIGFjYykgPT4gKHsgLi4ucHJldiwgLi4uYWNjIH0pLCB7fSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgLy8gaWYgbm90IGdyYWdnaW5nIGEgbGluZWFyIGVsZW1lbnQgcG9pbnQgKG91dHNpZGUgZWRpdG9yKVxuICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgICAgLy8gcmVtb3ZlIGVsZW1lbnQgZnJvbSBzZWxlY3Rpb24gd2hpbGVcbiAgICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2VsZWN0ZWRFbGVtZW50SWRzID0ge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IGZhbHNlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICAgICAgeyAuLi5wcmV2U3RhdGUsIHNlbGVjdGVkRWxlbWVudElkczogbmV3U2VsZWN0ZWRFbGVtZW50SWRzIH0sXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogbmV3U2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IG9ubHkgaWYgdGhhdHMgdGhlIG9ubHkgZWxlbWVudCBzZWxlY3RlZFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICAgICAgbmV3U2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgICAgICBpc0xpbmVhckVsZW1lbnQobmV3U2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gYWRkIGVsZW1lbnQgdG8gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAvLyBrZWVwaW5nIHByZXYgZWxlbWVudHMgc2VsZWN0ZWRcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKF9wcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIC4uLnNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDpcbiAgICAgICAgICAgICAgICAgIGlzTGluZWFyRWxlbWVudChoaXRFbGVtZW50KSAmJlxuICAgICAgICAgICAgICAgICAgLy8gRG9uJ3Qgc2V0IGBzZWxlY3RlZExpbmVhckVsZW1lbnRgIGlmIGl0cyBzYW1lIGFzIHRoZSBoaXRFbGVtZW50LCB0aGlzIGlzIG1haW5seSB0byBwcmV2ZW50IHJlc2V0dGluZyB0aGUgYGhvdmVyUG9pbnRJbmRleGAgdG8gLTEuXG4gICAgICAgICAgICAgICAgICAvLyBGdXR1cmUgd2Ugc2hvdWxkIHVwZGF0ZSB0aGUgQVBJIHRvIHRha2UgY2FyZSBvZiBzZXR0aW5nIHRoZSBjb3JyZWN0IGBob3ZlclBvaW50SW5kZXhgIHdoZW4gaW5pdGlhbGl6ZWRcbiAgICAgICAgICAgICAgICAgIHByZXZTdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT0gaGl0RWxlbWVudC5pZFxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKGhpdEVsZW1lbnQsIHRoaXMuc2NlbmUpXG4gICAgICAgICAgICAgICAgICAgIDogcHJldlN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5pc1Jlc2l6aW5nICYmXG4gICAgICAgICgoaGl0RWxlbWVudCAmJlxuICAgICAgICAgIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSkgfHxcbiAgICAgICAgICAoIWhpdEVsZW1lbnQgJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSlcbiAgICAgICkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXNlbGVjdCBzZWxlY3RlZCBlbGVtZW50c1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFhY3RpdmVUb29sLmxvY2tlZCAmJlxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwiZnJlZWRyYXdcIiAmJlxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnRcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQodGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgfHwgaXNSZXNpemluZyB8fCBpc1JvdGF0aW5nKSB7XG4gICAgICAgIChpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cykoXG4gICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhY3RpdmVUb29sLmxvY2tlZCAmJiBhY3RpdmVUb29sLnR5cGUgIT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVSZWFkeVRvRXJhc2VFbGVtZW50cyA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0ub3BhY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBpc0JvdW5kVG9Db250YWluZXIoZWxlKSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0gJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdLmVyYXNlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgIG9wYWNpdHk6IHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5vcGFjaXR5LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBlcmFzZUVsZW1lbnRzID0gKHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUpID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHsgaXNEZWxldGVkOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHsgaXNEZWxldGVkOiB0cnVlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZTtcbiAgICB9KTtcblxuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2UgPSBhc3luYyAoe1xuICAgIGltYWdlRmlsZSxcbiAgICBpbWFnZUVsZW1lbnQ6IF9pbWFnZUVsZW1lbnQsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldyA9IGZhbHNlLFxuICB9OiB7XG4gICAgaW1hZ2VGaWxlOiBGaWxlO1xuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudDtcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3PzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIC8vIGF0IHRoaXMgcG9pbnQgdGhpcyBzaG91bGQgYmUgZ3VhcmFudGVlZCBpbWFnZSBmaWxlLCBidXQgd2UgZG8gdGhpcyBjaGVja1xuICAgIC8vIHRvIHNhdGlzZnkgVFMgZG93biB0aGUgbGluZVxuICAgIGlmICghaXNTdXBwb3J0ZWRJbWFnZUZpbGUoaW1hZ2VGaWxlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMudW5zdXBwb3J0ZWRGaWxlVHlwZVwiKSk7XG4gICAgfVxuICAgIGNvbnN0IG1pbWVUeXBlID0gaW1hZ2VGaWxlLnR5cGU7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIFwid2FpdFwiKTtcblxuICAgIGlmIChtaW1lVHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IFNWR1N0cmluZ1RvRmlsZShcbiAgICAgICAgICBhd2FpdCBub3JtYWxpemVTVkcoYXdhaXQgaW1hZ2VGaWxlLnRleHQoKSksXG4gICAgICAgICAgaW1hZ2VGaWxlLm5hbWUsXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnN2Z0ltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGdlbmVyYXRlIGltYWdlIGlkIChieSBkZWZhdWx0IHRoZSBmaWxlIGRpZ2VzdCkgYmVmb3JlIGFueVxuICAgIC8vIHJlc2l6aW5nL2NvbXByZXNzaW9uIHRha2VzIHBsYWNlIHRvIGtlZXAgaXQgbW9yZSBwb3J0YWJsZVxuICAgIGNvbnN0IGZpbGVJZCA9IGF3YWl0ICgodGhpcy5wcm9wcy5nZW5lcmF0ZUlkRm9yRmlsZT8uKFxuICAgICAgaW1hZ2VGaWxlLFxuICAgICkgYXMgUHJvbWlzZTxGaWxlSWQ+KSB8fCBnZW5lcmF0ZUlkRnJvbUZpbGUoaW1hZ2VGaWxlKSk7XG5cbiAgICBpZiAoIWZpbGVJZCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkNvdWxkbid0IGdlbmVyYXRlIGZpbGUgaWQgb3IgdGhlIHN1cHBsaWVkIGBnZW5lcmF0ZUlkRm9yRmlsZWAgZGlkbid0IHJlc29sdmUgdG8gb25lLlwiLFxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nRmlsZURhdGEgPSB0aGlzLmZpbGVzW2ZpbGVJZF07XG4gICAgaWYgKCFleGlzdGluZ0ZpbGVEYXRhPy5kYXRhVVJMKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBhd2FpdCByZXNpemVJbWFnZUZpbGUoaW1hZ2VGaWxlLCB7XG4gICAgICAgICAgbWF4V2lkdGhPckhlaWdodDogREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIHRyeWluZyB0byByZXNpbmcgaW1hZ2UgZmlsZSBvbiBpbnNlcnRpb25cIiwgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW1hZ2VGaWxlLnNpemUgPiBNQVhfQUxMT1dFRF9GSUxFX0JZVEVTKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICB0KFwiZXJyb3JzLmZpbGVUb29CaWdcIiwge1xuICAgICAgICAgICAgbWF4U2l6ZTogYCR7TWF0aC50cnVuYyhNQVhfQUxMT1dFRF9GSUxFX0JZVEVTIC8gMTAyNCAvIDEwMjQpfU1CYCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvd0N1cnNvckltYWdlUHJldmlldykge1xuICAgICAgY29uc3QgZGF0YVVSTCA9IHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTDtcbiAgICAgIC8vIG9wdGltaXphdGlvbiBzbyB0aGF0IHdlIGRvbid0IHVubmVjZXNzYXJpbHkgcmVzaXplIHRoZSBvcmlnaW5hbFxuICAgICAgLy8gZnVsbC1zaXplIGZpbGUgZm9yIGN1cnNvciBwcmV2aWV3XG4gICAgICAvLyAoaXQncyBtdWNoIGZhc3RlciB0byBjb252ZXJ0IHRoZSByZXNpemVkIGRhdGFVUkwgdG8gRmlsZSlcbiAgICAgIGNvbnN0IHJlc2l6ZWRGaWxlID0gZGF0YVVSTCAmJiBkYXRhVVJMVG9GaWxlKGRhdGFVUkwpO1xuXG4gICAgICB0aGlzLnNldEltYWdlUHJldmlld0N1cnNvcihyZXNpemVkRmlsZSB8fCBpbWFnZUZpbGUpO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFVUkwgPVxuICAgICAgdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMIHx8IChhd2FpdCBnZXREYXRhVVJMKGltYWdlRmlsZSkpO1xuXG4gICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gbXV0YXRlRWxlbWVudChcbiAgICAgIF9pbWFnZUVsZW1lbnQsXG4gICAgICB7XG4gICAgICAgIGZpbGVJZCxcbiAgICAgIH0sXG4gICAgICBmYWxzZSxcbiAgICApIGFzIE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50PjtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD4+KFxuICAgICAgYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuZmlsZXMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmZpbGVzLFxuICAgICAgICAgICAgW2ZpbGVJZF06IHtcbiAgICAgICAgICAgICAgbWltZVR5cGUsXG4gICAgICAgICAgICAgIGlkOiBmaWxlSWQsXG4gICAgICAgICAgICAgIGRhdGFVUkwsXG4gICAgICAgICAgICAgIGNyZWF0ZWQ6IERhdGUubm93KCksXG4gICAgICAgICAgICAgIGxhc3RSZXRyaWV2ZWQ6IERhdGUubm93KCksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY2FjaGVkSW1hZ2VEYXRhID0gdGhpcy5pbWFnZUNhY2hlLmdldChmaWxlSWQpO1xuICAgICAgICAgIGlmICghY2FjaGVkSW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFtpbWFnZUVsZW1lbnRdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNhY2hlZEltYWdlRGF0YT8uaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBhd2FpdCBjYWNoZWRJbWFnZURhdGEuaW1hZ2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkICE9PSBpbWFnZUVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50Py5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50LCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShpbWFnZUVsZW1lbnQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoIXNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogaW5zZXJ0cyBpbWFnZSBpbnRvIGVsZW1lbnRzIGFycmF5IGFuZCByZXJlbmRlcnNcbiAgICovXG4gIHByaXZhdGUgaW5zZXJ0SW1hZ2VFbGVtZW50ID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBpbWFnZUZpbGU6IEZpbGUsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBpbWFnZUVsZW1lbnQsXG4gICAgXSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplSW1hZ2Uoe1xuICAgICAgICBpbWFnZUZpbGUsXG4gICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgc2hvd0N1cnNvckltYWdlUHJldmlldyxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIGlzRGVsZXRlZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB8fCB0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIiksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRJbWFnZVByZXZpZXdDdXJzb3IgPSBhc3luYyAoaW1hZ2VGaWxlOiBGaWxlKSA9PiB7XG4gICAgLy8gbXVzdG4ndCBiZSBsYXJnZXIgdGhhbiAxMjggcHhcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ1NTX0Jhc2ljX1VzZXJfSW50ZXJmYWNlL1VzaW5nX1VSTF92YWx1ZXNfZm9yX3RoZV9jdXJzb3JfcHJvcGVydHlcbiAgICBjb25zdCBjdXJzb3JJbWFnZVNpemVQeCA9IDk2O1xuXG4gICAgY29uc3QgaW1hZ2VQcmV2aWV3ID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgbWF4V2lkdGhPckhlaWdodDogY3Vyc29ySW1hZ2VTaXplUHgsXG4gICAgfSk7XG5cbiAgICBsZXQgcHJldmlld0RhdGFVUkwgPSBhd2FpdCBnZXREYXRhVVJMKGltYWdlUHJldmlldyk7XG5cbiAgICAvLyBTVkcgY2Fubm90IGJlIHJlc2l6ZWQgdmlhIGByZXNpemVJbWFnZUZpbGVgIHNvIHdlIHJlc2l6ZSBieSByZW5kZXJpbmcgdG9cbiAgICAvLyBhIHNtYWxsIGNhbnZhc1xuICAgIGlmIChpbWFnZUZpbGUudHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIGNvbnN0IGltZyA9IGF3YWl0IGxvYWRIVE1MSW1hZ2VFbGVtZW50KHByZXZpZXdEYXRhVVJMKTtcblxuICAgICAgbGV0IGhlaWdodCA9IE1hdGgubWluKGltZy5oZWlnaHQsIGN1cnNvckltYWdlU2l6ZVB4KTtcbiAgICAgIGxldCB3aWR0aCA9IGhlaWdodCAqIChpbWcud2lkdGggLyBpbWcuaGVpZ2h0KTtcblxuICAgICAgaWYgKHdpZHRoID4gY3Vyc29ySW1hZ2VTaXplUHgpIHtcbiAgICAgICAgd2lkdGggPSBjdXJzb3JJbWFnZVNpemVQeDtcbiAgICAgICAgaGVpZ2h0ID0gd2lkdGggKiAoaW1nLmhlaWdodCAvIGltZy53aWR0aCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSE7XG5cbiAgICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgIHByZXZpZXdEYXRhVVJMID0gY2FudmFzLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgYHVybCgke3ByZXZpZXdEYXRhVVJMfSkgNCA0LCBhdXRvYCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25JbWFnZUFjdGlvbiA9IGFzeW5jIChcbiAgICB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHkgfSA9IHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseTogZmFsc2UgfSxcbiAgKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNsaWVudFggPSB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdDtcbiAgICAgIGNvbnN0IGNsaWVudFkgPSB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcDtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2VGaWxlID0gYXdhaXQgZmlsZU9wZW4oe1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJbWFnZVwiLFxuICAgICAgICBleHRlbnNpb25zOiBPYmplY3Qua2V5cyhcbiAgICAgICAgICBJTUFHRV9NSU1FX1RZUEVTLFxuICAgICAgICApIGFzIChrZXlvZiB0eXBlb2YgSU1BR0VfTUlNRV9UWVBFUylbXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7XG4gICAgICAgIHNjZW5lWDogeCxcbiAgICAgICAgc2NlbmVZOiB5LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChpbnNlcnRPbkNhbnZhc0RpcmVjdGx5KSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgaW1hZ2VGaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBpbWFnZUVsZW1lbnQuaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChcbiAgICAgICAgICAgICAgaW1hZ2VFbGVtZW50LFxuICAgICAgICAgICAgICBpbWFnZUZpbGUsXG4gICAgICAgICAgICAgIC8qIHNob3dDdXJzb3JJbWFnZVByZXZpZXcgKi8gdHJ1ZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJBYm9ydEVycm9yXCIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogbnVsbCxcbiAgICAgICAgICBlZGl0aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyA9IChcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gICAgZm9yY2VOYXR1cmFsU2l6ZSA9IGZhbHNlLFxuICApID0+IHtcbiAgICBjb25zdCBpbWFnZSA9XG4gICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCkgJiZcbiAgICAgIHRoaXMuaW1hZ2VDYWNoZS5nZXQoaW1hZ2VFbGVtZW50LmZpbGVJZCk/LmltYWdlO1xuXG4gICAgaWYgKCFpbWFnZSB8fCBpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgIGlmIChcbiAgICAgICAgaW1hZ2VFbGVtZW50LndpZHRoIDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlICYmXG4gICAgICAgIGltYWdlRWxlbWVudC5oZWlnaHQgPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWVcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwbGFjZWhvbGRlclNpemUgPSAxMDAgLyB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7XG4gICAgICAgICAgeDogaW1hZ2VFbGVtZW50LnggLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHk6IGltYWdlRWxlbWVudC55IC0gcGxhY2Vob2xkZXJTaXplIC8gMixcbiAgICAgICAgICB3aWR0aDogcGxhY2Vob2xkZXJTaXplLFxuICAgICAgICAgIGhlaWdodDogcGxhY2Vob2xkZXJTaXplLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGZvcmNlTmF0dXJhbFNpemUgfHxcbiAgICAgIC8vIGlmIHVzZXItY3JlYXRlZCBib3VuZGluZyBib3ggaXMgYmVsb3cgdGhyZXNob2xkLCBhc3N1bWUgdGhlXG4gICAgICAvLyBpbnRlbnRpb24gd2FzIHRvIGNsaWNrIGluc3RlYWQgb2YgZHJhZywgYW5kIHVzZSB0aGUgaW1hZ2Unc1xuICAgICAgLy8gaW50cmluc2ljIHNpemVcbiAgICAgIChpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSlcbiAgICApIHtcbiAgICAgIGNvbnN0IG1pbkhlaWdodCA9IE1hdGgubWF4KHRoaXMuc3RhdGUuaGVpZ2h0IC0gMTIwLCAxNjApO1xuICAgICAgLy8gbWF4IDY1JSBvZiBjYW52YXMgaGVpZ2h0LCBjbGFtcGVkIHRvIDwzMDBweCwgdmggLSAxMjBweD5cbiAgICAgIGNvbnN0IG1heEhlaWdodCA9IE1hdGgubWluKFxuICAgICAgICBtaW5IZWlnaHQsXG4gICAgICAgIE1hdGguZmxvb3IodGhpcy5zdGF0ZS5oZWlnaHQgKiAwLjUpIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5taW4oaW1hZ2UubmF0dXJhbEhlaWdodCwgbWF4SGVpZ2h0KTtcbiAgICAgIGNvbnN0IHdpZHRoID0gaGVpZ2h0ICogKGltYWdlLm5hdHVyYWxXaWR0aCAvIGltYWdlLm5hdHVyYWxIZWlnaHQpO1xuXG4gICAgICAvLyBhZGQgY3VycmVudCBpbWFnZUVsZW1lbnQgd2lkdGgvaGVpZ2h0IHRvIGFjY291bnQgZm9yIHByZXZpb3VzIGNlbnRlcmluZ1xuICAgICAgLy8gb2YgdGhlIHBsYWNlaG9sZGVyIGltYWdlXG4gICAgICBjb25zdCB4ID0gaW1hZ2VFbGVtZW50LnggKyBpbWFnZUVsZW1lbnQud2lkdGggLyAyIC0gd2lkdGggLyAyO1xuICAgICAgY29uc3QgeSA9IGltYWdlRWxlbWVudC55ICsgaW1hZ2VFbGVtZW50LmhlaWdodCAvIDIgLSBoZWlnaHQgLyAyO1xuXG4gICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwgeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0pO1xuICAgIH1cbiAgfTtcblxuICAvKiogdXBkYXRlcyBpbWFnZSBjYWNoZSwgcmVmcmVzaGluZyB1cGRhdGVkIGVsZW1lbnRzIGFuZC9vciBzZXR0aW5nIHN0YXR1c1xuICAgICAgdG8gZXJyb3IgZm9yIGltYWdlcyB0aGF0IGZhaWwgZHVyaW5nIDxpbWc+IGVsZW1lbnQgY3JlYXRpb24gKi9cbiAgcHJpdmF0ZSB1cGRhdGVJbWFnZUNhY2hlID0gYXN5bmMgKFxuICAgIGVsZW1lbnRzOiByZWFkb25seSBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnRbXSxcbiAgICBmaWxlcyA9IHRoaXMuZmlsZXMsXG4gICkgPT4ge1xuICAgIGNvbnN0IHsgdXBkYXRlZEZpbGVzLCBlcnJvcmVkRmlsZXMgfSA9IGF3YWl0IF91cGRhdGVJbWFnZUNhY2hlKHtcbiAgICAgIGltYWdlQ2FjaGU6IHRoaXMuaW1hZ2VDYWNoZSxcbiAgICAgIGZpbGVJZHM6IGVsZW1lbnRzLm1hcCgoZWxlbWVudCkgPT4gZWxlbWVudC5maWxlSWQpLFxuICAgICAgZmlsZXMsXG4gICAgfSk7XG4gICAgaWYgKHVwZGF0ZWRGaWxlcy5zaXplIHx8IGVycm9yZWRGaWxlcy5zaXplKSB7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgaWYgKHVwZGF0ZWRGaWxlcy5oYXMoZWxlbWVudC5maWxlSWQpKSB7XG4gICAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZXJyb3JlZEZpbGVzLnNpemUpIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZWxlbWVudCkgJiZcbiAgICAgICAgICAgIGVycm9yZWRGaWxlcy5oYXMoZWxlbWVudC5maWxlSWQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlbWVudCwge1xuICAgICAgICAgICAgICBzdGF0dXM6IFwiZXJyb3JcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB7IHVwZGF0ZWRGaWxlcywgZXJyb3JlZEZpbGVzIH07XG4gIH07XG5cbiAgLyoqIGFkZHMgbmV3IGltYWdlcyB0byBpbWFnZUNhY2hlIGFuZCByZS1yZW5kZXJzIGlmIG5lZWRlZCAqL1xuICBwcml2YXRlIGFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSA9IGFzeW5jIChcbiAgICBpbWFnZUVsZW1lbnRzOiBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnRbXSA9IGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgKSxcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB1bmNhY2hlZEltYWdlRWxlbWVudHMgPSBpbWFnZUVsZW1lbnRzLmZpbHRlcihcbiAgICAgIChlbGVtZW50KSA9PiAhZWxlbWVudC5pc0RlbGV0ZWQgJiYgIXRoaXMuaW1hZ2VDYWNoZS5oYXMoZWxlbWVudC5maWxlSWQpLFxuICAgICk7XG5cbiAgICBpZiAodW5jYWNoZWRJbWFnZUVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29uc3QgeyB1cGRhdGVkRmlsZXMgfSA9IGF3YWl0IHRoaXMudXBkYXRlSW1hZ2VDYWNoZShcbiAgICAgICAgdW5jYWNoZWRJbWFnZUVsZW1lbnRzLFxuICAgICAgICBmaWxlcyxcbiAgICAgICk7XG4gICAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5pbmZvcm1NdXRhdGlvbigpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKiogZ2VuZXJhbGx5IHlvdSBzaG91bGQgdXNlIGBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKWAgZGlyZWN0bHkgaWYgeW91IG5lZWRcbiAgICogIHRvIHJlbmRlciBuZXcgaW1hZ2VzLiBUaGlzIGlzIGp1c3QgYSBmYWlsc2FmZSAgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZUltYWdlUmVmcmVzaCA9IHRocm90dGxlKCgpID0+IHtcbiAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICB9LCBJTUFHRV9SRU5ERVJfVElNRU9VVCk7XG5cbiAgcHJpdmF0ZSB1cGRhdGVCaW5kaW5nRW5hYmxlZE9uUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGNvbnN0IHNob3VsZEVuYWJsZUJpbmRpbmcgPSBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50KGV2ZW50KTtcbiAgICBpZiAodGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkICE9PSBzaG91bGRFbmFibGVCaW5kaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogc2hvdWxkRW5hYmxlQmluZGluZyB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3IgPSAocG9pbnRlckNvb3Jkczoge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gIH0pOiB2b2lkID0+IHtcbiAgICBjb25zdCBob3ZlcmVkQmluZGFibGVFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOlxuICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgPyBbaG92ZXJlZEJpbmRhYmxlRWxlbWVudF0gOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzID0gKFxuICAgIGxpbmVhckVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIC8qKiBzY2VuZSBjb29yZHMgKi9cbiAgICBwb2ludGVyQ29vcmRzOiB7XG4gICAgICB4OiBudW1iZXI7XG4gICAgICB5OiBudW1iZXI7XG4gICAgfVtdLFxuICAgIC8vIER1cmluZyBsaW5lIGNyZWF0aW9uIHRoZSBzdGFydCBiaW5kaW5nIGhhc24ndCBiZWVuIHdyaXR0ZW4geWV0XG4gICAgLy8gaW50byBgbGluZWFyRWxlbWVudGBcbiAgICBvcHBvc2l0ZUJpbmRpbmdCb3VuZEVsZW1lbnQ/OiBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50IHwgbnVsbCxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKCFwb2ludGVyQ29vcmRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN1Z2dlc3RlZEJpbmRpbmdzID0gcG9pbnRlckNvb3Jkcy5yZWR1Y2UoXG4gICAgICAoYWNjOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQ+W10sIGNvb3JkcykgPT4ge1xuICAgICAgICBjb25zdCBob3ZlcmVkQmluZGFibGVFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgICAgIGNvb3JkcyxcbiAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCAhPSBudWxsICYmXG4gICAgICAgICAgIWlzTGluZWFyRWxlbWVudFNpbXBsZUFuZEFscmVhZHlCb3VuZChcbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBvcHBvc2l0ZUJpbmRpbmdCb3VuZEVsZW1lbnQ/LmlkLFxuICAgICAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCxcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIGFjYy5wdXNoKGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgW10sXG4gICAgKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoXG4gICAgc2VsZWN0ZWRFbGVtZW50czogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD5bXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3MgfSk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgIC8vIENvbnRpbnVlIGVkaXRpbmcgdGhlIHNhbWUgZ3JvdXAgaWYgdGhlIHVzZXIgc2VsZWN0ZWQgYSBkaWZmZXJlbnRcbiAgICAgIC8vIGVsZW1lbnQgZnJvbSBpdFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6XG4gICAgICAgIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICBoaXRFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgPyBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWRcbiAgICAgICAgICA6IG51bGwsXG4gICAgfSkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUmVmID0gKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQpID0+IHtcbiAgICAvLyBjYW52YXMgaXMgbnVsbCB3aGVuIHVubW91bnRpbmdcbiAgICBpZiAoY2FudmFzICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICAgIHRoaXMucmMgPSByb3VnaC5jYW52YXModGhpcy5jYW52YXMpO1xuXG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsLCB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9FTkQsIHRoaXMub25UYXBFbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5XSEVFTCwgdGhpcy5oYW5kbGVXaGVlbCk7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9TVEFSVCwgdGhpcy5vblRhcFN0YXJ0KTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQXBwT25Ecm9wID0gYXN5bmMgKGV2ZW50OiBSZWFjdC5EcmFnRXZlbnQ8SFRNTERpdkVsZW1lbnQ+KSA9PiB7XG4gICAgLy8gbXVzdCBiZSByZXRyaWV2ZWQgZmlyc3QsIGluIHRoZSBzYW1lIGZyYW1lXG4gICAgY29uc3QgeyBmaWxlLCBmaWxlSGFuZGxlIH0gPSBhd2FpdCBnZXRGaWxlRnJvbUV2ZW50KGV2ZW50KTtcblxuICAgIHRyeSB7XG4gICAgICBpZiAoaXNTdXBwb3J0ZWRJbWFnZUZpbGUoZmlsZSkpIHtcbiAgICAgICAgLy8gZmlyc3QgYXR0ZW1wdCB0byBkZWNvZGUgc2NlbmUgZnJvbSB0aGUgaW1hZ2UgaWYgaXQncyBlbWJlZGRlZFxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgICAgICBpZiAoZmlsZT8udHlwZSA9PT0gTUlNRV9UWVBFUy5wbmcgfHwgZmlsZT8udHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2NlbmUgPSBhd2FpdCBsb2FkRnJvbUJsb2IoXG4gICAgICAgICAgICAgIGZpbGUsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICAgIGZpbGVIYW5kbGUsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgICAgICAgICAgLi4uc2NlbmUsXG4gICAgICAgICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgICAgICAgLi4uKHNjZW5lLmFwcFN0YXRlIHx8IHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHJlcGxhY2VGaWxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgIT09IFwiRW5jb2RpbmdFcnJvclwiKSB7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIG5vIHNjZW5lIGlzIGVtYmVkZGVkIG9yIHdlIGZhaWwgZm9yIHdoYXRldmVyIHJlYXNvbiwgZmFsbCBiYWNrXG4gICAgICAgIC8vIHRvIGltcG9ydGluZyBhcyByZWd1bGFyIGltYWdlXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGNvbnN0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICBldmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHsgc2NlbmVYLCBzY2VuZVkgfSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgZmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgbGlicmFyeUpTT04gPSBldmVudC5kYXRhVHJhbnNmZXIuZ2V0RGF0YShNSU1FX1RZUEVTLmV4Y2FsaWRyYXdsaWIpO1xuICAgIGlmIChsaWJyYXJ5SlNPTiAmJiB0eXBlb2YgbGlicmFyeUpTT04gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGxpYnJhcnlJdGVtcyA9IHBhcnNlTGlicmFyeUpTT04obGlicmFyeUpTT04pO1xuICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICBlbGVtZW50czogZGlzdHJpYnV0ZUxpYnJhcnlJdGVtc09uU3F1YXJlR3JpZChsaWJyYXJ5SXRlbXMpLFxuICAgICAgICAgIHBvc2l0aW9uOiBldmVudCxcbiAgICAgICAgICBmaWxlczogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGZpbGUpIHtcbiAgICAgIC8vIGF0ZXRtcHQgdG8gcGFyc2UgYW4gZXhjYWxpZHJhdy9leGNhbGlkcmF3bGliIGZpbGVcbiAgICAgIGF3YWl0IHRoaXMubG9hZEZpbGVUb0NhbnZhcyhmaWxlLCBmaWxlSGFuZGxlKTtcbiAgICB9XG4gIH07XG5cbiAgbG9hZEZpbGVUb0NhbnZhcyA9IGFzeW5jIChcbiAgICBmaWxlOiBGaWxlLFxuICAgIGZpbGVIYW5kbGU6IEZpbGVTeXN0ZW1IYW5kbGUgfCBudWxsLFxuICApID0+IHtcbiAgICBmaWxlID0gYXdhaXQgbm9ybWFsaXplRmlsZShmaWxlKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmV0ID0gYXdhaXQgbG9hZFNjZW5lT3JMaWJyYXJ5RnJvbUJsb2IoXG4gICAgICAgIGZpbGUsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGZpbGVIYW5kbGUsXG4gICAgICApO1xuICAgICAgaWYgKHJldC50eXBlID09PSBNSU1FX1RZUEVTLmV4Y2FsaWRyYXcpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgICAgICAuLi5yZXQuZGF0YSxcbiAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgLi4uKHJldC5kYXRhLmFwcFN0YXRlIHx8IHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcGxhY2VGaWxlczogdHJ1ZSxcbiAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChyZXQudHlwZSA9PT0gTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubGlicmFyeVxuICAgICAgICAgIC51cGRhdGVMaWJyYXJ5KHtcbiAgICAgICAgICAgIGxpYnJhcnlJdGVtczogZmlsZSxcbiAgICAgICAgICAgIG1lcmdlOiB0cnVlLFxuICAgICAgICAgICAgb3BlbkxpYnJhcnlNZW51OiB0cnVlLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiB0KFwiZXJyb3JzLmltcG9ydExpYnJhcnlFcnJvclwiKSB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiBmYWxzZSwgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0NvbnRleHRNZW51ID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKFxuICAgICAgKGV2ZW50Lm5hdGl2ZUV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIgfHxcbiAgICAgICAgKGV2ZW50Lm5hdGl2ZUV2ZW50LnBvaW50ZXJUeXBlID09PSBcInBlblwiICYmXG4gICAgICAgICAgLy8gYWx3YXlzIGFsbG93IGlmIHVzZXIgdXNlcyBhIHBlbiBzZWNvbmRhcnkgYnV0dG9uXG4gICAgICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5TRUNPTkRBUlkpKSAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCJcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oeCwgeSwge1xuICAgICAgcHJlZmVyU2VsZWN0ZWQ6IHRydWUsXG4gICAgICBpbmNsdWRlTG9ja2VkRWxlbWVudHM6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgaXNIaXR0aWduQ29tbW9uQm91bmRCb3ggPVxuICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgeyB4LCB5IH0sXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICApO1xuXG4gICAgY29uc3QgdHlwZSA9IGVsZW1lbnQgfHwgaXNIaXR0aWduQ29tbW9uQm91bmRCb3ggPyBcImVsZW1lbnRcIiA6IFwiY2FudmFzXCI7XG5cbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCE7XG4gICAgY29uc3QgeyB0b3A6IG9mZnNldFRvcCwgbGVmdDogb2Zmc2V0TGVmdCB9ID1cbiAgICAgIGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBsZWZ0ID0gZXZlbnQuY2xpZW50WCAtIG9mZnNldExlZnQ7XG4gICAgY29uc3QgdG9wID0gZXZlbnQuY2xpZW50WSAtIG9mZnNldFRvcDtcblxuICAgIHRyYWNrRXZlbnQoXCJjb250ZXh0TWVudVwiLCBcIm9wZW5Db250ZXh0TWVudVwiLCB0eXBlKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICB7XG4gICAgICAgIC4uLihlbGVtZW50ICYmICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1tlbGVtZW50LmlkXVxuICAgICAgICAgID8gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDogaXNMaW5lYXJFbGVtZW50KGVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKGVsZW1lbnQsIHRoaXMuc2NlbmUpXG4gICAgICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiB0aGlzLnN0YXRlKSxcbiAgICAgICAgc2hvd0h5cGVybGlua1BvcHVwOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGNvbnRleHRNZW51OiB7IHRvcCwgbGVmdCwgaXRlbXM6IHRoaXMuZ2V0Q29udGV4dE1lbnVJdGVtcyh0eXBlKSB9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50ID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIlxuICAgICkge1xuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyQ29vcmRzLngpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LCBwb2ludGVyQ29vcmRzLnkpLFxuICAgICAgICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZSA9XG4gICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSAmJlxuICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGRyYWdnaW5nRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcbiAgICAgIGNvbnN0IGFzcGVjdFJhdGlvID1cbiAgICAgICAgaW1hZ2UgJiYgIShpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpXG4gICAgICAgICAgPyBpbWFnZS53aWR0aCAvIGltYWdlLmhlaWdodFxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksXG4gICAgICAgIGdyaWRYLFxuICAgICAgICBncmlkWSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCwgZ3JpZFgpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LCBncmlkWSksXG4gICAgICAgIGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBhc3BlY3RSYXRpbyxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChbZHJhZ2dpbmdFbGVtZW50XSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVIYW5kbGVSZXNpemUgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIFRPRE86IHJlbmFtZSB0aGlzIHN0YXRlIGZpZWxkIHRvIFwiaXNTY2FsaW5nXCIgdG8gZGlzdGluZ3Vpc2hcbiAgICAgIC8vIGl0IGZyb20gdGhlIGdlbmVyaWMgXCJpc1Jlc2l6aW5nXCIgd2hpY2ggaW5jbHVkZXMgc2NhbGluZyBhbmRcbiAgICAgIC8vIHJvdGF0aW5nXG4gICAgICBpc1Jlc2l6aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlICYmIHRyYW5zZm9ybUhhbmRsZVR5cGUgIT09IFwicm90YXRpb25cIixcbiAgICAgIGlzUm90YXRpbmc6IHRyYW5zZm9ybUhhbmRsZVR5cGUgPT09IFwicm90YXRpb25cIixcbiAgICB9KTtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGNvbnN0IFtyZXNpemVYLCByZXNpemVZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC54LFxuICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0LnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgaWYgKFxuICAgICAgdHJhbnNmb3JtRWxlbWVudHMoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uLFxuICAgICAgICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0ltYWdlRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgcmVzaXplWCxcbiAgICAgICAgcmVzaXplWSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuY2VudGVyLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci55LFxuICAgICAgKVxuICAgICkge1xuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIGdldENvbnRleHRNZW51SXRlbXMgPSAoXG4gICAgdHlwZTogXCJjYW52YXNcIiB8IFwiZWxlbWVudFwiLFxuICApOiBDb250ZXh0TWVudUl0ZW1zID0+IHtcbiAgICBjb25zdCBvcHRpb25zOiBDb250ZXh0TWVudUl0ZW1zID0gW107XG5cbiAgICBvcHRpb25zLnB1c2goYWN0aW9uQ29weUFzUG5nLCBhY3Rpb25Db3B5QXNTdmcpO1xuXG4gICAgLy8gY2FudmFzIGNvbnRleHRNZW51XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgaWYgKHR5cGUgPT09IFwiY2FudmFzXCIpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gICAgICAgICAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgICAgXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFtcbiAgICAgICAgYWN0aW9uUGFzdGUsXG4gICAgICAgIENPTlRFWFRfTUVOVV9TRVBBUkFUT1IsXG4gICAgICAgIGFjdGlvbkNvcHlBc1BuZyxcbiAgICAgICAgYWN0aW9uQ29weUFzU3ZnLFxuICAgICAgICBjb3B5VGV4dCxcbiAgICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgICAgYWN0aW9uU2VsZWN0QWxsLFxuICAgICAgICBhY3Rpb25VbmxvY2tBbGxFbGVtZW50cyxcbiAgICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgICAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gICAgICAgIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgIGFjdGlvblRvZ2dsZVZpZXdNb2RlLFxuICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgIF07XG4gICAgfVxuXG4gICAgLy8gZWxlbWVudCBjb250ZXh0TWVudVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIG9wdGlvbnMucHVzaChjb3B5VGV4dCk7XG5cbiAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybiBbYWN0aW9uQ29weSwgLi4ub3B0aW9uc107XG4gICAgfVxuXG4gICAgcmV0dXJuIFtcbiAgICAgIGFjdGlvbkN1dCxcbiAgICAgIGFjdGlvbkNvcHksXG4gICAgICBhY3Rpb25QYXN0ZSxcbiAgICAgIENPTlRFWFRfTUVOVV9TRVBBUkFUT1IsXG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvbkNvcHlTdHlsZXMsXG4gICAgICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgICAgIENPTlRFWFRfTUVOVV9TRVBBUkFUT1IsXG4gICAgICBhY3Rpb25Hcm91cCxcbiAgICAgIGFjdGlvblVuYmluZFRleHQsXG4gICAgICBhY3Rpb25CaW5kVGV4dCxcbiAgICAgIGFjdGlvbldyYXBUZXh0SW5Db250YWluZXIsXG4gICAgICBhY3Rpb25Vbmdyb3VwLFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgICAgIENPTlRFWFRfTUVOVV9TRVBBUkFUT1IsXG4gICAgICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gICAgICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gICAgICBhY3Rpb25TZW5kVG9CYWNrLFxuICAgICAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICAgICAgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICAgICAgQ09OVEVYVF9NRU5VX1NFUEFSQVRPUixcbiAgICAgIGFjdGlvblRvZ2dsZUxpbmVhckVkaXRvcixcbiAgICAgIGFjdGlvbkxpbmssXG4gICAgICBhY3Rpb25EdXBsaWNhdGVTZWxlY3Rpb24sXG4gICAgICBhY3Rpb25Ub2dnbGVFbGVtZW50TG9jayxcbiAgICAgIENPTlRFWFRfTUVOVV9TRVBBUkFUT1IsXG4gICAgICBhY3Rpb25EZWxldGVTZWxlY3RlZCxcbiAgICBdO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlV2hlZWwgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBXaGVlbEV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoaXNQYW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBkZWx0YVgsIGRlbHRhWSB9ID0gZXZlbnQ7XG4gICAgLy8gbm90ZSB0aGF0IGV2ZW50LmN0cmxLZXkgaXMgbmVjZXNzYXJ5IHRvIGhhbmRsZSBwaW5jaCB6b29taW5nXG4gICAgaWYgKGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleSkge1xuICAgICAgY29uc3Qgc2lnbiA9IE1hdGguc2lnbihkZWx0YVkpO1xuICAgICAgY29uc3QgTUFYX1NURVAgPSBaT09NX1NURVAgKiAxMDA7XG4gICAgICBjb25zdCBhYnNEZWx0YSA9IE1hdGguYWJzKGRlbHRhWSk7XG4gICAgICBsZXQgZGVsdGEgPSBkZWx0YVk7XG4gICAgICBpZiAoYWJzRGVsdGEgPiBNQVhfU1RFUCkge1xuICAgICAgICBkZWx0YSA9IE1BWF9TVEVQICogc2lnbjtcbiAgICAgIH1cblxuICAgICAgbGV0IG5ld1pvb20gPSB0aGlzLnN0YXRlLnpvb20udmFsdWUgLSBkZWx0YSAvIDEwMDtcbiAgICAgIC8vIGluY3JlYXNlIHpvb20gc3RlcHMgdGhlIG1vcmUgem9vbWVkLWluIHdlIGFyZSAoYXBwbGllcyB0byA+MTAwJSBvbmx5KVxuICAgICAgbmV3Wm9vbSArPVxuICAgICAgICBNYXRoLmxvZzEwKE1hdGgubWF4KDEsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpICpcbiAgICAgICAgLXNpZ24gKlxuICAgICAgICAvLyByZWR1Y2VkIGFtcGxpZmljYXRpb24gZm9yIHNtYWxsIGRlbHRhcyAoc21hbGwgbW92ZW1lbnRzIG9uIGEgdHJhY2twYWQpXG4gICAgICAgIE1hdGgubWluKDEsIGFic0RlbHRhIC8gMjApO1xuXG4gICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcygoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldFN0YXRlRm9yWm9vbShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2aWV3cG9ydFg6IGN1cnNvclgsXG4gICAgICAgICAgICB2aWV3cG9ydFk6IGN1cnNvclksXG4gICAgICAgICAgICBuZXh0Wm9vbTogZ2V0Tm9ybWFsaXplZFpvb20obmV3Wm9vbSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKSxcbiAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHNjcm9sbCBob3Jpem9udGFsbHkgd2hlbiBzaGlmdCBwcmVzc2VkXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcygoeyB6b29tLCBzY3JvbGxYIH0pID0+ICh7XG4gICAgICAgIC8vIG9uIE1hYywgc2hpZnQrd2hlZWwgdGVuZHMgdG8gcmVzdWx0IGluIGRlbHRhWFxuICAgICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gKGRlbHRhWSB8fCBkZWx0YVgpIC8gem9vbS52YWx1ZSxcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnRyYW5zbGF0ZUNhbnZhcygoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZIH0pID0+ICh7XG4gICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gZGVsdGFYIC8gem9vbS52YWx1ZSxcbiAgICAgIHNjcm9sbFk6IHNjcm9sbFkgLSBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBnZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICAgIGNvbnRhaW5lcj86IEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyIHwgbnVsbCxcbiAgKSB7XG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgbGV0IGVsZW1lbnRDZW50ZXJYID0gY29udGFpbmVyLnggKyBjb250YWluZXIud2lkdGggLyAyO1xuICAgICAgbGV0IGVsZW1lbnRDZW50ZXJZID0gY29udGFpbmVyLnkgKyBjb250YWluZXIuaGVpZ2h0IC8gMjtcblxuICAgICAgY29uc3QgZWxlbWVudENlbnRlciA9IGdldENvbnRhaW5lckNlbnRlcihjb250YWluZXIsIGFwcFN0YXRlKTtcbiAgICAgIGlmIChlbGVtZW50Q2VudGVyKSB7XG4gICAgICAgIGVsZW1lbnRDZW50ZXJYID0gZWxlbWVudENlbnRlci54O1xuICAgICAgICBlbGVtZW50Q2VudGVyWSA9IGVsZW1lbnRDZW50ZXIueTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRpc3RhbmNlVG9DZW50ZXIgPSBNYXRoLmh5cG90KFxuICAgICAgICB4IC0gZWxlbWVudENlbnRlclgsXG4gICAgICAgIHkgLSBlbGVtZW50Q2VudGVyWSxcbiAgICAgICk7XG4gICAgICBjb25zdCBpc1NuYXBwZWRUb0NlbnRlciA9XG4gICAgICAgIGRpc3RhbmNlVG9DZW50ZXIgPCBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRDtcbiAgICAgIGlmIChpc1NuYXBwZWRUb0NlbnRlcikge1xuICAgICAgICBjb25zdCB7IHg6IHZpZXdwb3J0WCwgeTogdmlld3BvcnRZIH0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgICAgeyBzY2VuZVg6IGVsZW1lbnRDZW50ZXJYLCBzY2VuZVk6IGVsZW1lbnRDZW50ZXJZIH0sXG4gICAgICAgICAgYXBwU3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IHZpZXdwb3J0WCwgdmlld3BvcnRZLCBlbGVtZW50Q2VudGVyWCwgZWxlbWVudENlbnRlclkgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNhdmVQb2ludGVyID0gKHg6IG51bWJlciwgeTogbnVtYmVyLCBidXR0b246IFwidXBcIiB8IFwiZG93blwiKSA9PiB7XG4gICAgaWYgKCF4IHx8ICF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IHgsIGNsaWVudFk6IHkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChpc05hTihwb2ludGVyLngpIHx8IGlzTmFOKHBvaW50ZXIueSkpIHtcbiAgICAgIC8vIHNvbWV0aW1lcyB0aGUgcG9pbnRlciBnb2VzIG9mZiBzY3JlZW5cbiAgICB9XG5cbiAgICB0aGlzLnByb3BzLm9uUG9pbnRlclVwZGF0ZT8uKHtcbiAgICAgIHBvaW50ZXIsXG4gICAgICBidXR0b24sXG4gICAgICBwb2ludGVyc01hcDogZ2VzdHVyZS5wb2ludGVycyxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGlmICghdGhpcy51bm1vdW50ZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlIH0pO1xuICAgIH1cbiAgfSwgMzAwKTtcblxuICBwcml2YXRlIHVwZGF0ZURPTVJlY3QgPSAoY2I/OiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aCxcbiAgICAgICAgaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBvZmZzZXRMZWZ0LFxuICAgICAgICB0b3A6IG9mZnNldFRvcCxcbiAgICAgIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aDogY3VycmVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGN1cnJlbnRIZWlnaHQsXG4gICAgICAgIG9mZnNldFRvcDogY3VycmVudE9mZnNldFRvcCxcbiAgICAgICAgb2Zmc2V0TGVmdDogY3VycmVudE9mZnNldExlZnQsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgaWYgKFxuICAgICAgICB3aWR0aCA9PT0gY3VycmVudFdpZHRoICYmXG4gICAgICAgIGhlaWdodCA9PT0gY3VycmVudEhlaWdodCAmJlxuICAgICAgICBvZmZzZXRMZWZ0ID09PSBjdXJyZW50T2Zmc2V0TGVmdCAmJlxuICAgICAgICBvZmZzZXRUb3AgPT09IGN1cnJlbnRPZmZzZXRUb3BcbiAgICAgICkge1xuICAgICAgICBpZiAoY2IpIHtcbiAgICAgICAgICBjYigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICBvZmZzZXRMZWZ0LFxuICAgICAgICAgIG9mZnNldFRvcCxcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGNiICYmIGNiKCk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgcmVmcmVzaCA9ICgpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCkgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRDYW52YXNPZmZzZXRzKCk6IFBpY2s8QXBwU3RhdGUsIFwib2Zmc2V0VG9wXCIgfCBcIm9mZnNldExlZnRcIj4ge1xuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IGV4Y2FsaWRyYXdDb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb2Zmc2V0TGVmdDogbGVmdCxcbiAgICAgICAgb2Zmc2V0VG9wOiB0b3AsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb2Zmc2V0TGVmdDogMCxcbiAgICAgIG9mZnNldFRvcDogMCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVMYW5ndWFnZSgpIHtcbiAgICBjb25zdCBjdXJyZW50TGFuZyA9XG4gICAgICBsYW5ndWFnZXMuZmluZCgobGFuZykgPT4gbGFuZy5jb2RlID09PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB8fFxuICAgICAgZGVmYXVsdExhbmc7XG4gICAgYXdhaXQgc2V0TGFuZ3VhZ2UoY3VycmVudExhbmcpO1xuICAgIHRoaXMuc2V0QXBwU3RhdGUoe30pO1xuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBURVNUIEhPT0tTXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBXaW5kb3cge1xuICAgIGg6IHtcbiAgICAgIGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdO1xuICAgICAgc3RhdGU6IEFwcFN0YXRlO1xuICAgICAgc2V0U3RhdGU6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdO1xuICAgICAgYXBwOiBJbnN0YW5jZVR5cGU8dHlwZW9mIEFwcD47XG4gICAgICBoaXN0b3J5OiBIaXN0b3J5O1xuICAgIH07XG4gIH1cbn1cblxuaWYgKFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLlRFU1QgfHxcbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVFxuKSB7XG4gIHdpbmRvdy5oID0gd2luZG93LmggfHwgKHt9IGFzIFdpbmRvd1tcImhcIl0pO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgZWxlbWVudHM6IHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwPy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgIH0sXG4gICAgICBzZXQoZWxlbWVudHM6IEV4Y2FsaWRyYXdFbGVtZW50W10pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwPy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
2717
2717
 
2718
2718
  /***/ }),
2719
2719
 
@@ -4264,7 +4264,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4264
4264
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4265
4265
 
4266
4266
  "use strict";
4267
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants */ \"../../constants.ts\");\n\nif (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_0__.ENV.TEST) {\n /* eslint-disable */\n /* global __webpack_public_path__:writable */\n __webpack_require__.p =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@dwelle/excalidraw\"}@${\"0.4.0-b39f4a9\"}/dist/`;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9wdWJsaWNQYXRoLmpzLmpzIiwibWFwcGluZ3MiOiI7O0FBQXNDO0FBQ3RDLElBQUksYUFBb0IsS0FBSyxnREFBUSxFQUFFO0lBQ3JDLG9CQUFvQjtJQUNwQiw2Q0FBNkM7SUFDN0MscUJBQXVCO1FBQ3JCLE1BQU0sQ0FBQyxxQkFBcUI7WUFDNUIscUJBQXFCLG9CQUFvQixJQUFJLGVBQXVCLFFBQVEsQ0FBQztDQUNoRiIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3B1YmxpY1BhdGguanM/YTg3ZCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFTlYgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzXCI7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5URVNUKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlICovXG4gIC8qIGdsb2JhbCBfX3dlYnBhY2tfcHVibGljX3BhdGhfXzp3cml0YWJsZSAqL1xuICBfX3dlYnBhY2tfcHVibGljX3BhdGhfXyA9XG4gICAgd2luZG93LkVYQ0FMSURSQVdfQVNTRVRfUEFUSCB8fFxuICAgIGBodHRwczovL3VucGtnLmNvbS8ke3Byb2Nlc3MuZW52LlBLR19OQU1FfUAke3Byb2Nlc3MuZW52LlBLR19WRVJTSU9OfS9kaXN0L2A7XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./publicPath.js\n");
4267
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants */ \"../../constants.ts\");\n\nif (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_0__.ENV.TEST) {\n /* eslint-disable */\n /* global __webpack_public_path__:writable */\n __webpack_require__.p =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@dwelle/excalidraw\"}@${\"0.4.0-b411b92\"}/dist/`;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9wdWJsaWNQYXRoLmpzLmpzIiwibWFwcGluZ3MiOiI7O0FBQXNDO0FBQ3RDLElBQUksYUFBb0IsS0FBSyxnREFBUSxFQUFFO0lBQ3JDLG9CQUFvQjtJQUNwQiw2Q0FBNkM7SUFDN0MscUJBQXVCO1FBQ3JCLE1BQU0sQ0FBQyxxQkFBcUI7WUFDNUIscUJBQXFCLG9CQUFvQixJQUFJLGVBQXVCLFFBQVEsQ0FBQztDQUNoRiIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3B1YmxpY1BhdGguanM/YTg3ZCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFTlYgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzXCI7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5URVNUKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlICovXG4gIC8qIGdsb2JhbCBfX3dlYnBhY2tfcHVibGljX3BhdGhfXzp3cml0YWJsZSAqL1xuICBfX3dlYnBhY2tfcHVibGljX3BhdGhfXyA9XG4gICAgd2luZG93LkVYQ0FMSURSQVdfQVNTRVRfUEFUSCB8fFxuICAgIGBodHRwczovL3VucGtnLmNvbS8ke3Byb2Nlc3MuZW52LlBLR19OQU1FfUAke3Byb2Nlc3MuZW52LlBLR19WRVJTSU9OfS9kaXN0L2A7XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./publicPath.js\n");
4268
4268
 
4269
4269
  /***/ }),
4270
4270
 
@@ -4385,7 +4385,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4385
4385
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4386
4386
 
4387
4387
  "use strict";
4388
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SVG_EXPORT_TAG\": () => (/* binding */ SVG_EXPORT_TAG),\n/* harmony export */ \"exportToCanvas\": () => (/* binding */ exportToCanvas),\n/* harmony export */ \"exportToSvg\": () => (/* binding */ exportToSvg),\n/* harmony export */ \"getExportSize\": () => (/* binding */ getExportSize)\n/* harmony export */ });\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var _element_bounds__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element/bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../data/json */ \"../../data/json.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\nconst SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;\n/**\n * This API is usually used as a precursor to searializing to Blob or PNG,\n * but can also be used to create a canvas for other purposes.\n */\nconst exportToCanvas = ({ data, config, }) => __awaiter(void 0, void 0, void 0, function* () {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n // initialize defaults\n // ---------------------------------------------------------------------------\n const { elements, files } = data;\n const appState = (0,_data_restore__WEBPACK_IMPORTED_MODULE_7__.restoreAppState)(data.appState, null);\n // clone\n const cfg = Object.assign({}, config);\n if (cfg.x != null || cfg.x != null) {\n if (cfg.fit != null && cfg.fit !== \"none\") {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`fit` will be ignored (automatically set to `none`) when you specify `x` or `y` offsets\");\n }\n }\n cfg.fit = \"none\";\n }\n cfg.fit = (_a = cfg.fit) !== null && _a !== void 0 ? _a : \"contain\";\n if (cfg.fit === \"cover\" && cfg.padding) {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`padding` is ignored when `fit` is set to `cover`\");\n }\n cfg.padding = 0;\n }\n cfg.scale = (_b = cfg.scale) !== null && _b !== void 0 ? _b : 1;\n cfg.origin = (_c = cfg.origin) !== null && _c !== void 0 ? _c : \"canvas\";\n cfg.position = (_d = cfg.position) !== null && _d !== void 0 ? _d : \"center\";\n cfg.padding = (_e = cfg.padding) !== null && _e !== void 0 ? _e : _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING;\n if (cfg.maxWidthOrHeight != null && cfg.widthOrHeight != null) {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`maxWidthOrHeight` is ignored when `widthOrHeight` is set\");\n }\n cfg.maxWidthOrHeight = undefined;\n }\n if ((cfg.maxWidthOrHeight != null || cfg.width != null || cfg.height != null) &&\n cfg.getDimensions) {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`getDimensions` is ignored when `width`, `height`, or `maxWidthOrHeight` is set\");\n }\n cfg.getDimensions = undefined;\n }\n // ---------------------------------------------------------------------------\n // value used to scale the canvas context. By default, we use this to\n // make the canvas fit into the frame (e.g. for `cfg.fit` set to `contain`).\n // If `cfg.scale` is set, we multiply the resulting canvasScale by it to\n // scale the output further.\n let canvasScale = 1;\n const origCanvasSize = getCanvasSize(elements, cfg.padding);\n // variables for original content bounding box\n const [origX, origY, origWidth, origHeight] = origCanvasSize;\n // variables for target bounding box\n let [x, y, width, height] = origCanvasSize;\n if (cfg.maxWidthOrHeight != null || cfg.widthOrHeight != null) {\n const max = Math.max(origWidth, origHeight);\n if (cfg.widthOrHeight != null) {\n // calculate by how much do we need to scale the canvas to fit into the\n // target dimension (e.g. target: max 50px, actual: 70x100px => scale: 0.5)\n canvasScale = cfg.widthOrHeight / max;\n }\n else if (cfg.maxWidthOrHeight != null) {\n canvasScale = cfg.maxWidthOrHeight < max ? cfg.maxWidthOrHeight / max : 1;\n }\n width *= canvasScale;\n height *= canvasScale;\n }\n else if (cfg.width != null) {\n width = cfg.width;\n if (cfg.height) {\n height = cfg.height;\n }\n else {\n // if height not specified, scale the original height to match the new\n // width while maintaining aspect ratio\n height *= width / origWidth;\n }\n }\n else if (cfg.height != null) {\n height = cfg.height;\n // width not specified, so scale the original width to match the new\n // height while maintaining aspect ratio\n width *= height / origHeight;\n }\n else if (cfg.getDimensions) {\n const ret = cfg.getDimensions(width, height);\n width = ret.width;\n height = ret.height;\n cfg.scale = (_f = ret.scale) !== null && _f !== void 0 ? _f : cfg.scale;\n }\n if (cfg.fit === \"contain\" && !cfg.maxWidthOrHeight) {\n const wRatio = width / origWidth;\n const hRatio = height / origHeight;\n // scale the orig canvas to fit in the target frame\n canvasScale = Math.min(wRatio, hRatio);\n }\n else if (cfg.fit === \"cover\") {\n const wRatio = width / origWidth;\n const hRatio = height / origHeight;\n // scale the orig canvas to fill the the target frame\n // (opposite of \"contain\")\n canvasScale = Math.max(wRatio, hRatio);\n }\n x = (_g = cfg.x) !== null && _g !== void 0 ? _g : origX;\n y = (_h = cfg.y) !== null && _h !== void 0 ? _h : origY;\n // if we switch to \"content\" coords, we need to offset cfg-supplied\n // coords by the x/y of content bounding box\n if (cfg.origin === \"content\") {\n if (cfg.x != null) {\n x += origX;\n }\n if (cfg.y != null) {\n y += origY;\n }\n }\n // Centering the content to the frame.\n // We divide width/height by canvasScale so that we calculate in the original\n // aspect ratio dimensions.\n if (cfg.position === \"center\") {\n if (cfg.x == null) {\n x -= width / canvasScale / 2 - origWidth / 2;\n }\n if (cfg.y == null) {\n y -= height / canvasScale / 2 - origHeight / 2;\n }\n }\n const canvas = cfg.createCanvas\n ? cfg.createCanvas()\n : document.createElement(\"canvas\");\n // scale the whole frame by cfg.scale (on top of whatever canvasScale we\n // calculated above)\n canvasScale *= cfg.scale;\n width *= cfg.scale;\n height *= cfg.scale;\n canvas.width = width;\n canvas.height = height;\n const { imageCache } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_6__.updateImageCache)({\n imageCache: new Map(),\n fileIds: (0,_element_image__WEBPACK_IMPORTED_MODULE_6__.getInitializedImageElements)(elements).map((element) => element.fileId),\n files: files || {},\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderScene)({\n elements,\n appState: Object.assign(Object.assign({}, appState), { width, height, offsetLeft: 0, offsetTop: 0 }),\n rc: roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas),\n canvas,\n renderConfig: {\n canvasBackgroundColor: cfg.canvasBackgroundColor === false\n ? // null indicates transparent background\n null\n : cfg.canvasBackgroundColor ||\n appState.viewBackgroundColor ||\n _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_BACKGROUND_COLOR,\n scrollX: -x + cfg.padding,\n scrollY: -y + cfg.padding,\n canvasScale,\n zoom: { value: _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_ZOOM_VALUE },\n remotePointerViewportCoords: {},\n remoteSelectedElementIds: {},\n shouldCacheIgnoreZoom: false,\n remotePointerUsernames: {},\n remotePointerUserStates: {},\n theme: cfg.theme || _constants__WEBPACK_IMPORTED_MODULE_4__.THEME.LIGHT,\n imageCache,\n renderScrollbars: false,\n renderSelection: false,\n renderGrid: false,\n isExporting: true,\n },\n });\n return canvas;\n});\nconst exportToSvg = (elements, appState, files, opts) => __awaiter(void 0, void 0, void 0, function* () {\n var _j;\n const { exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, exportScale = 1, exportEmbedScene, } = appState;\n let metadata = \"\";\n if (exportEmbedScene) {\n try {\n metadata = yield (yield Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../../src/data/image */ \"../../data/image.ts\"))).encodeSvgMetadata({\n text: (opts === null || opts === void 0 ? void 0 : opts.serializeAsJSON)\n ? (_j = opts === null || opts === void 0 ? void 0 : opts.serializeAsJSON) === null || _j === void 0 ? void 0 : _j.call(opts)\n : (0,_data_json__WEBPACK_IMPORTED_MODULE_5__.serializeAsJSON)(elements, appState, files || {}, \"local\"),\n });\n }\n catch (error) {\n console.error(error);\n }\n }\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n // initialize SVG root\n const svgRoot = document.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"svg\");\n svgRoot.setAttribute(\"version\", \"1.1\");\n svgRoot.setAttribute(\"xmlns\", _constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS);\n svgRoot.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svgRoot.setAttribute(\"width\", `${width * exportScale}`);\n svgRoot.setAttribute(\"height\", `${height * exportScale}`);\n if (appState.exportWithDarkMode) {\n svgRoot.setAttribute(\"filter\", _constants__WEBPACK_IMPORTED_MODULE_4__.THEME_FILTER);\n }\n let assetPath = \"https://excalidraw.com/\";\n // Asset path needs to be determined only when using package\n if (true) {\n assetPath =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@dwelle/excalidraw\"}@${\"0.4.0-b39f4a9\"}`;\n if (assetPath === null || assetPath === void 0 ? void 0 : assetPath.startsWith(\"/\")) {\n assetPath = assetPath.replace(\"/\", `${window.location.origin}/`);\n }\n assetPath = `${assetPath}/dist/excalidraw-assets/`;\n }\n svgRoot.innerHTML = `\n ${SVG_EXPORT_TAG}\n ${metadata}\n <defs>\n <style class=\"style-fonts\">\n @font-face {\n font-family: \"Virgil\";\n src: url(\"https://excalidraw.com/Virgil.woff2\");\n }\n @font-face {\n font-family: \"Cascadia\";\n src: url(\"https://excalidraw.com/Cascadia.woff2\");\n }\n </style>\n </defs>\n `;\n // render background rect\n if (appState.exportBackground && viewBackgroundColor) {\n const rect = svgRoot.ownerDocument.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", `${width}`);\n rect.setAttribute(\"height\", `${height}`);\n rect.setAttribute(\"fill\", viewBackgroundColor);\n svgRoot.appendChild(rect);\n }\n const rsvg = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].svg(svgRoot);\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderSceneToSvg)(elements, rsvg, svgRoot, files || {}, {\n offsetX: -minX + exportPadding,\n offsetY: -minY + exportPadding,\n exportWithDarkMode: appState.exportWithDarkMode,\n });\n return svgRoot;\n});\n// calculate smallest area to fit the contents in\nconst getCanvasSize = (elements, exportPadding) => {\n const [minX, minY, maxX, maxY] = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(elements);\n const width = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minX, maxX) + exportPadding * 2;\n const height = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minY, maxY) + exportPadding + exportPadding;\n return [minX, minY, width, height];\n};\nconst getExportSize = (elements, padding, scale) => {\n const [, , width, height] = getCanvasSize(elements, padding).map((dimension) => Math.trunc(dimension * scale));\n return [width, height];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3JDLENBQUMsQ0FBQztBQUVLLE1BQU0sYUFBYSxHQUFHLENBQzNCLFFBQWdELEVBQ2hELE9BQWUsRUFDZixLQUFhLEVBQ0ssRUFBRTtJQUNwQixNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FDOUQsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUM3QyxDQUFDO0lBRUYsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN6QixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vc2NlbmUvZXhwb3J0LnRzPzliZjciXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJvdWdoIGZyb20gXCJyb3VnaGpzL2Jpbi9yb3VnaFwiO1xuaW1wb3J0IHsgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50LCBUaGVtZSB9IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDb21tb25Cb3VuZHMgfSBmcm9tIFwiLi4vZWxlbWVudC9ib3VuZHNcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lLCByZW5kZXJTY2VuZVRvU3ZnIH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlclNjZW5lXCI7XG5pbXBvcnQgeyBkaXN0YW5jZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXBwU3RhdGUsIEJpbmFyeUZpbGVzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IsXG4gIERFRkFVTFRfRVhQT1JUX1BBRERJTkcsXG4gIERFRkFVTFRfWk9PTV9WQUxVRSxcbiAgRU5WLFxuICBTVkdfTlMsXG4gIFRIRU1FLFxuICBUSEVNRV9GSUxURVIsXG59IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNlcmlhbGl6ZUFzSlNPTiB9IGZyb20gXCIuLi9kYXRhL2pzb25cIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcbmltcG9ydCB7IHJlc3RvcmVBcHBTdGF0ZSB9IGZyb20gXCIuLi9kYXRhL3Jlc3RvcmVcIjtcblxuZXhwb3J0IGNvbnN0IFNWR19FWFBPUlRfVEFHID0gYDwhLS0gc3ZnLXNvdXJjZTpleGNhbGlkcmF3IC0tPmA7XG5cbmV4cG9ydCB0eXBlIEV4cG9ydFRvQ2FudmFzRGF0YSA9IHtcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdO1xuICBhcHBTdGF0ZT86IFBhcnRpYWw8T21pdDxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPj47XG4gIGZpbGVzOiBCaW5hcnlGaWxlcyB8IG51bGw7XG59O1xuXG5leHBvcnQgdHlwZSBFeHBvcnRUb0NhbnZhc0NvbmZpZyA9IHtcbiAgdGhlbWU/OiBUaGVtZTtcbiAgLyoqXG4gICAqIENhbnZhcyBiYWNrZ3JvdW5kLiBWYWxpZCB2YWx1ZXMgYXJlOlxuICAgKlxuICAgKiAtIGB1bmRlZmluZWRgIC0gdGhlIGJhY2tncm91bmQgb2YgXCJhcHBTdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yXCIgaXMgdXNlZC5cbiAgICogLSBgZmFsc2VgIC0gbm8gYmFja2dyb3VuZCBpcyB1c2VkIChzZXQgdG8gXCJ0cmFuc3BhcmVudFwiKS5cbiAgICogLSBgc3RyaW5nYCAtIHNob3VsZCBiZSBhIHZhbGlkIENTUyBjb2xvci5cbiAgICpcbiAgICogQGRlZmF1bHQgdW5kZWZpbmVkXG4gICAqL1xuICBjYW52YXNCYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmcgfCBmYWxzZTtcbiAgLyoqXG4gICAqIENhbnZhcyBwYWRkaW5nIGluIHBpeGVscy4gQWZmZWN0ZWQgYnkgc2NhbGUuIElnbm9yZWQgaWYgYGZpdGAgaXMgc2V0IHRvXG4gICAqIGBjb3ZlcmAuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEwXG4gICAqL1xuICBwYWRkaW5nPzogbnVtYmVyO1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBNYWtlcyBzdXJlIHRoZSBjYW52YXMgY29udGVudCBmaXRzIGludG8gYSBmcmFtZSBvZiB3aWR0aC9oZWlnaHQgbm8gbGFyZ2VyXG4gICAqIHRoYW4gdGhpcyB2YWx1ZSwgd2hpbGUgbWFpbnRhaW5pbmcgdGhlIGFzcGVjdCByYXRpby5cbiAgICpcbiAgICogRmluYWwgZGltZW5zaW9ucyBjYW4gZ2V0IHNtYWxsZXIvbGFyZ2VyIGlmIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aFxuICAgKiBgc2NhbGVgLlxuICAgKi9cbiAgbWF4V2lkdGhPckhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFNjYWxlIHRoZSBjYW52YXMgY29udGVudCB0byBiZSBleGNhdGx5IHRoaXMgbWFueSBwaXhlbHMgd2lkZS90YWxsLlxuICAgKlxuICAgKiBDYW5ub3QgYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBtYXhXaWR0aE9ySGVpZ2h0YC5cbiAgICpcbiAgICogRmluYWwgZGltZW5zaW9ucyBjYW4gZ2V0IHNtYWxsZXIvbGFyZ2VyIGlmIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aFxuICAgKiBgc2NhbGVgLlxuICAgKi9cbiAgd2lkdGhPckhlaWdodD86IG51bWJlcjtcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogV2lkdGggb2YgdGhlIGZyYW1lLiBTdXBwbHkgYHhgIG9yIGB5YCBpZiB5b3Ugd2FudCB0byBvZnNzZXQgdGhlIGNhbnZhc1xuICAgKiBjb250ZW50LlxuICAgKlxuICAgKiBJZiBgd2lkdGhgIG9taXR0ZWQgYnV0IGBoZWlnaHRgIHN1cHBsaWVkLCBgd2lkdGhgIGlzIGNhbGN1bGF0ZWQgZnJvbSB0aGVcbiAgICogdGhlIGNvbnRlbnQncyBib3VuZGluZyBib3ggdG8gcHJlc2VydmUgdGhlIGFzcGVjdCByYXRpby5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gdGhlIGNvbnRlbnQgYm91bmRpbmcgYm94IHdpZHRoIHdoZW4gYm90aCBgd2lkdGhgIGFuZCBgaGVpZ2h0YFxuICAgKiBhcmUgb21pdHRlZC5cbiAgICovXG4gIHdpZHRoPzogbnVtYmVyO1xuICAvKipcbiAgICogSGVpZ2h0IG9mIHRoZSBmcmFtZS5cbiAgICpcbiAgICogSWYgYGhlaWdodGAgb21pdHRlZCBidXQgYHdpZHRoYCBzdXBwbGllZCwgYGhlaWdodGAgaXMgY2FsY3VsYXRlZCBmcm9tIHRoZVxuICAgKiBjb250ZW50J3MgYm91bmRpbmcgYm94IHRvIHByZXNlcnZlIHRoZSBhc3BlY3QgcmF0aW8uXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHRoZSBjb250ZW50IGJvdW5kaW5nIGJveCBoZWlnaHQgd2hlbiBib3RoIGB3aWR0aGAgYW5kIGBoZWlnaHRgXG4gICAqIGFyZSBvbWl0dGVkLlxuICAgKi9cbiAgaGVpZ2h0PzogbnVtYmVyO1xuICAvKipcbiAgICogTGVmdCBjYW52YXMgb2Zmc2V0LiBCeSBkZWZhdWx0IHRoZSBjb29yZGluYXRlIGlzIHJlbGF0aXZlIHRvIHRoZSBjYW52YXMuXG4gICAqIFlvdSBjYW4gc3dpdGNoIHRvIGNvbnRlbnQgY29vcmRpbmF0ZXMgYnkgc2V0dGluZyBgb3JpZ2luYCB0byBgY29udGVudGAuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHRoZSBgeGAgcG9zdGlvbiBvZiB0aGUgY29udGVudCBib3VuZGluZyBib3guXG4gICAqL1xuICB4PzogbnVtYmVyO1xuICAvKipcbiAgICogVG9wIGNhbnZhcyBvZmZzZXQuIEJ5IGRlZmF1bHQgdGhlIGNvb3JkaW5hdGUgaXMgcmVsYXRpdmUgdG8gdGhlIGNhbnZhcy5cbiAgICogWW91IGNhbiBzd2l0Y2ggdG8gY29udGVudCBjb29yZGluYXRlcyBieSBzZXR0aW5nIGBvcmlnaW5gIHRvIGBjb250ZW50YC5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gdGhlIGB5YCBwb3N0aW9uIG9mIHRoZSBjb250ZW50IGJvdW5kaW5nIGJveC5cbiAgICovXG4gIHk/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhlIGNvb3JkaW5hdGUgc3lzdGVtIG9mIHRoZSBgeGAgYW5kIGB5YCB2YWx1ZXMuXG4gICAqXG4gICAqIC0gYGNhbnZhc2AgLSBgeGAgYW5kIGB5YCBhcmUgcmVsYXRpdmUgdG8gdGhlIGNhbnZhcyBbMCwgMF0gcG9zaXRpb24uXG4gICAqIC0gYGNvbnRlbnRgIC0gYHhgIGFuZCBgeWAgYXJlIHJlbGF0aXZlIHRvIHRoZSBjb250ZW50IGJvdW5kaW5nIGJveC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJjYW52YXNcIlxuICAgKi9cbiAgb3JpZ2luPzogXCJjYW52YXNcIiB8IFwiY29udGVudFwiO1xuICAvKipcbiAgICogSWYgZGltZW5zaW9ucyBzcGVjaWZpZWQgYW5kIGB4YCBhbmQgYHlgIGFyZSBub3Qgc3BlY2lmaWVkLCB0aGlzIGluZGljYXRlc1xuICAgKiBob3cgdGhlIGNhbnZhcyBzaG91bGQgYmUgc2NhbGVkLlxuICAgKlxuICAgKiBCZWhhdmlvciBhbGlnbnMgd2l0aCB0aGUgYG9iamVjdC1maXRgIENTUyBwcm9wZXJ0eS5cbiAgICpcbiAgICogLSBgbm9uZWAgICAgLSBubyBzY2FsaW5nLlxuICAgKiAtIGBjb250YWluYCAtIHNjYWxlIHRvIGZpdCB0aGUgZnJhbWUuXG4gICAqIC0gYGNvdmVyYCAgIC0gc2NhbGUgdG8gZmlsbCB0aGUgZnJhbWUgd2hpbGUgbWFpbnRhaW5pbmcgYXNwZWN0IHJhdGlvLiBJZlxuICAgKiAgICAgICAgICAgICAgIGNvbnRlbnQgb3ZlcmZsb3dzLCBpdCB3aWxsIGJlIGNyb3BwZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiY29udGFpblwiIHVubGVzcyBgeGAgb3IgYHlgIGFyZSBzcGVjaWZpZWQsIGluIHdoaWNoIGNhc2UgXCJub25lXCJcbiAgICogaXMgdXNlZCAoZm9yY2VkKS5cbiAgICovXG4gIGZpdD86IFwibm9uZVwiIHwgXCJjb250YWluXCIgfCBcImNvdmVyXCI7XG4gIC8qKlxuICAgKiBXaGVuIGVpdGhlciBgeGAgb3IgYHlgIGFyZSBub3Qgc3BlY2lmaWVkLCBpbmRpY2F0ZXMgaG93IHRoZSBjYW52YXMgc2hvdWxkXG4gICAqIGJlIGFsaWduZWQgb24gdGhlIHJlc3BlY3RpdmUgYXhpcy5cbiAgICpcbiAgICogLSBgbm9uZWAgICAtIGNhbnZhcyBhbGlnbmVkIHRvIHRvcCBsZWZ0LlxuICAgKiAtIGBjZW50ZXJgIC0gY2FudmFzIGlzIGNlbnRlcmVkIG9uIHRoZSBheGlzIHdoaWNoIGlzIG5vdCBzcGVjaWZpZWRcbiAgICogICAgICAgICAgICAgIChvciBib3RoKS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJjZW50ZXJcIlxuICAgKi9cbiAgcG9zaXRpb24/OiBcImNlbnRlclwiIHwgXCJub25lXCI7XG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEEgbXVsdGlwbGllciB0byBpbmNyZWFzZS9kZWNyZWFzZSB0aGUgZnJhbWUgZGltZW5zaW9uc1xuICAgKiAoY29udGVudCByZXNvbHV0aW9uKS5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIGlmIHlvdXIgY2FudmFzIGlzIDMwMHgxNTAgYW5kIHlvdSBzZXQgc2NhbGUgdG8gMiwgdGhlXG4gICAqIHJlc3VsdGluZyBzaXplIHdpbGwgYmUgNjAweDMwMC5cbiAgICpcbiAgICogQGRlZmF1bHQgMVxuICAgKi9cbiAgc2NhbGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBJZiB5b3UgbmVlZCB0byBzdXBseSB5b3VyIG93biBjYW52YXMsIGUuZy4gaW4gdGVzdCBlbnZpcm9ubWVudHMgb3IgaW5cbiAgICogTm9kZS5qcy5cbiAgICpcbiAgICogRG8gbm90IHNldCBgY2FudmFzLndpZHRoL2hlaWdodGAgb3IgbW9kaWZ5IHRoZSBjYW52YXMgY29udGV4dCBhcyB0aGF0J3NcbiAgICogaGFuZGxlZCBieSBFeGNhbGlkcmF3LlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKWAuXG4gICAqL1xuICBjcmVhdGVDYW52YXM/OiAoKSA9PiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgLyoqXG4gICAqIElmIHlvdSB3YW50IHRvIHN1cHBseSBgd2lkdGhgL2BoZWlnaHRgIGR5bmFtaWNhbGx5IChvciBkZXJpdmUgZnJvbSB0aGVcbiAgICogY29udGVudCBib3VuZGluZyBib3gpLCB5b3UgY2FuIHVzZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBJZ25vcmVkIGlmIGBtYXhXaWR0aE9ySGVpZ2h0YCwgYHdpZHRoYCwgb3IgYGhlaWdodGAgaXMgc2V0LlxuICAgKi9cbiAgZ2V0RGltZW5zaW9ucz86IChcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICApID0+IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXI7IHNjYWxlPzogbnVtYmVyIH07XG59O1xuXG4vKipcbiAqIFRoaXMgQVBJIGlzIHVzdWFsbHkgdXNlZCBhcyBhIHByZWN1cnNvciB0byBzZWFyaWFsaXppbmcgdG8gQmxvYiBvciBQTkcsXG4gKiBidXQgY2FuIGFsc28gYmUgdXNlZCB0byBjcmVhdGUgYSBjYW52YXMgZm9yIG90aGVyIHB1cnBvc2VzLlxuICovXG5leHBvcnQgY29uc3QgZXhwb3J0VG9DYW52YXMgPSBhc3luYyAoe1xuICBkYXRhLFxuICBjb25maWcsXG59OiB7XG4gIGRhdGE6IEV4cG9ydFRvQ2FudmFzRGF0YTtcbiAgY29uZmlnPzogRXhwb3J0VG9DYW52YXNDb25maWc7XG59KSA9PiB7XG4gIC8vIGluaXRpYWxpemUgZGVmYXVsdHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIGNvbnN0IHsgZWxlbWVudHMsIGZpbGVzIH0gPSBkYXRhO1xuXG4gIGNvbnN0IGFwcFN0YXRlID0gcmVzdG9yZUFwcFN0YXRlKGRhdGEuYXBwU3RhdGUsIG51bGwpO1xuXG4gIC8vIGNsb25lXG4gIGNvbnN0IGNmZyA9IE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZyk7XG5cbiAgaWYgKGNmZy54ICE9IG51bGwgfHwgY2ZnLnggIT0gbnVsbCkge1xuICAgIGlmIChjZmcuZml0ICE9IG51bGwgJiYgY2ZnLmZpdCAhPT0gXCJub25lXCIpIHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gRU5WLlBST0RVQ1RJT04pIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIFwiYGZpdGAgd2lsbCBiZSBpZ25vcmVkIChhdXRvbWF0aWNhbGx5IHNldCB0byBgbm9uZWApIHdoZW4geW91IHNwZWNpZnkgYHhgIG9yIGB5YCBvZmZzZXRzXCIsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNmZy5maXQgPSBcIm5vbmVcIjtcbiAgfVxuXG4gIGNmZy5maXQgPSBjZmcuZml0ID8/IFwiY29udGFpblwiO1xuXG4gIGlmIChjZmcuZml0ID09PSBcImNvdmVyXCIgJiYgY2ZnLnBhZGRpbmcpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5QUk9EVUNUSU9OKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJgcGFkZGluZ2AgaXMgaWdub3JlZCB3aGVuIGBmaXRgIGlzIHNldCB0byBgY292ZXJgXCIpO1xuICAgIH1cbiAgICBjZmcucGFkZGluZyA9IDA7XG4gIH1cblxuICBjZmcuc2NhbGUgPSBjZmcuc2NhbGUgPz8gMTtcblxuICBjZmcub3JpZ2luID0gY2ZnLm9yaWdpbiA/PyBcImNhbnZhc1wiO1xuICBjZmcucG9zaXRpb24gPSBjZmcucG9zaXRpb24gPz8gXCJjZW50ZXJcIjtcbiAgY2ZnLnBhZGRpbmcgPSBjZmcucGFkZGluZyA/PyBERUZBVUxUX0VYUE9SVF9QQURESU5HO1xuXG4gIGlmIChjZmcubWF4V2lkdGhPckhlaWdodCAhPSBudWxsICYmIGNmZy53aWR0aE9ySGVpZ2h0ICE9IG51bGwpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5QUk9EVUNUSU9OKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJgbWF4V2lkdGhPckhlaWdodGAgaXMgaWdub3JlZCB3aGVuIGB3aWR0aE9ySGVpZ2h0YCBpcyBzZXRcIik7XG4gICAgfVxuICAgIGNmZy5tYXhXaWR0aE9ySGVpZ2h0ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKFxuICAgIChjZmcubWF4V2lkdGhPckhlaWdodCAhPSBudWxsIHx8IGNmZy53aWR0aCAhPSBudWxsIHx8IGNmZy5oZWlnaHQgIT0gbnVsbCkgJiZcbiAgICBjZmcuZ2V0RGltZW5zaW9uc1xuICApIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5QUk9EVUNUSU9OKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiYGdldERpbWVuc2lvbnNgIGlzIGlnbm9yZWQgd2hlbiBgd2lkdGhgLCBgaGVpZ2h0YCwgb3IgYG1heFdpZHRoT3JIZWlnaHRgIGlzIHNldFwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgY2ZnLmdldERpbWVuc2lvbnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gdmFsdWUgdXNlZCB0byBzY2FsZSB0aGUgY2FudmFzIGNvbnRleHQuIEJ5IGRlZmF1bHQsIHdlIHVzZSB0aGlzIHRvXG4gIC8vIG1ha2UgdGhlIGNhbnZhcyBmaXQgaW50byB0aGUgZnJhbWUgKGUuZy4gZm9yIGBjZmcuZml0YCBzZXQgdG8gYGNvbnRhaW5gKS5cbiAgLy8gSWYgYGNmZy5zY2FsZWAgaXMgc2V0LCB3ZSBtdWx0aXBseSB0aGUgcmVzdWx0aW5nIGNhbnZhc1NjYWxlIGJ5IGl0IHRvXG4gIC8vIHNjYWxlIHRoZSBvdXRwdXQgZnVydGhlci5cbiAgbGV0IGNhbnZhc1NjYWxlID0gMTtcblxuICBjb25zdCBvcmlnQ2FudmFzU2l6ZSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGNmZy5wYWRkaW5nKTtcblxuICAvLyB2YXJpYWJsZXMgZm9yIG9yaWdpbmFsIGNvbnRlbnQgYm91bmRpbmcgYm94XG4gIGNvbnN0IFtvcmlnWCwgb3JpZ1ksIG9yaWdXaWR0aCwgb3JpZ0hlaWdodF0gPSBvcmlnQ2FudmFzU2l6ZTtcbiAgLy8gdmFyaWFibGVzIGZvciB0YXJnZXQgYm91bmRpbmcgYm94XG4gIGxldCBbeCwgeSwgd2lkdGgsIGhlaWdodF0gPSBvcmlnQ2FudmFzU2l6ZTtcblxuICBpZiAoY2ZnLm1heFdpZHRoT3JIZWlnaHQgIT0gbnVsbCB8fCBjZmcud2lkdGhPckhlaWdodCAhPSBudWxsKSB7XG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgob3JpZ1dpZHRoLCBvcmlnSGVpZ2h0KTtcbiAgICBpZiAoY2ZnLndpZHRoT3JIZWlnaHQgIT0gbnVsbCkge1xuICAgICAgLy8gY2FsY3VsYXRlIGJ5IGhvdyBtdWNoIGRvIHdlIG5lZWQgdG8gc2NhbGUgdGhlIGNhbnZhcyB0byBmaXQgaW50byB0aGVcbiAgICAgIC8vIHRhcmdldCBkaW1lbnNpb24gKGUuZy4gdGFyZ2V0OiBtYXggNTBweCwgYWN0dWFsOiA3MHgxMDBweCA9PiBzY2FsZTogMC41KVxuICAgICAgY2FudmFzU2NhbGUgPSBjZmcud2lkdGhPckhlaWdodCAvIG1heDtcbiAgICB9IGVsc2UgaWYgKGNmZy5tYXhXaWR0aE9ySGVpZ2h0ICE9IG51bGwpIHtcbiAgICAgIGNhbnZhc1NjYWxlID0gY2ZnLm1heFdpZHRoT3JIZWlnaHQgPCBtYXggPyBjZmcubWF4V2lkdGhPckhlaWdodCAvIG1heCA6IDE7XG4gICAgfVxuXG4gICAgd2lkdGggKj0gY2FudmFzU2NhbGU7XG4gICAgaGVpZ2h0ICo9IGNhbnZhc1NjYWxlO1xuICB9IGVsc2UgaWYgKGNmZy53aWR0aCAhPSBudWxsKSB7XG4gICAgd2lkdGggPSBjZmcud2lkdGg7XG5cbiAgICBpZiAoY2ZnLmhlaWdodCkge1xuICAgICAgaGVpZ2h0ID0gY2ZnLmhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgaGVpZ2h0IG5vdCBzcGVjaWZpZWQsIHNjYWxlIHRoZSBvcmlnaW5hbCBoZWlnaHQgdG8gbWF0Y2ggdGhlIG5ld1xuICAgICAgLy8gd2lkdGggd2hpbGUgbWFpbnRhaW5pbmcgYXNwZWN0IHJhdGlvXG4gICAgICBoZWlnaHQgKj0gd2lkdGggLyBvcmlnV2lkdGg7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNmZy5oZWlnaHQgIT0gbnVsbCkge1xuICAgIGhlaWdodCA9IGNmZy5oZWlnaHQ7XG4gICAgLy8gd2lkdGggbm90IHNwZWNpZmllZCwgc28gc2NhbGUgdGhlIG9yaWdpbmFsIHdpZHRoIHRvIG1hdGNoIHRoZSBuZXdcbiAgICAvLyBoZWlnaHQgd2hpbGUgbWFpbnRhaW5pbmcgYXNwZWN0IHJhdGlvXG4gICAgd2lkdGggKj0gaGVpZ2h0IC8gb3JpZ0hlaWdodDtcbiAgfSBlbHNlIGlmIChjZmcuZ2V0RGltZW5zaW9ucykge1xuICAgIGNvbnN0IHJldCA9IGNmZy5nZXREaW1lbnNpb25zKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgd2lkdGggPSByZXQud2lkdGg7XG4gICAgaGVpZ2h0ID0gcmV0LmhlaWdodDtcbiAgICBjZmcuc2NhbGUgPSByZXQuc2NhbGUgPz8gY2ZnLnNjYWxlO1xuICB9XG5cbiAgaWYgKGNmZy5maXQgPT09IFwiY29udGFpblwiICYmICFjZmcubWF4V2lkdGhPckhlaWdodCkge1xuICAgIGNvbnN0IHdSYXRpbyA9IHdpZHRoIC8gb3JpZ1dpZHRoO1xuICAgIGNvbnN0IGhSYXRpbyA9IGhlaWdodCAvIG9yaWdIZWlnaHQ7XG4gICAgLy8gc2NhbGUgdGhlIG9yaWcgY2FudmFzIHRvIGZpdCBpbiB0aGUgdGFyZ2V0IGZyYW1lXG4gICAgY2FudmFzU2NhbGUgPSBNYXRoLm1pbih3UmF0aW8sIGhSYXRpbyk7XG4gIH0gZWxzZSBpZiAoY2ZnLmZpdCA9PT0gXCJjb3ZlclwiKSB7XG4gICAgY29uc3Qgd1JhdGlvID0gd2lkdGggLyBvcmlnV2lkdGg7XG4gICAgY29uc3QgaFJhdGlvID0gaGVpZ2h0IC8gb3JpZ0hlaWdodDtcbiAgICAvLyBzY2FsZSB0aGUgb3JpZyBjYW52YXMgdG8gZmlsbCB0aGUgdGhlIHRhcmdldCBmcmFtZVxuICAgIC8vIChvcHBvc2l0ZSBvZiBcImNvbnRhaW5cIilcbiAgICBjYW52YXNTY2FsZSA9IE1hdGgubWF4KHdSYXRpbywgaFJhdGlvKTtcbiAgfVxuXG4gIHggPSBjZmcueCA/PyBvcmlnWDtcbiAgeSA9IGNmZy55ID8/IG9yaWdZO1xuXG4gIC8vIGlmIHdlIHN3aXRjaCB0byBcImNvbnRlbnRcIiBjb29yZHMsIHdlIG5lZWQgdG8gb2Zmc2V0IGNmZy1zdXBwbGllZFxuICAvLyBjb29yZHMgYnkgdGhlIHgveSBvZiBjb250ZW50IGJvdW5kaW5nIGJveFxuICBpZiAoY2ZnLm9yaWdpbiA9PT0gXCJjb250ZW50XCIpIHtcbiAgICBpZiAoY2ZnLnggIT0gbnVsbCkge1xuICAgICAgeCArPSBvcmlnWDtcbiAgICB9XG4gICAgaWYgKGNmZy55ICE9IG51bGwpIHtcbiAgICAgIHkgKz0gb3JpZ1k7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2VudGVyaW5nIHRoZSBjb250ZW50IHRvIHRoZSBmcmFtZS5cbiAgLy8gV2UgZGl2aWRlIHdpZHRoL2hlaWdodCBieSBjYW52YXNTY2FsZSBzbyB0aGF0IHdlIGNhbGN1bGF0ZSBpbiB0aGUgb3JpZ2luYWxcbiAgLy8gYXNwZWN0IHJhdGlvIGRpbWVuc2lvbnMuXG4gIGlmIChjZmcucG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcbiAgICBpZiAoY2ZnLnggPT0gbnVsbCkge1xuICAgICAgeCAtPSB3aWR0aCAvIGNhbnZhc1NjYWxlIC8gMiAtIG9yaWdXaWR0aCAvIDI7XG4gICAgfVxuICAgIGlmIChjZmcueSA9PSBudWxsKSB7XG4gICAgICB5IC09IGhlaWdodCAvIGNhbnZhc1NjYWxlIC8gMiAtIG9yaWdIZWlnaHQgLyAyO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNhbnZhcyA9IGNmZy5jcmVhdGVDYW52YXNcbiAgICA/IGNmZy5jcmVhdGVDYW52YXMoKVxuICAgIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAvLyBzY2FsZSB0aGUgd2hvbGUgZnJhbWUgYnkgY2ZnLnNjYWxlIChvbiB0b3Agb2Ygd2hhdGV2ZXIgY2FudmFzU2NhbGUgd2VcbiAgLy8gY2FsY3VsYXRlZCBhYm92ZSlcbiAgY2FudmFzU2NhbGUgKj0gY2ZnLnNjYWxlO1xuICB3aWR0aCAqPSBjZmcuc2NhbGU7XG4gIGhlaWdodCAqPSBjZmcuc2NhbGU7XG5cbiAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgY29uc3QgeyBpbWFnZUNhY2hlIH0gPSBhd2FpdCB1cGRhdGVJbWFnZUNhY2hlKHtcbiAgICBpbWFnZUNhY2hlOiBuZXcgTWFwKCksXG4gICAgZmlsZUlkczogZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKGVsZW1lbnRzKS5tYXAoXG4gICAgICAoZWxlbWVudCkgPT4gZWxlbWVudC5maWxlSWQsXG4gICAgKSxcbiAgICBmaWxlczogZmlsZXMgfHwge30sXG4gIH0pO1xuXG4gIHJlbmRlclNjZW5lKHtcbiAgICBlbGVtZW50cyxcbiAgICBhcHBTdGF0ZTogeyAuLi5hcHBTdGF0ZSwgd2lkdGgsIGhlaWdodCwgb2Zmc2V0TGVmdDogMCwgb2Zmc2V0VG9wOiAwIH0sXG4gICAgcmM6IHJvdWdoLmNhbnZhcyhjYW52YXMpLFxuICAgIGNhbnZhcyxcbiAgICByZW5kZXJDb25maWc6IHtcbiAgICAgIGNhbnZhc0JhY2tncm91bmRDb2xvcjpcbiAgICAgICAgY2ZnLmNhbnZhc0JhY2tncm91bmRDb2xvciA9PT0gZmFsc2VcbiAgICAgICAgICA/IC8vIG51bGwgaW5kaWNhdGVzIHRyYW5zcGFyZW50IGJhY2tncm91bmRcbiAgICAgICAgICAgIG51bGxcbiAgICAgICAgICA6IGNmZy5jYW52YXNCYWNrZ3JvdW5kQ29sb3IgfHxcbiAgICAgICAgICAgIGFwcFN0YXRlLnZpZXdCYWNrZ3JvdW5kQ29sb3IgfHxcbiAgICAgICAgICAgIERFRkFVTFRfQkFDS0dST1VORF9DT0xPUixcbiAgICAgIHNjcm9sbFg6IC14ICsgY2ZnLnBhZGRpbmcsXG4gICAgICBzY3JvbGxZOiAteSArIGNmZy5wYWRkaW5nLFxuICAgICAgY2FudmFzU2NhbGUsXG4gICAgICB6b29tOiB7IHZhbHVlOiBERUZBVUxUX1pPT01fVkFMVUUgfSxcbiAgICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkczoge30sXG4gICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiBmYWxzZSxcbiAgICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHt9LFxuICAgICAgcmVtb3RlUG9pbnRlclVzZXJTdGF0ZXM6IHt9LFxuICAgICAgdGhlbWU6IGNmZy50aGVtZSB8fCBUSEVNRS5MSUdIVCxcbiAgICAgIGltYWdlQ2FjaGUsXG4gICAgICByZW5kZXJTY3JvbGxiYXJzOiBmYWxzZSxcbiAgICAgIHJlbmRlclNlbGVjdGlvbjogZmFsc2UsXG4gICAgICByZW5kZXJHcmlkOiBmYWxzZSxcbiAgICAgIGlzRXhwb3J0aW5nOiB0cnVlLFxuICAgIH0sXG4gIH0pO1xuXG4gIHJldHVybiBjYW52YXM7XG59O1xuXG5leHBvcnQgY29uc3QgZXhwb3J0VG9TdmcgPSBhc3luYyAoXG4gIGVsZW1lbnRzOiByZWFkb25seSBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnRbXSxcbiAgYXBwU3RhdGU6IHtcbiAgICBleHBvcnRCYWNrZ3JvdW5kOiBib29sZWFuO1xuICAgIGV4cG9ydFBhZGRpbmc/OiBudW1iZXI7XG4gICAgZXhwb3J0U2NhbGU/OiBudW1iZXI7XG4gICAgdmlld0JhY2tncm91bmRDb2xvcjogc3RyaW5nO1xuICAgIGV4cG9ydFdpdGhEYXJrTW9kZT86IGJvb2xlYW47XG4gICAgZXhwb3J0RW1iZWRTY2VuZT86IGJvb2xlYW47XG4gIH0sXG4gIGZpbGVzOiBCaW5hcnlGaWxlcyB8IG51bGwsXG4gIG9wdHM/OiB7XG4gICAgc2VyaWFsaXplQXNKU09OPzogKCkgPT4gc3RyaW5nO1xuICB9LFxuKTogUHJvbWlzZTxTVkdTVkdFbGVtZW50PiA9PiB7XG4gIGNvbnN0IHtcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICAgIGV4cG9ydFNjYWxlID0gMSxcbiAgICBleHBvcnRFbWJlZFNjZW5lLFxuICB9ID0gYXBwU3RhdGU7XG4gIGxldCBtZXRhZGF0YSA9IFwiXCI7XG4gIGlmIChleHBvcnRFbWJlZFNjZW5lKSB7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoLyogd2VicGFja0NodW5rTmFtZTogXCJpbWFnZVwiICovIFwiLi4vLi4vc3JjL2RhdGEvaW1hZ2VcIilcbiAgICAgICkuZW5jb2RlU3ZnTWV0YWRhdGEoe1xuICAgICAgICB0ZXh0OiBvcHRzPy5zZXJpYWxpemVBc0pTT05cbiAgICAgICAgICA/IG9wdHM/LnNlcmlhbGl6ZUFzSlNPTj8uKClcbiAgICAgICAgICA6IHNlcmlhbGl6ZUFzSlNPTihlbGVtZW50cywgYXBwU3RhdGUsIGZpbGVzIHx8IHt9LCBcImxvY2FsXCIpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgfVxuICB9XG4gIGNvbnN0IFttaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpO1xuXG4gIC8vIGluaXRpYWxpemUgU1ZHIHJvb3RcbiAgY29uc3Qgc3ZnUm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIFwic3ZnXCIpO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcInZlcnNpb25cIiwgXCIxLjFcIik7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwieG1sbnNcIiwgU1ZHX05TKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJ2aWV3Qm94XCIsIGAwIDAgJHt3aWR0aH0gJHtoZWlnaHR9YCk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgYCR7d2lkdGggKiBleHBvcnRTY2FsZX1gKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgYCR7aGVpZ2h0ICogZXhwb3J0U2NhbGV9YCk7XG4gIGlmIChhcHBTdGF0ZS5leHBvcnRXaXRoRGFya01vZGUpIHtcbiAgICBzdmdSb290LnNldEF0dHJpYnV0ZShcImZpbHRlclwiLCBUSEVNRV9GSUxURVIpO1xuICB9XG5cbiAgbGV0IGFzc2V0UGF0aCA9IFwiaHR0cHM6Ly9leGNhbGlkcmF3LmNvbS9cIjtcblxuICAvLyBBc3NldCBwYXRoIG5lZWRzIHRvIGJlIGRldGVybWluZWQgb25seSB3aGVuIHVzaW5nIHBhY2thZ2VcbiAgaWYgKHByb2Nlc3MuZW52LklTX0VYQ0FMSURSQVdfTlBNX1BBQ0tBR0UpIHtcbiAgICBhc3NldFBhdGggPVxuICAgICAgd2luZG93LkVYQ0FMSURSQVdfQVNTRVRfUEFUSCB8fFxuICAgICAgYGh0dHBzOi8vdW5wa2cuY29tLyR7cHJvY2Vzcy5lbnYuUEtHX05BTUV9QCR7cHJvY2Vzcy5lbnYuUEtHX1ZFUlNJT059YDtcblxuICAgIGlmIChhc3NldFBhdGg/LnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgICBhc3NldFBhdGggPSBhc3NldFBhdGgucmVwbGFjZShcIi9cIiwgYCR7d2luZG93LmxvY2F0aW9uLm9yaWdpbn0vYCk7XG4gICAgfVxuICAgIGFzc2V0UGF0aCA9IGAke2Fzc2V0UGF0aH0vZGlzdC9leGNhbGlkcmF3LWFzc2V0cy9gO1xuICB9XG4gIHN2Z1Jvb3QuaW5uZXJIVE1MID0gYFxuICAke1NWR19FWFBPUlRfVEFHfVxuICAke21ldGFkYXRhfVxuICA8ZGVmcz5cbiAgICA8c3R5bGUgY2xhc3M9XCJzdHlsZS1mb250c1wiPlxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIlZpcmdpbFwiO1xuICAgICAgICBzcmM6IHVybChcImh0dHBzOi8vZXhjYWxpZHJhdy5jb20vVmlyZ2lsLndvZmYyXCIpO1xuICAgICAgfVxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIkNhc2NhZGlhXCI7XG4gICAgICAgIHNyYzogdXJsKFwiaHR0cHM6Ly9leGNhbGlkcmF3LmNvbS9DYXNjYWRpYS53b2ZmMlwiKTtcbiAgICAgIH1cbiAgICA8L3N0eWxlPlxuICA8L2RlZnM+XG4gIGA7XG4gIC8vIHJlbmRlciBiYWNrZ3JvdW5kIHJlY3RcbiAgaWYgKGFwcFN0YXRlLmV4cG9ydEJhY2tncm91bmQgJiYgdmlld0JhY2tncm91bmRDb2xvcikge1xuICAgIGNvbnN0IHJlY3QgPSBzdmdSb290Lm93bmVyRG9jdW1lbnQhLmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIFwicmVjdFwiKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcInhcIiwgXCIwXCIpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwieVwiLCBcIjBcIik7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCBgJHt3aWR0aH1gKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBgJHtoZWlnaHR9YCk7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHZpZXdCYWNrZ3JvdW5kQ29sb3IpO1xuICAgIHN2Z1Jvb3QuYXBwZW5kQ2hpbGQocmVjdCk7XG4gIH1cblxuICBjb25zdCByc3ZnID0gcm91Z2guc3ZnKHN2Z1Jvb3QpO1xuICByZW5kZXJTY2VuZVRvU3ZnKGVsZW1lbnRzLCByc3ZnLCBzdmdSb290LCBmaWxlcyB8fCB7fSwge1xuICAgIG9mZnNldFg6IC1taW5YICsgZXhwb3J0UGFkZGluZyxcbiAgICBvZmZzZXRZOiAtbWluWSArIGV4cG9ydFBhZGRpbmcsXG4gICAgZXhwb3J0V2l0aERhcmtNb2RlOiBhcHBTdGF0ZS5leHBvcnRXaXRoRGFya01vZGUsXG4gIH0pO1xuXG4gIHJldHVybiBzdmdSb290O1xufTtcblxuLy8gY2FsY3VsYXRlIHNtYWxsZXN0IGFyZWEgdG8gZml0IHRoZSBjb250ZW50cyBpblxuY29uc3QgZ2V0Q2FudmFzU2l6ZSA9IChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBleHBvcnRQYWRkaW5nOiBudW1iZXIsXG4pOiBbbWluWDogbnVtYmVyLCBtaW5ZOiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyXSA9PiB7XG4gIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhlbGVtZW50cyk7XG4gIGNvbnN0IHdpZHRoID0gZGlzdGFuY2UobWluWCwgbWF4WCkgKyBleHBvcnRQYWRkaW5nICogMjtcbiAgY29uc3QgaGVpZ2h0ID0gZGlzdGFuY2UobWluWSwgbWF4WSkgKyBleHBvcnRQYWRkaW5nICsgZXhwb3J0UGFkZGluZztcblxuICByZXR1cm4gW21pblgsIG1pblksIHdpZHRoLCBoZWlnaHRdO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEV4cG9ydFNpemUgPSAoXG4gIGVsZW1lbnRzOiByZWFkb25seSBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnRbXSxcbiAgcGFkZGluZzogbnVtYmVyLFxuICBzY2FsZTogbnVtYmVyLFxuKTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IFssICwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBwYWRkaW5nKS5tYXAoXG4gICAgKGRpbWVuc2lvbikgPT4gTWF0aC50cnVuYyhkaW1lbnNpb24gKiBzY2FsZSksXG4gICk7XG5cbiAgcmV0dXJuIFt3aWR0aCwgaGVpZ2h0XTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../scene/export.ts\n");
4388
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SVG_EXPORT_TAG\": () => (/* binding */ SVG_EXPORT_TAG),\n/* harmony export */ \"exportToCanvas\": () => (/* binding */ exportToCanvas),\n/* harmony export */ \"exportToSvg\": () => (/* binding */ exportToSvg),\n/* harmony export */ \"getExportSize\": () => (/* binding */ getExportSize)\n/* harmony export */ });\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var _element_bounds__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element/bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../data/json */ \"../../data/json.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\nconst SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;\n/**\n * This API is usually used as a precursor to searializing to Blob or PNG,\n * but can also be used to create a canvas for other purposes.\n */\nconst exportToCanvas = ({ data, config, }) => __awaiter(void 0, void 0, void 0, function* () {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n // initialize defaults\n // ---------------------------------------------------------------------------\n const { elements, files } = data;\n const appState = (0,_data_restore__WEBPACK_IMPORTED_MODULE_7__.restoreAppState)(data.appState, null);\n // clone\n const cfg = Object.assign({}, config);\n if (cfg.x != null || cfg.x != null) {\n if (cfg.fit != null && cfg.fit !== \"none\") {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`fit` will be ignored (automatically set to `none`) when you specify `x` or `y` offsets\");\n }\n }\n cfg.fit = \"none\";\n }\n cfg.fit = (_a = cfg.fit) !== null && _a !== void 0 ? _a : \"contain\";\n if (cfg.fit === \"cover\" && cfg.padding) {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`padding` is ignored when `fit` is set to `cover`\");\n }\n cfg.padding = 0;\n }\n cfg.scale = (_b = cfg.scale) !== null && _b !== void 0 ? _b : 1;\n cfg.origin = (_c = cfg.origin) !== null && _c !== void 0 ? _c : \"canvas\";\n cfg.position = (_d = cfg.position) !== null && _d !== void 0 ? _d : \"center\";\n cfg.padding = (_e = cfg.padding) !== null && _e !== void 0 ? _e : _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING;\n if (cfg.maxWidthOrHeight != null && cfg.widthOrHeight != null) {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`maxWidthOrHeight` is ignored when `widthOrHeight` is set\");\n }\n cfg.maxWidthOrHeight = undefined;\n }\n if ((cfg.maxWidthOrHeight != null || cfg.width != null || cfg.height != null) &&\n cfg.getDimensions) {\n if (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_4__.ENV.PRODUCTION) {\n console.warn(\"`getDimensions` is ignored when `width`, `height`, or `maxWidthOrHeight` is set\");\n }\n cfg.getDimensions = undefined;\n }\n // ---------------------------------------------------------------------------\n // value used to scale the canvas context. By default, we use this to\n // make the canvas fit into the frame (e.g. for `cfg.fit` set to `contain`).\n // If `cfg.scale` is set, we multiply the resulting canvasScale by it to\n // scale the output further.\n let canvasScale = 1;\n const origCanvasSize = getCanvasSize(elements, cfg.padding);\n // variables for original content bounding box\n const [origX, origY, origWidth, origHeight] = origCanvasSize;\n // variables for target bounding box\n let [x, y, width, height] = origCanvasSize;\n if (cfg.maxWidthOrHeight != null || cfg.widthOrHeight != null) {\n const max = Math.max(origWidth, origHeight);\n if (cfg.widthOrHeight != null) {\n // calculate by how much do we need to scale the canvas to fit into the\n // target dimension (e.g. target: max 50px, actual: 70x100px => scale: 0.5)\n canvasScale = cfg.widthOrHeight / max;\n }\n else if (cfg.maxWidthOrHeight != null) {\n canvasScale = cfg.maxWidthOrHeight < max ? cfg.maxWidthOrHeight / max : 1;\n }\n width *= canvasScale;\n height *= canvasScale;\n }\n else if (cfg.width != null) {\n width = cfg.width;\n if (cfg.height) {\n height = cfg.height;\n }\n else {\n // if height not specified, scale the original height to match the new\n // width while maintaining aspect ratio\n height *= width / origWidth;\n }\n }\n else if (cfg.height != null) {\n height = cfg.height;\n // width not specified, so scale the original width to match the new\n // height while maintaining aspect ratio\n width *= height / origHeight;\n }\n else if (cfg.getDimensions) {\n const ret = cfg.getDimensions(width, height);\n width = ret.width;\n height = ret.height;\n cfg.scale = (_f = ret.scale) !== null && _f !== void 0 ? _f : cfg.scale;\n }\n if (cfg.fit === \"contain\" && !cfg.maxWidthOrHeight) {\n const wRatio = width / origWidth;\n const hRatio = height / origHeight;\n // scale the orig canvas to fit in the target frame\n canvasScale = Math.min(wRatio, hRatio);\n }\n else if (cfg.fit === \"cover\") {\n const wRatio = width / origWidth;\n const hRatio = height / origHeight;\n // scale the orig canvas to fill the the target frame\n // (opposite of \"contain\")\n canvasScale = Math.max(wRatio, hRatio);\n }\n x = (_g = cfg.x) !== null && _g !== void 0 ? _g : origX;\n y = (_h = cfg.y) !== null && _h !== void 0 ? _h : origY;\n // if we switch to \"content\" coords, we need to offset cfg-supplied\n // coords by the x/y of content bounding box\n if (cfg.origin === \"content\") {\n if (cfg.x != null) {\n x += origX;\n }\n if (cfg.y != null) {\n y += origY;\n }\n }\n // Centering the content to the frame.\n // We divide width/height by canvasScale so that we calculate in the original\n // aspect ratio dimensions.\n if (cfg.position === \"center\") {\n if (cfg.x == null) {\n x -= width / canvasScale / 2 - origWidth / 2;\n }\n if (cfg.y == null) {\n y -= height / canvasScale / 2 - origHeight / 2;\n }\n }\n const canvas = cfg.createCanvas\n ? cfg.createCanvas()\n : document.createElement(\"canvas\");\n // scale the whole frame by cfg.scale (on top of whatever canvasScale we\n // calculated above)\n canvasScale *= cfg.scale;\n width *= cfg.scale;\n height *= cfg.scale;\n canvas.width = width;\n canvas.height = height;\n const { imageCache } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_6__.updateImageCache)({\n imageCache: new Map(),\n fileIds: (0,_element_image__WEBPACK_IMPORTED_MODULE_6__.getInitializedImageElements)(elements).map((element) => element.fileId),\n files: files || {},\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderScene)({\n elements,\n appState: Object.assign(Object.assign({}, appState), { width, height, offsetLeft: 0, offsetTop: 0 }),\n rc: roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas),\n canvas,\n renderConfig: {\n canvasBackgroundColor: cfg.canvasBackgroundColor === false\n ? // null indicates transparent background\n null\n : cfg.canvasBackgroundColor ||\n appState.viewBackgroundColor ||\n _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_BACKGROUND_COLOR,\n scrollX: -x + cfg.padding,\n scrollY: -y + cfg.padding,\n canvasScale,\n zoom: { value: _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_ZOOM_VALUE },\n remotePointerViewportCoords: {},\n remoteSelectedElementIds: {},\n shouldCacheIgnoreZoom: false,\n remotePointerUsernames: {},\n remotePointerUserStates: {},\n theme: cfg.theme || _constants__WEBPACK_IMPORTED_MODULE_4__.THEME.LIGHT,\n imageCache,\n renderScrollbars: false,\n renderSelection: false,\n renderGrid: false,\n isExporting: true,\n },\n });\n return canvas;\n});\nconst exportToSvg = (elements, appState, files, opts) => __awaiter(void 0, void 0, void 0, function* () {\n var _j;\n const { exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, exportScale = 1, exportEmbedScene, } = appState;\n let metadata = \"\";\n if (exportEmbedScene) {\n try {\n metadata = yield (yield Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../../src/data/image */ \"../../data/image.ts\"))).encodeSvgMetadata({\n text: (opts === null || opts === void 0 ? void 0 : opts.serializeAsJSON)\n ? (_j = opts === null || opts === void 0 ? void 0 : opts.serializeAsJSON) === null || _j === void 0 ? void 0 : _j.call(opts)\n : (0,_data_json__WEBPACK_IMPORTED_MODULE_5__.serializeAsJSON)(elements, appState, files || {}, \"local\"),\n });\n }\n catch (error) {\n console.error(error);\n }\n }\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n // initialize SVG root\n const svgRoot = document.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"svg\");\n svgRoot.setAttribute(\"version\", \"1.1\");\n svgRoot.setAttribute(\"xmlns\", _constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS);\n svgRoot.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svgRoot.setAttribute(\"width\", `${width * exportScale}`);\n svgRoot.setAttribute(\"height\", `${height * exportScale}`);\n if (appState.exportWithDarkMode) {\n svgRoot.setAttribute(\"filter\", _constants__WEBPACK_IMPORTED_MODULE_4__.THEME_FILTER);\n }\n let assetPath = \"https://excalidraw.com/\";\n // Asset path needs to be determined only when using package\n if (true) {\n assetPath =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@dwelle/excalidraw\"}@${\"0.4.0-b411b92\"}`;\n if (assetPath === null || assetPath === void 0 ? void 0 : assetPath.startsWith(\"/\")) {\n assetPath = assetPath.replace(\"/\", `${window.location.origin}/`);\n }\n assetPath = `${assetPath}/dist/excalidraw-assets/`;\n }\n svgRoot.innerHTML = `\n ${SVG_EXPORT_TAG}\n ${metadata}\n <defs>\n <style class=\"style-fonts\">\n @font-face {\n font-family: \"Virgil\";\n src: url(\"https://excalidraw.com/Virgil.woff2\");\n }\n @font-face {\n font-family: \"Cascadia\";\n src: url(\"https://excalidraw.com/Cascadia.woff2\");\n }\n </style>\n </defs>\n `;\n // render background rect\n if (appState.exportBackground && viewBackgroundColor) {\n const rect = svgRoot.ownerDocument.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", `${width}`);\n rect.setAttribute(\"height\", `${height}`);\n rect.setAttribute(\"fill\", viewBackgroundColor);\n svgRoot.appendChild(rect);\n }\n const rsvg = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].svg(svgRoot);\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderSceneToSvg)(elements, rsvg, svgRoot, files || {}, {\n offsetX: -minX + exportPadding,\n offsetY: -minY + exportPadding,\n exportWithDarkMode: appState.exportWithDarkMode,\n });\n return svgRoot;\n});\n// calculate smallest area to fit the contents in\nconst getCanvasSize = (elements, exportPadding) => {\n const [minX, minY, maxX, maxY] = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(elements);\n const width = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minX, maxX) + exportPadding * 2;\n const height = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minY, maxY) + exportPadding + exportPadding;\n return [minX, minY, width, height];\n};\nconst getExportSize = (elements, padding, scale) => {\n const [, , width, height] = getCanvasSize(elements, padding).map((dimension) => Math.trunc(dimension * scale));\n return [width, height];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3JDLENBQUMsQ0FBQztBQUVLLE1BQU0sYUFBYSxHQUFHLENBQzNCLFFBQWdELEVBQ2hELE9BQWUsRUFDZixLQUFhLEVBQ0ssRUFBRTtJQUNwQixNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FDOUQsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUM3QyxDQUFDO0lBRUYsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN6QixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vc2NlbmUvZXhwb3J0LnRzPzliZjciXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJvdWdoIGZyb20gXCJyb3VnaGpzL2Jpbi9yb3VnaFwiO1xuaW1wb3J0IHsgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50LCBUaGVtZSB9IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDb21tb25Cb3VuZHMgfSBmcm9tIFwiLi4vZWxlbWVudC9ib3VuZHNcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lLCByZW5kZXJTY2VuZVRvU3ZnIH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlclNjZW5lXCI7XG5pbXBvcnQgeyBkaXN0YW5jZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXBwU3RhdGUsIEJpbmFyeUZpbGVzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IsXG4gIERFRkFVTFRfRVhQT1JUX1BBRERJTkcsXG4gIERFRkFVTFRfWk9PTV9WQUxVRSxcbiAgRU5WLFxuICBTVkdfTlMsXG4gIFRIRU1FLFxuICBUSEVNRV9GSUxURVIsXG59IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNlcmlhbGl6ZUFzSlNPTiB9IGZyb20gXCIuLi9kYXRhL2pzb25cIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcbmltcG9ydCB7IHJlc3RvcmVBcHBTdGF0ZSB9IGZyb20gXCIuLi9kYXRhL3Jlc3RvcmVcIjtcblxuZXhwb3J0IGNvbnN0IFNWR19FWFBPUlRfVEFHID0gYDwhLS0gc3ZnLXNvdXJjZTpleGNhbGlkcmF3IC0tPmA7XG5cbmV4cG9ydCB0eXBlIEV4cG9ydFRvQ2FudmFzRGF0YSA9IHtcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdO1xuICBhcHBTdGF0ZT86IFBhcnRpYWw8T21pdDxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPj47XG4gIGZpbGVzOiBCaW5hcnlGaWxlcyB8IG51bGw7XG59O1xuXG5leHBvcnQgdHlwZSBFeHBvcnRUb0NhbnZhc0NvbmZpZyA9IHtcbiAgdGhlbWU/OiBUaGVtZTtcbiAgLyoqXG4gICAqIENhbnZhcyBiYWNrZ3JvdW5kLiBWYWxpZCB2YWx1ZXMgYXJlOlxuICAgKlxuICAgKiAtIGB1bmRlZmluZWRgIC0gdGhlIGJhY2tncm91bmQgb2YgXCJhcHBTdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yXCIgaXMgdXNlZC5cbiAgICogLSBgZmFsc2VgIC0gbm8gYmFja2dyb3VuZCBpcyB1c2VkIChzZXQgdG8gXCJ0cmFuc3BhcmVudFwiKS5cbiAgICogLSBgc3RyaW5nYCAtIHNob3VsZCBiZSBhIHZhbGlkIENTUyBjb2xvci5cbiAgICpcbiAgICogQGRlZmF1bHQgdW5kZWZpbmVkXG4gICAqL1xuICBjYW52YXNCYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmcgfCBmYWxzZTtcbiAgLyoqXG4gICAqIENhbnZhcyBwYWRkaW5nIGluIHBpeGVscy4gQWZmZWN0ZWQgYnkgc2NhbGUuIElnbm9yZWQgaWYgYGZpdGAgaXMgc2V0IHRvXG4gICAqIGBjb3ZlcmAuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEwXG4gICAqL1xuICBwYWRkaW5nPzogbnVtYmVyO1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBNYWtlcyBzdXJlIHRoZSBjYW52YXMgY29udGVudCBmaXRzIGludG8gYSBmcmFtZSBvZiB3aWR0aC9oZWlnaHQgbm8gbGFyZ2VyXG4gICAqIHRoYW4gdGhpcyB2YWx1ZSwgd2hpbGUgbWFpbnRhaW5pbmcgdGhlIGFzcGVjdCByYXRpby5cbiAgICpcbiAgICogRmluYWwgZGltZW5zaW9ucyBjYW4gZ2V0IHNtYWxsZXIvbGFyZ2VyIGlmIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aFxuICAgKiBgc2NhbGVgLlxuICAgKi9cbiAgbWF4V2lkdGhPckhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFNjYWxlIHRoZSBjYW52YXMgY29udGVudCB0byBiZSBleGNhdGx5IHRoaXMgbWFueSBwaXhlbHMgd2lkZS90YWxsLlxuICAgKlxuICAgKiBDYW5ub3QgYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBtYXhXaWR0aE9ySGVpZ2h0YC5cbiAgICpcbiAgICogRmluYWwgZGltZW5zaW9ucyBjYW4gZ2V0IHNtYWxsZXIvbGFyZ2VyIGlmIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aFxuICAgKiBgc2NhbGVgLlxuICAgKi9cbiAgd2lkdGhPckhlaWdodD86IG51bWJlcjtcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogV2lkdGggb2YgdGhlIGZyYW1lLiBTdXBwbHkgYHhgIG9yIGB5YCBpZiB5b3Ugd2FudCB0byBvZnNzZXQgdGhlIGNhbnZhc1xuICAgKiBjb250ZW50LlxuICAgKlxuICAgKiBJZiBgd2lkdGhgIG9taXR0ZWQgYnV0IGBoZWlnaHRgIHN1cHBsaWVkLCBgd2lkdGhgIGlzIGNhbGN1bGF0ZWQgZnJvbSB0aGVcbiAgICogdGhlIGNvbnRlbnQncyBib3VuZGluZyBib3ggdG8gcHJlc2VydmUgdGhlIGFzcGVjdCByYXRpby5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gdGhlIGNvbnRlbnQgYm91bmRpbmcgYm94IHdpZHRoIHdoZW4gYm90aCBgd2lkdGhgIGFuZCBgaGVpZ2h0YFxuICAgKiBhcmUgb21pdHRlZC5cbiAgICovXG4gIHdpZHRoPzogbnVtYmVyO1xuICAvKipcbiAgICogSGVpZ2h0IG9mIHRoZSBmcmFtZS5cbiAgICpcbiAgICogSWYgYGhlaWdodGAgb21pdHRlZCBidXQgYHdpZHRoYCBzdXBwbGllZCwgYGhlaWdodGAgaXMgY2FsY3VsYXRlZCBmcm9tIHRoZVxuICAgKiBjb250ZW50J3MgYm91bmRpbmcgYm94IHRvIHByZXNlcnZlIHRoZSBhc3BlY3QgcmF0aW8uXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHRoZSBjb250ZW50IGJvdW5kaW5nIGJveCBoZWlnaHQgd2hlbiBib3RoIGB3aWR0aGAgYW5kIGBoZWlnaHRgXG4gICAqIGFyZSBvbWl0dGVkLlxuICAgKi9cbiAgaGVpZ2h0PzogbnVtYmVyO1xuICAvKipcbiAgICogTGVmdCBjYW52YXMgb2Zmc2V0LiBCeSBkZWZhdWx0IHRoZSBjb29yZGluYXRlIGlzIHJlbGF0aXZlIHRvIHRoZSBjYW52YXMuXG4gICAqIFlvdSBjYW4gc3dpdGNoIHRvIGNvbnRlbnQgY29vcmRpbmF0ZXMgYnkgc2V0dGluZyBgb3JpZ2luYCB0byBgY29udGVudGAuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHRoZSBgeGAgcG9zdGlvbiBvZiB0aGUgY29udGVudCBib3VuZGluZyBib3guXG4gICAqL1xuICB4PzogbnVtYmVyO1xuICAvKipcbiAgICogVG9wIGNhbnZhcyBvZmZzZXQuIEJ5IGRlZmF1bHQgdGhlIGNvb3JkaW5hdGUgaXMgcmVsYXRpdmUgdG8gdGhlIGNhbnZhcy5cbiAgICogWW91IGNhbiBzd2l0Y2ggdG8gY29udGVudCBjb29yZGluYXRlcyBieSBzZXR0aW5nIGBvcmlnaW5gIHRvIGBjb250ZW50YC5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gdGhlIGB5YCBwb3N0aW9uIG9mIHRoZSBjb250ZW50IGJvdW5kaW5nIGJveC5cbiAgICovXG4gIHk/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhlIGNvb3JkaW5hdGUgc3lzdGVtIG9mIHRoZSBgeGAgYW5kIGB5YCB2YWx1ZXMuXG4gICAqXG4gICAqIC0gYGNhbnZhc2AgLSBgeGAgYW5kIGB5YCBhcmUgcmVsYXRpdmUgdG8gdGhlIGNhbnZhcyBbMCwgMF0gcG9zaXRpb24uXG4gICAqIC0gYGNvbnRlbnRgIC0gYHhgIGFuZCBgeWAgYXJlIHJlbGF0aXZlIHRvIHRoZSBjb250ZW50IGJvdW5kaW5nIGJveC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJjYW52YXNcIlxuICAgKi9cbiAgb3JpZ2luPzogXCJjYW52YXNcIiB8IFwiY29udGVudFwiO1xuICAvKipcbiAgICogSWYgZGltZW5zaW9ucyBzcGVjaWZpZWQgYW5kIGB4YCBhbmQgYHlgIGFyZSBub3Qgc3BlY2lmaWVkLCB0aGlzIGluZGljYXRlc1xuICAgKiBob3cgdGhlIGNhbnZhcyBzaG91bGQgYmUgc2NhbGVkLlxuICAgKlxuICAgKiBCZWhhdmlvciBhbGlnbnMgd2l0aCB0aGUgYG9iamVjdC1maXRgIENTUyBwcm9wZXJ0eS5cbiAgICpcbiAgICogLSBgbm9uZWAgICAgLSBubyBzY2FsaW5nLlxuICAgKiAtIGBjb250YWluYCAtIHNjYWxlIHRvIGZpdCB0aGUgZnJhbWUuXG4gICAqIC0gYGNvdmVyYCAgIC0gc2NhbGUgdG8gZmlsbCB0aGUgZnJhbWUgd2hpbGUgbWFpbnRhaW5pbmcgYXNwZWN0IHJhdGlvLiBJZlxuICAgKiAgICAgICAgICAgICAgIGNvbnRlbnQgb3ZlcmZsb3dzLCBpdCB3aWxsIGJlIGNyb3BwZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiY29udGFpblwiIHVubGVzcyBgeGAgb3IgYHlgIGFyZSBzcGVjaWZpZWQsIGluIHdoaWNoIGNhc2UgXCJub25lXCJcbiAgICogaXMgdXNlZCAoZm9yY2VkKS5cbiAgICovXG4gIGZpdD86IFwibm9uZVwiIHwgXCJjb250YWluXCIgfCBcImNvdmVyXCI7XG4gIC8qKlxuICAgKiBXaGVuIGVpdGhlciBgeGAgb3IgYHlgIGFyZSBub3Qgc3BlY2lmaWVkLCBpbmRpY2F0ZXMgaG93IHRoZSBjYW52YXMgc2hvdWxkXG4gICAqIGJlIGFsaWduZWQgb24gdGhlIHJlc3BlY3RpdmUgYXhpcy5cbiAgICpcbiAgICogLSBgbm9uZWAgICAtIGNhbnZhcyBhbGlnbmVkIHRvIHRvcCBsZWZ0LlxuICAgKiAtIGBjZW50ZXJgIC0gY2FudmFzIGlzIGNlbnRlcmVkIG9uIHRoZSBheGlzIHdoaWNoIGlzIG5vdCBzcGVjaWZpZWRcbiAgICogICAgICAgICAgICAgIChvciBib3RoKS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJjZW50ZXJcIlxuICAgKi9cbiAgcG9zaXRpb24/OiBcImNlbnRlclwiIHwgXCJub25lXCI7XG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEEgbXVsdGlwbGllciB0byBpbmNyZWFzZS9kZWNyZWFzZSB0aGUgZnJhbWUgZGltZW5zaW9uc1xuICAgKiAoY29udGVudCByZXNvbHV0aW9uKS5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIGlmIHlvdXIgY2FudmFzIGlzIDMwMHgxNTAgYW5kIHlvdSBzZXQgc2NhbGUgdG8gMiwgdGhlXG4gICAqIHJlc3VsdGluZyBzaXplIHdpbGwgYmUgNjAweDMwMC5cbiAgICpcbiAgICogQGRlZmF1bHQgMVxuICAgKi9cbiAgc2NhbGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBJZiB5b3UgbmVlZCB0byBzdXBseSB5b3VyIG93biBjYW52YXMsIGUuZy4gaW4gdGVzdCBlbnZpcm9ubWVudHMgb3IgaW5cbiAgICogTm9kZS5qcy5cbiAgICpcbiAgICogRG8gbm90IHNldCBgY2FudmFzLndpZHRoL2hlaWdodGAgb3IgbW9kaWZ5IHRoZSBjYW52YXMgY29udGV4dCBhcyB0aGF0J3NcbiAgICogaGFuZGxlZCBieSBFeGNhbGlkcmF3LlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKWAuXG4gICAqL1xuICBjcmVhdGVDYW52YXM/OiAoKSA9PiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgLyoqXG4gICAqIElmIHlvdSB3YW50IHRvIHN1cHBseSBgd2lkdGhgL2BoZWlnaHRgIGR5bmFtaWNhbGx5IChvciBkZXJpdmUgZnJvbSB0aGVcbiAgICogY29udGVudCBib3VuZGluZyBib3gpLCB5b3UgY2FuIHVzZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBJZ25vcmVkIGlmIGBtYXhXaWR0aE9ySGVpZ2h0YCwgYHdpZHRoYCwgb3IgYGhlaWdodGAgaXMgc2V0LlxuICAgKi9cbiAgZ2V0RGltZW5zaW9ucz86IChcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICApID0+IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXI7IHNjYWxlPzogbnVtYmVyIH07XG59O1xuXG4vKipcbiAqIFRoaXMgQVBJIGlzIHVzdWFsbHkgdXNlZCBhcyBhIHByZWN1cnNvciB0byBzZWFyaWFsaXppbmcgdG8gQmxvYiBvciBQTkcsXG4gKiBidXQgY2FuIGFsc28gYmUgdXNlZCB0byBjcmVhdGUgYSBjYW52YXMgZm9yIG90aGVyIHB1cnBvc2VzLlxuICovXG5leHBvcnQgY29uc3QgZXhwb3J0VG9DYW52YXMgPSBhc3luYyAoe1xuICBkYXRhLFxuICBjb25maWcsXG59OiB7XG4gIGRhdGE6IEV4cG9ydFRvQ2FudmFzRGF0YTtcbiAgY29uZmlnPzogRXhwb3J0VG9DYW52YXNDb25maWc7XG59KSA9PiB7XG4gIC8vIGluaXRpYWxpemUgZGVmYXVsdHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIGNvbnN0IHsgZWxlbWVudHMsIGZpbGVzIH0gPSBkYXRhO1xuXG4gIGNvbnN0IGFwcFN0YXRlID0gcmVzdG9yZUFwcFN0YXRlKGRhdGEuYXBwU3RhdGUsIG51bGwpO1xuXG4gIC8vIGNsb25lXG4gIGNvbnN0IGNmZyA9IE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZyk7XG5cbiAgaWYgKGNmZy54ICE9IG51bGwgfHwgY2ZnLnggIT0gbnVsbCkge1xuICAgIGlmIChjZmcuZml0ICE9IG51bGwgJiYgY2ZnLmZpdCAhPT0gXCJub25lXCIpIHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gRU5WLlBST0RVQ1RJT04pIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIFwiYGZpdGAgd2lsbCBiZSBpZ25vcmVkIChhdXRvbWF0aWNhbGx5IHNldCB0byBgbm9uZWApIHdoZW4geW91IHNwZWNpZnkgYHhgIG9yIGB5YCBvZmZzZXRzXCIsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNmZy5maXQgPSBcIm5vbmVcIjtcbiAgfVxuXG4gIGNmZy5maXQgPSBjZmcuZml0ID8/IFwiY29udGFpblwiO1xuXG4gIGlmIChjZmcuZml0ID09PSBcImNvdmVyXCIgJiYgY2ZnLnBhZGRpbmcpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5QUk9EVUNUSU9OKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJgcGFkZGluZ2AgaXMgaWdub3JlZCB3aGVuIGBmaXRgIGlzIHNldCB0byBgY292ZXJgXCIpO1xuICAgIH1cbiAgICBjZmcucGFkZGluZyA9IDA7XG4gIH1cblxuICBjZmcuc2NhbGUgPSBjZmcuc2NhbGUgPz8gMTtcblxuICBjZmcub3JpZ2luID0gY2ZnLm9yaWdpbiA/PyBcImNhbnZhc1wiO1xuICBjZmcucG9zaXRpb24gPSBjZmcucG9zaXRpb24gPz8gXCJjZW50ZXJcIjtcbiAgY2ZnLnBhZGRpbmcgPSBjZmcucGFkZGluZyA/PyBERUZBVUxUX0VYUE9SVF9QQURESU5HO1xuXG4gIGlmIChjZmcubWF4V2lkdGhPckhlaWdodCAhPSBudWxsICYmIGNmZy53aWR0aE9ySGVpZ2h0ICE9IG51bGwpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5QUk9EVUNUSU9OKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJgbWF4V2lkdGhPckhlaWdodGAgaXMgaWdub3JlZCB3aGVuIGB3aWR0aE9ySGVpZ2h0YCBpcyBzZXRcIik7XG4gICAgfVxuICAgIGNmZy5tYXhXaWR0aE9ySGVpZ2h0ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKFxuICAgIChjZmcubWF4V2lkdGhPckhlaWdodCAhPSBudWxsIHx8IGNmZy53aWR0aCAhPSBudWxsIHx8IGNmZy5oZWlnaHQgIT0gbnVsbCkgJiZcbiAgICBjZmcuZ2V0RGltZW5zaW9uc1xuICApIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IEVOVi5QUk9EVUNUSU9OKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiYGdldERpbWVuc2lvbnNgIGlzIGlnbm9yZWQgd2hlbiBgd2lkdGhgLCBgaGVpZ2h0YCwgb3IgYG1heFdpZHRoT3JIZWlnaHRgIGlzIHNldFwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgY2ZnLmdldERpbWVuc2lvbnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gdmFsdWUgdXNlZCB0byBzY2FsZSB0aGUgY2FudmFzIGNvbnRleHQuIEJ5IGRlZmF1bHQsIHdlIHVzZSB0aGlzIHRvXG4gIC8vIG1ha2UgdGhlIGNhbnZhcyBmaXQgaW50byB0aGUgZnJhbWUgKGUuZy4gZm9yIGBjZmcuZml0YCBzZXQgdG8gYGNvbnRhaW5gKS5cbiAgLy8gSWYgYGNmZy5zY2FsZWAgaXMgc2V0LCB3ZSBtdWx0aXBseSB0aGUgcmVzdWx0aW5nIGNhbnZhc1NjYWxlIGJ5IGl0IHRvXG4gIC8vIHNjYWxlIHRoZSBvdXRwdXQgZnVydGhlci5cbiAgbGV0IGNhbnZhc1NjYWxlID0gMTtcblxuICBjb25zdCBvcmlnQ2FudmFzU2l6ZSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGNmZy5wYWRkaW5nKTtcblxuICAvLyB2YXJpYWJsZXMgZm9yIG9yaWdpbmFsIGNvbnRlbnQgYm91bmRpbmcgYm94XG4gIGNvbnN0IFtvcmlnWCwgb3JpZ1ksIG9yaWdXaWR0aCwgb3JpZ0hlaWdodF0gPSBvcmlnQ2FudmFzU2l6ZTtcbiAgLy8gdmFyaWFibGVzIGZvciB0YXJnZXQgYm91bmRpbmcgYm94XG4gIGxldCBbeCwgeSwgd2lkdGgsIGhlaWdodF0gPSBvcmlnQ2FudmFzU2l6ZTtcblxuICBpZiAoY2ZnLm1heFdpZHRoT3JIZWlnaHQgIT0gbnVsbCB8fCBjZmcud2lkdGhPckhlaWdodCAhPSBudWxsKSB7XG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgob3JpZ1dpZHRoLCBvcmlnSGVpZ2h0KTtcbiAgICBpZiAoY2ZnLndpZHRoT3JIZWlnaHQgIT0gbnVsbCkge1xuICAgICAgLy8gY2FsY3VsYXRlIGJ5IGhvdyBtdWNoIGRvIHdlIG5lZWQgdG8gc2NhbGUgdGhlIGNhbnZhcyB0byBmaXQgaW50byB0aGVcbiAgICAgIC8vIHRhcmdldCBkaW1lbnNpb24gKGUuZy4gdGFyZ2V0OiBtYXggNTBweCwgYWN0dWFsOiA3MHgxMDBweCA9PiBzY2FsZTogMC41KVxuICAgICAgY2FudmFzU2NhbGUgPSBjZmcud2lkdGhPckhlaWdodCAvIG1heDtcbiAgICB9IGVsc2UgaWYgKGNmZy5tYXhXaWR0aE9ySGVpZ2h0ICE9IG51bGwpIHtcbiAgICAgIGNhbnZhc1NjYWxlID0gY2ZnLm1heFdpZHRoT3JIZWlnaHQgPCBtYXggPyBjZmcubWF4V2lkdGhPckhlaWdodCAvIG1heCA6IDE7XG4gICAgfVxuXG4gICAgd2lkdGggKj0gY2FudmFzU2NhbGU7XG4gICAgaGVpZ2h0ICo9IGNhbnZhc1NjYWxlO1xuICB9IGVsc2UgaWYgKGNmZy53aWR0aCAhPSBudWxsKSB7XG4gICAgd2lkdGggPSBjZmcud2lkdGg7XG5cbiAgICBpZiAoY2ZnLmhlaWdodCkge1xuICAgICAgaGVpZ2h0ID0gY2ZnLmhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgaGVpZ2h0IG5vdCBzcGVjaWZpZWQsIHNjYWxlIHRoZSBvcmlnaW5hbCBoZWlnaHQgdG8gbWF0Y2ggdGhlIG5ld1xuICAgICAgLy8gd2lkdGggd2hpbGUgbWFpbnRhaW5pbmcgYXNwZWN0IHJhdGlvXG4gICAgICBoZWlnaHQgKj0gd2lkdGggLyBvcmlnV2lkdGg7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNmZy5oZWlnaHQgIT0gbnVsbCkge1xuICAgIGhlaWdodCA9IGNmZy5oZWlnaHQ7XG4gICAgLy8gd2lkdGggbm90IHNwZWNpZmllZCwgc28gc2NhbGUgdGhlIG9yaWdpbmFsIHdpZHRoIHRvIG1hdGNoIHRoZSBuZXdcbiAgICAvLyBoZWlnaHQgd2hpbGUgbWFpbnRhaW5pbmcgYXNwZWN0IHJhdGlvXG4gICAgd2lkdGggKj0gaGVpZ2h0IC8gb3JpZ0hlaWdodDtcbiAgfSBlbHNlIGlmIChjZmcuZ2V0RGltZW5zaW9ucykge1xuICAgIGNvbnN0IHJldCA9IGNmZy5nZXREaW1lbnNpb25zKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgd2lkdGggPSByZXQud2lkdGg7XG4gICAgaGVpZ2h0ID0gcmV0LmhlaWdodDtcbiAgICBjZmcuc2NhbGUgPSByZXQuc2NhbGUgPz8gY2ZnLnNjYWxlO1xuICB9XG5cbiAgaWYgKGNmZy5maXQgPT09IFwiY29udGFpblwiICYmICFjZmcubWF4V2lkdGhPckhlaWdodCkge1xuICAgIGNvbnN0IHdSYXRpbyA9IHdpZHRoIC8gb3JpZ1dpZHRoO1xuICAgIGNvbnN0IGhSYXRpbyA9IGhlaWdodCAvIG9yaWdIZWlnaHQ7XG4gICAgLy8gc2NhbGUgdGhlIG9yaWcgY2FudmFzIHRvIGZpdCBpbiB0aGUgdGFyZ2V0IGZyYW1lXG4gICAgY2FudmFzU2NhbGUgPSBNYXRoLm1pbih3UmF0aW8sIGhSYXRpbyk7XG4gIH0gZWxzZSBpZiAoY2ZnLmZpdCA9PT0gXCJjb3ZlclwiKSB7XG4gICAgY29uc3Qgd1JhdGlvID0gd2lkdGggLyBvcmlnV2lkdGg7XG4gICAgY29uc3QgaFJhdGlvID0gaGVpZ2h0IC8gb3JpZ0hlaWdodDtcbiAgICAvLyBzY2FsZSB0aGUgb3JpZyBjYW52YXMgdG8gZmlsbCB0aGUgdGhlIHRhcmdldCBmcmFtZVxuICAgIC8vIChvcHBvc2l0ZSBvZiBcImNvbnRhaW5cIilcbiAgICBjYW52YXNTY2FsZSA9IE1hdGgubWF4KHdSYXRpbywgaFJhdGlvKTtcbiAgfVxuXG4gIHggPSBjZmcueCA/PyBvcmlnWDtcbiAgeSA9IGNmZy55ID8/IG9yaWdZO1xuXG4gIC8vIGlmIHdlIHN3aXRjaCB0byBcImNvbnRlbnRcIiBjb29yZHMsIHdlIG5lZWQgdG8gb2Zmc2V0IGNmZy1zdXBwbGllZFxuICAvLyBjb29yZHMgYnkgdGhlIHgveSBvZiBjb250ZW50IGJvdW5kaW5nIGJveFxuICBpZiAoY2ZnLm9yaWdpbiA9PT0gXCJjb250ZW50XCIpIHtcbiAgICBpZiAoY2ZnLnggIT0gbnVsbCkge1xuICAgICAgeCArPSBvcmlnWDtcbiAgICB9XG4gICAgaWYgKGNmZy55ICE9IG51bGwpIHtcbiAgICAgIHkgKz0gb3JpZ1k7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2VudGVyaW5nIHRoZSBjb250ZW50IHRvIHRoZSBmcmFtZS5cbiAgLy8gV2UgZGl2aWRlIHdpZHRoL2hlaWdodCBieSBjYW52YXNTY2FsZSBzbyB0aGF0IHdlIGNhbGN1bGF0ZSBpbiB0aGUgb3JpZ2luYWxcbiAgLy8gYXNwZWN0IHJhdGlvIGRpbWVuc2lvbnMuXG4gIGlmIChjZmcucG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcbiAgICBpZiAoY2ZnLnggPT0gbnVsbCkge1xuICAgICAgeCAtPSB3aWR0aCAvIGNhbnZhc1NjYWxlIC8gMiAtIG9yaWdXaWR0aCAvIDI7XG4gICAgfVxuICAgIGlmIChjZmcueSA9PSBudWxsKSB7XG4gICAgICB5IC09IGhlaWdodCAvIGNhbnZhc1NjYWxlIC8gMiAtIG9yaWdIZWlnaHQgLyAyO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNhbnZhcyA9IGNmZy5jcmVhdGVDYW52YXNcbiAgICA/IGNmZy5jcmVhdGVDYW52YXMoKVxuICAgIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAvLyBzY2FsZSB0aGUgd2hvbGUgZnJhbWUgYnkgY2ZnLnNjYWxlIChvbiB0b3Agb2Ygd2hhdGV2ZXIgY2FudmFzU2NhbGUgd2VcbiAgLy8gY2FsY3VsYXRlZCBhYm92ZSlcbiAgY2FudmFzU2NhbGUgKj0gY2ZnLnNjYWxlO1xuICB3aWR0aCAqPSBjZmcuc2NhbGU7XG4gIGhlaWdodCAqPSBjZmcuc2NhbGU7XG5cbiAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgY29uc3QgeyBpbWFnZUNhY2hlIH0gPSBhd2FpdCB1cGRhdGVJbWFnZUNhY2hlKHtcbiAgICBpbWFnZUNhY2hlOiBuZXcgTWFwKCksXG4gICAgZmlsZUlkczogZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKGVsZW1lbnRzKS5tYXAoXG4gICAgICAoZWxlbWVudCkgPT4gZWxlbWVudC5maWxlSWQsXG4gICAgKSxcbiAgICBmaWxlczogZmlsZXMgfHwge30sXG4gIH0pO1xuXG4gIHJlbmRlclNjZW5lKHtcbiAgICBlbGVtZW50cyxcbiAgICBhcHBTdGF0ZTogeyAuLi5hcHBTdGF0ZSwgd2lkdGgsIGhlaWdodCwgb2Zmc2V0TGVmdDogMCwgb2Zmc2V0VG9wOiAwIH0sXG4gICAgcmM6IHJvdWdoLmNhbnZhcyhjYW52YXMpLFxuICAgIGNhbnZhcyxcbiAgICByZW5kZXJDb25maWc6IHtcbiAgICAgIGNhbnZhc0JhY2tncm91bmRDb2xvcjpcbiAgICAgICAgY2ZnLmNhbnZhc0JhY2tncm91bmRDb2xvciA9PT0gZmFsc2VcbiAgICAgICAgICA/IC8vIG51bGwgaW5kaWNhdGVzIHRyYW5zcGFyZW50IGJhY2tncm91bmRcbiAgICAgICAgICAgIG51bGxcbiAgICAgICAgICA6IGNmZy5jYW52YXNCYWNrZ3JvdW5kQ29sb3IgfHxcbiAgICAgICAgICAgIGFwcFN0YXRlLnZpZXdCYWNrZ3JvdW5kQ29sb3IgfHxcbiAgICAgICAgICAgIERFRkFVTFRfQkFDS0dST1VORF9DT0xPUixcbiAgICAgIHNjcm9sbFg6IC14ICsgY2ZnLnBhZGRpbmcsXG4gICAgICBzY3JvbGxZOiAteSArIGNmZy5wYWRkaW5nLFxuICAgICAgY2FudmFzU2NhbGUsXG4gICAgICB6b29tOiB7IHZhbHVlOiBERUZBVUxUX1pPT01fVkFMVUUgfSxcbiAgICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkczoge30sXG4gICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiBmYWxzZSxcbiAgICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHt9LFxuICAgICAgcmVtb3RlUG9pbnRlclVzZXJTdGF0ZXM6IHt9LFxuICAgICAgdGhlbWU6IGNmZy50aGVtZSB8fCBUSEVNRS5MSUdIVCxcbiAgICAgIGltYWdlQ2FjaGUsXG4gICAgICByZW5kZXJTY3JvbGxiYXJzOiBmYWxzZSxcbiAgICAgIHJlbmRlclNlbGVjdGlvbjogZmFsc2UsXG4gICAgICByZW5kZXJHcmlkOiBmYWxzZSxcbiAgICAgIGlzRXhwb3J0aW5nOiB0cnVlLFxuICAgIH0sXG4gIH0pO1xuXG4gIHJldHVybiBjYW52YXM7XG59O1xuXG5leHBvcnQgY29uc3QgZXhwb3J0VG9TdmcgPSBhc3luYyAoXG4gIGVsZW1lbnRzOiByZWFkb25seSBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnRbXSxcbiAgYXBwU3RhdGU6IHtcbiAgICBleHBvcnRCYWNrZ3JvdW5kOiBib29sZWFuO1xuICAgIGV4cG9ydFBhZGRpbmc/OiBudW1iZXI7XG4gICAgZXhwb3J0U2NhbGU/OiBudW1iZXI7XG4gICAgdmlld0JhY2tncm91bmRDb2xvcjogc3RyaW5nO1xuICAgIGV4cG9ydFdpdGhEYXJrTW9kZT86IGJvb2xlYW47XG4gICAgZXhwb3J0RW1iZWRTY2VuZT86IGJvb2xlYW47XG4gIH0sXG4gIGZpbGVzOiBCaW5hcnlGaWxlcyB8IG51bGwsXG4gIG9wdHM/OiB7XG4gICAgc2VyaWFsaXplQXNKU09OPzogKCkgPT4gc3RyaW5nO1xuICB9LFxuKTogUHJvbWlzZTxTVkdTVkdFbGVtZW50PiA9PiB7XG4gIGNvbnN0IHtcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICAgIGV4cG9ydFNjYWxlID0gMSxcbiAgICBleHBvcnRFbWJlZFNjZW5lLFxuICB9ID0gYXBwU3RhdGU7XG4gIGxldCBtZXRhZGF0YSA9IFwiXCI7XG4gIGlmIChleHBvcnRFbWJlZFNjZW5lKSB7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoLyogd2VicGFja0NodW5rTmFtZTogXCJpbWFnZVwiICovIFwiLi4vLi4vc3JjL2RhdGEvaW1hZ2VcIilcbiAgICAgICkuZW5jb2RlU3ZnTWV0YWRhdGEoe1xuICAgICAgICB0ZXh0OiBvcHRzPy5zZXJpYWxpemVBc0pTT05cbiAgICAgICAgICA/IG9wdHM/LnNlcmlhbGl6ZUFzSlNPTj8uKClcbiAgICAgICAgICA6IHNlcmlhbGl6ZUFzSlNPTihlbGVtZW50cywgYXBwU3RhdGUsIGZpbGVzIHx8IHt9LCBcImxvY2FsXCIpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgfVxuICB9XG4gIGNvbnN0IFttaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpO1xuXG4gIC8vIGluaXRpYWxpemUgU1ZHIHJvb3RcbiAgY29uc3Qgc3ZnUm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIFwic3ZnXCIpO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcInZlcnNpb25cIiwgXCIxLjFcIik7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwieG1sbnNcIiwgU1ZHX05TKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJ2aWV3Qm94XCIsIGAwIDAgJHt3aWR0aH0gJHtoZWlnaHR9YCk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgYCR7d2lkdGggKiBleHBvcnRTY2FsZX1gKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgYCR7aGVpZ2h0ICogZXhwb3J0U2NhbGV9YCk7XG4gIGlmIChhcHBTdGF0ZS5leHBvcnRXaXRoRGFya01vZGUpIHtcbiAgICBzdmdSb290LnNldEF0dHJpYnV0ZShcImZpbHRlclwiLCBUSEVNRV9GSUxURVIpO1xuICB9XG5cbiAgbGV0IGFzc2V0UGF0aCA9IFwiaHR0cHM6Ly9leGNhbGlkcmF3LmNvbS9cIjtcblxuICAvLyBBc3NldCBwYXRoIG5lZWRzIHRvIGJlIGRldGVybWluZWQgb25seSB3aGVuIHVzaW5nIHBhY2thZ2VcbiAgaWYgKHByb2Nlc3MuZW52LklTX0VYQ0FMSURSQVdfTlBNX1BBQ0tBR0UpIHtcbiAgICBhc3NldFBhdGggPVxuICAgICAgd2luZG93LkVYQ0FMSURSQVdfQVNTRVRfUEFUSCB8fFxuICAgICAgYGh0dHBzOi8vdW5wa2cuY29tLyR7cHJvY2Vzcy5lbnYuUEtHX05BTUV9QCR7cHJvY2Vzcy5lbnYuUEtHX1ZFUlNJT059YDtcblxuICAgIGlmIChhc3NldFBhdGg/LnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgICBhc3NldFBhdGggPSBhc3NldFBhdGgucmVwbGFjZShcIi9cIiwgYCR7d2luZG93LmxvY2F0aW9uLm9yaWdpbn0vYCk7XG4gICAgfVxuICAgIGFzc2V0UGF0aCA9IGAke2Fzc2V0UGF0aH0vZGlzdC9leGNhbGlkcmF3LWFzc2V0cy9gO1xuICB9XG4gIHN2Z1Jvb3QuaW5uZXJIVE1MID0gYFxuICAke1NWR19FWFBPUlRfVEFHfVxuICAke21ldGFkYXRhfVxuICA8ZGVmcz5cbiAgICA8c3R5bGUgY2xhc3M9XCJzdHlsZS1mb250c1wiPlxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIlZpcmdpbFwiO1xuICAgICAgICBzcmM6IHVybChcImh0dHBzOi8vZXhjYWxpZHJhdy5jb20vVmlyZ2lsLndvZmYyXCIpO1xuICAgICAgfVxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIkNhc2NhZGlhXCI7XG4gICAgICAgIHNyYzogdXJsKFwiaHR0cHM6Ly9leGNhbGlkcmF3LmNvbS9DYXNjYWRpYS53b2ZmMlwiKTtcbiAgICAgIH1cbiAgICA8L3N0eWxlPlxuICA8L2RlZnM+XG4gIGA7XG4gIC8vIHJlbmRlciBiYWNrZ3JvdW5kIHJlY3RcbiAgaWYgKGFwcFN0YXRlLmV4cG9ydEJhY2tncm91bmQgJiYgdmlld0JhY2tncm91bmRDb2xvcikge1xuICAgIGNvbnN0IHJlY3QgPSBzdmdSb290Lm93bmVyRG9jdW1lbnQhLmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIFwicmVjdFwiKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcInhcIiwgXCIwXCIpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwieVwiLCBcIjBcIik7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCBgJHt3aWR0aH1gKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBgJHtoZWlnaHR9YCk7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHZpZXdCYWNrZ3JvdW5kQ29sb3IpO1xuICAgIHN2Z1Jvb3QuYXBwZW5kQ2hpbGQocmVjdCk7XG4gIH1cblxuICBjb25zdCByc3ZnID0gcm91Z2guc3ZnKHN2Z1Jvb3QpO1xuICByZW5kZXJTY2VuZVRvU3ZnKGVsZW1lbnRzLCByc3ZnLCBzdmdSb290LCBmaWxlcyB8fCB7fSwge1xuICAgIG9mZnNldFg6IC1taW5YICsgZXhwb3J0UGFkZGluZyxcbiAgICBvZmZzZXRZOiAtbWluWSArIGV4cG9ydFBhZGRpbmcsXG4gICAgZXhwb3J0V2l0aERhcmtNb2RlOiBhcHBTdGF0ZS5leHBvcnRXaXRoRGFya01vZGUsXG4gIH0pO1xuXG4gIHJldHVybiBzdmdSb290O1xufTtcblxuLy8gY2FsY3VsYXRlIHNtYWxsZXN0IGFyZWEgdG8gZml0IHRoZSBjb250ZW50cyBpblxuY29uc3QgZ2V0Q2FudmFzU2l6ZSA9IChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBleHBvcnRQYWRkaW5nOiBudW1iZXIsXG4pOiBbbWluWDogbnVtYmVyLCBtaW5ZOiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyXSA9PiB7XG4gIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhlbGVtZW50cyk7XG4gIGNvbnN0IHdpZHRoID0gZGlzdGFuY2UobWluWCwgbWF4WCkgKyBleHBvcnRQYWRkaW5nICogMjtcbiAgY29uc3QgaGVpZ2h0ID0gZGlzdGFuY2UobWluWSwgbWF4WSkgKyBleHBvcnRQYWRkaW5nICsgZXhwb3J0UGFkZGluZztcblxuICByZXR1cm4gW21pblgsIG1pblksIHdpZHRoLCBoZWlnaHRdO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEV4cG9ydFNpemUgPSAoXG4gIGVsZW1lbnRzOiByZWFkb25seSBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnRbXSxcbiAgcGFkZGluZzogbnVtYmVyLFxuICBzY2FsZTogbnVtYmVyLFxuKTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IFssICwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBwYWRkaW5nKS5tYXAoXG4gICAgKGRpbWVuc2lvbikgPT4gTWF0aC50cnVuYyhkaW1lbnNpb24gKiBzY2FsZSksXG4gICk7XG5cbiAgcmV0dXJuIFt3aWR0aCwgaGVpZ2h0XTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../scene/export.ts\n");
4389
4389
 
4390
4390
  /***/ }),
4391
4391