@excalidraw/excalidraw 0.12.0-3d9d398 → 0.12.0-45b5922

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.
@@ -2029,7 +2029,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2029
2029
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2030
2030
 
2031
2031
  "use strict";
2032
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nvar _a, _b;\nconst trackEvent = typeof process !== \"undefined\" &&\n ((_a = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-3d9d398\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.REACT_APP_GOOGLE_ANALYTICS_ID) &&\n typeof window !== \"undefined\" &&\n window.gtag\n ? (category, action, label, value) => {\n try {\n window.gtag(\"event\", action, {\n event_category: category,\n event_label: label,\n value,\n });\n }\n catch (error) {\n console.error(\"error logging to ga\", error);\n }\n }\n : typeof process !== \"undefined\" && ((_b = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-3d9d398\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _b === void 0 ? void 0 : _b.JEST_WORKER_ID)\n ? (category, action, label, value) => { }\n : (category, action, label, value) => {\n // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vYW5hbHl0aWNzLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQU8sTUFBTSxVQUFVLEdBQ3JCLE9BQU8sT0FBTyxLQUFLLFdBQVc7S0FDOUIsaTRCQUFXLDBDQUFFLDZCQUE2QjtJQUMxQyxPQUFPLE1BQU0sS0FBSyxXQUFXO0lBQzdCLE1BQU0sQ0FBQyxJQUFJO0lBQ1QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFO1FBQ25FLElBQUk7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7Z0JBQzNCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzdDO0lBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxPQUFPLE9BQU8sS0FBSyxXQUFXLEtBQUksaTRCQUFXLDBDQUFFLGNBQWM7UUFDL0QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFLEdBQUUsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FBQyxRQUFnQixFQUFFLE1BQWMsRUFBRSxLQUFjLEVBQUUsS0FBYyxFQUFFLEVBQUU7WUFDbkUsMkNBQTJDO1lBQzNDLGtFQUFrRTtRQUNwRSxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vYW5hbHl0aWNzLnRzPzVmMGMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHRyYWNrRXZlbnQgPVxuICB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICBwcm9jZXNzLmVudj8uUkVBQ1RfQVBQX0dPT0dMRV9BTkFMWVRJQ1NfSUQgJiZcbiAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICB3aW5kb3cuZ3RhZ1xuICAgID8gKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB3aW5kb3cuZ3RhZyhcImV2ZW50XCIsIGFjdGlvbiwge1xuICAgICAgICAgICAgZXZlbnRfY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICAgICAgZXZlbnRfbGFiZWw6IGxhYmVsLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIGxvZ2dpbmcgdG8gZ2FcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgOiB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudj8uSkVTVF9XT1JLRVJfSURcbiAgICA/IChjYXRlZ29yeTogc3RyaW5nLCBhY3Rpb246IHN0cmluZywgbGFiZWw/OiBzdHJpbmcsIHZhbHVlPzogbnVtYmVyKSA9PiB7fVxuICAgIDogKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgLy8gVW5jb21tZW50IHRoZSBuZXh0IGxpbmUgdG8gdHJhY2sgbG9jYWxseVxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlRyYWNrIEV2ZW50XCIsIHsgY2F0ZWdvcnksIGFjdGlvbiwgbGFiZWwsIHZhbHVlIH0pO1xuICAgICAgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../analytics.ts\n");
2032
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nvar _a, _b;\nconst trackEvent = typeof process !== \"undefined\" &&\n ((_a = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-45b5922\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.REACT_APP_GOOGLE_ANALYTICS_ID) &&\n typeof window !== \"undefined\" &&\n window.gtag\n ? (category, action, label, value) => {\n try {\n window.gtag(\"event\", action, {\n event_category: category,\n event_label: label,\n value,\n });\n }\n catch (error) {\n console.error(\"error logging to ga\", error);\n }\n }\n : typeof process !== \"undefined\" && ((_b = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-45b5922\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _b === void 0 ? void 0 : _b.JEST_WORKER_ID)\n ? (category, action, label, value) => { }\n : (category, action, label, value) => {\n // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vYW5hbHl0aWNzLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQU8sTUFBTSxVQUFVLEdBQ3JCLE9BQU8sT0FBTyxLQUFLLFdBQVc7S0FDOUIsaTRCQUFXLDBDQUFFLDZCQUE2QjtJQUMxQyxPQUFPLE1BQU0sS0FBSyxXQUFXO0lBQzdCLE1BQU0sQ0FBQyxJQUFJO0lBQ1QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFO1FBQ25FLElBQUk7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7Z0JBQzNCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzdDO0lBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxPQUFPLE9BQU8sS0FBSyxXQUFXLEtBQUksaTRCQUFXLDBDQUFFLGNBQWM7UUFDL0QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFLEdBQUUsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FBQyxRQUFnQixFQUFFLE1BQWMsRUFBRSxLQUFjLEVBQUUsS0FBYyxFQUFFLEVBQUU7WUFDbkUsMkNBQTJDO1lBQzNDLGtFQUFrRTtRQUNwRSxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vYW5hbHl0aWNzLnRzPzVmMGMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHRyYWNrRXZlbnQgPVxuICB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICBwcm9jZXNzLmVudj8uUkVBQ1RfQVBQX0dPT0dMRV9BTkFMWVRJQ1NfSUQgJiZcbiAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICB3aW5kb3cuZ3RhZ1xuICAgID8gKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB3aW5kb3cuZ3RhZyhcImV2ZW50XCIsIGFjdGlvbiwge1xuICAgICAgICAgICAgZXZlbnRfY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICAgICAgZXZlbnRfbGFiZWw6IGxhYmVsLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIGxvZ2dpbmcgdG8gZ2FcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgOiB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudj8uSkVTVF9XT1JLRVJfSURcbiAgICA/IChjYXRlZ29yeTogc3RyaW5nLCBhY3Rpb246IHN0cmluZywgbGFiZWw/OiBzdHJpbmcsIHZhbHVlPzogbnVtYmVyKSA9PiB7fVxuICAgIDogKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgLy8gVW5jb21tZW50IHRoZSBuZXh0IGxpbmUgdG8gdHJhY2sgbG9jYWxseVxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlRyYWNrIEV2ZW50XCIsIHsgY2F0ZWdvcnksIGFjdGlvbiwgbGFiZWwsIHZhbHVlIH0pO1xuICAgICAgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../analytics.ts\n");
2033
2033
 
2034
2034
  /***/ }),
2035
2035
 
@@ -2117,7 +2117,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2117
2117
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2118
2118
 
2119
2119
  "use strict";
2120
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer)\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_46__ = __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\");\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\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\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 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.contextMenuOpen = false;\n this.lastScenePointer = null;\n this.focusContainer = () => {\n var _a;\n if (this.props.autoFocus) {\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n }\n };\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\n var _a, _b, _c, _d, _e, _f;\n // Since context menu closes when action triggered so setting to false\n this.contextMenuOpen = false;\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) {\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 let theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.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 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.theme !== \"undefined\") {\n theme = this.props.theme;\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 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 });\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.onFontLoaded = () => {\n this.scene.getElementsIncludingDeleted().forEach((element) => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.onSceneUpdated();\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.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);\n scene.appState = Object.assign(Object.assign({}, scene.appState), { \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 isLibraryOpen: ((_b = initialData === null || initialData === void 0 ? void 0 : initialData.appState) === null || _b === void 0 ? void 0 : _b.isLibraryOpen) || this.state.isLibraryOpen, 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 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 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.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 (!_keys__WEBPACK_IMPORTED_MODULE_26__.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 (_keys__WEBPACK_IMPORTED_MODULE_26__.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 // #686\n const target = document.activeElement;\n const isExcalidrawActive = (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);\n if (!isExcalidrawActive) {\n return;\n }\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\n if (\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\n // thus these checks don't make sense\n 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);\n if (!file && data.text) {\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) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true,\n },\n });\n }\n else if (data.elements) {\n this.addElementsFromPasteOrLibrary({\n elements: data.elements,\n files: data.files || null,\n position: \"cursor\",\n });\n }\n else if (data.text) {\n this.addTextFromPaste(data.text);\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 groupIdMap = new Map();\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\n const oldIdToDuplicatedId = new Map();\n const newElements = elements.map((element) => {\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY,\n });\n oldIdToDuplicatedId.set(element.id, newElement.id);\n return newElement;\n });\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\n const nextElements = [\n ...this.scene.getElementsIncludingDeleted(),\n ...newElements,\n ];\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n this.scene.replaceAllElements(nextElements);\n this.history.resumeRecording();\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: this.state.isLibraryOpen && this.device.canDeviceFitSidebar\n ? this.state.isLibraryMenuDocked\n : false, 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 // Collaboration\n this.setAppState = (obj) => {\n this.setState(obj);\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.scrollToContent = (target = this.scene.getNonDeletedElements()) => {\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\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 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 // 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 showHelpDialog: true,\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 (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\n const nextState = !this.state.isLibraryOpen;\n this.setState({ isLibraryOpen: nextState });\n // track only openings\n if (nextState) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"library\", \"toggleLibrary (open)\", `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\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 const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state, true);\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 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 if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\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(selectedElements[0], this.scene),\n });\n }\n }\n else {\n const selectedElement = selectedElements[0];\n this.startTextEditing({\n sceneX: selectedElement.x + selectedElement.width / 2,\n sceneY: selectedElement.y + selectedElement.height / 2,\n shouldBind: true,\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.GRABBING);\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: \"backgroundColorPicker\" });\n event.stopPropagation();\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({ openPopup: \"strokeColorPicker\" });\n event.stopPropagation();\n }\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 (!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, shouldBind, insertAtParentCenter = true, }) => {\n var _a, _b;\n let parentCenterPosition = insertAtParentCenter &&\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\n let existingTextElement = null;\n let container = 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 ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(selectedElements[0], false)) {\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 // bind to container when shouldBind is true or\n // clicked on center of container\n if (!container &&\n !existingTextElement &&\n (shouldBind || parentCenterPosition)) {\n container = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getNonDeletedElements()\n .filter((ele) => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(ele, false) && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(ele)), sceneX, sceneY);\n }\n if (!existingTextElement && container) {\n const fontString = {\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const newHeight = Math.max(container.height, minHeight);\n const newWidth = Math.max(container.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, this.canvas, window.devicePixelRatio);\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 strokeSharpness: this.state.currentItemStrokeSharpness,\n text: \"\",\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\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: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\n groupIds: (_b = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _b !== void 0 ? _b : [],\n locked: false,\n });\n this.setState({ editingElement: element });\n if (!existingTextElement) {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n // case: creating new text not centered to parent element → offset Y\n // so that the text is centered to cursor position\n if (!parentCenterPosition) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n y: element.y - element.baseline / 2,\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 (!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 }\n return;\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 selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\n if (canBindText) {\n sceneX = selectedElement.x + selectedElement.width / 2;\n sceneY = selectedElement.y + selectedElement.height / 2;\n }\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\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 return {\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 || isPanning || isDraggingScrollBar) {\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.editingLinearElement, this.state.gridSize);\n if (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({ editingLinearElement });\n });\n }\n if (editingLinearElement.lastUncommittedPoint != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n else {\n this.setState({ suggestedBindings: [] });\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.contextMenuOpen &&\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 (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 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 // 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 this.updateGestureOnPointerDown(event);\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 // Since context menu closes on pointer down so setting to false\n this.contextMenuOpen = false;\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.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 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 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.setState({\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 if ((0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y], this.device.isMobile)) {\n return false;\n }\n pointerDownState.hit.hasHitElementInside =\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y]);\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 const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\n if (canBindText) {\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\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 strokeSharpness: this.state.currentItemLinearStrokeSharpness,\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 opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\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 strokeSharpness: this.state.currentItemLinearStrokeSharpness,\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 strokeSharpness: this.state.currentItemStrokeSharpness,\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 } });\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: [\"jpg\", \"png\", \"svg\", \"gif\"],\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 type = element ? \"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 if (element && !this.state.selectedElementIds[element.id]) {\n this.setState((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._openContextMenu({ top, left }, type);\n });\n }\n else {\n this._openContextMenu({ top, left }, type);\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 /** @private use this.handleCanvasContextMenu */\n this._openContextMenu = ({ left, top, }, type) => {\n if (this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n this.contextMenuOpen = true;\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowUnbinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowBinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const separator = \"separator\";\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const options = [];\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng);\n }\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg);\n }\n if (type === \"element\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText.contextItemPredicate(elements, this.state) &&\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n }\n if (type === \"canvas\") {\n const viewModeOptions = [\n ...options,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: viewModeOptions,\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile &&\n navigator.clipboard && {\n trackEvent: false,\n name: \"paste\",\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && navigator.clipboard && separator,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n selectedElements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText,\n ((_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) ||\n (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0)) &&\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll,\n separator,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n }\n else if (type === \"element\") {\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCut,\n this.device.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy,\n this.device.isMobile &&\n navigator.clipboard && {\n name: \"paste\",\n trackEvent: false,\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && separator,\n ...options,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles,\n separator,\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup,\n mayBeAllowUnbinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText,\n mayBeAllowBinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText,\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup,\n (maybeGroupAction || maybeUngroupAction) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary,\n 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 separator,\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal,\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical,\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink.contextItemPredicate(elements, this.state) && _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLock,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\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 = 10;\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.setState((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.setState(({ 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.setState(({ 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, isLibraryMenuDocked: false });\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_46__.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 };\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.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, _b;\n const selectedElement = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const { onCollabButtonClick, renderTopRightUI, renderFooter, 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--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)(ExcalidrawContainerContext.Provider, Object.assign({ value: this.excalidrawContainerValue }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(DeviceContext.Provider, Object.assign({ value: this.device }, { children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], { canvas: this.canvas, appState: this.state, files: this.files, setAppState: this.setAppState, actionManager: this.actionManager, elements: this.scene.getNonDeletedElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onPenModeToggle: this.togglePenMode, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null,\n }), langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, renderCustomStats: renderCustomStats, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\n this.state.zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\n this.props.UIOptions.canvasActions.theme, libraryReturnUrl: this.props.libraryReturnUrl, UIOptions: this.props.UIOptions, focusContainer: this.focusContainer, library: this.library, id: this.id, onImageAction: this.onImageAction }), (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 && this.state.showHyperlinkPopup && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.Hyperlink, { element: selectedElement[0], appState: this.state, 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 })), (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.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 });\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 clearTimeout(touchTimeout);\n touchTimeout = 0;\n }\n removeEventListeners() {\n var _a, _b, _c, _d, _e;\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 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 (_e = this.detachIsMobileMqHandler) === null || _e === void 0 ? void 0 : _e.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.onFontLoaded);\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.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.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 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 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 (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__.renderScene)(renderingElements, this.state, this.state.selectionElement, window.devicePixelRatio, this.rc, this.canvas, {\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n viewBackgroundColor: 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 }, ({ 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 }, THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true);\n if (!THROTTLE_NEXT_RENDER) {\n THROTTLE_NEXT_RENDER = true;\n }\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);\n }\n }\n static resetTapTwice() {\n didTapTwice = false;\n }\n addTextFromPaste(text) {\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\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 roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\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 this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({ selectedElementIds: { [element.id]: true } });\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 if (!element) {\n return;\n }\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\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 if (hoverPointIndex >= 0) {\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 if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { hoverPointIndex }),\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 hasHitElementInside: false,\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, _b, _c, _d;\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 const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(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 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 if ((hasHitASelectedElement ||\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\n // this allows for box-selecting points when clicking inside the\n // line's bounding box\n (!this.state.editingLinearElement || !event.shiftKey) &&\n // box-selecting without shift when editing line, not clicking on a line\n (!this.state.editingLinearElement ||\n ((_a = this.state.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !==\n ((_b = pointerDownState.hit.element) === null || _b === void 0 ? void 0 : _b.id) ||\n pointerDownState.hit.hasHitElementInside) &&\n (!this.state.selectedLinearElement ||\n ((_c = this.state.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.elementId) !==\n ((_d = pointerDownState.hit.element) === null || _d === void 0 ? void 0 : _d.id) ||\n pointerDownState.hit.hasHitElementInside)) {\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 if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\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, { points: [...points, [dx, dy]] });\n }\n else if (points.length > 1) {\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.setState({\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.setState({\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;\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 // 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 !pointerDownState.hit.hasHitElementInside)) {\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 (!pointerDownState.boxSelection.hasOccurred &&\n (((_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 !pointerDownState.hit.hasHitElementInside)) {\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: linearElementEditor,\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 selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\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 }\n else {\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 = this.state.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n : this.state.selectedLinearElement }), this.scene.getNonDeletedElements())));\n });\n }\n }\n if (!this.state.selectedLinearElement &&\n !this.state.editingLinearElement &&\n !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 // Deselect selected elements\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\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, canvas, scale) {\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getElementsIncludingDeleted()\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\n if (elementClickedInside) {\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\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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Q0FBQyxJQUFLLEVBQWtCLENBQUM7SUFFM0MsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7UUFDaEMsUUFBUSxFQUFFO1lBQ1IsWUFBWSxFQUFFLElBQUk7WUFDbEIsR0FBRzs7Z0JBQ0QsT0FBTyxVQUFJLENBQUMsR0FBRywwQ0FBRSxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztZQUN2RCxDQUFDO1lBQ0QsR0FBRyxDQUFDLFFBQTZCOztnQkFDL0IsT0FBTyxVQUFJLENBQUMsR0FBRywwQ0FBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdEQsQ0FBQztTQUNGO0tBQ0YsQ0FBQyxDQUFDO0NBQ0o7QUFDRCxpRUFBZSxHQUFHLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vY29tcG9uZW50cy9BcHAudHN4PzAwNzAiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHVzZUNvbnRleHQgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IGZsdXNoU3luYyB9IGZyb20gXCJyZWFjdC1kb21cIjtcbmltcG9ydCB7IFJvdWdoQ2FudmFzIH0gZnJvbSBcInJvdWdoanMvYmluL2NhbnZhc1wiO1xuaW1wb3J0IHJvdWdoIGZyb20gXCJyb3VnaGpzL2Jpbi9yb3VnaFwiO1xuaW1wb3J0IGNsc3ggZnJvbSBcImNsc3hcIjtcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gXCJuYW5vaWRcIjtcblxuaW1wb3J0IHtcbiAgYWN0aW9uQWRkVG9MaWJyYXJ5LFxuICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gIGFjdGlvbkJyaW5nVG9Gcm9udCxcbiAgYWN0aW9uQ29weSxcbiAgYWN0aW9uQ29weUFzUG5nLFxuICBhY3Rpb25Db3B5QXNTdmcsXG4gIGNvcHlUZXh0LFxuICBhY3Rpb25Db3B5U3R5bGVzLFxuICBhY3Rpb25DdXQsXG4gIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICBhY3Rpb25EdXBsaWNhdGVTZWxlY3Rpb24sXG4gIGFjdGlvbkZpbmFsaXplLFxuICBhY3Rpb25GbGlwSG9yaXpvbnRhbCxcbiAgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICBhY3Rpb25Hcm91cCxcbiAgYWN0aW9uUGFzdGVTdHlsZXMsXG4gIGFjdGlvblNlbGVjdEFsbCxcbiAgYWN0aW9uU2VuZEJhY2t3YXJkLFxuICBhY3Rpb25TZW5kVG9CYWNrLFxuICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gIGFjdGlvblVuYmluZFRleHQsXG4gIGFjdGlvbkJpbmRUZXh0LFxuICBhY3Rpb25Vbmdyb3VwLFxuICBhY3Rpb25MaW5rLFxuICBhY3Rpb25Ub2dnbGVMb2NrLFxufSBmcm9tIFwiLi4vYWN0aW9uc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVkb0FjdGlvbiwgY3JlYXRlVW5kb0FjdGlvbiB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvbkhpc3RvcnlcIjtcbmltcG9ydCB7IEFjdGlvbk1hbmFnZXIgfSBmcm9tIFwiLi4vYWN0aW9ucy9tYW5hZ2VyXCI7XG5pbXBvcnQgeyBhY3Rpb25zIH0gZnJvbSBcIi4uL2FjdGlvbnMvcmVnaXN0ZXJcIjtcbmltcG9ydCB7IEFjdGlvblJlc3VsdCB9IGZyb20gXCIuLi9hY3Rpb25zL3R5cGVzXCI7XG5pbXBvcnQgeyB0cmFja0V2ZW50IH0gZnJvbSBcIi4uL2FuYWx5dGljc1wiO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdEFwcFN0YXRlLCBpc0VyYXNlckFjdGl2ZSB9IGZyb20gXCIuLi9hcHBTdGF0ZVwiO1xuaW1wb3J0IHtcbiAgcGFyc2VDbGlwYm9hcmQsXG4gIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iLFxuICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0LFxufSBmcm9tIFwiLi4vY2xpcGJvYXJkXCI7XG5pbXBvcnQge1xuICBBUFBfTkFNRSxcbiAgQ1VSU09SX1RZUEUsXG4gIERFRkFVTFRfTUFYX0lNQUdFX1dJRFRIX09SX0hFSUdIVCxcbiAgREVGQVVMVF9VSV9PUFRJT05TLFxuICBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICBEUkFHR0lOR19USFJFU0hPTEQsXG4gIEVMRU1FTlRfUkVBRFlfVE9fRVJBU0VfT1BBQ0lUWSxcbiAgRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5ULFxuICBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVOVixcbiAgRVZFTlQsXG4gIEdSSURfU0laRSxcbiAgSU1BR0VfUkVOREVSX1RJTUVPVVQsXG4gIExJTkVfQ09ORklSTV9USFJFU0hPTEQsXG4gIE1BWF9BTExPV0VEX0ZJTEVfQllURVMsXG4gIE1JTUVfVFlQRVMsXG4gIE1RX01BWF9IRUlHSFRfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfUE9SVFJBSVQsXG4gIE1RX1JJR0hUX1NJREVCQVJfTUlOX1dJRFRILFxuICBNUV9TTV9NQVhfV0lEVEgsXG4gIFBPSU5URVJfQlVUVE9OLFxuICBTQ1JPTExfVElNRU9VVCxcbiAgVEFQX1RXSUNFX1RJTUVPVVQsXG4gIFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xELFxuICBUSEVNRSxcbiAgVE9VQ0hfQ1RYX01FTlVfVElNRU9VVCxcbiAgVkVSVElDQUxfQUxJR04sXG59IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGxvYWRGcm9tQmxvYiB9IGZyb20gXCIuLi9kYXRhXCI7XG5pbXBvcnQgTGlicmFyeSwgeyBkaXN0cmlidXRlTGlicmFyeUl0ZW1zT25TcXVhcmVHcmlkIH0gZnJvbSBcIi4uL2RhdGEvbGlicmFyeVwiO1xuaW1wb3J0IHsgcmVzdG9yZSwgcmVzdG9yZUVsZW1lbnRzIH0gZnJvbSBcIi4uL2RhdGEvcmVzdG9yZVwiO1xuaW1wb3J0IHtcbiAgZHJhZ05ld0VsZW1lbnQsXG4gIGRyYWdTZWxlY3RlZEVsZW1lbnRzLFxuICBkdXBsaWNhdGVFbGVtZW50LFxuICBnZXRDb21tb25Cb3VuZHMsXG4gIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCxcbiAgZ2V0RHJhZ09mZnNldFhZLFxuICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gIGdldE5vcm1hbGl6ZWREaW1lbnNpb25zLFxuICBnZXRSZXNpemVBcnJvd0RpcmVjdGlvbixcbiAgZ2V0UmVzaXplT2Zmc2V0WFksXG4gIGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZSxcbiAgZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMsXG4gIGhpdFRlc3QsXG4gIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudCxcbiAgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQsXG4gIGlzTm9uRGVsZXRlZEVsZW1lbnQsXG4gIGlzVGV4dEVsZW1lbnQsXG4gIG5ld0VsZW1lbnQsXG4gIG5ld0xpbmVhckVsZW1lbnQsXG4gIG5ld1RleHRFbGVtZW50LFxuICBuZXdJbWFnZUVsZW1lbnQsXG4gIHRleHRXeXNpd3lnLFxuICB0cmFuc2Zvcm1FbGVtZW50cyxcbiAgdXBkYXRlVGV4dEVsZW1lbnQsXG59IGZyb20gXCIuLi9lbGVtZW50XCI7XG5pbXBvcnQge1xuICBiaW5kT3JVbmJpbmRMaW5lYXJFbGVtZW50LFxuICBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzLFxuICBmaXhCaW5kaW5nc0FmdGVyRGVsZXRpb24sXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcsXG4gIGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyxcbiAgaXNCaW5kaW5nRW5hYmxlZCxcbiAgaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kLFxuICBtYXliZUJpbmRMaW5lYXJFbGVtZW50LFxuICBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50LFxuICB1bmJpbmRMaW5lYXJFbGVtZW50cyxcbiAgdXBkYXRlQm91bmRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvYmluZGluZ1wiO1xuaW1wb3J0IHsgTGluZWFyRWxlbWVudEVkaXRvciB9IGZyb20gXCIuLi9lbGVtZW50L2xpbmVhckVsZW1lbnRFZGl0b3JcIjtcbmltcG9ydCB7IG11dGF0ZUVsZW1lbnQsIG5ld0VsZW1lbnRXaXRoIH0gZnJvbSBcIi4uL2VsZW1lbnQvbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHsgZGVlcENvcHlFbGVtZW50LCBuZXdGcmVlRHJhd0VsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudC9uZXdFbGVtZW50XCI7XG5pbXBvcnQge1xuICBoYXNCb3VuZFRleHRFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50VHlwZSxcbiAgaXNCb3VuZFRvQ29udGFpbmVyLFxuICBpc0ltYWdlRWxlbWVudCxcbiAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50LFxuICBpc0xpbmVhckVsZW1lbnRUeXBlLFxuICBpc1RleHRCaW5kYWJsZUNvbnRhaW5lcixcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZUNoZWNrc1wiO1xuaW1wb3J0IHtcbiAgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdHZW5lcmljRWxlbWVudCxcbiAgRXhjYWxpZHJhd0xpbmVhckVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgTm9uRGVsZXRlZCxcbiAgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICBGaWxlSWQsXG4gIE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd1RleHRDb250YWluZXIsXG59IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDZW50ZXIsIGdldERpc3RhbmNlIH0gZnJvbSBcIi4uL2dlc3R1cmVcIjtcbmltcG9ydCB7XG4gIGVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudCxcbiAgZ2V0RWxlbWVudHNJbkdyb3VwLFxuICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50LFxuICBnZXRTZWxlY3RlZEdyb3VwSWRzLFxuICBpc0VsZW1lbnRJbkdyb3VwLFxuICBpc1NlbGVjdGVkVmlhR3JvdXAsXG4gIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMsXG59IGZyb20gXCIuLi9ncm91cHNcIjtcbmltcG9ydCBIaXN0b3J5IGZyb20gXCIuLi9oaXN0b3J5XCI7XG5pbXBvcnQgeyBkZWZhdWx0TGFuZywgZ2V0TGFuZ3VhZ2UsIGxhbmd1YWdlcywgc2V0TGFuZ3VhZ2UsIHQgfSBmcm9tIFwiLi4vaTE4blwiO1xuaW1wb3J0IHtcbiAgQ09ERVMsXG4gIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIsXG4gIHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8sXG4gIHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlLFxuICBpc0Fycm93S2V5LFxuICBLRVlTLFxuICBpc0FuZHJvaWQsXG59IGZyb20gXCIuLi9rZXlzXCI7XG5pbXBvcnQgeyBkaXN0YW5jZTJkLCBnZXRHcmlkUG9pbnQsIGlzUGF0aEFMb29wIH0gZnJvbSBcIi4uL21hdGhcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lIH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlclNjZW5lXCI7XG5pbXBvcnQgeyBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50IH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlckVsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZVNjcm9sbENlbnRlcixcbiAgZ2V0VGV4dEJpbmRhYmxlQ29udGFpbmVyQXRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNBdFBvc2l0aW9uLFxuICBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbixcbiAgZ2V0Tm9ybWFsaXplZFpvb20sXG4gIGdldFNlbGVjdGVkRWxlbWVudHMsXG4gIGhhc0JhY2tncm91bmQsXG4gIGlzT3ZlclNjcm9sbEJhcnMsXG4gIGlzU29tZUVsZW1lbnRTZWxlY3RlZCxcbn0gZnJvbSBcIi4uL3NjZW5lXCI7XG5pbXBvcnQgU2NlbmUgZnJvbSBcIi4uL3NjZW5lL1NjZW5lXCI7XG5pbXBvcnQgeyBSZW5kZXJDb25maWcsIFNjcm9sbEJhcnMgfSBmcm9tIFwiLi4vc2NlbmUvdHlwZXNcIjtcbmltcG9ydCB7IGdldFN0YXRlRm9yWm9vbSB9IGZyb20gXCIuLi9zY2VuZS96b29tXCI7XG5pbXBvcnQgeyBmaW5kU2hhcGVCeUtleSwgU0hBUEVTIH0gZnJvbSBcIi4uL3NoYXBlc1wiO1xuaW1wb3J0IHtcbiAgQXBwQ2xhc3NQcm9wZXJ0aWVzLFxuICBBcHBQcm9wcyxcbiAgQXBwU3RhdGUsXG4gIEJpbmFyeUZpbGVEYXRhLFxuICBEYXRhVVJMLFxuICBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSxcbiAgQmluYXJ5RmlsZXMsXG4gIEdlc3R1cmUsXG4gIEdlc3R1cmVFdmVudCxcbiAgTGlicmFyeUl0ZW1zLFxuICBQb2ludGVyRG93blN0YXRlLFxuICBTY2VuZURhdGEsXG4gIERldmljZSxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBkZWJvdW5jZSxcbiAgZGlzdGFuY2UsXG4gIGdldEZvbnRTdHJpbmcsXG4gIGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLFxuICBpc0lucHV0TGlrZSxcbiAgaXNUb29sSWNvbixcbiAgaXNXcml0YWJsZUVsZW1lbnQsXG4gIHJlc2V0Q3Vyc29yLFxuICByZXNvbHZhYmxlUHJvbWlzZSxcbiAgc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzLFxuICBzZXRDdXJzb3IsXG4gIHNldEN1cnNvckZvclNoYXBlLFxuICB0dXBsZVRvQ29vcnMsXG4gIHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyxcbiAgd2l0aEJhdGNoZWRVcGRhdGVzLFxuICB3cmFwRXZlbnQsXG4gIHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCxcbiAgdXBkYXRlT2JqZWN0LFxuICBzZXRFcmFzZXJDdXJzb3IsXG4gIHVwZGF0ZUFjdGl2ZVRvb2wsXG59IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IENvbnRleHRNZW51LCB7IENvbnRleHRNZW51T3B0aW9uIH0gZnJvbSBcIi4vQ29udGV4dE1lbnVcIjtcbmltcG9ydCBMYXllclVJIGZyb20gXCIuL0xheWVyVUlcIjtcbmltcG9ydCB7IFRvYXN0IH0gZnJvbSBcIi4vVG9hc3RcIjtcbmltcG9ydCB7IGFjdGlvblRvZ2dsZVZpZXdNb2RlIH0gZnJvbSBcIi4uL2FjdGlvbnMvYWN0aW9uVG9nZ2xlVmlld01vZGVcIjtcbmltcG9ydCB7XG4gIGRhdGFVUkxUb0ZpbGUsXG4gIGdlbmVyYXRlSWRGcm9tRmlsZSxcbiAgZ2V0RGF0YVVSTCxcbiAgZ2V0RmlsZUZyb21FdmVudCxcbiAgaXNTdXBwb3J0ZWRJbWFnZUZpbGUsXG4gIGxvYWRTY2VuZU9yTGlicmFyeUZyb21CbG9iLFxuICBub3JtYWxpemVGaWxlLFxuICBwYXJzZUxpYnJhcnlKU09OLFxuICByZXNpemVJbWFnZUZpbGUsXG4gIFNWR1N0cmluZ1RvRmlsZSxcbn0gZnJvbSBcIi4uL2RhdGEvYmxvYlwiO1xuaW1wb3J0IHtcbiAgZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzLFxuICBsb2FkSFRNTEltYWdlRWxlbWVudCxcbiAgbm9ybWFsaXplU1ZHLFxuICB1cGRhdGVJbWFnZUNhY2hlIGFzIF91cGRhdGVJbWFnZUNhY2hlLFxufSBmcm9tIFwiLi4vZWxlbWVudC9pbWFnZVwiO1xuaW1wb3J0IHRocm90dGxlIGZyb20gXCJsb2Rhc2gudGhyb3R0bGVcIjtcbmltcG9ydCB7IGZpbGVPcGVuLCBGaWxlU3lzdGVtSGFuZGxlIH0gZnJvbSBcIi4uL2RhdGEvZmlsZXN5c3RlbVwiO1xuaW1wb3J0IHtcbiAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0QXBwcm94TWluTGluZUhlaWdodCxcbiAgZ2V0QXBwcm94TWluTGluZVdpZHRoLFxuICBnZXRCb3VuZFRleHRFbGVtZW50LFxufSBmcm9tIFwiLi4vZWxlbWVudC90ZXh0RWxlbWVudFwiO1xuaW1wb3J0IHsgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3ggfSBmcm9tIFwiLi4vZWxlbWVudC9jb2xsaXNpb25cIjtcbmltcG9ydCB7XG4gIG5vcm1hbGl6ZUxpbmssXG4gIHNob3dIeXBlcmxpbmtUb29sdGlwLFxuICBoaWRlSHlwZXJsaW5rVG9vbGlwLFxuICBIeXBlcmxpbmssXG4gIGlzUG9pbnRIaXR0aW5nTGlua0ljb24sXG4gIGlzTG9jYWxMaW5rLFxufSBmcm9tIFwiLi4vZWxlbWVudC9IeXBlcmxpbmtcIjtcblxuY29uc3QgZGV2aWNlQ29udGV4dEluaXRpYWxWYWx1ZSA9IHtcbiAgaXNTbVNjcmVlbjogZmFsc2UsXG4gIGlzTW9iaWxlOiBmYWxzZSxcbiAgaXNUb3VjaFNjcmVlbjogZmFsc2UsXG4gIGNhbkRldmljZUZpdFNpZGViYXI6IGZhbHNlLFxufTtcbmNvbnN0IERldmljZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PERldmljZT4oZGV2aWNlQ29udGV4dEluaXRpYWxWYWx1ZSk7XG5leHBvcnQgY29uc3QgdXNlRGV2aWNlID0gKCkgPT4gdXNlQ29udGV4dDxEZXZpY2U+KERldmljZUNvbnRleHQpO1xuY29uc3QgRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PHtcbiAgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG4gIGlkOiBzdHJpbmcgfCBudWxsO1xufT4oeyBjb250YWluZXI6IG51bGwsIGlkOiBudWxsIH0pO1xuZXhwb3J0IGNvbnN0IHVzZUV4Y2FsaWRyYXdDb250YWluZXIgPSAoKSA9PlxuICB1c2VDb250ZXh0KEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0KTtcblxubGV0IGRpZFRhcFR3aWNlOiBib29sZWFuID0gZmFsc2U7XG5sZXQgdGFwcGVkVHdpY2VUaW1lciA9IDA7XG5sZXQgY3Vyc29yWCA9IDA7XG5sZXQgY3Vyc29yWSA9IDA7XG5sZXQgaXNIb2xkaW5nU3BhY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBpc1Bhbm5pbmc6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBpc0RyYWdnaW5nU2Nyb2xsQmFyOiBib29sZWFuID0gZmFsc2U7XG5sZXQgY3VycmVudFNjcm9sbEJhcnM6IFNjcm9sbEJhcnMgPSB7IGhvcml6b250YWw6IG51bGwsIHZlcnRpY2FsOiBudWxsIH07XG5sZXQgdG91Y2hUaW1lb3V0ID0gMDtcbmxldCBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcblxuLy8gcmVtb3ZlIHRoaXMgaGFjayB3aGVuIHdlIGNhbiBzeW5jIHJlbmRlciAmIHJlc2l6ZU9ic2VydmVyIChzdGF0ZSB1cGRhdGUpXG4vLyB0byByQUYuIFNlZSAjNTQzOVxubGV0IFRIUk9UVExFX05FWFRfUkVOREVSID0gdHJ1ZTtcblxubGV0IGxhc3RQb2ludGVyVXA6ICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbmNvbnN0IGdlc3R1cmU6IEdlc3R1cmUgPSB7XG4gIHBvaW50ZXJzOiBuZXcgTWFwKCksXG4gIGxhc3RDZW50ZXI6IG51bGwsXG4gIGluaXRpYWxEaXN0YW5jZTogbnVsbCxcbiAgaW5pdGlhbFNjYWxlOiBudWxsLFxufTtcblxuY2xhc3MgQXBwIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PEFwcFByb3BzLCBBcHBTdGF0ZT4ge1xuICBjYW52YXM6IEFwcENsYXNzUHJvcGVydGllc1tcImNhbnZhc1wiXSA9IG51bGw7XG4gIHJjOiBSb3VnaENhbnZhcyB8IG51bGwgPSBudWxsO1xuICB1bm1vdW50ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYWN0aW9uTWFuYWdlcjogQWN0aW9uTWFuYWdlcjtcbiAgZGV2aWNlOiBEZXZpY2UgPSBkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlO1xuICBkZXRhY2hJc01vYmlsZU1xSGFuZGxlcj86ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBleGNhbGlkcmF3Q29udGFpbmVyUmVmID0gUmVhY3QuY3JlYXRlUmVmPEhUTUxEaXZFbGVtZW50PigpO1xuXG4gIHB1YmxpYyBzdGF0aWMgZGVmYXVsdFByb3BzOiBQYXJ0aWFsPEFwcFByb3BzPiA9IHtcbiAgICAvLyBuZWVkZWQgZm9yIHRlc3RzIHRvIHBhc3Mgc2luY2Ugd2UgZGlyZWN0bHkgcmVuZGVyIEFwcCBpbiBtYW55IHRlc3RzXG4gICAgVUlPcHRpb25zOiBERUZBVUxUX1VJX09QVElPTlMsXG4gIH07XG5cbiAgcHVibGljIHNjZW5lOiBTY2VuZTtcbiAgcHJpdmF0ZSByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyBsaWJyYXJ5OiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJsaWJyYXJ5XCJdO1xuICBwdWJsaWMgbGlicmFyeUl0ZW1zRnJvbVN0b3JhZ2U6IExpYnJhcnlJdGVtcyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICBwcml2YXRlIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gIHByaXZhdGUgZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlOiB7XG4gICAgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG4gICAgaWQ6IHN0cmluZztcbiAgfTtcblxuICBwdWJsaWMgZmlsZXM6IEJpbmFyeUZpbGVzID0ge307XG4gIHB1YmxpYyBpbWFnZUNhY2hlOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJpbWFnZUNhY2hlXCJdID0gbmV3IE1hcCgpO1xuXG4gIGhpdExpbmtFbGVtZW50PzogTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50O1xuICBsYXN0UG9pbnRlckRvd246IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4gfCBudWxsID0gbnVsbDtcbiAgbGFzdFBvaW50ZXJVcDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxFbGVtZW50PiB8IFBvaW50ZXJFdmVudCB8IG51bGwgPSBudWxsO1xuICBjb250ZXh0TWVudU9wZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgbGFzdFNjZW5lUG9pbnRlcjogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IEFwcFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIGNvbnN0IGRlZmF1bHRBcHBTdGF0ZSA9IGdldERlZmF1bHRBcHBTdGF0ZSgpO1xuICAgIGNvbnN0IHtcbiAgICAgIGV4Y2FsaWRyYXdSZWYsXG4gICAgICB2aWV3TW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIHplbk1vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICBncmlkTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIHRoZW1lID0gZGVmYXVsdEFwcFN0YXRlLnRoZW1lLFxuICAgICAgbmFtZSA9IGRlZmF1bHRBcHBTdGF0ZS5uYW1lLFxuICAgIH0gPSBwcm9wcztcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgLi4uZGVmYXVsdEFwcFN0YXRlLFxuICAgICAgdGhlbWUsXG4gICAgICBpc0xvYWRpbmc6IHRydWUsXG4gICAgICAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSxcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgZ3JpZFNpemU6IGdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGwsXG4gICAgICBuYW1lLFxuICAgICAgd2lkdGg6IHdpbmRvdy5pbm5lcldpZHRoLFxuICAgICAgaGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlLFxuICAgICAgaXNMaWJyYXJ5TWVudURvY2tlZDogZmFsc2UsXG4gICAgfTtcblxuICAgIHRoaXMuaWQgPSBuYW5vaWQoKTtcblxuICAgIHRoaXMubGlicmFyeSA9IG5ldyBMaWJyYXJ5KHRoaXMpO1xuICAgIGlmIChleGNhbGlkcmF3UmVmKSB7XG4gICAgICBjb25zdCByZWFkeVByb21pc2UgPVxuICAgICAgICAoXCJjdXJyZW50XCIgaW4gZXhjYWxpZHJhd1JlZiAmJiBleGNhbGlkcmF3UmVmLmN1cnJlbnQ/LnJlYWR5UHJvbWlzZSkgfHxcbiAgICAgICAgcmVzb2x2YWJsZVByb21pc2U8RXhjYWxpZHJhd0ltcGVyYXRpdmVBUEk+KCk7XG5cbiAgICAgIGNvbnN0IGFwaTogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUEkgPSB7XG4gICAgICAgIHJlYWR5OiB0cnVlLFxuICAgICAgICByZWFkeVByb21pc2UsXG4gICAgICAgIHVwZGF0ZVNjZW5lOiB0aGlzLnVwZGF0ZVNjZW5lLFxuICAgICAgICB1cGRhdGVMaWJyYXJ5OiB0aGlzLmxpYnJhcnkudXBkYXRlTGlicmFyeSxcbiAgICAgICAgYWRkRmlsZXM6IHRoaXMuYWRkRmlsZXMsXG4gICAgICAgIHJlc2V0U2NlbmU6IHRoaXMucmVzZXRTY2VuZSxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQ6IHRoaXMuZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQsXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBjbGVhcjogdGhpcy5yZXNldEhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICAgIHNjcm9sbFRvQ29udGVudDogdGhpcy5zY3JvbGxUb0NvbnRlbnQsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHM6IHRoaXMuZ2V0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgZ2V0QXBwU3RhdGU6ICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAgIGdldEZpbGVzOiAoKSA9PiB0aGlzLmZpbGVzLFxuICAgICAgICByZWZyZXNoOiB0aGlzLnJlZnJlc2gsXG4gICAgICAgIHNldFRvYXN0OiB0aGlzLnNldFRvYXN0LFxuICAgICAgICBpZDogdGhpcy5pZCxcbiAgICAgICAgc2V0QWN0aXZlVG9vbDogdGhpcy5zZXRBY3RpdmVUb29sLFxuICAgICAgICBzZXRDdXJzb3I6IHRoaXMuc2V0Q3Vyc29yLFxuICAgICAgICByZXNldEN1cnNvcjogdGhpcy5yZXNldEN1cnNvcixcbiAgICAgIH0gYXMgY29uc3Q7XG4gICAgICBpZiAodHlwZW9mIGV4Y2FsaWRyYXdSZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBleGNhbGlkcmF3UmVmKGFwaSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGNhbGlkcmF3UmVmLmN1cnJlbnQgPSBhcGk7XG4gICAgICB9XG4gICAgICByZWFkeVByb21pc2UucmVzb2x2ZShhcGkpO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlID0ge1xuICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCxcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgIH07XG5cbiAgICB0aGlzLnNjZW5lID0gbmV3IFNjZW5lKCk7XG4gICAgdGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIgPSBuZXcgQWN0aW9uTWFuYWdlcihcbiAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCxcbiAgICAgICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAoKSA9PiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcyxcbiAgICApO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFsbChhY3Rpb25zKTtcblxuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVVbmRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVSZWRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJDYW52YXMoKSB7XG4gICAgY29uc3QgY2FudmFzU2NhbGUgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICB9ID0gdGhpcy5zdGF0ZTtcbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhc0RPTVdpZHRoICogY2FudmFzU2NhbGU7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY2FudmFzRE9NSGVpZ2h0ICogY2FudmFzU2NhbGU7XG4gICAgaWYgKHZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPGNhbnZhc1xuICAgICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICAgICAgY3Vyc29yOiBDVVJTT1JfVFlQRS5HUkFCLFxuICAgICAgICAgIH19XG4gICAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJVcH1cbiAgICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgPlxuICAgICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICAgIDwvY2FudmFzPlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxjYW52YXNcbiAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgIH19XG4gICAgICAgIHdpZHRoPXtjYW52YXNXaWR0aH1cbiAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgIG9uQ29udGV4dE1lbnU9e3RoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnV9XG4gICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgIG9uRG91YmxlQ2xpY2s9e3RoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2t9XG4gICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJVcH1cbiAgICAgICAgb25Qb2ludGVyQ2FuY2VsPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgIG9uVG91Y2hNb3ZlPXt0aGlzLmhhbmRsZVRvdWNoTW92ZX1cbiAgICAgID5cbiAgICAgICAge3QoXCJsYWJlbHMuZHJhd2luZ0NhbnZhc1wiKX1cbiAgICAgIDwvY2FudmFzPlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVuZGVyKCkge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IHtcbiAgICAgIG9uQ29sbGFiQnV0dG9uQ2xpY2ssXG4gICAgICByZW5kZXJUb3BSaWdodFVJLFxuICAgICAgcmVuZGVyRm9vdGVyLFxuICAgICAgcmVuZGVyQ3VzdG9tU3RhdHMsXG4gICAgfSA9IHRoaXMucHJvcHM7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdlxuICAgICAgICBjbGFzc05hbWU9e2Nsc3goXCJleGNhbGlkcmF3IGV4Y2FsaWRyYXctY29udGFpbmVyXCIsIHtcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLXZpZXctbW9kZVwiOiB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLW1vYmlsZVwiOiB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICAgICAgfSl9XG4gICAgICAgIHJlZj17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmfVxuICAgICAgICBvbkRyb3A9e3RoaXMuaGFuZGxlQXBwT25Ecm9wfVxuICAgICAgICB0YWJJbmRleD17MH1cbiAgICAgICAgb25LZXlEb3duPXtcbiAgICAgICAgICB0aGlzLnByb3BzLmhhbmRsZUtleWJvYXJkR2xvYmFsbHkgPyB1bmRlZmluZWQgOiB0aGlzLm9uS2V5RG93blxuICAgICAgICB9XG4gICAgICA+XG4gICAgICAgIDxFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlclxuICAgICAgICAgIHZhbHVlPXt0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZX1cbiAgICAgICAgPlxuICAgICAgICAgIDxEZXZpY2VDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLmRldmljZX0+XG4gICAgICAgICAgICA8TGF5ZXJVSVxuICAgICAgICAgICAgICBjYW52YXM9e3RoaXMuY2FudmFzfVxuICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgZmlsZXM9e3RoaXMuZmlsZXN9XG4gICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICBhY3Rpb25NYW5hZ2VyPXt0aGlzLmFjdGlvbk1hbmFnZXJ9XG4gICAgICAgICAgICAgIGVsZW1lbnRzPXt0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpfVxuICAgICAgICAgICAgICBvbkNvbGxhYkJ1dHRvbkNsaWNrPXtvbkNvbGxhYkJ1dHRvbkNsaWNrfVxuICAgICAgICAgICAgICBvbkxvY2tUb2dnbGU9e3RoaXMudG9nZ2xlTG9ja31cbiAgICAgICAgICAgICAgb25QZW5Nb2RlVG9nZ2xlPXt0aGlzLnRvZ2dsZVBlbk1vZGV9XG4gICAgICAgICAgICAgIG9uSW5zZXJ0RWxlbWVudHM9eyhlbGVtZW50cykgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFwiY2VudGVyXCIsXG4gICAgICAgICAgICAgICAgICBmaWxlczogbnVsbCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxhbmdDb2RlPXtnZXRMYW5ndWFnZSgpLmNvZGV9XG4gICAgICAgICAgICAgIGlzQ29sbGFib3JhdGluZz17dGhpcy5wcm9wcy5pc0NvbGxhYm9yYXRpbmd9XG4gICAgICAgICAgICAgIHJlbmRlclRvcFJpZ2h0VUk9e3JlbmRlclRvcFJpZ2h0VUl9XG4gICAgICAgICAgICAgIHJlbmRlckN1c3RvbUZvb3Rlcj17cmVuZGVyRm9vdGVyfVxuICAgICAgICAgICAgICByZW5kZXJDdXN0b21TdGF0cz17cmVuZGVyQ3VzdG9tU3RhdHN9XG4gICAgICAgICAgICAgIHNob3dFeGl0WmVuTW9kZUJ0bj17XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHM/Lnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS56ZW5Nb2RlRW5hYmxlZFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNob3dUaGVtZUJ0bj17XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHM/LnRoZW1lID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuY2FudmFzQWN0aW9ucy50aGVtZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxpYnJhcnlSZXR1cm5Vcmw9e3RoaXMucHJvcHMubGlicmFyeVJldHVyblVybH1cbiAgICAgICAgICAgICAgVUlPcHRpb25zPXt0aGlzLnByb3BzLlVJT3B0aW9uc31cbiAgICAgICAgICAgICAgZm9jdXNDb250YWluZXI9e3RoaXMuZm9jdXNDb250YWluZXJ9XG4gICAgICAgICAgICAgIGxpYnJhcnk9e3RoaXMubGlicmFyeX1cbiAgICAgICAgICAgICAgaWQ9e3RoaXMuaWR9XG4gICAgICAgICAgICAgIG9uSW1hZ2VBY3Rpb249e3RoaXMub25JbWFnZUFjdGlvbn1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImV4Y2FsaWRyYXctdGV4dEVkaXRvckNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImV4Y2FsaWRyYXctY29udGV4dE1lbnVDb250YWluZXJcIiAvPlxuICAgICAgICAgICAge3NlbGVjdGVkRWxlbWVudC5sZW5ndGggPT09IDEgJiYgdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXAgJiYgKFxuICAgICAgICAgICAgICA8SHlwZXJsaW5rXG4gICAgICAgICAgICAgICAga2V5PXtzZWxlY3RlZEVsZW1lbnRbMF0uaWR9XG4gICAgICAgICAgICAgICAgZWxlbWVudD17c2VsZWN0ZWRFbGVtZW50WzBdfVxuICAgICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgIG9uTGlua09wZW49e3RoaXMucHJvcHMub25MaW5rT3Blbn1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICB7dGhpcy5zdGF0ZS50b2FzdCAhPT0gbnVsbCAmJiAoXG4gICAgICAgICAgICAgIDxUb2FzdFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U9e3RoaXMuc3RhdGUudG9hc3QubWVzc2FnZX1cbiAgICAgICAgICAgICAgICBvbkNsb3NlPXsoKSA9PiB0aGlzLnNldFRvYXN0KG51bGwpfVxuICAgICAgICAgICAgICAgIGR1cmF0aW9uPXt0aGlzLnN0YXRlLnRvYXN0LmR1cmF0aW9ufVxuICAgICAgICAgICAgICAgIGNsb3NhYmxlPXt0aGlzLnN0YXRlLnRvYXN0LmNsb3NhYmxlfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxtYWluPnt0aGlzLnJlbmRlckNhbnZhcygpfTwvbWFpbj5cbiAgICAgICAgICA8L0RldmljZUNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgIDwvRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGZvY3VzQ29udGFpbmVyOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJmb2N1c0NvbnRhaW5lclwiXSA9ICgpID0+IHtcbiAgICBpZiAodGhpcy5wcm9wcy5hdXRvRm9jdXMpIHtcbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gIH07XG5cbiAgcHVibGljIGdldFNjZW5lRWxlbWVudHMgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBzeW5jQWN0aW9uUmVzdWx0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChhY3Rpb25SZXN1bHQ6IEFjdGlvblJlc3VsdCkgPT4ge1xuICAgICAgLy8gU2luY2UgY29udGV4dCBtZW51IGNsb3NlcyB3aGVuIGFjdGlvbiB0cmlnZ2VyZWQgc28gc2V0dGluZyB0byBmYWxzZVxuICAgICAgdGhpcy5jb250ZXh0TWVudU9wZW4gPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLnVubW91bnRlZCB8fCBhY3Rpb25SZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGVkaXRpbmdFbGVtZW50OiBBcHBTdGF0ZVtcImVkaXRpbmdFbGVtZW50XCJdIHwgbnVsbCA9IG51bGw7XG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKSB7XG4gICAgICAgIGFjdGlvblJlc3VsdC5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudD8uaWQgPT09IGVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgIT09IGVsZW1lbnQgJiZcbiAgICAgICAgICAgIGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhhY3Rpb25SZXN1bHQuZWxlbWVudHMpO1xuICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmZpbGVzKSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSBhY3Rpb25SZXN1bHQucmVwbGFjZUZpbGVzXG4gICAgICAgICAgPyBhY3Rpb25SZXN1bHQuZmlsZXNcbiAgICAgICAgICA6IHsgLi4udGhpcy5maWxlcywgLi4uYWN0aW9uUmVzdWx0LmZpbGVzIH07XG4gICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwgZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmlld01vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udmlld01vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgemVuTW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy56ZW5Nb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IGdyaWRTaXplID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uZ3JpZFNpemUgfHwgbnVsbDtcbiAgICAgICAgbGV0IHRoZW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udGhlbWUgfHwgVEhFTUUuTElHSFQ7XG4gICAgICAgIGxldCBuYW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8ubmFtZSA/PyB0aGlzLnN0YXRlLm5hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHplbk1vZGVFbmFibGVkID0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBncmlkU2l6ZSA9IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy50aGVtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHRoZW1lID0gdGhpcy5wcm9wcy50aGVtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5uYW1lICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgbmFtZSA9IHRoaXMucHJvcHMubmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgLy8gdXNpbmcgT2JqZWN0LmFzc2lnbiBpbnN0ZWFkIG9mIHNwcmVhZCB0byBmb29sIFRTIDQuMi4yKyBpbnRvXG4gICAgICAgICAgICAvLyByZWdhcmRpbmcgdGhlIHJlc3VsdGluZyB0eXBlIGFzIG5vdCBjb250YWluaW5nIHVuZGVmaW5lZFxuICAgICAgICAgICAgLy8gKHdoaWNoIHRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbiB3aWxsIG5ldmVyIGNvbnRhaW4pXG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwge30sIHtcbiAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgfHwgYWN0aW9uUmVzdWx0LmFwcFN0YXRlPy5lZGl0aW5nRWxlbWVudCB8fCBudWxsLFxuICAgICAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgICAgICAgICBncmlkU2l6ZSxcbiAgICAgICAgICAgICAgdGhlbWUsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGlmIChhY3Rpb25SZXN1bHQuc3luY0hpc3RvcnkpIHtcbiAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnNldEN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIC8vIExpZmVjeWNsZVxuXG4gIHByaXZhdGUgb25CbHVyID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBwcml2YXRlIG9uVW5sb2FkID0gKCkgPT4ge1xuICAgIHRoaXMub25CbHVyKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRXZlbnQ6IEV2ZW50TGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuXG4gIHByaXZhdGUgb25Gb250TG9hZGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm9uU2NlbmVVcGRhdGVkKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEhpc3RvcnkgPSAoKSA9PiB7XG4gICAgdGhpcy5oaXN0b3J5LmNsZWFyKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlc2V0cyBzY2VuZSAmIGhpc3RvcnkuXG4gICAqICEgRG8gbm90IHVzZSB0byBjbGVhciBzY2VuZSB1c2VyIGFjdGlvbiAhXG4gICAqL1xuICBwcml2YXRlIHJlc2V0U2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKG9wdHM/OiB7IHJlc2V0TG9hZGluZ1N0YXRlOiBib29sZWFuIH0pID0+IHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXREZWZhdWx0QXBwU3RhdGUoKSxcbiAgICAgICAgaXNMb2FkaW5nOiBvcHRzPy5yZXNldExvYWRpbmdTdGF0ZSA/IGZhbHNlIDogc3RhdGUuaXNMb2FkaW5nLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGluaXRpYWxpemVTY2VuZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAoXCJsYXVuY2hRdWV1ZVwiIGluIHdpbmRvdyAmJiBcIkxhdW5jaFBhcmFtc1wiIGluIHdpbmRvdykge1xuICAgICAgKHdpbmRvdyBhcyBhbnkpLmxhdW5jaFF1ZXVlLnNldENvbnN1bWVyKFxuICAgICAgICBhc3luYyAobGF1bmNoUGFyYW1zOiB7IGZpbGVzOiBhbnlbXSB9KSA9PiB7XG4gICAgICAgICAgaWYgKCFsYXVuY2hQYXJhbXMuZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpbGVIYW5kbGUgPSBsYXVuY2hQYXJhbXMuZmlsZXNbMF07XG4gICAgICAgICAgY29uc3QgYmxvYjogQmxvYiA9IGF3YWl0IGZpbGVIYW5kbGUuZ2V0RmlsZSgpO1xuICAgICAgICAgIHRoaXMubG9hZEZpbGVUb0NhbnZhcyhcbiAgICAgICAgICAgIG5ldyBGaWxlKFtibG9iXSwgYmxvYi5uYW1lIHx8IFwiXCIsIHsgdHlwZTogYmxvYi50eXBlIH0pLFxuICAgICAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgIH1cbiAgICBsZXQgaW5pdGlhbERhdGEgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBpbml0aWFsRGF0YSA9IChhd2FpdCB0aGlzLnByb3BzLmluaXRpYWxEYXRhKSB8fCBudWxsO1xuICAgICAgaWYgKGluaXRpYWxEYXRhPy5saWJyYXJ5SXRlbXMpIHtcbiAgICAgICAgdGhpcy5saWJyYXJ5XG4gICAgICAgICAgLnVwZGF0ZUxpYnJhcnkoe1xuICAgICAgICAgICAgbGlicmFyeUl0ZW1zOiBpbml0aWFsRGF0YS5saWJyYXJ5SXRlbXMsXG4gICAgICAgICAgICBtZXJnZTogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgaW5pdGlhbERhdGEgPSB7XG4gICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgZXJyb3JNZXNzYWdlOlxuICAgICAgICAgICAgZXJyb3IubWVzc2FnZSB8fFxuICAgICAgICAgICAgXCJFbmNvdW50ZXJlZCBhbiBlcnJvciBkdXJpbmcgaW1wb3J0aW5nIG9yIHJlc3RvcmluZyBzY2VuZSBkYXRhXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBzY2VuZSA9IHJlc3RvcmUoaW5pdGlhbERhdGEsIG51bGwsIG51bGwpO1xuICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAvLyB3ZSdyZSBmYWxsaW5nIGJhY2sgdG8gY3VycmVudCAocHJlLWluaXQpIHN0YXRlIHdoZW4gZGVjaWRpbmdcbiAgICAgIC8vIHdoZXRoZXIgdG8gb3BlbiB0aGUgbGlicmFyeSwgdG8gaGFuZGxlIGEgY2FzZSB3aGVyZSB3ZVxuICAgICAgLy8gdXBkYXRlIHRoZSBzdGF0ZSBvdXRzaWRlIG9mIGluaXRpYWxEYXRhIChlLmcuIHdoZW4gbG9hZGluZyB0aGUgYXBwXG4gICAgICAvLyB3aXRoIGEgbGlicmFyeSBpbnN0YWxsIGxpbmssIHdoaWNoIHNob3VsZCBhdXRvLW9wZW4gdGhlIGxpYnJhcnkpXG4gICAgICBpc0xpYnJhcnlPcGVuOlxuICAgICAgICBpbml0aWFsRGF0YT8uYXBwU3RhdGU/LmlzTGlicmFyeU9wZW4gfHwgdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuLFxuICAgICAgYWN0aXZlVG9vbDpcbiAgICAgICAgc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCJcbiAgICAgICAgICA/IHsgLi4uc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbCwgdHlwZTogXCJzZWxlY3Rpb25cIiB9XG4gICAgICAgICAgOiBzY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgIHRvYXN0OiB0aGlzLnN0YXRlLnRvYXN0LFxuICAgIH07XG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxUb0NvbnRlbnQpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICAgIHNjZW5lLmVsZW1lbnRzLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAgICAgd2lkdGg6IHRoaXMuc3RhdGUud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuc3RhdGUuaGVpZ2h0LFxuICAgICAgICAgICAgb2Zmc2V0VG9wOiB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgICAgIG9mZnNldExlZnQ6IHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgIC4uLnNjZW5lLFxuICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVmcmVzaERldmljZVN0YXRlID0gKGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQpID0+IHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBzaWRlYmFyQnJlYWtwb2ludCA9XG4gICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPSBudWxsXG4gICAgICAgID8gdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICAgICAgOiBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSDtcbiAgICB0aGlzLmRldmljZSA9IHVwZGF0ZU9iamVjdCh0aGlzLmRldmljZSwge1xuICAgICAgaXNTbVNjcmVlbjogd2lkdGggPCBNUV9TTV9NQVhfV0lEVEgsXG4gICAgICBpc01vYmlsZTpcbiAgICAgICAgd2lkdGggPCBNUV9NQVhfV0lEVEhfUE9SVFJBSVQgfHxcbiAgICAgICAgKGhlaWdodCA8IE1RX01BWF9IRUlHSFRfTEFORFNDQVBFICYmIHdpZHRoIDwgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSksXG4gICAgICBjYW5EZXZpY2VGaXRTaWRlYmFyOiB3aWR0aCA+IHNpZGViYXJCcmVha3BvaW50LFxuICAgIH0pO1xuICB9O1xuXG4gIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICB0aGlzLnVubW91bnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlLmNvbnRhaW5lciA9XG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcblxuICAgIGlmIChcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVFxuICAgICkge1xuICAgICAgY29uc3Qgc2V0U3RhdGUgPSB0aGlzLnNldFN0YXRlLmJpbmQodGhpcyk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh3aW5kb3cuaCwge1xuICAgICAgICBzdGF0ZToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXRlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHNldFN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiAoLi4uYXJnczogUGFyYW1ldGVyczx0eXBlb2Ygc2V0U3RhdGU+KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRTdGF0ZSguLi5hcmdzKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBhcHA6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6IHRoaXMsXG4gICAgICAgIH0sXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6IHRoaXMuaGlzdG9yeSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuc2NlbmUuYWRkQ2FsbGJhY2sodGhpcy5vblNjZW5lVXBkYXRlZCk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuXG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KSB7XG4gICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQgJiZcbiAgICAgIC8vIGJvdW5kaW5nIHJlY3RzIGRvbid0IHdvcmsgaW4gdGVzdHMgc28gdXBkYXRpbmdcbiAgICAgIC8vIHRoZSBzdGF0ZSBvbiBpbml0IHdvdWxkIHJlc3VsdCBpbiBtYWtpbmcgdGhlIHRlc3QgZW52aXJvIHJ1blxuICAgICAgLy8gaW4gbW9iaWxlIGJyZWFrcG9pbnQgKDAgd2lkdGgvaGVpZ2h0KSwgbWFraW5nIGV2ZXJ5dGhpbmcgZmFpbFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwidGVzdFwiXG4gICAgKSB7XG4gICAgICB0aGlzLnJlZnJlc2hEZXZpY2VTdGF0ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCk7XG4gICAgfVxuXG4gICAgaWYgKFwiUmVzaXplT2JzZXJ2ZXJcIiBpbiB3aW5kb3cgJiYgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSBmYWxzZTtcbiAgICAgICAgLy8gcmVjb21wdXRlIGRldmljZSBkaW1lbnNpb25zIHN0YXRlXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnJlZnJlc2hEZXZpY2VTdGF0ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEpO1xuICAgICAgICAvLyByZWZyZXNoIG9mZnNldHNcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCgpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5vYnNlcnZlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKSB7XG4gICAgICBjb25zdCBtZFNjcmVlblF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9QT1JUUkFJVH1weCksIChtYXgtaGVpZ2h0OiAke01RX01BWF9IRUlHSFRfTEFORFNDQVBFfXB4KSBhbmQgKG1heC13aWR0aDogJHtNUV9NQVhfV0lEVEhfTEFORFNDQVBFfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3Qgc21TY3JlZW5RdWVyeSA9IHdpbmRvdy5tYXRjaE1lZGlhKFxuICAgICAgICBgKG1heC13aWR0aDogJHtNUV9TTV9NQVhfV0lEVEh9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBjYW5EZXZpY2VGaXRTaWRlYmFyTWVkaWFRdWVyeSA9IHdpbmRvdy5tYXRjaE1lZGlhKFxuICAgICAgICBgKG1pbi13aWR0aDogJHtcbiAgICAgICAgICAvLyBOT1RFIHRoaXMgd29uJ3QgdXBkYXRlIGlmIGEgZGlmZmVyZW50IGJyZWFrcG9pbnQgaXMgc3VwcGxpZWRcbiAgICAgICAgICAvLyBhZnRlciBtb3VudFxuICAgICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50ICE9IG51bGxcbiAgICAgICAgICAgID8gdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICAgICAgICAgIDogTVFfUklHSFRfU0lERUJBUl9NSU5fV0lEVEhcbiAgICAgICAgfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB0aGlzLmRldmljZSA9IHVwZGF0ZU9iamVjdCh0aGlzLmRldmljZSwge1xuICAgICAgICAgIGlzU21TY3JlZW46IHNtU2NyZWVuUXVlcnkubWF0Y2hlcyxcbiAgICAgICAgICBpc01vYmlsZTogbWRTY3JlZW5RdWVyeS5tYXRjaGVzLFxuICAgICAgICAgIGNhbkRldmljZUZpdFNpZGViYXI6IGNhbkRldmljZUZpdFNpZGViYXJNZWRpYVF1ZXJ5Lm1hdGNoZXMsXG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIG1kU2NyZWVuUXVlcnkuYWRkTGlzdGVuZXIoaGFuZGxlcik7XG4gICAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyID0gKCkgPT5cbiAgICAgICAgbWRTY3JlZW5RdWVyeS5yZW1vdmVMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc2xpY2UoMSkpO1xuXG4gICAgaWYgKHNlYXJjaFBhcmFtcy5oYXMoXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpKSB7XG4gICAgICAvLyBPYnRhaW4gYSBmaWxlIHRoYXQgd2FzIHNoYXJlZCB2aWEgdGhlIFdlYiBTaGFyZSBUYXJnZXQgQVBJLlxuICAgICAgdGhpcy5yZXN0b3JlRmlsZUZyb21TaGFyZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURPTVJlY3QodGhpcy5pbml0aWFsaXplU2NlbmUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICB0aGlzLmZpbGVzID0ge307XG4gICAgdGhpcy5pbWFnZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMudW5tb3VudGVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zY2VuZS5kZXN0cm95KCk7XG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgfVxuXG4gIHByaXZhdGUgb25SZXNpemUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIHRoaXMuc2NlbmVcbiAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgLmZvckVhY2goKGVsZW1lbnQpID0+IGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9KTtcblxuICBwcml2YXRlIHJlbW92ZUV2ZW50TGlzdGVuZXJzKCkge1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuV0hFRUwsXG4gICAgICB0aGlzLm9uV2hlZWwsXG4gICAgKTtcbiAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyPy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuU0NST0xMLFxuICAgICAgdGhpcy5vblNjcm9sbCxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgdGhpcy5vbktleURvd24sIGZhbHNlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuTU9VU0VfTU9WRSxcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uLFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCB0aGlzLm9uS2V5VXApO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlJFU0laRSwgdGhpcy5vblJlc2l6ZSwgZmFsc2UpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlVOTE9BRCwgdGhpcy5vblVubG9hZCwgZmFsc2UpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRoaXMub25CbHVyLCBmYWxzZSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUkFHX09WRVIsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUk9QLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgdGhpcy5kZXRhY2hJc01vYmlsZU1xSGFuZGxlcj8uKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEV2ZW50TGlzdGVuZXJzKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRoaXMucmVtb3ZlUG9pbnRlcik7IC8vICMzNTUzXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DT1BZLCB0aGlzLm9uQ29weSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5XSEVFTCxcbiAgICAgIHRoaXMub25XaGVlbCxcbiAgICAgIHsgcGFzc2l2ZTogZmFsc2UgfSxcbiAgICApO1xuXG4gICAgaWYgKHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSkge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIH1cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCB0aGlzLm9uS2V5VXAsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuTU9VU0VfTU9WRSxcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uLFxuICAgICk7XG4gICAgLy8gcmVyZW5kZXIgdGV4dCBlbGVtZW50cyBvbiBmb250IGxvYWQgdG8gZml4ICM2MzcgJiYgIzE1NTNcbiAgICBkb2N1bWVudC5mb250cz8uYWRkRXZlbnRMaXN0ZW5lcj8uKFwibG9hZGluZ2RvbmVcIiwgdGhpcy5vbkZvbnRMb2FkZWQpO1xuICAgIC8vIFNhZmFyaS1vbmx5IGRlc2t0b3AgcGluY2ggem9vbVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX1NUQVJULFxuICAgICAgdGhpcy5vbkdlc3R1cmVTdGFydCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0NIQU5HRSxcbiAgICAgIHRoaXMub25HZXN0dXJlQ2hhbmdlIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfRU5ELFxuICAgICAgdGhpcy5vbkdlc3R1cmVFbmQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIGlmICh0aGlzLnByb3BzLmRldGVjdFNjcm9sbCkge1xuICAgICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lciA9IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyKFxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICApO1xuICAgICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgICApO1xuICAgIH1cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5SRVNJWkUsIHRoaXMub25SZXNpemUsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5VTkxPQUQsIHRoaXMub25VbmxvYWQsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0aGlzLm9uQmx1ciwgZmFsc2UpO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuRFJBR19PVkVSLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuRFJPUCxcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgfVxuXG4gIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IEFwcFByb3BzLCBwcmV2U3RhdGU6IEFwcFN0YXRlKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQgJiZcbiAgICAgIHByZXZQcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnQgIT09XG4gICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50XG4gICAgKSB7XG4gICAgICB0aGlzLnJlZnJlc2hEZXZpY2VTdGF0ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLnNjcm9sbFggIT09IHRoaXMuc3RhdGUuc2Nyb2xsWCB8fFxuICAgICAgcHJldlN0YXRlLnNjcm9sbFkgIT09IHRoaXMuc3RhdGUuc2Nyb2xsWVxuICAgICkge1xuICAgICAgdGhpcy5wcm9wcz8ub25TY3JvbGxDaGFuZ2U/Lih0aGlzLnN0YXRlLnNjcm9sbFgsIHRoaXMuc3RhdGUuc2Nyb2xsWSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgT2JqZWN0LmtleXModGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMpLmxlbmd0aCAmJlxuICAgICAgaXNFcmFzZXJBY3RpdmUodGhpcy5zdGF0ZSlcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJlcmFzZXJcIiAmJlxuICAgICAgcHJldlN0YXRlLnRoZW1lICE9PSB0aGlzLnN0YXRlLnRoZW1lXG4gICAgKSB7XG4gICAgICBzZXRFcmFzZXJDdXJzb3IodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUudGhlbWUpO1xuICAgIH1cbiAgICAvLyBIaWRlIGh5cGVybGluayBwb3B1cCBpZiBzaG93biB3aGVuIGVsZW1lbnQgdHlwZSBpcyBub3Qgc2VsZWN0aW9uXG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgIHRoaXMuc3RhdGUuc2hvd0h5cGVybGlua1BvcHVwXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0h5cGVybGlua1BvcHVwOiBmYWxzZSB9KTtcbiAgICB9XG4gICAgaWYgKHByZXZQcm9wcy5sYW5nQ29kZSAhPT0gdGhpcy5wcm9wcy5sYW5nQ29kZSkge1xuICAgICAgdGhpcy51cGRhdGVMYW5ndWFnZSgpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpZXdNb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCB9KTtcbiAgICB9XG5cbiAgICBpZiAocHJldlN0YXRlLnZpZXdNb2RlRW5hYmxlZCAhPT0gdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB6ZW5Nb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudGhlbWUgIT09IHRoaXMucHJvcHMudGhlbWUgJiYgdGhpcy5wcm9wcy50aGVtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHRoZW1lOiB0aGlzLnByb3BzLnRoZW1lIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGdyaWRTaXplOiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9wcy5uYW1lICYmIHByZXZQcm9wcy5uYW1lICE9PSB0aGlzLnByb3BzLm5hbWUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBuYW1lOiB0aGlzLnByb3BzLm5hbWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY2xhc3NMaXN0LnRvZ2dsZShcbiAgICAgIFwidGhlbWUtLWRhcmtcIixcbiAgICAgIHRoaXMuc3RhdGUudGhlbWUgPT09IFwiZGFya1wiLFxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdXG4gICAgKSB7XG4gICAgICAvLyBkZWZlciBzbyB0aGF0IHRoZSBjb21taXRUb0hpc3RvcnkgZmxhZyBpc24ndCByZXNldCB2aWEgY3VycmVudCB1cGRhdGVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW3RoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF1cbiAgICApIHtcbiAgICAgIC8vIFRvIG1ha2Ugc3VyZSBgc2VsZWN0ZWRMaW5lYXJFbGVtZW50YCBpcyBpbiBzeW5jIHdpdGggYHNlbGVjdGVkRWxlbWVudElkc2AsIGhvd2V2ZXIgdGhpcyBzaG91bGRuJ3QgYmUgbmVlZGVkIG9uY2VcbiAgICAgIC8vIHdlIGhhdmUgYSBzaW5nbGUgQVBJIHRvIHVwZGF0ZSBgc2VsZWN0ZWRFbGVtZW50SWRzYFxuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkTGluZWFyRWxlbWVudDogbnVsbCB9KTtcbiAgICB9XG5cbiAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gcHJldlN0YXRlO1xuICAgIGlmIChcbiAgICAgIHByZXZTdGF0ZS5hY3RpdmVUb29sICE9PSB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wgJiZcbiAgICAgIG11bHRpRWxlbWVudCAhPSBudWxsICYmXG4gICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpICYmXG4gICAgICBpc0JpbmRpbmdFbGVtZW50KG11bHRpRWxlbWVudCwgZmFsc2UpXG4gICAgKSB7XG4gICAgICBtYXliZUJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgIHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50QXRJbmRleEdsb2JhbENvb3JkaW5hdGVzKFxuICAgICAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICAgICAgLTEsXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY3Vyc29yQnV0dG9uOiB7XG4gICAgICBbaWQ6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICB9ID0ge307XG4gICAgY29uc3QgcG9pbnRlclZpZXdwb3J0Q29vcmRzOiBSZW5kZXJDb25maWdbXCJyZW1vdGVQb2ludGVyVmlld3BvcnRDb29yZHNcIl0gPVxuICAgICAge307XG4gICAgY29uc3QgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzOiBSZW5kZXJDb25maWdbXCJyZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNcIl0gPVxuICAgICAge307XG4gICAgY29uc3QgcG9pbnRlclVzZXJuYW1lczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgY29uc3QgcG9pbnRlclVzZXJTdGF0ZXM6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIHRoaXMuc3RhdGUuY29sbGFib3JhdG9ycy5mb3JFYWNoKCh1c2VyLCBzb2NrZXRJZCkgPT4ge1xuICAgICAgaWYgKHVzZXIuc2VsZWN0ZWRFbGVtZW50SWRzKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgT2JqZWN0LmtleXModXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgaWYgKCEoaWQgaW4gcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzKSkge1xuICAgICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzW2lkXSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdLnB1c2goc29ja2V0SWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXIucG9pbnRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodXNlci51c2VybmFtZSkge1xuICAgICAgICBwb2ludGVyVXNlcm5hbWVzW3NvY2tldElkXSA9IHVzZXIudXNlcm5hbWU7XG4gICAgICB9XG4gICAgICBpZiAodXNlci51c2VyU3RhdGUpIHtcbiAgICAgICAgcG9pbnRlclVzZXJTdGF0ZXNbc29ja2V0SWRdID0gdXNlci51c2VyU3RhdGU7XG4gICAgICB9XG4gICAgICBwb2ludGVyVmlld3BvcnRDb29yZHNbc29ja2V0SWRdID0gc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzKFxuICAgICAgICB7XG4gICAgICAgICAgc2NlbmVYOiB1c2VyLnBvaW50ZXIueCxcbiAgICAgICAgICBzY2VuZVk6IHVzZXIucG9pbnRlci55LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGN1cnNvckJ1dHRvbltzb2NrZXRJZF0gPSB1c2VyLmJ1dHRvbjtcbiAgICB9KTtcbiAgICBjb25zdCByZW5kZXJpbmdFbGVtZW50cyA9IHRoaXMuc2NlbmVcbiAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgLmZpbHRlcigoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoaXNJbWFnZUVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAvLyBub3QgcGxhY2VkIG9uIGNhbnZhcyB5ZXQgKGJ1dCBpbiBlbGVtZW50cyBhcnJheSlcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkID09PSBlbGVtZW50LmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGRvbid0IHJlbmRlciB0ZXh0IGVsZW1lbnQgdGhhdCdzIGJlaW5nIGN1cnJlbnRseSBlZGl0ZWQgKGl0J3NcbiAgICAgICAgLy8gcmVuZGVyZWQgb24gcmVtb3RlIG9ubHkpXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50LnR5cGUgIT09IFwidGV4dFwiIHx8XG4gICAgICAgICAgZWxlbWVudC5pZCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC5pZFxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICByZW5kZXJTY2VuZShcbiAgICAgIHJlbmRlcmluZ0VsZW1lbnRzLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIHRoaXMuc3RhdGUuc2VsZWN0aW9uRWxlbWVudCxcbiAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgdGhpcy5yYyEsXG4gICAgICB0aGlzLmNhbnZhcyEsXG4gICAgICB7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZLFxuICAgICAgICB2aWV3QmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLnZpZXdCYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIHpvb206IHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgcmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzOiBwb2ludGVyVmlld3BvcnRDb29yZHMsXG4gICAgICAgIHJlbW90ZVBvaW50ZXJCdXR0b246IGN1cnNvckJ1dHRvbixcbiAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICByZW1vdGVQb2ludGVyVXNlcm5hbWVzOiBwb2ludGVyVXNlcm5hbWVzLFxuICAgICAgICByZW1vdGVQb2ludGVyVXNlclN0YXRlczogcG9pbnRlclVzZXJTdGF0ZXMsXG4gICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdGhpcy5zdGF0ZS5zaG91bGRDYWNoZUlnbm9yZVpvb20sXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICAgIGlzRXhwb3J0aW5nOiBmYWxzZSxcbiAgICAgICAgcmVuZGVyU2Nyb2xsYmFyczogIXRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgfSxcbiAgICAgICh7IGF0TGVhc3RPbmVWaXNpYmxlRWxlbWVudCwgc2Nyb2xsQmFycyB9KSA9PiB7XG4gICAgICAgIGlmIChzY3JvbGxCYXJzKSB7XG4gICAgICAgICAgY3VycmVudFNjcm9sbEJhcnMgPSBzY3JvbGxCYXJzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjcm9sbGVkT3V0c2lkZSA9XG4gICAgICAgICAgLy8gaGlkZSB3aGVuIGVkaXRpbmcgdGV4dFxuICAgICAgICAgIGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgICAgID8gZmFsc2VcbiAgICAgICAgICAgIDogIWF0TGVhc3RPbmVWaXNpYmxlRWxlbWVudCAmJiByZW5kZXJpbmdFbGVtZW50cy5sZW5ndGggPiAwO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zY3JvbGxlZE91dHNpZGUgIT09IHNjcm9sbGVkT3V0c2lkZSkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzY3JvbGxlZE91dHNpZGUgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNjaGVkdWxlSW1hZ2VSZWZyZXNoKCk7XG4gICAgICB9LFxuICAgICAgVEhST1RUTEVfTkVYVF9SRU5ERVIgJiYgd2luZG93LkVYQ0FMSURSQVdfVEhST1RUTEVfUkVOREVSID09PSB0cnVlLFxuICAgICk7XG5cbiAgICBpZiAoIVRIUk9UVExFX05FWFRfUkVOREVSKSB7XG4gICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5oaXN0b3J5LnJlY29yZCh0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKTtcblxuICAgIC8vIERvIG5vdCBub3RpZnkgY29uc3VtZXJzIGlmIHdlJ3JlIHN0aWxsIGxvYWRpbmcgdGhlIHNjZW5lLiBBbW9uZyBvdGhlclxuICAgIC8vIHBvdGVudGlhbCBpc3N1ZXMsIHRoaXMgZml4ZXMgYSBjYXNlIHdoZXJlIHRoZSB0YWIgaXNuJ3QgZm9jdXNlZCBkdXJpbmdcbiAgICAvLyBpbml0LCB3aGljaCB3b3VsZCB0cmlnZ2VyIG9uQ2hhbmdlIHdpdGggZW1wdHkgZWxlbWVudHMsIHdoaWNoIHdvdWxkIHRoZW5cbiAgICAvLyBvdmVycmlkZSB3aGF0ZXZlciBpcyBpbiBsb2NhbFN0b3JhZ2UgY3VycmVudGx5LlxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMucHJvcHMub25DaGFuZ2U/LihcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5maWxlcyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblNjcm9sbCA9IGRlYm91bmNlKCgpID0+IHtcbiAgICBjb25zdCB7IG9mZnNldFRvcCwgb2Zmc2V0TGVmdCB9ID0gdGhpcy5nZXRDYW52YXNPZmZzZXRzKCk7XG4gICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+IHtcbiAgICAgIGlmIChzdGF0ZS5vZmZzZXRMZWZ0ID09PSBvZmZzZXRMZWZ0ICYmIHN0YXRlLm9mZnNldFRvcCA9PT0gb2Zmc2V0VG9wKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH07XG4gICAgfSk7XG4gIH0sIFNDUk9MTF9USU1FT1VUKTtcblxuICAvLyBDb3B5L3Bhc3RlXG5cbiAgcHJpdmF0ZSBvbkN1dCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jdXRBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICBwcml2YXRlIG9uQ29weSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb3B5QWxsKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBjdXRBbGwgPSAoKSA9PiB7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uQ3V0LCBcImtleWJvYXJkXCIpO1xuICB9O1xuXG4gIHByaXZhdGUgY29weUFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25Db3B5LCBcImtleWJvYXJkXCIpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIHJlc2V0VGFwVHdpY2UoKSB7XG4gICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25UYXBTdGFydCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIC8vIGZpeCBmb3IgQXBwbGUgUGVuY2lsIFNjcmliYmxlXG4gICAgLy8gT24gQW5kcm9pZCwgcHJldmVudGluZyB0aGUgZXZlbnQgd291bGQgZGlzYWJsZSBjb250ZXh0TWVudSBvbiB0YXAtaG9sZFxuICAgIGlmICghaXNBbmRyb2lkKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIGlmICghZGlkVGFwVHdpY2UpIHtcbiAgICAgIGRpZFRhcFR3aWNlID0gdHJ1ZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICAgIHRhcHBlZFR3aWNlVGltZXIgPSB3aW5kb3cuc2V0VGltZW91dChcbiAgICAgICAgQXBwLnJlc2V0VGFwVHdpY2UsXG4gICAgICAgIFRBUF9UV0lDRV9USU1FT1VULFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gaW5zZXJ0IHRleHQgb25seSBpZiB3ZSB0YXBwZWQgdHdpY2Ugd2l0aCBhIHNpbmdsZSBmaW5nZXJcbiAgICAvLyBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSB3aWxsIGFsc28gcHJldmVudCBpbnNlcnRpbmcgdGV4dCB3aGVuIHVzZXIncyB6b29taW5nXG4gICAgaWYgKGRpZFRhcFR3aWNlICYmIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb25zdCBbdG91Y2hdID0gZXZlbnQudG91Y2hlcztcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHRoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2soe1xuICAgICAgICBjbGllbnRYOiB0b3VjaC5jbGllbnRYLFxuICAgICAgICBjbGllbnRZOiB0b3VjaC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgIH1cbiAgICBpZiAoaXNBbmRyb2lkKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvblRhcEVuZCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIHRoaXMucmVzZXRDb250ZXh0TWVudVRpbWVyKCk7XG4gICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuY2xlYXIoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBwYXN0ZUZyb21DbGlwYm9hcmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgYXN5bmMgKGV2ZW50OiBDbGlwYm9hcmRFdmVudCB8IG51bGwpID0+IHtcbiAgICAgIC8vICM2ODZcbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPVxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnModGFyZ2V0KTtcbiAgICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWxlbWVudFVuZGVyQ3Vyc29yID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChjdXJzb3JYLCBjdXJzb3JZKTtcbiAgICAgIGlmIChcbiAgICAgICAgLy8gaWYgbm8gQ2xpcGJvYXJkRXZlbnQgc3VwcGxpZWQsIGFzc3VtZSB3ZSdyZSBwYXN0aW5nIHZpYSBjb250ZXh0TWVudVxuICAgICAgICAvLyB0aHVzIHRoZXNlIGNoZWNrcyBkb24ndCBtYWtlIHNlbnNlXG4gICAgICAgIGV2ZW50ICYmXG4gICAgICAgICghKGVsZW1lbnRVbmRlckN1cnNvciBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB8fFxuICAgICAgICAgIGlzV3JpdGFibGVFbGVtZW50KHRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBtdXN0IGJlIGNhbGxlZCBpbiB0aGUgc2FtZSBmcmFtZSAodGh1cyBiZWZvcmUgYW55IGF3YWl0cykgYXMgdGhlIHBhc3RlXG4gICAgICAvLyBldmVudCBlbHNlIHNvbWUgYnJvd3NlcnMgKEZGLi4uKSB3aWxsIGNsZWFyIHRoZSBjbGlwYm9hcmREYXRhXG4gICAgICAvLyAoc29tZXRoaW5nIHNvbWV0aGluZyBzZWN1cml0eSlcbiAgICAgIGxldCBmaWxlID0gZXZlbnQ/LmNsaXBib2FyZERhdGE/LmZpbGVzWzBdO1xuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcGFyc2VDbGlwYm9hcmQoZXZlbnQpO1xuXG4gICAgICBpZiAoIWZpbGUgJiYgZGF0YS50ZXh0KSB7XG4gICAgICAgIGNvbnN0IHN0cmluZyA9IGRhdGEudGV4dC50cmltKCk7XG4gICAgICAgIGlmIChzdHJpbmcuc3RhcnRzV2l0aChcIjxzdmdcIikgJiYgc3RyaW5nLmVuZHNXaXRoKFwiPC9zdmc+XCIpKSB7XG4gICAgICAgICAgLy8gaWdub3JlIFNWRyB2YWxpZGF0aW9uL25vcm1hbGl6YXRpb24gd2hpY2ggd2lsbCBiZSBkb25lIGR1cmluZyBpbWFnZVxuICAgICAgICAgIC8vIGluaXRpYWxpemF0aW9uXG4gICAgICAgICAgZmlsZSA9IFNWR1N0cmluZ1RvRmlsZShzdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHByZWZlciBzcHJlYWRzaGVldCBkYXRhIG92ZXIgaW1hZ2UgZmlsZSAoTVMgT2ZmaWNlL0xpYnJlIE9mZmljZSlcbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSAmJiAhZGF0YS5zcHJlYWRzaGVldCkge1xuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucHJvcHMub25QYXN0ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICgoYXdhaXQgdGhpcy5wcm9wcy5vblBhc3RlKGRhdGEsIGV2ZW50KSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkYXRhLmVycm9yTWVzc2FnZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBkYXRhLmVycm9yTWVzc2FnZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5zcHJlYWRzaGVldCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBwYXN0ZURpYWxvZzoge1xuICAgICAgICAgICAgZGF0YTogZGF0YS5zcHJlYWRzaGVldCxcbiAgICAgICAgICAgIHNob3duOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkYXRhLmVsZW1lbnRzLFxuICAgICAgICAgIGZpbGVzOiBkYXRhLmZpbGVzIHx8IG51bGwsXG4gICAgICAgICAgcG9zaXRpb246IFwiY3Vyc29yXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnRleHQpIHtcbiAgICAgICAgdGhpcy5hZGRUZXh0RnJvbVBhc3RlKGRhdGEudGV4dCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGl2ZVRvb2woeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pO1xuICAgICAgZXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5ID0gKG9wdHM6IHtcbiAgICBlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXTtcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsO1xuICAgIHBvc2l0aW9uOiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0gfCBcImN1cnNvclwiIHwgXCJjZW50ZXJcIjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gcmVzdG9yZUVsZW1lbnRzKG9wdHMuZWxlbWVudHMsIG51bGwpO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhlbGVtZW50cyk7XG5cbiAgICBjb25zdCBlbGVtZW50c0NlbnRlclggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSAvIDI7XG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJZID0gZGlzdGFuY2UobWluWSwgbWF4WSkgLyAyO1xuXG4gICAgY29uc3QgY2xpZW50WCA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WFxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JYXG4gICAgICAgIDogdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgY29uc3QgY2xpZW50WSA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WVxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JZXG4gICAgICAgIDogdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3QgZHggPSB4IC0gZWxlbWVudHNDZW50ZXJYO1xuICAgIGNvbnN0IGR5ID0geSAtIGVsZW1lbnRzQ2VudGVyWTtcbiAgICBjb25zdCBncm91cElkTWFwID0gbmV3IE1hcCgpO1xuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoZHgsIGR5LCB0aGlzLnN0YXRlLmdyaWRTaXplKTtcblxuICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgbmV3RWxlbWVudHMgPSBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkdXBsaWNhdGVFbGVtZW50KFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkLFxuICAgICAgICBncm91cElkTWFwLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICB7XG4gICAgICAgICAgeDogZWxlbWVudC54ICsgZ3JpZFggLSBtaW5YLFxuICAgICAgICAgIHk6IGVsZW1lbnQueSArIGdyaWRZIC0gbWluWSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBuZXdFbGVtZW50LmlkKTtcbiAgICAgIHJldHVybiBuZXdFbGVtZW50O1xuICAgIH0pO1xuICAgIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24obmV3RWxlbWVudHMsIGVsZW1lbnRzLCBvbGRJZFRvRHVwbGljYXRlZElkKTtcbiAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgLi4ubmV3RWxlbWVudHMsXG4gICAgXTtcbiAgICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24obmV4dEVsZW1lbnRzLCBlbGVtZW50cywgb2xkSWRUb0R1cGxpY2F0ZWRJZCk7XG5cbiAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4ub3B0cy5maWxlcyB9O1xuICAgIH1cblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRFbGVtZW50cyk7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuXG4gICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgIHtcbiAgICAgICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgICAgIGlzTGlicmFyeU9wZW46XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4gJiYgdGhpcy5kZXZpY2UuY2FuRGV2aWNlRml0U2lkZWJhclxuICAgICAgICAgICAgICA/IHRoaXMuc3RhdGUuaXNMaWJyYXJ5TWVudURvY2tlZFxuICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogbmV3RWxlbWVudHMucmVkdWNlKFxuICAgICAgICAgICAgKGFjYzogUmVjb3JkPEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0sIHRydWU+LCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNCb3VuZFRvQ29udGFpbmVyKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgYWNjW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICksXG4gICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICApLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLnNldEFjdGl2ZVRvb2woeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgYWRkVGV4dEZyb21QYXN0ZSh0ZXh0OiBhbnkpIHtcbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WDogY3Vyc29yWCwgY2xpZW50WTogY3Vyc29yWSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld1RleHRFbGVtZW50KHtcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgICB0ZXh0LFxuICAgICAgZm9udFNpemU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250U2l6ZSxcbiAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgdGV4dEFsaWduOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtVGV4dEFsaWduLFxuICAgICAgdmVydGljYWxBbGlnbjogREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgfVxuXG4gIC8vIENvbGxhYm9yYXRpb25cblxuICBzZXRBcHBTdGF0ZSA9IChvYmo6IGFueSkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUob2JqKTtcbiAgfTtcblxuICByZW1vdmVQb2ludGVyID0gKGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTEVsZW1lbnQ+IHwgUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgaWYgKHRvdWNoVGltZW91dCkge1xuICAgICAgdGhpcy5yZXNldENvbnRleHRNZW51VGltZXIoKTtcbiAgICB9XG5cbiAgICBnZXN0dXJlLnBvaW50ZXJzLmRlbGV0ZShldmVudC5wb2ludGVySWQpO1xuICB9O1xuXG4gIHRvZ2dsZUxvY2sgPSAoc291cmNlOiBcImtleWJvYXJkXCIgfCBcInVpXCIgPSBcInVpXCIpID0+IHtcbiAgICBpZiAoIXRoaXMuc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgIHRyYWNrRXZlbnQoXG4gICAgICAgIFwidG9vbGJhclwiLFxuICAgICAgICBcInRvZ2dsZUxvY2tcIixcbiAgICAgICAgYCR7c291cmNlfSAoJHt0aGlzLmRldmljZS5pc01vYmlsZSA/IFwibW9iaWxlXCIgOiBcImRlc2t0b3BcIn0pYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWN0aXZlVG9vbDoge1xuICAgICAgICAgIC4uLnByZXZTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgICAgIC4uLnVwZGF0ZUFjdGl2ZVRvb2woXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcHJldlN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkXG4gICAgICAgICAgICAgID8geyB0eXBlOiBcInNlbGVjdGlvblwiIH1cbiAgICAgICAgICAgICAgOiBwcmV2U3RhdGUuYWN0aXZlVG9vbCxcbiAgICAgICAgICApLFxuICAgICAgICAgIGxvY2tlZDogIXByZXZTdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH07XG5cbiAgdG9nZ2xlUGVuTW9kZSA9ICgpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBlbk1vZGU6ICFwcmV2U3RhdGUucGVuTW9kZSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH07XG5cbiAgc2Nyb2xsVG9Db250ZW50ID0gKFxuICAgIHRhcmdldDpcbiAgICAgIHwgRXhjYWxpZHJhd0VsZW1lbnRcbiAgICAgIHwgcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXSA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICBBcnJheS5pc0FycmF5KHRhcmdldCkgPyB0YXJnZXQgOiBbdGFyZ2V0XSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICApLFxuICAgIH0pO1xuICB9O1xuXG4gIHNldFRvYXN0ID0gKFxuICAgIHRvYXN0OiB7XG4gICAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgICBjbG9zYWJsZT86IGJvb2xlYW47XG4gICAgICBkdXJhdGlvbj86IG51bWJlcjtcbiAgICB9IHwgbnVsbCxcbiAgKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHRvYXN0IH0pO1xuICB9O1xuXG4gIHJlc3RvcmVGaWxlRnJvbVNoYXJlID0gYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB3ZWJTaGFyZVRhcmdldENhY2hlID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUubWF0Y2goXCJzaGFyZWQtZmlsZVwiKTtcbiAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICBjb25zdCBibG9iID0gYXdhaXQgcmVzcG9uc2UuYmxvYigpO1xuICAgICAgICBjb25zdCBmaWxlID0gbmV3IEZpbGUoW2Jsb2JdLCBibG9iLm5hbWUgfHwgXCJcIiwgeyB0eXBlOiBibG9iLnR5cGUgfSk7XG4gICAgICAgIHRoaXMubG9hZEZpbGVUb0NhbnZhcyhmaWxlLCBudWxsKTtcbiAgICAgICAgYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5kZWxldGUoXCJzaGFyZWQtZmlsZVwiKTtcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsIEFQUF9OQU1FLCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiBhZGRzIHN1cHBsaWVkIGZpbGVzIHRvIGV4aXN0aW5nIGZpbGVzIGluIHRoZSBhcHBTdGF0ZSAqL1xuICBwdWJsaWMgYWRkRmlsZXM6IEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJW1wiYWRkRmlsZXNcIl0gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGZpbGVzKSA9PiB7XG4gICAgICBjb25zdCBmaWxlc01hcCA9IGZpbGVzLnJlZHVjZSgoYWNjLCBmaWxlRGF0YSkgPT4ge1xuICAgICAgICBhY2Muc2V0KGZpbGVEYXRhLmlkLCBmaWxlRGF0YSk7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCBuZXcgTWFwPEZpbGVJZCwgQmluYXJ5RmlsZURhdGE+KCkpO1xuXG4gICAgICB0aGlzLmZpbGVzID0geyAuLi50aGlzLmZpbGVzLCAuLi5PYmplY3QuZnJvbUVudHJpZXMoZmlsZXNNYXApIH07XG5cbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgIGZpbGVzTWFwLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmRlbGV0ZShlbGVtZW50LmZpbGVJZCk7XG4gICAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG5cbiAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgfSxcbiAgKTtcblxuICBwdWJsaWMgdXBkYXRlU2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgPEsgZXh0ZW5kcyBrZXlvZiBBcHBTdGF0ZT4oc2NlbmVEYXRhOiB7XG4gICAgICBlbGVtZW50cz86IFNjZW5lRGF0YVtcImVsZW1lbnRzXCJdO1xuICAgICAgYXBwU3RhdGU/OiBQaWNrPEFwcFN0YXRlLCBLPiB8IG51bGw7XG4gICAgICBjb2xsYWJvcmF0b3JzPzogU2NlbmVEYXRhW1wiY29sbGFib3JhdG9yc1wiXTtcbiAgICAgIGNvbW1pdFRvSGlzdG9yeT86IFNjZW5lRGF0YVtcImNvbW1pdFRvSGlzdG9yeVwiXTtcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoc2NlbmVEYXRhLmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuYXBwU3RhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShzY2VuZURhdGEuYXBwU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NlbmVEYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKHNjZW5lRGF0YS5lbGVtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuY29sbGFib3JhdG9ycykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29sbGFib3JhdG9yczogc2NlbmVEYXRhLmNvbGxhYm9yYXRvcnMgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uU2NlbmVVcGRhdGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgY3Vyc29yWCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBjdXJzb3JZID0gZXZlbnQuY2xpZW50WTtcbiAgICB9LFxuICApO1xuXG4gIC8vIElucHV0IGhhbmRsaW5nXG5cbiAgcHJpdmF0ZSBvbktleURvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBSZWFjdC5LZXlib2FyZEV2ZW50IHwgS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gbm9ybWFsaXplIGBldmVudC5rZXlgIHdoZW4gQ2Fwc0xvY2sgaXMgcHJlc3NlZCAjMjM3MlxuXG4gICAgICBpZiAoXG4gICAgICAgIFwiUHJveHlcIiBpbiB3aW5kb3cgJiZcbiAgICAgICAgKCghZXZlbnQuc2hpZnRLZXkgJiYgL15bQS1aXSQvLnRlc3QoZXZlbnQua2V5KSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXkgJiYgL15bYS16XSQvLnRlc3QoZXZlbnQua2V5KSkpXG4gICAgICApIHtcbiAgICAgICAgZXZlbnQgPSBuZXcgUHJveHkoZXZlbnQsIHtcbiAgICAgICAgICBnZXQoZXY6IGFueSwgcHJvcCkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBldltwcm9wXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAvLyBmaXggZm9yIFByb3hpZXMgaGlqYWNraW5nIGB0aGlzYFxuICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYmluZChldik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvcCA9PT0gXCJrZXlcIlxuICAgICAgICAgICAgICA/IC8vIENhcHNMb2NrIGludmVydHMgY2FwaXRhbGl6YXRpb24gYmFzZWQgb24gU2hpZnRLZXksIHNvIGludmVydFxuICAgICAgICAgICAgICAgIC8vIGl0IGJhY2tcbiAgICAgICAgICAgICAgICBldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICAgID8gZXYua2V5LnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgICAgICA6IGV2LmtleS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgIDogdmFsdWU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIHByZXZlbnQgYnJvd3NlciB6b29tIGluIGlucHV0IGZpZWxkc1xuICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmIGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09IENPREVTLk1JTlVTIHx8IGV2ZW50LmNvZGUgPT09IENPREVTLkVRVUFMKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gYmFpbCBpZlxuICAgICAgaWYgKFxuICAgICAgICAvLyBpbnNpZGUgYW4gaW5wdXRcbiAgICAgICAgKGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkgJiZcbiAgICAgICAgICAvLyB1bmxlc3MgcHJlc3NpbmcgZXNjYXBlIChmaW5hbGl6ZSBhY3Rpb24pXG4gICAgICAgICAgZXZlbnQua2V5ICE9PSBLRVlTLkVTQ0FQRSkgfHxcbiAgICAgICAgLy8gb3IgdW5sZXNzIHVzaW5nIGFycm93cyAodG8gbW92ZSBiZXR3ZWVuIGJ1dHRvbnMpXG4gICAgICAgIChpc0Fycm93S2V5KGV2ZW50LmtleSkgJiYgaXNJbnB1dExpa2UoZXZlbnQudGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUVVFU1RJT05fTUFSSykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzaG93SGVscERpYWxvZzogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmFjdGlvbk1hbmFnZXIuaGFuZGxlS2V5RG93bihldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgdGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmNvZGUgPT09IENPREVTLlpFUk8pIHtcbiAgICAgICAgY29uc3QgbmV4dFN0YXRlID0gIXRoaXMuc3RhdGUuaXNMaWJyYXJ5T3BlbjtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IG5leHRTdGF0ZSB9KTtcbiAgICAgICAgLy8gdHJhY2sgb25seSBvcGVuaW5nc1xuICAgICAgICBpZiAobmV4dFN0YXRlKSB7XG4gICAgICAgICAgdHJhY2tFdmVudChcbiAgICAgICAgICAgIFwibGlicmFyeVwiLFxuICAgICAgICAgICAgXCJ0b2dnbGVMaWJyYXJ5IChvcGVuKVwiLFxuICAgICAgICAgICAgYGtleWJvYXJkICgke3RoaXMuZGV2aWNlLmlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwifSlgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyb3dLZXkoZXZlbnQua2V5KSkge1xuICAgICAgICBjb25zdCBzdGVwID1cbiAgICAgICAgICAodGhpcy5zdGF0ZS5ncmlkU2l6ZSAmJlxuICAgICAgICAgICAgKGV2ZW50LnNoaWZ0S2V5XG4gICAgICAgICAgICAgID8gRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5UXG4gICAgICAgICAgICAgIDogdGhpcy5zdGF0ZS5ncmlkU2l6ZSkpIHx8XG4gICAgICAgICAgKGV2ZW50LnNoaWZ0S2V5XG4gICAgICAgICAgICA/IEVMRU1FTlRfU0hJRlRfVFJBTlNMQVRFX0FNT1VOVFxuICAgICAgICAgICAgOiBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlQpO1xuXG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICB0cnVlLFxuICAgICAgICApO1xuXG4gICAgICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICAgICAgbGV0IG9mZnNldFkgPSAwO1xuXG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfTEVGVCkge1xuICAgICAgICAgIG9mZnNldFggPSAtc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfUklHSFQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfVVApIHtcbiAgICAgICAgICBvZmZzZXRZID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0RPV04pIHtcbiAgICAgICAgICBvZmZzZXRZID0gc3RlcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICAgICAgeDogZWxlbWVudC54ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgIHk6IGVsZW1lbnQueSArIG9mZnNldFksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHNpbXVsdGFuZW91c2x5VXBkYXRlZDogc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5FTlRFUikge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT1cbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcblxuICAgICAgICAgICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgICAgICAgICAgc2NlbmVYOiBzZWxlY3RlZEVsZW1lbnQueCArIHNlbGVjdGVkRWxlbWVudC53aWR0aCAvIDIsXG4gICAgICAgICAgICAgIHNjZW5lWTogc2VsZWN0ZWRFbGVtZW50LnkgKyBzZWxlY3RlZEVsZW1lbnQuaGVpZ2h0IC8gMixcbiAgICAgICAgICAgICAgc2hvdWxkQmluZDogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICFldmVudC5jdHJsS2V5ICYmXG4gICAgICAgICFldmVudC5hbHRLZXkgJiZcbiAgICAgICAgIWV2ZW50Lm1ldGFLZXkgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgPT09IG51bGxcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzaGFwZSA9IGZpbmRTaGFwZUJ5S2V5KGV2ZW50LmtleSk7XG4gICAgICAgIGlmIChzaGFwZSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gc2hhcGUpIHtcbiAgICAgICAgICAgIHRyYWNrRXZlbnQoXG4gICAgICAgICAgICAgIFwidG9vbGJhclwiLFxuICAgICAgICAgICAgICBzaGFwZSxcbiAgICAgICAgICAgICAgYGtleWJvYXJkICgke3RoaXMuZGV2aWNlLmlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwifSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZXRBY3RpdmVUb29sKHsgdHlwZTogc2hhcGUgfSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlEpIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZUxvY2soXCJrZXlib2FyZFwiKTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSAmJiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDApIHtcbiAgICAgICAgaXNIb2xkaW5nU3BhY2UgPSB0cnVlO1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAoZXZlbnQua2V5ID09PSBLRVlTLkcgfHwgZXZlbnQua2V5ID09PSBLRVlTLlMpICYmXG4gICAgICAgICFldmVudC5hbHRLZXkgJiZcbiAgICAgICAgIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgICAhc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGhcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIGV2ZW50LmtleSA9PT0gS0VZUy5HICYmXG4gICAgICAgICAgKGhhc0JhY2tncm91bmQodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUpIHx8XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLnNvbWUoKGVsZW1lbnQpID0+IGhhc0JhY2tncm91bmQoZWxlbWVudC50eXBlKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwiYmFja2dyb3VuZENvbG9yUGlja2VyXCIgfSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5Qb3B1cDogXCJzdHJva2VDb2xvclBpY2tlclwiIH0pO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uV2hlZWwgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBXaGVlbEV2ZW50KSA9PiB7XG4gICAgLy8gcHJldmVudCBicm93c2VyIHBpbmNoIHpvb20gb24gRE9NIGVsZW1lbnRzXG4gICAgaWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpICYmIGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9KTtcblxuICBwcml2YXRlIG9uS2V5VXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSkge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmICF0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgIH1cbiAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgID8gYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50cyhzZWxlY3RlZEVsZW1lbnRzKVxuICAgICAgICA6IHVuYmluZExpbmVhckVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgc2V0QWN0aXZlVG9vbCA9IChcbiAgICB0b29sOlxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBTSEFQRVNbbnVtYmVyXVtcInZhbHVlXCJdIHwgXCJlcmFzZXJcIiB9XG4gICAgICB8IHsgdHlwZTogXCJjdXN0b21cIjsgY3VzdG9tVHlwZTogc3RyaW5nIH0sXG4gICkgPT4ge1xuICAgIGNvbnN0IG5leHRBY3RpdmVUb29sID0gdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB0b29sKTtcbiAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgfVxuICAgIGlmIChpc1Rvb2xJY29uKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgfVxuICAgIGlmICghaXNMaW5lYXJFbGVtZW50VHlwZShuZXh0QWN0aXZlVG9vbC50eXBlKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICB9XG4gICAgaWYgKG5leHRBY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgdGhpcy5vbkltYWdlQWN0aW9uKCk7XG4gICAgfVxuICAgIGlmIChuZXh0QWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgYWN0aXZlVG9vbDogbmV4dEFjdGl2ZVRvb2wsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgYWN0aXZlVG9vbDogbmV4dEFjdGl2ZVRvb2wgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc2V0Q3Vyc29yID0gKGN1cnNvcjogc3RyaW5nKSA9PiB7XG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBjdXJzb3IpO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRDdXJzb3IgPSAoKSA9PiB7XG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICB9O1xuICAvKipcbiAgICogcmV0dXJucyB3aGV0aGVyIHVzZXIgaXMgbWFraW5nIGEgZ2VzdHVyZSB3aXRoID49IDIgZmluZ2VycyAocG9pbnRzKVxuICAgKiBvbiBvIHRvdWNoIHNjcmVlbiAobm90IG9uIGEgdHJhY2twYWQpLiBDdXJyZW50bHkgb25seSByZWxhdGVzIHRvIERhcndpblxuICAgKiAoaU9TL2lQYWRPUyxNYWNPUyksIGJ1dCBtYXkgd29yayBvbiBvdGhlciBkZXZpY2VzIGluIHRoZSBmdXR1cmUgaWZcbiAgICogR2VzdHVyZUV2ZW50IGlzIHN0YW5kYXJkaXplZC5cbiAgICovXG4gIHByaXZhdGUgaXNUb3VjaFNjcmVlbk11bHRpVG91Y2hHZXN0dXJlID0gKCkgPT4ge1xuICAgIC8vIHdlIGRvbid0IHdhbnQgdG8gZGVzZWxlY3Qgd2hlbiB1c2luZyB0cmFja3BhZCwgYW5kIG11bHRpLXBvaW50IGdlc3R1cmVzXG4gICAgLy8gb25seSB3b3JrIG9uIHRvdWNoIHNjcmVlbnMsIHNvIGNoZWNraW5nIGZvciA+PSBwb2ludGVycyBtZWFucyB3ZSdyZSBvbiBhXG4gICAgLy8gdG91Y2hzY3JlZW5cbiAgICByZXR1cm4gZ2VzdHVyZS5wb2ludGVycy5zaXplID49IDI7XG4gIH07XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVTdGFydCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAvLyB3ZSBvbmx5IHdhbnQgdG8gZGVzZWxlY3Qgb24gdG91Y2ggc2NyZWVucyBiZWNhdXNlIHVzZXIgbWF5IGhhdmUgc2VsZWN0ZWRcbiAgICAvLyBlbGVtZW50cyBieSBtaXN0YWtlIHdoaWxlIHpvb21pbmdcbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gIH0pO1xuXG4gIC8vIGZpcmVzIG9ubHkgb24gU2FmYXJpXG4gIHByaXZhdGUgb25HZXN0dXJlQ2hhbmdlID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIG9uR2VzdHVyZUNoYW5nZSBvbmx5IGhhcyB6b29tIGZhY3RvciBidXQgbm90IHRoZSBjZW50ZXIuXG4gICAgLy8gSWYgd2UncmUgb24gaVBhZCBvciBpUGhvbmUsIHRoZW4gd2UgcmVjb2duaXplIG11bHRpLXRvdWNoIGFuZCB3aWxsXG4gICAgLy8gem9vbSBpbiBhdCB0aGUgcmlnaHQgbG9jYXRpb24gaW4gdGhlIHRvdWNobW92ZSBoYW5kbGVyXG4gICAgLy8gKGhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlKS5cbiAgICAvL1xuICAgIC8vIE9uIE1hY2Jvb2sgdHJhY2twYWQsIHdlIGRvbid0IGhhdmUgdGhvc2UgZXZlbnRzIHNvIHdpbGwgem9vbSBpbiBhdCB0aGVcbiAgICAvLyBjdXJyZW50IGxvY2F0aW9uIGluc3RlYWQuXG4gICAgLy9cbiAgICAvLyBBcyBzdWNoLCBiYWlsIGZyb20gdGhpcyBoYW5kbGVyIG9uIHRvdWNoIGRldmljZXMuXG4gICAgaWYgKHRoaXMuaXNUb3VjaFNjcmVlbk11bHRpVG91Y2hHZXN0dXJlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoaW5pdGlhbFNjYWxlKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgLi4uZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY3Vyc29yWCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY3Vyc29yWSxcbiAgICAgICAgICAgIG5leHRab29tOiBnZXROb3JtYWxpemVkWm9vbShpbml0aWFsU2NhbGUgKiBldmVudC5zY2FsZSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGZpcmVzIG9ubHkgb24gU2FmYXJpXG4gIHByaXZhdGUgb25HZXN0dXJlRW5kID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAvLyByZXNlbGVjdCBlbGVtZW50cyBvbmx5IG9uIHRvdWNoIHNjcmVlbnMgKHNlZSBvbkdlc3R1cmVTdGFydClcbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gbnVsbDtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0V3lzaXd5ZyhcbiAgICBlbGVtZW50OiBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gICAge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQgPSBmYWxzZSxcbiAgICB9OiB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudCA9IChcbiAgICAgIHRleHQ6IHN0cmluZyxcbiAgICAgIG9yaWdpbmFsVGV4dDogc3RyaW5nLFxuICAgICAgaXNEZWxldGVkOiBib29sZWFuLFxuICAgICkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoX2VsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoX2VsZW1lbnQuaWQgPT09IGVsZW1lbnQuaWQgJiYgaXNUZXh0RWxlbWVudChfZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVUZXh0RWxlbWVudChfZWxlbWVudCwge1xuICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICBpc0RlbGV0ZWQsXG4gICAgICAgICAgICAgIG9yaWdpbmFsVGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX2VsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgfTtcblxuICAgIHRleHRXeXNpd3lnKHtcbiAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgY2FudmFzOiB0aGlzLmNhbnZhcyxcbiAgICAgIGdldFZpZXdwb3J0Q29vcmRzOiAoeCwgeSkgPT4ge1xuICAgICAgICBjb25zdCB7IHg6IHZpZXdwb3J0WCwgeTogdmlld3BvcnRZIH0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2NlbmVYOiB4LFxuICAgICAgICAgICAgc2NlbmVZOiB5LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICB2aWV3cG9ydFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgICAgdmlld3BvcnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgICAgIF07XG4gICAgICB9LFxuICAgICAgb25DaGFuZ2U6IHdpdGhCYXRjaGVkVXBkYXRlcygodGV4dCkgPT4ge1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIHRleHQsIGZhbHNlKTtcbiAgICAgICAgaWYgKGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICAgIG9uU3VibWl0OiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKHsgdGV4dCwgdmlhS2V5Ym9hcmQsIG9yaWdpbmFsVGV4dCB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGlzRGVsZXRlZCA9ICF0ZXh0LnRyaW0oKTtcbiAgICAgICAgdXBkYXRlRWxlbWVudCh0ZXh0LCBvcmlnaW5hbFRleHQsIGlzRGVsZXRlZCk7XG4gICAgICAgIC8vIHNlbGVjdCB0aGUgY3JlYXRlZCB0ZXh0IGVsZW1lbnQgb25seSBpZiBzdWJtaXR0aW5nIHZpYSBrZXlib2FyZFxuICAgICAgICAvLyAod2hlbiBzdWJtaXR0aW5nIHZpYSBjbGljayBpdCBzaG91bGQgYWN0IGFzIHNpZ25hbCB0byBkZXNlbGVjdClcbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgJiYgdmlhS2V5Ym9hcmQpIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50SWRUb1NlbGVjdCA9IGVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgICAgID8gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgOiBlbGVtZW50LmlkO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICBbZWxlbWVudElkVG9TZWxlY3RdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVsZXRlZCkge1xuICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbih0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCBbXG4gICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIF0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNEZWxldGVkIHx8IGlzRXhpc3RpbmdFbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgICB9KSxcbiAgICAgIGVsZW1lbnQsXG4gICAgICBleGNhbGlkcmF3Q29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCxcbiAgICAgIGFwcDogdGhpcyxcbiAgICB9KTtcbiAgICAvLyBkZXNlbGVjdCBhbGwgb3RoZXIgZWxlbWVudHMgd2hlbiBpbnNlcnRpbmcgdGV4dFxuICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuXG4gICAgLy8gZG8gYW4gaW5pdGlhbCB1cGRhdGUgdG8gcmUtaW5pdGlhbGl6ZSBlbGVtZW50IHBvc2l0aW9uIHNpbmNlIHdlIHdlcmVcbiAgICAvLyBtb2RpZnlpbmcgZWxlbWVudCdzIHgveSBmb3Igc2FrZSBvZiBlZGl0b3IgKGNhc2U6IHN5bmNpbmcgdG8gcmVtb3RlKVxuICAgIHVwZGF0ZUVsZW1lbnQoZWxlbWVudC50ZXh0LCBlbGVtZW50Lm9yaWdpbmFsVGV4dCwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXNlbGVjdEVsZW1lbnRzKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdUZXh0RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGlmIChlbGVtZW50ICYmIGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgIWVsZW1lbnQuaXNEZWxldGVkKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgb3B0cz86IHtcbiAgICAgIC8qKiBpZiB0cnVlLCByZXR1cm5zIHRoZSBmaXJzdCBzZWxlY3RlZCBlbGVtZW50ICh3aXRoIGhpZ2hlc3Qgei1pbmRleClcbiAgICAgICAgb2YgYWxsIGhpdCBlbGVtZW50cyAqL1xuICAgICAgcHJlZmVyU2VsZWN0ZWQ/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUxvY2tlZEVsZW1lbnRzPzogYm9vbGVhbjtcbiAgICB9LFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGFsbEhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIG9wdHM/LmluY2x1ZGVCb3VuZFRleHRFbGVtZW50LFxuICAgICAgb3B0cz8uaW5jbHVkZUxvY2tlZEVsZW1lbnRzLFxuICAgICk7XG4gICAgaWYgKGFsbEhpdEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGlmIChvcHRzPy5wcmVmZXJTZWxlY3RlZCkge1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IGFsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDE7IGluZGV4ID4gLTE7IGluZGV4LS0pIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbYWxsSGl0RWxlbWVudHNbaW5kZXhdLmlkXSkge1xuICAgICAgICAgICAgcmV0dXJuIGFsbEhpdEVsZW1lbnRzW2luZGV4XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleCA9XG4gICAgICAgIGFsbEhpdEVsZW1lbnRzW2FsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgLy8gSWYgd2UncmUgaGl0dGluZyBlbGVtZW50IHdpdGggaGlnaGVzdCB6LWluZGV4IG9ubHkgb24gaXRzIGJvdW5kaW5nIGJveFxuICAgICAgLy8gd2hpbGUgYWxzbyBoaXR0aW5nIG90aGVyIGVsZW1lbnQgZmlndXJlLCB0aGUgbGF0dGVyIHNob3VsZCBiZSBjb25zaWRlcmVkLlxuICAgICAgcmV0dXJuIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgKVxuICAgICAgICA/IGFsbEhpdEVsZW1lbnRzW2FsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDJdXG4gICAgICAgIDogZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4O1xuICAgIH1cbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbMF07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogYm9vbGVhbiA9IGZhbHNlLFxuICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50czogYm9vbGVhbiA9IGZhbHNlLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdIHtcbiAgICBjb25zdCBlbGVtZW50cyA9XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudCAmJiBpbmNsdWRlTG9ja2VkRWxlbWVudHNcbiAgICAgICAgPyB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgIDogdGhpcy5zY2VuZVxuICAgICAgICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAoZWxlbWVudCkgPT5cbiAgICAgICAgICAgICAgICAoaW5jbHVkZUxvY2tlZEVsZW1lbnRzIHx8ICFlbGVtZW50LmxvY2tlZCkgJiZcbiAgICAgICAgICAgICAgICAoaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQgfHxcbiAgICAgICAgICAgICAgICAgICEoaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiBlbGVtZW50LmNvbnRhaW5lcklkKSksXG4gICAgICAgICAgICApO1xuXG4gICAgcmV0dXJuIGdldEVsZW1lbnRzQXRQb3NpdGlvbihlbGVtZW50cywgKGVsZW1lbnQpID0+XG4gICAgICBoaXRUZXN0KGVsZW1lbnQsIHRoaXMuc3RhdGUsIHgsIHkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0VGV4dEVkaXRpbmcgPSAoe1xuICAgIHNjZW5lWCxcbiAgICBzY2VuZVksXG4gICAgc2hvdWxkQmluZCxcbiAgICBpbnNlcnRBdFBhcmVudENlbnRlciA9IHRydWUsXG4gIH06IHtcbiAgICAvKiogWCBwb3NpdGlvbiB0byBpbnNlcnQgdGV4dCBhdCAqL1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIC8qKiBZIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVZOiBudW1iZXI7XG4gICAgc2hvdWxkQmluZDogYm9vbGVhbjtcbiAgICAvKiogd2hldGhlciB0byBhdHRlbXB0IHRvIGluc2VydCBhdCBlbGVtZW50IGNlbnRlciBpZiBhcHBsaWNhYmxlICovXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgbGV0IHBhcmVudENlbnRlclBvc2l0aW9uID1cbiAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyICYmXG4gICAgICB0aGlzLmdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICApO1xuXG4gICAgbGV0IGV4aXN0aW5nVGV4dEVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd1RleHRFbGVtZW50PiB8IG51bGwgPSBudWxsO1xuICAgIGxldCBjb250YWluZXI6IEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGlmIChpc1RleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuICAgICAgfSBlbHNlIGlmIChpc1RleHRCaW5kYWJsZUNvbnRhaW5lcihzZWxlY3RlZEVsZW1lbnRzWzBdLCBmYWxzZSkpIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IGdldEJvdW5kVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5nZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5nZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuICAgIH1cblxuICAgIC8vIGJpbmQgdG8gY29udGFpbmVyIHdoZW4gc2hvdWxkQmluZCBpcyB0cnVlIG9yXG4gICAgLy8gY2xpY2tlZCBvbiBjZW50ZXIgb2YgY29udGFpbmVyXG4gICAgaWYgKFxuICAgICAgIWNvbnRhaW5lciAmJlxuICAgICAgIWV4aXN0aW5nVGV4dEVsZW1lbnQgJiZcbiAgICAgIChzaG91bGRCaW5kIHx8IHBhcmVudENlbnRlclBvc2l0aW9uKVxuICAgICkge1xuICAgICAgY29udGFpbmVyID0gZ2V0VGV4dEJpbmRhYmxlQ29udGFpbmVyQXRQb3NpdGlvbihcbiAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAoZWxlKSA9PlxuICAgICAgICAgICAgICBpc1RleHRCaW5kYWJsZUNvbnRhaW5lcihlbGUsIGZhbHNlKSAmJiAhZ2V0Qm91bmRUZXh0RWxlbWVudChlbGUpLFxuICAgICAgICAgICksXG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWV4aXN0aW5nVGV4dEVsZW1lbnQgJiYgY29udGFpbmVyKSB7XG4gICAgICBjb25zdCBmb250U3RyaW5nID0ge1xuICAgICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIH07XG4gICAgICBjb25zdCBtaW5XaWR0aCA9IGdldEFwcHJveE1pbkxpbmVXaWR0aChnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpKTtcbiAgICAgIGNvbnN0IG1pbkhlaWdodCA9IGdldEFwcHJveE1pbkxpbmVIZWlnaHQoZ2V0Rm9udFN0cmluZyhmb250U3RyaW5nKSk7XG4gICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1heChjb250YWluZXIuaGVpZ2h0LCBtaW5IZWlnaHQpO1xuICAgICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLm1heChjb250YWluZXIud2lkdGgsIG1pbldpZHRoKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7IGhlaWdodDogbmV3SGVpZ2h0LCB3aWR0aDogbmV3V2lkdGggfSk7XG4gICAgICBzY2VuZVggPSBjb250YWluZXIueCArIG5ld1dpZHRoIC8gMjtcbiAgICAgIHNjZW5lWSA9IGNvbnRhaW5lci55ICsgbmV3SGVpZ2h0IC8gMjtcbiAgICAgIGlmIChwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgICBwYXJlbnRDZW50ZXJQb3NpdGlvbiA9IHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgICBzY2VuZVgsXG4gICAgICAgICAgc2NlbmVZLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudCA9IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgID8gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgOiBuZXdUZXh0RWxlbWVudCh7XG4gICAgICAgICAgeDogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlclhcbiAgICAgICAgICAgIDogc2NlbmVYLFxuICAgICAgICAgIHk6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJZXG4gICAgICAgICAgICA6IHNjZW5lWSxcbiAgICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgICAgICAgdGV4dDogXCJcIixcbiAgICAgICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgICAgIHRleHRBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gXCJjZW50ZXJcIlxuICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtVGV4dEFsaWduLFxuICAgICAgICAgIHZlcnRpY2FsQWxpZ246IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IFZFUlRJQ0FMX0FMSUdOLk1JRERMRVxuICAgICAgICAgICAgOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgICAgICAgIGNvbnRhaW5lcklkOiBjb250YWluZXI/LmlkID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICBncm91cElkczogY29udGFpbmVyPy5ncm91cElkcyA/PyBbXSxcbiAgICAgICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nRWxlbWVudDogZWxlbWVudCB9KTtcblxuICAgIGlmICghZXhpc3RpbmdUZXh0RWxlbWVudCkge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG5cbiAgICAgIC8vIGNhc2U6IGNyZWF0aW5nIG5ldyB0ZXh0IG5vdCBjZW50ZXJlZCB0byBwYXJlbnQgZWxlbWVudCDihpIgb2Zmc2V0IFlcbiAgICAgIC8vIHNvIHRoYXQgdGhlIHRleHQgaXMgY2VudGVyZWQgdG8gY3Vyc29yIHBvc2l0aW9uXG4gICAgICBpZiAoIXBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICAgIHk6IGVsZW1lbnQueSAtIGVsZW1lbnQuYmFzZWxpbmUgLyAyLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgIH0pO1xuXG4gICAgdGhpcy5oYW5kbGVUZXh0V3lzaXd5ZyhlbGVtZW50LCB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudDogISFleGlzdGluZ1RleHRFbGVtZW50LFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2sgPSAoXG4gICAgZXZlbnQ6IFJlYWN0Lk1vdXNlRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICAvLyBjYXNlOiBkb3VibGUtY2xpY2tpbmcgd2l0aCBhcnJvdy9saW5lIHRvb2wgc2VsZWN0ZWQgd291bGQgYm90aCBjcmVhdGVcbiAgICAvLyB0ZXh0IGFuZCBlbnRlciBtdWx0aUVsZW1lbnQgbW9kZVxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyB3ZSBzaG91bGQgb25seSBiZSBhYmxlIHRvIGRvdWJsZSBjbGljayB3aGVuIG1vZGUgaXMgc2VsZWN0aW9uXG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmIGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSkge1xuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT0gc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuXG4gICAgbGV0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIGV2ZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkcyA9IGdldFNlbGVjdGVkR3JvdXBJZHModGhpcy5zdGF0ZSk7XG5cbiAgICBpZiAoc2VsZWN0ZWRHcm91cElkcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG5cbiAgICAgIGNvbnN0IHNlbGVjdGVkR3JvdXBJZCA9XG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgZ2V0U2VsZWN0ZWRHcm91cElkRm9yRWxlbWVudChoaXRFbGVtZW50LCB0aGlzLnN0YXRlLnNlbGVjdGVkR3JvdXBJZHMpO1xuXG4gICAgICBpZiAoc2VsZWN0ZWRHcm91cElkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBzZWxlY3RlZEdyb3VwSWQsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudCEuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICBpZiAoIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmICF0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG4gICAgICAgIGNvbnN0IGNhbkJpbmRUZXh0ID0gaGFzQm91bmRUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnQpO1xuICAgICAgICBpZiAoY2FuQmluZFRleHQpIHtcbiAgICAgICAgICBzY2VuZVggPSBzZWxlY3RlZEVsZW1lbnQueCArIHNlbGVjdGVkRWxlbWVudC53aWR0aCAvIDI7XG4gICAgICAgICAgc2NlbmVZID0gc2VsZWN0ZWRFbGVtZW50LnkgKyBzZWxlY3RlZEVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHNob3VsZEJpbmQ6IGZhbHNlLFxuICAgICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGdldEVsZW1lbnRMaW5rQXRQb3NpdGlvbiA9IChcbiAgICBzY2VuZVBvaW50ZXI6IFJlYWRvbmx5PHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfT4sXG4gICAgaGl0RWxlbWVudDogTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCxcbiAgKTogRXhjYWxpZHJhd0VsZW1lbnQgfCB1bmRlZmluZWQgPT4ge1xuICAgIC8vIFJldmVyc2luZyBzbyB3ZSB0cmF2ZXJzZSB0aGUgZWxlbWVudHMgaW4gZGVjcmVhc2luZyBvcmRlclxuICAgIC8vIG9mIHotaW5kZXhcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCkuc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgbGV0IGhpdEVsZW1lbnRJbmRleCA9IEluZmluaXR5O1xuXG4gICAgcmV0dXJuIGVsZW1lbnRzLmZpbmQoKGVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaGl0RWxlbWVudCAmJiBlbGVtZW50LmlkID09PSBoaXRFbGVtZW50LmlkKSB7XG4gICAgICAgIGhpdEVsZW1lbnRJbmRleCA9IGluZGV4O1xuICAgICAgfVxuICAgICAgcmV0dXJuIChcbiAgICAgICAgZWxlbWVudC5saW5rICYmXG4gICAgICAgIGluZGV4IDw9IGhpdEVsZW1lbnRJbmRleCAmJlxuICAgICAgICBpc1BvaW50SGl0dGluZ0xpbmtJY29uKFxuICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICBbc2NlbmVQb2ludGVyLngsIHNjZW5lUG9pbnRlci55XSxcbiAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIHJlZGlyZWN0VG9MaW5rID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGlzVG91Y2hTY3JlZW46IGJvb2xlYW4sXG4gICkgPT4ge1xuICAgIGNvbnN0IGRyYWdnZWREaXN0YW5jZSA9IGRpc3RhbmNlMmQoXG4gICAgICB0aGlzLmxhc3RQb2ludGVyRG93biEuY2xpZW50WCxcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRZLFxuICAgICAgdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRYLFxuICAgICAgdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRZLFxuICAgICk7XG4gICAgaWYgKFxuICAgICAgIXRoaXMuaGl0TGlua0VsZW1lbnQgfHxcbiAgICAgIC8vIEZvciB0b3VjaCBzY3JlZW4gYWxsb3cgZHJhZ2dpbmcgdGhyZXNob2xkIGVsc2Ugc3RyaWN0IGNoZWNrXG4gICAgICAoaXNUb3VjaFNjcmVlbiAmJiBkcmFnZ2VkRGlzdGFuY2UgPiBEUkFHR0lOR19USFJFU0hPTEQpIHx8XG4gICAgICAoIWlzVG91Y2hTY3JlZW4gJiYgZHJhZ2dlZERpc3RhbmNlICE9PSAwKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBsYXN0UG9pbnRlckRvd25Db29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB0aGlzLmxhc3RQb2ludGVyRG93biEsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJEb3duSGl0dGluZ0xpbmtJY29uID0gaXNQb2ludEhpdHRpbmdMaW5rSWNvbihcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICAgW2xhc3RQb2ludGVyRG93bkNvb3Jkcy54LCBsYXN0UG9pbnRlckRvd25Db29yZHMueV0sXG4gICAgICB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICApO1xuICAgIGNvbnN0IGxhc3RQb2ludGVyVXBDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IGxhc3RQb2ludGVyVXBIaXR0aW5nTGlua0ljb24gPSBpc1BvaW50SGl0dGluZ0xpbmtJY29uKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICBbbGFzdFBvaW50ZXJVcENvb3Jkcy54LCBsYXN0UG9pbnRlclVwQ29vcmRzLnldLFxuICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgKTtcbiAgICBpZiAobGFzdFBvaW50ZXJEb3duSGl0dGluZ0xpbmtJY29uICYmIGxhc3RQb2ludGVyVXBIaXR0aW5nTGlua0ljb24pIHtcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMuaGl0TGlua0VsZW1lbnQubGluaztcbiAgICAgIGlmICh1cmwpIHtcbiAgICAgICAgbGV0IGN1c3RvbUV2ZW50O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkxpbmtPcGVuKSB7XG4gICAgICAgICAgY3VzdG9tRXZlbnQgPSB3cmFwRXZlbnQoRVZFTlQuRVhDQUxJRFJBV19MSU5LLCBldmVudC5uYXRpdmVFdmVudCk7XG4gICAgICAgICAgdGhpcy5wcm9wcy5vbkxpbmtPcGVuKHRoaXMuaGl0TGlua0VsZW1lbnQsIGN1c3RvbUV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWN1c3RvbUV2ZW50Py5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgY29uc3QgdGFyZ2V0ID0gaXNMb2NhbExpbmsodXJsKSA/IFwiX3NlbGZcIiA6IFwiX2JsYW5rXCI7XG4gICAgICAgICAgY29uc3QgbmV3V2luZG93ID0gd2luZG93Lm9wZW4odW5kZWZpbmVkLCB0YXJnZXQpO1xuICAgICAgICAgIC8vIGh0dHBzOi8vbWF0aGlhc2J5bmVucy5naXRodWIuaW8vcmVsLW5vb3BlbmVyL1xuICAgICAgICAgIGlmIChuZXdXaW5kb3cpIHtcbiAgICAgICAgICAgIG5ld1dpbmRvdy5vcGVuZXIgPSBudWxsO1xuICAgICAgICAgICAgbmV3V2luZG93LmxvY2F0aW9uID0gbm9ybWFsaXplTGluayh1cmwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIHRoaXMuc3RhdGUuY3Vyc29yQnV0dG9uKTtcbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5oYXMoZXZlbnQucG9pbnRlcklkKSkge1xuICAgICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoXG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIgJiZcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciAmJlxuICAgICAgaW5pdGlhbFNjYWxlICYmXG4gICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZVxuICAgICkge1xuICAgICAgY29uc3QgY2VudGVyID0gZ2V0Q2VudGVyKGdlc3R1cmUucG9pbnRlcnMpO1xuICAgICAgY29uc3QgZGVsdGFYID0gY2VudGVyLnggLSBnZXN0dXJlLmxhc3RDZW50ZXIueDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGNlbnRlci55IC0gZ2VzdHVyZS5sYXN0Q2VudGVyLnk7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPSBjZW50ZXI7XG5cbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZ2V0RGlzdGFuY2UoQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSk7XG4gICAgICBjb25zdCBzY2FsZUZhY3RvciA9XG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImZyZWVkcmF3XCIgJiYgdGhpcy5zdGF0ZS5wZW5Nb2RlXG4gICAgICAgICAgPyAxXG4gICAgICAgICAgOiBkaXN0YW5jZSAvIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlO1xuXG4gICAgICBjb25zdCBuZXh0Wm9vbSA9IHNjYWxlRmFjdG9yXG4gICAgICAgID8gZ2V0Tm9ybWFsaXplZFpvb20oaW5pdGlhbFNjYWxlICogc2NhbGVGYWN0b3IpXG4gICAgICAgIDogdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgICBjb25zdCB6b29tU3RhdGUgPSBnZXRTdGF0ZUZvclpvb20oXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmlld3BvcnRYOiBjZW50ZXIueCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY2VudGVyLnksXG4gICAgICAgICAgICBuZXh0Wm9vbSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgem9vbTogem9vbVN0YXRlLnpvb20sXG4gICAgICAgICAgc2Nyb2xsWDogem9vbVN0YXRlLnNjcm9sbFggKyBkZWx0YVggLyBuZXh0Wm9vbSxcbiAgICAgICAgICBzY3JvbGxZOiB6b29tU3RhdGUuc2Nyb2xsWSArIGRlbHRhWSAvIG5leHRab29tLFxuICAgICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZSA9XG4gICAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID1cbiAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIGlmIChpc0hvbGRpbmdTcGFjZSB8fCBpc1Bhbm5pbmcgfHwgaXNEcmFnZ2luZ1Njcm9sbEJhcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlzUG9pbnRlck92ZXJTY3JvbGxCYXJzID0gaXNPdmVyU2Nyb2xsQmFycyhcbiAgICAgIGN1cnJlbnRTY3JvbGxCYXJzLFxuICAgICAgZXZlbnQuY2xpZW50WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgIGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICApO1xuICAgIGNvbnN0IGlzT3ZlclNjcm9sbEJhciA9IGlzUG9pbnRlck92ZXJTY3JvbGxCYXJzLmlzT3ZlckVpdGhlcjtcbiAgICBpZiAoIXRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50ICYmICF0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgaWYgKGlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2NlbmVQb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCB7IHg6IHNjZW5lUG9pbnRlclgsIHk6IHNjZW5lUG9pbnRlclkgfSA9IHNjZW5lUG9pbnRlcjtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmlzRHJhZ2dpbmdcbiAgICApIHtcbiAgICAgIGNvbnN0IGVkaXRpbmdMaW5lYXJFbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyTW92ZShcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50ICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIC8vIFNpbmNlIHdlIGFyZSByZWFkaW5nIGZyb20gcHJldmlvdXMgc3RhdGUgd2hpY2ggaXMgbm90IHBvc3NpYmxlIHdpdGhcbiAgICAgICAgLy8gYXV0b21hdGljIGJhdGNoaW5nIGluIFJlYWN0IDE4IGhlbmNlIHVzaW5nIGZsdXNoIHN5bmMgdG8gc3luY2hyb25vdXNseVxuICAgICAgICAvLyB1cGRhdGUgdGhlIHN0YXRlLiBDaGVjayBodHRwczovL2dpdGh1Yi5jb20vZXhjYWxpZHJhdy9leGNhbGlkcmF3L3B1bGwvNTUwOCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICBmbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudCB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQubGFzdFVuY29tbWl0dGVkUG9pbnQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNCaW5kaW5nRWxlbWVudFR5cGUodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgICAvLyBIb3ZlcmluZyB3aXRoIGEgc2VsZWN0ZWQgdG9vbCBvciBjcmVhdGluZyBuZXcgbGluZWFyIGVsZW1lbnQgdmlhIGNsaWNrXG4gICAgICAvLyBhbmQgcG9pbnRcbiAgICAgIGNvbnN0IHsgZHJhZ2dpbmdFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCBmYWxzZSkpIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgW3NjZW5lUG9pbnRlcl0sXG4gICAgICAgICAgdGhpcy5zdGF0ZS5zdGFydEJvdW5kRWxlbWVudCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IHsgeDogcngsIHk6IHJ5IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIGNvbnN0IHsgcG9pbnRzLCBsYXN0Q29tbWl0dGVkUG9pbnQgfSA9IG11bHRpRWxlbWVudDtcbiAgICAgIGNvbnN0IGxhc3RQb2ludCA9IHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV07XG5cbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcblxuICAgICAgaWYgKGxhc3RQb2ludCA9PT0gbGFzdENvbW1pdHRlZFBvaW50KSB7XG4gICAgICAgIC8vIGlmIHdlIGhhdmVuJ3QgeWV0IGNyZWF0ZWQgYSB0ZW1wIHBvaW50IGFuZCB3ZSdyZSBiZXlvbmQgY29tbWl0LXpvbmVcbiAgICAgICAgLy8gdGhyZXNob2xkLCBhZGQgYSBwb2ludFxuICAgICAgICBpZiAoXG4gICAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSByeSxcbiAgICAgICAgICAgIGxhc3RQb2ludFswXSxcbiAgICAgICAgICAgIGxhc3RQb2ludFsxXSxcbiAgICAgICAgICApID49IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICAgKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW3NjZW5lUG9pbnRlclggLSByeCwgc2NlbmVQb2ludGVyWSAtIHJ5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgICAvLyBpbiB0aGlzIGJyYW5jaCwgd2UncmUgaW5zaWRlIHRoZSBjb21taXQgem9uZSwgYW5kIG5vIHVuY29tbWl0dGVkXG4gICAgICAgICAgLy8gcG9pbnQgZXhpc3RzLiBUaHVzIGRvIG5vdGhpbmcgKGRvbid0IGFkZC9yZW1vdmUgcG9pbnRzKS5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgcG9pbnRzLmxlbmd0aCA+IDIgJiZcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50ICYmXG4gICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCAtIHJ4LFxuICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSByeSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMF0sXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzFdLFxuICAgICAgICApIDwgTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBwb2ludHMuc2xpY2UoMCwgLTEpLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IFtsYXN0Q29tbWl0dGVkWCwgbGFzdENvbW1pdHRlZFldID1cbiAgICAgICAgICBtdWx0aUVsZW1lbnQ/Lmxhc3RDb21taXR0ZWRQb2ludCA/PyBbMCwgMF07XG5cbiAgICAgICAgbGV0IGR4RnJvbUxhc3RDb21taXR0ZWQgPSBncmlkWCAtIHJ4IC0gbGFzdENvbW1pdHRlZFg7XG4gICAgICAgIGxldCBkeUZyb21MYXN0Q29tbWl0dGVkID0gZ3JpZFkgLSByeSAtIGxhc3RDb21taXR0ZWRZO1xuXG4gICAgICAgIGlmIChzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCkpIHtcbiAgICAgICAgICAoeyB3aWR0aDogZHhGcm9tTGFzdENvbW1pdHRlZCwgaGVpZ2h0OiBkeUZyb21MYXN0Q29tbWl0dGVkIH0gPVxuICAgICAgICAgICAgZ2V0TG9ja2VkTGluZWFyQ3Vyc29yQWxpZ25TaXplKFxuICAgICAgICAgICAgICAvLyBhY3R1YWwgY29vcmRpbmF0ZSBvZiB0aGUgbGFzdCBjb21taXR0ZWQgcG9pbnRcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFggKyByeCxcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFkgKyByeSxcbiAgICAgICAgICAgICAgLy8gY3Vyc29yLWdyaWQgY29vcmRpbmF0ZVxuICAgICAgICAgICAgICBncmlkWCxcbiAgICAgICAgICAgICAgZ3JpZFksXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1BhdGhBTG9vcChwb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVwZGF0ZSBsYXN0IHVuY29tbWl0dGVkIHBvaW50XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAuLi5wb2ludHMuc2xpY2UoMCwgLTEpLFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWCArIGR4RnJvbUxhc3RDb21taXR0ZWQsXG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRZICsgZHlGcm9tTGFzdENvbW1pdHRlZCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNEZXNlbGVjdGVkQnV0dG9uID0gQm9vbGVhbihldmVudC5idXR0b25zKTtcbiAgICBpZiAoXG4gICAgICBoYXNEZXNlbGVjdGVkQnV0dG9uIHx8XG4gICAgICAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwidGV4dFwiICYmXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcImVyYXNlclwiKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICBpZiAoXG4gICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgIWlzT3ZlclNjcm9sbEJhciAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnRcbiAgICApIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgJiZcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGVcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSAmJiAhaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAodHJhbnNmb3JtSGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcbiAgICB0aGlzLmhpdExpbmtFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50TGlua0F0UG9zaXRpb24oXG4gICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICBoaXRFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLmhpdExpbmtFbGVtZW50LmlkXVxuICAgICkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgIHNob3dIeXBlcmxpbmtUb29sdGlwKHRoaXMuaGl0TGlua0VsZW1lbnQsIHRoaXMuc3RhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWRlSHlwZXJsaW5rVG9vbGlwKCk7XG4gICAgICBpZiAoXG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgaGl0RWxlbWVudC5saW5rICYmXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdICYmXG4gICAgICAgICF0aGlzLmNvbnRleHRNZW51T3BlbiAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXBcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0h5cGVybGlua1BvcHVwOiBcImluZm9cIiB9KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBpc1RleHRFbGVtZW50KGhpdEVsZW1lbnQpID8gQ1VSU09SX1RZUEUuVEVYVCA6IENVUlNPUl9UWVBFLkNST1NTSEFJUixcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGFuZGxlSG92ZXJTZWxlY3RlZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgLy8gaWYgdXNpbmcgY21kL2N0cmwsIHdlJ3JlIG5vdCBkcmFnZ2luZ1xuICAgICAgICAhZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiZcbiAgICAgICAgKGhpdEVsZW1lbnQgfHxcbiAgICAgICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICApKSAmJlxuICAgICAgICAhaGl0RWxlbWVudD8ubG9ja2VkXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlRXJhc2VyID0gKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBzY2VuZVBvaW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSxcbiAgKSA9PiB7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudElkcyA9IChlbGVtZW50czogRXhjYWxpZHJhd0VsZW1lbnRbXSkgPT4ge1xuICAgICAgZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoZWxlbWVudC5sb2NrZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZHNUb1VwZGF0ZS5wdXNoKGVsZW1lbnQuaWQpO1xuICAgICAgICBpZiAoZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXSAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXS5lcmFzZVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXS5lcmFzZSA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXSkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0gPSB7XG4gICAgICAgICAgICBlcmFzZTogdHJ1ZSxcbiAgICAgICAgICAgIG9wYWNpdHk6IGVsZW1lbnQub3BhY2l0eSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgY29uc3QgaWRzVG9VcGRhdGU6IEFycmF5PHN0cmluZz4gPSBbXTtcblxuICAgIGNvbnN0IGRpc3RhbmNlID0gZGlzdGFuY2UyZChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnksXG4gICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICk7XG4gICAgY29uc3QgdGhyZXNob2xkID0gMTAgLyB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgY29uc3QgcG9pbnQgPSB7IC4uLnBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcyB9O1xuICAgIGxldCBzYW1wbGluZ0ludGVydmFsID0gMDtcbiAgICB3aGlsZSAoc2FtcGxpbmdJbnRlcnZhbCA8PSBkaXN0YW5jZSkge1xuICAgICAgY29uc3QgaGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihwb2ludC54LCBwb2ludC55KTtcbiAgICAgIHVwZGF0ZUVsZW1lbnRJZHMoaGl0RWxlbWVudHMpO1xuXG4gICAgICAvLyBFeGl0IHNpbmNlIHdlIHJlYWNoZWQgY3VycmVudCBwb2ludFxuICAgICAgaWYgKHNhbXBsaW5nSW50ZXJ2YWwgPT09IGRpc3RhbmNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBDYWxjdWxhdGUgbmV4dCBwb2ludCBpbiB0aGUgbGluZSBhdCBhIGRpc3RhbmNlIG9mIHNhbXBsaW5nIGludGVydmFsXG4gICAgICBzYW1wbGluZ0ludGVydmFsID0gTWF0aC5taW4oc2FtcGxpbmdJbnRlcnZhbCArIHRocmVzaG9sZCwgZGlzdGFuY2UpO1xuXG4gICAgICBjb25zdCBkaXN0YW5jZVJhdGlvID0gc2FtcGxpbmdJbnRlcnZhbCAvIGRpc3RhbmNlO1xuICAgICAgY29uc3QgbmV4dFggPVxuICAgICAgICAoMSAtIGRpc3RhbmNlUmF0aW8pICogcG9pbnQueCArIGRpc3RhbmNlUmF0aW8gKiBzY2VuZVBvaW50ZXIueDtcbiAgICAgIGNvbnN0IG5leHRZID1cbiAgICAgICAgKDEgLSBkaXN0YW5jZVJhdGlvKSAqIHBvaW50LnkgKyBkaXN0YW5jZVJhdGlvICogc2NlbmVQb2ludGVyLnk7XG4gICAgICBwb2ludC54ID0gbmV4dFg7XG4gICAgICBwb2ludC55ID0gbmV4dFk7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlKSA9PiB7XG4gICAgICBjb25zdCBpZCA9XG4gICAgICAgIGlzQm91bmRUb0NvbnRhaW5lcihlbGUpICYmIGlkc1RvVXBkYXRlLmluY2x1ZGVzKGVsZS5jb250YWluZXJJZClcbiAgICAgICAgICA/IGVsZS5jb250YWluZXJJZFxuICAgICAgICAgIDogZWxlLmlkO1xuICAgICAgaWYgKGlkc1RvVXBkYXRlLmluY2x1ZGVzKGlkKSkge1xuICAgICAgICBpZiAoZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtpZF0gJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaWRdLmVyYXNlID09PSBmYWxzZVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2lkXS5vcGFjaXR5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IEVMRU1FTlRfUkVBRFlfVE9fRVJBU0VfT1BBQ0lUWSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGVsZW1lbnRzKTtcblxuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gc2NlbmVQb2ludGVyLng7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBzY2VuZVBvaW50ZXIueTtcbiAgfTtcbiAgLy8gc2V0IHRvdWNoIG1vdmluZyBmb3IgbW9iaWxlIGNvbnRleHQgbWVudVxuICBwcml2YXRlIGhhbmRsZVRvdWNoTW92ZSA9IChldmVudDogUmVhY3QuVG91Y2hFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4pID0+IHtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICB9O1xuXG4gIGhhbmRsZUhvdmVyU2VsZWN0ZWRMaW5lYXJFbGVtZW50KFxuICAgIGxpbmVhckVsZW1lbnRFZGl0b3I6IExpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgc2NlbmVQb2ludGVyWDogbnVtYmVyLFxuICAgIHNjZW5lUG9pbnRlclk6IG51bWJlcixcbiAgKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChcbiAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IuZWxlbWVudElkLFxuICAgICk7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICBsZXQgaG92ZXJQb2ludEluZGV4ID0gLTE7XG4gICAgICBpZiAoXG4gICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KGVsZW1lbnQsIHRoaXMuc3RhdGUsIFtcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIF0pXG4gICAgICApIHtcbiAgICAgICAgaG92ZXJQb2ludEluZGV4ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEluZGV4VW5kZXJDdXJzb3IoXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICApO1xuICAgICAgICBpZiAoaG92ZXJQb2ludEluZGV4ID49IDApIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5ob3ZlclBvaW50SW5kZXggIT09IGhvdmVyUG9pbnRJbmRleFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBob3ZlclBvaW50SW5kZXgsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIHJlbW92ZSBhbnkgYWN0aXZlIHNlbGVjdGlvbiB3aGVuIHdlIHN0YXJ0IHRvIGludGVyYWN0IHdpdGggY2FudmFzXG4gICAgLy8gKG1haW5seSwgd2UgY2FyZSBhYm91dCByZW1vdmluZyBzZWxlY3Rpb24gb3V0c2lkZSB0aGUgY29tcG9uZW50IHdoaWNoXG4gICAgLy8gIHdvdWxkIHByZXZlbnQgb3VyIGNvcHkgaGFuZGxpbmcgb3RoZXJ3aXNlKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWxlY3Rpb24/LmFuY2hvck5vZGUpIHtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICB9XG4gICAgdGhpcy5tYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyhldmVudCk7XG4gICAgdGhpcy5tYXliZUNsZWFudXBBZnRlck1pc3NpbmdQb2ludGVyVXAoZXZlbnQpO1xuXG4gICAgLy9maXJlcyBvbmx5IG9uY2UsIGlmIHBlbiBpcyBkZXRlY3RlZCwgcGVuTW9kZSBpcyBlbmFibGVkXG4gICAgLy90aGUgdXNlciBjYW4gZGlzYWJsZSB0aGlzIGJ5IHRvZ2dsaW5nIHRoZSBwZW5Nb2RlIGJ1dHRvblxuICAgIGlmICghdGhpcy5zdGF0ZS5wZW5EZXRlY3RlZCAmJiBldmVudC5wb2ludGVyVHlwZSA9PT0gXCJwZW5cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGVuTW9kZTogdHJ1ZSxcbiAgICAgICAgICBwZW5EZXRlY3RlZDogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICF0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuICYmXG4gICAgICBbXCJwZW5cIiwgXCJ0b3VjaFwiXS5pbmNsdWRlcyhldmVudC5wb2ludGVyVHlwZSlcbiAgICApIHtcbiAgICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7IGlzVG91Y2hTY3JlZW46IHRydWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubGFzdFBvaW50ZXJEb3duID0gZXZlbnQ7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBsYXN0UG9pbnRlckRvd25XaXRoOiBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgIGN1cnNvckJ1dHRvbjogXCJkb3duXCIsXG4gICAgfSk7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcImRvd25cIik7XG5cbiAgICB0aGlzLnVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyhldmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBvbmx5IGhhbmRsZSBsZWZ0IG1vdXNlIGJ1dHRvbiBvciB0b3VjaFxuICAgIGlmIChcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uTUFJTiAmJlxuICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5UT1VDSFxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRvbid0IHNlbGVjdCB3aGlsZSBwYW5uaW5nXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA+IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGF0ZSBmb3IgdGhlIGR1cmF0aW9uIG9mIGEgcG9pbnRlciBpbnRlcmFjdGlvbiwgd2hpY2ggc3RhcnRzIHdpdGggYVxuICAgIC8vIHBvaW50ZXJEb3duIGV2ZW50LCBlbmRzIHdpdGggYSBwb2ludGVyVXAgZXZlbnQgKG9yIGFub3RoZXIgcG9pbnRlckRvd24pXG4gICAgY29uc3QgcG9pbnRlckRvd25TdGF0ZSA9IHRoaXMuaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2luY2UgY29udGV4dCBtZW51IGNsb3NlcyBvbiBwb2ludGVyIGRvd24gc28gc2V0dGluZyB0byBmYWxzZVxuICAgIHRoaXMuY29udGV4dE1lbnVPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFsbG93T25Qb2ludGVyRG93biA9XG4gICAgICAhdGhpcy5zdGF0ZS5wZW5Nb2RlIHx8XG4gICAgICBldmVudC5wb2ludGVyVHlwZSAhPT0gXCJ0b3VjaFwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiO1xuXG4gICAgaWYgKCFhbGxvd09uUG9pbnRlckRvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICB0aGlzLmhhbmRsZVRleHRPblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwibGluZVwiXG4gICAgKSB7XG4gICAgICB0aGlzLmhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgLy8gcmVzZXQgaW1hZ2UgcHJldmlldyBvbiBwb2ludGVyZG93blxuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5DUk9TU0hBSVIpO1xuXG4gICAgICAvLyByZXRyaWV2ZSB0aGUgbGF0ZXN0IGVsZW1lbnQgYXMgdGhlIHN0YXRlIG1heSBiZSBzdGFsZVxuICAgICAgY29uc3QgcGVuZGluZ0ltYWdlRWxlbWVudCA9XG4gICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkICYmXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudCh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCk7XG5cbiAgICAgIGlmICghcGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IHBlbmRpbmdJbWFnZUVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBwZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwsXG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgICBtdXRhdGVFbGVtZW50KHBlbmRpbmdJbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgdGhpcy5oYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiY3VzdG9tXCIpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIikge1xuICAgICAgdGhpcy5jcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb3BzPy5vblBvaW50ZXJEb3duPy4odGhpcy5zdGF0ZS5hY3RpdmVUb29sLCBwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPVxuICAgICAgdGhpcy5vblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID1cbiAgICAgIHRoaXMub25Qb2ludGVyVXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25LZXlEb3duID0gdGhpcy5vbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIGNvbnN0IG9uS2V5VXAgPSB0aGlzLm9uS2V5VXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgaWYgKCF0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIG9uS2V5RG93bik7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgb25LZXlVcCk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSA9IG9uUG9pbnRlck1vdmU7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAgPSBvblBvaW50ZXJVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCA9IG9uS2V5VXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biA9IG9uS2V5RG93bjtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyVXAgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMubGFzdFBvaW50ZXJVcCA9IGV2ZW50O1xuICAgIGlmICh0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuKSB7XG4gICAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WDogZXZlbnQuY2xpZW50WCwgY2xpZW50WTogZXZlbnQuY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICApO1xuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5oaXRMaW5rRWxlbWVudC5pZF1cbiAgICApIHtcbiAgICAgIHRoaXMucmVkaXJlY3RUb0xpbmsoZXZlbnQsIHRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4pO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlUG9pbnRlcihldmVudCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCA9PiB7XG4gICAgLy8gZGVhbCB3aXRoIG9wZW5pbmcgY29udGV4dCBtZW51IG9uIHRvdWNoIGRldmljZXNcbiAgICBpZiAoZXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIikge1xuICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbiAgICAgIGlmICh0b3VjaFRpbWVvdXQpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUncyBhbHJlYWR5IGEgdG91Y2hUaW1lb3V0LCB0aGlzIG1lYW5zIHRoYXQgdGhlcmUncyBhbm90aGVyXG4gICAgICAgIC8vIHRvdWNoIGRvd24gYW5kIHdlIGFyZSBkb2luZyBhbm90aGVyIHRvdWNoLCBzbyB3ZSBzaG91bGRuJ3Qgb3BlbiB0aGVcbiAgICAgICAgLy8gY29udGV4dCBtZW51LlxuICAgICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb3BlbiB0aGUgY29udGV4dCBtZW51IHdpdGggdGhlIGZpcnN0IHRvdWNoJ3MgY2xpZW50WCBhbmQgY2xpZW50WVxuICAgICAgICAvLyBpZiB0aGUgdG91Y2ggaXMgbm90IG1vdmluZ1xuICAgICAgICB0b3VjaFRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICAgICAgICBpZiAoIWludmFsaWRhdGVDb250ZXh0TWVudSkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudShldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBUT1VDSF9DVFhfTUVOVV9USU1FT1VUKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldENvbnRleHRNZW51VGltZXIgPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgaWYgKGxhc3RQb2ludGVyVXAgIT09IG51bGwpIHtcbiAgICAgIC8vIFVuZm9ydHVuYXRlbHksIHNvbWV0aW1lcyB3ZSBkb24ndCBnZXQgYSBwb2ludGVydXAgYWZ0ZXIgYSBwb2ludGVyZG93bixcbiAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29udGV4dHVhbCBtZW51IG9yIGFsZXJ0IGlzIHRyaWdnZXJlZC4gSW4gb3JkZXIgdG8gYXZvaWRcbiAgICAgIC8vIGJlaW5nIGluIGEgd2VpcmQgc3RhdGUsIHdlIGNsZWFuIHVwIG9uIHRoZSBuZXh0IHBvaW50ZXJkb3duXG4gICAgICBsYXN0UG9pbnRlclVwKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgcGFubmluZ1xuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKFxuICAgICAgIShcbiAgICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplIDw9IDEgJiZcbiAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uV0hFRUwgfHxcbiAgICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmIGlzSG9sZGluZ1NwYWNlKSB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKVxuICAgICAgKSB8fFxuICAgICAgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBsZXQgbmV4dFBhc3RlUHJldmVudGVkID0gZmFsc2U7XG4gICAgY29uc3QgaXNMaW51eCA9IC9MaW51eC8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtKTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgIGxldCB7IGNsaWVudFg6IGxhc3RYLCBjbGllbnRZOiBsYXN0WSB9ID0gZXZlbnQ7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgZGVsdGFYID0gbGFzdFggLSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZGVsdGFZID0gbGFzdFkgLSBldmVudC5jbGllbnRZO1xuICAgICAgbGFzdFggPSBldmVudC5jbGllbnRYO1xuICAgICAgbGFzdFkgPSBldmVudC5jbGllbnRZO1xuXG4gICAgICAvKlxuICAgICAgICogUHJldmVudCBwYXN0ZSBldmVudCBpZiB3ZSBtb3ZlIHdoaWxlIG1pZGRsZSBjbGlja2luZyBvbiBMaW51eC5cbiAgICAgICAqIFNlZSBpc3N1ZSAjMTM4My5cbiAgICAgICAqL1xuICAgICAgaWYgKFxuICAgICAgICBpc0xpbnV4ICYmXG4gICAgICAgICFuZXh0UGFzdGVQcmV2ZW50ZWQgJiZcbiAgICAgICAgKE1hdGguYWJzKGRlbHRhWCkgPiAxIHx8IE1hdGguYWJzKGRlbHRhWSkgPiAxKVxuICAgICAgKSB7XG4gICAgICAgIG5leHRQYXN0ZVByZXZlbnRlZCA9IHRydWU7XG5cbiAgICAgICAgLyogUHJldmVudCB0aGUgbmV4dCBwYXN0ZSBldmVudCAqL1xuICAgICAgICBjb25zdCBwcmV2ZW50TmV4dFBhc3RlID0gKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLypcbiAgICAgICAgICogUmVlbmFibGUgbmV4dCBwYXN0ZSBpbiBjYXNlIG9mIGRpc2FibGVkIG1pZGRsZSBjbGljayBwYXN0ZSBmb3JcbiAgICAgICAgICogYW55IHJlYXNvbjpcbiAgICAgICAgICogLSByaWdodCBjbGljayBwYXN0ZVxuICAgICAgICAgKiAtIGVtcHR5IGNsaXBib2FyZFxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZW5hYmxlTmV4dFBhc3RlID0gKCkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIGVuYWJsZU5leHRQYXN0ZSk7XG4gICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZGVsdGFYIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFkgLSBkZWx0YVkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBjb25zdCB0ZWFyZG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAgIChsYXN0UG9pbnRlclVwID0gKCkgPT4ge1xuICAgICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgICAgaXNQYW5uaW5nID0gZmFsc2U7XG4gICAgICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwidXBcIik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRlYXJkb3duKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgICAgICBvblBvaW50ZXJNb3ZlLmZsdXNoKCk7XG4gICAgICB9KSxcbiAgICApO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUsIHtcbiAgICAgIHBhc3NpdmU6IHRydWUsXG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGVhcmRvd24pO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlR2VzdHVyZU9uUG9pbnRlckRvd24oXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQge1xuICAgIGdlc3R1cmUucG9pbnRlcnMuc2V0KGV2ZW50LnBvaW50ZXJJZCwge1xuICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgfSk7XG5cbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAyKSB7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlID0gZ2V0RGlzdGFuY2UoXG4gICAgICAgIEFycmF5LmZyb20oZ2VzdHVyZS5wb2ludGVycy52YWx1ZXMoKSksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IFBvaW50ZXJEb3duU3RhdGUge1xuICAgIGNvbnN0IG9yaWdpbiA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBvcmlnaW4sXG4gICAgICB3aXRoQ21kT3JDdHJsOiBldmVudFtLRVlTLkNUUkxfT1JfQ01EXSxcbiAgICAgIG9yaWdpbkluR3JpZDogdHVwbGVUb0Nvb3JzKFxuICAgICAgICBnZXRHcmlkUG9pbnQob3JpZ2luLngsIG9yaWdpbi55LCB0aGlzLnN0YXRlLmdyaWRTaXplKSxcbiAgICAgICksXG4gICAgICBzY3JvbGxiYXJzOiBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgICAgZXZlbnQuY2xpZW50WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgKSxcbiAgICAgIC8vIHdlIG5lZWQgdG8gZHVwbGljYXRlIGJlY2F1c2Ugd2UnbGwgYmUgdXBkYXRpbmcgdGhpcyBzdGF0ZVxuICAgICAgbGFzdENvb3JkczogeyAuLi5vcmlnaW4gfSxcbiAgICAgIG9yaWdpbmFsRWxlbWVudHM6IHRoaXMuc2NlbmVcbiAgICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgIC5yZWR1Y2UoKGFjYywgZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGFjYy5zZXQoZWxlbWVudC5pZCwgZGVlcENvcHlFbGVtZW50KGVsZW1lbnQpKTtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCBuZXcgTWFwKCkgYXMgUG9pbnRlckRvd25TdGF0ZVtcIm9yaWdpbmFsRWxlbWVudHNcIl0pLFxuICAgICAgcmVzaXplOiB7XG4gICAgICAgIGhhbmRsZVR5cGU6IGZhbHNlLFxuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgYXJyb3dEaXJlY3Rpb246IFwib3JpZ2luXCIsXG4gICAgICAgIGNlbnRlcjogeyB4OiAobWF4WCArIG1pblgpIC8gMiwgeTogKG1heFkgKyBtaW5ZKSAvIDIgfSxcbiAgICAgIH0sXG4gICAgICBoaXQ6IHtcbiAgICAgICAgZWxlbWVudDogbnVsbCxcbiAgICAgICAgYWxsSGl0RWxlbWVudHM6IFtdLFxuICAgICAgICB3YXNBZGRlZFRvU2VsZWN0aW9uOiBmYWxzZSxcbiAgICAgICAgaGFzQmVlbkR1cGxpY2F0ZWQ6IGZhbHNlLFxuICAgICAgICBoYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50czpcbiAgICAgICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICApLFxuICAgICAgICBoYXNIaXRFbGVtZW50SW5zaWRlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBkcmFnOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGV2ZW50TGlzdGVuZXJzOiB7XG4gICAgICAgIG9uTW92ZTogbnVsbCxcbiAgICAgICAgb25VcDogbnVsbCxcbiAgICAgICAgb25LZXlVcDogbnVsbCxcbiAgICAgICAgb25LZXlEb3duOiBudWxsLFxuICAgICAgfSxcbiAgICAgIGJveFNlbGVjdGlvbjoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZWxlbWVudElkc1RvRXJhc2U6IHt9LFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgZHJhZ2dpbmcgYSBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVEcmFnZ2luZ1Njcm9sbEJhcihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoXG4gICAgICAhKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJFaXRoZXIgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gdHJ1ZTtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IGV2ZW50LmNsaWVudFg7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gZmFsc2U7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIG9uUG9pbnRlck1vdmUuZmx1c2goKTtcbiAgICB9KTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24gPSAoKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIGV2ZW50IGhhcyBiZWVuIGNvbXBsZXRlbHkgaGFuZGxlZFxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9XG4gICAgICAgICAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgICApO1xuICAgICAgICBpZiAoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICE9IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHJlc2l6aW5nRWxlbWVudDogZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLmVsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9XG4gICAgICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlOiBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5pc1Jlc2l6aW5nID0gdHJ1ZTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldFJlc2l6ZU9mZnNldFhZKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkgJiZcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLnBvaW50cy5sZW5ndGggPT09IDJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuYXJyb3dEaXJlY3Rpb24gPSBnZXRSZXNpemVBcnJvd0RpcmVjdGlvbihcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IGxpbmVhckVsZW1lbnRFZGl0b3IgPVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fCB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudDtcbiAgICAgICAgICBjb25zdCByZXQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJEb3duKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJldC5oaXRFbGVtZW50KSB7XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID0gcmV0LmhpdEVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQubGluZWFyRWxlbWVudEVkaXRvcikge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkTGluZWFyRWxlbWVudDogcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgfSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudDogcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQuZGlkQWRkUG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoaXRFbGVtZW50IG1heSBhbHJlYWR5IGJlIHNldCBhYm92ZSwgc28gY2hlY2sgZmlyc3RcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA/P1xuICAgICAgICAgIHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApO1xuXG4gICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgLy8gRWFybHkgcmV0dXJuIGlmIHBvaW50ZXIgaXMgaGl0dGluZyBsaW5rIGljb25cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc1BvaW50SGl0dGluZ0xpbmtJY29uKFxuICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCwgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueV0sXG4gICAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlID1cbiAgICAgICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KFxuICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCwgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueV0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIG92ZXJsYXBwZWQgZWxlbWVudHMgb25lIHBvc2l0aW9uIG1heSBoaXRcbiAgICAgICAgLy8gbXVsdGlwbGUgZWxlbWVudHNcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT5cbiAgICAgICAgICAgIHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAoaGl0RWxlbWVudCA9PT0gbnVsbCB8fCAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkKSAmJlxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICBbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBJZiB3ZSBjbGljayBvbiBzb21ldGhpbmdcbiAgICAgICAgfSBlbHNlIGlmIChoaXRFbGVtZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAvLyBvbiBDTUQvQ1RSTCwgZHJpbGwgZG93biB0byBoaXQgZWxlbWVudCByZWdhcmRsZXNzIG9mIGdyb3VwcyBldGMuXG4gICAgICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICAuLi5lZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQocHJldlN0YXRlLCBoaXRFbGVtZW50KSxcbiAgICAgICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgLy8gbWFyayBhcyBub3QgY29tcGxldGVseSBoYW5kbGVkIHNvIGFzIHRvIGFsbG93IGRyYWdnaW5nIGV0Yy5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBkZXNlbGVjdCBpZiBpdGVtIGlzIHNlbGVjdGVkXG4gICAgICAgICAgLy8gaWYgc2hpZnQgaXMgbm90IGNsaWNrZWQsIHRoaXMgd2lsbCBhbHdheXMgcmV0dXJuIHRydWVcbiAgICAgICAgICAvLyBvdGhlcndpc2UsIGl0IHdpbGwgdHJpZ2dlciBzZWxlY3Rpb24gYmFzZWQgb24gY3VycmVudFxuICAgICAgICAgIC8vIHN0YXRlIG9mIHRoZSBib3hcbiAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgY3VycmVudGx5IGVkaXRpbmcgYSBncm91cCwgZXhpdGluZyBlZGl0aW5nIG1vZGUgYW5kIGRlc2VsZWN0IHRoZSBncm91cC5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICAgICAgICAhaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBZGQgaGl0IGVsZW1lbnQgdG8gc2VsZWN0aW9uLiBBdCB0aGlzIHBvaW50IGlmIHdlJ3JlIG5vdCBob2xkaW5nXG4gICAgICAgICAgICAvLyBTSElGVCB0aGUgcHJldmlvdXNseSBzZWxlY3RlZCBlbGVtZW50KHMpIHdlcmUgZGVzZWxlY3RlZCBhYm92ZVxuICAgICAgICAgICAgLy8gKG1ha2Ugc3VyZSB5b3UgdXNlIHNldFN0YXRlIHVwZGF0ZXIgdG8gdXNlIGxhdGVzdCBzdGF0ZSlcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgIXNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCAmJlxuICAgICAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2hvd0h5cGVybGlua1BvcHVwOiBoaXRFbGVtZW50LmxpbmsgPyBcImluZm9cIiA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIGlzQVNlbGVjdGVkRWxlbWVudChoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGl0RWxlbWVudCAhPSBudWxsICYmIHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICBwb2ludDogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSG93IG1hbnkgcGl4ZWxzIG9mZiB0aGUgc2hhcGUgYm91bmRhcnkgd2Ugc3RpbGwgY29uc2lkZXIgYSBoaXRcbiAgICBjb25zdCB0aHJlc2hvbGQgPSAxMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHJldHVybiAoXG4gICAgICBwb2ludC54ID4geDEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnggPCB4MiArIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueSA+IHkxIC0gdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55IDwgeTIgKyB0aHJlc2hvbGRcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBpZiB3ZSdyZSBjdXJyZW50bHkgc3RpbGwgZWRpdGluZyB0ZXh0LCBjbGlja2luZyBvdXRzaWRlXG4gICAgLy8gc2hvdWxkIG9ubHkgZmluYWxpemUgaXQsIG5vdCBjcmVhdGUgYW5vdGhlciAoaXJyZXNwZWN0aXZlXG4gICAgLy8gb2Ygc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpXG4gICAgaWYgKGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHNjZW5lWCA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLng7XG4gICAgbGV0IHNjZW5lWSA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSwge1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBjYW5CaW5kVGV4dCA9IGhhc0JvdW5kVGV4dEVsZW1lbnQoZWxlbWVudCk7XG4gICAgaWYgKGNhbkJpbmRUZXh0KSB7XG4gICAgICBzY2VuZVggPSBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoIC8gMjtcbiAgICAgIHNjZW5lWSA9IGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgICB9XG4gICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgIHNjZW5lWCxcbiAgICAgIHNjZW5lWSxcbiAgICAgIHNob3VsZEJpbmQ6IGZhbHNlLFxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI6ICFldmVudC5hbHRLZXksXG4gICAgfSk7XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICAvLyBCZWdpbiBhIG1hcmsgY2FwdHVyZS4gVGhpcyBkb2VzIG5vdCBoYXZlIHRvIHVwZGF0ZSBzdGF0ZSB5ZXQuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIG51bGwsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdGcmVlRHJhd0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICBzaW11bGF0ZVByZXNzdXJlOiBldmVudC5wcmVzc3VyZSA9PT0gMC41LFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBwcmVzc3VyZXMgPSBlbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgID8gZWxlbWVudC5wcmVzc3VyZXNcbiAgICAgIDogWy4uLmVsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHBvaW50czogW1swLCAwXV0sXG4gICAgICBwcmVzc3VyZXMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUltYWdlRWxlbWVudCA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgfToge1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIHNjZW5lWTogbnVtYmVyO1xuICB9KSA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoc2NlbmVYLCBzY2VuZVksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ltYWdlRWxlbWVudCh7XG4gICAgICB0eXBlOiBcImltYWdlXCIsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0xpbmVhckVsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIC8vIGZpbmFsaXplIGlmIGNvbXBsZXRpbmcgYSBsb29wXG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC50eXBlID09PSBcImxpbmVcIiAmJlxuICAgICAgICBpc1BhdGhBTG9vcChtdWx0aUVsZW1lbnQucG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgICApIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnksIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICAvLyBjbGlja2luZyBpbnNpZGUgY29tbWl0IHpvbmUg4oaSIGZpbmFsaXplIGFycm93XG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoID4gMSAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54IC0gcngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbbXVsdGlFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIC8vIGNsaWNraW5nIG91dHNpZGUgY29tbWl0IHpvbmUg4oaSIHVwZGF0ZSByZWZlcmVuY2UgZm9yIGxhc3QgY29tbWl0dGVkXG4gICAgICAvLyBwb2ludFxuICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICB9KTtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLyogSWYgYXJyb3cgaXMgcHJlLWFycm93aGVhZHMsIGl0IHdpbGwgaGF2ZSB1bmRlZmluZWQgZm9yIGJvdGggc3RhcnQgYW5kIGVuZCBhcnJvd2hlYWRzLlxuICAgICAgSWYgc28sIHdlIHdhbnQgaXQgdG8gYmUgbnVsbCBmb3Igc3RhcnQgYW5kIFwiYXJyb3dcIiBmb3IgZW5kLiBJZiB0aGUgbGluZWFyIGl0ZW0gaXMgbm90XG4gICAgICBhbiBhcnJvdywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBib3RoLiBPdGhlcndpc2UsIHdlIHdhbnQgaXQgdG8gdXNlIHRoZVxuICAgICAgdmFsdWVzIGZyb20gYXBwU3RhdGUuICovXG5cbiAgICAgIGNvbnN0IHsgY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCBbc3RhcnRBcnJvd2hlYWQsIGVuZEFycm93aGVhZF0gPVxuICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiXG4gICAgICAgICAgPyBbY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWRdXG4gICAgICAgICAgOiBbbnVsbCwgbnVsbF07XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdMaW5lYXJFbGVtZW50KHtcbiAgICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICAgIHg6IGdyaWRYLFxuICAgICAgICB5OiBncmlkWSxcbiAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgICAgc3RhcnRBcnJvd2hlYWQsXG4gICAgICAgIGVuZEFycm93aGVhZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgcG9pbnRzOiBbLi4uZWxlbWVudC5wb2ludHMsIFswLCAwXV0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICApO1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gUHJldmVudHMgZm9jdXMgZnJvbSBlc2NhcGluZyBleGNhbGlkcmF3IHRhYlxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkFMVCAmJiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzVGhyb3R0bGVkKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGluaXRpYWxpemUgZHJhZ09mZnNldFhZIG9ubHkgYWZ0ZXIgd2UndmUgdXBkYXRlZFxuICAgICAgLy8gYHN0YXRlLnNlbGVjdGVkRWxlbWVudElkc2Agb24gcG9pbnRlckRvd24uIERvaW5nIGl0IGhlcmUgaW4gcG9pbnRlck1vdmVcbiAgICAgIC8vIGV2ZW50IGhhbmRsZXIgc2hvdWxkIGhvcGVmdWxseSBlbnN1cmUgd2UncmUgYWxyZWFkeSB3b3JraW5nIHdpdGhcbiAgICAgIC8vIHRoZSB1cGRhdGVkIHN0YXRlLlxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPT09IG51bGwpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXREcmFnT2Zmc2V0WFkoXG4gICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG5cbiAgICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgICB0aGlzLmhhbmRsZUVyYXNlcihldmVudCwgcG9pbnRlckRvd25TdGF0ZSwgcG9pbnRlckNvb3Jkcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLy8gZm9yIGFycm93cy9saW5lcywgZG9uJ3Qgc3RhcnQgZHJhZ2dpbmcgdW50aWwgYSBnaXZlbiB0aHJlc2hvbGRcbiAgICAgIC8vIHRvIGVuc3VyZSB3ZSBkb24ndCBjcmVhdGUgYSAyLXBvaW50IGFycm93IGJ5IG1pc3Rha2Ugd2hlblxuICAgICAgLy8gdXNlciBjbGlja3MgbW91c2UgaW4gYSB3YXkgdGhhdCBpdCBtb3ZlcyBhIHRpbnkgYml0ICh0aHVzXG4gICAgICAvLyB0cmlnZ2VyaW5nIHBvaW50ZXJtb3ZlKVxuICAgICAgaWYgKFxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJhcnJvd1wiIHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwibGluZVwiKVxuICAgICAgKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSA8IERSQUdHSU5HX1RIUkVTSE9MRFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmlzUmVzaXppbmcpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgbGluZWFyRWxlbWVudEVkaXRvciA9XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fCB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudDtcbiAgICAgICAgY29uc3QgZGlkRHJhZyA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnREcmFnZ2luZyhcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKGVsZW1lbnQsIHBvaW50c1NjZW5lQ29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBwb2ludHNTY2VuZUNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICApO1xuICAgICAgICBpZiAoZGlkRHJhZykge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmlzRHJhZ2dpbmdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBoYXNIaXRBU2VsZWN0ZWRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZShcbiAgICAgICAgKGVsZW1lbnQpID0+IHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgKTtcblxuICAgICAgaWYgKFxuICAgICAgICAoaGFzSGl0QVNlbGVjdGVkRWxlbWVudCB8fFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSAmJlxuICAgICAgICAvLyB0aGlzIGFsbG93cyBmb3IgYm94LXNlbGVjdGluZyBwb2ludHMgd2hlbiBjbGlja2luZyBpbnNpZGUgdGhlXG4gICAgICAgIC8vIGxpbmUncyBib3VuZGluZyBib3hcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8ICFldmVudC5zaGlmdEtleSkgJiZcbiAgICAgICAgLy8gYm94LXNlbGVjdGluZyB3aXRob3V0IHNoaWZ0IHdoZW4gZWRpdGluZyBsaW5lLCBub3QgY2xpY2tpbmcgb24gYSBsaW5lXG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT1cbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ/LmlkIHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0RWxlbWVudEluc2lkZSkgJiZcbiAgICAgICAgKCF0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5lbGVtZW50SWQgIT09XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50Py5pZCB8fFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUpXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5ldmVyeSgoZWxlbWVudCkgPT4gZWxlbWVudC5sb2NrZWQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIE1hcmtpbmcgdGhhdCBjbGljayB3YXMgdXNlZCBmb3IgZHJhZ2dpbmcgdG8gY2hlY2tcbiAgICAgICAgLy8gaWYgZWxlbWVudHMgc2hvdWxkIGJlIGRlc2VsZWN0ZWQgb24gcG9pbnRlcnVwXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIC8vIHByZXZlbnQgZHJhZ2dpbmcgZXZlbiBpZiB3ZSdyZSBubyBsb25nZXIgaG9sZGluZyBjbWQvY3RybCBvdGhlcndpc2VcbiAgICAgICAgLy8gaXQgd291bGQgaGF2ZSB3ZWlyZCByZXN1bHRzIChzdHVmZiBqdW1waW5nIGFsbCBvdmVyIHRoZSBzY3JlZW4pXG4gICAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDAgJiYgIXBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCkge1xuICAgICAgICAgIGNvbnN0IFtkcmFnWCwgZHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgW2RyYWdEaXN0YW5jZVgsIGRyYWdEaXN0YW5jZVldID0gW1xuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCksXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55KSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgLy8gV2Ugb25seSBkcmFnIGluIG9uZSBkaXJlY3Rpb24gaWYgc2hpZnQgaXMgcHJlc3NlZFxuICAgICAgICAgIGNvbnN0IGxvY2tEaXJlY3Rpb24gPSBldmVudC5zaGlmdEtleTtcbiAgICAgICAgICBkcmFnU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ1gsXG4gICAgICAgICAgICBkcmFnWSxcbiAgICAgICAgICAgIGxvY2tEaXJlY3Rpb24sXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2VYLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgICAvLyBXZSBkdXBsaWNhdGUgdGhlIHNlbGVjdGVkIGVsZW1lbnQgaWYgYWx0IGlzIHByZXNzZWQgb24gcG9pbnRlciBtb3ZlXG4gICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSAmJiAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQpIHtcbiAgICAgICAgICAgIC8vIE1vdmUgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBlbGVtZW50cyB0byB0aGUgdG9wIG9mIHRoZSB6IGluZGV4IHN0YWNrLCBhbmRcbiAgICAgICAgICAgIC8vIHB1dCB0aGUgZHVwbGljYXRlcyB3aGVyZSB0aGUgc2VsZWN0ZWQgZWxlbWVudHMgdXNlZCB0byBiZS5cbiAgICAgICAgICAgIC8vICh0aGUgb3JpZ2luIHBvaW50IHdoZXJlIHRoZSBkcmFnZ2luZyBzdGFydGVkKVxuXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHNUb0FwcGVuZCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudElkczogQXJyYXk8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXT4gPVxuICAgICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlLCB0cnVlKS5tYXAoXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQpID0+IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzLmluY2x1ZGVzKGVsZW1lbnQuaWQpIHx8XG4gICAgICAgICAgICAgICAgLy8gY2FzZTogdGhlIHN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyBtaWdodCBub3QgaGF2ZSBiZWVuXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlZCB5ZXQgYnkgdGhlIHRpbWUgdGhpcyBtb3VzZW1vdmUgZXZlbnQgaXMgZmlyZWRcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24pXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZWRFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgICAgICAgICAgICBncm91cElkTWFwLFxuICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtvcmlnaW5EcmFnWCwgb3JpZ2luRHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChkdXBsaWNhdGVkRWxlbWVudCwge1xuICAgICAgICAgICAgICAgICAgeDogZHVwbGljYXRlZEVsZW1lbnQueCArIChvcmlnaW5EcmFnWCAtIGRyYWdYKSxcbiAgICAgICAgICAgICAgICAgIHk6IGR1cGxpY2F0ZWRFbGVtZW50LnkgKyAob3JpZ2luRHJhZ1kgLSBkcmFnWSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZHVwbGljYXRlZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBkdXBsaWNhdGVkRWxlbWVudC5pZCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5leHRTY2VuZUVsZW1lbnRzID0gWy4uLm5leHRFbGVtZW50cywgLi4uZWxlbWVudHNUb0FwcGVuZF07XG4gICAgICAgICAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0RWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICAgXCJkdXBsaWNhdGVzU2VydmVBc09sZFwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRTY2VuZUVsZW1lbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEl0IGlzIHZlcnkgaW1wb3J0YW50IHRvIHJlYWQgdGhpcy5zdGF0ZSB3aXRoaW4gZWFjaCBtb3ZlIGV2ZW50LFxuICAgICAgLy8gb3RoZXJ3aXNlIHdlIHdvdWxkIHJlYWQgYSBzdGFsZSBvbmUhXG4gICAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgY29uc3QgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgY29uc3QgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHMubGVuZ3RoID4gMCAmJiBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCBkaXNjYXJkUG9pbnQgPVxuICAgICAgICAgIGxhc3RQb2ludCAmJiBsYXN0UG9pbnRbMF0gPT09IGR4ICYmIGxhc3RQb2ludFsxXSA9PT0gZHk7XG5cbiAgICAgICAgaWYgKCFkaXNjYXJkUG9pbnQpIHtcbiAgICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgICAgPyBkcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzXG4gICAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNMaW5lYXJFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgbGV0IGR4ID0gZ3JpZFggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gZ3JpZFkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBpZiAoc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpICYmIHBvaW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAoeyB3aWR0aDogZHgsIGhlaWdodDogZHkgfSA9IGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZShcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudC54LFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LnksXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7IHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cy5zbGljZSgwLCAtMSksIFtkeCwgZHldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpKSB7XG4gICAgICAgICAgLy8gV2hlbiBjcmVhdGluZyBhIGxpbmVhciBlbGVtZW50IGJ5IGRyYWdnaW5nXG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIFtwb2ludGVyQ29vcmRzXSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgICAvLyBhbGxvd3MgZm9yIGJveC1zZWxlY3RpbmcgcG9pbnRzICh3aXRob3V0IHNoaWZ0KVxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKGVsZW1lbnRzLCB0aGlzLnN0YXRlKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsICYmIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBib3gtc2VsZWN0IGxpbmUgZWRpdG9yIHBvaW50c1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlQm94U2VsZWN0aW9uKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gcmVndWxhciBib3gtc2VsZWN0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24gPSBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbihcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5lbGVtZW50c1dpdGhpblNlbGVjdGlvbi5yZWR1Y2UoXG4gICAgICAgICAgICAgICAgICAgIChhY2M6IFJlY29yZDxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdLCB0cnVlPiwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGFjY1tlbGVtZW50LmlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgLi4uKHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB1c2luZyBjdHJsL2NtZCwgc2VsZWN0IHRoZSBoaXRFbGVtZW50IG9ubHkgaWYgd2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmVuJ3QgYm94LXNlbGVjdGVkIGFueXRoaW5nIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LmlkXTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIWVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDogbnVsbCksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6XG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdLmxpbmtcbiAgICAgICAgICAgICAgICAgICAgPyBcImluZm9cIlxuICAgICAgICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgICAgIC8vIHNlbGVjdCBsaW5lYXIgZWxlbWVudCBvbmx5IHdoZW4gd2UgaGF2ZW4ndCBib3gtc2VsZWN0ZWQgYW55dGhpbmcgZWxzZVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDpcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdKVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgbW92ZSBoYXBwZW5lZCBvdmVyIGVpdGhlciBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJIb3Jpem9udGFsKSB7XG4gICAgICBjb25zdCB4ID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGR4ID0geCAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54O1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGR4IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHg7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3ZlclZlcnRpY2FsKSB7XG4gICAgICBjb25zdCB5ID0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGNvbnN0IGR5ID0geSAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55O1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGR5IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGNoaWxkRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudCxcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICBhY3RpdmVUb29sLFxuICAgICAgICBpc1Jlc2l6aW5nLFxuICAgICAgICBpc1JvdGF0aW5nLFxuICAgICAgfSA9IHRoaXMuc3RhdGU7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIGlzUm90YXRpbmc6IGZhbHNlLFxuICAgICAgICByZXNpemluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICAvLyB0ZXh0IGVsZW1lbnRzIGFyZSByZXNldCBvbiBmaW5hbGl6ZSwgYW5kIHJlc2V0dGluZyBvbiBwb2ludGVydXBcbiAgICAgICAgLy8gbWF5IGNhdXNlIGlzc3VlcyB3aXRoIGRvdWJsZSB0YXBzXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgIG11bHRpRWxlbWVudCB8fCBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnRcbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGNoaWxkRXZlbnQuY2xpZW50WCwgY2hpbGRFdmVudC5jbGllbnRZLCBcInVwXCIpO1xuXG4gICAgICAvLyBIYW5kbGUgZW5kIG9mIGRyYWdnaW5nIGEgcG9pbnQgb2YgYSBsaW5lYXIgZWxlbWVudCwgbWlnaHQgY2xvc2UgYSBsb29wXG4gICAgICAvLyBhbmQgc2V0cyBiaW5kaW5nIGVsZW1lbnRcbiAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgICAocG9pbnRlckRvd25TdGF0ZS5oaXQ/LmVsZW1lbnQ/LmlkICE9PVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgfHxcbiAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJVcChcbiAgICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5lbGVtZW50SWQgfHxcbiAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlKVxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEVMZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCB0byBudWxsIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgZWxlbWVudCBzZWxlY3RlZCBzaW5jZSB3ZSBkb24ndCB3YW50IHRvIHNob3cgbGluZWFyIGVsZW1lbnQgaGFuZGxlc1xuICAgICAgICAgIGlmIChzZWxlY3RlZEVMZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGxpbmVhckVsZW1lbnRFZGl0b3IgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJVcChcbiAgICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHsgc3RhcnRCaW5kaW5nRWxlbWVudCwgZW5kQmluZGluZ0VsZW1lbnQgfSA9XG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yO1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnQobGluZWFyRWxlbWVudEVkaXRvci5lbGVtZW50SWQpO1xuICAgICAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBiaW5kT3JVbmJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBzdGFydEJpbmRpbmdFbGVtZW50LFxuICAgICAgICAgICAgICBlbmRCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGxpbmVhckVsZW1lbnRFZGl0b3IgIT09IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZS5mbHVzaCgpO1xuICAgICAgfVxuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuUE9JTlRFUl9NT1ZFLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWURPV04sXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuS0VZVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCEsXG4gICAgICApO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogbnVsbCB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudD8udHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICAvLyBBbGxvd3MgZG90cyB0byBhdm9pZCBiZWluZyBmbGFnZ2VkIGFzIGluZmluaXRlbHkgc21hbGxcbiAgICAgICAgaWYgKGR4ID09PSBwb2ludHNbMF1bMF0gJiYgZHkgPT09IHBvaW50c1swXVsxXSkge1xuICAgICAgICAgIGR5ICs9IDAuMDAwMTtcbiAgICAgICAgICBkeCArPSAwLjAwMDE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBjaGlsZEV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IFtkeCwgZHldLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICB7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSBpbWFnZUVsZW1lbnQuaWQpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQhLnBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgICAgIW11bHRpRWxlbWVudFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAgIC4uLmRyYWdnaW5nRWxlbWVudC5wb2ludHMsXG4gICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQ6IGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiYgIW11bHRpRWxlbWVudCkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCBmYWxzZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10sIHN0YXJ0Qm91bmRFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICAgIGlmICghYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbZHJhZ2dpbmdFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICkge1xuICAgICAgICAvLyByZW1vdmUgaW52aXNpYmxlIGVsZW1lbnQgd2hpY2ggd2FzIGFkZGVkIGluIG9uUG9pbnRlckRvd25cbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5zbGljZSgwLCAtMSksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyhkcmFnZ2luZ0VsZW1lbnQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCAmJiBpc0ludmlzaWJseVNtYWxsRWxlbWVudChyZXNpemluZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSByZXNpemluZ0VsZW1lbnQuaWQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDb2RlIGJlbG93IGhhbmRsZXMgc2VsZWN0aW9uIHdoZW4gZWxlbWVudChzKSB3ZXJlbid0XG4gICAgICAvLyBkcmFnIG9yIGFkZGVkIHRvIHNlbGVjdGlvbiBvbiBwb2ludGVyIGRvd24gcGhhc2UuXG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgaXNMaW5lYXJFbGVtZW50KGhpdEVsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFTGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IHdoZW4gbm8gb3RoZXIgZWxlbWVudCBzZWxlY3RlZCBleGNlcHRcbiAgICAgICAgLy8gdGhlIG9uZSB3ZSd2ZSBoaXRcbiAgICAgICAgaWYgKHNlbGVjdGVkRUxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICAgIGNvbnN0IGRyYWdnZWREaXN0YW5jZSA9IGRpc3RhbmNlMmQoXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFgsXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFksXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRYLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZHJhZ2dlZERpc3RhbmNlID09PSAwKSB7XG4gICAgICAgICAgY29uc3Qgc2NlbmVQb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjbGllbnRYOiB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICAgICAgICAgIGNsaWVudFk6IHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgaGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBoaXRFbGVtZW50cy5mb3JFYWNoKFxuICAgICAgICAgICAgKGhpdEVsZW1lbnQpID0+XG4gICAgICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2hpdEVsZW1lbnQuaWRdID0ge1xuICAgICAgICAgICAgICAgIGVyYXNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IGhpdEVsZW1lbnQub3BhY2l0eSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVyYXNlRWxlbWVudHMocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LmtleXMocG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZSkubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucmVzdG9yZVJlYWR5VG9FcmFzZUVsZW1lbnRzKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiAmJlxuICAgICAgICAvLyBpZiB3ZSdyZSBlZGl0aW5nIGEgbGluZSwgcG9pbnRlcnVwIHNob3VsZG4ndCBzd2l0Y2ggc2VsZWN0aW9uIGlmXG4gICAgICAgIC8vIGJveCBzZWxlY3RlZFxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQpXG4gICAgICApIHtcbiAgICAgICAgLy8gd2hlbiBpbnNpZGUgbGluZSBlZGl0b3IsIHNoaWZ0IHNlbGVjdHMgcG9pbnRzIGluc3RlYWRcbiAgICAgICAgaWYgKGNoaWxkRXZlbnQuc2hpZnRLZXkgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIGlmIChpc1NlbGVjdGVkVmlhR3JvdXAodGhpcy5zdGF0ZSwgaGl0RWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgLy8gV2Ugd2FudCB0byB1bnNlbGVjdCBhbGwgZ3JvdXBzIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICAvLyBhcyB3ZWxsIGFzIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBncm91cHNcbiAgICAgICAgICAgICAgLy8gaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIGNvbnN0IGlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyA9IGhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAuZmxhdE1hcCgoZ3JvdXBJZCkgPT5cbiAgICAgICAgICAgICAgICAgIGdldEVsZW1lbnRzSW5Hcm91cChcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBJZCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5tYXAoKGVsZW1lbnQpID0+ICh7IFtlbGVtZW50LmlkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldklkLCBhY2MpID0+ICh7IC4uLnByZXZJZCwgLi4uYWNjIH0pLCB7fSk7XG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZ0lkKSA9PiAoeyBbZ0lkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXYsIGFjYykgPT4gKHsgLi4ucHJldiwgLi4uYWNjIH0pLCB7fSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIHJlbW92ZSBlbGVtZW50IGZyb20gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkRWxlbWVudElkcyA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICAgIHsgLi4ucHJldlN0YXRlLCBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld1NlbGVjdGVkRWxlbWVudElkcyB9LFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCBvbmx5IGlmIHRoYXRzIHRoZSBvbmx5IGVsZW1lbnQgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OlxuICAgICAgICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KG5ld1NlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBwcmV2U3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGFkZCBlbGVtZW50IHRvIHNlbGVjdGlvbiB3aGlsZVxuICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAuLi5zZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoaGl0RWxlbWVudCkgJiZcbiAgICAgICAgICAgICAgICAgIC8vIERvbid0IHNldCBgc2VsZWN0ZWRMaW5lYXJFbGVtZW50YCBpZiBpdHMgc2FtZSBhcyB0aGUgaGl0RWxlbWVudCwgdGhpcyBpcyBtYWlubHkgdG8gcHJldmVudCByZXNldHRpbmcgdGhlIGBob3ZlclBvaW50SW5kZXhgIHRvIC0xLlxuICAgICAgICAgICAgICAgICAgLy8gRnV0dXJlIHdlIHNob3VsZCB1cGRhdGUgdGhlIEFQSSB0byB0YWtlIGNhcmUgb2Ygc2V0dGluZyB0aGUgY29ycmVjdCBgaG92ZXJQb2ludEluZGV4YCB3aGVuIGluaXRpYWxpemVkXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudD8uZWxlbWVudElkICE9PSBoaXRFbGVtZW50LmlkXG4gICAgICAgICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoaGl0RWxlbWVudCwgdGhpcy5zY2VuZSlcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgIXRoaXMuc3RhdGUuaXNSZXNpemluZyAmJlxuICAgICAgICAoKGhpdEVsZW1lbnQgJiZcbiAgICAgICAgICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICkpIHx8XG4gICAgICAgICAgKCFoaXRFbGVtZW50ICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cykpXG4gICAgICApIHtcbiAgICAgICAgLy8gRGVzZWxlY3Qgc2VsZWN0ZWQgZWxlbWVudHNcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFhY3RpdmVUb29sLmxvY2tlZCAmJlxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwiZnJlZWRyYXdcIiAmJlxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnRcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQodGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgfHwgaXNSZXNpemluZyB8fCBpc1JvdGF0aW5nKSB7XG4gICAgICAgIChpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cykoXG4gICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhY3RpdmVUb29sLmxvY2tlZCAmJiBhY3RpdmVUb29sLnR5cGUgIT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVSZWFkeVRvRXJhc2VFbGVtZW50cyA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0ub3BhY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBpc0JvdW5kVG9Db250YWluZXIoZWxlKSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0gJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdLmVyYXNlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgIG9wYWNpdHk6IHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5vcGFjaXR5LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBlcmFzZUVsZW1lbnRzID0gKHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUpID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHsgaXNEZWxldGVkOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHsgaXNEZWxldGVkOiB0cnVlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZTtcbiAgICB9KTtcblxuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2UgPSBhc3luYyAoe1xuICAgIGltYWdlRmlsZSxcbiAgICBpbWFnZUVsZW1lbnQ6IF9pbWFnZUVsZW1lbnQsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldyA9IGZhbHNlLFxuICB9OiB7XG4gICAgaW1hZ2VGaWxlOiBGaWxlO1xuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudDtcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3PzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIC8vIGF0IHRoaXMgcG9pbnQgdGhpcyBzaG91bGQgYmUgZ3VhcmFudGVlZCBpbWFnZSBmaWxlLCBidXQgd2UgZG8gdGhpcyBjaGVja1xuICAgIC8vIHRvIHNhdGlzZnkgVFMgZG93biB0aGUgbGluZVxuICAgIGlmICghaXNTdXBwb3J0ZWRJbWFnZUZpbGUoaW1hZ2VGaWxlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMudW5zdXBwb3J0ZWRGaWxlVHlwZVwiKSk7XG4gICAgfVxuICAgIGNvbnN0IG1pbWVUeXBlID0gaW1hZ2VGaWxlLnR5cGU7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIFwid2FpdFwiKTtcblxuICAgIGlmIChtaW1lVHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IFNWR1N0cmluZ1RvRmlsZShcbiAgICAgICAgICBhd2FpdCBub3JtYWxpemVTVkcoYXdhaXQgaW1hZ2VGaWxlLnRleHQoKSksXG4gICAgICAgICAgaW1hZ2VGaWxlLm5hbWUsXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnN2Z0ltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGdlbmVyYXRlIGltYWdlIGlkIChieSBkZWZhdWx0IHRoZSBmaWxlIGRpZ2VzdCkgYmVmb3JlIGFueVxuICAgIC8vIHJlc2l6aW5nL2NvbXByZXNzaW9uIHRha2VzIHBsYWNlIHRvIGtlZXAgaXQgbW9yZSBwb3J0YWJsZVxuICAgIGNvbnN0IGZpbGVJZCA9IGF3YWl0ICgodGhpcy5wcm9wcy5nZW5lcmF0ZUlkRm9yRmlsZT8uKFxuICAgICAgaW1hZ2VGaWxlLFxuICAgICkgYXMgUHJvbWlzZTxGaWxlSWQ+KSB8fCBnZW5lcmF0ZUlkRnJvbUZpbGUoaW1hZ2VGaWxlKSk7XG5cbiAgICBpZiAoIWZpbGVJZCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkNvdWxkbid0IGdlbmVyYXRlIGZpbGUgaWQgb3IgdGhlIHN1cHBsaWVkIGBnZW5lcmF0ZUlkRm9yRmlsZWAgZGlkbid0IHJlc29sdmUgdG8gb25lLlwiLFxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nRmlsZURhdGEgPSB0aGlzLmZpbGVzW2ZpbGVJZF07XG4gICAgaWYgKCFleGlzdGluZ0ZpbGVEYXRhPy5kYXRhVVJMKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBhd2FpdCByZXNpemVJbWFnZUZpbGUoaW1hZ2VGaWxlLCB7XG4gICAgICAgICAgbWF4V2lkdGhPckhlaWdodDogREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIHRyeWluZyB0byByZXNpbmcgaW1hZ2UgZmlsZSBvbiBpbnNlcnRpb25cIiwgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW1hZ2VGaWxlLnNpemUgPiBNQVhfQUxMT1dFRF9GSUxFX0JZVEVTKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICB0KFwiZXJyb3JzLmZpbGVUb29CaWdcIiwge1xuICAgICAgICAgICAgbWF4U2l6ZTogYCR7TWF0aC50cnVuYyhNQVhfQUxMT1dFRF9GSUxFX0JZVEVTIC8gMTAyNCAvIDEwMjQpfU1CYCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvd0N1cnNvckltYWdlUHJldmlldykge1xuICAgICAgY29uc3QgZGF0YVVSTCA9IHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTDtcbiAgICAgIC8vIG9wdGltaXphdGlvbiBzbyB0aGF0IHdlIGRvbid0IHVubmVjZXNzYXJpbHkgcmVzaXplIHRoZSBvcmlnaW5hbFxuICAgICAgLy8gZnVsbC1zaXplIGZpbGUgZm9yIGN1cnNvciBwcmV2aWV3XG4gICAgICAvLyAoaXQncyBtdWNoIGZhc3RlciB0byBjb252ZXJ0IHRoZSByZXNpemVkIGRhdGFVUkwgdG8gRmlsZSlcbiAgICAgIGNvbnN0IHJlc2l6ZWRGaWxlID0gZGF0YVVSTCAmJiBkYXRhVVJMVG9GaWxlKGRhdGFVUkwpO1xuXG4gICAgICB0aGlzLnNldEltYWdlUHJldmlld0N1cnNvcihyZXNpemVkRmlsZSB8fCBpbWFnZUZpbGUpO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFVUkwgPVxuICAgICAgdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMIHx8IChhd2FpdCBnZXREYXRhVVJMKGltYWdlRmlsZSkpO1xuXG4gICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gbXV0YXRlRWxlbWVudChcbiAgICAgIF9pbWFnZUVsZW1lbnQsXG4gICAgICB7XG4gICAgICAgIGZpbGVJZCxcbiAgICAgIH0sXG4gICAgICBmYWxzZSxcbiAgICApIGFzIE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50PjtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD4+KFxuICAgICAgYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuZmlsZXMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmZpbGVzLFxuICAgICAgICAgICAgW2ZpbGVJZF06IHtcbiAgICAgICAgICAgICAgbWltZVR5cGUsXG4gICAgICAgICAgICAgIGlkOiBmaWxlSWQsXG4gICAgICAgICAgICAgIGRhdGFVUkwsXG4gICAgICAgICAgICAgIGNyZWF0ZWQ6IERhdGUubm93KCksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY2FjaGVkSW1hZ2VEYXRhID0gdGhpcy5pbWFnZUNhY2hlLmdldChmaWxlSWQpO1xuICAgICAgICAgIGlmICghY2FjaGVkSW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFtpbWFnZUVsZW1lbnRdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNhY2hlZEltYWdlRGF0YT8uaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBhd2FpdCBjYWNoZWRJbWFnZURhdGEuaW1hZ2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkICE9PSBpbWFnZUVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50Py5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50LCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShpbWFnZUVsZW1lbnQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoIXNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogaW5zZXJ0cyBpbWFnZSBpbnRvIGVsZW1lbnRzIGFycmF5IGFuZCByZXJlbmRlcnNcbiAgICovXG4gIHByaXZhdGUgaW5zZXJ0SW1hZ2VFbGVtZW50ID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBpbWFnZUZpbGU6IEZpbGUsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBpbWFnZUVsZW1lbnQsXG4gICAgXSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplSW1hZ2Uoe1xuICAgICAgICBpbWFnZUZpbGUsXG4gICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgc2hvd0N1cnNvckltYWdlUHJldmlldyxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIGlzRGVsZXRlZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB8fCB0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIiksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRJbWFnZVByZXZpZXdDdXJzb3IgPSBhc3luYyAoaW1hZ2VGaWxlOiBGaWxlKSA9PiB7XG4gICAgLy8gbXVzdG4ndCBiZSBsYXJnZXIgdGhhbiAxMjggcHhcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ1NTX0Jhc2ljX1VzZXJfSW50ZXJmYWNlL1VzaW5nX1VSTF92YWx1ZXNfZm9yX3RoZV9jdXJzb3JfcHJvcGVydHlcbiAgICBjb25zdCBjdXJzb3JJbWFnZVNpemVQeCA9IDk2O1xuXG4gICAgY29uc3QgaW1hZ2VQcmV2aWV3ID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgbWF4V2lkdGhPckhlaWdodDogY3Vyc29ySW1hZ2VTaXplUHgsXG4gICAgfSk7XG5cbiAgICBsZXQgcHJldmlld0RhdGFVUkwgPSBhd2FpdCBnZXREYXRhVVJMKGltYWdlUHJldmlldyk7XG5cbiAgICAvLyBTVkcgY2Fubm90IGJlIHJlc2l6ZWQgdmlhIGByZXNpemVJbWFnZUZpbGVgIHNvIHdlIHJlc2l6ZSBieSByZW5kZXJpbmcgdG9cbiAgICAvLyBhIHNtYWxsIGNhbnZhc1xuICAgIGlmIChpbWFnZUZpbGUudHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIGNvbnN0IGltZyA9IGF3YWl0IGxvYWRIVE1MSW1hZ2VFbGVtZW50KHByZXZpZXdEYXRhVVJMKTtcblxuICAgICAgbGV0IGhlaWdodCA9IE1hdGgubWluKGltZy5oZWlnaHQsIGN1cnNvckltYWdlU2l6ZVB4KTtcbiAgICAgIGxldCB3aWR0aCA9IGhlaWdodCAqIChpbWcud2lkdGggLyBpbWcuaGVpZ2h0KTtcblxuICAgICAgaWYgKHdpZHRoID4gY3Vyc29ySW1hZ2VTaXplUHgpIHtcbiAgICAgICAgd2lkdGggPSBjdXJzb3JJbWFnZVNpemVQeDtcbiAgICAgICAgaGVpZ2h0ID0gd2lkdGggKiAoaW1nLmhlaWdodCAvIGltZy53aWR0aCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSE7XG5cbiAgICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgIHByZXZpZXdEYXRhVVJMID0gY2FudmFzLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgYHVybCgke3ByZXZpZXdEYXRhVVJMfSkgNCA0LCBhdXRvYCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25JbWFnZUFjdGlvbiA9IGFzeW5jIChcbiAgICB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHkgfSA9IHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseTogZmFsc2UgfSxcbiAgKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNsaWVudFggPSB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdDtcbiAgICAgIGNvbnN0IGNsaWVudFkgPSB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcDtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2VGaWxlID0gYXdhaXQgZmlsZU9wZW4oe1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJbWFnZVwiLFxuICAgICAgICBleHRlbnNpb25zOiBbXCJqcGdcIiwgXCJwbmdcIiwgXCJzdmdcIiwgXCJnaWZcIl0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoe1xuICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgIHNjZW5lWTogeSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaW5zZXJ0T25DYW52YXNEaXJlY3RseSkge1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGltYWdlRmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogaW1hZ2VFbGVtZW50LmlkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoXG4gICAgICAgICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICAgICAgICAvKiBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ICovIHRydWUsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgaWYgKGVycm9yLm5hbWUgIT09IFwiQWJvcnRFcnJvclwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICAgIH0sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMgPSAoXG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICAgIGZvcmNlTmF0dXJhbFNpemUgPSBmYWxzZSxcbiAgKSA9PiB7XG4gICAgY29uc3QgaW1hZ2UgPVxuICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQpICYmXG4gICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGltYWdlRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcblxuICAgIGlmICghaW1hZ2UgfHwgaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgcGxhY2Vob2xkZXJTaXplID0gMTAwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICAgIHg6IGltYWdlRWxlbWVudC54IC0gcGxhY2Vob2xkZXJTaXplIC8gMixcbiAgICAgICAgICB5OiBpbWFnZUVsZW1lbnQueSAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgd2lkdGg6IHBsYWNlaG9sZGVyU2l6ZSxcbiAgICAgICAgICBoZWlnaHQ6IHBsYWNlaG9sZGVyU2l6ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBmb3JjZU5hdHVyYWxTaXplIHx8XG4gICAgICAvLyBpZiB1c2VyLWNyZWF0ZWQgYm91bmRpbmcgYm94IGlzIGJlbG93IHRocmVzaG9sZCwgYXNzdW1lIHRoZVxuICAgICAgLy8gaW50ZW50aW9uIHdhcyB0byBjbGljayBpbnN0ZWFkIG9mIGRyYWcsIGFuZCB1c2UgdGhlIGltYWdlJ3NcbiAgICAgIC8vIGludHJpbnNpYyBzaXplXG4gICAgICAoaW1hZ2VFbGVtZW50LndpZHRoIDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlICYmXG4gICAgICAgIGltYWdlRWxlbWVudC5oZWlnaHQgPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgKSB7XG4gICAgICBjb25zdCBtaW5IZWlnaHQgPSBNYXRoLm1heCh0aGlzLnN0YXRlLmhlaWdodCAtIDEyMCwgMTYwKTtcbiAgICAgIC8vIG1heCA2NSUgb2YgY2FudmFzIGhlaWdodCwgY2xhbXBlZCB0byA8MzAwcHgsIHZoIC0gMTIwcHg+XG4gICAgICBjb25zdCBtYXhIZWlnaHQgPSBNYXRoLm1pbihcbiAgICAgICAgbWluSGVpZ2h0LFxuICAgICAgICBNYXRoLmZsb29yKHRoaXMuc3RhdGUuaGVpZ2h0ICogMC41KSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGhlaWdodCA9IE1hdGgubWluKGltYWdlLm5hdHVyYWxIZWlnaHQsIG1heEhlaWdodCk7XG4gICAgICBjb25zdCB3aWR0aCA9IGhlaWdodCAqIChpbWFnZS5uYXR1cmFsV2lkdGggLyBpbWFnZS5uYXR1cmFsSGVpZ2h0KTtcblxuICAgICAgLy8gYWRkIGN1cnJlbnQgaW1hZ2VFbGVtZW50IHdpZHRoL2hlaWdodCB0byBhY2NvdW50IGZvciBwcmV2aW91cyBjZW50ZXJpbmdcbiAgICAgIC8vIG9mIHRoZSBwbGFjZWhvbGRlciBpbWFnZVxuICAgICAgY29uc3QgeCA9IGltYWdlRWxlbWVudC54ICsgaW1hZ2VFbGVtZW50LndpZHRoIC8gMiAtIHdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IHkgPSBpbWFnZUVsZW1lbnQueSArIGltYWdlRWxlbWVudC5oZWlnaHQgLyAyIC0gaGVpZ2h0IC8gMjtcblxuICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHsgeCwgeSwgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIHVwZGF0ZXMgaW1hZ2UgY2FjaGUsIHJlZnJlc2hpbmcgdXBkYXRlZCBlbGVtZW50cyBhbmQvb3Igc2V0dGluZyBzdGF0dXNcbiAgICAgIHRvIGVycm9yIGZvciBpbWFnZXMgdGhhdCBmYWlsIGR1cmluZyA8aW1nPiBlbGVtZW50IGNyZWF0aW9uICovXG4gIHByaXZhdGUgdXBkYXRlSW1hZ2VDYWNoZSA9IGFzeW5jIChcbiAgICBlbGVtZW50czogcmVhZG9ubHkgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10sXG4gICAgZmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcywgZXJyb3JlZEZpbGVzIH0gPSBhd2FpdCBfdXBkYXRlSW1hZ2VDYWNoZSh7XG4gICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICBmaWxlSWRzOiBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IGVsZW1lbnQuZmlsZUlkKSxcbiAgICAgIGZpbGVzLFxuICAgIH0pO1xuICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSB8fCBlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKSB7XG4gICAgICAgIGlmICh1cGRhdGVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKSkge1xuICAgICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVycm9yZWRGaWxlcy5zaXplKSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgICBlcnJvcmVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9O1xuICB9O1xuXG4gIC8qKiBhZGRzIG5ldyBpbWFnZXMgdG8gaW1hZ2VDYWNoZSBhbmQgcmUtcmVuZGVycyBpZiBuZWVkZWQgKi9cbiAgcHJpdmF0ZSBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgaW1hZ2VFbGVtZW50czogSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10gPSBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICksXG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgdW5jYWNoZWRJbWFnZUVsZW1lbnRzID0gaW1hZ2VFbGVtZW50cy5maWx0ZXIoXG4gICAgICAoZWxlbWVudCkgPT4gIWVsZW1lbnQuaXNEZWxldGVkICYmICF0aGlzLmltYWdlQ2FjaGUuaGFzKGVsZW1lbnQuZmlsZUlkKSxcbiAgICApO1xuXG4gICAgaWYgKHVuY2FjaGVkSW1hZ2VFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHsgdXBkYXRlZEZpbGVzIH0gPSBhd2FpdCB0aGlzLnVwZGF0ZUltYWdlQ2FjaGUoXG4gICAgICAgIHVuY2FjaGVkSW1hZ2VFbGVtZW50cyxcbiAgICAgICAgZmlsZXMsXG4gICAgICApO1xuICAgICAgaWYgKHVwZGF0ZWRGaWxlcy5zaXplKSB7XG4gICAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqIGdlbmVyYWxseSB5b3Ugc2hvdWxkIHVzZSBgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKClgIGRpcmVjdGx5IGlmIHlvdSBuZWVkXG4gICAqICB0byByZW5kZXIgbmV3IGltYWdlcy4gVGhpcyBpcyBqdXN0IGEgZmFpbHNhZmUgICovXG4gIHByaXZhdGUgc2NoZWR1bGVJbWFnZVJlZnJlc2ggPSB0aHJvdHRsZSgoKSA9PiB7XG4gICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgfSwgSU1BR0VfUkVOREVSX1RJTUVPVVQpO1xuXG4gIHByaXZhdGUgdXBkYXRlQmluZGluZ0VuYWJsZWRPblBvaW50ZXJNb3ZlID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICBjb25zdCBzaG91bGRFbmFibGVCaW5kaW5nID0gc2hvdWxkRW5hYmxlQmluZGluZ0ZvclBvaW50ZXJFdmVudChldmVudCk7XG4gICAgaWYgKHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCAhPT0gc2hvdWxkRW5hYmxlQmluZGluZykge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHNob3VsZEVuYWJsZUJpbmRpbmcgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yID0gKHBvaW50ZXJDb29yZHM6IHtcbiAgICB4OiBudW1iZXI7XG4gICAgeTogbnVtYmVyO1xuICB9KTogdm9pZCA9PiB7XG4gICAgY29uc3QgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICB0aGlzLnNjZW5lLFxuICAgICk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzdWdnZXN0ZWRCaW5kaW5nczpcbiAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCAhPSBudWxsID8gW2hvdmVyZWRCaW5kYWJsZUVsZW1lbnRdIDogW10sXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyA9IChcbiAgICBsaW5lYXJFbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICAvKiogc2NlbmUgY29vcmRzICovXG4gICAgcG9pbnRlckNvb3Jkczoge1xuICAgICAgeDogbnVtYmVyO1xuICAgICAgeTogbnVtYmVyO1xuICAgIH1bXSxcbiAgICAvLyBEdXJpbmcgbGluZSBjcmVhdGlvbiB0aGUgc3RhcnQgYmluZGluZyBoYXNuJ3QgYmVlbiB3cml0dGVuIHlldFxuICAgIC8vIGludG8gYGxpbmVhckVsZW1lbnRgXG4gICAgb3Bwb3NpdGVCaW5kaW5nQm91bmRFbGVtZW50PzogRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCB8IG51bGwsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICghcG9pbnRlckNvb3Jkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IHBvaW50ZXJDb29yZHMucmVkdWNlKFxuICAgICAgKGFjYzogTm9uRGVsZXRlZDxFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50PltdLCBjb29yZHMpID0+IHtcbiAgICAgICAgY29uc3QgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgICBjb29yZHMsXG4gICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICAgICFpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQoXG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgb3Bwb3NpdGVCaW5kaW5nQm91bmRFbGVtZW50Py5pZCxcbiAgICAgICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQsXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICBhY2MucHVzaChob3ZlcmVkQmluZGFibGVFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIFtdLFxuICAgICk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3MgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHN1Z2dlc3RlZEJpbmRpbmdzID0gZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbihoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAvLyBDb250aW51ZSBlZGl0aW5nIHRoZSBzYW1lIGdyb3VwIGlmIHRoZSB1c2VyIHNlbGVjdGVkIGEgZGlmZmVyZW50XG4gICAgICAvLyBlbGVtZW50IGZyb20gaXRcbiAgICAgIGVkaXRpbmdHcm91cElkOlxuICAgICAgICBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWQgJiZcbiAgICAgICAgaGl0RWxlbWVudCAhPSBudWxsICYmXG4gICAgICAgIGlzRWxlbWVudEluR3JvdXAoaGl0RWxlbWVudCwgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgID8gcHJldlN0YXRlLmVkaXRpbmdHcm91cElkXG4gICAgICAgICAgOiBudWxsLFxuICAgIH0pKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1JlZiA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB7XG4gICAgLy8gY2FudmFzIGlzIG51bGwgd2hlbiB1bm1vdW50aW5nXG4gICAgaWYgKGNhbnZhcyAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5jYW52YXMgPSBjYW52YXM7XG4gICAgICB0aGlzLnJjID0gcm91Z2guY2FudmFzKHRoaXMuY2FudmFzKTtcblxuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5XSEVFTCwgdGhpcy5oYW5kbGVXaGVlbCwge1xuICAgICAgICBwYXNzaXZlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9TVEFSVCwgdGhpcy5vblRhcFN0YXJ0KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9FTkQsIHRoaXMub25UYXBFbmQpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUFwcE9uRHJvcCA9IGFzeW5jIChldmVudDogUmVhY3QuRHJhZ0V2ZW50PEhUTUxEaXZFbGVtZW50PikgPT4ge1xuICAgIC8vIG11c3QgYmUgcmV0cmlldmVkIGZpcnN0LCBpbiB0aGUgc2FtZSBmcmFtZVxuICAgIGNvbnN0IHsgZmlsZSwgZmlsZUhhbmRsZSB9ID0gYXdhaXQgZ2V0RmlsZUZyb21FdmVudChldmVudCk7XG5cbiAgICB0cnkge1xuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpKSB7XG4gICAgICAgIC8vIGZpcnN0IGF0dGVtcHQgdG8gZGVjb2RlIHNjZW5lIGZyb20gdGhlIGltYWdlIGlmIGl0J3MgZW1iZWRkZWRcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgaWYgKGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMucG5nIHx8IGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHNjZW5lID0gYXdhaXQgbG9hZEZyb21CbG9iKFxuICAgICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICAgICAgICBmaWxlSGFuZGxlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgICAgIC4uLnNjZW5lLFxuICAgICAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkVuY29kaW5nRXJyb3JcIikge1xuICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBubyBzY2VuZSBpcyBlbWJlZGRlZCBvciB3ZSBmYWlsIGZvciB3aGF0ZXZlciByZWFzb24sIGZhbGwgYmFja1xuICAgICAgICAvLyB0byBpbXBvcnRpbmcgYXMgcmVndWxhciBpbWFnZVxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGxpYnJhcnlKU09OID0gZXZlbnQuZGF0YVRyYW5zZmVyLmdldERhdGEoTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliKTtcbiAgICBpZiAobGlicmFyeUpTT04gJiYgdHlwZW9mIGxpYnJhcnlKU09OID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsaWJyYXJ5SXRlbXMgPSBwYXJzZUxpYnJhcnlKU09OKGxpYnJhcnlKU09OKTtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgZWxlbWVudHM6IGRpc3RyaWJ1dGVMaWJyYXJ5SXRlbXNPblNxdWFyZUdyaWQobGlicmFyeUl0ZW1zKSxcbiAgICAgICAgICBwb3NpdGlvbjogZXZlbnQsXG4gICAgICAgICAgZmlsZXM6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChmaWxlKSB7XG4gICAgICAvLyBhdGV0bXB0IHRvIHBhcnNlIGFuIGV4Y2FsaWRyYXcvZXhjYWxpZHJhd2xpYiBmaWxlXG4gICAgICBhd2FpdCB0aGlzLmxvYWRGaWxlVG9DYW52YXMoZmlsZSwgZmlsZUhhbmRsZSk7XG4gICAgfVxuICB9O1xuXG4gIGxvYWRGaWxlVG9DYW52YXMgPSBhc3luYyAoXG4gICAgZmlsZTogRmlsZSxcbiAgICBmaWxlSGFuZGxlOiBGaWxlU3lzdGVtSGFuZGxlIHwgbnVsbCxcbiAgKSA9PiB7XG4gICAgZmlsZSA9IGF3YWl0IG5vcm1hbGl6ZUZpbGUoZmlsZSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJldCA9IGF3YWl0IGxvYWRTY2VuZU9yTGlicmFyeUZyb21CbG9iKFxuICAgICAgICBmaWxlLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBmaWxlSGFuZGxlLFxuICAgICAgKTtcbiAgICAgIGlmIChyZXQudHlwZSA9PT0gTUlNRV9UWVBFUy5leGNhbGlkcmF3KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgLi4ucmV0LmRhdGEsXG4gICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgIC4uLihyZXQuZGF0YS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocmV0LnR5cGUgPT09IE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYikge1xuICAgICAgICBhd2FpdCB0aGlzLmxpYnJhcnlcbiAgICAgICAgICAudXBkYXRlTGlicmFyeSh7XG4gICAgICAgICAgICBsaWJyYXJ5SXRlbXM6IGZpbGUsXG4gICAgICAgICAgICBtZXJnZTogdHJ1ZSxcbiAgICAgICAgICAgIG9wZW5MaWJyYXJ5TWVudTogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogdChcImVycm9ycy5pbXBvcnRMaWJyYXJ5RXJyb3JcIikgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogZmFsc2UsIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNDb250ZXh0TWVudSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmIChcbiAgICAgIChldmVudC5uYXRpdmVFdmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiIHx8XG4gICAgICAgIChldmVudC5uYXRpdmVFdmVudC5wb2ludGVyVHlwZSA9PT0gXCJwZW5cIiAmJlxuICAgICAgICAgIC8vIGFsd2F5cyBhbGxvdyBpZiB1c2VyIHVzZXMgYSBwZW4gc2Vjb25kYXJ5IGJ1dHRvblxuICAgICAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uU0VDT05EQVJZKSkgJiZcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHtcbiAgICAgIHByZWZlclNlbGVjdGVkOiB0cnVlLFxuICAgICAgaW5jbHVkZUxvY2tlZEVsZW1lbnRzOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdHlwZSA9IGVsZW1lbnQgPyBcImVsZW1lbnRcIiA6IFwiY2FudmFzXCI7XG5cbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCE7XG4gICAgY29uc3QgeyB0b3A6IG9mZnNldFRvcCwgbGVmdDogb2Zmc2V0TGVmdCB9ID1cbiAgICAgIGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBsZWZ0ID0gZXZlbnQuY2xpZW50WCAtIG9mZnNldExlZnQ7XG4gICAgY29uc3QgdG9wID0gZXZlbnQuY2xpZW50WSAtIG9mZnNldFRvcDtcblxuICAgIGlmIChlbGVtZW50ICYmICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1tlbGVtZW50LmlkXSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBpc0xpbmVhckVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihlbGVtZW50LCB0aGlzLnNjZW5lKVxuICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICApLFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50ID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIlxuICAgICkge1xuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyQ29vcmRzLngpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LCBwb2ludGVyQ29vcmRzLnkpLFxuICAgICAgICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZSA9XG4gICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSAmJlxuICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGRyYWdnaW5nRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcbiAgICAgIGNvbnN0IGFzcGVjdFJhdGlvID1cbiAgICAgICAgaW1hZ2UgJiYgIShpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpXG4gICAgICAgICAgPyBpbWFnZS53aWR0aCAvIGltYWdlLmhlaWdodFxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksXG4gICAgICAgIGdyaWRYLFxuICAgICAgICBncmlkWSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCwgZ3JpZFgpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LCBncmlkWSksXG4gICAgICAgIGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBhc3BlY3RSYXRpbyxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChbZHJhZ2dpbmdFbGVtZW50XSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVIYW5kbGVSZXNpemUgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIFRPRE86IHJlbmFtZSB0aGlzIHN0YXRlIGZpZWxkIHRvIFwiaXNTY2FsaW5nXCIgdG8gZGlzdGluZ3Vpc2hcbiAgICAgIC8vIGl0IGZyb20gdGhlIGdlbmVyaWMgXCJpc1Jlc2l6aW5nXCIgd2hpY2ggaW5jbHVkZXMgc2NhbGluZyBhbmRcbiAgICAgIC8vIHJvdGF0aW5nXG4gICAgICBpc1Jlc2l6aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlICYmIHRyYW5zZm9ybUhhbmRsZVR5cGUgIT09IFwicm90YXRpb25cIixcbiAgICAgIGlzUm90YXRpbmc6IHRyYW5zZm9ybUhhbmRsZVR5cGUgPT09IFwicm90YXRpb25cIixcbiAgICB9KTtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGNvbnN0IFtyZXNpemVYLCByZXNpemVZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC54LFxuICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0LnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgaWYgKFxuICAgICAgdHJhbnNmb3JtRWxlbWVudHMoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uLFxuICAgICAgICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0ltYWdlRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgcmVzaXplWCxcbiAgICAgICAgcmVzaXplWSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuY2VudGVyLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci55LFxuICAgICAgKVxuICAgICkge1xuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICAvKiogQHByaXZhdGUgdXNlIHRoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgKi9cbiAgcHJpdmF0ZSBfb3BlbkNvbnRleHRNZW51ID0gKFxuICAgIHtcbiAgICAgIGxlZnQsXG4gICAgICB0b3AsXG4gICAgfToge1xuICAgICAgbGVmdDogbnVtYmVyO1xuICAgICAgdG9wOiBudW1iZXI7XG4gICAgfSxcbiAgICB0eXBlOiBcImNhbnZhc1wiIHwgXCJlbGVtZW50XCIsXG4gICkgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dIeXBlcmxpbmtQb3B1cDogZmFsc2UgfSk7XG4gICAgfVxuICAgIHRoaXMuY29udGV4dE1lbnVPcGVuID0gdHJ1ZTtcbiAgICBjb25zdCBtYXliZUdyb3VwQWN0aW9uID0gYWN0aW9uR3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlVW5ncm91cEFjdGlvbiA9IGFjdGlvblVuZ3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcEhvcml6b250YWwgPSBhY3Rpb25GbGlwSG9yaXpvbnRhbC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3QgbWF5YmVGbGlwVmVydGljYWwgPSBhY3Rpb25GbGlwVmVydGljYWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heUJlQWxsb3dVbmJpbmRpbmcgPSBhY3Rpb25VbmJpbmRUZXh0LmNvbnRleHRJdGVtUHJlZGljYXRlKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heUJlQWxsb3dCaW5kaW5nID0gYWN0aW9uQmluZFRleHQuY29udGV4dEl0ZW1QcmVkaWNhdGUoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3Qgc2VwYXJhdG9yID0gXCJzZXBhcmF0b3JcIjtcblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IG9wdGlvbnM6IENvbnRleHRNZW51T3B0aW9uW10gPSBbXTtcbiAgICBpZiAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1BuZyk7XG4gICAgfVxuXG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1N2Zyk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZSA9PT0gXCJlbGVtZW50XCIgJiZcbiAgICAgIGNvcHlUZXh0LmNvbnRleHRJdGVtUHJlZGljYXRlKGVsZW1lbnRzLCB0aGlzLnN0YXRlKSAmJlxuICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dFxuICAgICkge1xuICAgICAgb3B0aW9ucy5wdXNoKGNvcHlUZXh0KTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09IFwiY2FudmFzXCIpIHtcbiAgICAgIGNvbnN0IHZpZXdNb2RlT3B0aW9ucyA9IFtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZVZpZXdNb2RlLFxuICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgIF07XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiB2aWV3TW9kZU9wdGlvbnMsXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIHRyYWNrRXZlbnQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmXG4gICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgYWN0aW9uQ29weUFzUG5nLFxuICAgICAgICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJlxuICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGFjdGlvbkNvcHlBc1N2ZyxcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiZcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGNvcHlUZXh0LFxuICAgICAgICAgICAgKChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB8fFxuICAgICAgICAgICAgICAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSkgJiZcbiAgICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uU2VsZWN0QWxsLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZWxlbWVudFwiKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogW25hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSwgLi4ub3B0aW9uc10sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmIGFjdGlvbkN1dCxcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSxcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICB0cmFja0V2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uQ29weVN0eWxlcyxcbiAgICAgICAgICAgIGFjdGlvblBhc3RlU3R5bGVzLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgbWF5YmVHcm91cEFjdGlvbiAmJiBhY3Rpb25Hcm91cCxcbiAgICAgICAgICAgIG1heUJlQWxsb3dVbmJpbmRpbmcgJiYgYWN0aW9uVW5iaW5kVGV4dCxcbiAgICAgICAgICAgIG1heUJlQWxsb3dCaW5kaW5nICYmIGFjdGlvbkJpbmRUZXh0LFxuICAgICAgICAgICAgbWF5YmVVbmdyb3VwQWN0aW9uICYmIGFjdGlvblVuZ3JvdXAsXG4gICAgICAgICAgICAobWF5YmVHcm91cEFjdGlvbiB8fCBtYXliZVVuZ3JvdXBBY3Rpb24pICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgICAgICAgICAgIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgICAgICAgICAgIGFjdGlvblNlbmRUb0JhY2ssXG4gICAgICAgICAgICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBtYXliZUZsaXBIb3Jpem9udGFsICYmIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICAgICAgICAgICAgbWF5YmVGbGlwVmVydGljYWwgJiYgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICAgICAgICAgICAgKG1heWJlRmxpcEhvcml6b250YWwgfHwgbWF5YmVGbGlwVmVydGljYWwpICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkxpbmsuY29udGV4dEl0ZW1QcmVkaWNhdGUoZWxlbWVudHMsIHRoaXMuc3RhdGUpICYmIGFjdGlvbkxpbmssXG4gICAgICAgICAgICBhY3Rpb25EdXBsaWNhdGVTZWxlY3Rpb24sXG4gICAgICAgICAgICBhY3Rpb25Ub2dnbGVMb2NrLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0b3AsXG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICBhY3Rpb25NYW5hZ2VyOiB0aGlzLmFjdGlvbk1hbmFnZXIsXG4gICAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVdoZWVsID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogV2hlZWxFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGVsdGFYLCBkZWx0YVkgfSA9IGV2ZW50O1xuICAgIC8vIG5vdGUgdGhhdCBldmVudC5jdHJsS2V5IGlzIG5lY2Vzc2FyeSB0byBoYW5kbGUgcGluY2ggem9vbWluZ1xuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIGNvbnN0IHNpZ24gPSBNYXRoLnNpZ24oZGVsdGFZKTtcbiAgICAgIGNvbnN0IE1BWF9TVEVQID0gMTA7XG4gICAgICBjb25zdCBhYnNEZWx0YSA9IE1hdGguYWJzKGRlbHRhWSk7XG4gICAgICBsZXQgZGVsdGEgPSBkZWx0YVk7XG4gICAgICBpZiAoYWJzRGVsdGEgPiBNQVhfU1RFUCkge1xuICAgICAgICBkZWx0YSA9IE1BWF9TVEVQICogc2lnbjtcbiAgICAgIH1cblxuICAgICAgbGV0IG5ld1pvb20gPSB0aGlzLnN0YXRlLnpvb20udmFsdWUgLSBkZWx0YSAvIDEwMDtcbiAgICAgIC8vIGluY3JlYXNlIHpvb20gc3RlcHMgdGhlIG1vcmUgem9vbWVkLWluIHdlIGFyZSAoYXBwbGllcyB0byA+MTAwJSBvbmx5KVxuICAgICAgbmV3Wm9vbSArPVxuICAgICAgICBNYXRoLmxvZzEwKE1hdGgubWF4KDEsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpICpcbiAgICAgICAgLXNpZ24gKlxuICAgICAgICAvLyByZWR1Y2VkIGFtcGxpZmljYXRpb24gZm9yIHNtYWxsIGRlbHRhcyAoc21hbGwgbW92ZW1lbnRzIG9uIGEgdHJhY2twYWQpXG4gICAgICAgIE1hdGgubWluKDEsIGFic0RlbHRhIC8gMjApO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgLi4uZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY3Vyc29yWCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY3Vyc29yWSxcbiAgICAgICAgICAgIG5leHRab29tOiBnZXROb3JtYWxpemVkWm9vbShuZXdab29tKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc2Nyb2xsIGhvcml6b250YWxseSB3aGVuIHNoaWZ0IHByZXNzZWRcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCB9KSA9PiAoe1xuICAgICAgICAvLyBvbiBNYWMsIHNoaWZ0K3doZWVsIHRlbmRzIHRvIHJlc3VsdCBpbiBkZWx0YVhcbiAgICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIChkZWx0YVkgfHwgZGVsdGFYKSAvIHpvb20udmFsdWUsXG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZIH0pID0+ICh7XG4gICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gZGVsdGFYIC8gem9vbS52YWx1ZSxcbiAgICAgIHNjcm9sbFk6IHNjcm9sbFkgLSBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBnZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICAgIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICAgIHNjYWxlOiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IGVsZW1lbnRDbGlja2VkSW5zaWRlID0gZ2V0VGV4dEJpbmRhYmxlQ29udGFpbmVyQXRQb3NpdGlvbihcbiAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+ICFpc1RleHRFbGVtZW50KGVsZW1lbnQpKSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICk7XG4gICAgaWYgKGVsZW1lbnRDbGlja2VkSW5zaWRlKSB7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWCA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnggKyBlbGVtZW50Q2xpY2tlZEluc2lkZS53aWR0aCAvIDI7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWSA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnkgKyBlbGVtZW50Q2xpY2tlZEluc2lkZS5oZWlnaHQgLyAyO1xuICAgICAgY29uc3QgZGlzdGFuY2VUb0NlbnRlciA9IE1hdGguaHlwb3QoXG4gICAgICAgIHggLSBlbGVtZW50Q2VudGVyWCxcbiAgICAgICAgeSAtIGVsZW1lbnRDZW50ZXJZLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzU25hcHBlZFRvQ2VudGVyID1cbiAgICAgICAgZGlzdGFuY2VUb0NlbnRlciA8IFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xEO1xuICAgICAgaWYgKGlzU25hcHBlZFRvQ2VudGVyKSB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7IHNjZW5lWDogZWxlbWVudENlbnRlclgsIHNjZW5lWTogZWxlbWVudENlbnRlclkgfSxcbiAgICAgICAgICBhcHBTdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgdmlld3BvcnRYLCB2aWV3cG9ydFksIGVsZW1lbnRDZW50ZXJYLCBlbGVtZW50Q2VudGVyWSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2F2ZVBvaW50ZXIgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIGJ1dHRvbjogXCJ1cFwiIHwgXCJkb3duXCIpID0+IHtcbiAgICBpZiAoIXggfHwgIXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKGlzTmFOKHBvaW50ZXIueCkgfHwgaXNOYU4ocG9pbnRlci55KSkge1xuICAgICAgLy8gc29tZXRpbWVzIHRoZSBwb2ludGVyIGdvZXMgb2ZmIHNjcmVlblxuICAgIH1cblxuICAgIHRoaXMucHJvcHMub25Qb2ludGVyVXBkYXRlPy4oe1xuICAgICAgcG9pbnRlcixcbiAgICAgIGJ1dHRvbixcbiAgICAgIHBvaW50ZXJzTWFwOiBnZXN0dXJlLnBvaW50ZXJzLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQgPSBkZWJvdW5jZSgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLnVubW91bnRlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3VsZENhY2hlSWdub3JlWm9vbTogZmFsc2UgfSk7XG4gICAgfVxuICB9LCAzMDApO1xuXG4gIHByaXZhdGUgdXBkYXRlRE9NUmVjdCA9IChjYj86ICgpID0+IHZvaWQpID0+IHtcbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICBjb25zdCBleGNhbGlkcmF3Q29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IG9mZnNldExlZnQsXG4gICAgICAgIHRvcDogb2Zmc2V0VG9wLFxuICAgICAgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoOiBjdXJyZW50V2lkdGgsXG4gICAgICAgIGhlaWdodDogY3VycmVudEhlaWdodCxcbiAgICAgICAgb2Zmc2V0VG9wOiBjdXJyZW50T2Zmc2V0VG9wLFxuICAgICAgICBvZmZzZXRMZWZ0OiBjdXJyZW50T2Zmc2V0TGVmdCxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHdpZHRoID09PSBjdXJyZW50V2lkdGggJiZcbiAgICAgICAgaGVpZ2h0ID09PSBjdXJyZW50SGVpZ2h0ICYmXG4gICAgICAgIG9mZnNldExlZnQgPT09IGN1cnJlbnRPZmZzZXRMZWZ0ICYmXG4gICAgICAgIG9mZnNldFRvcCA9PT0gY3VycmVudE9mZnNldFRvcFxuICAgICAgKSB7XG4gICAgICAgIGlmIChjYikge1xuICAgICAgICAgIGNiKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIG9mZnNldExlZnQsXG4gICAgICAgICAgb2Zmc2V0VG9wLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY2IgJiYgY2IoKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyByZWZyZXNoID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSB9KTtcbiAgfTtcblxuICBwcml2YXRlIGdldENhbnZhc09mZnNldHMoKTogUGljazxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXRMZWZ0OiBsZWZ0LFxuICAgICAgICBvZmZzZXRUb3A6IHRvcCxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRMZWZ0OiAwLFxuICAgICAgb2Zmc2V0VG9wOiAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUxhbmd1YWdlKCkge1xuICAgIGNvbnN0IGN1cnJlbnRMYW5nID1cbiAgICAgIGxhbmd1YWdlcy5maW5kKChsYW5nKSA9PiBsYW5nLmNvZGUgPT09IHRoaXMucHJvcHMubGFuZ0NvZGUpIHx8XG4gICAgICBkZWZhdWx0TGFuZztcbiAgICBhd2FpdCBzZXRMYW5ndWFnZShjdXJyZW50TGFuZyk7XG4gICAgdGhpcy5zZXRBcHBTdGF0ZSh7fSk7XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRFU1QgSE9PS1Ncbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgaDoge1xuICAgICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgICBzdGF0ZTogQXBwU3RhdGU7XG4gICAgICBzZXRTdGF0ZTogUmVhY3QuQ29tcG9uZW50PGFueSwgQXBwU3RhdGU+W1wic2V0U3RhdGVcIl07XG4gICAgICBhcHA6IEluc3RhbmNlVHlwZTx0eXBlb2YgQXBwPjtcbiAgICAgIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gICAgfTtcbiAgfVxufVxuXG5pZiAoXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4pIHtcbiAgd2luZG93LmggPSB3aW5kb3cuaCB8fCAoe30gYXMgV2luZG93W1wiaFwiXSk7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICBlbGVtZW50czoge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHA/LnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpO1xuICAgICAgfSxcbiAgICAgIHNldChlbGVtZW50czogRXhjYWxpZHJhd0VsZW1lbnRbXSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHA/LnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xufVxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
2120
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer)\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_46__ = __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\");\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\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\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 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.contextMenuOpen = false;\n this.lastScenePointer = null;\n this.focusContainer = () => {\n var _a;\n if (this.props.autoFocus) {\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n }\n };\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\n var _a, _b, _c, _d, _e, _f;\n // Since context menu closes when action triggered so setting to false\n this.contextMenuOpen = false;\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) {\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 let theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.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 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.theme !== \"undefined\") {\n theme = this.props.theme;\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 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 });\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.onFontLoaded = () => {\n this.scene.getElementsIncludingDeleted().forEach((element) => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.onSceneUpdated();\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.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);\n scene.appState = Object.assign(Object.assign({}, scene.appState), { \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 isLibraryOpen: ((_b = initialData === null || initialData === void 0 ? void 0 : initialData.appState) === null || _b === void 0 ? void 0 : _b.isLibraryOpen) || this.state.isLibraryOpen, 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 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 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.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 (!_keys__WEBPACK_IMPORTED_MODULE_26__.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 (_keys__WEBPACK_IMPORTED_MODULE_26__.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 // #686\n const target = document.activeElement;\n const isExcalidrawActive = (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);\n if (!isExcalidrawActive) {\n return;\n }\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\n if (\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\n // thus these checks don't make sense\n 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);\n if (!file && data.text) {\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) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true,\n },\n });\n }\n else if (data.elements) {\n this.addElementsFromPasteOrLibrary({\n elements: data.elements,\n files: data.files || null,\n position: \"cursor\",\n });\n }\n else if (data.text) {\n this.addTextFromPaste(data.text);\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 groupIdMap = new Map();\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\n const oldIdToDuplicatedId = new Map();\n const newElements = elements.map((element) => {\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY,\n });\n oldIdToDuplicatedId.set(element.id, newElement.id);\n return newElement;\n });\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\n const nextElements = [\n ...this.scene.getElementsIncludingDeleted(),\n ...newElements,\n ];\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n this.scene.replaceAllElements(nextElements);\n this.history.resumeRecording();\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: this.state.isLibraryOpen && this.device.canDeviceFitSidebar\n ? this.state.isLibraryMenuDocked\n : false, 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 // Collaboration\n this.setAppState = (obj) => {\n this.setState(obj);\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.scrollToContent = (target = this.scene.getNonDeletedElements()) => {\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\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 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 // 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 showHelpDialog: true,\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 (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\n const nextState = !this.state.isLibraryOpen;\n this.setState({ isLibraryOpen: nextState });\n // track only openings\n if (nextState) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"library\", \"toggleLibrary (open)\", `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\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 const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state, true);\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 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 if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\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(selectedElements[0], this.scene),\n });\n }\n }\n else {\n const selectedElement = selectedElements[0];\n this.startTextEditing({\n sceneX: selectedElement.x + selectedElement.width / 2,\n sceneY: selectedElement.y + selectedElement.height / 2,\n shouldBind: true,\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.GRABBING);\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: \"backgroundColorPicker\" });\n event.stopPropagation();\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({ openPopup: \"strokeColorPicker\" });\n event.stopPropagation();\n }\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 (!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, shouldBind, insertAtParentCenter = true, }) => {\n var _a, _b;\n let parentCenterPosition = insertAtParentCenter &&\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\n let existingTextElement = null;\n let container = 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 ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(selectedElements[0], false)) {\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 // bind to container when shouldBind is true or\n // clicked on center of container\n if (!container &&\n !existingTextElement &&\n (shouldBind || parentCenterPosition)) {\n container = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getNonDeletedElements()\n .filter((ele) => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(ele, false) && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(ele)), sceneX, sceneY);\n }\n if (!existingTextElement && container) {\n const fontString = {\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const newHeight = Math.max(container.height, minHeight);\n const newWidth = Math.max(container.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, this.canvas, window.devicePixelRatio);\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 strokeSharpness: this.state.currentItemStrokeSharpness,\n text: \"\",\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\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: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\n groupIds: (_b = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _b !== void 0 ? _b : [],\n locked: false,\n });\n this.setState({ editingElement: element });\n if (!existingTextElement) {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n // case: creating new text not centered to parent element → offset Y\n // so that the text is centered to cursor position\n if (!parentCenterPosition) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n y: element.y - element.baseline / 2,\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 (!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 }\n return;\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 selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\n if (canBindText) {\n sceneX = selectedElement.x + selectedElement.width / 2;\n sceneY = selectedElement.y + selectedElement.height / 2;\n }\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\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 return {\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 || isPanning || isDraggingScrollBar) {\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.editingLinearElement, this.state.gridSize);\n if (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({ editingLinearElement });\n });\n }\n if (editingLinearElement.lastUncommittedPoint != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n else {\n this.setState({ suggestedBindings: [] });\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.contextMenuOpen &&\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 (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 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 // 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 this.updateGestureOnPointerDown(event);\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 // Since context menu closes on pointer down so setting to false\n this.contextMenuOpen = false;\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.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 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 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.setState({\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 if ((0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y], this.device.isMobile)) {\n return false;\n }\n pointerDownState.hit.hasHitElementInside =\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y]);\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 const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\n if (canBindText) {\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\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 strokeSharpness: this.state.currentItemLinearStrokeSharpness,\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 opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\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 strokeSharpness: this.state.currentItemLinearStrokeSharpness,\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 strokeSharpness: this.state.currentItemStrokeSharpness,\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 } });\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: [\"jpg\", \"png\", \"svg\", \"gif\"],\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 type = element ? \"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 if (element && !this.state.selectedElementIds[element.id]) {\n this.setState((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._openContextMenu({ top, left }, type);\n });\n }\n else {\n this._openContextMenu({ top, left }, type);\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 /** @private use this.handleCanvasContextMenu */\n this._openContextMenu = ({ left, top, }, type) => {\n if (this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n this.contextMenuOpen = true;\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowUnbinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowBinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const separator = \"separator\";\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const options = [];\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng);\n }\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg);\n }\n if (type === \"element\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText.contextItemPredicate(elements, this.state) &&\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n }\n if (type === \"canvas\") {\n const viewModeOptions = [\n ...options,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: viewModeOptions,\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile &&\n navigator.clipboard && {\n trackEvent: false,\n name: \"paste\",\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && navigator.clipboard && separator,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n selectedElements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText,\n ((_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) ||\n (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0)) &&\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll,\n separator,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n }\n else if (type === \"element\") {\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCut,\n this.device.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy,\n this.device.isMobile &&\n navigator.clipboard && {\n name: \"paste\",\n trackEvent: false,\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && separator,\n ...options,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles,\n separator,\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup,\n mayBeAllowUnbinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText,\n mayBeAllowBinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText,\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup,\n (maybeGroupAction || maybeUngroupAction) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary,\n 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 separator,\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal,\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical,\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink.contextItemPredicate(elements, this.state) && _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLock,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\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 = 10;\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.setState((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.setState(({ 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.setState(({ 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, isLibraryMenuDocked: false });\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_46__.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 };\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.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, _b;\n const selectedElement = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const { onCollabButtonClick, renderTopRightUI, renderFooter, 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--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)(ExcalidrawContainerContext.Provider, Object.assign({ value: this.excalidrawContainerValue }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(DeviceContext.Provider, Object.assign({ value: this.device }, { children: [(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], { canvas: this.canvas, appState: this.state, files: this.files, setAppState: this.setAppState, actionManager: this.actionManager, elements: this.scene.getNonDeletedElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onPenModeToggle: this.togglePenMode, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null,\n }), langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, renderCustomStats: renderCustomStats, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\n this.state.zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\n this.props.UIOptions.canvasActions.theme, libraryReturnUrl: this.props.libraryReturnUrl, UIOptions: this.props.UIOptions, focusContainer: this.focusContainer, library: this.library, id: this.id, onImageAction: this.onImageAction }), (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 && this.state.showHyperlinkPopup && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.Hyperlink, { element: selectedElement[0], appState: this.state, 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 })), (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.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 });\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 clearTimeout(touchTimeout);\n touchTimeout = 0;\n }\n removeEventListeners() {\n var _a, _b, _c, _d, _e;\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 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 (_e = this.detachIsMobileMqHandler) === null || _e === void 0 ? void 0 : _e.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.onFontLoaded);\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.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.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 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 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 (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__.renderScene)(renderingElements, this.state, this.state.selectionElement, window.devicePixelRatio, this.rc, this.canvas, {\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n viewBackgroundColor: 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 }, ({ 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 }, THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true);\n if (!THROTTLE_NEXT_RENDER) {\n THROTTLE_NEXT_RENDER = true;\n }\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);\n }\n }\n static resetTapTwice() {\n didTapTwice = false;\n }\n addTextFromPaste(text) {\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\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 roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\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 this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({ selectedElementIds: { [element.id]: true } });\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 if (!element) {\n return;\n }\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\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 if (hoverPointIndex >= 0) {\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 if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { hoverPointIndex }),\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 hasHitElementInside: false,\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, _b, _c, _d;\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 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 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 if ((hasHitASelectedElement ||\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\n // this allows for box-selecting points when clicking inside the\n // line's bounding box\n (!this.state.editingLinearElement || !event.shiftKey) &&\n // box-selecting without shift when editing line, not clicking on a line\n (!this.state.editingLinearElement ||\n ((_a = this.state.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !==\n ((_b = pointerDownState.hit.element) === null || _b === void 0 ? void 0 : _b.id) ||\n pointerDownState.hit.hasHitElementInside) &&\n (!this.state.selectedLinearElement ||\n ((_c = this.state.selectedLinearElement) === null || _c === void 0 ? void 0 : _c.elementId) !==\n ((_d = pointerDownState.hit.element) === null || _d === void 0 ? void 0 : _d.id) ||\n pointerDownState.hit.hasHitElementInside)) {\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 if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\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, { points: [...points, [dx, dy]] });\n }\n else if (points.length > 1) {\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.setState({\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.setState({\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 // 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 !pointerDownState.hit.hasHitElementInside)) {\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 (!pointerDownState.boxSelection.hasOccurred &&\n (((_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 !pointerDownState.hit.hasHitElementInside)) {\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 selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\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 (!this.state.selectedLinearElement &&\n !this.state.editingLinearElement &&\n !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 // Deselect selected elements\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\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, canvas, scale) {\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getElementsIncludingDeleted()\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\n if (elementClickedInside) {\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\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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TEosSUFDRSxhQUFvQixLQUFLLGlEQUFRO0lBQ2pDLGFBQW9CLEtBQUssd0RBQWUsRUFDeEM7SUFDQSxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLElBQUssRUFBa0IsQ0FBQztJQUUzQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtRQUNoQyxRQUFRLEVBQUU7WUFDUixZQUFZLEVBQUUsSUFBSTtZQUNsQixHQUFHOztnQkFDRCxPQUFPLFVBQUksQ0FBQyxHQUFHLDBDQUFFLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1lBQ3ZELENBQUM7WUFDRCxHQUFHLENBQUMsUUFBNkI7O2dCQUMvQixPQUFPLFVBQUksQ0FBQyxHQUFHLDBDQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0RCxDQUFDO1NBQ0Y7S0FDRixDQUFDLENBQUM7Q0FDSjtBQUNELGlFQUFlLEdBQUcsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9jb21wb25lbnRzL0FwcC50c3g/MDA3MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ29udGV4dCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgZmx1c2hTeW5jIH0gZnJvbSBcInJlYWN0LWRvbVwiO1xuaW1wb3J0IHsgUm91Z2hDYW52YXMgfSBmcm9tIFwicm91Z2hqcy9iaW4vY2FudmFzXCI7XG5pbXBvcnQgcm91Z2ggZnJvbSBcInJvdWdoanMvYmluL3JvdWdoXCI7XG5pbXBvcnQgY2xzeCBmcm9tIFwiY2xzeFwiO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSBcIm5hbm9pZFwiO1xuXG5pbXBvcnQge1xuICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICBhY3Rpb25Db3B5LFxuICBhY3Rpb25Db3B5QXNQbmcsXG4gIGFjdGlvbkNvcHlBc1N2ZyxcbiAgY29weVRleHQsXG4gIGFjdGlvbkNvcHlTdHlsZXMsXG4gIGFjdGlvbkN1dCxcbiAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgYWN0aW9uRmluYWxpemUsXG4gIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICBhY3Rpb25GbGlwVmVydGljYWwsXG4gIGFjdGlvbkdyb3VwLFxuICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgYWN0aW9uU2VsZWN0QWxsLFxuICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gIGFjdGlvblNlbmRUb0JhY2ssXG4gIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgYWN0aW9uVW5iaW5kVGV4dCxcbiAgYWN0aW9uQmluZFRleHQsXG4gIGFjdGlvblVuZ3JvdXAsXG4gIGFjdGlvbkxpbmssXG4gIGFjdGlvblRvZ2dsZUxvY2ssXG59IGZyb20gXCIuLi9hY3Rpb25zXCI7XG5pbXBvcnQgeyBjcmVhdGVSZWRvQWN0aW9uLCBjcmVhdGVVbmRvQWN0aW9uIH0gZnJvbSBcIi4uL2FjdGlvbnMvYWN0aW9uSGlzdG9yeVwiO1xuaW1wb3J0IHsgQWN0aW9uTWFuYWdlciB9IGZyb20gXCIuLi9hY3Rpb25zL21hbmFnZXJcIjtcbmltcG9ydCB7IGFjdGlvbnMgfSBmcm9tIFwiLi4vYWN0aW9ucy9yZWdpc3RlclwiO1xuaW1wb3J0IHsgQWN0aW9uUmVzdWx0IH0gZnJvbSBcIi4uL2FjdGlvbnMvdHlwZXNcIjtcbmltcG9ydCB7IHRyYWNrRXZlbnQgfSBmcm9tIFwiLi4vYW5hbHl0aWNzXCI7XG5pbXBvcnQgeyBnZXREZWZhdWx0QXBwU3RhdGUsIGlzRXJhc2VyQWN0aXZlIH0gZnJvbSBcIi4uL2FwcFN0YXRlXCI7XG5pbXBvcnQge1xuICBwYXJzZUNsaXBib2FyZCxcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IsXG4gIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQsXG59IGZyb20gXCIuLi9jbGlwYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFQUF9OQU1FLFxuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICBERUZBVUxUX1VJX09QVElPTlMsXG4gIERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gIERSQUdHSU5HX1RIUkVTSE9MRCxcbiAgRUxFTUVOVF9SRUFEWV9UT19FUkFTRV9PUEFDSVRZLFxuICBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRU5WLFxuICBFVkVOVCxcbiAgR1JJRF9TSVpFLFxuICBJTUFHRV9SRU5ERVJfVElNRU9VVCxcbiAgTElORV9DT05GSVJNX1RIUkVTSE9MRCxcbiAgTUFYX0FMTE9XRURfRklMRV9CWVRFUyxcbiAgTUlNRV9UWVBFUyxcbiAgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9QT1JUUkFJVCxcbiAgTVFfUklHSFRfU0lERUJBUl9NSU5fV0lEVEgsXG4gIE1RX1NNX01BWF9XSURUSCxcbiAgUE9JTlRFUl9CVVRUT04sXG4gIFNDUk9MTF9USU1FT1VULFxuICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgVEVYVF9UT19DRU5URVJfU05BUF9USFJFU0hPTEQsXG4gIFRIRU1FLFxuICBUT1VDSF9DVFhfTUVOVV9USU1FT1VULFxuICBWRVJUSUNBTF9BTElHTixcbn0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgbG9hZEZyb21CbG9iIH0gZnJvbSBcIi4uL2RhdGFcIjtcbmltcG9ydCBMaWJyYXJ5LCB7IGRpc3RyaWJ1dGVMaWJyYXJ5SXRlbXNPblNxdWFyZUdyaWQgfSBmcm9tIFwiLi4vZGF0YS9saWJyYXJ5XCI7XG5pbXBvcnQgeyByZXN0b3JlLCByZXN0b3JlRWxlbWVudHMgfSBmcm9tIFwiLi4vZGF0YS9yZXN0b3JlXCI7XG5pbXBvcnQge1xuICBkcmFnTmV3RWxlbWVudCxcbiAgZHJhZ1NlbGVjdGVkRWxlbWVudHMsXG4gIGR1cGxpY2F0ZUVsZW1lbnQsXG4gIGdldENvbW1vbkJvdW5kcyxcbiAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50LFxuICBnZXREcmFnT2Zmc2V0WFksXG4gIGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgZ2V0Tm9ybWFsaXplZERpbWVuc2lvbnMsXG4gIGdldFJlc2l6ZUFycm93RGlyZWN0aW9uLFxuICBnZXRSZXNpemVPZmZzZXRYWSxcbiAgZ2V0TG9ja2VkTGluZWFyQ3Vyc29yQWxpZ25TaXplLFxuICBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyxcbiAgaGl0VGVzdCxcbiAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50LFxuICBpc0ludmlzaWJseVNtYWxsRWxlbWVudCxcbiAgaXNOb25EZWxldGVkRWxlbWVudCxcbiAgaXNUZXh0RWxlbWVudCxcbiAgbmV3RWxlbWVudCxcbiAgbmV3TGluZWFyRWxlbWVudCxcbiAgbmV3VGV4dEVsZW1lbnQsXG4gIG5ld0ltYWdlRWxlbWVudCxcbiAgdGV4dFd5c2l3eWcsXG4gIHRyYW5zZm9ybUVsZW1lbnRzLFxuICB1cGRhdGVUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4uL2VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGJpbmRPclVuYmluZExpbmVhckVsZW1lbnQsXG4gIGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMsXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbixcbiAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uLFxuICBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyxcbiAgZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nLFxuICBpc0JpbmRpbmdFbmFibGVkLFxuICBpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQsXG4gIG1heWJlQmluZExpbmVhckVsZW1lbnQsXG4gIHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQsXG4gIHVuYmluZExpbmVhckVsZW1lbnRzLFxuICB1cGRhdGVCb3VuZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZWxlbWVudC9iaW5kaW5nXCI7XG5pbXBvcnQgeyBMaW5lYXJFbGVtZW50RWRpdG9yIH0gZnJvbSBcIi4uL2VsZW1lbnQvbGluZWFyRWxlbWVudEVkaXRvclwiO1xuaW1wb3J0IHsgbXV0YXRlRWxlbWVudCwgbmV3RWxlbWVudFdpdGggfSBmcm9tIFwiLi4vZWxlbWVudC9tdXRhdGVFbGVtZW50XCI7XG5pbXBvcnQgeyBkZWVwQ29weUVsZW1lbnQsIG5ld0ZyZWVEcmF3RWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50L25ld0VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGhhc0JvdW5kVGV4dEVsZW1lbnQsXG4gIGlzQmluZGluZ0VsZW1lbnQsXG4gIGlzQmluZGluZ0VsZW1lbnRUeXBlLFxuICBpc0JvdW5kVG9Db250YWluZXIsXG4gIGlzSW1hZ2VFbGVtZW50LFxuICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50LFxuICBpc0xpbmVhckVsZW1lbnQsXG4gIGlzTGluZWFyRWxlbWVudFR5cGUsXG4gIGlzVGV4dEJpbmRhYmxlQ29udGFpbmVyLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlQ2hlY2tzXCI7XG5pbXBvcnQge1xuICBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50LFxuICBFeGNhbGlkcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0ZyZWVEcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50LFxuICBFeGNhbGlkcmF3TGluZWFyRWxlbWVudCxcbiAgRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICBOb25EZWxldGVkLFxuICBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEZpbGVJZCxcbiAgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3VGV4dENvbnRhaW5lcixcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IGdldENlbnRlciwgZ2V0RGlzdGFuY2UgfSBmcm9tIFwiLi4vZ2VzdHVyZVwiO1xuaW1wb3J0IHtcbiAgZWRpdEdyb3VwRm9yU2VsZWN0ZWRFbGVtZW50LFxuICBnZXRFbGVtZW50c0luR3JvdXAsXG4gIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQsXG4gIGdldFNlbGVjdGVkR3JvdXBJZHMsXG4gIGlzRWxlbWVudEluR3JvdXAsXG4gIGlzU2VsZWN0ZWRWaWFHcm91cCxcbiAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2dyb3Vwc1wiO1xuaW1wb3J0IEhpc3RvcnkgZnJvbSBcIi4uL2hpc3RvcnlcIjtcbmltcG9ydCB7IGRlZmF1bHRMYW5nLCBnZXRMYW5ndWFnZSwgbGFuZ3VhZ2VzLCBzZXRMYW5ndWFnZSwgdCB9IGZyb20gXCIuLi9pMThuXCI7XG5pbXBvcnQge1xuICBDT0RFUyxcbiAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcixcbiAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyxcbiAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUsXG4gIGlzQXJyb3dLZXksXG4gIEtFWVMsXG4gIGlzQW5kcm9pZCxcbn0gZnJvbSBcIi4uL2tleXNcIjtcbmltcG9ydCB7IGRpc3RhbmNlMmQsIGdldEdyaWRQb2ludCwgaXNQYXRoQUxvb3AgfSBmcm9tIFwiLi4vbWF0aFwiO1xuaW1wb3J0IHsgcmVuZGVyU2NlbmUgfSBmcm9tIFwiLi4vcmVuZGVyZXIvcmVuZGVyU2NlbmVcIjtcbmltcG9ydCB7IGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQgfSBmcm9tIFwiLi4vcmVuZGVyZXIvcmVuZGVyRWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgY2FsY3VsYXRlU2Nyb2xsQ2VudGVyLFxuICBnZXRUZXh0QmluZGFibGVDb250YWluZXJBdFBvc2l0aW9uLFxuICBnZXRFbGVtZW50c0F0UG9zaXRpb24sXG4gIGdldEVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLFxuICBnZXROb3JtYWxpemVkWm9vbSxcbiAgZ2V0U2VsZWN0ZWRFbGVtZW50cyxcbiAgaGFzQmFja2dyb3VuZCxcbiAgaXNPdmVyU2Nyb2xsQmFycyxcbiAgaXNTb21lRWxlbWVudFNlbGVjdGVkLFxufSBmcm9tIFwiLi4vc2NlbmVcIjtcbmltcG9ydCBTY2VuZSBmcm9tIFwiLi4vc2NlbmUvU2NlbmVcIjtcbmltcG9ydCB7IFJlbmRlckNvbmZpZywgU2Nyb2xsQmFycyB9IGZyb20gXCIuLi9zY2VuZS90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0U3RhdGVGb3Jab29tIH0gZnJvbSBcIi4uL3NjZW5lL3pvb21cIjtcbmltcG9ydCB7IGZpbmRTaGFwZUJ5S2V5LCBTSEFQRVMgfSBmcm9tIFwiLi4vc2hhcGVzXCI7XG5pbXBvcnQge1xuICBBcHBDbGFzc1Byb3BlcnRpZXMsXG4gIEFwcFByb3BzLFxuICBBcHBTdGF0ZSxcbiAgQmluYXJ5RmlsZURhdGEsXG4gIERhdGFVUkwsXG4gIEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJLFxuICBCaW5hcnlGaWxlcyxcbiAgR2VzdHVyZSxcbiAgR2VzdHVyZUV2ZW50LFxuICBMaWJyYXJ5SXRlbXMsXG4gIFBvaW50ZXJEb3duU3RhdGUsXG4gIFNjZW5lRGF0YSxcbiAgRGV2aWNlLFxufSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGRlYm91bmNlLFxuICBkaXN0YW5jZSxcbiAgZ2V0Rm9udFN0cmluZyxcbiAgZ2V0TmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIsXG4gIGlzSW5wdXRMaWtlLFxuICBpc1Rvb2xJY29uLFxuICBpc1dyaXRhYmxlRWxlbWVudCxcbiAgcmVzZXRDdXJzb3IsXG4gIHJlc29sdmFibGVQcm9taXNlLFxuICBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMsXG4gIHNldEN1cnNvcixcbiAgc2V0Q3Vyc29yRm9yU2hhcGUsXG4gIHR1cGxlVG9Db29ycyxcbiAgdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzLFxuICB3aXRoQmF0Y2hlZFVwZGF0ZXMsXG4gIHdyYXBFdmVudCxcbiAgd2l0aEJhdGNoZWRVcGRhdGVzVGhyb3R0bGVkLFxuICB1cGRhdGVPYmplY3QsXG4gIHNldEVyYXNlckN1cnNvcixcbiAgdXBkYXRlQWN0aXZlVG9vbCxcbn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgQ29udGV4dE1lbnUsIHsgQ29udGV4dE1lbnVPcHRpb24gfSBmcm9tIFwiLi9Db250ZXh0TWVudVwiO1xuaW1wb3J0IExheWVyVUkgZnJvbSBcIi4vTGF5ZXJVSVwiO1xuaW1wb3J0IHsgVG9hc3QgfSBmcm9tIFwiLi9Ub2FzdFwiO1xuaW1wb3J0IHsgYWN0aW9uVG9nZ2xlVmlld01vZGUgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25Ub2dnbGVWaWV3TW9kZVwiO1xuaW1wb3J0IHtcbiAgZGF0YVVSTFRvRmlsZSxcbiAgZ2VuZXJhdGVJZEZyb21GaWxlLFxuICBnZXREYXRhVVJMLFxuICBnZXRGaWxlRnJvbUV2ZW50LFxuICBpc1N1cHBvcnRlZEltYWdlRmlsZSxcbiAgbG9hZFNjZW5lT3JMaWJyYXJ5RnJvbUJsb2IsXG4gIG5vcm1hbGl6ZUZpbGUsXG4gIHBhcnNlTGlicmFyeUpTT04sXG4gIHJlc2l6ZUltYWdlRmlsZSxcbiAgU1ZHU3RyaW5nVG9GaWxlLFxufSBmcm9tIFwiLi4vZGF0YS9ibG9iXCI7XG5pbXBvcnQge1xuICBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMsXG4gIGxvYWRIVE1MSW1hZ2VFbGVtZW50LFxuICBub3JtYWxpemVTVkcsXG4gIHVwZGF0ZUltYWdlQ2FjaGUgYXMgX3VwZGF0ZUltYWdlQ2FjaGUsXG59IGZyb20gXCIuLi9lbGVtZW50L2ltYWdlXCI7XG5pbXBvcnQgdGhyb3R0bGUgZnJvbSBcImxvZGFzaC50aHJvdHRsZVwiO1xuaW1wb3J0IHsgZmlsZU9wZW4sIEZpbGVTeXN0ZW1IYW5kbGUgfSBmcm9tIFwiLi4vZGF0YS9maWxlc3lzdGVtXCI7XG5pbXBvcnQge1xuICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uLFxuICBnZXRBcHByb3hNaW5MaW5lSGVpZ2h0LFxuICBnZXRBcHByb3hNaW5MaW5lV2lkdGgsXG4gIGdldEJvdW5kVGV4dEVsZW1lbnQsXG59IGZyb20gXCIuLi9lbGVtZW50L3RleHRFbGVtZW50XCI7XG5pbXBvcnQgeyBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveCB9IGZyb20gXCIuLi9lbGVtZW50L2NvbGxpc2lvblwiO1xuaW1wb3J0IHtcbiAgbm9ybWFsaXplTGluayxcbiAgc2hvd0h5cGVybGlua1Rvb2x0aXAsXG4gIGhpZGVIeXBlcmxpbmtUb29saXAsXG4gIEh5cGVybGluayxcbiAgaXNQb2ludEhpdHRpbmdMaW5rSWNvbixcbiAgaXNMb2NhbExpbmssXG59IGZyb20gXCIuLi9lbGVtZW50L0h5cGVybGlua1wiO1xuXG5jb25zdCBkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlID0ge1xuICBpc1NtU2NyZWVuOiBmYWxzZSxcbiAgaXNNb2JpbGU6IGZhbHNlLFxuICBpc1RvdWNoU2NyZWVuOiBmYWxzZSxcbiAgY2FuRGV2aWNlRml0U2lkZWJhcjogZmFsc2UsXG59O1xuY29uc3QgRGV2aWNlQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8RGV2aWNlPihkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlKTtcbmV4cG9ydCBjb25zdCB1c2VEZXZpY2UgPSAoKSA9PiB1c2VDb250ZXh0PERldmljZT4oRGV2aWNlQ29udGV4dCk7XG5jb25zdCBFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8e1xuICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgaWQ6IHN0cmluZyB8IG51bGw7XG59Pih7IGNvbnRhaW5lcjogbnVsbCwgaWQ6IG51bGwgfSk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd0NvbnRhaW5lciA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQpO1xuXG5sZXQgZGlkVGFwVHdpY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCB0YXBwZWRUd2ljZVRpbWVyID0gMDtcbmxldCBjdXJzb3JYID0gMDtcbmxldCBjdXJzb3JZID0gMDtcbmxldCBpc0hvbGRpbmdTcGFjZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzUGFubmluZzogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzRHJhZ2dpbmdTY3JvbGxCYXI6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBjdXJyZW50U2Nyb2xsQmFyczogU2Nyb2xsQmFycyA9IHsgaG9yaXpvbnRhbDogbnVsbCwgdmVydGljYWw6IG51bGwgfTtcbmxldCB0b3VjaFRpbWVvdXQgPSAwO1xubGV0IGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG4vLyByZW1vdmUgdGhpcyBoYWNrIHdoZW4gd2UgY2FuIHN5bmMgcmVuZGVyICYgcmVzaXplT2JzZXJ2ZXIgKHN0YXRlIHVwZGF0ZSlcbi8vIHRvIHJBRi4gU2VlICM1NDM5XG5sZXQgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSB0cnVlO1xuXG5sZXQgbGFzdFBvaW50ZXJVcDogKChldmVudDogYW55KSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuY29uc3QgZ2VzdHVyZTogR2VzdHVyZSA9IHtcbiAgcG9pbnRlcnM6IG5ldyBNYXAoKSxcbiAgbGFzdENlbnRlcjogbnVsbCxcbiAgaW5pdGlhbERpc3RhbmNlOiBudWxsLFxuICBpbml0aWFsU2NhbGU6IG51bGwsXG59O1xuXG5jbGFzcyBBcHAgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8QXBwUHJvcHMsIEFwcFN0YXRlPiB7XG4gIGNhbnZhczogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiY2FudmFzXCJdID0gbnVsbDtcbiAgcmM6IFJvdWdoQ2FudmFzIHwgbnVsbCA9IG51bGw7XG4gIHVubW91bnRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBhY3Rpb25NYW5hZ2VyOiBBY3Rpb25NYW5hZ2VyO1xuICBkZXZpY2U6IERldmljZSA9IGRldmljZUNvbnRleHRJbml0aWFsVmFsdWU7XG4gIGRldGFjaElzTW9iaWxlTXFIYW5kbGVyPzogKCkgPT4gdm9pZDtcblxuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJSZWYgPSBSZWFjdC5jcmVhdGVSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgcHVibGljIHN0YXRpYyBkZWZhdWx0UHJvcHM6IFBhcnRpYWw8QXBwUHJvcHM+ID0ge1xuICAgIC8vIG5lZWRlZCBmb3IgdGVzdHMgdG8gcGFzcyBzaW5jZSB3ZSBkaXJlY3RseSByZW5kZXIgQXBwIGluIG1hbnkgdGVzdHNcbiAgICBVSU9wdGlvbnM6IERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgfTtcblxuICBwdWJsaWMgc2NlbmU6IFNjZW5lO1xuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBuZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBEb2N1bWVudCB8IHVuZGVmaW5lZDtcbiAgcHVibGljIGxpYnJhcnk6IEFwcENsYXNzUHJvcGVydGllc1tcImxpYnJhcnlcIl07XG4gIHB1YmxpYyBsaWJyYXJ5SXRlbXNGcm9tU3RvcmFnZTogTGlicmFyeUl0ZW1zIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGlkOiBzdHJpbmc7XG4gIHByaXZhdGUgaGlzdG9yeTogSGlzdG9yeTtcbiAgcHJpdmF0ZSBleGNhbGlkcmF3Q29udGFpbmVyVmFsdWU6IHtcbiAgICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgICBpZDogc3RyaW5nO1xuICB9O1xuXG4gIHB1YmxpYyBmaWxlczogQmluYXJ5RmlsZXMgPSB7fTtcbiAgcHVibGljIGltYWdlQ2FjaGU6IEFwcENsYXNzUHJvcGVydGllc1tcImltYWdlQ2FjaGVcIl0gPSBuZXcgTWFwKCk7XG5cbiAgaGl0TGlua0VsZW1lbnQ/OiBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQ7XG4gIGxhc3RQb2ludGVyRG93bjogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PiB8IG51bGwgPSBudWxsO1xuICBsYXN0UG9pbnRlclVwOiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTEVsZW1lbnQ+IHwgUG9pbnRlckV2ZW50IHwgbnVsbCA9IG51bGw7XG4gIGNvbnRleHRNZW51T3BlbjogYm9vbGVhbiA9IGZhbHNlO1xuICBsYXN0U2NlbmVQb2ludGVyOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQXBwUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG4gICAgY29uc3Qge1xuICAgICAgZXhjYWxpZHJhd1JlZixcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgemVuTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIGdyaWRNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgdGhlbWUgPSBkZWZhdWx0QXBwU3RhdGUudGhlbWUsXG4gICAgICBuYW1lID0gZGVmYXVsdEFwcFN0YXRlLm5hbWUsXG4gICAgfSA9IHByb3BzO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi5kZWZhdWx0QXBwU3RhdGUsXG4gICAgICB0aGVtZSxcbiAgICAgIGlzTG9hZGluZzogdHJ1ZSxcbiAgICAgIC4uLnRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpLFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICBncmlkU2l6ZTogZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIG5hbWUsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICAgIHNob3dIeXBlcmxpbmtQb3B1cDogZmFsc2UsXG4gICAgICBpc0xpYnJhcnlNZW51RG9ja2VkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgdGhpcy5pZCA9IG5hbm9pZCgpO1xuXG4gICAgdGhpcy5saWJyYXJ5ID0gbmV3IExpYnJhcnkodGhpcyk7XG4gICAgaWYgKGV4Y2FsaWRyYXdSZWYpIHtcbiAgICAgIGNvbnN0IHJlYWR5UHJvbWlzZSA9XG4gICAgICAgIChcImN1cnJlbnRcIiBpbiBleGNhbGlkcmF3UmVmICYmIGV4Y2FsaWRyYXdSZWYuY3VycmVudD8ucmVhZHlQcm9taXNlKSB8fFxuICAgICAgICByZXNvbHZhYmxlUHJvbWlzZTxFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQST4oKTtcblxuICAgICAgY29uc3QgYXBpOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSA9IHtcbiAgICAgICAgcmVhZHk6IHRydWUsXG4gICAgICAgIHJlYWR5UHJvbWlzZSxcbiAgICAgICAgdXBkYXRlU2NlbmU6IHRoaXMudXBkYXRlU2NlbmUsXG4gICAgICAgIHVwZGF0ZUxpYnJhcnk6IHRoaXMubGlicmFyeS51cGRhdGVMaWJyYXJ5LFxuICAgICAgICBhZGRGaWxlczogdGhpcy5hZGRGaWxlcyxcbiAgICAgICAgcmVzZXRTY2VuZTogdGhpcy5yZXNldFNjZW5lLFxuICAgICAgICBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZDogdGhpcy5nZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNsZWFyOiB0aGlzLnJlc2V0SGlzdG9yeSxcbiAgICAgICAgfSxcbiAgICAgICAgc2Nyb2xsVG9Db250ZW50OiB0aGlzLnNjcm9sbFRvQ29udGVudCxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50czogdGhpcy5nZXRTY2VuZUVsZW1lbnRzLFxuICAgICAgICBnZXRBcHBTdGF0ZTogKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICAgZ2V0RmlsZXM6ICgpID0+IHRoaXMuZmlsZXMsXG4gICAgICAgIHJlZnJlc2g6IHRoaXMucmVmcmVzaCxcbiAgICAgICAgc2V0VG9hc3Q6IHRoaXMuc2V0VG9hc3QsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICBzZXRBY3RpdmVUb29sOiB0aGlzLnNldEFjdGl2ZVRvb2wsXG4gICAgICAgIHNldEN1cnNvcjogdGhpcy5zZXRDdXJzb3IsXG4gICAgICAgIHJlc2V0Q3Vyc29yOiB0aGlzLnJlc2V0Q3Vyc29yLFxuICAgICAgfSBhcyBjb25zdDtcbiAgICAgIGlmICh0eXBlb2YgZXhjYWxpZHJhd1JlZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYoYXBpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYuY3VycmVudCA9IGFwaTtcbiAgICAgIH1cbiAgICAgIHJlYWR5UHJvbWlzZS5yZXNvbHZlKGFwaSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUgPSB7XG4gICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgfTtcblxuICAgIHRoaXMuc2NlbmUgPSBuZXcgU2NlbmUoKTtcbiAgICB0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeSgpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlciA9IG5ldyBBY3Rpb25NYW5hZ2VyKFxuICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0LFxuICAgICAgKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICgpID0+IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLFxuICAgICk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWxsKGFjdGlvbnMpO1xuXG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVVuZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVJlZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNhbnZhcygpIHtcbiAgICBjb25zdCBjYW52YXNTY2FsZSA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgIH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY2FudmFzRE9NV2lkdGggKiBjYW52YXNTY2FsZTtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjYW52YXNET01IZWlnaHQgKiBjYW52YXNTY2FsZTtcbiAgICBpZiAodmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Y2FudmFzXG4gICAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgICAgICBjdXJzb3I6IENVUlNPUl9UWVBFLkdSQUIsXG4gICAgICAgICAgfX1cbiAgICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlclVwfVxuICAgICAgICAgIG9uUG9pbnRlckNhbmNlbD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICAgIG9uVG91Y2hNb3ZlPXt0aGlzLmhhbmRsZVRvdWNoTW92ZX1cbiAgICAgICAgICBvblBvaW50ZXJEb3duPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJEb3dufVxuICAgICAgICA+XG4gICAgICAgICAge3QoXCJsYWJlbHMuZHJhd2luZ0NhbnZhc1wiKX1cbiAgICAgICAgPC9jYW52YXM+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgPGNhbnZhc1xuICAgICAgICBjbGFzc05hbWU9XCJleGNhbGlkcmF3X19jYW52YXNcIlxuICAgICAgICBzdHlsZT17e1xuICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgICAgfX1cbiAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICBoZWlnaHQ9e2NhbnZhc0hlaWdodH1cbiAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgb25Eb3VibGVDbGljaz17dGhpcy5oYW5kbGVDYW52YXNEb3VibGVDbGlja31cbiAgICAgICAgb25Qb2ludGVyTW92ZT17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyTW92ZX1cbiAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlclVwfVxuICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgPlxuICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgPC9jYW52YXM+XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZW5kZXIoKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3Qge1xuICAgICAgb25Db2xsYWJCdXR0b25DbGljayxcbiAgICAgIHJlbmRlclRvcFJpZ2h0VUksXG4gICAgICByZW5kZXJGb290ZXIsXG4gICAgICByZW5kZXJDdXN0b21TdGF0cyxcbiAgICB9ID0gdGhpcy5wcm9wcztcblxuICAgIHJldHVybiAoXG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT17Y2xzeChcImV4Y2FsaWRyYXcgZXhjYWxpZHJhdy1jb250YWluZXJcIiwge1xuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tdmlldy1tb2RlXCI6IHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkLFxuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tbW9iaWxlXCI6IHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgICB9KX1cbiAgICAgICAgcmVmPXt0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWZ9XG4gICAgICAgIG9uRHJvcD17dGhpcy5oYW5kbGVBcHBPbkRyb3B9XG4gICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgICBvbktleURvd249e1xuICAgICAgICAgIHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSA/IHVuZGVmaW5lZCA6IHRoaXMub25LZXlEb3duXG4gICAgICAgIH1cbiAgICAgID5cbiAgICAgICAgPEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0LlByb3ZpZGVyXG4gICAgICAgICAgdmFsdWU9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlfVxuICAgICAgICA+XG4gICAgICAgICAgPERldmljZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3RoaXMuZGV2aWNlfT5cbiAgICAgICAgICAgIDxMYXllclVJXG4gICAgICAgICAgICAgIGNhbnZhcz17dGhpcy5jYW52YXN9XG4gICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICBmaWxlcz17dGhpcy5maWxlc31cbiAgICAgICAgICAgICAgc2V0QXBwU3RhdGU9e3RoaXMuc2V0QXBwU3RhdGV9XG4gICAgICAgICAgICAgIGFjdGlvbk1hbmFnZXI9e3RoaXMuYWN0aW9uTWFuYWdlcn1cbiAgICAgICAgICAgICAgZWxlbWVudHM9e3RoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCl9XG4gICAgICAgICAgICAgIG9uQ29sbGFiQnV0dG9uQ2xpY2s9e29uQ29sbGFiQnV0dG9uQ2xpY2t9XG4gICAgICAgICAgICAgIG9uTG9ja1RvZ2dsZT17dGhpcy50b2dnbGVMb2NrfVxuICAgICAgICAgICAgICBvblBlbk1vZGVUb2dnbGU9e3RoaXMudG9nZ2xlUGVuTW9kZX1cbiAgICAgICAgICAgICAgb25JbnNlcnRFbGVtZW50cz17KGVsZW1lbnRzKSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICAgICAgICBwb3NpdGlvbjogXCJjZW50ZXJcIixcbiAgICAgICAgICAgICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGFuZ0NvZGU9e2dldExhbmd1YWdlKCkuY29kZX1cbiAgICAgICAgICAgICAgaXNDb2xsYWJvcmF0aW5nPXt0aGlzLnByb3BzLmlzQ29sbGFib3JhdGluZ31cbiAgICAgICAgICAgICAgcmVuZGVyVG9wUmlnaHRVST17cmVuZGVyVG9wUmlnaHRVSX1cbiAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tRm9vdGVyPXtyZW5kZXJGb290ZXJ9XG4gICAgICAgICAgICAgIHJlbmRlckN1c3RvbVN0YXRzPXtyZW5kZXJDdXN0b21TdGF0c31cbiAgICAgICAgICAgICAgc2hvd0V4aXRaZW5Nb2RlQnRuPXtcbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8uemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnplbk1vZGVFbmFibGVkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2hvd1RoZW1lQnRuPXtcbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8udGhlbWUgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5jYW52YXNBY3Rpb25zLnRoZW1lXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGlicmFyeVJldHVyblVybD17dGhpcy5wcm9wcy5saWJyYXJ5UmV0dXJuVXJsfVxuICAgICAgICAgICAgICBVSU9wdGlvbnM9e3RoaXMucHJvcHMuVUlPcHRpb25zfVxuICAgICAgICAgICAgICBmb2N1c0NvbnRhaW5lcj17dGhpcy5mb2N1c0NvbnRhaW5lcn1cbiAgICAgICAgICAgICAgbGlicmFyeT17dGhpcy5saWJyYXJ5fVxuICAgICAgICAgICAgICBpZD17dGhpcy5pZH1cbiAgICAgICAgICAgICAgb25JbWFnZUFjdGlvbj17dGhpcy5vbkltYWdlQWN0aW9ufVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy10ZXh0RWRpdG9yQ29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy1jb250ZXh0TWVudUNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICB7c2VsZWN0ZWRFbGVtZW50Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cCAmJiAoXG4gICAgICAgICAgICAgIDxIeXBlcmxpbmtcbiAgICAgICAgICAgICAgICBrZXk9e3NlbGVjdGVkRWxlbWVudFswXS5pZH1cbiAgICAgICAgICAgICAgICBlbGVtZW50PXtzZWxlY3RlZEVsZW1lbnRbMF19XG4gICAgICAgICAgICAgICAgYXBwU3RhdGU9e3RoaXMuc3RhdGV9XG4gICAgICAgICAgICAgICAgc2V0QXBwU3RhdGU9e3RoaXMuc2V0QXBwU3RhdGV9XG4gICAgICAgICAgICAgICAgb25MaW5rT3Blbj17dGhpcy5wcm9wcy5vbkxpbmtPcGVufVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLnRvYXN0ICE9PSBudWxsICYmIChcbiAgICAgICAgICAgICAgPFRvYXN0XG4gICAgICAgICAgICAgICAgbWVzc2FnZT17dGhpcy5zdGF0ZS50b2FzdC5tZXNzYWdlfVxuICAgICAgICAgICAgICAgIG9uQ2xvc2U9eygpID0+IHRoaXMuc2V0VG9hc3QobnVsbCl9XG4gICAgICAgICAgICAgICAgZHVyYXRpb249e3RoaXMuc3RhdGUudG9hc3QuZHVyYXRpb259XG4gICAgICAgICAgICAgICAgY2xvc2FibGU9e3RoaXMuc3RhdGUudG9hc3QuY2xvc2FibGV9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAgPG1haW4+e3RoaXMucmVuZGVyQ2FudmFzKCl9PC9tYWluPlxuICAgICAgICAgIDwvRGV2aWNlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgPC9FeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZm9jdXNDb250YWluZXI6IEFwcENsYXNzUHJvcGVydGllc1tcImZvY3VzQ29udGFpbmVyXCJdID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnByb3BzLmF1dG9Gb2N1cykge1xuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmZvY3VzKCk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50cyA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcbiAgfTtcblxuICBwcml2YXRlIHN5bmNBY3Rpb25SZXN1bHQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGFjdGlvblJlc3VsdDogQWN0aW9uUmVzdWx0KSA9PiB7XG4gICAgICAvLyBTaW5jZSBjb250ZXh0IG1lbnUgY2xvc2VzIHdoZW4gYWN0aW9uIHRyaWdnZXJlZCBzbyBzZXR0aW5nIHRvIGZhbHNlXG4gICAgICB0aGlzLmNvbnRleHRNZW51T3BlbiA9IGZhbHNlO1xuICAgICAgaWYgKHRoaXMudW5tb3VudGVkIHx8IGFjdGlvblJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgZWRpdGluZ0VsZW1lbnQ6IEFwcFN0YXRlW1wiZWRpdGluZ0VsZW1lbnRcIl0gfCBudWxsID0gbnVsbDtcbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuZWxlbWVudHMpIHtcbiAgICAgICAgYWN0aW9uUmVzdWx0LmVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50Py5pZCA9PT0gZWxlbWVudC5pZCAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCAhPT0gZWxlbWVudCAmJlxuICAgICAgICAgICAgaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGFjdGlvblJlc3VsdC5lbGVtZW50cyk7XG4gICAgICAgIGlmIChhY3Rpb25SZXN1bHQuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuZmlsZXMpIHtcbiAgICAgICAgdGhpcy5maWxlcyA9IGFjdGlvblJlc3VsdC5yZXBsYWNlRmlsZXNcbiAgICAgICAgICA/IGFjdGlvblJlc3VsdC5maWxlc1xuICAgICAgICAgIDogeyAuLi50aGlzLmZpbGVzLCAuLi5hY3Rpb25SZXN1bHQuZmlsZXMgfTtcbiAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFjdGlvblJlc3VsdC5hcHBTdGF0ZSB8fCBlZGl0aW5nRWxlbWVudCkge1xuICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB2aWV3TW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy52aWV3TW9kZUVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGxldCB6ZW5Nb2RlRW5hYmxlZCA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/Lnplbk1vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgZ3JpZFNpemUgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy5ncmlkU2l6ZSB8fCBudWxsO1xuICAgICAgICBsZXQgdGhlbWUgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy50aGVtZSB8fCBUSEVNRS5MSUdIVDtcbiAgICAgICAgbGV0IG5hbWUgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy5uYW1lID8/IHRoaXMuc3RhdGUubmFtZTtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgemVuTW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIGdyaWRTaXplID0gdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnRoZW1lICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdGhlbWUgPSB0aGlzLnByb3BzLnRoZW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLm5hbWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBuYW1lID0gdGhpcy5wcm9wcy5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgICAvLyB1c2luZyBPYmplY3QuYXNzaWduIGluc3RlYWQgb2Ygc3ByZWFkIHRvIGZvb2wgVFMgNC4yLjIrIGludG9cbiAgICAgICAgICAgIC8vIHJlZ2FyZGluZyB0aGUgcmVzdWx0aW5nIHR5cGUgYXMgbm90IGNvbnRhaW5pbmcgdW5kZWZpbmVkXG4gICAgICAgICAgICAvLyAod2hpY2ggdGhlIGZvbGxvd2luZyBleHByZXNzaW9uIHdpbGwgbmV2ZXIgY29udGFpbilcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGFjdGlvblJlc3VsdC5hcHBTdGF0ZSB8fCB7fSwge1xuICAgICAgICAgICAgICBlZGl0aW5nRWxlbWVudDpcbiAgICAgICAgICAgICAgICBlZGl0aW5nRWxlbWVudCB8fCBhY3Rpb25SZXN1bHQuYXBwU3RhdGU/LmVkaXRpbmdFbGVtZW50IHx8IG51bGwsXG4gICAgICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIGdyaWRTaXplLFxuICAgICAgICAgICAgICB0aGVtZSxcbiAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5zeW5jSGlzdG9yeSkge1xuICAgICAgICAgICAgICB0aGlzLmhpc3Rvcnkuc2V0Q3VycmVudFN0YXRlKFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgLy8gTGlmZWN5Y2xlXG5cbiAgcHJpdmF0ZSBvbkJsdXIgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25VbmxvYWQgPSAoKSA9PiB7XG4gICAgdGhpcy5vbkJsdXIoKTtcbiAgfTtcblxuICBwcml2YXRlIGRpc2FibGVFdmVudDogRXZlbnRMaXN0ZW5lciA9IChldmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBvbkZvbnRMb2FkZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoaXNUZXh0RWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMub25TY2VuZVVwZGF0ZWQoKTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0SGlzdG9yeSA9ICgpID0+IHtcbiAgICB0aGlzLmhpc3RvcnkuY2xlYXIoKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzZXRzIHNjZW5lICYgaGlzdG9yeS5cbiAgICogISBEbyBub3QgdXNlIHRvIGNsZWFyIHNjZW5lIHVzZXIgYWN0aW9uICFcbiAgICovXG4gIHByaXZhdGUgcmVzZXRTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAob3B0cz86IHsgcmVzZXRMb2FkaW5nU3RhdGU6IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW10pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldERlZmF1bHRBcHBTdGF0ZSgpLFxuICAgICAgICBpc0xvYWRpbmc6IG9wdHM/LnJlc2V0TG9hZGluZ1N0YXRlID8gZmFsc2UgOiBzdGF0ZS5pc0xvYWRpbmcsXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVNjZW5lID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChcImxhdW5jaFF1ZXVlXCIgaW4gd2luZG93ICYmIFwiTGF1bmNoUGFyYW1zXCIgaW4gd2luZG93KSB7XG4gICAgICAod2luZG93IGFzIGFueSkubGF1bmNoUXVldWUuc2V0Q29uc3VtZXIoXG4gICAgICAgIGFzeW5jIChsYXVuY2hQYXJhbXM6IHsgZmlsZXM6IGFueVtdIH0pID0+IHtcbiAgICAgICAgICBpZiAoIWxhdW5jaFBhcmFtcy5maWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZmlsZUhhbmRsZSA9IGxhdW5jaFBhcmFtcy5maWxlc1swXTtcbiAgICAgICAgICBjb25zdCBibG9iOiBCbG9iID0gYXdhaXQgZmlsZUhhbmRsZS5nZXRGaWxlKCk7XG4gICAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKFxuICAgICAgICAgICAgbmV3IEZpbGUoW2Jsb2JdLCBibG9iLm5hbWUgfHwgXCJcIiwgeyB0eXBlOiBibG9iLnR5cGUgfSksXG4gICAgICAgICAgICBmaWxlSGFuZGxlLFxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgfVxuICAgIGxldCBpbml0aWFsRGF0YSA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGluaXRpYWxEYXRhID0gKGF3YWl0IHRoaXMucHJvcHMuaW5pdGlhbERhdGEpIHx8IG51bGw7XG4gICAgICBpZiAoaW5pdGlhbERhdGE/LmxpYnJhcnlJdGVtcykge1xuICAgICAgICB0aGlzLmxpYnJhcnlcbiAgICAgICAgICAudXBkYXRlTGlicmFyeSh7XG4gICAgICAgICAgICBsaWJyYXJ5SXRlbXM6IGluaXRpYWxEYXRhLmxpYnJhcnlJdGVtcyxcbiAgICAgICAgICAgIG1lcmdlOiB0cnVlLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICBpbml0aWFsRGF0YSA9IHtcbiAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICBlcnJvck1lc3NhZ2U6XG4gICAgICAgICAgICBlcnJvci5tZXNzYWdlIHx8XG4gICAgICAgICAgICBcIkVuY291bnRlcmVkIGFuIGVycm9yIGR1cmluZyBpbXBvcnRpbmcgb3IgcmVzdG9yaW5nIHNjZW5lIGRhdGFcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHNjZW5lID0gcmVzdG9yZShpbml0aWFsRGF0YSwgbnVsbCwgbnVsbCk7XG4gICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgIC8vIHdlJ3JlIGZhbGxpbmcgYmFjayB0byBjdXJyZW50IChwcmUtaW5pdCkgc3RhdGUgd2hlbiBkZWNpZGluZ1xuICAgICAgLy8gd2hldGhlciB0byBvcGVuIHRoZSBsaWJyYXJ5LCB0byBoYW5kbGUgYSBjYXNlIHdoZXJlIHdlXG4gICAgICAvLyB1cGRhdGUgdGhlIHN0YXRlIG91dHNpZGUgb2YgaW5pdGlhbERhdGEgKGUuZy4gd2hlbiBsb2FkaW5nIHRoZSBhcHBcbiAgICAgIC8vIHdpdGggYSBsaWJyYXJ5IGluc3RhbGwgbGluaywgd2hpY2ggc2hvdWxkIGF1dG8tb3BlbiB0aGUgbGlicmFyeSlcbiAgICAgIGlzTGlicmFyeU9wZW46XG4gICAgICAgIGluaXRpYWxEYXRhPy5hcHBTdGF0ZT8uaXNMaWJyYXJ5T3BlbiB8fCB0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4sXG4gICAgICBhY3RpdmVUb29sOlxuICAgICAgICBzY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIlxuICAgICAgICAgID8geyAuLi5zY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLCB0eXBlOiBcInNlbGVjdGlvblwiIH1cbiAgICAgICAgICA6IHNjZW5lLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgdG9hc3Q6IHRoaXMuc3RhdGUudG9hc3QsXG4gICAgfTtcbiAgICBpZiAoaW5pdGlhbERhdGE/LnNjcm9sbFRvQ29udGVudCkge1xuICAgICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAuLi5jYWxjdWxhdGVTY3JvbGxDZW50ZXIoXG4gICAgICAgICAgc2NlbmUuZWxlbWVudHMsXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAgICAgICB3aWR0aDogdGhpcy5zdGF0ZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5zdGF0ZS5oZWlnaHQsXG4gICAgICAgICAgICBvZmZzZXRUb3A6IHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICAgICAgb2Zmc2V0TGVmdDogdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgLi4uc2NlbmUsXG4gICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWZyZXNoRGV2aWNlU3RhdGUgPSAoY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCkgPT4ge1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHNpZGViYXJCcmVha3BvaW50ID1cbiAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50ICE9IG51bGxcbiAgICAgICAgPyB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICAgICA6IE1RX1JJR0hUX1NJREVCQVJfTUlOX1dJRFRIO1xuICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7XG4gICAgICBpc1NtU2NyZWVuOiB3aWR0aCA8IE1RX1NNX01BWF9XSURUSCxcbiAgICAgIGlzTW9iaWxlOlxuICAgICAgICB3aWR0aCA8IE1RX01BWF9XSURUSF9QT1JUUkFJVCB8fFxuICAgICAgICAoaGVpZ2h0IDwgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUgJiYgd2lkdGggPCBNUV9NQVhfV0lEVEhfTEFORFNDQVBFKSxcbiAgICAgIGNhbkRldmljZUZpdFNpZGViYXI6IHdpZHRoID4gc2lkZWJhckJyZWFrcG9pbnQsXG4gICAgfSk7XG4gIH07XG5cbiAgcHVibGljIGFzeW5jIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgIHRoaXMudW5tb3VudGVkID0gZmFsc2U7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUuY29udGFpbmVyID1cbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuXG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5URVNUIHx8XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4gICAgKSB7XG4gICAgICBjb25zdCBzZXRTdGF0ZSA9IHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2V0U3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6ICguLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiBzZXRTdGF0ZT4pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKC4uLmFyZ3MpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFwcDoge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcyxcbiAgICAgICAgfSxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcy5oaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5hZGRDYWxsYmFjayh0aGlzLm9uU2NlbmVVcGRhdGVkKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCAmJlxuICAgICAgLy8gYm91bmRpbmcgcmVjdHMgZG9uJ3Qgd29yayBpbiB0ZXN0cyBzbyB1cGRhdGluZ1xuICAgICAgLy8gdGhlIHN0YXRlIG9uIGluaXQgd291bGQgcmVzdWx0IGluIG1ha2luZyB0aGUgdGVzdCBlbnZpcm8gcnVuXG4gICAgICAvLyBpbiBtb2JpbGUgYnJlYWtwb2ludCAoMCB3aWR0aC9oZWlnaHQpLCBtYWtpbmcgZXZlcnl0aGluZyBmYWlsXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJ0ZXN0XCJcbiAgICApIHtcbiAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoXCJSZXNpemVPYnNlcnZlclwiIGluIHdpbmRvdyAmJiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiA9IGZhbHNlO1xuICAgICAgICAvLyByZWNvbXB1dGUgZGV2aWNlIGRpbWVuc2lvbnMgc3RhdGVcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISk7XG4gICAgICAgIC8vIHJlZnJlc2ggb2Zmc2V0c1xuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy51cGRhdGVET01SZWN0KCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/Lm9ic2VydmUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH0gZWxzZSBpZiAod2luZG93Lm1hdGNoTWVkaWEpIHtcbiAgICAgIGNvbnN0IG1kU2NyZWVuUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtYXgtd2lkdGg6ICR7TVFfTUFYX1dJRFRIX1BPUlRSQUlUfXB4KSwgKG1heC1oZWlnaHQ6ICR7TVFfTUFYX0hFSUdIVF9MQU5EU0NBUEV9cHgpIGFuZCAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9MQU5EU0NBUEV9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBzbVNjcmVlblF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX1NNX01BWF9XSURUSH1weClgLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGNhbkRldmljZUZpdFNpZGViYXJNZWRpYVF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWluLXdpZHRoOiAke1xuICAgICAgICAgIC8vIE5PVEUgdGhpcyB3b24ndCB1cGRhdGUgaWYgYSBkaWZmZXJlbnQgYnJlYWtwb2ludCBpcyBzdXBwbGllZFxuICAgICAgICAgIC8vIGFmdGVyIG1vdW50XG4gICAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnQgIT0gbnVsbFxuICAgICAgICAgICAgPyB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICAgICAgICAgOiBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSFxuICAgICAgICB9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7XG4gICAgICAgICAgaXNTbVNjcmVlbjogc21TY3JlZW5RdWVyeS5tYXRjaGVzLFxuICAgICAgICAgIGlzTW9iaWxlOiBtZFNjcmVlblF1ZXJ5Lm1hdGNoZXMsXG4gICAgICAgICAgY2FuRGV2aWNlRml0U2lkZWJhcjogY2FuRGV2aWNlRml0U2lkZWJhck1lZGlhUXVlcnkubWF0Y2hlcyxcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgbWRTY3JlZW5RdWVyeS5hZGRMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXIgPSAoKSA9PlxuICAgICAgICBtZFNjcmVlblF1ZXJ5LnJlbW92ZUxpc3RlbmVyKGhhbmRsZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaC5zbGljZSgxKSk7XG5cbiAgICBpZiAoc2VhcmNoUGFyYW1zLmhhcyhcIndlYi1zaGFyZS10YXJnZXRcIikpIHtcbiAgICAgIC8vIE9idGFpbiBhIGZpbGUgdGhhdCB3YXMgc2hhcmVkIHZpYSB0aGUgV2ViIFNoYXJlIFRhcmdldCBBUEkuXG4gICAgICB0aGlzLnJlc3RvcmVGaWxlRnJvbVNoYXJlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCh0aGlzLmluaXRpYWxpemVTY2VuZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgIHRoaXMuZmlsZXMgPSB7fTtcbiAgICB0aGlzLmltYWdlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy51bm1vdW50ZWQgPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNjZW5lLmRlc3Ryb3koKTtcbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICB9XG5cbiAgcHJpdmF0ZSBvblJlc2l6ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgdGhpcy5zY2VuZVxuICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5XSEVFTCxcbiAgICAgIHRoaXMub25XaGVlbCxcbiAgICApO1xuICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRSQUdfT1ZFUixcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRST1AsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG5cbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG5cbiAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyPy4oKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTsgLy8gIzM1NTNcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULldIRUVMLFxuICAgICAgdGhpcy5vbldoZWVsLFxuICAgICAgeyBwYXNzaXZlOiBmYWxzZSB9LFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5KSB7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIHRoaXMub25LZXlEb3duLCBmYWxzZSk7XG4gICAgfVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgKTtcbiAgICAvLyByZXJlbmRlciB0ZXh0IGVsZW1lbnRzIG9uIGZvbnQgbG9hZCB0byBmaXggIzYzNyAmJiAjMTU1M1xuICAgIGRvY3VtZW50LmZvbnRzPy5hZGRFdmVudExpc3RlbmVyPy4oXCJsb2FkaW5nZG9uZVwiLCB0aGlzLm9uRm9udExvYWRlZCk7XG4gICAgLy8gU2FmYXJpLW9ubHkgZGVza3RvcCBwaW5jaCB6b29tXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgaWYgKHRoaXMucHJvcHMuZGV0ZWN0U2Nyb2xsKSB7XG4gICAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gZ2V0TmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIoXG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICk7XG4gICAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlNDUk9MTCxcbiAgICAgICAgdGhpcy5vblNjcm9sbCxcbiAgICAgICk7XG4gICAgfVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlJFU0laRSwgdGhpcy5vblJlc2l6ZSwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlVOTE9BRCwgdGhpcy5vblVubG9hZCwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRoaXMub25CbHVyLCBmYWxzZSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUkFHX09WRVIsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUk9QLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuICB9XG5cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogQXBwUHJvcHMsIHByZXZTdGF0ZTogQXBwU3RhdGUpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCAmJlxuICAgICAgcHJldlByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPT1cbiAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICApIHtcbiAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuc2Nyb2xsWCAhPT0gdGhpcy5zdGF0ZS5zY3JvbGxYIHx8XG4gICAgICBwcmV2U3RhdGUuc2Nyb2xsWSAhPT0gdGhpcy5zdGF0ZS5zY3JvbGxZXG4gICAgKSB7XG4gICAgICB0aGlzLnByb3BzPy5vblNjcm9sbENoYW5nZT8uKHRoaXMuc3RhdGUuc2Nyb2xsWCwgdGhpcy5zdGF0ZS5zY3JvbGxZKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBPYmplY3Qua2V5cyh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcykubGVuZ3RoICYmXG4gICAgICBpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKVxuICAgICkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiICYmXG4gICAgICBwcmV2U3RhdGUudGhlbWUgIT09IHRoaXMuc3RhdGUudGhlbWVcbiAgICApIHtcbiAgICAgIHNldEVyYXNlckN1cnNvcih0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS50aGVtZSk7XG4gICAgfVxuICAgIC8vIEhpZGUgaHlwZXJsaW5rIHBvcHVwIGlmIHNob3duIHdoZW4gZWxlbWVudCB0eXBlIGlzIG5vdCBzZWxlY3Rpb25cbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXBcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlIH0pO1xuICAgIH1cbiAgICBpZiAocHJldlByb3BzLmxhbmdDb2RlICE9PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxhbmd1YWdlKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlld01vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMudmlld01vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2U3RhdGUudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHplbk1vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy50aGVtZSAhPT0gdGhpcy5wcm9wcy50aGVtZSAmJiB0aGlzLnByb3BzLnRoZW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdGhlbWU6IHRoaXMucHJvcHMudGhlbWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZ3JpZFNpemU6IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb3BzLm5hbWUgJiYgcHJldlByb3BzLm5hbWUgIT09IHRoaXMucHJvcHMubmFtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG5hbWU6IHRoaXMucHJvcHMubmFtZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jbGFzc0xpc3QudG9nZ2xlKFxuICAgICAgXCJ0aGVtZS0tZGFya1wiLFxuICAgICAgdGhpcy5zdGF0ZS50aGVtZSA9PT0gXCJkYXJrXCIsXG4gICAgKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF1cbiAgICApIHtcbiAgICAgIC8vIGRlZmVyIHNvIHRoYXQgdGhlIGNvbW1pdFRvSGlzdG9yeSBmbGFnIGlzbid0IHJlc2V0IHZpYSBjdXJyZW50IHVwZGF0ZVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuZWxlbWVudElkXVxuICAgICkge1xuICAgICAgLy8gVG8gbWFrZSBzdXJlIGBzZWxlY3RlZExpbmVhckVsZW1lbnRgIGlzIGluIHN5bmMgd2l0aCBgc2VsZWN0ZWRFbGVtZW50SWRzYCwgaG93ZXZlciB0aGlzIHNob3VsZG4ndCBiZSBuZWVkZWQgb25jZVxuICAgICAgLy8gd2UgaGF2ZSBhIHNpbmdsZSBBUEkgdG8gdXBkYXRlIGBzZWxlY3RlZEVsZW1lbnRJZHNgXG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBudWxsIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSBwcmV2U3RhdGU7XG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLmFjdGl2ZVRvb2wgIT09IHRoaXMuc3RhdGUuYWN0aXZlVG9vbCAmJlxuICAgICAgbXVsdGlFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgIGlzQmluZGluZ0VsZW1lbnQobXVsdGlFbGVtZW50LCBmYWxzZSlcbiAgICApIHtcbiAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRBdEluZGV4R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgICAgICAtMSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJzb3JCdXR0b246IHtcbiAgICAgIFtpZDogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVmlld3BvcnRDb29yZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlcm5hbWVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlclN0YXRlczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgdGhpcy5zdGF0ZS5jb2xsYWJvcmF0b3JzLmZvckVhY2goKHVzZXIsIHNvY2tldElkKSA9PiB7XG4gICAgICBpZiAodXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICBpZiAoIShpZCBpbiByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0ucHVzaChzb2NrZXRJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghdXNlci5wb2ludGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICAgIHBvaW50ZXJVc2VybmFtZXNbc29ja2V0SWRdID0gdXNlci51c2VybmFtZTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJTdGF0ZSkge1xuICAgICAgICBwb2ludGVyVXNlclN0YXRlc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJTdGF0ZTtcbiAgICAgIH1cbiAgICAgIHBvaW50ZXJWaWV3cG9ydENvb3Jkc1tzb2NrZXRJZF0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgIHtcbiAgICAgICAgICBzY2VuZVg6IHVzZXIucG9pbnRlci54LFxuICAgICAgICAgIHNjZW5lWTogdXNlci5wb2ludGVyLnksXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY3Vyc29yQnV0dG9uW3NvY2tldElkXSA9IHVzZXIuYnV0dG9uO1xuICAgIH0pO1xuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gdGhpcy5zY2VuZVxuICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAuZmlsdGVyKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChpc0ltYWdlRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIC8vIG5vdCBwbGFjZWQgb24gY2FudmFzIHlldCAoYnV0IGluIGVsZW1lbnRzIGFycmF5KVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQgPT09IGVsZW1lbnQuaWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZG9uJ3QgcmVuZGVyIHRleHQgZWxlbWVudCB0aGF0J3MgYmVpbmcgY3VycmVudGx5IGVkaXRlZCAoaXQnc1xuICAgICAgICAvLyByZW5kZXJlZCBvbiByZW1vdGUgb25seSlcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQudHlwZSAhPT0gXCJ0ZXh0XCIgfHxcbiAgICAgICAgICBlbGVtZW50LmlkICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50LmlkXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgIHJlbmRlclNjZW5lKFxuICAgICAgcmVuZGVyaW5nRWxlbWVudHMsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICAgdGhpcy5zdGF0ZS5zZWxlY3Rpb25FbGVtZW50LFxuICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICB0aGlzLnJjISxcbiAgICAgIHRoaXMuY2FudmFzISxcbiAgICAgIHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYLFxuICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFksXG4gICAgICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUudmlld0JhY2tncm91bmRDb2xvcixcbiAgICAgICAgem9vbTogdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICByZW1vdGVQb2ludGVyVmlld3BvcnRDb29yZHM6IHBvaW50ZXJWaWV3cG9ydENvb3JkcyxcbiAgICAgICAgcmVtb3RlUG9pbnRlckJ1dHRvbjogY3Vyc29yQnV0dG9uLFxuICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHBvaW50ZXJVc2VybmFtZXMsXG4gICAgICAgIHJlbW90ZVBvaW50ZXJVc2VyU3RhdGVzOiBwb2ludGVyVXNlclN0YXRlcyxcbiAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0aGlzLnN0YXRlLnNob3VsZENhY2hlSWdub3JlWm9vbSxcbiAgICAgICAgdGhlbWU6IHRoaXMuc3RhdGUudGhlbWUsXG4gICAgICAgIGltYWdlQ2FjaGU6IHRoaXMuaW1hZ2VDYWNoZSxcbiAgICAgICAgaXNFeHBvcnRpbmc6IGZhbHNlLFxuICAgICAgICByZW5kZXJTY3JvbGxiYXJzOiAhdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICB9LFxuICAgICAgKHsgYXRMZWFzdE9uZVZpc2libGVFbGVtZW50LCBzY3JvbGxCYXJzIH0pID0+IHtcbiAgICAgICAgaWYgKHNjcm9sbEJhcnMpIHtcbiAgICAgICAgICBjdXJyZW50U2Nyb2xsQmFycyA9IHNjcm9sbEJhcnM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2Nyb2xsZWRPdXRzaWRlID1cbiAgICAgICAgICAvLyBoaWRlIHdoZW4gZWRpdGluZyB0ZXh0XG4gICAgICAgICAgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICAgICAgICAgPyBmYWxzZVxuICAgICAgICAgICAgOiAhYXRMZWFzdE9uZVZpc2libGVFbGVtZW50ICYmIHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCA+IDA7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNjcm9sbGVkT3V0c2lkZSAhPT0gc2Nyb2xsZWRPdXRzaWRlKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNjcm9sbGVkT3V0c2lkZSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2NoZWR1bGVJbWFnZVJlZnJlc2goKTtcbiAgICAgIH0sXG4gICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiAmJiB3aW5kb3cuRVhDQUxJRFJBV19USFJPVFRMRV9SRU5ERVIgPT09IHRydWUsXG4gICAgKTtcblxuICAgIGlmICghVEhST1RUTEVfTkVYVF9SRU5ERVIpIHtcbiAgICAgIFRIUk9UVExFX05FWFRfUkVOREVSID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmhpc3RvcnkucmVjb3JkKHRoaXMuc3RhdGUsIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkpO1xuXG4gICAgLy8gRG8gbm90IG5vdGlmeSBjb25zdW1lcnMgaWYgd2UncmUgc3RpbGwgbG9hZGluZyB0aGUgc2NlbmUuIEFtb25nIG90aGVyXG4gICAgLy8gcG90ZW50aWFsIGlzc3VlcywgdGhpcyBmaXhlcyBhIGNhc2Ugd2hlcmUgdGhlIHRhYiBpc24ndCBmb2N1c2VkIGR1cmluZ1xuICAgIC8vIGluaXQsIHdoaWNoIHdvdWxkIHRyaWdnZXIgb25DaGFuZ2Ugd2l0aCBlbXB0eSBlbGVtZW50cywgd2hpY2ggd291bGQgdGhlblxuICAgIC8vIG92ZXJyaWRlIHdoYXRldmVyIGlzIGluIGxvY2FsU3RvcmFnZSBjdXJyZW50bHkuXG4gICAgaWYgKCF0aGlzLnN0YXRlLmlzTG9hZGluZykge1xuICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZT8uKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmZpbGVzLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uU2Nyb2xsID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGNvbnN0IHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSB0aGlzLmdldENhbnZhc09mZnNldHMoKTtcbiAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgaWYgKHN0YXRlLm9mZnNldExlZnQgPT09IG9mZnNldExlZnQgJiYgc3RhdGUub2Zmc2V0VG9wID09PSBvZmZzZXRUb3ApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBvZmZzZXRUb3AsIG9mZnNldExlZnQgfTtcbiAgICB9KTtcbiAgfSwgU0NST0xMX1RJTUVPVVQpO1xuXG4gIC8vIENvcHkvcGFzdGVcblxuICBwcml2YXRlIG9uQ3V0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1dEFsbCgpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25Db3B5ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICBwcml2YXRlIGN1dEFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25DdXQsIFwia2V5Ym9hcmRcIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb3B5QWxsID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkNvcHksIFwia2V5Ym9hcmRcIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVzZXRUYXBUd2ljZSgpIHtcbiAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblRhcFN0YXJ0ID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XG4gICAgLy8gZml4IGZvciBBcHBsZSBQZW5jaWwgU2NyaWJibGVcbiAgICAvLyBPbiBBbmRyb2lkLCBwcmV2ZW50aW5nIHRoZSBldmVudCB3b3VsZCBkaXNhYmxlIGNvbnRleHRNZW51IG9uIHRhcC1ob2xkXG4gICAgaWYgKCFpc0FuZHJvaWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFkaWRUYXBUd2ljZSkge1xuICAgICAgZGlkVGFwVHdpY2UgPSB0cnVlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgICAgdGFwcGVkVHdpY2VUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KFxuICAgICAgICBBcHAucmVzZXRUYXBUd2ljZSxcbiAgICAgICAgVEFQX1RXSUNFX1RJTUVPVVQsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBpbnNlcnQgdGV4dCBvbmx5IGlmIHdlIHRhcHBlZCB0d2ljZSB3aXRoIGEgc2luZ2xlIGZpbmdlclxuICAgIC8vIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxIHdpbGwgYWxzbyBwcmV2ZW50IGluc2VydGluZyB0ZXh0IHdoZW4gdXNlcidzIHpvb21pbmdcbiAgICBpZiAoZGlkVGFwVHdpY2UgJiYgZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGNvbnN0IFt0b3VjaF0gPSBldmVudC50b3VjaGVzO1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5oYW5kbGVDYW52YXNEb3VibGVDbGljayh7XG4gICAgICAgIGNsaWVudFg6IHRvdWNoLmNsaWVudFgsXG4gICAgICAgIGNsaWVudFk6IHRvdWNoLmNsaWVudFksXG4gICAgICB9KTtcbiAgICAgIGRpZFRhcFR3aWNlID0gZmFsc2U7XG4gICAgICBjbGVhclRpbWVvdXQodGFwcGVkVHdpY2VUaW1lcik7XG4gICAgfVxuICAgIGlmIChpc0FuZHJvaWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uVGFwRW5kID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XG4gICAgdGhpcy5yZXNldENvbnRleHRNZW51VGltZXIoKTtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5wb2ludGVycy5jbGVhcigpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHBhc3RlRnJvbUNsaXBib2FyZCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICBhc3luYyAoZXZlbnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbCkgPT4ge1xuICAgICAgLy8gIzY4NlxuICAgICAgY29uc3QgdGFyZ2V0ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IGlzRXhjYWxpZHJhd0FjdGl2ZSA9XG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jb250YWlucyh0YXJnZXQpO1xuICAgICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBlbGVtZW50VW5kZXJDdXJzb3IgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGN1cnNvclgsIGN1cnNvclkpO1xuICAgICAgaWYgKFxuICAgICAgICAvLyBpZiBubyBDbGlwYm9hcmRFdmVudCBzdXBwbGllZCwgYXNzdW1lIHdlJ3JlIHBhc3RpbmcgdmlhIGNvbnRleHRNZW51XG4gICAgICAgIC8vIHRodXMgdGhlc2UgY2hlY2tzIGRvbid0IG1ha2Ugc2Vuc2VcbiAgICAgICAgZXZlbnQgJiZcbiAgICAgICAgKCEoZWxlbWVudFVuZGVyQ3Vyc29yIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHx8XG4gICAgICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG11c3QgYmUgY2FsbGVkIGluIHRoZSBzYW1lIGZyYW1lICh0aHVzIGJlZm9yZSBhbnkgYXdhaXRzKSBhcyB0aGUgcGFzdGVcbiAgICAgIC8vIGV2ZW50IGVsc2Ugc29tZSBicm93c2VycyAoRkYuLi4pIHdpbGwgY2xlYXIgdGhlIGNsaXBib2FyZERhdGFcbiAgICAgIC8vIChzb21ldGhpbmcgc29tZXRoaW5nIHNlY3VyaXR5KVxuICAgICAgbGV0IGZpbGUgPSBldmVudD8uY2xpcGJvYXJkRGF0YT8uZmlsZXNbMF07XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBwYXJzZUNsaXBib2FyZChldmVudCk7XG5cbiAgICAgIGlmICghZmlsZSAmJiBkYXRhLnRleHQpIHtcbiAgICAgICAgY29uc3Qgc3RyaW5nID0gZGF0YS50ZXh0LnRyaW0oKTtcbiAgICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKFwiPHN2Z1wiKSAmJiBzdHJpbmcuZW5kc1dpdGgoXCI8L3N2Zz5cIikpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgU1ZHIHZhbGlkYXRpb24vbm9ybWFsaXphdGlvbiB3aGljaCB3aWxsIGJlIGRvbmUgZHVyaW5nIGltYWdlXG4gICAgICAgICAgLy8gaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICBmaWxlID0gU1ZHU3RyaW5nVG9GaWxlKHN0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gcHJlZmVyIHNwcmVhZHNoZWV0IGRhdGEgb3ZlciBpbWFnZSBmaWxlIChNUyBPZmZpY2UvTGlicmUgT2ZmaWNlKVxuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpICYmICFkYXRhLnNwcmVhZHNoZWV0KSB7XG4gICAgICAgIGNvbnN0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHsgc2NlbmVYLCBzY2VuZVkgfSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgZmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5wcm9wcy5vblBhc3RlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3BzLm9uUGFzdGUoZGF0YSwgZXZlbnQpKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRhdGEuZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGRhdGEuZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnNwcmVhZHNoZWV0KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHBhc3RlRGlhbG9nOiB7XG4gICAgICAgICAgICBkYXRhOiBkYXRhLnNwcmVhZHNoZWV0LFxuICAgICAgICAgICAgc2hvd246IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgZWxlbWVudHM6IGRhdGEuZWxlbWVudHMsXG4gICAgICAgICAgZmlsZXM6IGRhdGEuZmlsZXMgfHwgbnVsbCxcbiAgICAgICAgICBwb3NpdGlvbjogXCJjdXJzb3JcIixcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEudGV4dCkge1xuICAgICAgICB0aGlzLmFkZFRleHRGcm9tUGFzdGUoZGF0YS50ZXh0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0QWN0aXZlVG9vbCh7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSk7XG4gICAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkgPSAob3B0czoge1xuICAgIGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdO1xuICAgIGZpbGVzOiBCaW5hcnlGaWxlcyB8IG51bGw7XG4gICAgcG9zaXRpb246IHsgY2xpZW50WDogbnVtYmVyOyBjbGllbnRZOiBudW1iZXIgfSB8IFwiY3Vyc29yXCIgfCBcImNlbnRlclwiO1xuICB9KSA9PiB7XG4gICAgY29uc3QgZWxlbWVudHMgPSByZXN0b3JlRWxlbWVudHMob3B0cy5lbGVtZW50cywgbnVsbCk7XG4gICAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKGVsZW1lbnRzKTtcblxuICAgIGNvbnN0IGVsZW1lbnRzQ2VudGVyWCA9IGRpc3RhbmNlKG1pblgsIG1heFgpIC8gMjtcbiAgICBjb25zdCBlbGVtZW50c0NlbnRlclkgPSBkaXN0YW5jZShtaW5ZLCBtYXhZKSAvIDI7XG5cbiAgICBjb25zdCBjbGllbnRYID1cbiAgICAgIHR5cGVvZiBvcHRzLnBvc2l0aW9uID09PSBcIm9iamVjdFwiXG4gICAgICAgID8gb3B0cy5wb3NpdGlvbi5jbGllbnRYXG4gICAgICAgIDogb3B0cy5wb3NpdGlvbiA9PT0gXCJjdXJzb3JcIlxuICAgICAgICA/IGN1cnNvclhcbiAgICAgICAgOiB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdDtcbiAgICBjb25zdCBjbGllbnRZID1cbiAgICAgIHR5cGVvZiBvcHRzLnBvc2l0aW9uID09PSBcIm9iamVjdFwiXG4gICAgICAgID8gb3B0cy5wb3NpdGlvbi5jbGllbnRZXG4gICAgICAgIDogb3B0cy5wb3NpdGlvbiA9PT0gXCJjdXJzb3JcIlxuICAgICAgICA/IGN1cnNvcllcbiAgICAgICAgOiB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcDtcblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYLCBjbGllbnRZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBkeCA9IHggLSBlbGVtZW50c0NlbnRlclg7XG4gICAgY29uc3QgZHkgPSB5IC0gZWxlbWVudHNDZW50ZXJZO1xuICAgIGNvbnN0IGdyb3VwSWRNYXAgPSBuZXcgTWFwKCk7XG5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChkeCwgZHksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3Qgb2xkSWRUb0R1cGxpY2F0ZWRJZCA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBuZXdFbGVtZW50cyA9IGVsZW1lbnRzLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgbmV3RWxlbWVudCA9IGR1cGxpY2F0ZUVsZW1lbnQoXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgIGdyb3VwSWRNYXAsXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHtcbiAgICAgICAgICB4OiBlbGVtZW50LnggKyBncmlkWCAtIG1pblgsXG4gICAgICAgICAgeTogZWxlbWVudC55ICsgZ3JpZFkgLSBtaW5ZLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQuc2V0KGVsZW1lbnQuaWQsIG5ld0VsZW1lbnQuaWQpO1xuICAgICAgcmV0dXJuIG5ld0VsZW1lbnQ7XG4gICAgfSk7XG4gICAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbihuZXdFbGVtZW50cywgZWxlbWVudHMsIG9sZElkVG9EdXBsaWNhdGVkSWQpO1xuICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAuLi5uZXdFbGVtZW50cyxcbiAgICBdO1xuICAgIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbihuZXh0RWxlbWVudHMsIGVsZW1lbnRzLCBvbGRJZFRvRHVwbGljYXRlZElkKTtcblxuICAgIGlmIChvcHRzLmZpbGVzKSB7XG4gICAgICB0aGlzLmZpbGVzID0geyAuLi50aGlzLmZpbGVzLCAuLi5vcHRzLmZpbGVzIH07XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMobmV4dEVsZW1lbnRzKTtcbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG5cbiAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAge1xuICAgICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgICAgaXNMaWJyYXJ5T3BlbjpcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuaXNMaWJyYXJ5T3BlbiAmJiB0aGlzLmRldmljZS5jYW5EZXZpY2VGaXRTaWRlYmFyXG4gICAgICAgICAgICAgID8gdGhpcy5zdGF0ZS5pc0xpYnJhcnlNZW51RG9ja2VkXG4gICAgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBuZXdFbGVtZW50cy5yZWR1Y2UoXG4gICAgICAgICAgICAoYWNjOiBSZWNvcmQ8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXSwgdHJ1ZT4sIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc0JvdW5kVG9Db250YWluZXIoZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICBhY2NbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge30sXG4gICAgICAgICAgKSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICksXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGlmIChvcHRzLmZpbGVzKSB7XG4gICAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICApO1xuICAgIHRoaXMuc2V0QWN0aXZlVG9vbCh7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBhZGRUZXh0RnJvbVBhc3RlKHRleHQ6IGFueSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHRleHQsXG4gICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB0ZXh0QWxpZ246IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2VsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICB9XG5cbiAgLy8gQ29sbGFib3JhdGlvblxuXG4gIHNldEFwcFN0YXRlID0gKG9iajogYW55KSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZShvYmopO1xuICB9O1xuXG4gIHJlbW92ZVBvaW50ZXIgPSAoZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MRWxlbWVudD4gfCBQb2ludGVyRXZlbnQpID0+IHtcbiAgICBpZiAodG91Y2hUaW1lb3V0KSB7XG4gICAgICB0aGlzLnJlc2V0Q29udGV4dE1lbnVUaW1lcigpO1xuICAgIH1cblxuICAgIGdlc3R1cmUucG9pbnRlcnMuZGVsZXRlKGV2ZW50LnBvaW50ZXJJZCk7XG4gIH07XG5cbiAgdG9nZ2xlTG9jayA9IChzb3VyY2U6IFwia2V5Ym9hcmRcIiB8IFwidWlcIiA9IFwidWlcIikgPT4ge1xuICAgIGlmICghdGhpcy5zdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgdHJhY2tFdmVudChcbiAgICAgICAgXCJ0b29sYmFyXCIsXG4gICAgICAgIFwidG9nZ2xlTG9ja1wiLFxuICAgICAgICBgJHtzb3VyY2V9ICgke3RoaXMuZGV2aWNlLmlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwifSlgLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBhY3RpdmVUb29sOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICAgICAgLi4udXBkYXRlQWN0aXZlVG9vbChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbC5sb2NrZWRcbiAgICAgICAgICAgICAgPyB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfVxuICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgICAgICksXG4gICAgICAgICAgbG9ja2VkOiAhcHJldlN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICB0b2dnbGVQZW5Nb2RlID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGVuTW9kZTogIXByZXZTdGF0ZS5wZW5Nb2RlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICBzY3JvbGxUb0NvbnRlbnQgPSAoXG4gICAgdGFyZ2V0OlxuICAgICAgfCBFeGNhbGlkcmF3RWxlbWVudFxuICAgICAgfCByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAuLi5jYWxjdWxhdGVTY3JvbGxDZW50ZXIoXG4gICAgICAgIEFycmF5LmlzQXJyYXkodGFyZ2V0KSA/IHRhcmdldCA6IFt0YXJnZXRdLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICksXG4gICAgfSk7XG4gIH07XG5cbiAgc2V0VG9hc3QgPSAoXG4gICAgdG9hc3Q6IHtcbiAgICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICAgIGNsb3NhYmxlPzogYm9vbGVhbjtcbiAgICAgIGR1cmF0aW9uPzogbnVtYmVyO1xuICAgIH0gfCBudWxsLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgdG9hc3QgfSk7XG4gIH07XG5cbiAgcmVzdG9yZUZpbGVGcm9tU2hhcmUgPSBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUgPSBhd2FpdCBjYWNoZXMub3BlbihcIndlYi1zaGFyZS10YXJnZXRcIik7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5tYXRjaChcInNoYXJlZC1maWxlXCIpO1xuICAgICAgaWYgKHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBhd2FpdCByZXNwb25zZS5ibG9iKCk7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBuZXcgRmlsZShbYmxvYl0sIGJsb2IubmFtZSB8fCBcIlwiLCB7IHR5cGU6IGJsb2IudHlwZSB9KTtcbiAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUsIG51bGwpO1xuICAgICAgICBhd2FpdCB3ZWJTaGFyZVRhcmdldENhY2hlLmRlbGV0ZShcInNoYXJlZC1maWxlXCIpO1xuICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgQVBQX05BTUUsIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIGFkZHMgc3VwcGxpZWQgZmlsZXMgdG8gZXhpc3RpbmcgZmlsZXMgaW4gdGhlIGFwcFN0YXRlICovXG4gIHB1YmxpYyBhZGRGaWxlczogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUElbXCJhZGRGaWxlc1wiXSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZmlsZXMpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVzTWFwID0gZmlsZXMucmVkdWNlKChhY2MsIGZpbGVEYXRhKSA9PiB7XG4gICAgICAgIGFjYy5zZXQoZmlsZURhdGEuaWQsIGZpbGVEYXRhKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIG5ldyBNYXA8RmlsZUlkLCBCaW5hcnlGaWxlRGF0YT4oKSk7XG5cbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLk9iamVjdC5mcm9tRW50cmllcyhmaWxlc01hcCkgfTtcblxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgZmlsZXNNYXAuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZGVsZXRlKGVsZW1lbnQuZmlsZUlkKTtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcblxuICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICB9LFxuICApO1xuXG4gIHB1YmxpYyB1cGRhdGVTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICA8SyBleHRlbmRzIGtleW9mIEFwcFN0YXRlPihzY2VuZURhdGE6IHtcbiAgICAgIGVsZW1lbnRzPzogU2NlbmVEYXRhW1wiZWxlbWVudHNcIl07XG4gICAgICBhcHBTdGF0ZT86IFBpY2s8QXBwU3RhdGUsIEs+IHwgbnVsbDtcbiAgICAgIGNvbGxhYm9yYXRvcnM/OiBTY2VuZURhdGFbXCJjb2xsYWJvcmF0b3JzXCJdO1xuICAgICAgY29tbWl0VG9IaXN0b3J5PzogU2NlbmVEYXRhW1wiY29tbWl0VG9IaXN0b3J5XCJdO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChzY2VuZURhdGEuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5hcHBTdGF0ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHNjZW5lRGF0YS5hcHBTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoc2NlbmVEYXRhLmVsZW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5jb2xsYWJvcmF0b3JzKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb2xsYWJvcmF0b3JzOiBzY2VuZURhdGEuY29sbGFib3JhdG9ycyB9KTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25TY2VuZVVwZGF0ZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjdXJzb3JYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGN1cnNvclkgPSBldmVudC5jbGllbnRZO1xuICAgIH0sXG4gICk7XG5cbiAgLy8gSW5wdXQgaGFuZGxpbmdcblxuICBwcml2YXRlIG9uS2V5RG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IFJlYWN0LktleWJvYXJkRXZlbnQgfCBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBub3JtYWxpemUgYGV2ZW50LmtleWAgd2hlbiBDYXBzTG9jayBpcyBwcmVzc2VkICMyMzcyXG5cbiAgICAgIGlmIChcbiAgICAgICAgXCJQcm94eVwiIGluIHdpbmRvdyAmJlxuICAgICAgICAoKCFldmVudC5zaGlmdEtleSAmJiAvXltBLVpdJC8udGVzdChldmVudC5rZXkpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleSAmJiAvXlthLXpdJC8udGVzdChldmVudC5rZXkpKSlcbiAgICAgICkge1xuICAgICAgICBldmVudCA9IG5ldyBQcm94eShldmVudCwge1xuICAgICAgICAgIGdldChldjogYW55LCBwcm9wKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGV2W3Byb3BdO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgIC8vIGZpeCBmb3IgUHJveGllcyBoaWphY2tpbmcgYHRoaXNgXG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5iaW5kKGV2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwcm9wID09PSBcImtleVwiXG4gICAgICAgICAgICAgID8gLy8gQ2Fwc0xvY2sgaW52ZXJ0cyBjYXBpdGFsaXphdGlvbiBiYXNlZCBvbiBTaGlmdEtleSwgc28gaW52ZXJ0XG4gICAgICAgICAgICAgICAgLy8gaXQgYmFja1xuICAgICAgICAgICAgICAgIGV2ZW50LnNoaWZ0S2V5XG4gICAgICAgICAgICAgICAgPyBldi5rZXkudG9VcHBlckNhc2UoKVxuICAgICAgICAgICAgICAgIDogZXYua2V5LnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gcHJldmVudCBicm93c2VyIHpvb20gaW4gaW5wdXQgZmllbGRzXG4gICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gQ09ERVMuTUlOVVMgfHwgZXZlbnQuY29kZSA9PT0gQ09ERVMuRVFVQUwpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBiYWlsIGlmXG4gICAgICBpZiAoXG4gICAgICAgIC8vIGluc2lkZSBhbiBpbnB1dFxuICAgICAgICAoaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSAmJlxuICAgICAgICAgIC8vIHVubGVzcyBwcmVzc2luZyBlc2NhcGUgKGZpbmFsaXplIGFjdGlvbilcbiAgICAgICAgICBldmVudC5rZXkgIT09IEtFWVMuRVNDQVBFKSB8fFxuICAgICAgICAvLyBvciB1bmxlc3MgdXNpbmcgYXJyb3dzICh0byBtb3ZlIGJldHdlZW4gYnV0dG9ucylcbiAgICAgICAgKGlzQXJyb3dLZXkoZXZlbnQua2V5KSAmJiBpc0lucHV0TGlrZShldmVudC50YXJnZXQpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5RVUVTVElPTl9NQVJLKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNob3dIZWxwRGlhbG9nOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYWN0aW9uTWFuYWdlci5oYW5kbGVLZXlEb3duKGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiB0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IGZhbHNlIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQuY29kZSA9PT0gQ09ERVMuWkVSTykge1xuICAgICAgICBjb25zdCBuZXh0U3RhdGUgPSAhdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogbmV4dFN0YXRlIH0pO1xuICAgICAgICAvLyB0cmFjayBvbmx5IG9wZW5pbmdzXG4gICAgICAgIGlmIChuZXh0U3RhdGUpIHtcbiAgICAgICAgICB0cmFja0V2ZW50KFxuICAgICAgICAgICAgXCJsaWJyYXJ5XCIsXG4gICAgICAgICAgICBcInRvZ2dsZUxpYnJhcnkgKG9wZW4pXCIsXG4gICAgICAgICAgICBga2V5Ym9hcmQgKCR7dGhpcy5kZXZpY2UuaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCJ9KWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAgICh0aGlzLnN0YXRlLmdyaWRTaXplICYmXG4gICAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgPyBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmdyaWRTaXplKSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgID8gRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5UXG4gICAgICAgICAgICA6IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IG9mZnNldFggPSAwO1xuICAgICAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19MRUZUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19SSUdIVCkge1xuICAgICAgICAgIG9mZnNldFggPSBzdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19VUCkge1xuICAgICAgICAgIG9mZnNldFkgPSAtc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfRE9XTikge1xuICAgICAgICAgIG9mZnNldFkgPSBzdGVwO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgICAgICB4OiBlbGVtZW50LnggKyBvZmZzZXRYLFxuICAgICAgICAgICAgeTogZWxlbWVudC55ICsgb2Zmc2V0WSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCwge1xuICAgICAgICAgICAgc2ltdWx0YW5lb3VzbHlVcGRhdGVkOiBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVOVEVSKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBpZiAoaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0uaWRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuXG4gICAgICAgICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICAgICAgICBzY2VuZVg6IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMixcbiAgICAgICAgICAgICAgc2NlbmVZOiBzZWxlY3RlZEVsZW1lbnQueSArIHNlbGVjdGVkRWxlbWVudC5oZWlnaHQgLyAyLFxuICAgICAgICAgICAgICBzaG91bGRCaW5kOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgIWV2ZW50LmN0cmxLZXkgJiZcbiAgICAgICAgIWV2ZW50LmFsdEtleSAmJlxuICAgICAgICAhZXZlbnQubWV0YUtleSAmJlxuICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCA9PT0gbnVsbFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gZmluZFNoYXBlQnlLZXkoZXZlbnQua2V5KTtcbiAgICAgICAgaWYgKHNoYXBlKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBzaGFwZSkge1xuICAgICAgICAgICAgdHJhY2tFdmVudChcbiAgICAgICAgICAgICAgXCJ0b29sYmFyXCIsXG4gICAgICAgICAgICAgIHNoYXBlLFxuICAgICAgICAgICAgICBga2V5Ym9hcmQgKCR7dGhpcy5kZXZpY2UuaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCJ9KWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNldEFjdGl2ZVRvb2woeyB0eXBlOiBzaGFwZSB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuUSkge1xuICAgICAgICAgIHRoaXMudG9nZ2xlTG9jayhcImtleWJvYXJkXCIpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFICYmIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBpc0hvbGRpbmdTcGFjZSA9IHRydWU7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIChldmVudC5rZXkgPT09IEtFWVMuRyB8fCBldmVudC5rZXkgPT09IEtFWVMuUykgJiZcbiAgICAgICAgIWV2ZW50LmFsdEtleSAmJlxuICAgICAgICAhZXZlbnRbS0VZUy5DVFJMX09SX0NNRF1cbiAgICAgICkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICAgICFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkcgJiZcbiAgICAgICAgICAoaGFzQmFja2dyb3VuZCh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSkgfHxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT4gaGFzQmFja2dyb3VuZChlbGVtZW50LnR5cGUpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5Qb3B1cDogXCJiYWNrZ3JvdW5kQ29sb3JQaWNrZXJcIiB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlMpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgb3BlblBvcHVwOiBcInN0cm9rZUNvbG9yUGlja2VyXCIgfSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25XaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICAvLyBwcmV2ZW50IGJyb3dzZXIgcGluY2ggem9vbSBvbiBET00gZWxlbWVudHNcbiAgICBpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkgJiYgZXZlbnQuY3RybEtleSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgb25LZXlVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gICAgfVxuICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpXG4gICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBzZXRBY3RpdmVUb29sID0gKFxuICAgIHRvb2w6XG4gICAgICB8IHsgdHlwZTogdHlwZW9mIFNIQVBFU1tudW1iZXJdW1widmFsdWVcIl0gfCBcImVyYXNlclwiIH1cbiAgICAgIHwgeyB0eXBlOiBcImN1c3RvbVwiOyBjdXN0b21UeXBlOiBzdHJpbmcgfSxcbiAgKSA9PiB7XG4gICAgY29uc3QgbmV4dEFjdGl2ZVRvb2wgPSB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHRvb2wpO1xuICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgaWYgKGlzVG9vbEljb24oZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG4gICAgaWYgKCFpc0xpbmVhckVsZW1lbnRUeXBlKG5leHRBY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgICBpZiAobmV4dEFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICB0aGlzLm9uSW1hZ2VBY3Rpb24oKTtcbiAgICB9XG4gICAgaWYgKG5leHRBY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiBuZXh0QWN0aXZlVG9vbCxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBhY3RpdmVUb29sOiBuZXh0QWN0aXZlVG9vbCB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRDdXJzb3IgPSAoY3Vyc29yOiBzdHJpbmcpID0+IHtcbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIGN1cnNvcik7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEN1cnNvciA9ICgpID0+IHtcbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gIH07XG4gIC8qKlxuICAgKiByZXR1cm5zIHdoZXRoZXIgdXNlciBpcyBtYWtpbmcgYSBnZXN0dXJlIHdpdGggPj0gMiBmaW5nZXJzIChwb2ludHMpXG4gICAqIG9uIG8gdG91Y2ggc2NyZWVuIChub3Qgb24gYSB0cmFja3BhZCkuIEN1cnJlbnRseSBvbmx5IHJlbGF0ZXMgdG8gRGFyd2luXG4gICAqIChpT1MvaVBhZE9TLE1hY09TKSwgYnV0IG1heSB3b3JrIG9uIG90aGVyIGRldmljZXMgaW4gdGhlIGZ1dHVyZSBpZlxuICAgKiBHZXN0dXJlRXZlbnQgaXMgc3RhbmRhcmRpemVkLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUgPSAoKSA9PiB7XG4gICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBkZXNlbGVjdCB3aGVuIHVzaW5nIHRyYWNrcGFkLCBhbmQgbXVsdGktcG9pbnQgZ2VzdHVyZXNcbiAgICAvLyBvbmx5IHdvcmsgb24gdG91Y2ggc2NyZWVucywgc28gY2hlY2tpbmcgZm9yID49IHBvaW50ZXJzIG1lYW5zIHdlJ3JlIG9uIGFcbiAgICAvLyB0b3VjaHNjcmVlblxuICAgIHJldHVybiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPj0gMjtcbiAgfTtcblxuICAvLyBmaXJlcyBvbmx5IG9uIFNhZmFyaVxuICBwcml2YXRlIG9uR2VzdHVyZVN0YXJ0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIHdlIG9ubHkgd2FudCB0byBkZXNlbGVjdCBvbiB0b3VjaCBzY3JlZW5zIGJlY2F1c2UgdXNlciBtYXkgaGF2ZSBzZWxlY3RlZFxuICAgIC8vIGVsZW1lbnRzIGJ5IG1pc3Rha2Ugd2hpbGUgem9vbWluZ1xuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgfSk7XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVDaGFuZ2UgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gb25HZXN0dXJlQ2hhbmdlIG9ubHkgaGFzIHpvb20gZmFjdG9yIGJ1dCBub3QgdGhlIGNlbnRlci5cbiAgICAvLyBJZiB3ZSdyZSBvbiBpUGFkIG9yIGlQaG9uZSwgdGhlbiB3ZSByZWNvZ25pemUgbXVsdGktdG91Y2ggYW5kIHdpbGxcbiAgICAvLyB6b29tIGluIGF0IHRoZSByaWdodCBsb2NhdGlvbiBpbiB0aGUgdG91Y2htb3ZlIGhhbmRsZXJcbiAgICAvLyAoaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUpLlxuICAgIC8vXG4gICAgLy8gT24gTWFjYm9vayB0cmFja3BhZCwgd2UgZG9uJ3QgaGF2ZSB0aG9zZSBldmVudHMgc28gd2lsbCB6b29tIGluIGF0IHRoZVxuICAgIC8vIGN1cnJlbnQgbG9jYXRpb24gaW5zdGVhZC5cbiAgICAvL1xuICAgIC8vIEFzIHN1Y2gsIGJhaWwgZnJvbSB0aGlzIGhhbmRsZXIgb24gdG91Y2ggZGV2aWNlcy5cbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChpbml0aWFsU2NhbGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXRTdGF0ZUZvclpvb20oXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmlld3BvcnRYOiBjdXJzb3JYLFxuICAgICAgICAgICAgdmlld3BvcnRZOiBjdXJzb3JZLFxuICAgICAgICAgICAgbmV4dFpvb206IGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIGV2ZW50LnNjYWxlKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVFbmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIC8vIHJlc2VsZWN0IGVsZW1lbnRzIG9ubHkgb24gdG91Y2ggc2NyZWVucyAoc2VlIG9uR2VzdHVyZVN0YXJ0KVxuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSBudWxsO1xuICB9KTtcblxuICBwcml2YXRlIGhhbmRsZVRleHRXeXNpd3lnKFxuICAgIGVsZW1lbnQ6IEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgICB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudCA9IGZhbHNlLFxuICAgIH06IHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50PzogYm9vbGVhbjtcbiAgICB9LFxuICApIHtcbiAgICBjb25zdCB1cGRhdGVFbGVtZW50ID0gKFxuICAgICAgdGV4dDogc3RyaW5nLFxuICAgICAgb3JpZ2luYWxUZXh0OiBzdHJpbmcsXG4gICAgICBpc0RlbGV0ZWQ6IGJvb2xlYW4sXG4gICAgKSA9PiB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChfZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChfZWxlbWVudC5pZCA9PT0gZWxlbWVudC5pZCAmJiBpc1RleHRFbGVtZW50KF9lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVRleHRFbGVtZW50KF9lbGVtZW50LCB7XG4gICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgIGlzRGVsZXRlZCxcbiAgICAgICAgICAgICAgb3JpZ2luYWxUZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBfZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICBdKTtcbiAgICB9O1xuXG4gICAgdGV4dFd5c2l3eWcoe1xuICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICBjYW52YXM6IHRoaXMuY2FudmFzLFxuICAgICAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4LCB5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgICAgICBzY2VuZVk6IHksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHZpZXdwb3J0WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB2aWV3cG9ydFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgXTtcbiAgICAgIH0sXG4gICAgICBvbkNoYW5nZTogd2l0aEJhdGNoZWRVcGRhdGVzKCh0ZXh0KSA9PiB7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgdGV4dCwgZmFsc2UpO1xuICAgICAgICBpZiAoaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgb25TdWJtaXQ6IHdpdGhCYXRjaGVkVXBkYXRlcygoeyB0ZXh0LCB2aWFLZXlib2FyZCwgb3JpZ2luYWxUZXh0IH0pID0+IHtcbiAgICAgICAgY29uc3QgaXNEZWxldGVkID0gIXRleHQudHJpbSgpO1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIG9yaWdpbmFsVGV4dCwgaXNEZWxldGVkKTtcbiAgICAgICAgLy8gc2VsZWN0IHRoZSBjcmVhdGVkIHRleHQgZWxlbWVudCBvbmx5IGlmIHN1Ym1pdHRpbmcgdmlhIGtleWJvYXJkXG4gICAgICAgIC8vICh3aGVuIHN1Ym1pdHRpbmcgdmlhIGNsaWNrIGl0IHNob3VsZCBhY3QgYXMgc2lnbmFsIHRvIGRlc2VsZWN0KVxuICAgICAgICBpZiAoIWlzRGVsZXRlZCAmJiB2aWFLZXlib2FyZCkge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRJZFRvU2VsZWN0ID0gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgPyBlbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgICAgICA6IGVsZW1lbnQuaWQ7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgIFtlbGVtZW50SWRUb1NlbGVjdF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWxldGVkKSB7XG4gICAgICAgICAgZml4QmluZGluZ3NBZnRlckRlbGV0aW9uKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIFtcbiAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgfHwgaXNFeGlzdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICAgIH0pLFxuICAgICAgZWxlbWVudCxcbiAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgYXBwOiB0aGlzLFxuICAgIH0pO1xuICAgIC8vIGRlc2VsZWN0IGFsbCBvdGhlciBlbGVtZW50cyB3aGVuIGluc2VydGluZyB0ZXh0XG4gICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG5cbiAgICAvLyBkbyBhbiBpbml0aWFsIHVwZGF0ZSB0byByZS1pbml0aWFsaXplIGVsZW1lbnQgcG9zaXRpb24gc2luY2Ugd2Ugd2VyZVxuICAgIC8vIG1vZGlmeWluZyBlbGVtZW50J3MgeC95IGZvciBzYWtlIG9mIGVkaXRvciAoY2FzZTogc3luY2luZyB0byByZW1vdGUpXG4gICAgdXBkYXRlRWxlbWVudChlbGVtZW50LnRleHQsIGVsZW1lbnQub3JpZ2luYWxUZXh0LCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIGRlc2VsZWN0RWxlbWVudHMoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd1RleHRFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQgJiYgaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiAhZWxlbWVudC5pc0RlbGV0ZWQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBvcHRzPzoge1xuICAgICAgLyoqIGlmIHRydWUsIHJldHVybnMgdGhlIGZpcnN0IHNlbGVjdGVkIGVsZW1lbnQgKHdpdGggaGlnaGVzdCB6LWluZGV4KVxuICAgICAgICBvZiBhbGwgaGl0IGVsZW1lbnRzICovXG4gICAgICBwcmVmZXJTZWxlY3RlZD86IGJvb2xlYW47XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudD86IGJvb2xlYW47XG4gICAgICBpbmNsdWRlTG9ja2VkRWxlbWVudHM/OiBib29sZWFuO1xuICAgIH0sXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+IHwgbnVsbCB7XG4gICAgY29uc3QgYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgb3B0cz8uaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQsXG4gICAgICBvcHRzPy5pbmNsdWRlTG9ja2VkRWxlbWVudHMsXG4gICAgKTtcbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKG9wdHM/LnByZWZlclNlbGVjdGVkKSB7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMTsgaW5kZXggPiAtMTsgaW5kZXgtLSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1thbGxIaXRFbGVtZW50c1tpbmRleF0uaWRdKSB7XG4gICAgICAgICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbaW5kZXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4ID1cbiAgICAgICAgYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMV07XG4gICAgICAvLyBJZiB3ZSdyZSBoaXR0aW5nIGVsZW1lbnQgd2l0aCBoaWdoZXN0IHotaW5kZXggb25seSBvbiBpdHMgYm91bmRpbmcgYm94XG4gICAgICAvLyB3aGlsZSBhbHNvIGhpdHRpbmcgb3RoZXIgZWxlbWVudCBmaWd1cmUsIHRoZSBsYXR0ZXIgc2hvdWxkIGJlIGNvbnNpZGVyZWQuXG4gICAgICByZXR1cm4gaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXgsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICApXG4gICAgICAgID8gYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMl1cbiAgICAgICAgOiBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXg7XG4gICAgfVxuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1swXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgaW5jbHVkZUxvY2tlZEVsZW1lbnRzOiBib29sZWFuID0gZmFsc2UsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10ge1xuICAgIGNvbnN0IGVsZW1lbnRzID1cbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50ICYmIGluY2x1ZGVMb2NrZWRFbGVtZW50c1xuICAgICAgICA/IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgOiB0aGlzLnNjZW5lXG4gICAgICAgICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAgIChlbGVtZW50KSA9PlxuICAgICAgICAgICAgICAgIChpbmNsdWRlTG9ja2VkRWxlbWVudHMgfHwgIWVsZW1lbnQubG9ja2VkKSAmJlxuICAgICAgICAgICAgICAgIChpbmNsdWRlQm91bmRUZXh0RWxlbWVudCB8fFxuICAgICAgICAgICAgICAgICAgIShpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmIGVsZW1lbnQuY29udGFpbmVySWQpKSxcbiAgICAgICAgICAgICk7XG5cbiAgICByZXR1cm4gZ2V0RWxlbWVudHNBdFBvc2l0aW9uKGVsZW1lbnRzLCAoZWxlbWVudCkgPT5cbiAgICAgIGhpdFRlc3QoZWxlbWVudCwgdGhpcy5zdGF0ZSwgeCwgeSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUZXh0RWRpdGluZyA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgICBzaG91bGRCaW5kLFxuICAgIGluc2VydEF0UGFyZW50Q2VudGVyID0gdHJ1ZSxcbiAgfToge1xuICAgIC8qKiBYIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgLyoqIFkgcG9zaXRpb24gdG8gaW5zZXJ0IHRleHQgYXQgKi9cbiAgICBzY2VuZVk6IG51bWJlcjtcbiAgICBzaG91bGRCaW5kOiBib29sZWFuO1xuICAgIC8qKiB3aGV0aGVyIHRvIGF0dGVtcHQgdG8gaW5zZXJ0IGF0IGVsZW1lbnQgY2VudGVyIGlmIGFwcGxpY2FibGUgKi9cbiAgICBpbnNlcnRBdFBhcmVudENlbnRlcj86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICBsZXQgcGFyZW50Q2VudGVyUG9zaXRpb24gPVxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgJiZcbiAgICAgIHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICk7XG5cbiAgICBsZXQgZXhpc3RpbmdUZXh0RWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3VGV4dEVsZW1lbnQ+IHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGNvbnRhaW5lcjogRXhjYWxpZHJhd1RleHRDb250YWluZXIgfCBudWxsID0gbnVsbDtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkpIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG4gICAgICB9IGVsc2UgaWYgKGlzVGV4dEJpbmRhYmxlQ29udGFpbmVyKHNlbGVjdGVkRWxlbWVudHNbMF0sIGZhbHNlKSkge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gZ2V0Qm91bmRUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSB0aGlzLmdldFRleHRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSB0aGlzLmdldFRleHRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG4gICAgfVxuXG4gICAgLy8gYmluZCB0byBjb250YWluZXIgd2hlbiBzaG91bGRCaW5kIGlzIHRydWUgb3JcbiAgICAvLyBjbGlja2VkIG9uIGNlbnRlciBvZiBjb250YWluZXJcbiAgICBpZiAoXG4gICAgICAhY29udGFpbmVyICYmXG4gICAgICAhZXhpc3RpbmdUZXh0RWxlbWVudCAmJlxuICAgICAgKHNob3VsZEJpbmQgfHwgcGFyZW50Q2VudGVyUG9zaXRpb24pXG4gICAgKSB7XG4gICAgICBjb250YWluZXIgPSBnZXRUZXh0QmluZGFibGVDb250YWluZXJBdFBvc2l0aW9uKFxuICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChlbGUpID0+XG4gICAgICAgICAgICAgIGlzVGV4dEJpbmRhYmxlQ29udGFpbmVyKGVsZSwgZmFsc2UpICYmICFnZXRCb3VuZFRleHRFbGVtZW50KGVsZSksXG4gICAgICAgICAgKSxcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghZXhpc3RpbmdUZXh0RWxlbWVudCAmJiBjb250YWluZXIpIHtcbiAgICAgIGNvbnN0IGZvbnRTdHJpbmcgPSB7XG4gICAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1pbldpZHRoID0gZ2V0QXBwcm94TWluTGluZVdpZHRoKGdldEZvbnRTdHJpbmcoZm9udFN0cmluZykpO1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gZ2V0QXBwcm94TWluTGluZUhlaWdodChnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpKTtcbiAgICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KGNvbnRhaW5lci5oZWlnaHQsIG1pbkhlaWdodCk7XG4gICAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KGNvbnRhaW5lci53aWR0aCwgbWluV2lkdGgpO1xuICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBuZXdIZWlnaHQsIHdpZHRoOiBuZXdXaWR0aCB9KTtcbiAgICAgIHNjZW5lWCA9IGNvbnRhaW5lci54ICsgbmV3V2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gY29udGFpbmVyLnkgKyBuZXdIZWlnaHQgLyAyO1xuICAgICAgaWYgKHBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICAgIHBhcmVudENlbnRlclBvc2l0aW9uID0gdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICAgIHNjZW5lWCxcbiAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgPyBleGlzdGluZ1RleHRFbGVtZW50XG4gICAgICA6IG5ld1RleHRFbGVtZW50KHtcbiAgICAgICAgICB4OiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBwYXJlbnRDZW50ZXJQb3NpdGlvbi5lbGVtZW50Q2VudGVyWFxuICAgICAgICAgICAgOiBzY2VuZVgsXG4gICAgICAgICAgeTogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlcllcbiAgICAgICAgICAgIDogc2NlbmVZLFxuICAgICAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgICAgICB0ZXh0OiBcIlwiLFxuICAgICAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICAgICAgdGV4dEFsaWduOiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBcImNlbnRlclwiXG4gICAgICAgICAgICA6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICAgICAgdmVydGljYWxBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gVkVSVElDQUxfQUxJR04uTUlERExFXG4gICAgICAgICAgICA6IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgICAgICAgY29udGFpbmVySWQ6IGNvbnRhaW5lcj8uaWQgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgIGdyb3VwSWRzOiBjb250YWluZXI/Lmdyb3VwSWRzID8/IFtdLFxuICAgICAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdFbGVtZW50OiBlbGVtZW50IH0pO1xuXG4gICAgaWYgKCFleGlzdGluZ1RleHRFbGVtZW50KSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcblxuICAgICAgLy8gY2FzZTogY3JlYXRpbmcgbmV3IHRleHQgbm90IGNlbnRlcmVkIHRvIHBhcmVudCBlbGVtZW50IOKGkiBvZmZzZXQgWVxuICAgICAgLy8gc28gdGhhdCB0aGUgdGV4dCBpcyBjZW50ZXJlZCB0byBjdXJzb3IgcG9zaXRpb25cbiAgICAgIGlmICghcGFyZW50Q2VudGVyUG9zaXRpb24pIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgICAgeTogZWxlbWVudC55IC0gZWxlbWVudC5iYXNlbGluZSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmhhbmRsZVRleHRXeXNpd3lnKGVsZW1lbnQsIHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50OiAhIWV4aXN0aW5nVGV4dEVsZW1lbnQsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNEb3VibGVDbGljayA9IChcbiAgICBldmVudDogUmVhY3QuTW91c2VFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIGNhc2U6IGRvdWJsZS1jbGlja2luZyB3aXRoIGFycm93L2xpbmUgdG9vbCBzZWxlY3RlZCB3b3VsZCBib3RoIGNyZWF0ZVxuICAgIC8vIHRleHQgYW5kIGVudGVyIG11bHRpRWxlbWVudCBtb2RlXG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHdlIHNob3VsZCBvbmx5IGJlIGFibGUgdG8gZG91YmxlIGNsaWNrIHdoZW4gbW9kZSBpcyBzZWxlY3Rpb25cbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICApLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG5cbiAgICBsZXQgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgZXZlbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWRzID0gZ2V0U2VsZWN0ZWRHcm91cElkcyh0aGlzLnN0YXRlKTtcblxuICAgIGlmIChzZWxlY3RlZEdyb3VwSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcblxuICAgICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkID1cbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50KGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cElkcyk7XG5cbiAgICAgIGlmIChzZWxlY3RlZEdyb3VwSWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IHNlbGVjdGVkR3JvdXBJZCxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50IS5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcbiAgICAgICAgY29uc3QgY2FuQmluZFRleHQgPSBoYXNCb3VuZFRleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudCk7XG4gICAgICAgIGlmIChjYW5CaW5kVGV4dCkge1xuICAgICAgICAgIHNjZW5lWCA9IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMjtcbiAgICAgICAgICBzY2VuZVkgPSBzZWxlY3RlZEVsZW1lbnQueSArIHNlbGVjdGVkRWxlbWVudC5oZWlnaHQgLyAyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICAgc2hvdWxkQmluZDogZmFsc2UsXG4gICAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyOiAhZXZlbnQuYWx0S2V5LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uID0gKFxuICAgIHNjZW5lUG9pbnRlcjogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBoaXRFbGVtZW50OiBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsLFxuICApOiBFeGNhbGlkcmF3RWxlbWVudCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgLy8gUmV2ZXJzaW5nIHNvIHdlIHRyYXZlcnNlIHRoZSBlbGVtZW50cyBpbiBkZWNyZWFzaW5nIG9yZGVyXG4gICAgLy8gb2Ygei1pbmRleFxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICBsZXQgaGl0RWxlbWVudEluZGV4ID0gSW5maW5pdHk7XG5cbiAgICByZXR1cm4gZWxlbWVudHMuZmluZCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChoaXRFbGVtZW50ICYmIGVsZW1lbnQuaWQgPT09IGhpdEVsZW1lbnQuaWQpIHtcbiAgICAgICAgaGl0RWxlbWVudEluZGV4ID0gaW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gKFxuICAgICAgICBlbGVtZW50LmxpbmsgJiZcbiAgICAgICAgaW5kZXggPD0gaGl0RWxlbWVudEluZGV4ICYmXG4gICAgICAgIGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXIueCwgc2NlbmVQb2ludGVyLnldLFxuICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVkaXJlY3RUb0xpbmsgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgaXNUb3VjaFNjcmVlbjogYm9vbGVhbixcbiAgKSA9PiB7XG4gICAgY29uc3QgZHJhZ2dlZERpc3RhbmNlID0gZGlzdGFuY2UyZChcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRYLFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFksXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5oaXRMaW5rRWxlbWVudCB8fFxuICAgICAgLy8gRm9yIHRvdWNoIHNjcmVlbiBhbGxvdyBkcmFnZ2luZyB0aHJlc2hvbGQgZWxzZSBzdHJpY3QgY2hlY2tcbiAgICAgIChpc1RvdWNoU2NyZWVuICYmIGRyYWdnZWREaXN0YW5jZSA+IERSQUdHSU5HX1RIUkVTSE9MRCkgfHxcbiAgICAgICghaXNUb3VjaFNjcmVlbiAmJiBkcmFnZ2VkRGlzdGFuY2UgIT09IDApXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxhc3RQb2ludGVyRG93bkNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duISxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlckRvd25IaXR0aW5nTGlua0ljb24gPSBpc1BvaW50SGl0dGluZ0xpbmtJY29uKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICBbbGFzdFBvaW50ZXJEb3duQ29vcmRzLngsIGxhc3RQb2ludGVyRG93bkNvb3Jkcy55XSxcbiAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJVcENvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJVcEhpdHRpbmdMaW5rSWNvbiA9IGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIFtsYXN0UG9pbnRlclVwQ29vcmRzLngsIGxhc3RQb2ludGVyVXBDb29yZHMueV0sXG4gICAgICB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICApO1xuICAgIGlmIChsYXN0UG9pbnRlckRvd25IaXR0aW5nTGlua0ljb24gJiYgbGFzdFBvaW50ZXJVcEhpdHRpbmdMaW5rSWNvbikge1xuICAgICAgY29uc3QgdXJsID0gdGhpcy5oaXRMaW5rRWxlbWVudC5saW5rO1xuICAgICAgaWYgKHVybCkge1xuICAgICAgICBsZXQgY3VzdG9tRXZlbnQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTGlua09wZW4pIHtcbiAgICAgICAgICBjdXN0b21FdmVudCA9IHdyYXBFdmVudChFVkVOVC5FWENBTElEUkFXX0xJTkssIGV2ZW50Lm5hdGl2ZUV2ZW50KTtcbiAgICAgICAgICB0aGlzLnByb3BzLm9uTGlua09wZW4odGhpcy5oaXRMaW5rRWxlbWVudCwgY3VzdG9tRXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY3VzdG9tRXZlbnQ/LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBpc0xvY2FsTGluayh1cmwpID8gXCJfc2VsZlwiIDogXCJfYmxhbmtcIjtcbiAgICAgICAgICBjb25zdCBuZXdXaW5kb3cgPSB3aW5kb3cub3Blbih1bmRlZmluZWQsIHRhcmdldCk7XG4gICAgICAgICAgLy8gaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmdpdGh1Yi5pby9yZWwtbm9vcGVuZXIvXG4gICAgICAgICAgaWYgKG5ld1dpbmRvdykge1xuICAgICAgICAgICAgbmV3V2luZG93Lm9wZW5lciA9IG51bGw7XG4gICAgICAgICAgICBuZXdXaW5kb3cubG9jYXRpb24gPSBub3JtYWxpemVMaW5rKHVybCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgdGhpcy5zdGF0ZS5jdXJzb3JCdXR0b24pO1xuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLmhhcyhldmVudC5wb2ludGVySWQpKSB7XG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMiAmJlxuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyICYmXG4gICAgICBpbml0aWFsU2NhbGUgJiZcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlXG4gICAgKSB7XG4gICAgICBjb25zdCBjZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBjb25zdCBkZWx0YVggPSBjZW50ZXIueCAtIGdlc3R1cmUubGFzdENlbnRlci54O1xuICAgICAgY29uc3QgZGVsdGFZID0gY2VudGVyLnkgLSBnZXN0dXJlLmxhc3RDZW50ZXIueTtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGNlbnRlcjtcblxuICAgICAgY29uc3QgZGlzdGFuY2UgPSBnZXREaXN0YW5jZShBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpKTtcbiAgICAgIGNvbnN0IHNjYWxlRmFjdG9yID1cbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiZnJlZWRyYXdcIiAmJiB0aGlzLnN0YXRlLnBlbk1vZGVcbiAgICAgICAgICA/IDFcbiAgICAgICAgICA6IGRpc3RhbmNlIC8gZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2U7XG5cbiAgICAgIGNvbnN0IG5leHRab29tID0gc2NhbGVGYWN0b3JcbiAgICAgICAgPyBnZXROb3JtYWxpemVkWm9vbShpbml0aWFsU2NhbGUgKiBzY2FsZUZhY3RvcilcbiAgICAgICAgOiB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiB7XG4gICAgICAgIGNvbnN0IHpvb21TdGF0ZSA9IGdldFN0YXRlRm9yWm9vbShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2aWV3cG9ydFg6IGNlbnRlci54LFxuICAgICAgICAgICAgdmlld3BvcnRZOiBjZW50ZXIueSxcbiAgICAgICAgICAgIG5leHRab29tLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB6b29tOiB6b29tU3RhdGUuem9vbSxcbiAgICAgICAgICBzY3JvbGxYOiB6b29tU3RhdGUuc2Nyb2xsWCArIGRlbHRhWCAvIG5leHRab29tLFxuICAgICAgICAgIHNjcm9sbFk6IHpvb21TdGF0ZS5zY3JvbGxZICsgZGVsdGFZIC8gbmV4dFpvb20sXG4gICAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9XG4gICAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPVxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGlzSG9sZGluZ1NwYWNlIHx8IGlzUGFubmluZyB8fCBpc0RyYWdnaW5nU2Nyb2xsQmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMgPSBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICk7XG4gICAgY29uc3QgaXNPdmVyU2Nyb2xsQmFyID0gaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMuaXNPdmVyRWl0aGVyO1xuICAgIGlmICghdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHsgeDogc2NlbmVQb2ludGVyWCwgeTogc2NlbmVQb2ludGVyWSB9ID0gc2NlbmVQb2ludGVyO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICkge1xuICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJNb3ZlKFxuICAgICAgICBldmVudCxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG4gICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgLy8gU2luY2Ugd2UgYXJlIHJlYWRpbmcgZnJvbSBwcmV2aW91cyBzdGF0ZSB3aGljaCBpcyBub3QgcG9zc2libGUgd2l0aFxuICAgICAgICAvLyBhdXRvbWF0aWMgYmF0Y2hpbmcgaW4gUmVhY3QgMTggaGVuY2UgdXNpbmcgZmx1c2ggc3luYyB0byBzeW5jaHJvbm91c2x5XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGUuIENoZWNrIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC81NTA4IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgIGZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdMaW5lYXJFbGVtZW50IH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudC5sYXN0VW5jb21taXR0ZWRQb2ludCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0JpbmRpbmdFbGVtZW50VHlwZSh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSkpIHtcbiAgICAgIC8vIEhvdmVyaW5nIHdpdGggYSBzZWxlY3RlZCB0b29sIG9yIGNyZWF0aW5nIG5ldyBsaW5lYXIgZWxlbWVudCB2aWEgY2xpY2tcbiAgICAgIC8vIGFuZCBwb2ludFxuICAgICAgY29uc3QgeyBkcmFnZ2luZ0VsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIGZhbHNlKSkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBbc2NlbmVQb2ludGVyXSxcbiAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3Ioc2NlbmVQb2ludGVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnkgfSA9IG11bHRpRWxlbWVudDtcblxuICAgICAgY29uc3QgeyBwb2ludHMsIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuICAgICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcblxuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuXG4gICAgICBpZiAobGFzdFBvaW50ID09PSBsYXN0Q29tbWl0dGVkUG9pbnQpIHtcbiAgICAgICAgLy8gaWYgd2UgaGF2ZW4ndCB5ZXQgY3JlYXRlZCBhIHRlbXAgcG9pbnQgYW5kIHdlJ3JlIGJleW9uZCBjb21taXQtem9uZVxuICAgICAgICAvLyB0aHJlc2hvbGQsIGFkZCBhIHBvaW50XG4gICAgICAgIGlmIChcbiAgICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyWCAtIHJ4LFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyWSAtIHJ5LFxuICAgICAgICAgICAgbGFzdFBvaW50WzBdLFxuICAgICAgICAgICAgbGFzdFBvaW50WzFdLFxuICAgICAgICAgICkgPj0gTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbc2NlbmVQb2ludGVyWCAtIHJ4LCBzY2VuZVBvaW50ZXJZIC0gcnldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICAgIC8vIGluIHRoaXMgYnJhbmNoLCB3ZSdyZSBpbnNpZGUgdGhlIGNvbW1pdCB6b25lLCBhbmQgbm8gdW5jb21taXR0ZWRcbiAgICAgICAgICAvLyBwb2ludCBleGlzdHMuIFRodXMgZG8gbm90aGluZyAoZG9uJ3QgYWRkL3JlbW92ZSBwb2ludHMpLlxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBwb2ludHMubGVuZ3RoID4gMiAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IHBvaW50cy5zbGljZSgwLCAtMSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgW2xhc3RDb21taXR0ZWRYLCBsYXN0Q29tbWl0dGVkWV0gPVxuICAgICAgICAgIG11bHRpRWxlbWVudD8ubGFzdENvbW1pdHRlZFBvaW50ID8/IFswLCAwXTtcblxuICAgICAgICBsZXQgZHhGcm9tTGFzdENvbW1pdHRlZCA9IGdyaWRYIC0gcnggLSBsYXN0Q29tbWl0dGVkWDtcbiAgICAgICAgbGV0IGR5RnJvbUxhc3RDb21taXR0ZWQgPSBncmlkWSAtIHJ5IC0gbGFzdENvbW1pdHRlZFk7XG5cbiAgICAgICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSkge1xuICAgICAgICAgICh7IHdpZHRoOiBkeEZyb21MYXN0Q29tbWl0dGVkLCBoZWlnaHQ6IGR5RnJvbUxhc3RDb21taXR0ZWQgfSA9XG4gICAgICAgICAgICBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUoXG4gICAgICAgICAgICAgIC8vIGFjdHVhbCBjb29yZGluYXRlIG9mIHRoZSBsYXN0IGNvbW1pdHRlZCBwb2ludFxuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWCArIHJ4LFxuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWSArIHJ5LFxuICAgICAgICAgICAgICAvLyBjdXJzb3ItZ3JpZCBjb29yZGluYXRlXG4gICAgICAgICAgICAgIGdyaWRYLFxuICAgICAgICAgICAgICBncmlkWSxcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzUGF0aEFMb29wKHBvaW50cywgdGhpcy5zdGF0ZS56b29tLnZhbHVlKSkge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdXBkYXRlIGxhc3QgdW5jb21taXR0ZWQgcG9pbnRcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgIC4uLnBvaW50cy5zbGljZSgwLCAtMSksXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRYICsgZHhGcm9tTGFzdENvbW1pdHRlZCxcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFkgKyBkeUZyb21MYXN0Q29tbWl0dGVkLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhc0Rlc2VsZWN0ZWRCdXR0b24gPSBCb29sZWFuKGV2ZW50LmJ1dHRvbnMpO1xuICAgIGlmIChcbiAgICAgIGhhc0Rlc2VsZWN0ZWRCdXR0b24gfHxcbiAgICAgICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJ0ZXh0XCIgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiZXJhc2VyXCIpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgIGlmIChcbiAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAhaXNPdmVyU2Nyb2xsQmFyICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudFxuICAgICkge1xuICAgICAgY29uc3QgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAoXG4gICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSAmJlxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAxICYmICFpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybUhhbmRsZVR5cGUgPSBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyhcbiAgICAgICAgZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpLFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgKTtcbiAgICAgIGlmICh0cmFuc2Zvcm1IYW5kbGVUeXBlKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoe1xuICAgICAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICApO1xuICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRMaW5rQXRQb3NpdGlvbihcbiAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgIGhpdEVsZW1lbnQsXG4gICAgKTtcbiAgICBpZiAoaXNFcmFzZXJBY3RpdmUodGhpcy5zdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW3RoaXMuaGl0TGlua0VsZW1lbnQuaWRdXG4gICAgKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgc2hvd0h5cGVybGlua1Rvb2x0aXAodGhpcy5oaXRMaW5rRWxlbWVudCwgdGhpcy5zdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZGVIeXBlcmxpbmtUb29saXAoKTtcbiAgICAgIGlmIChcbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBoaXRFbGVtZW50LmxpbmsgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0gJiZcbiAgICAgICAgIXRoaXMuY29udGV4dE1lbnVPcGVuICYmXG4gICAgICAgICF0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IFwiaW5mb1wiIH0pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGlzVGV4dEVsZW1lbnQoaGl0RWxlbWVudCkgPyBDVVJTT1JfVFlQRS5URVhUIDogQ1VSU09SX1RZUEUuQ1JPU1NIQUlSLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgfSBlbHNlIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVIb3ZlclNlbGVjdGVkTGluZWFyRWxlbWVudChcbiAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAvLyBpZiB1c2luZyBjbWQvY3RybCwgd2UncmUgbm90IGRyYWdnaW5nXG4gICAgICAgICFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJlxuICAgICAgICAoaGl0RWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICkpICYmXG4gICAgICAgICFoaXRFbGVtZW50Py5sb2NrZWRcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVFcmFzZXIgPSAoXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIHNjZW5lUG9pbnRlcjogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LFxuICApID0+IHtcbiAgICBjb25zdCB1cGRhdGVFbGVtZW50SWRzID0gKGVsZW1lbnRzOiBFeGNhbGlkcmF3RWxlbWVudFtdKSA9PiB7XG4gICAgICBlbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChlbGVtZW50LmxvY2tlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlkc1RvVXBkYXRlLnB1c2goZWxlbWVudC5pZCk7XG4gICAgICAgIGlmIChldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdLmVyYXNlXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdLmVyYXNlID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXSA9IHtcbiAgICAgICAgICAgIGVyYXNlOiB0cnVlLFxuICAgICAgICAgICAgb3BhY2l0eTogZWxlbWVudC5vcGFjaXR5LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBjb25zdCBpZHNUb1VwZGF0ZTogQXJyYXk8c3RyaW5nPiA9IFtdO1xuXG4gICAgY29uc3QgZGlzdGFuY2UgPSBkaXN0YW5jZTJkKFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSxcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSAxMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICBjb25zdCBwb2ludCA9IHsgLi4ucG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzIH07XG4gICAgbGV0IHNhbXBsaW5nSW50ZXJ2YWwgPSAwO1xuICAgIHdoaWxlIChzYW1wbGluZ0ludGVydmFsIDw9IGRpc3RhbmNlKSB7XG4gICAgICBjb25zdCBoaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKHBvaW50LngsIHBvaW50LnkpO1xuICAgICAgdXBkYXRlRWxlbWVudElkcyhoaXRFbGVtZW50cyk7XG5cbiAgICAgIC8vIEV4aXQgc2luY2Ugd2UgcmVhY2hlZCBjdXJyZW50IHBvaW50XG4gICAgICBpZiAoc2FtcGxpbmdJbnRlcnZhbCA9PT0gZGlzdGFuY2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBuZXh0IHBvaW50IGluIHRoZSBsaW5lIGF0IGEgZGlzdGFuY2Ugb2Ygc2FtcGxpbmcgaW50ZXJ2YWxcbiAgICAgIHNhbXBsaW5nSW50ZXJ2YWwgPSBNYXRoLm1pbihzYW1wbGluZ0ludGVydmFsICsgdGhyZXNob2xkLCBkaXN0YW5jZSk7XG5cbiAgICAgIGNvbnN0IGRpc3RhbmNlUmF0aW8gPSBzYW1wbGluZ0ludGVydmFsIC8gZGlzdGFuY2U7XG4gICAgICBjb25zdCBuZXh0WCA9XG4gICAgICAgICgxIC0gZGlzdGFuY2VSYXRpbykgKiBwb2ludC54ICsgZGlzdGFuY2VSYXRpbyAqIHNjZW5lUG9pbnRlci54O1xuICAgICAgY29uc3QgbmV4dFkgPVxuICAgICAgICAoMSAtIGRpc3RhbmNlUmF0aW8pICogcG9pbnQueSArIGRpc3RhbmNlUmF0aW8gKiBzY2VuZVBvaW50ZXIueTtcbiAgICAgIHBvaW50LnggPSBuZXh0WDtcbiAgICAgIHBvaW50LnkgPSBuZXh0WTtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGNvbnN0IGlkID1cbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiYgaWRzVG9VcGRhdGUuaW5jbHVkZXMoZWxlLmNvbnRhaW5lcklkKVxuICAgICAgICAgID8gZWxlLmNvbnRhaW5lcklkXG4gICAgICAgICAgOiBlbGUuaWQ7XG4gICAgICBpZiAoaWRzVG9VcGRhdGUuaW5jbHVkZXMoaWQpKSB7XG4gICAgICAgIGlmIChldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2lkXSAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtpZF0uZXJhc2UgPT09IGZhbHNlXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgICAgIG9wYWNpdHk6IHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaWRdLm9wYWNpdHksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgICAgb3BhY2l0eTogRUxFTUVOVF9SRUFEWV9UT19FUkFTRV9PUEFDSVRZLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuXG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBzY2VuZVBvaW50ZXIueDtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHNjZW5lUG9pbnRlci55O1xuICB9O1xuICAvLyBzZXQgdG91Y2ggbW92aW5nIGZvciBtb2JpbGUgY29udGV4dCBtZW51XG4gIHByaXZhdGUgaGFuZGxlVG91Y2hNb3ZlID0gKGV2ZW50OiBSZWFjdC5Ub3VjaEV2ZW50PEhUTUxDYW52YXNFbGVtZW50PikgPT4ge1xuICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IHRydWU7XG4gIH07XG5cbiAgaGFuZGxlSG92ZXJTZWxlY3RlZExpbmVhckVsZW1lbnQoXG4gICAgbGluZWFyRWxlbWVudEVkaXRvcjogTGluZWFyRWxlbWVudEVkaXRvcixcbiAgICBzY2VuZVBvaW50ZXJYOiBudW1iZXIsXG4gICAgc2NlbmVQb2ludGVyWTogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KFxuICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5lbGVtZW50SWQsXG4gICAgKTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgIGxldCBob3ZlclBvaW50SW5kZXggPSAtMTtcbiAgICAgIGlmIChcbiAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goZWxlbWVudCwgdGhpcy5zdGF0ZSwgW1xuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgXSlcbiAgICAgICkge1xuICAgICAgICBob3ZlclBvaW50SW5kZXggPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50SW5kZXhVbmRlckN1cnNvcihcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICk7XG4gICAgICAgIGlmIChob3ZlclBvaW50SW5kZXggPj0gMCkge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmhvdmVyUG9pbnRJbmRleCAhPT0gaG92ZXJQb2ludEluZGV4XG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIGhvdmVyUG9pbnRJbmRleCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gcmVtb3ZlIGFueSBhY3RpdmUgc2VsZWN0aW9uIHdoZW4gd2Ugc3RhcnQgdG8gaW50ZXJhY3Qgd2l0aCBjYW52YXNcbiAgICAvLyAobWFpbmx5LCB3ZSBjYXJlIGFib3V0IHJlbW92aW5nIHNlbGVjdGlvbiBvdXRzaWRlIHRoZSBjb21wb25lbnQgd2hpY2hcbiAgICAvLyAgd291bGQgcHJldmVudCBvdXIgY29weSBoYW5kbGluZyBvdGhlcndpc2UpXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKHNlbGVjdGlvbj8uYW5jaG9yTm9kZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIH1cbiAgICB0aGlzLm1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzKGV2ZW50KTtcbiAgICB0aGlzLm1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChldmVudCk7XG5cbiAgICAvL2ZpcmVzIG9ubHkgb25jZSwgaWYgcGVuIGlzIGRldGVjdGVkLCBwZW5Nb2RlIGlzIGVuYWJsZWRcbiAgICAvL3RoZSB1c2VyIGNhbiBkaXNhYmxlIHRoaXMgYnkgdG9nZ2xpbmcgdGhlIHBlbk1vZGUgYnV0dG9uXG4gICAgaWYgKCF0aGlzLnN0YXRlLnBlbkRldGVjdGVkICYmIGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInBlblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwZW5Nb2RlOiB0cnVlLFxuICAgICAgICAgIHBlbkRldGVjdGVkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgIXRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4gJiZcbiAgICAgIFtcInBlblwiLCBcInRvdWNoXCJdLmluY2x1ZGVzKGV2ZW50LnBvaW50ZXJUeXBlKVxuICAgICkge1xuICAgICAgdGhpcy5kZXZpY2UgPSB1cGRhdGVPYmplY3QodGhpcy5kZXZpY2UsIHsgaXNUb3VjaFNjcmVlbjogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAoaXNQYW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0UG9pbnRlckRvd24gPSBldmVudDtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGxhc3RQb2ludGVyRG93bldpdGg6IGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgY3Vyc29yQnV0dG9uOiBcImRvd25cIixcbiAgICB9KTtcbiAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwiZG93blwiKTtcblxuICAgIHRoaXMudXBkYXRlR2VzdHVyZU9uUG9pbnRlckRvd24oZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlQ2FudmFzUGFuVXNpbmdXaGVlbE9yU3BhY2VEcmFnKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG9ubHkgaGFuZGxlIGxlZnQgbW91c2UgYnV0dG9uIG9yIHRvdWNoXG4gICAgaWYgKFxuICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmXG4gICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLlRPVUNIXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZG9uJ3Qgc2VsZWN0IHdoaWxlIHBhbm5pbmdcbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5zaXplID4gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFN0YXRlIGZvciB0aGUgZHVyYXRpb24gb2YgYSBwb2ludGVyIGludGVyYWN0aW9uLCB3aGljaCBzdGFydHMgd2l0aCBhXG4gICAgLy8gcG9pbnRlckRvd24gZXZlbnQsIGVuZHMgd2l0aCBhIHBvaW50ZXJVcCBldmVudCAob3IgYW5vdGhlciBwb2ludGVyRG93bilcbiAgICBjb25zdCBwb2ludGVyRG93blN0YXRlID0gdGhpcy5pbml0aWFsUG9pbnRlckRvd25TdGF0ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVEcmFnZ2luZ1Njcm9sbEJhcihldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTaW5jZSBjb250ZXh0IG1lbnUgY2xvc2VzIG9uIHBvaW50ZXIgZG93biBzbyBzZXR0aW5nIHRvIGZhbHNlXG4gICAgdGhpcy5jb250ZXh0TWVudU9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmNsZWFyU2VsZWN0aW9uSWZOb3RVc2luZ1NlbGVjdGlvbigpO1xuICAgIHRoaXMudXBkYXRlQmluZGluZ0VuYWJsZWRPblBvaW50ZXJNb3ZlKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZVNlbGVjdGlvbk9uUG9pbnRlckRvd24oZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYWxsb3dPblBvaW50ZXJEb3duID1cbiAgICAgICF0aGlzLnN0YXRlLnBlbk1vZGUgfHxcbiAgICAgIGV2ZW50LnBvaW50ZXJUeXBlICE9PSBcInRvdWNoXCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJ0ZXh0XCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCI7XG5cbiAgICBpZiAoIWFsbG93T25Qb2ludGVyRG93bikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlVGV4dE9uUG9pbnRlckRvd24oZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJhcnJvd1wiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJsaW5lXCJcbiAgICApIHtcbiAgICAgIHRoaXMuaGFuZGxlTGluZWFyRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIGV2ZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICAvLyByZXNldCBpbWFnZSBwcmV2aWV3IG9uIHBvaW50ZXJkb3duXG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkNST1NTSEFJUik7XG5cbiAgICAgIC8vIHJldHJpZXZlIHRoZSBsYXRlc3QgZWxlbWVudCBhcyB0aGUgc3RhdGUgbWF5IGJlIHN0YWxlXG4gICAgICBjb25zdCBwZW5kaW5nSW1hZ2VFbGVtZW50ID1cbiAgICAgICAgdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQgJiZcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50KHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkKTtcblxuICAgICAgaWYgKCFwZW5kaW5nSW1hZ2VFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogcGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IHBlbmRpbmdJbWFnZUVsZW1lbnQsXG4gICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogbnVsbCxcbiAgICAgICAgbXVsdGlFbGVtZW50OiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQocGVuZGluZ0ltYWdlRWxlbWVudCwge1xuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICB0aGlzLmhhbmRsZUZyZWVEcmF3RWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIGV2ZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcImVyYXNlclwiKSB7XG4gICAgICB0aGlzLmNyZWF0ZUdlbmVyaWNFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMucHJvcHM/Lm9uUG9pbnRlckRvd24/Lih0aGlzLnN0YXRlLmFjdGl2ZVRvb2wsIHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9XG4gICAgICB0aGlzLm9uUG9pbnRlck1vdmVGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyVXAgPVxuICAgICAgdGhpcy5vblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvbktleURvd24gPSB0aGlzLm9uS2V5RG93bkZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgY29uc3Qgb25LZXlVcCA9IHRoaXMub25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBsYXN0UG9pbnRlclVwID0gb25Qb2ludGVyVXA7XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgb25LZXlEb3duKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCBvbktleVVwKTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlID0gb25Qb2ludGVyTW92ZTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCA9IG9uUG9pbnRlclVwO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleVVwID0gb25LZXlVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duID0gb25LZXlEb3duO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJVcCA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgdGhpcy5sYXN0UG9pbnRlclVwID0gZXZlbnQ7XG4gICAgaWYgKHRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4pIHtcbiAgICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgeyBjbGllbnRYOiBldmVudC5jbGllbnRYLCBjbGllbnRZOiBldmVudC5jbGllbnRZIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICAgICk7XG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50TGlua0F0UG9zaXRpb24oXG4gICAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLmhpdExpbmtFbGVtZW50LmlkXVxuICAgICkge1xuICAgICAgdGhpcy5yZWRpcmVjdFRvTGluayhldmVudCwgdGhpcy5kZXZpY2UuaXNUb3VjaFNjcmVlbik7XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmVQb2ludGVyKGV2ZW50KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBkZWFsIHdpdGggb3BlbmluZyBjb250ZXh0IG1lbnUgb24gdG91Y2ggZGV2aWNlc1xuICAgIGlmIChldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiKSB7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcblxuICAgICAgaWYgKHRvdWNoVGltZW91dCkge1xuICAgICAgICAvLyBJZiB0aGVyZSdzIGFscmVhZHkgYSB0b3VjaFRpbWVvdXQsIHRoaXMgbWVhbnMgdGhhdCB0aGVyZSdzIGFub3RoZXJcbiAgICAgICAgLy8gdG91Y2ggZG93biBhbmQgd2UgYXJlIGRvaW5nIGFub3RoZXIgdG91Y2gsIHNvIHdlIHNob3VsZG4ndCBvcGVuIHRoZVxuICAgICAgICAvLyBjb250ZXh0IG1lbnUuXG4gICAgICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvcGVuIHRoZSBjb250ZXh0IG1lbnUgd2l0aCB0aGUgZmlyc3QgdG91Y2gncyBjbGllbnRYIGFuZCBjbGllbnRZXG4gICAgICAgIC8vIGlmIHRoZSB0b3VjaCBpcyBub3QgbW92aW5nXG4gICAgICAgIHRvdWNoVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgICAgICAgIGlmICghaW52YWxpZGF0ZUNvbnRleHRNZW51KSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51KGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIFRPVUNIX0NUWF9NRU5VX1RJTUVPVVQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHJlc2V0Q29udGV4dE1lbnVUaW1lciA9ICgpID0+IHtcbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVDbGVhbnVwQWZ0ZXJNaXNzaW5nUG9pbnRlclVwKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBpZiAobGFzdFBvaW50ZXJVcCAhPT0gbnVsbCkge1xuICAgICAgLy8gVW5mb3J0dW5hdGVseSwgc29tZXRpbWVzIHdlIGRvbid0IGdldCBhIHBvaW50ZXJ1cCBhZnRlciBhIHBvaW50ZXJkb3duLFxuICAgICAgLy8gdGhpcyBjYW4gaGFwcGVuIHdoZW4gYSBjb250ZXh0dWFsIG1lbnUgb3IgYWxlcnQgaXMgdHJpZ2dlcmVkLiBJbiBvcmRlciB0byBhdm9pZFxuICAgICAgLy8gYmVpbmcgaW4gYSB3ZWlyZCBzdGF0ZSwgd2UgY2xlYW4gdXAgb24gdGhlIG5leHQgcG9pbnRlcmRvd25cbiAgICAgIGxhc3RQb2ludGVyVXAoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBwYW5uaW5nXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUGFuVXNpbmdXaGVlbE9yU3BhY2VEcmFnID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAoXG4gICAgICAhKFxuICAgICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPD0gMSAmJlxuICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5XSEVFTCB8fFxuICAgICAgICAgIChldmVudC5idXR0b24gPT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiYgaXNIb2xkaW5nU3BhY2UpIHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpXG4gICAgICApIHx8XG4gICAgICBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlzUGFubmluZyA9IHRydWU7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGxldCBuZXh0UGFzdGVQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICBjb25zdCBpc0xpbnV4ID0gL0xpbnV4Ly50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm0pO1xuXG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCQklORyk7XG4gICAgbGV0IHsgY2xpZW50WDogbGFzdFgsIGNsaWVudFk6IGxhc3RZIH0gPSBldmVudDtcbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID0gd2l0aEJhdGNoZWRVcGRhdGVzVGhyb3R0bGVkKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBkZWx0YVggPSBsYXN0WCAtIGV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBkZWx0YVkgPSBsYXN0WSAtIGV2ZW50LmNsaWVudFk7XG4gICAgICBsYXN0WCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBsYXN0WSA9IGV2ZW50LmNsaWVudFk7XG5cbiAgICAgIC8qXG4gICAgICAgKiBQcmV2ZW50IHBhc3RlIGV2ZW50IGlmIHdlIG1vdmUgd2hpbGUgbWlkZGxlIGNsaWNraW5nIG9uIExpbnV4LlxuICAgICAgICogU2VlIGlzc3VlICMxMzgzLlxuICAgICAgICovXG4gICAgICBpZiAoXG4gICAgICAgIGlzTGludXggJiZcbiAgICAgICAgIW5leHRQYXN0ZVByZXZlbnRlZCAmJlxuICAgICAgICAoTWF0aC5hYnMoZGVsdGFYKSA+IDEgfHwgTWF0aC5hYnMoZGVsdGFZKSA+IDEpXG4gICAgICApIHtcbiAgICAgICAgbmV4dFBhc3RlUHJldmVudGVkID0gdHJ1ZTtcblxuICAgICAgICAvKiBQcmV2ZW50IHRoZSBuZXh0IHBhc3RlIGV2ZW50ICovXG4gICAgICAgIGNvbnN0IHByZXZlbnROZXh0UGFzdGUgPSAoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKlxuICAgICAgICAgKiBSZWVuYWJsZSBuZXh0IHBhc3RlIGluIGNhc2Ugb2YgZGlzYWJsZWQgbWlkZGxlIGNsaWNrIHBhc3RlIGZvclxuICAgICAgICAgKiBhbnkgcmVhc29uOlxuICAgICAgICAgKiAtIHJpZ2h0IGNsaWNrIHBhc3RlXG4gICAgICAgICAqIC0gZW1wdHkgY2xpcGJvYXJkXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBlbmFibGVOZXh0UGFzdGUgPSAoKSA9PiB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgZW5hYmxlTmV4dFBhc3RlKTtcbiAgICAgICAgICB9LCAxMDApO1xuICAgICAgICB9O1xuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIGVuYWJsZU5leHRQYXN0ZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFggLSBkZWx0YVggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGRlbHRhWSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNvbnN0IHRlYXJkb3duID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgICAgKGxhc3RQb2ludGVyVXAgPSAoKSA9PiB7XG4gICAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuICAgICAgICBpc1Bhbm5pbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKCFpc0hvbGRpbmdTcGFjZSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGVhcmRvd24pO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0ZWFyZG93bik7XG4gICAgICAgIG9uUG9pbnRlck1vdmUuZmx1c2goKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSwge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVHZXN0dXJlT25Qb2ludGVyRG93bihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICB9KTtcblxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIpIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPSBnZXREaXN0YW5jZShcbiAgICAgICAgQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsUG9pbnRlckRvd25TdGF0ZShcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogUG9pbnRlckRvd25TdGF0ZSB7XG4gICAgY29uc3Qgb3JpZ2luID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9yaWdpbixcbiAgICAgIHdpdGhDbWRPckN0cmw6IGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdLFxuICAgICAgb3JpZ2luSW5HcmlkOiB0dXBsZVRvQ29vcnMoXG4gICAgICAgIGdldEdyaWRQb2ludChvcmlnaW4ueCwgb3JpZ2luLnksIHRoaXMuc3RhdGUuZ3JpZFNpemUpLFxuICAgICAgKSxcbiAgICAgIHNjcm9sbGJhcnM6IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICAgIGN1cnJlbnRTY3JvbGxCYXJzLFxuICAgICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgICApLFxuICAgICAgLy8gd2UgbmVlZCB0byBkdXBsaWNhdGUgYmVjYXVzZSB3ZSdsbCBiZSB1cGRhdGluZyB0aGlzIHN0YXRlXG4gICAgICBsYXN0Q29vcmRzOiB7IC4uLm9yaWdpbiB9LFxuICAgICAgb3JpZ2luYWxFbGVtZW50czogdGhpcy5zY2VuZVxuICAgICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgLnJlZHVjZSgoYWNjLCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgYWNjLnNldChlbGVtZW50LmlkLCBkZWVwQ29weUVsZW1lbnQoZWxlbWVudCkpO1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIG5ldyBNYXAoKSBhcyBQb2ludGVyRG93blN0YXRlW1wib3JpZ2luYWxFbGVtZW50c1wiXSksXG4gICAgICByZXNpemU6IHtcbiAgICAgICAgaGFuZGxlVHlwZTogZmFsc2UsXG4gICAgICAgIGlzUmVzaXppbmc6IGZhbHNlLFxuICAgICAgICBvZmZzZXQ6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICBhcnJvd0RpcmVjdGlvbjogXCJvcmlnaW5cIixcbiAgICAgICAgY2VudGVyOiB7IHg6IChtYXhYICsgbWluWCkgLyAyLCB5OiAobWF4WSArIG1pblkpIC8gMiB9LFxuICAgICAgfSxcbiAgICAgIGhpdDoge1xuICAgICAgICBlbGVtZW50OiBudWxsLFxuICAgICAgICBhbGxIaXRFbGVtZW50czogW10sXG4gICAgICAgIHdhc0FkZGVkVG9TZWxlY3Rpb246IGZhbHNlLFxuICAgICAgICBoYXNCZWVuRHVwbGljYXRlZDogZmFsc2UsXG4gICAgICAgIGhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzOlxuICAgICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICksXG4gICAgICAgIGhhc0hpdEVsZW1lbnRJbnNpZGU6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGRyYWc6IHtcbiAgICAgICAgaGFzT2NjdXJyZWQ6IGZhbHNlLFxuICAgICAgICBvZmZzZXQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZXZlbnRMaXN0ZW5lcnM6IHtcbiAgICAgICAgb25Nb3ZlOiBudWxsLFxuICAgICAgICBvblVwOiBudWxsLFxuICAgICAgICBvbktleVVwOiBudWxsLFxuICAgICAgICBvbktleURvd246IG51bGwsXG4gICAgICB9LFxuICAgICAgYm94U2VsZWN0aW9uOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBlbGVtZW50SWRzVG9FcmFzZToge30sXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBkcmFnZ2luZyBhIHNjcm9sbGJhclxuICBwcml2YXRlIGhhbmRsZURyYWdnaW5nU2Nyb2xsQmFyKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChcbiAgICAgICEocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3ZlckVpdGhlciAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgPSB0cnVlO1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gZXZlbnQuY2xpZW50WDtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IGV2ZW50LmNsaWVudFk7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5oYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgPSBmYWxzZTtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwidXBcIik7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgICAgb25Qb2ludGVyTW92ZS5mbHVzaCgpO1xuICAgIH0pO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2VsZWN0aW9uSWZOb3RVc2luZ1NlbGVjdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgZXZlbnQgaGFzIGJlZW4gY29tcGxldGVseSBoYW5kbGVkXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZVNlbGVjdGlvbk9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSk7XG4gICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlID1cbiAgICAgICAgICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUoXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgcmVzaXppbmdFbGVtZW50OiBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUuZWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlID1cbiAgICAgICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS50cmFuc2Zvcm1IYW5kbGVUeXBlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgICAgZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpLFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGU6IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmlzUmVzaXppbmcgPSB0cnVlO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQgPSB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgZ2V0UmVzaXplT2Zmc2V0WFkoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgIGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSAmJlxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0ucG9pbnRzLmxlbmd0aCA9PT0gMlxuICAgICAgICApIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbiA9IGdldFJlc2l6ZUFycm93RGlyZWN0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgbGluZWFyRWxlbWVudEVkaXRvciA9XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50O1xuICAgICAgICAgIGNvbnN0IHJldCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlckRvd24oXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAocmV0LmhpdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPSByZXQuaGl0RWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJldC5saW5lYXJFbGVtZW50RWRpdG9yKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiByZXQubGluZWFyRWxlbWVudEVkaXRvciB9KTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdMaW5lYXJFbGVtZW50OiByZXQubGluZWFyRWxlbWVudEVkaXRvciB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJldC5kaWRBZGRQb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGhpdEVsZW1lbnQgbWF5IGFscmVhZHkgYmUgc2V0IGFib3ZlLCBzbyBjaGVjayBmaXJzdFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID8/XG4gICAgICAgICAgdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQpIHtcbiAgICAgICAgICAvLyBFYXJseSByZXR1cm4gaWYgcG9pbnRlciBpcyBoaXR0aW5nIGxpbmsgaWNvblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55XSxcbiAgICAgICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUgPVxuICAgICAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goXG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55XSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3Igb3ZlcmxhcHBlZCBlbGVtZW50cyBvbmUgcG9zaXRpb24gbWF5IGhpdFxuICAgICAgICAvLyBtdWx0aXBsZSBlbGVtZW50c1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgY29uc3Qgc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PlxuICAgICAgICAgICAgdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChoaXRFbGVtZW50ID09PSBudWxsIHx8ICFzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQpICYmXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIElmIHdlIGNsaWNrIG9uIHNvbWV0aGluZ1xuICAgICAgICB9IGVsc2UgaWYgKGhpdEVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgIC8vIG9uIENNRC9DVFJMLCBkcmlsbCBkb3duIHRvIGhpdCBlbGVtZW50IHJlZ2FyZGxlc3Mgb2YgZ3JvdXBzIGV0Yy5cbiAgICAgICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIC4uLmVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudChwcmV2U3RhdGUsIGhpdEVsZW1lbnQpLFxuICAgICAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAvLyBtYXJrIGFzIG5vdCBjb21wbGV0ZWx5IGhhbmRsZWQgc28gYXMgdG8gYWxsb3cgZHJhZ2dpbmcgZXRjLlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlc2VsZWN0IGlmIGl0ZW0gaXMgc2VsZWN0ZWRcbiAgICAgICAgICAvLyBpZiBzaGlmdCBpcyBub3QgY2xpY2tlZCwgdGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZVxuICAgICAgICAgIC8vIG90aGVyd2lzZSwgaXQgd2lsbCB0cmlnZ2VyIHNlbGVjdGlvbiBiYXNlZCBvbiBjdXJyZW50XG4gICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGJveFxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBjdXJyZW50bHkgZWRpdGluZyBhIGdyb3VwLCBleGl0aW5nIGVkaXRpbmcgbW9kZSBhbmQgZGVzZWxlY3QgdGhlIGdyb3VwLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgICAgICAgICFpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBoaXQgZWxlbWVudCB0byBzZWxlY3Rpb24uIEF0IHRoaXMgcG9pbnQgaWYgd2UncmUgbm90IGhvbGRpbmdcbiAgICAgICAgICAgIC8vIFNISUZUIHRoZSBwcmV2aW91c2x5IHNlbGVjdGVkIGVsZW1lbnQocykgd2VyZSBkZXNlbGVjdGVkIGFib3ZlXG4gICAgICAgICAgICAvLyAobWFrZSBzdXJlIHlvdSB1c2Ugc2V0U3RhdGUgdXBkYXRlciB0byB1c2UgbGF0ZXN0IHN0YXRlKVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkICYmXG4gICAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6IGhpdEVsZW1lbnQubGluayA/IFwiaW5mb1wiIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgaXNBU2VsZWN0ZWRFbGVtZW50KGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBoaXRFbGVtZW50ICE9IG51bGwgJiYgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF07XG4gIH1cblxuICBwcml2YXRlIGlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgIHBvaW50OiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIb3cgbWFueSBwaXhlbHMgb2ZmIHRoZSBzaGFwZSBib3VuZGFyeSB3ZSBzdGlsbCBjb25zaWRlciBhIGhpdFxuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvaW50LnggPiB4MSAtIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueCA8IHgyICsgdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55ID4geTEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnkgPCB5MiArIHRocmVzaG9sZFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRleHRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGlmIHdlJ3JlIGN1cnJlbnRseSBzdGlsbCBlZGl0aW5nIHRleHQsIGNsaWNraW5nIG91dHNpZGVcbiAgICAvLyBzaG91bGQgb25seSBmaW5hbGl6ZSBpdCwgbm90IGNyZWF0ZSBhbm90aGVyIChpcnJlc3BlY3RpdmVcbiAgICAvLyBvZiBzdGF0ZS5hY3RpdmVUb29sLmxvY2tlZClcbiAgICBpZiAoaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgc2NlbmVYID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueDtcbiAgICBsZXQgc2NlbmVZID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZLCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNhbkJpbmRUZXh0ID0gaGFzQm91bmRUZXh0RWxlbWVudChlbGVtZW50KTtcbiAgICBpZiAoY2FuQmluZFRleHQpIHtcbiAgICAgIHNjZW5lWCA9IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgLyAyO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgc2NlbmVYLFxuICAgICAgc2NlbmVZLFxuICAgICAgc2hvdWxkQmluZDogZmFsc2UsXG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICB9KTtcblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICBpZiAoIXRoaXMuc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUZyZWVEcmF3RWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkgPT4ge1xuICAgIC8vIEJlZ2luIGEgbWFyayBjYXB0dXJlLiBUaGlzIGRvZXMgbm90IGhhdmUgdG8gdXBkYXRlIHN0YXRlIHlldC5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgbnVsbCxcbiAgICApO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ZyZWVEcmF3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHNpbXVsYXRlUHJlc3N1cmU6IGV2ZW50LnByZXNzdXJlID09PSAwLjUsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIGNvbnN0IHByZXNzdXJlcyA9IGVsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgPyBlbGVtZW50LnByZXNzdXJlc1xuICAgICAgOiBbLi4uZWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgcG9pbnRzOiBbWzAsIDBdXSxcbiAgICAgIHByZXNzdXJlcyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlSW1hZ2VFbGVtZW50ID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICB9OiB7XG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgc2NlbmVZOiBudW1iZXI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChzY2VuZVgsIHNjZW5lWSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3SW1hZ2VFbGVtZW50KHtcbiAgICAgIHR5cGU6IFwiaW1hZ2VcIixcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3TGluZWFyRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgLy8gZmluYWxpemUgaWYgY29tcGxldGluZyBhIGxvb3BcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnR5cGUgPT09IFwibGluZVwiICYmXG4gICAgICAgIGlzUGF0aEFMb29wKG11bHRpRWxlbWVudC5wb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSlcbiAgICAgICkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDpcbiAgICAgICAgICAgIG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSwgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIC8vIGNsaWNraW5nIGluc2lkZSBjb21taXQgem9uZSDihpIgZmluYWxpemUgYXJyb3dcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggPiAxICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSByeCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFttdWx0aUVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgLy8gY2xpY2tpbmcgb3V0c2lkZSBjb21taXQgem9uZSDihpIgdXBkYXRlIHJlZmVyZW5jZSBmb3IgbGFzdCBjb21taXR0ZWRcbiAgICAgIC8vIHBvaW50XG4gICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgIH0pO1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvKiBJZiBhcnJvdyBpcyBwcmUtYXJyb3doZWFkcywgaXQgd2lsbCBoYXZlIHVuZGVmaW5lZCBmb3IgYm90aCBzdGFydCBhbmQgZW5kIGFycm93aGVhZHMuXG4gICAgICBJZiBzbywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBzdGFydCBhbmQgXCJhcnJvd1wiIGZvciBlbmQuIElmIHRoZSBsaW5lYXIgaXRlbSBpcyBub3RcbiAgICAgIGFuIGFycm93LCB3ZSB3YW50IGl0IHRvIGJlIG51bGwgZm9yIGJvdGguIE90aGVyd2lzZSwgd2Ugd2FudCBpdCB0byB1c2UgdGhlXG4gICAgICB2YWx1ZXMgZnJvbSBhcHBTdGF0ZS4gKi9cblxuICAgICAgY29uc3QgeyBjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IFtzdGFydEFycm93aGVhZCwgZW5kQXJyb3doZWFkXSA9XG4gICAgICAgIGVsZW1lbnRUeXBlID09PSBcImFycm93XCJcbiAgICAgICAgICA/IFtjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZF1cbiAgICAgICAgICA6IFtudWxsLCBudWxsXTtcblxuICAgICAgY29uc3QgZWxlbWVudCA9IG5ld0xpbmVhckVsZW1lbnQoe1xuICAgICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgICAgeDogZ3JpZFgsXG4gICAgICAgIHk6IGdyaWRZLFxuICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtTGluZWFyU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgICBzdGFydEFycm93aGVhZCxcbiAgICAgICAgZW5kQXJyb3doZWFkLFxuICAgICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgW2VsZW1lbnQuaWRdOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICBwb2ludHM6IFsuLi5lbGVtZW50LnBvaW50cywgWzAsIDBdXSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYm91bmRFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICk7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBjcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdHZW5lcmljRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgKTtcbiAgICBjb25zdCBlbGVtZW50ID0gbmV3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICBpZiAoZWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uS2V5RG93bkZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvbktleVVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBQcmV2ZW50cyBmb2N1cyBmcm9tIGVzY2FwaW5nIGV4Y2FsaWRyYXcgdGFiXG4gICAgICBldmVudC5rZXkgPT09IEtFWVMuQUxUICYmIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlck1vdmVGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gaW5pdGlhbGl6ZSBkcmFnT2Zmc2V0WFkgb25seSBhZnRlciB3ZSd2ZSB1cGRhdGVkXG4gICAgICAvLyBgc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzYCBvbiBwb2ludGVyRG93bi4gRG9pbmcgaXQgaGVyZSBpbiBwb2ludGVyTW92ZVxuICAgICAgLy8gZXZlbnQgaGFuZGxlciBzaG91bGQgaG9wZWZ1bGx5IGVuc3VyZSB3ZSdyZSBhbHJlYWR5IHdvcmtpbmcgd2l0aFxuICAgICAgLy8gdGhlIHVwZGF0ZWQgc3RhdGUuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9PT0gbnVsbCkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldERyYWdPZmZzZXRYWShcbiAgICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHModGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcblxuICAgICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlRXJhc2VyKGV2ZW50LCBwb2ludGVyRG93blN0YXRlLCBwb2ludGVyQ29vcmRzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvLyBmb3IgYXJyb3dzL2xpbmVzLCBkb24ndCBzdGFydCBkcmFnZ2luZyB1bnRpbCBhIGdpdmVuIHRocmVzaG9sZFxuICAgICAgLy8gdG8gZW5zdXJlIHdlIGRvbid0IGNyZWF0ZSBhIDItcG9pbnQgYXJyb3cgYnkgbWlzdGFrZSB3aGVuXG4gICAgICAvLyB1c2VyIGNsaWNrcyBtb3VzZSBpbiBhIHdheSB0aGF0IGl0IG1vdmVzIGEgdGlueSBiaXQgKHRodXNcbiAgICAgIC8vIHRyaWdnZXJpbmcgcG9pbnRlcm1vdmUpXG4gICAgICBpZiAoXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImFycm93XCIgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJsaW5lXCIpXG4gICAgICApIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApIDwgRFJBR0dJTkdfVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZykge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBsaW5lYXJFbGVtZW50RWRpdG9yID1cbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50O1xuICAgICAgICBjb25zdCBkaWREcmFnID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludERyYWdnaW5nKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICAoZWxlbWVudCwgcG9pbnRzU2NlbmVDb29yZHMpID0+IHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgIHBvaW50c1NjZW5lQ29vcmRzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChkaWREcmFnKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0hpdEFTZWxlY3RlZEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKFxuICAgICAgICAoZWxlbWVudCkgPT4gdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICApO1xuXG4gICAgICBpZiAoXG4gICAgICAgIChoYXNIaXRBU2VsZWN0ZWRFbGVtZW50IHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpICYmXG4gICAgICAgIC8vIHRoaXMgYWxsb3dzIGZvciBib3gtc2VsZWN0aW5nIHBvaW50cyB3aGVuIGNsaWNraW5nIGluc2lkZSB0aGVcbiAgICAgICAgLy8gbGluZSdzIGJvdW5kaW5nIGJveFxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHwgIWV2ZW50LnNoaWZ0S2V5KSAmJlxuICAgICAgICAvLyBib3gtc2VsZWN0aW5nIHdpdGhvdXQgc2hpZnQgd2hlbiBlZGl0aW5nIGxpbmUsIG5vdCBjbGlja2luZyBvbiBhIGxpbmVcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudD8uZWxlbWVudElkICE9PVxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudD8uaWQgfHxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlKSAmJlxuICAgICAgICAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT1cbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ/LmlkIHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0RWxlbWVudEluc2lkZSlcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmV2ZXJ5KChlbGVtZW50KSA9PiBlbGVtZW50LmxvY2tlZCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gTWFya2luZyB0aGF0IGNsaWNrIHdhcyB1c2VkIGZvciBkcmFnZ2luZyB0byBjaGVja1xuICAgICAgICAvLyBpZiBlbGVtZW50cyBzaG91bGQgYmUgZGVzZWxlY3RlZCBvbiBwb2ludGVydXBcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgLy8gcHJldmVudCBkcmFnZ2luZyBldmVuIGlmIHdlJ3JlIG5vIGxvbmdlciBob2xkaW5nIGNtZC9jdHJsIG90aGVyd2lzZVxuICAgICAgICAvLyBpdCB3b3VsZCBoYXZlIHdlaXJkIHJlc3VsdHMgKHN0dWZmIGp1bXBpbmcgYWxsIG92ZXIgdGhlIHNjcmVlbilcbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMCAmJiAhcG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsKSB7XG4gICAgICAgICAgY29uc3QgW2RyYWdYLCBkcmFnWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBbZHJhZ0Rpc3RhbmNlWCwgZHJhZ0Rpc3RhbmNlWV0gPSBbXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54KSxcbiAgICAgICAgICAgIE1hdGguYWJzKHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkpLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICAvLyBXZSBvbmx5IGRyYWcgaW4gb25lIGRpcmVjdGlvbiBpZiBzaGlmdCBpcyBwcmVzc2VkXG4gICAgICAgICAgY29uc3QgbG9ja0RpcmVjdGlvbiA9IGV2ZW50LnNoaWZ0S2V5O1xuICAgICAgICAgIGRyYWdTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgICBkcmFnWCxcbiAgICAgICAgICAgIGRyYWdZLFxuICAgICAgICAgICAgbG9ja0RpcmVjdGlvbixcbiAgICAgICAgICAgIGRyYWdEaXN0YW5jZVgsXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2VZLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgICAgICAgIC8vIFdlIGR1cGxpY2F0ZSB0aGUgc2VsZWN0ZWQgZWxlbWVudCBpZiBhbHQgaXMgcHJlc3NlZCBvbiBwb2ludGVyIG1vdmVcbiAgICAgICAgICBpZiAoZXZlbnQuYWx0S2V5ICYmICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCkge1xuICAgICAgICAgICAgLy8gTW92ZSB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGVsZW1lbnRzIHRvIHRoZSB0b3Agb2YgdGhlIHogaW5kZXggc3RhY2ssIGFuZFxuICAgICAgICAgICAgLy8gcHV0IHRoZSBkdXBsaWNhdGVzIHdoZXJlIHRoZSBzZWxlY3RlZCBlbGVtZW50cyB1c2VkIHRvIGJlLlxuICAgICAgICAgICAgLy8gKHRoZSBvcmlnaW4gcG9pbnQgd2hlcmUgdGhlIGRyYWdnaW5nIHN0YXJ0ZWQpXG5cbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0JlZW5EdXBsaWNhdGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgbmV4dEVsZW1lbnRzID0gW107XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50c1RvQXBwZW5kID0gW107XG4gICAgICAgICAgICBjb25zdCBncm91cElkTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3Qgb2xkSWRUb0R1cGxpY2F0ZWRJZCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50O1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpO1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50SWRzOiBBcnJheTxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdPiA9XG4gICAgICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUsIHRydWUpLm1hcChcbiAgICAgICAgICAgICAgICAoZWxlbWVudCkgPT4gZWxlbWVudC5pZCxcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKSB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHMuaW5jbHVkZXMoZWxlbWVudC5pZCkgfHxcbiAgICAgICAgICAgICAgICAvLyBjYXNlOiB0aGUgc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzIG1pZ2h0IG5vdCBoYXZlIGJlZW5cbiAgICAgICAgICAgICAgICAvLyB1cGRhdGVkIHlldCBieSB0aGUgdGltZSB0aGlzIG1vdXNlbW92ZSBldmVudCBpcyBmaXJlZFxuICAgICAgICAgICAgICAgIChlbGVtZW50LmlkID09PSBoaXRFbGVtZW50Py5pZCAmJlxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbilcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZHVwbGljYXRlZEVsZW1lbnQgPSBkdXBsaWNhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCxcbiAgICAgICAgICAgICAgICAgIGdyb3VwSWRNYXAsXG4gICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc3QgW29yaWdpbkRyYWdYLCBvcmlnaW5EcmFnWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC54LFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBtdXRhdGVFbGVtZW50KGR1cGxpY2F0ZWRFbGVtZW50LCB7XG4gICAgICAgICAgICAgICAgICB4OiBkdXBsaWNhdGVkRWxlbWVudC54ICsgKG9yaWdpbkRyYWdYIC0gZHJhZ1gpLFxuICAgICAgICAgICAgICAgICAgeTogZHVwbGljYXRlZEVsZW1lbnQueSArIChvcmlnaW5EcmFnWSAtIGRyYWdZKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBuZXh0RWxlbWVudHMucHVzaChkdXBsaWNhdGVkRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZC5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQuc2V0KGVsZW1lbnQuaWQsIGR1cGxpY2F0ZWRFbGVtZW50LmlkKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXh0RWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmV4dFNjZW5lRWxlbWVudHMgPSBbLi4ubmV4dEVsZW1lbnRzLCAuLi5lbGVtZW50c1RvQXBwZW5kXTtcbiAgICAgICAgICAgIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24oXG4gICAgICAgICAgICAgIG5leHRFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24oXG4gICAgICAgICAgICAgIG5leHRTY2VuZUVsZW1lbnRzLFxuICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLFxuICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLFxuICAgICAgICAgICAgICBcImR1cGxpY2F0ZXNTZXJ2ZUFzT2xkXCIsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMobmV4dFNjZW5lRWxlbWVudHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSXQgaXMgdmVyeSBpbXBvcnRhbnQgdG8gcmVhZCB0aGlzLnN0YXRlIHdpdGhpbiBlYWNoIG1vdmUgZXZlbnQsXG4gICAgICAvLyBvdGhlcndpc2Ugd2Ugd291bGQgcmVhZCBhIHN0YWxlIG9uZSFcbiAgICAgIGNvbnN0IGRyYWdnaW5nRWxlbWVudCA9IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgaWYgKCFkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50LnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBjb25zdCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBjb25zdCBkeSA9IHBvaW50ZXJDb29yZHMueSAtIGRyYWdnaW5nRWxlbWVudC55O1xuXG4gICAgICAgIGNvbnN0IGxhc3RQb2ludCA9IHBvaW50cy5sZW5ndGggPiAwICYmIHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGNvbnN0IGRpc2NhcmRQb2ludCA9XG4gICAgICAgICAgbGFzdFBvaW50ICYmIGxhc3RQb2ludFswXSA9PT0gZHggJiYgbGFzdFBvaW50WzFdID09PSBkeTtcblxuICAgICAgICBpZiAoIWRpc2NhcmRQb2ludCkge1xuICAgICAgICAgIGNvbnN0IHByZXNzdXJlcyA9IGRyYWdnaW5nRWxlbWVudC5zaW11bGF0ZVByZXNzdXJlXG4gICAgICAgICAgICA/IGRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXNcbiAgICAgICAgICAgIDogWy4uLmRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpc0xpbmVhckVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBsZXQgZHggPSBncmlkWCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBncmlkWSAtIGRyYWdnaW5nRWxlbWVudC55O1xuXG4gICAgICAgIGlmIChzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCkgJiYgcG9pbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICh7IHdpZHRoOiBkeCwgaGVpZ2h0OiBkeSB9ID0gZ2V0TG9ja2VkTGluZWFyQ3Vyc29yQWxpZ25TaXplKFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LngsXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQueSxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb2ludHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHsgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0gfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSwgW2R4LCBkeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCBmYWxzZSkpIHtcbiAgICAgICAgICAvLyBXaGVuIGNyZWF0aW5nIGEgbGluZWFyIGVsZW1lbnQgYnkgZHJhZ2dpbmdcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgW3BvaW50ZXJDb29yZHNdLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zdGFydEJvdW5kRWxlbWVudCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQgPSB0cnVlO1xuXG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgIC8vIGFsbG93cyBmb3IgYm94LXNlbGVjdGluZyBwb2ludHMgKHdpdGhvdXQgc2hpZnQpXG4gICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQoZWxlbWVudHMsIHRoaXMuc3RhdGUpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLndpdGhDbWRPckN0cmwgJiYgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGJveC1zZWxlY3QgbGluZSBlZGl0b3IgcG9pbnRzXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVCb3hTZWxlY3Rpb24oXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlLmJpbmQodGhpcyksXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyByZWd1bGFyIGJveC1zZWxlY3RcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50c1dpdGhpblNlbGVjdGlvbiA9IGdldEVsZW1lbnRzV2l0aGluU2VsZWN0aW9uKFxuICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLnJlZHVjZShcbiAgICAgICAgICAgICAgICAgICAgKGFjYzogUmVjb3JkPEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0sIHRydWU+LCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgYWNjW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAuLi4ocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHVzaW5nIGN0cmwvY21kLCBzZWxlY3QgdGhlIGhpdEVsZW1lbnQgb25seSBpZiB3ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGF2ZW4ndCBib3gtc2VsZWN0ZWQgYW55dGhpbmcgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQuaWRdOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAhZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgOiBudWxsKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNob3dIeXBlcmxpbmtQb3B1cDpcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb25bMF0ubGlua1xuICAgICAgICAgICAgICAgICAgICA/IFwiaW5mb1wiXG4gICAgICAgICAgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgLy8gc2VsZWN0IGxpbmVhciBlbGVtZW50IG9ubHkgd2hlbiB3ZSBoYXZlbid0IGJveC1zZWxlY3RlZCBhbnl0aGluZyBlbHNlXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OlxuICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoZWxlbWVudHNXaXRoaW5TZWxlY3Rpb25bMF0pXG4gICAgICAgICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgcG9pbnRlciBtb3ZlIGhhcHBlbmVkIG92ZXIgZWl0aGVyIHNjcm9sbGJhclxuICBwcml2YXRlIGhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3Zlckhvcml6b250YWwpIHtcbiAgICAgIGNvbnN0IHggPSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZHggPSB4IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLng7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZHggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0geDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyVmVydGljYWwpIHtcbiAgICAgIGNvbnN0IHkgPSBldmVudC5jbGllbnRZO1xuICAgICAgY29uc3QgZHkgPSB5IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZHkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0geTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoY2hpbGRFdmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgcmVzaXppbmdFbGVtZW50LFxuICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgIGFjdGl2ZVRvb2wsXG4gICAgICAgIGlzUmVzaXppbmcsXG4gICAgICAgIGlzUm90YXRpbmcsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgaXNSb3RhdGluZzogZmFsc2UsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogbnVsbCxcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIC8vIHRleHQgZWxlbWVudHMgYXJlIHJlc2V0IG9uIGZpbmFsaXplLCBhbmQgcmVzZXR0aW5nIG9uIHBvaW50ZXJ1cFxuICAgICAgICAvLyBtYXkgY2F1c2UgaXNzdWVzIHdpdGggZG91YmxlIHRhcHNcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgbXVsdGlFbGVtZW50IHx8IGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgICAgID8gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudFxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoY2hpbGRFdmVudC5jbGllbnRYLCBjaGlsZEV2ZW50LmNsaWVudFksIFwidXBcIik7XG5cbiAgICAgIC8vIEhhbmRsZSBlbmQgb2YgZHJhZ2dpbmcgYSBwb2ludCBvZiBhIGxpbmVhciBlbGVtZW50LCBtaWdodCBjbG9zZSBhIGxvb3BcbiAgICAgIC8vIGFuZCBzZXRzIGJpbmRpbmcgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCB8fFxuICAgICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlclVwKFxuICAgICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50ICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgKHBvaW50ZXJEb3duU3RhdGUuaGl0Py5lbGVtZW50Py5pZCAhPT1cbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCB8fFxuICAgICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUpXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRUxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IHRvIG51bGwgaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBlbGVtZW50IHNlbGVjdGVkIHNpbmNlIHdlIGRvbid0IHdhbnQgdG8gc2hvdyBsaW5lYXIgZWxlbWVudCBoYW5kbGVzXG4gICAgICAgICAgaWYgKHNlbGVjdGVkRUxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkTGluZWFyRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbGluZWFyRWxlbWVudEVkaXRvciA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlclVwKFxuICAgICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgeyBzdGFydEJpbmRpbmdFbGVtZW50LCBlbmRCaW5kaW5nRWxlbWVudCB9ID1cbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3I7XG4gICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudChsaW5lYXJFbGVtZW50RWRpdG9yLmVsZW1lbnRJZCk7XG4gICAgICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIGJpbmRPclVuYmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgIHN0YXJ0QmluZGluZ0VsZW1lbnQsXG4gICAgICAgICAgICAgIGVuZEJpbmRpbmdFbGVtZW50LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobGluZWFyRWxlbWVudEVkaXRvciAhPT0gdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAuLi5saW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogbnVsbCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUuZmx1c2goKTtcbiAgICAgIH1cblxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfTU9WRSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5QT0lOVEVSX1VQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5LRVlET1dOLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWVVQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAhLFxuICAgICAgKTtcblxuICAgICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQ/LnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBsZXQgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgLy8gQWxsb3dzIGRvdHMgdG8gYXZvaWQgYmVpbmcgZmxhZ2dlZCBhcyBpbmZpbml0ZWx5IHNtYWxsXG4gICAgICAgIGlmIChkeCA9PT0gcG9pbnRzWzBdWzBdICYmIGR5ID09PSBwb2ludHNbMF1bMV0pIHtcbiAgICAgICAgICBkeSArPSAwLjAwMDE7XG4gICAgICAgICAgZHggKz0gMC4wMDAxO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJlc3N1cmVzID0gZHJhZ2dpbmdFbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiBbLi4uZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlcywgY2hpbGRFdmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBbZHgsIGR5XSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc0ltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IGRyYWdnaW5nRWxlbWVudDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgICAgeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiBlbC5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0xpbmVhckVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50IS5wb2ludHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgICAgICFtdWx0aUVsZW1lbnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgICAuLi5kcmFnZ2luZ0VsZW1lbnQucG9pbnRzLFxuICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50LngsXG4gICAgICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50LnksXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbXVsdGlFbGVtZW50OiBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBlZGl0aW5nRWxlbWVudDogdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmICFtdWx0aUVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpICYmXG4gICAgICAgICAgICBpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBtYXliZUJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLCBzdGFydEJvdW5kRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgICBpZiAoIWFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFtkcmFnZ2luZ0VsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgICBpc0ludmlzaWJseVNtYWxsRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgLy8gcmVtb3ZlIGludmlzaWJsZSBlbGVtZW50IHdoaWNoIHdhcyBhZGRlZCBpbiBvblBvaW50ZXJEb3duXG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuc2xpY2UoMCwgLTEpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZERpbWVuc2lvbnMoZHJhZ2dpbmdFbGVtZW50KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNpemluZ0VsZW1lbnQgJiYgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQocmVzaXppbmdFbGVtZW50KSkge1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiBlbC5pZCAhPT0gcmVzaXppbmdFbGVtZW50LmlkKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29kZSBiZWxvdyBoYW5kbGVzIHNlbGVjdGlvbiB3aGVuIGVsZW1lbnQocykgd2VyZW4ndFxuICAgICAgLy8gZHJhZyBvciBhZGRlZCB0byBzZWxlY3Rpb24gb24gcG9pbnRlciBkb3duIHBoYXNlLlxuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5lbGVtZW50SWQgIT09IGhpdEVsZW1lbnQ/LmlkICYmXG4gICAgICAgIGlzTGluZWFyRWxlbWVudChoaXRFbGVtZW50KVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRUxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCB3aGVuIG5vIG90aGVyIGVsZW1lbnQgc2VsZWN0ZWQgZXhjZXB0XG4gICAgICAgIC8vIHRoZSBvbmUgd2UndmUgaGl0XG4gICAgICAgIGlmIChzZWxlY3RlZEVMZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgICBjb25zdCBkcmFnZ2VkRGlzdGFuY2UgPSBkaXN0YW5jZTJkKFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRYLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRZLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WCxcbiAgICAgICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRyYWdnZWREaXN0YW5jZSA9PT0gMCkge1xuICAgICAgICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2xpZW50WDogdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRYLFxuICAgICAgICAgICAgICBjbGllbnRZOiB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IGhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICAgICAgICk7XG4gICAgICAgICAgaGl0RWxlbWVudHMuZm9yRWFjaChcbiAgICAgICAgICAgIChoaXRFbGVtZW50KSA9PlxuICAgICAgICAgICAgICAocG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtoaXRFbGVtZW50LmlkXSA9IHtcbiAgICAgICAgICAgICAgICBlcmFzZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBoaXRFbGVtZW50Lm9wYWNpdHksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lcmFzZUVsZW1lbnRzKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKE9iamVjdC5rZXlzKHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2UpLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnJlc3RvcmVSZWFkeVRvRXJhc2VFbGVtZW50cyhwb2ludGVyRG93blN0YXRlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gJiZcbiAgICAgICAgLy8gaWYgd2UncmUgZWRpdGluZyBhIGxpbmUsIHBvaW50ZXJ1cCBzaG91bGRuJ3Qgc3dpdGNoIHNlbGVjdGlvbiBpZlxuICAgICAgICAvLyBib3ggc2VsZWN0ZWRcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkKVxuICAgICAgKSB7XG4gICAgICAgIC8vIHdoZW4gaW5zaWRlIGxpbmUgZWRpdG9yLCBzaGlmdCBzZWxlY3RzIHBvaW50cyBpbnN0ZWFkXG4gICAgICAgIGlmIChjaGlsZEV2ZW50LnNoaWZ0S2V5ICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICBpZiAoaXNTZWxlY3RlZFZpYUdyb3VwKHRoaXMuc3RhdGUsIGhpdEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8gdW5zZWxlY3QgYWxsIGdyb3VwcyBoaXRFbGVtZW50IGlzIHBhcnQgb2ZcbiAgICAgICAgICAgICAgLy8gYXMgd2VsbCBhcyBhbGwgZWxlbWVudHMgdGhhdCBhcmUgcGFydCBvZiB0aGUgZ3JvdXBzXG4gICAgICAgICAgICAgIC8vIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICBjb25zdCBpZHNPZlNlbGVjdGVkRWxlbWVudHNUaGF0QXJlSW5Hcm91cHMgPSBoaXRFbGVtZW50Lmdyb3VwSWRzXG4gICAgICAgICAgICAgICAgLmZsYXRNYXAoKGdyb3VwSWQpID0+XG4gICAgICAgICAgICAgICAgICBnZXRFbGVtZW50c0luR3JvdXAoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwSWQsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAubWFwKChlbGVtZW50KSA9PiAoeyBbZWxlbWVudC5pZF06IGZhbHNlIH0pKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXZJZCwgYWNjKSA9PiAoeyAuLi5wcmV2SWQsIC4uLmFjYyB9KSwge30pO1xuXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKF9wcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge1xuICAgICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5oaXRFbGVtZW50Lmdyb3VwSWRzXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGdJZCkgPT4gKHsgW2dJZF06IGZhbHNlIH0pKVxuICAgICAgICAgICAgICAgICAgICAucmVkdWNlKChwcmV2LCBhY2MpID0+ICh7IC4uLnByZXYsIC4uLmFjYyB9KSwge30pLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgIC8vIGlmIG5vdCBncmFnZ2luZyBhIGxpbmVhciBlbGVtZW50IHBvaW50IChvdXRzaWRlIGVkaXRvcilcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICAgIC8vIHJlbW92ZSBlbGVtZW50IGZyb20gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkRWxlbWVudElkcyA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICAgIHsgLi4ucHJldlN0YXRlLCBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld1NlbGVjdGVkRWxlbWVudElkcyB9LFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCBvbmx5IGlmIHRoYXRzIHRoZSBvbmx5IGVsZW1lbnQgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OlxuICAgICAgICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KG5ld1NlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBwcmV2U3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGFkZCBlbGVtZW50IHRvIHNlbGVjdGlvbiB3aGlsZVxuICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAuLi5zZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoaGl0RWxlbWVudCkgJiZcbiAgICAgICAgICAgICAgICAgIC8vIERvbid0IHNldCBgc2VsZWN0ZWRMaW5lYXJFbGVtZW50YCBpZiBpdHMgc2FtZSBhcyB0aGUgaGl0RWxlbWVudCwgdGhpcyBpcyBtYWlubHkgdG8gcHJldmVudCByZXNldHRpbmcgdGhlIGBob3ZlclBvaW50SW5kZXhgIHRvIC0xLlxuICAgICAgICAgICAgICAgICAgLy8gRnV0dXJlIHdlIHNob3VsZCB1cGRhdGUgdGhlIEFQSSB0byB0YWtlIGNhcmUgb2Ygc2V0dGluZyB0aGUgY29ycmVjdCBgaG92ZXJQb2ludEluZGV4YCB3aGVuIGluaXRpYWxpemVkXG4gICAgICAgICAgICAgICAgICBwcmV2U3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5lbGVtZW50SWQgIT09IGhpdEVsZW1lbnQuaWRcbiAgICAgICAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihoaXRFbGVtZW50LCB0aGlzLnNjZW5lKVxuICAgICAgICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICF0aGlzLnN0YXRlLmlzUmVzaXppbmcgJiZcbiAgICAgICAgKChoaXRFbGVtZW50ICYmXG4gICAgICAgICAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApKSB8fFxuICAgICAgICAgICghaGl0RWxlbWVudCAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpKVxuICAgICAgKSB7XG4gICAgICAgIC8vIERlc2VsZWN0IHNlbGVjdGVkIGVsZW1lbnRzXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhYWN0aXZlVG9vbC5sb2NrZWQgJiZcbiAgICAgICAgYWN0aXZlVG9vbC50eXBlICE9PSBcImZyZWVkcmF3XCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50XG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgIFtkcmFnZ2luZ0VsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgfHxcbiAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkIHx8IGlzUmVzaXppbmcgfHwgaXNSb3RhdGluZykge1xuICAgICAgICAoaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKVxuICAgICAgICAgID8gYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMpKFxuICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHModGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICghYWN0aXZlVG9vbC5sb2NrZWQgJiYgYWN0aXZlVG9vbC50eXBlICE9PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZXN0b3JlUmVhZHlUb0VyYXNlRWxlbWVudHMgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKSA9PiB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgb3BhY2l0eTogcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdLm9wYWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0ub3BhY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICB9O1xuXG4gIHByaXZhdGUgZXJhc2VFbGVtZW50cyA9IChwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlKSA9PiB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7IGlzRGVsZXRlZDogdHJ1ZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGlzQm91bmRUb0NvbnRhaW5lcihlbGUpICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7IGlzRGVsZXRlZDogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICB9O1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUltYWdlID0gYXN5bmMgKHtcbiAgICBpbWFnZUZpbGUsXG4gICAgaW1hZ2VFbGVtZW50OiBfaW1hZ2VFbGVtZW50LFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcgPSBmYWxzZSxcbiAgfToge1xuICAgIGltYWdlRmlsZTogRmlsZTtcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ7XG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICAvLyBhdCB0aGlzIHBvaW50IHRoaXMgc2hvdWxkIGJlIGd1YXJhbnRlZWQgaW1hZ2UgZmlsZSwgYnV0IHdlIGRvIHRoaXMgY2hlY2tcbiAgICAvLyB0byBzYXRpc2Z5IFRTIGRvd24gdGhlIGxpbmVcbiAgICBpZiAoIWlzU3VwcG9ydGVkSW1hZ2VGaWxlKGltYWdlRmlsZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnVuc3VwcG9ydGVkRmlsZVR5cGVcIikpO1xuICAgIH1cbiAgICBjb25zdCBtaW1lVHlwZSA9IGltYWdlRmlsZS50eXBlO1xuXG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBcIndhaXRcIik7XG5cbiAgICBpZiAobWltZVR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBTVkdTdHJpbmdUb0ZpbGUoXG4gICAgICAgICAgYXdhaXQgbm9ybWFsaXplU1ZHKGF3YWl0IGltYWdlRmlsZS50ZXh0KCkpLFxuICAgICAgICAgIGltYWdlRmlsZS5uYW1lLFxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy5zdmdJbWFnZUluc2VydEVycm9yXCIpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBnZW5lcmF0ZSBpbWFnZSBpZCAoYnkgZGVmYXVsdCB0aGUgZmlsZSBkaWdlc3QpIGJlZm9yZSBhbnlcbiAgICAvLyByZXNpemluZy9jb21wcmVzc2lvbiB0YWtlcyBwbGFjZSB0byBrZWVwIGl0IG1vcmUgcG9ydGFibGVcbiAgICBjb25zdCBmaWxlSWQgPSBhd2FpdCAoKHRoaXMucHJvcHMuZ2VuZXJhdGVJZEZvckZpbGU/LihcbiAgICAgIGltYWdlRmlsZSxcbiAgICApIGFzIFByb21pc2U8RmlsZUlkPikgfHwgZ2VuZXJhdGVJZEZyb21GaWxlKGltYWdlRmlsZSkpO1xuXG4gICAgaWYgKCFmaWxlSWQpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJDb3VsZG4ndCBnZW5lcmF0ZSBmaWxlIGlkIG9yIHRoZSBzdXBwbGllZCBgZ2VuZXJhdGVJZEZvckZpbGVgIGRpZG4ndCByZXNvbHZlIHRvIG9uZS5cIixcbiAgICAgICk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZ0ZpbGVEYXRhID0gdGhpcy5maWxlc1tmaWxlSWRdO1xuICAgIGlmICghZXhpc3RpbmdGaWxlRGF0YT8uZGF0YVVSTCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW1hZ2VGaWxlID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IERFRkFVTFRfTUFYX0lNQUdFX1dJRFRIX09SX0hFSUdIVCxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJlcnJvciB0cnlpbmcgdG8gcmVzaW5nIGltYWdlIGZpbGUgb24gaW5zZXJ0aW9uXCIsIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGltYWdlRmlsZS5zaXplID4gTUFYX0FMTE9XRURfRklMRV9CWVRFUykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgdChcImVycm9ycy5maWxlVG9vQmlnXCIsIHtcbiAgICAgICAgICAgIG1heFNpemU6IGAke01hdGgudHJ1bmMoTUFYX0FMTE9XRURfRklMRV9CWVRFUyAvIDEwMjQgLyAxMDI0KX1NQmAsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgIGNvbnN0IGRhdGFVUkwgPSB0aGlzLmZpbGVzW2ZpbGVJZF0/LmRhdGFVUkw7XG4gICAgICAvLyBvcHRpbWl6YXRpb24gc28gdGhhdCB3ZSBkb24ndCB1bm5lY2Vzc2FyaWx5IHJlc2l6ZSB0aGUgb3JpZ2luYWxcbiAgICAgIC8vIGZ1bGwtc2l6ZSBmaWxlIGZvciBjdXJzb3IgcHJldmlld1xuICAgICAgLy8gKGl0J3MgbXVjaCBmYXN0ZXIgdG8gY29udmVydCB0aGUgcmVzaXplZCBkYXRhVVJMIHRvIEZpbGUpXG4gICAgICBjb25zdCByZXNpemVkRmlsZSA9IGRhdGFVUkwgJiYgZGF0YVVSTFRvRmlsZShkYXRhVVJMKTtcblxuICAgICAgdGhpcy5zZXRJbWFnZVByZXZpZXdDdXJzb3IocmVzaXplZEZpbGUgfHwgaW1hZ2VGaWxlKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhVVJMID1cbiAgICAgIHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTCB8fCAoYXdhaXQgZ2V0RGF0YVVSTChpbWFnZUZpbGUpKTtcblxuICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IG11dGF0ZUVsZW1lbnQoXG4gICAgICBfaW1hZ2VFbGVtZW50LFxuICAgICAge1xuICAgICAgICBmaWxlSWQsXG4gICAgICB9LFxuICAgICAgZmFsc2UsXG4gICAgKSBhcyBOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD47XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8Tm9uRGVsZXRlZDxJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ+PihcbiAgICAgIGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmZpbGVzID0ge1xuICAgICAgICAgICAgLi4udGhpcy5maWxlcyxcbiAgICAgICAgICAgIFtmaWxlSWRdOiB7XG4gICAgICAgICAgICAgIG1pbWVUeXBlLFxuICAgICAgICAgICAgICBpZDogZmlsZUlkLFxuICAgICAgICAgICAgICBkYXRhVVJMLFxuICAgICAgICAgICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNhY2hlZEltYWdlRGF0YSA9IHRoaXMuaW1hZ2VDYWNoZS5nZXQoZmlsZUlkKTtcbiAgICAgICAgICBpZiAoIWNhY2hlZEltYWdlRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudXBkYXRlSW1hZ2VDYWNoZShbaW1hZ2VFbGVtZW50XSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjYWNoZWRJbWFnZURhdGE/LmltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgYXdhaXQgY2FjaGVkSW1hZ2VEYXRhLmltYWdlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCAhPT0gaW1hZ2VFbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudD8uaWQgIT09IGltYWdlRWxlbWVudC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgaWYgKCFzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGluc2VydHMgaW1hZ2UgaW50byBlbGVtZW50cyBhcnJheSBhbmQgcmVyZW5kZXJzXG4gICAqL1xuICBwcml2YXRlIGluc2VydEltYWdlRWxlbWVudCA9IGFzeW5jIChcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gICAgaW1hZ2VGaWxlOiBGaWxlLFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuLFxuICApID0+IHtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgaW1hZ2VFbGVtZW50LFxuICAgIF0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZUltYWdlKHtcbiAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICBpc0RlbGV0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfHwgdChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yID0gYXN5bmMgKGltYWdlRmlsZTogRmlsZSkgPT4ge1xuICAgIC8vIG11c3RuJ3QgYmUgbGFyZ2VyIHRoYW4gMTI4IHB4XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NTU19CYXNpY19Vc2VyX0ludGVyZmFjZS9Vc2luZ19VUkxfdmFsdWVzX2Zvcl90aGVfY3Vyc29yX3Byb3BlcnR5XG4gICAgY29uc3QgY3Vyc29ySW1hZ2VTaXplUHggPSA5NjtcblxuICAgIGNvbnN0IGltYWdlUHJldmlldyA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IGN1cnNvckltYWdlU2l6ZVB4LFxuICAgIH0pO1xuXG4gICAgbGV0IHByZXZpZXdEYXRhVVJMID0gYXdhaXQgZ2V0RGF0YVVSTChpbWFnZVByZXZpZXcpO1xuXG4gICAgLy8gU1ZHIGNhbm5vdCBiZSByZXNpemVkIHZpYSBgcmVzaXplSW1hZ2VGaWxlYCBzbyB3ZSByZXNpemUgYnkgcmVuZGVyaW5nIHRvXG4gICAgLy8gYSBzbWFsbCBjYW52YXNcbiAgICBpZiAoaW1hZ2VGaWxlLnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICBjb25zdCBpbWcgPSBhd2FpdCBsb2FkSFRNTEltYWdlRWxlbWVudChwcmV2aWV3RGF0YVVSTCk7XG5cbiAgICAgIGxldCBoZWlnaHQgPSBNYXRoLm1pbihpbWcuaGVpZ2h0LCBjdXJzb3JJbWFnZVNpemVQeCk7XG4gICAgICBsZXQgd2lkdGggPSBoZWlnaHQgKiAoaW1nLndpZHRoIC8gaW1nLmhlaWdodCk7XG5cbiAgICAgIGlmICh3aWR0aCA+IGN1cnNvckltYWdlU2l6ZVB4KSB7XG4gICAgICAgIHdpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgICAgIGhlaWdodCA9IHdpZHRoICogKGltZy5oZWlnaHQgLyBpbWcud2lkdGgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuXG4gICAgICBjb250ZXh0LmRyYXdJbWFnZShpbWcsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICBwcmV2aWV3RGF0YVVSTCA9IGNhbnZhcy50b0RhdGFVUkwoTUlNRV9UWVBFUy5zdmcpIGFzIERhdGFVUkw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pIDQgNCwgYXV0b2ApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uSW1hZ2VBY3Rpb24gPSBhc3luYyAoXG4gICAgeyBpbnNlcnRPbkNhbnZhc0RpcmVjdGx5IH0gPSB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHk6IGZhbHNlIH0sXG4gICkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbGllbnRYID0gdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgICBjb25zdCBjbGllbnRZID0gdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGltYWdlRmlsZSA9IGF3YWl0IGZpbGVPcGVuKHtcbiAgICAgICAgZGVzY3JpcHRpb246IFwiSW1hZ2VcIixcbiAgICAgICAgZXh0ZW5zaW9uczogW1wianBnXCIsIFwicG5nXCIsIFwic3ZnXCIsIFwiZ2lmXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHtcbiAgICAgICAgc2NlbmVYOiB4LFxuICAgICAgICBzY2VuZVk6IHksXG4gICAgICB9KTtcblxuICAgICAgaWYgKGluc2VydE9uQ2FudmFzRGlyZWN0bHkpIHtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBpbWFnZUZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IGltYWdlRWxlbWVudC5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KFxuICAgICAgICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgICAgICAgIGltYWdlRmlsZSxcbiAgICAgICAgICAgICAgLyogc2hvd0N1cnNvckltYWdlUHJldmlldyAqLyB0cnVlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkFib3J0RXJyb3JcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICB9XG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zID0gKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBmb3JjZU5hdHVyYWxTaXplID0gZmFsc2UsXG4gICkgPT4ge1xuICAgIGNvbnN0IGltYWdlID1cbiAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50KSAmJlxuICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChpbWFnZUVsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG5cbiAgICBpZiAoIWltYWdlIHx8IGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgaWYgKFxuICAgICAgICBpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyU2l6ZSA9IDEwMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgICB4OiBpbWFnZUVsZW1lbnQueCAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgeTogaW1hZ2VFbGVtZW50LnkgLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHdpZHRoOiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgICAgaGVpZ2h0OiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgZm9yY2VOYXR1cmFsU2l6ZSB8fFxuICAgICAgLy8gaWYgdXNlci1jcmVhdGVkIGJvdW5kaW5nIGJveCBpcyBiZWxvdyB0aHJlc2hvbGQsIGFzc3VtZSB0aGVcbiAgICAgIC8vIGludGVudGlvbiB3YXMgdG8gY2xpY2sgaW5zdGVhZCBvZiBkcmFnLCBhbmQgdXNlIHRoZSBpbWFnZSdzXG4gICAgICAvLyBpbnRyaW5zaWMgc2l6ZVxuICAgICAgKGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICkge1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5oZWlnaHQgLSAxMjAsIDE2MCk7XG4gICAgICAvLyBtYXggNjUlIG9mIGNhbnZhcyBoZWlnaHQsIGNsYW1wZWQgdG8gPDMwMHB4LCB2aCAtIDEyMHB4PlxuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gTWF0aC5taW4oXG4gICAgICAgIG1pbkhlaWdodCxcbiAgICAgICAgTWF0aC5mbG9vcih0aGlzLnN0YXRlLmhlaWdodCAqIDAuNSkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1pbihpbWFnZS5uYXR1cmFsSGVpZ2h0LCBtYXhIZWlnaHQpO1xuICAgICAgY29uc3Qgd2lkdGggPSBoZWlnaHQgKiAoaW1hZ2UubmF0dXJhbFdpZHRoIC8gaW1hZ2UubmF0dXJhbEhlaWdodCk7XG5cbiAgICAgIC8vIGFkZCBjdXJyZW50IGltYWdlRWxlbWVudCB3aWR0aC9oZWlnaHQgdG8gYWNjb3VudCBmb3IgcHJldmlvdXMgY2VudGVyaW5nXG4gICAgICAvLyBvZiB0aGUgcGxhY2Vob2xkZXIgaW1hZ2VcbiAgICAgIGNvbnN0IHggPSBpbWFnZUVsZW1lbnQueCArIGltYWdlRWxlbWVudC53aWR0aCAvIDIgLSB3aWR0aCAvIDI7XG4gICAgICBjb25zdCB5ID0gaW1hZ2VFbGVtZW50LnkgKyBpbWFnZUVsZW1lbnQuaGVpZ2h0IC8gMiAtIGhlaWdodCAvIDI7XG5cbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7IHgsIHksIHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiB1cGRhdGVzIGltYWdlIGNhY2hlLCByZWZyZXNoaW5nIHVwZGF0ZWQgZWxlbWVudHMgYW5kL29yIHNldHRpbmcgc3RhdHVzXG4gICAgICB0byBlcnJvciBmb3IgaW1hZ2VzIHRoYXQgZmFpbCBkdXJpbmcgPGltZz4gZWxlbWVudCBjcmVhdGlvbiAqL1xuICBwcml2YXRlIHVwZGF0ZUltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdLFxuICAgIGZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgeyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9ID0gYXdhaXQgX3VwZGF0ZUltYWdlQ2FjaGUoe1xuICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgZmlsZUlkczogZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiBlbGVtZW50LmZpbGVJZCksXG4gICAgICBmaWxlcyxcbiAgICB9KTtcbiAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUgfHwgZXJyb3JlZEZpbGVzLnNpemUpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICBpZiAodXBkYXRlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZCkpIHtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgICAgZXJyb3JlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGVtZW50LCB7XG4gICAgICAgICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdXBkYXRlZEZpbGVzLCBlcnJvcmVkRmlsZXMgfTtcbiAgfTtcblxuICAvKiogYWRkcyBuZXcgaW1hZ2VzIHRvIGltYWdlQ2FjaGUgYW5kIHJlLXJlbmRlcnMgaWYgbmVlZGVkICovXG4gIHByaXZhdGUgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudHM6IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdID0gZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICApLFxuICAgIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHRoaXMuZmlsZXMsXG4gICkgPT4ge1xuICAgIGNvbnN0IHVuY2FjaGVkSW1hZ2VFbGVtZW50cyA9IGltYWdlRWxlbWVudHMuZmlsdGVyKFxuICAgICAgKGVsZW1lbnQpID0+ICFlbGVtZW50LmlzRGVsZXRlZCAmJiAhdGhpcy5pbWFnZUNhY2hlLmhhcyhlbGVtZW50LmZpbGVJZCksXG4gICAgKTtcblxuICAgIGlmICh1bmNhY2hlZEltYWdlRWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcyB9ID0gYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFxuICAgICAgICB1bmNhY2hlZEltYWdlRWxlbWVudHMsXG4gICAgICAgIGZpbGVzLFxuICAgICAgKTtcbiAgICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSkge1xuICAgICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKiBnZW5lcmFsbHkgeW91IHNob3VsZCB1c2UgYGFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpYCBkaXJlY3RseSBpZiB5b3UgbmVlZFxuICAgKiAgdG8gcmVuZGVyIG5ldyBpbWFnZXMuIFRoaXMgaXMganVzdCBhIGZhaWxzYWZlICAqL1xuICBwcml2YXRlIHNjaGVkdWxlSW1hZ2VSZWZyZXNoID0gdGhyb3R0bGUoKCkgPT4ge1xuICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gIH0sIElNQUdFX1JFTkRFUl9USU1FT1VUKTtcblxuICBwcml2YXRlIHVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgY29uc3Qgc2hvdWxkRW5hYmxlQmluZGluZyA9IHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQoZXZlbnQpO1xuICAgIGlmICh0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQgIT09IHNob3VsZEVuYWJsZUJpbmRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBzaG91bGRFbmFibGVCaW5kaW5nIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvciA9IChwb2ludGVyQ29vcmRzOiB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgfSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6XG4gICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCA/IFtob3ZlcmVkQmluZGFibGVFbGVtZW50XSA6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMgPSAoXG4gICAgbGluZWFyRWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgLyoqIHNjZW5lIGNvb3JkcyAqL1xuICAgIHBvaW50ZXJDb29yZHM6IHtcbiAgICAgIHg6IG51bWJlcjtcbiAgICAgIHk6IG51bWJlcjtcbiAgICB9W10sXG4gICAgLy8gRHVyaW5nIGxpbmUgY3JlYXRpb24gdGhlIHN0YXJ0IGJpbmRpbmcgaGFzbid0IGJlZW4gd3JpdHRlbiB5ZXRcbiAgICAvLyBpbnRvIGBsaW5lYXJFbGVtZW50YFxuICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD86IEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQgfCBudWxsLFxuICApOiB2b2lkID0+IHtcbiAgICBpZiAoIXBvaW50ZXJDb29yZHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBwb2ludGVyQ29vcmRzLnJlZHVjZShcbiAgICAgIChhY2M6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudD5bXSwgY29vcmRzKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgICAgY29vcmRzLFxuICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgICAhaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kKFxuICAgICAgICAgICAgbGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD8uaWQsXG4gICAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50LFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjLnB1c2goaG92ZXJlZEJpbmRhYmxlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICBbXSxcbiAgICApO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IGdldEVsaWdpYmxlRWxlbWVudHNGb3JCaW5kaW5nKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgLy8gQ29udGludWUgZWRpdGluZyB0aGUgc2FtZSBncm91cCBpZiB0aGUgdXNlciBzZWxlY3RlZCBhIGRpZmZlcmVudFxuICAgICAgLy8gZWxlbWVudCBmcm9tIGl0XG4gICAgICBlZGl0aW5nR3JvdXBJZDpcbiAgICAgICAgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgIGhpdEVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICBpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZClcbiAgICAgICAgICA/IHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZFxuICAgICAgICAgIDogbnVsbCxcbiAgICB9KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNSZWYgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCkgPT4ge1xuICAgIC8vIGNhbnZhcyBpcyBudWxsIHdoZW4gdW5tb3VudGluZ1xuICAgIGlmIChjYW52YXMgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgICAgdGhpcy5yYyA9IHJvdWdoLmNhbnZhcyh0aGlzLmNhbnZhcyk7XG5cbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwsIHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsKTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVBcHBPbkRyb3AgPSBhc3luYyAoZXZlbnQ6IFJlYWN0LkRyYWdFdmVudDxIVE1MRGl2RWxlbWVudD4pID0+IHtcbiAgICAvLyBtdXN0IGJlIHJldHJpZXZlZCBmaXJzdCwgaW4gdGhlIHNhbWUgZnJhbWVcbiAgICBjb25zdCB7IGZpbGUsIGZpbGVIYW5kbGUgfSA9IGF3YWl0IGdldEZpbGVGcm9tRXZlbnQoZXZlbnQpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICAvLyBmaXJzdCBhdHRlbXB0IHRvIGRlY29kZSBzY2VuZSBmcm9tIHRoZSBpbWFnZSBpZiBpdCdzIGVtYmVkZGVkXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGlmIChmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnBuZyB8fCBmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzY2VuZSA9IGF3YWl0IGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAuLi4oc2NlbmUuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJFbmNvZGluZ0Vycm9yXCIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm8gc2NlbmUgaXMgZW1iZWRkZWQgb3Igd2UgZmFpbCBmb3Igd2hhdGV2ZXIgcmVhc29uLCBmYWxsIGJhY2tcbiAgICAgICAgLy8gdG8gaW1wb3J0aW5nIGFzIHJlZ3VsYXIgaW1hZ2VcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBsaWJyYXJ5SlNPTiA9IGV2ZW50LmRhdGFUcmFuc2Zlci5nZXREYXRhKE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYik7XG4gICAgaWYgKGxpYnJhcnlKU09OICYmIHR5cGVvZiBsaWJyYXJ5SlNPTiA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbGlicmFyeUl0ZW1zID0gcGFyc2VMaWJyYXJ5SlNPTihsaWJyYXJ5SlNPTik7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkaXN0cmlidXRlTGlicmFyeUl0ZW1zT25TcXVhcmVHcmlkKGxpYnJhcnlJdGVtcyksXG4gICAgICAgICAgcG9zaXRpb246IGV2ZW50LFxuICAgICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZmlsZSkge1xuICAgICAgLy8gYXRldG1wdCB0byBwYXJzZSBhbiBleGNhbGlkcmF3L2V4Y2FsaWRyYXdsaWIgZmlsZVxuICAgICAgYXdhaXQgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUsIGZpbGVIYW5kbGUpO1xuICAgIH1cbiAgfTtcblxuICBsb2FkRmlsZVRvQ2FudmFzID0gYXN5bmMgKFxuICAgIGZpbGU6IEZpbGUsXG4gICAgZmlsZUhhbmRsZTogRmlsZVN5c3RlbUhhbmRsZSB8IG51bGwsXG4gICkgPT4ge1xuICAgIGZpbGUgPSBhd2FpdCBub3JtYWxpemVGaWxlKGZpbGUpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXQgPSBhd2FpdCBsb2FkU2NlbmVPckxpYnJhcnlGcm9tQmxvYihcbiAgICAgICAgZmlsZSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICk7XG4gICAgICBpZiAocmV0LnR5cGUgPT09IE1JTUVfVFlQRVMuZXhjYWxpZHJhdykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgIC4uLnJldC5kYXRhLFxuICAgICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgICAuLi4ocmV0LmRhdGEuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHJldC50eXBlID09PSBNSU1FX1RZUEVTLmV4Y2FsaWRyYXdsaWIpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5saWJyYXJ5XG4gICAgICAgICAgLnVwZGF0ZUxpYnJhcnkoe1xuICAgICAgICAgICAgbGlicmFyeUl0ZW1zOiBmaWxlLFxuICAgICAgICAgICAgbWVyZ2U6IHRydWUsXG4gICAgICAgICAgICBvcGVuTGlicmFyeU1lbnU6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IHQoXCJlcnJvcnMuaW1wb3J0TGlicmFyeUVycm9yXCIpIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IGZhbHNlLCBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAoXG4gICAgICAoZXZlbnQubmF0aXZlRXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIiB8fFxuICAgICAgICAoZXZlbnQubmF0aXZlRXZlbnQucG9pbnRlclR5cGUgPT09IFwicGVuXCIgJiZcbiAgICAgICAgICAvLyBhbHdheXMgYWxsb3cgaWYgdXNlciB1c2VzIGEgcGVuIHNlY29uZGFyeSBidXR0b25cbiAgICAgICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLlNFQ09OREFSWSkpICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIlxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBwcmVmZXJTZWxlY3RlZDogdHJ1ZSxcbiAgICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50czogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHR5cGUgPSBlbGVtZW50ID8gXCJlbGVtZW50XCIgOiBcImNhbnZhc1wiO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhO1xuICAgIGNvbnN0IHsgdG9wOiBvZmZzZXRUb3AsIGxlZnQ6IG9mZnNldExlZnQgfSA9XG4gICAgICBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgbGVmdCA9IGV2ZW50LmNsaWVudFggLSBvZmZzZXRMZWZ0O1xuICAgIGNvbnN0IHRvcCA9IGV2ZW50LmNsaWVudFkgLSBvZmZzZXRUb3A7XG5cbiAgICBpZiAoZWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbZWxlbWVudC5pZF0pIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbZWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDogaXNMaW5lYXJFbGVtZW50KGVsZW1lbnQpXG4gICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoZWxlbWVudCwgdGhpcy5zY2VuZSlcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgKSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZURyYWdOZXdHZW5lcmljRWxlbWVudCA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBkcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiZXJhc2VyXCJcbiAgICApIHtcbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCwgcG9pbnRlckNvb3Jkcy54KSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSwgcG9pbnRlckNvb3Jkcy55KSxcbiAgICAgICAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2UgPVxuICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkgJiZcbiAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChkcmFnZ2luZ0VsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG4gICAgICBjb25zdCBhc3BlY3RSYXRpbyA9XG4gICAgICAgIGltYWdlICYmICEoaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICAgID8gaW1hZ2Uud2lkdGggLyBpbWFnZS5oZWlnaHRcbiAgICAgICAgICA6IG51bGw7XG5cbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LFxuICAgICAgICBncmlkWCxcbiAgICAgICAgZ3JpZFksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsIGdyaWRYKSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueSwgZ3JpZFkpLFxuICAgICAgICBpc0ltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICAgICAgPyAhc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudClcbiAgICAgICAgICA6IHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgYXNwZWN0UmF0aW8sXG4gICAgICApO1xuXG4gICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoW2RyYWdnaW5nRWxlbWVudF0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlSGFuZGxlUmVzaXplID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGU7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAvLyBUT0RPOiByZW5hbWUgdGhpcyBzdGF0ZSBmaWVsZCB0byBcImlzU2NhbGluZ1wiIHRvIGRpc3Rpbmd1aXNoXG4gICAgICAvLyBpdCBmcm9tIHRoZSBnZW5lcmljIFwiaXNSZXNpemluZ1wiIHdoaWNoIGluY2x1ZGVzIHNjYWxpbmcgYW5kXG4gICAgICAvLyByb3RhdGluZ1xuICAgICAgaXNSZXNpemluZzogdHJhbnNmb3JtSGFuZGxlVHlwZSAmJiB0cmFuc2Zvcm1IYW5kbGVUeXBlICE9PSBcInJvdGF0aW9uXCIsXG4gICAgICBpc1JvdGF0aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlID09PSBcInJvdGF0aW9uXCIsXG4gICAgfSk7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBjb25zdCBbcmVzaXplWCwgcmVzaXplWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQueCxcbiAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGlmIChcbiAgICAgIHRyYW5zZm9ybUVsZW1lbnRzKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbixcbiAgICAgICAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNJbWFnZUVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHJlc2l6ZVgsXG4gICAgICAgIHJlc2l6ZVksXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5jZW50ZXIueSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLyoqIEBwcml2YXRlIHVzZSB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51ICovXG4gIHByaXZhdGUgX29wZW5Db250ZXh0TWVudSA9IChcbiAgICB7XG4gICAgICBsZWZ0LFxuICAgICAgdG9wLFxuICAgIH06IHtcbiAgICAgIGxlZnQ6IG51bWJlcjtcbiAgICAgIHRvcDogbnVtYmVyO1xuICAgIH0sXG4gICAgdHlwZTogXCJjYW52YXNcIiB8IFwiZWxlbWVudFwiLFxuICApID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlIH0pO1xuICAgIH1cbiAgICB0aGlzLmNvbnRleHRNZW51T3BlbiA9IHRydWU7XG4gICAgY29uc3QgbWF5YmVHcm91cEFjdGlvbiA9IGFjdGlvbkdyb3VwLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZVVuZ3JvdXBBY3Rpb24gPSBhY3Rpb25Vbmdyb3VwLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZUZsaXBIb3Jpem9udGFsID0gYWN0aW9uRmxpcEhvcml6b250YWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcFZlcnRpY2FsID0gYWN0aW9uRmxpcFZlcnRpY2FsLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXlCZUFsbG93VW5iaW5kaW5nID0gYWN0aW9uVW5iaW5kVGV4dC5jb250ZXh0SXRlbVByZWRpY2F0ZShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXlCZUFsbG93QmluZGluZyA9IGFjdGlvbkJpbmRUZXh0LmNvbnRleHRJdGVtUHJlZGljYXRlKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IHNlcGFyYXRvciA9IFwic2VwYXJhdG9yXCI7XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBvcHRpb25zOiBDb250ZXh0TWVudU9wdGlvbltdID0gW107XG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNQbmcpO1xuICAgIH1cblxuICAgIGlmIChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNTdmcpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHR5cGUgPT09IFwiZWxlbWVudFwiICYmXG4gICAgICBjb3B5VGV4dC5jb250ZXh0SXRlbVByZWRpY2F0ZShlbGVtZW50cywgdGhpcy5zdGF0ZSkgJiZcbiAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHRcbiAgICApIHtcbiAgICAgIG9wdGlvbnMucHVzaChjb3B5VGV4dCk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSBcImNhbnZhc1wiKSB7XG4gICAgICBjb25zdCB2aWV3TW9kZU9wdGlvbnMgPSBbXG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJiBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gICAgICBdO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogdmlld01vZGVPcHRpb25zLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJlxuICAgICAgICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHtcbiAgICAgICAgICAgICAgICB0cmFja0V2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYW1lOiBcInBhc3RlXCIsXG4gICAgICAgICAgICAgICAgcGVyZm9ybTogKGVsZW1lbnRzLCBhcHBTdGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKG51bGwpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZXh0SXRlbUxhYmVsOiBcImxhYmVscy5wYXN0ZVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUgJiYgbmF2aWdhdG9yLmNsaXBib2FyZCAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJlxuICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGFjdGlvbkNvcHlBc1BuZyxcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiZcbiAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBhY3Rpb25Db3B5QXNTdmcsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBjb3B5VGV4dCxcbiAgICAgICAgICAgICgocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkgfHxcbiAgICAgICAgICAgICAgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkpICYmXG4gICAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbGVjdEFsbCxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlVmlld01vZGUsXG4gICAgICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImVsZW1lbnRcIikge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksIC4uLm9wdGlvbnNdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBhY3Rpb25DdXQsXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJlxuICAgICAgICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcInBhc3RlXCIsXG4gICAgICAgICAgICAgICAgdHJhY2tFdmVudDogZmFsc2UsXG4gICAgICAgICAgICAgICAgcGVyZm9ybTogKGVsZW1lbnRzLCBhcHBTdGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKG51bGwpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZXh0SXRlbUxhYmVsOiBcImxhYmVscy5wYXN0ZVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkNvcHlTdHlsZXMsXG4gICAgICAgICAgICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIG1heWJlR3JvdXBBY3Rpb24gJiYgYWN0aW9uR3JvdXAsXG4gICAgICAgICAgICBtYXlCZUFsbG93VW5iaW5kaW5nICYmIGFjdGlvblVuYmluZFRleHQsXG4gICAgICAgICAgICBtYXlCZUFsbG93QmluZGluZyAmJiBhY3Rpb25CaW5kVGV4dCxcbiAgICAgICAgICAgIG1heWJlVW5ncm91cEFjdGlvbiAmJiBhY3Rpb25Vbmdyb3VwLFxuICAgICAgICAgICAgKG1heWJlR3JvdXBBY3Rpb24gfHwgbWF5YmVVbmdyb3VwQWN0aW9uKSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gICAgICAgICAgICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gICAgICAgICAgICBhY3Rpb25TZW5kVG9CYWNrLFxuICAgICAgICAgICAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgbWF5YmVGbGlwSG9yaXpvbnRhbCAmJiBhY3Rpb25GbGlwSG9yaXpvbnRhbCxcbiAgICAgICAgICAgIG1heWJlRmxpcFZlcnRpY2FsICYmIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgICAgICAgICAgIChtYXliZUZsaXBIb3Jpem9udGFsIHx8IG1heWJlRmxpcFZlcnRpY2FsKSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25MaW5rLmNvbnRleHRJdGVtUHJlZGljYXRlKGVsZW1lbnRzLCB0aGlzLnN0YXRlKSAmJiBhY3Rpb25MaW5rLFxuICAgICAgICAgICAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICAgICAgICAgICAgYWN0aW9uVG9nZ2xlTG9jayxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVXaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmIChpc1Bhbm5pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGRlbHRhWCwgZGVsdGFZIH0gPSBldmVudDtcbiAgICAvLyBub3RlIHRoYXQgZXZlbnQuY3RybEtleSBpcyBuZWNlc3NhcnkgdG8gaGFuZGxlIHBpbmNoIHpvb21pbmdcbiAgICBpZiAoZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5KSB7XG4gICAgICBjb25zdCBzaWduID0gTWF0aC5zaWduKGRlbHRhWSk7XG4gICAgICBjb25zdCBNQVhfU1RFUCA9IDEwO1xuICAgICAgY29uc3QgYWJzRGVsdGEgPSBNYXRoLmFicyhkZWx0YVkpO1xuICAgICAgbGV0IGRlbHRhID0gZGVsdGFZO1xuICAgICAgaWYgKGFic0RlbHRhID4gTUFYX1NURVApIHtcbiAgICAgICAgZGVsdGEgPSBNQVhfU1RFUCAqIHNpZ247XG4gICAgICB9XG5cbiAgICAgIGxldCBuZXdab29tID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlIC0gZGVsdGEgLyAxMDA7XG4gICAgICAvLyBpbmNyZWFzZSB6b29tIHN0ZXBzIHRoZSBtb3JlIHpvb21lZC1pbiB3ZSBhcmUgKGFwcGxpZXMgdG8gPjEwMCUgb25seSlcbiAgICAgIG5ld1pvb20gKz1cbiAgICAgICAgTWF0aC5sb2cxMChNYXRoLm1heCgxLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSAqXG4gICAgICAgIC1zaWduICpcbiAgICAgICAgLy8gcmVkdWNlZCBhbXBsaWZpY2F0aW9uIGZvciBzbWFsbCBkZWx0YXMgKHNtYWxsIG1vdmVtZW50cyBvbiBhIHRyYWNrcGFkKVxuICAgICAgICBNYXRoLm1pbigxLCBhYnNEZWx0YSAvIDIwKTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldFN0YXRlRm9yWm9vbShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2aWV3cG9ydFg6IGN1cnNvclgsXG4gICAgICAgICAgICB2aWV3cG9ydFk6IGN1cnNvclksXG4gICAgICAgICAgICBuZXh0Wm9vbTogZ2V0Tm9ybWFsaXplZFpvb20obmV3Wm9vbSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKSxcbiAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHNjcm9sbCBob3Jpem9udGFsbHkgd2hlbiBzaGlmdCBwcmVzc2VkXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIHNjcm9sbFggfSkgPT4gKHtcbiAgICAgICAgLy8gb24gTWFjLCBzaGlmdCt3aGVlbCB0ZW5kcyB0byByZXN1bHQgaW4gZGVsdGFYXG4gICAgICAgIHNjcm9sbFg6IHNjcm9sbFggLSAoZGVsdGFZIHx8IGRlbHRhWCkgLyB6b29tLnZhbHVlLFxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCwgc2Nyb2xsWSB9KSA9PiAoe1xuICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIGRlbHRhWCAvIHpvb20udmFsdWUsXG4gICAgICBzY3JvbGxZOiBzY3JvbGxZIC0gZGVsdGFZIC8gem9vbS52YWx1ZSxcbiAgICB9KSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCxcbiAgICBzY2FsZTogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBlbGVtZW50Q2xpY2tlZEluc2lkZSA9IGdldFRleHRCaW5kYWJsZUNvbnRhaW5lckF0UG9zaXRpb24oXG4gICAgICB0aGlzLnNjZW5lXG4gICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAuZmlsdGVyKChlbGVtZW50KSA9PiAhaXNUZXh0RWxlbWVudChlbGVtZW50KSksXG4gICAgICB4LFxuICAgICAgeSxcbiAgICApO1xuICAgIGlmIChlbGVtZW50Q2xpY2tlZEluc2lkZSkge1xuICAgICAgY29uc3QgZWxlbWVudENlbnRlclggPVxuICAgICAgICBlbGVtZW50Q2xpY2tlZEluc2lkZS54ICsgZWxlbWVudENsaWNrZWRJbnNpZGUud2lkdGggLyAyO1xuICAgICAgY29uc3QgZWxlbWVudENlbnRlclkgPVxuICAgICAgICBlbGVtZW50Q2xpY2tlZEluc2lkZS55ICsgZWxlbWVudENsaWNrZWRJbnNpZGUuaGVpZ2h0IC8gMjtcbiAgICAgIGNvbnN0IGRpc3RhbmNlVG9DZW50ZXIgPSBNYXRoLmh5cG90KFxuICAgICAgICB4IC0gZWxlbWVudENlbnRlclgsXG4gICAgICAgIHkgLSBlbGVtZW50Q2VudGVyWSxcbiAgICAgICk7XG4gICAgICBjb25zdCBpc1NuYXBwZWRUb0NlbnRlciA9XG4gICAgICAgIGRpc3RhbmNlVG9DZW50ZXIgPCBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRDtcbiAgICAgIGlmIChpc1NuYXBwZWRUb0NlbnRlcikge1xuICAgICAgICBjb25zdCB7IHg6IHZpZXdwb3J0WCwgeTogdmlld3BvcnRZIH0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgICAgeyBzY2VuZVg6IGVsZW1lbnRDZW50ZXJYLCBzY2VuZVk6IGVsZW1lbnRDZW50ZXJZIH0sXG4gICAgICAgICAgYXBwU3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IHZpZXdwb3J0WCwgdmlld3BvcnRZLCBlbGVtZW50Q2VudGVyWCwgZWxlbWVudENlbnRlclkgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNhdmVQb2ludGVyID0gKHg6IG51bWJlciwgeTogbnVtYmVyLCBidXR0b246IFwidXBcIiB8IFwiZG93blwiKSA9PiB7XG4gICAgaWYgKCF4IHx8ICF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IHgsIGNsaWVudFk6IHkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChpc05hTihwb2ludGVyLngpIHx8IGlzTmFOKHBvaW50ZXIueSkpIHtcbiAgICAgIC8vIHNvbWV0aW1lcyB0aGUgcG9pbnRlciBnb2VzIG9mZiBzY3JlZW5cbiAgICB9XG5cbiAgICB0aGlzLnByb3BzLm9uUG9pbnRlclVwZGF0ZT8uKHtcbiAgICAgIHBvaW50ZXIsXG4gICAgICBidXR0b24sXG4gICAgICBwb2ludGVyc01hcDogZ2VzdHVyZS5wb2ludGVycyxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGlmICghdGhpcy51bm1vdW50ZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlIH0pO1xuICAgIH1cbiAgfSwgMzAwKTtcblxuICBwcml2YXRlIHVwZGF0ZURPTVJlY3QgPSAoY2I/OiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aCxcbiAgICAgICAgaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBvZmZzZXRMZWZ0LFxuICAgICAgICB0b3A6IG9mZnNldFRvcCxcbiAgICAgIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aDogY3VycmVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGN1cnJlbnRIZWlnaHQsXG4gICAgICAgIG9mZnNldFRvcDogY3VycmVudE9mZnNldFRvcCxcbiAgICAgICAgb2Zmc2V0TGVmdDogY3VycmVudE9mZnNldExlZnQsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgaWYgKFxuICAgICAgICB3aWR0aCA9PT0gY3VycmVudFdpZHRoICYmXG4gICAgICAgIGhlaWdodCA9PT0gY3VycmVudEhlaWdodCAmJlxuICAgICAgICBvZmZzZXRMZWZ0ID09PSBjdXJyZW50T2Zmc2V0TGVmdCAmJlxuICAgICAgICBvZmZzZXRUb3AgPT09IGN1cnJlbnRPZmZzZXRUb3BcbiAgICAgICkge1xuICAgICAgICBpZiAoY2IpIHtcbiAgICAgICAgICBjYigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICBvZmZzZXRMZWZ0LFxuICAgICAgICAgIG9mZnNldFRvcCxcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGNiICYmIGNiKCk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgcmVmcmVzaCA9ICgpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCkgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRDYW52YXNPZmZzZXRzKCk6IFBpY2s8QXBwU3RhdGUsIFwib2Zmc2V0VG9wXCIgfCBcIm9mZnNldExlZnRcIj4ge1xuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IGV4Y2FsaWRyYXdDb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb2Zmc2V0TGVmdDogbGVmdCxcbiAgICAgICAgb2Zmc2V0VG9wOiB0b3AsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb2Zmc2V0TGVmdDogMCxcbiAgICAgIG9mZnNldFRvcDogMCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVMYW5ndWFnZSgpIHtcbiAgICBjb25zdCBjdXJyZW50TGFuZyA9XG4gICAgICBsYW5ndWFnZXMuZmluZCgobGFuZykgPT4gbGFuZy5jb2RlID09PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB8fFxuICAgICAgZGVmYXVsdExhbmc7XG4gICAgYXdhaXQgc2V0TGFuZ3VhZ2UoY3VycmVudExhbmcpO1xuICAgIHRoaXMuc2V0QXBwU3RhdGUoe30pO1xuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBURVNUIEhPT0tTXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBXaW5kb3cge1xuICAgIGg6IHtcbiAgICAgIGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdO1xuICAgICAgc3RhdGU6IEFwcFN0YXRlO1xuICAgICAgc2V0U3RhdGU6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdO1xuICAgICAgYXBwOiBJbnN0YW5jZVR5cGU8dHlwZW9mIEFwcD47XG4gICAgICBoaXN0b3J5OiBIaXN0b3J5O1xuICAgIH07XG4gIH1cbn1cblxuaWYgKFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLlRFU1QgfHxcbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVFxuKSB7XG4gIHdpbmRvdy5oID0gd2luZG93LmggfHwgKHt9IGFzIFdpbmRvd1tcImhcIl0pO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgZWxlbWVudHM6IHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwPy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgIH0sXG4gICAgICBzZXQoZWxlbWVudHM6IEV4Y2FsaWRyYXdFbGVtZW50W10pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwPy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cbmV4cG9ydCBkZWZhdWx0IEFwcDtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
2121
2121
 
2122
2122
  /***/ }),
2123
2123
 
@@ -2854,7 +2854,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2854
2854
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2855
2855
 
2856
2856
  "use strict";
2857
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"LinearElementEditor\": () => (/* binding */ LinearElementEditor)\n/* harmony export */ });\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! . */ \"../../element/index.ts\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _binding__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./binding */ \"../../element/binding.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n\n\n\n\n\n\n\n\nclass LinearElementEditor {\n constructor(element, scene) {\n this.elementId = element.id;\n _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].mapElementToScene(this.elementId, scene);\n LinearElementEditor.normalizePoints(element);\n this.selectedPointsIndices = null;\n this.lastUncommittedPoint = null;\n this.isDragging = false;\n this.pointerOffset = { x: 0, y: 0 };\n this.startBindingElement = \"keep\";\n this.endBindingElement = \"keep\";\n this.pointerDownState = {\n prevSelectedPointsIndices: null,\n lastClickedPoint: -1,\n };\n this.hoverPointIndex = -1;\n }\n /**\n * @param id the `elementId` from the instance of this class (so that we can\n * statically guarantee this method returns an ExcalidrawLinearElement)\n */\n static getElement(id) {\n var _a;\n const element = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(id)) === null || _a === void 0 ? void 0 : _a.getNonDeletedElement(id);\n if (element) {\n return element;\n }\n return null;\n }\n static handleBoxSelection(event, appState, setState) {\n var _a;\n if (!appState.editingLinearElement ||\n ((_a = appState.draggingElement) === null || _a === void 0 ? void 0 : _a.type) !== \"selection\") {\n return false;\n }\n const { editingLinearElement } = appState;\n const { selectedPointsIndices, elementId } = editingLinearElement;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return false;\n }\n const [selectionX1, selectionY1, selectionX2, selectionY2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(appState.draggingElement);\n const pointsSceneCoords = LinearElementEditor.getPointsGlobalCoordinates(element);\n const nextSelectedPoints = pointsSceneCoords.reduce((acc, point, index) => {\n if ((point[0] >= selectionX1 &&\n point[0] <= selectionX2 &&\n point[1] >= selectionY1 &&\n point[1] <= selectionY2) ||\n (event.shiftKey && (selectedPointsIndices === null || selectedPointsIndices === void 0 ? void 0 : selectedPointsIndices.includes(index)))) {\n acc.push(index);\n }\n return acc;\n }, []);\n setState({\n editingLinearElement: Object.assign(Object.assign({}, editingLinearElement), { selectedPointsIndices: nextSelectedPoints.length\n ? nextSelectedPoints\n : null }),\n });\n }\n /** @returns whether point was dragged */\n static handlePointDragging(appState, scenePointerX, scenePointerY, maybeSuggestBinding, linearElementEditor) {\n if (!linearElementEditor) {\n return false;\n }\n const { selectedPointsIndices, elementId } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return false;\n }\n // point that's being dragged (out of all selected points)\n const draggingPoint = element.points[linearElementEditor.pointerDownState.lastClickedPoint];\n if (selectedPointsIndices && draggingPoint) {\n const newDraggingPointPosition = LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, appState.gridSize);\n const deltaX = newDraggingPointPosition[0] - draggingPoint[0];\n const deltaY = newDraggingPointPosition[1] - draggingPoint[1];\n LinearElementEditor.movePoints(element, selectedPointsIndices.map((pointIndex) => {\n const newPointPosition = pointIndex === linearElementEditor.pointerDownState.lastClickedPoint\n ? LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, appState.gridSize)\n : [\n element.points[pointIndex][0] + deltaX,\n element.points[pointIndex][1] + deltaY,\n ];\n return {\n index: pointIndex,\n point: newPointPosition,\n isDragging: pointIndex ===\n linearElementEditor.pointerDownState.lastClickedPoint,\n };\n }));\n // suggest bindings for first and last point if selected\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_7__.isBindingElement)(element, false)) {\n const coords = [];\n const firstSelectedIndex = selectedPointsIndices[0];\n if (firstSelectedIndex === 0) {\n coords.push((0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(LinearElementEditor.getPointGlobalCoordinates(element, element.points[0])));\n }\n const lastSelectedIndex = selectedPointsIndices[selectedPointsIndices.length - 1];\n if (lastSelectedIndex === element.points.length - 1) {\n coords.push((0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(LinearElementEditor.getPointGlobalCoordinates(element, element.points[lastSelectedIndex])));\n }\n if (coords.length) {\n maybeSuggestBinding(element, coords);\n }\n }\n return true;\n }\n return false;\n }\n static handlePointerUp(event, editingLinearElement, appState) {\n var _a;\n const { elementId, selectedPointsIndices, isDragging, pointerDownState } = editingLinearElement;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return editingLinearElement;\n }\n const bindings = {};\n if (isDragging && selectedPointsIndices) {\n for (const selectedPoint of selectedPointsIndices) {\n if (selectedPoint === 0 ||\n selectedPoint === element.points.length - 1) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_0__.isPathALoop)(element.points, appState.zoom.value)) {\n LinearElementEditor.movePoints(element, [\n {\n index: selectedPoint,\n point: selectedPoint === 0\n ? element.points[element.points.length - 1]\n : element.points[0],\n },\n ]);\n }\n const bindingElement = (0,_binding__WEBPACK_IMPORTED_MODULE_5__.isBindingEnabled)(appState)\n ? (0,_binding__WEBPACK_IMPORTED_MODULE_5__.getHoveredElementForBinding)((0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(LinearElementEditor.getPointAtIndexGlobalCoordinates(element, selectedPoint)), _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(element))\n : null;\n bindings[selectedPoint === 0 ? \"startBindingElement\" : \"endBindingElement\"] = bindingElement;\n }\n }\n }\n return Object.assign(Object.assign(Object.assign({}, editingLinearElement), bindings), { \n // if clicking without previously dragging a point(s), and not holding\n // shift, deselect all points except the one clicked. If holding shift,\n // toggle the point.\n selectedPointsIndices: isDragging || event.shiftKey\n ? !isDragging &&\n event.shiftKey &&\n ((_a = pointerDownState.prevSelectedPointsIndices) === null || _a === void 0 ? void 0 : _a.includes(pointerDownState.lastClickedPoint))\n ? selectedPointsIndices &&\n selectedPointsIndices.filter((pointIndex) => pointIndex !== pointerDownState.lastClickedPoint)\n : selectedPointsIndices\n : (selectedPointsIndices === null || selectedPointsIndices === void 0 ? void 0 : selectedPointsIndices.includes(pointerDownState.lastClickedPoint))\n ? [pointerDownState.lastClickedPoint]\n : selectedPointsIndices, isDragging: false, pointerOffset: { x: 0, y: 0 } });\n }\n static handlePointerDown(event, appState, history, scenePointer, linearElementEditor) {\n var _a;\n const ret = {\n didAddPoint: false,\n hitElement: null,\n linearElementEditor: null,\n };\n if (!linearElementEditor) {\n return ret;\n }\n const { elementId } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return ret;\n }\n if (event.altKey && appState.editingLinearElement) {\n if (linearElementEditor.lastUncommittedPoint == null) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n points: [\n ...element.points,\n LinearElementEditor.createPointAt(element, scenePointer.x, scenePointer.y, appState.gridSize),\n ],\n });\n }\n history.resumeRecording();\n ret.linearElementEditor = Object.assign(Object.assign({}, linearElementEditor), { pointerDownState: {\n prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,\n lastClickedPoint: -1,\n }, selectedPointsIndices: [element.points.length - 1], lastUncommittedPoint: null, endBindingElement: (0,_binding__WEBPACK_IMPORTED_MODULE_5__.getHoveredElementForBinding)(scenePointer, _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(element)) });\n ret.didAddPoint = true;\n return ret;\n }\n const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, appState.zoom, scenePointer.x, scenePointer.y);\n // if we clicked on a point, set the element as hitElement otherwise\n // it would get deselected if the point is outside the hitbox area\n if (clickedPointIndex > -1) {\n ret.hitElement = element;\n }\n else {\n // You might be wandering why we are storing the binding elements on\n // LinearElementEditor and passing them in, instead of calculating them\n // from the end points of the `linearElement` - this is to allow disabling\n // binding (which needs to happen at the point the user finishes moving\n // the point).\n const { startBindingElement, endBindingElement } = linearElementEditor;\n if ((0,_binding__WEBPACK_IMPORTED_MODULE_5__.isBindingEnabled)(appState) && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_7__.isBindingElement)(element)) {\n (0,_binding__WEBPACK_IMPORTED_MODULE_5__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n }\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const targetPoint = clickedPointIndex > -1 &&\n (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(element.x + element.points[clickedPointIndex][0], element.y + element.points[clickedPointIndex][1], cx, cy, element.angle);\n const nextSelectedPointsIndices = clickedPointIndex > -1 || event.shiftKey\n ? event.shiftKey ||\n ((_a = linearElementEditor.selectedPointsIndices) === null || _a === void 0 ? void 0 : _a.includes(clickedPointIndex))\n ? normalizeSelectedPoints([\n ...(linearElementEditor.selectedPointsIndices || []),\n clickedPointIndex,\n ])\n : [clickedPointIndex]\n : null;\n ret.linearElementEditor = Object.assign(Object.assign({}, linearElementEditor), { pointerDownState: {\n prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,\n lastClickedPoint: clickedPointIndex,\n }, selectedPointsIndices: nextSelectedPointsIndices, pointerOffset: targetPoint\n ? {\n x: scenePointer.x - targetPoint[0],\n y: scenePointer.y - targetPoint[1],\n }\n : { x: 0, y: 0 } });\n return ret;\n }\n static handlePointerMove(event, scenePointerX, scenePointerY, linearElementEditor, gridSize) {\n const { elementId, lastUncommittedPoint } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return linearElementEditor;\n }\n const { points } = element;\n const lastPoint = points[points.length - 1];\n if (!event.altKey) {\n if (lastPoint === lastUncommittedPoint) {\n LinearElementEditor.deletePoints(element, [points.length - 1]);\n }\n return Object.assign(Object.assign({}, linearElementEditor), { lastUncommittedPoint: null });\n }\n const newPoint = LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, gridSize);\n if (lastPoint === lastUncommittedPoint) {\n LinearElementEditor.movePoints(element, [\n {\n index: element.points.length - 1,\n point: newPoint,\n },\n ]);\n }\n else {\n LinearElementEditor.addPoints(element, [{ point: newPoint }]);\n }\n return Object.assign(Object.assign({}, linearElementEditor), { lastUncommittedPoint: element.points[element.points.length - 1] });\n }\n /** scene coords */\n static getPointGlobalCoordinates(element, point) {\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n let { x, y } = element;\n [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(x + point[0], y + point[1], cx, cy, element.angle);\n return [x, y];\n }\n /** scene coords */\n static getPointsGlobalCoordinates(element) {\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n return element.points.map((point) => {\n let { x, y } = element;\n [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(x + point[0], y + point[1], cx, cy, element.angle);\n return [x, y];\n });\n }\n static getPointAtIndexGlobalCoordinates(element, indexMaybeFromEnd) {\n const index = indexMaybeFromEnd < 0\n ? element.points.length + indexMaybeFromEnd\n : indexMaybeFromEnd;\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const point = element.points[index];\n const { x, y } = element;\n return (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(x + point[0], y + point[1], cx, cy, element.angle);\n }\n static pointFromAbsoluteCoords(element, absoluteCoords) {\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(absoluteCoords[0], absoluteCoords[1], cx, cy, -element.angle);\n return [x - element.x, y - element.y];\n }\n static getPointIndexUnderCursor(element, zoom, x, y) {\n const pointHandles = this.getPointsGlobalCoordinates(element);\n let idx = pointHandles.length;\n // loop from right to left because points on the right are rendered over\n // points on the left, thus should take precedence when clicking, if they\n // overlap\n while (--idx > -1) {\n const point = pointHandles[idx];\n if ((0,_math__WEBPACK_IMPORTED_MODULE_0__.distance2d)(x, y, point[0], point[1]) * zoom.value <\n // +1px to account for outline stroke\n this.POINT_HANDLE_SIZE + 1) {\n return idx;\n }\n }\n return -1;\n }\n static createPointAt(element, scenePointerX, scenePointerY, gridSize) {\n const pointerOnGrid = (0,_math__WEBPACK_IMPORTED_MODULE_0__.getGridPoint)(scenePointerX, scenePointerY, gridSize);\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const [rotatedX, rotatedY] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(pointerOnGrid[0], pointerOnGrid[1], cx, cy, -element.angle);\n return [rotatedX - element.x, rotatedY - element.y];\n }\n /**\n * Normalizes line points so that the start point is at [0,0]. This is\n * expected in various parts of the codebase. Also returns new x/y to account\n * for the potential normalization.\n */\n static getNormalizedPoints(element) {\n const { points } = element;\n const offsetX = points[0][0];\n const offsetY = points[0][1];\n return {\n points: points.map((point, _idx) => {\n return [point[0] - offsetX, point[1] - offsetY];\n }),\n x: element.x + offsetX,\n y: element.y + offsetY,\n };\n }\n // element-mutating methods\n // ---------------------------------------------------------------------------\n static normalizePoints(element) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, LinearElementEditor.getNormalizedPoints(element));\n }\n static duplicateSelectedPoints(appState) {\n if (!appState.editingLinearElement) {\n return false;\n }\n const { selectedPointsIndices, elementId } = appState.editingLinearElement;\n const element = LinearElementEditor.getElement(elementId);\n if (!element || selectedPointsIndices === null) {\n return false;\n }\n const { points } = element;\n const nextSelectedIndices = [];\n let pointAddedToEnd = false;\n let indexCursor = -1;\n const nextPoints = points.reduce((acc, point, index) => {\n ++indexCursor;\n acc.push(point);\n const isSelected = selectedPointsIndices.includes(index);\n if (isSelected) {\n const nextPoint = points[index + 1];\n if (!nextPoint) {\n pointAddedToEnd = true;\n }\n acc.push(nextPoint\n ? [(point[0] + nextPoint[0]) / 2, (point[1] + nextPoint[1]) / 2]\n : [point[0], point[1]]);\n nextSelectedIndices.push(indexCursor + 1);\n ++indexCursor;\n }\n return acc;\n }, []);\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, { points: nextPoints });\n // temp hack to ensure the line doesn't move when adding point to the end,\n // potentially expanding the bounding box\n if (pointAddedToEnd) {\n const lastPoint = element.points[element.points.length - 1];\n LinearElementEditor.movePoints(element, [\n {\n index: element.points.length - 1,\n point: [lastPoint[0] + 30, lastPoint[1] + 30],\n },\n ]);\n }\n return {\n appState: Object.assign(Object.assign({}, appState), { editingLinearElement: Object.assign(Object.assign({}, appState.editingLinearElement), { selectedPointsIndices: nextSelectedIndices }) }),\n };\n }\n static deletePoints(element, pointIndices) {\n let offsetX = 0;\n let offsetY = 0;\n const isDeletingOriginPoint = pointIndices.includes(0);\n // if deleting first point, make the next to be [0,0] and recalculate\n // positions of the rest with respect to it\n if (isDeletingOriginPoint) {\n const firstNonDeletedPoint = element.points.find((point, idx) => {\n return !pointIndices.includes(idx);\n });\n if (firstNonDeletedPoint) {\n offsetX = firstNonDeletedPoint[0];\n offsetY = firstNonDeletedPoint[1];\n }\n }\n const nextPoints = element.points.reduce((acc, point, idx) => {\n if (!pointIndices.includes(idx)) {\n acc.push(!acc.length ? [0, 0] : [point[0] - offsetX, point[1] - offsetY]);\n }\n return acc;\n }, []);\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY);\n }\n static addPoints(element, targetPoints) {\n const offsetX = 0;\n const offsetY = 0;\n const nextPoints = [...element.points, ...targetPoints.map((x) => x.point)];\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY);\n }\n static movePoints(element, targetPoints, otherUpdates) {\n const { points } = element;\n // in case we're moving start point, instead of modifying its position\n // which would break the invariant of it being at [0,0], we move\n // all the other points in the opposite direction by delta to\n // offset it. We do the same with actual element.x/y position, so\n // this hacks are completely transparent to the user.\n let offsetX = 0;\n let offsetY = 0;\n const selectedOriginPoint = targetPoints.find(({ index }) => index === 0);\n if (selectedOriginPoint) {\n offsetX =\n selectedOriginPoint.point[0] - points[selectedOriginPoint.index][0];\n offsetY =\n selectedOriginPoint.point[1] - points[selectedOriginPoint.index][1];\n }\n const nextPoints = points.map((point, idx) => {\n const selectedPointData = targetPoints.find((p) => p.index === idx);\n if (selectedPointData) {\n if (selectedOriginPoint) {\n return point;\n }\n const deltaX = selectedPointData.point[0] - points[selectedPointData.index][0];\n const deltaY = selectedPointData.point[1] - points[selectedPointData.index][1];\n return [point[0] + deltaX, point[1] + deltaY];\n }\n return offsetX || offsetY\n ? [point[0] - offsetX, point[1] - offsetY]\n : point;\n });\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY, otherUpdates);\n }\n static _updatePoints(element, nextPoints, offsetX, offsetY, otherUpdates) {\n const nextCoords = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementPointsCoords)(element, nextPoints, element.strokeSharpness || \"round\");\n const prevCoords = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementPointsCoords)(element, element.points, element.strokeSharpness || \"round\");\n const nextCenterX = (nextCoords[0] + nextCoords[2]) / 2;\n const nextCenterY = (nextCoords[1] + nextCoords[3]) / 2;\n const prevCenterX = (prevCoords[0] + prevCoords[2]) / 2;\n const prevCenterY = (prevCoords[1] + prevCoords[3]) / 2;\n const dX = prevCenterX - nextCenterX;\n const dY = prevCenterY - nextCenterY;\n const rotated = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(offsetX, offsetY, dX, dY, element.angle);\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, Object.assign(Object.assign({}, otherUpdates), { points: nextPoints, x: element.x + rotated[0], y: element.y + rotated[1] }));\n }\n}\n// ---------------------------------------------------------------------------\n// static methods\n// ---------------------------------------------------------------------------\nLinearElementEditor.POINT_HANDLE_SIZE = 10;\nconst normalizeSelectedPoints = (points) => {\n let nextPoints = [\n ...new Set(points.filter((p) => p !== null && p !== -1)),\n ];\n nextPoints = nextPoints.sort((a, b) => a - b);\n return nextPoints.length ? nextPoints : null;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QixDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQ3pCLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFDekIsQ0FBQztJQUNMLENBQUM7O0FBdnZCRCw4RUFBOEU7QUFDOUUsaUJBQWlCO0FBQ2pCLDhFQUE4RTtBQUV2RSxxQ0FBaUIsR0FBRyxFQUFFLENBQUM7QUFzdkJoQyxNQUFNLHVCQUF1QixHQUFHLENBQzlCLE1BQXlCLEVBQ1IsRUFBRTtJQUNuQixJQUFJLFVBQVUsR0FBRztRQUNmLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM3QyxDQUFDO0lBQ2QsVUFBVSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDOUMsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUMvQyxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vZWxlbWVudC9saW5lYXJFbGVtZW50RWRpdG9yLnRzP2ZjNDMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgTm9uRGVsZXRlZCxcbiAgRXhjYWxpZHJhd0xpbmVhckVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdFbGVtZW50LFxuICBQb2ludEJpbmRpbmcsXG4gIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBkaXN0YW5jZTJkLCByb3RhdGUsIGlzUGF0aEFMb29wLCBnZXRHcmlkUG9pbnQgfSBmcm9tIFwiLi4vbWF0aFwiO1xuaW1wb3J0IHsgZ2V0RWxlbWVudEFic29sdXRlQ29vcmRzIH0gZnJvbSBcIi5cIjtcbmltcG9ydCB7IGdldEVsZW1lbnRQb2ludHNDb29yZHMgfSBmcm9tIFwiLi9ib3VuZHNcIjtcbmltcG9ydCB7IFBvaW50LCBBcHBTdGF0ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgbXV0YXRlRWxlbWVudCB9IGZyb20gXCIuL211dGF0ZUVsZW1lbnRcIjtcbmltcG9ydCBIaXN0b3J5IGZyb20gXCIuLi9oaXN0b3J5XCI7XG5cbmltcG9ydCBTY2VuZSBmcm9tIFwiLi4vc2NlbmUvU2NlbmVcIjtcbmltcG9ydCB7XG4gIGJpbmRPclVuYmluZExpbmVhckVsZW1lbnQsXG4gIGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyxcbiAgaXNCaW5kaW5nRW5hYmxlZCxcbn0gZnJvbSBcIi4vYmluZGluZ1wiO1xuaW1wb3J0IHsgdHVwbGVUb0Nvb3JzIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBpc0JpbmRpbmdFbGVtZW50IH0gZnJvbSBcIi4vdHlwZUNoZWNrc1wiO1xuXG5leHBvcnQgY2xhc3MgTGluZWFyRWxlbWVudEVkaXRvciB7XG4gIHB1YmxpYyBlbGVtZW50SWQ6IEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0gJiB7XG4gICAgX2JyYW5kOiBcImV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50SWRcIjtcbiAgfTtcbiAgLyoqIGluZGljZXMgKi9cbiAgcHVibGljIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10gfCBudWxsO1xuXG4gIHB1YmxpYyBwb2ludGVyRG93blN0YXRlOiBSZWFkb25seTx7XG4gICAgcHJldlNlbGVjdGVkUG9pbnRzSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10gfCBudWxsO1xuICAgIC8qKiBpbmRleCAqL1xuICAgIGxhc3RDbGlja2VkUG9pbnQ6IG51bWJlcjtcbiAgfT47XG5cbiAgLyoqIHdoZXRoZXIgeW91J3JlIGRyYWdnaW5nIGEgcG9pbnQgKi9cbiAgcHVibGljIGlzRHJhZ2dpbmc6IGJvb2xlYW47XG4gIHB1YmxpYyBsYXN0VW5jb21taXR0ZWRQb2ludDogUG9pbnQgfCBudWxsO1xuICBwdWJsaWMgcG9pbnRlck9mZnNldDogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PjtcbiAgcHVibGljIHN0YXJ0QmluZGluZ0VsZW1lbnQ6IEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQgfCBudWxsIHwgXCJrZWVwXCI7XG4gIHB1YmxpYyBlbmRCaW5kaW5nRWxlbWVudDogRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCB8IG51bGwgfCBcImtlZXBcIjtcbiAgcHVibGljIGhvdmVyUG9pbnRJbmRleDogbnVtYmVyO1xuICBjb25zdHJ1Y3RvcihlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50Piwgc2NlbmU6IFNjZW5lKSB7XG4gICAgdGhpcy5lbGVtZW50SWQgPSBlbGVtZW50LmlkIGFzIHN0cmluZyAmIHtcbiAgICAgIF9icmFuZDogXCJleGNhbGlkcmF3TGluZWFyRWxlbWVudElkXCI7XG4gICAgfTtcbiAgICBTY2VuZS5tYXBFbGVtZW50VG9TY2VuZSh0aGlzLmVsZW1lbnRJZCwgc2NlbmUpO1xuICAgIExpbmVhckVsZW1lbnRFZGl0b3Iubm9ybWFsaXplUG9pbnRzKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5zZWxlY3RlZFBvaW50c0luZGljZXMgPSBudWxsO1xuICAgIHRoaXMubGFzdFVuY29tbWl0dGVkUG9pbnQgPSBudWxsO1xuICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMucG9pbnRlck9mZnNldCA9IHsgeDogMCwgeTogMCB9O1xuICAgIHRoaXMuc3RhcnRCaW5kaW5nRWxlbWVudCA9IFwia2VlcFwiO1xuICAgIHRoaXMuZW5kQmluZGluZ0VsZW1lbnQgPSBcImtlZXBcIjtcbiAgICB0aGlzLnBvaW50ZXJEb3duU3RhdGUgPSB7XG4gICAgICBwcmV2U2VsZWN0ZWRQb2ludHNJbmRpY2VzOiBudWxsLFxuICAgICAgbGFzdENsaWNrZWRQb2ludDogLTEsXG4gICAgfTtcbiAgICB0aGlzLmhvdmVyUG9pbnRJbmRleCA9IC0xO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIHN0YXRpYyBtZXRob2RzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHN0YXRpYyBQT0lOVF9IQU5ETEVfU0laRSA9IDEwO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gaWQgdGhlIGBlbGVtZW50SWRgIGZyb20gdGhlIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgKHNvIHRoYXQgd2UgY2FuXG4gICAqICBzdGF0aWNhbGx5IGd1YXJhbnRlZSB0aGlzIG1ldGhvZCByZXR1cm5zIGFuIEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50KVxuICAgKi9cbiAgc3RhdGljIGdldEVsZW1lbnQoaWQ6IEluc3RhbmNlVHlwZTx0eXBlb2YgTGluZWFyRWxlbWVudEVkaXRvcj5bXCJlbGVtZW50SWRcIl0pIHtcbiAgICBjb25zdCBlbGVtZW50ID0gU2NlbmUuZ2V0U2NlbmUoaWQpPy5nZXROb25EZWxldGVkRWxlbWVudChpZCk7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50IGFzIE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVCb3hTZWxlY3Rpb24oXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICAgc2V0U3RhdGU6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdLFxuICApIHtcbiAgICBpZiAoXG4gICAgICAhYXBwU3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgIGFwcFN0YXRlLmRyYWdnaW5nRWxlbWVudD8udHlwZSAhPT0gXCJzZWxlY3Rpb25cIlxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCB7IGVkaXRpbmdMaW5lYXJFbGVtZW50IH0gPSBhcHBTdGF0ZTtcbiAgICBjb25zdCB7IHNlbGVjdGVkUG9pbnRzSW5kaWNlcywgZWxlbWVudElkIH0gPSBlZGl0aW5nTGluZWFyRWxlbWVudDtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldEVsZW1lbnQoZWxlbWVudElkKTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBbc2VsZWN0aW9uWDEsIHNlbGVjdGlvblkxLCBzZWxlY3Rpb25YMiwgc2VsZWN0aW9uWTJdID1cbiAgICAgIGdldEVsZW1lbnRBYnNvbHV0ZUNvb3JkcyhhcHBTdGF0ZS5kcmFnZ2luZ0VsZW1lbnQpO1xuXG4gICAgY29uc3QgcG9pbnRzU2NlbmVDb29yZHMgPVxuICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludHNHbG9iYWxDb29yZGluYXRlcyhlbGVtZW50KTtcblxuICAgIGNvbnN0IG5leHRTZWxlY3RlZFBvaW50cyA9IHBvaW50c1NjZW5lQ29vcmRzLnJlZHVjZShcbiAgICAgIChhY2M6IG51bWJlcltdLCBwb2ludCwgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChwb2ludFswXSA+PSBzZWxlY3Rpb25YMSAmJlxuICAgICAgICAgICAgcG9pbnRbMF0gPD0gc2VsZWN0aW9uWDIgJiZcbiAgICAgICAgICAgIHBvaW50WzFdID49IHNlbGVjdGlvblkxICYmXG4gICAgICAgICAgICBwb2ludFsxXSA8PSBzZWxlY3Rpb25ZMikgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXkgJiYgc2VsZWN0ZWRQb2ludHNJbmRpY2VzPy5pbmNsdWRlcyhpbmRleCkpXG4gICAgICAgICkge1xuICAgICAgICAgIGFjYy5wdXNoKGluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgW10sXG4gICAgKTtcblxuICAgIHNldFN0YXRlKHtcbiAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgIC4uLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6IG5leHRTZWxlY3RlZFBvaW50cy5sZW5ndGhcbiAgICAgICAgICA/IG5leHRTZWxlY3RlZFBvaW50c1xuICAgICAgICAgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKiogQHJldHVybnMgd2hldGhlciBwb2ludCB3YXMgZHJhZ2dlZCAqL1xuICBzdGF0aWMgaGFuZGxlUG9pbnREcmFnZ2luZyhcbiAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICAgc2NlbmVQb2ludGVyWDogbnVtYmVyLFxuICAgIHNjZW5lUG9pbnRlclk6IG51bWJlcixcbiAgICBtYXliZVN1Z2dlc3RCaW5kaW5nOiAoXG4gICAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICAgIHBvaW50U2NlbmVDb29yZHM6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfVtdLFxuICAgICkgPT4gdm9pZCxcbiAgICBsaW5lYXJFbGVtZW50RWRpdG9yOiBMaW5lYXJFbGVtZW50RWRpdG9yLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoIWxpbmVhckVsZW1lbnRFZGl0b3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB7IHNlbGVjdGVkUG9pbnRzSW5kaWNlcywgZWxlbWVudElkIH0gPSBsaW5lYXJFbGVtZW50RWRpdG9yO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldEVsZW1lbnQoZWxlbWVudElkKTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBwb2ludCB0aGF0J3MgYmVpbmcgZHJhZ2dlZCAob3V0IG9mIGFsbCBzZWxlY3RlZCBwb2ludHMpXG4gICAgY29uc3QgZHJhZ2dpbmdQb2ludCA9IGVsZW1lbnQucG9pbnRzW1xuICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5wb2ludGVyRG93blN0YXRlLmxhc3RDbGlja2VkUG9pbnRcbiAgICBdIGFzIFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQ7XG4gICAgaWYgKHNlbGVjdGVkUG9pbnRzSW5kaWNlcyAmJiBkcmFnZ2luZ1BvaW50KSB7XG4gICAgICBjb25zdCBuZXdEcmFnZ2luZ1BvaW50UG9zaXRpb24gPSBMaW5lYXJFbGVtZW50RWRpdG9yLmNyZWF0ZVBvaW50QXQoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHNjZW5lUG9pbnRlclggLSBsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJPZmZzZXQueCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSAtIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlck9mZnNldC55LFxuICAgICAgICBhcHBTdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGRlbHRhWCA9IG5ld0RyYWdnaW5nUG9pbnRQb3NpdGlvblswXSAtIGRyYWdnaW5nUG9pbnRbMF07XG4gICAgICBjb25zdCBkZWx0YVkgPSBuZXdEcmFnZ2luZ1BvaW50UG9zaXRpb25bMV0gLSBkcmFnZ2luZ1BvaW50WzFdO1xuXG4gICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLm1vdmVQb2ludHMoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlcy5tYXAoKHBvaW50SW5kZXgpID0+IHtcbiAgICAgICAgICBjb25zdCBuZXdQb2ludFBvc2l0aW9uID1cbiAgICAgICAgICAgIHBvaW50SW5kZXggPT09IGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50XG4gICAgICAgICAgICAgID8gTGluZWFyRWxlbWVudEVkaXRvci5jcmVhdGVQb2ludEF0KFxuICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgIHNjZW5lUG9pbnRlclggLSBsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJPZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSBsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJPZmZzZXQueSxcbiAgICAgICAgICAgICAgICAgIGFwcFN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgOiAoW1xuICAgICAgICAgICAgICAgICAgZWxlbWVudC5wb2ludHNbcG9pbnRJbmRleF1bMF0gKyBkZWx0YVgsXG4gICAgICAgICAgICAgICAgICBlbGVtZW50LnBvaW50c1twb2ludEluZGV4XVsxXSArIGRlbHRhWSxcbiAgICAgICAgICAgICAgICBdIGFzIGNvbnN0KTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaW5kZXg6IHBvaW50SW5kZXgsXG4gICAgICAgICAgICBwb2ludDogbmV3UG9pbnRQb3NpdGlvbixcbiAgICAgICAgICAgIGlzRHJhZ2dpbmc6XG4gICAgICAgICAgICAgIHBvaW50SW5kZXggPT09XG4gICAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50LFxuICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgLy8gc3VnZ2VzdCBiaW5kaW5ncyBmb3IgZmlyc3QgYW5kIGxhc3QgcG9pbnQgaWYgc2VsZWN0ZWRcbiAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGVsZW1lbnQsIGZhbHNlKSkge1xuICAgICAgICBjb25zdCBjb29yZHM6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfVtdID0gW107XG5cbiAgICAgICAgY29uc3QgZmlyc3RTZWxlY3RlZEluZGV4ID0gc2VsZWN0ZWRQb2ludHNJbmRpY2VzWzBdO1xuICAgICAgICBpZiAoZmlyc3RTZWxlY3RlZEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgY29vcmRzLnB1c2goXG4gICAgICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgIGVsZW1lbnQucG9pbnRzWzBdLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGFzdFNlbGVjdGVkSW5kZXggPVxuICAgICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlc1tzZWxlY3RlZFBvaW50c0luZGljZXMubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChsYXN0U2VsZWN0ZWRJbmRleCA9PT0gZWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIGNvb3Jkcy5wdXNoKFxuICAgICAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICBlbGVtZW50LnBvaW50c1tsYXN0U2VsZWN0ZWRJbmRleF0sXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29vcmRzLmxlbmd0aCkge1xuICAgICAgICAgIG1heWJlU3VnZ2VzdEJpbmRpbmcoZWxlbWVudCwgY29vcmRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzdGF0aWMgaGFuZGxlUG9pbnRlclVwKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IExpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICApOiBMaW5lYXJFbGVtZW50RWRpdG9yIHtcbiAgICBjb25zdCB7IGVsZW1lbnRJZCwgc2VsZWN0ZWRQb2ludHNJbmRpY2VzLCBpc0RyYWdnaW5nLCBwb2ludGVyRG93blN0YXRlIH0gPVxuICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ7XG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChlbGVtZW50SWQpO1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVkaXRpbmdMaW5lYXJFbGVtZW50O1xuICAgIH1cblxuICAgIGNvbnN0IGJpbmRpbmdzOiBQYXJ0aWFsPFxuICAgICAgUGljazxcbiAgICAgICAgSW5zdGFuY2VUeXBlPHR5cGVvZiBMaW5lYXJFbGVtZW50RWRpdG9yPixcbiAgICAgICAgXCJzdGFydEJpbmRpbmdFbGVtZW50XCIgfCBcImVuZEJpbmRpbmdFbGVtZW50XCJcbiAgICAgID5cbiAgICA+ID0ge307XG5cbiAgICBpZiAoaXNEcmFnZ2luZyAmJiBzZWxlY3RlZFBvaW50c0luZGljZXMpIHtcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0ZWRQb2ludCBvZiBzZWxlY3RlZFBvaW50c0luZGljZXMpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkUG9pbnQgPT09IDAgfHxcbiAgICAgICAgICBzZWxlY3RlZFBvaW50ID09PSBlbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChpc1BhdGhBTG9vcChlbGVtZW50LnBvaW50cywgYXBwU3RhdGUuem9vbS52YWx1ZSkpIHtcbiAgICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IubW92ZVBvaW50cyhlbGVtZW50LCBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpbmRleDogc2VsZWN0ZWRQb2ludCxcbiAgICAgICAgICAgICAgICBwb2ludDpcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkUG9pbnQgPT09IDBcbiAgICAgICAgICAgICAgICAgICAgPyBlbGVtZW50LnBvaW50c1tlbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXVxuICAgICAgICAgICAgICAgICAgICA6IGVsZW1lbnQucG9pbnRzWzBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgYmluZGluZ0VsZW1lbnQgPSBpc0JpbmRpbmdFbmFibGVkKGFwcFN0YXRlKVxuICAgICAgICAgICAgPyBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgICAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEF0SW5kZXhHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRQb2ludCEsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgU2NlbmUuZ2V0U2NlbmUoZWxlbWVudCkhLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICA6IG51bGw7XG5cbiAgICAgICAgICBiaW5kaW5nc1tcbiAgICAgICAgICAgIHNlbGVjdGVkUG9pbnQgPT09IDAgPyBcInN0YXJ0QmluZGluZ0VsZW1lbnRcIiA6IFwiZW5kQmluZGluZ0VsZW1lbnRcIlxuICAgICAgICAgIF0gPSBiaW5kaW5nRWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAuLi5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgIC4uLmJpbmRpbmdzLFxuICAgICAgLy8gaWYgY2xpY2tpbmcgd2l0aG91dCBwcmV2aW91c2x5IGRyYWdnaW5nIGEgcG9pbnQocyksIGFuZCBub3QgaG9sZGluZ1xuICAgICAgLy8gc2hpZnQsIGRlc2VsZWN0IGFsbCBwb2ludHMgZXhjZXB0IHRoZSBvbmUgY2xpY2tlZC4gSWYgaG9sZGluZyBzaGlmdCxcbiAgICAgIC8vIHRvZ2dsZSB0aGUgcG9pbnQuXG4gICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6XG4gICAgICAgIGlzRHJhZ2dpbmcgfHwgZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICA/ICFpc0RyYWdnaW5nICYmXG4gICAgICAgICAgICBldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5wcmV2U2VsZWN0ZWRQb2ludHNJbmRpY2VzPy5pbmNsdWRlcyhcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50LFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgPyBzZWxlY3RlZFBvaW50c0luZGljZXMgJiZcbiAgICAgICAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAocG9pbnRJbmRleCkgPT5cbiAgICAgICAgICAgICAgICAgIHBvaW50SW5kZXggIT09IHBvaW50ZXJEb3duU3RhdGUubGFzdENsaWNrZWRQb2ludCxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgOiBzZWxlY3RlZFBvaW50c0luZGljZXNcbiAgICAgICAgICA6IHNlbGVjdGVkUG9pbnRzSW5kaWNlcz8uaW5jbHVkZXMocG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50KVxuICAgICAgICAgID8gW3BvaW50ZXJEb3duU3RhdGUubGFzdENsaWNrZWRQb2ludF1cbiAgICAgICAgICA6IHNlbGVjdGVkUG9pbnRzSW5kaWNlcyxcbiAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxuICAgICAgcG9pbnRlck9mZnNldDogeyB4OiAwLCB5OiAwIH0sXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVQb2ludGVyRG93bihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICAgaGlzdG9yeTogSGlzdG9yeSxcbiAgICBzY2VuZVBvaW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSxcbiAgICBsaW5lYXJFbGVtZW50RWRpdG9yOiBMaW5lYXJFbGVtZW50RWRpdG9yLFxuICApOiB7XG4gICAgZGlkQWRkUG9pbnQ6IGJvb2xlYW47XG4gICAgaGl0RWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD4gfCBudWxsO1xuICAgIGxpbmVhckVsZW1lbnRFZGl0b3I6IExpbmVhckVsZW1lbnRFZGl0b3IgfCBudWxsO1xuICB9IHtcbiAgICBjb25zdCByZXQ6IFJldHVyblR5cGU8dHlwZW9mIExpbmVhckVsZW1lbnRFZGl0b3JbXCJoYW5kbGVQb2ludGVyRG93blwiXT4gPSB7XG4gICAgICBkaWRBZGRQb2ludDogZmFsc2UsXG4gICAgICBoaXRFbGVtZW50OiBudWxsLFxuICAgICAgbGluZWFyRWxlbWVudEVkaXRvcjogbnVsbCxcbiAgICB9O1xuXG4gICAgaWYgKCFsaW5lYXJFbGVtZW50RWRpdG9yKSB7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNvbnN0IHsgZWxlbWVudElkIH0gPSBsaW5lYXJFbGVtZW50RWRpdG9yO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldEVsZW1lbnQoZWxlbWVudElkKTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gICAgaWYgKGV2ZW50LmFsdEtleSAmJiBhcHBTdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgaWYgKGxpbmVhckVsZW1lbnRFZGl0b3IubGFzdFVuY29tbWl0dGVkUG9pbnQgPT0gbnVsbCkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgIC4uLmVsZW1lbnQucG9pbnRzLFxuICAgICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5jcmVhdGVQb2ludEF0KFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICAgICAgICAgIGFwcFN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICByZXQubGluZWFyRWxlbWVudEVkaXRvciA9IHtcbiAgICAgICAgLi4ubGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZToge1xuICAgICAgICAgIHByZXZTZWxlY3RlZFBvaW50c0luZGljZXM6IGxpbmVhckVsZW1lbnRFZGl0b3Iuc2VsZWN0ZWRQb2ludHNJbmRpY2VzLFxuICAgICAgICAgIGxhc3RDbGlja2VkUG9pbnQ6IC0xLFxuICAgICAgICB9LFxuICAgICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6IFtlbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgbGFzdFVuY29tbWl0dGVkUG9pbnQ6IG51bGwsXG4gICAgICAgIGVuZEJpbmRpbmdFbGVtZW50OiBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgICAgIFNjZW5lLmdldFNjZW5lKGVsZW1lbnQpISxcbiAgICAgICAgKSxcbiAgICAgIH07XG5cbiAgICAgIHJldC5kaWRBZGRQb2ludCA9IHRydWU7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNvbnN0IGNsaWNrZWRQb2ludEluZGV4ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEluZGV4VW5kZXJDdXJzb3IoXG4gICAgICBlbGVtZW50LFxuICAgICAgYXBwU3RhdGUuem9vbSxcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcblxuICAgIC8vIGlmIHdlIGNsaWNrZWQgb24gYSBwb2ludCwgc2V0IHRoZSBlbGVtZW50IGFzIGhpdEVsZW1lbnQgb3RoZXJ3aXNlXG4gICAgLy8gaXQgd291bGQgZ2V0IGRlc2VsZWN0ZWQgaWYgdGhlIHBvaW50IGlzIG91dHNpZGUgdGhlIGhpdGJveCBhcmVhXG4gICAgaWYgKGNsaWNrZWRQb2ludEluZGV4ID4gLTEpIHtcbiAgICAgIHJldC5oaXRFbGVtZW50ID0gZWxlbWVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gWW91IG1pZ2h0IGJlIHdhbmRlcmluZyB3aHkgd2UgYXJlIHN0b3JpbmcgdGhlIGJpbmRpbmcgZWxlbWVudHMgb25cbiAgICAgIC8vIExpbmVhckVsZW1lbnRFZGl0b3IgYW5kIHBhc3NpbmcgdGhlbSBpbiwgaW5zdGVhZCBvZiBjYWxjdWxhdGluZyB0aGVtXG4gICAgICAvLyBmcm9tIHRoZSBlbmQgcG9pbnRzIG9mIHRoZSBgbGluZWFyRWxlbWVudGAgLSB0aGlzIGlzIHRvIGFsbG93IGRpc2FibGluZ1xuICAgICAgLy8gYmluZGluZyAod2hpY2ggbmVlZHMgdG8gaGFwcGVuIGF0IHRoZSBwb2ludCB0aGUgdXNlciBmaW5pc2hlcyBtb3ZpbmdcbiAgICAgIC8vIHRoZSBwb2ludCkuXG4gICAgICBjb25zdCB7IHN0YXJ0QmluZGluZ0VsZW1lbnQsIGVuZEJpbmRpbmdFbGVtZW50IH0gPSBsaW5lYXJFbGVtZW50RWRpdG9yO1xuICAgICAgaWYgKGlzQmluZGluZ0VuYWJsZWQoYXBwU3RhdGUpICYmIGlzQmluZGluZ0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgYmluZE9yVW5iaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHN0YXJ0QmluZGluZ0VsZW1lbnQsXG4gICAgICAgICAgZW5kQmluZGluZ0VsZW1lbnQsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IGdldEVsZW1lbnRBYnNvbHV0ZUNvb3JkcyhlbGVtZW50KTtcbiAgICBjb25zdCBjeCA9ICh4MSArIHgyKSAvIDI7XG4gICAgY29uc3QgY3kgPSAoeTEgKyB5MikgLyAyO1xuICAgIGNvbnN0IHRhcmdldFBvaW50ID1cbiAgICAgIGNsaWNrZWRQb2ludEluZGV4ID4gLTEgJiZcbiAgICAgIHJvdGF0ZShcbiAgICAgICAgZWxlbWVudC54ICsgZWxlbWVudC5wb2ludHNbY2xpY2tlZFBvaW50SW5kZXhdWzBdLFxuICAgICAgICBlbGVtZW50LnkgKyBlbGVtZW50LnBvaW50c1tjbGlja2VkUG9pbnRJbmRleF1bMV0sXG4gICAgICAgIGN4LFxuICAgICAgICBjeSxcbiAgICAgICAgZWxlbWVudC5hbmdsZSxcbiAgICAgICk7XG5cbiAgICBjb25zdCBuZXh0U2VsZWN0ZWRQb2ludHNJbmRpY2VzID1cbiAgICAgIGNsaWNrZWRQb2ludEluZGV4ID4gLTEgfHwgZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgPyBldmVudC5zaGlmdEtleSB8fFxuICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3Iuc2VsZWN0ZWRQb2ludHNJbmRpY2VzPy5pbmNsdWRlcyhjbGlja2VkUG9pbnRJbmRleClcbiAgICAgICAgICA/IG5vcm1hbGl6ZVNlbGVjdGVkUG9pbnRzKFtcbiAgICAgICAgICAgICAgLi4uKGxpbmVhckVsZW1lbnRFZGl0b3Iuc2VsZWN0ZWRQb2ludHNJbmRpY2VzIHx8IFtdKSxcbiAgICAgICAgICAgICAgY2xpY2tlZFBvaW50SW5kZXgsXG4gICAgICAgICAgICBdKVxuICAgICAgICAgIDogW2NsaWNrZWRQb2ludEluZGV4XVxuICAgICAgICA6IG51bGw7XG4gICAgcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgPSB7XG4gICAgICAuLi5saW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgcG9pbnRlckRvd25TdGF0ZToge1xuICAgICAgICBwcmV2U2VsZWN0ZWRQb2ludHNJbmRpY2VzOiBsaW5lYXJFbGVtZW50RWRpdG9yLnNlbGVjdGVkUG9pbnRzSW5kaWNlcyxcbiAgICAgICAgbGFzdENsaWNrZWRQb2ludDogY2xpY2tlZFBvaW50SW5kZXgsXG4gICAgICB9LFxuICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzOiBuZXh0U2VsZWN0ZWRQb2ludHNJbmRpY2VzLFxuICAgICAgcG9pbnRlck9mZnNldDogdGFyZ2V0UG9pbnRcbiAgICAgICAgPyB7XG4gICAgICAgICAgICB4OiBzY2VuZVBvaW50ZXIueCAtIHRhcmdldFBvaW50WzBdLFxuICAgICAgICAgICAgeTogc2NlbmVQb2ludGVyLnkgLSB0YXJnZXRQb2ludFsxXSxcbiAgICAgICAgICB9XG4gICAgICAgIDogeyB4OiAwLCB5OiAwIH0sXG4gICAgfTtcblxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICBzdGF0aWMgaGFuZGxlUG9pbnRlck1vdmUoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgc2NlbmVQb2ludGVyWDogbnVtYmVyLFxuICAgIHNjZW5lUG9pbnRlclk6IG51bWJlcixcbiAgICBsaW5lYXJFbGVtZW50RWRpdG9yOiBMaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgIGdyaWRTaXplOiBudW1iZXIgfCBudWxsLFxuICApOiBMaW5lYXJFbGVtZW50RWRpdG9yIHtcbiAgICBjb25zdCB7IGVsZW1lbnRJZCwgbGFzdFVuY29tbWl0dGVkUG9pbnQgfSA9IGxpbmVhckVsZW1lbnRFZGl0b3I7XG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChlbGVtZW50SWQpO1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGxpbmVhckVsZW1lbnRFZGl0b3I7XG4gICAgfVxuXG4gICAgY29uc3QgeyBwb2ludHMgfSA9IGVsZW1lbnQ7XG4gICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcblxuICAgIGlmICghZXZlbnQuYWx0S2V5KSB7XG4gICAgICBpZiAobGFzdFBvaW50ID09PSBsYXN0VW5jb21taXR0ZWRQb2ludCkge1xuICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmRlbGV0ZVBvaW50cyhlbGVtZW50LCBbcG9pbnRzLmxlbmd0aCAtIDFdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IC4uLmxpbmVhckVsZW1lbnRFZGl0b3IsIGxhc3RVbmNvbW1pdHRlZFBvaW50OiBudWxsIH07XG4gICAgfVxuXG4gICAgY29uc3QgbmV3UG9pbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmNyZWF0ZVBvaW50QXQoXG4gICAgICBlbGVtZW50LFxuICAgICAgc2NlbmVQb2ludGVyWCAtIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlck9mZnNldC54LFxuICAgICAgc2NlbmVQb2ludGVyWSAtIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlck9mZnNldC55LFxuICAgICAgZ3JpZFNpemUsXG4gICAgKTtcblxuICAgIGlmIChsYXN0UG9pbnQgPT09IGxhc3RVbmNvbW1pdHRlZFBvaW50KSB7XG4gICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLm1vdmVQb2ludHMoZWxlbWVudCwgW1xuICAgICAgICB7XG4gICAgICAgICAgaW5kZXg6IGVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDEsXG4gICAgICAgICAgcG9pbnQ6IG5ld1BvaW50LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuYWRkUG9pbnRzKGVsZW1lbnQsIFt7IHBvaW50OiBuZXdQb2ludCB9XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICBsYXN0VW5jb21taXR0ZWRQb2ludDogZWxlbWVudC5wb2ludHNbZWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBzY2VuZSBjb29yZHMgKi9cbiAgc3RhdGljIGdldFBvaW50R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgcG9pbnQ6IFBvaW50LFxuICApIHtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0RWxlbWVudEFic29sdXRlQ29vcmRzKGVsZW1lbnQpO1xuICAgIGNvbnN0IGN4ID0gKHgxICsgeDIpIC8gMjtcbiAgICBjb25zdCBjeSA9ICh5MSArIHkyKSAvIDI7XG5cbiAgICBsZXQgeyB4LCB5IH0gPSBlbGVtZW50O1xuICAgIFt4LCB5XSA9IHJvdGF0ZSh4ICsgcG9pbnRbMF0sIHkgKyBwb2ludFsxXSwgY3gsIGN5LCBlbGVtZW50LmFuZ2xlKTtcbiAgICByZXR1cm4gW3gsIHldIGFzIGNvbnN0O1xuICB9XG5cbiAgLyoqIHNjZW5lIGNvb3JkcyAqL1xuICBzdGF0aWMgZ2V0UG9pbnRzR2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICkge1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRFbGVtZW50QWJzb2x1dGVDb29yZHMoZWxlbWVudCk7XG4gICAgY29uc3QgY3ggPSAoeDEgKyB4MikgLyAyO1xuICAgIGNvbnN0IGN5ID0gKHkxICsgeTIpIC8gMjtcbiAgICByZXR1cm4gZWxlbWVudC5wb2ludHMubWFwKChwb2ludCkgPT4ge1xuICAgICAgbGV0IHsgeCwgeSB9ID0gZWxlbWVudDtcbiAgICAgIFt4LCB5XSA9IHJvdGF0ZSh4ICsgcG9pbnRbMF0sIHkgKyBwb2ludFsxXSwgY3gsIGN5LCBlbGVtZW50LmFuZ2xlKTtcbiAgICAgIHJldHVybiBbeCwgeV07XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0UG9pbnRBdEluZGV4R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgaW5kZXhNYXliZUZyb21FbmQ6IG51bWJlciwgLy8gLTEgZm9yIGxhc3QgZWxlbWVudFxuICApOiBQb2ludCB7XG4gICAgY29uc3QgaW5kZXggPVxuICAgICAgaW5kZXhNYXliZUZyb21FbmQgPCAwXG4gICAgICAgID8gZWxlbWVudC5wb2ludHMubGVuZ3RoICsgaW5kZXhNYXliZUZyb21FbmRcbiAgICAgICAgOiBpbmRleE1heWJlRnJvbUVuZDtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0RWxlbWVudEFic29sdXRlQ29vcmRzKGVsZW1lbnQpO1xuICAgIGNvbnN0IGN4ID0gKHgxICsgeDIpIC8gMjtcbiAgICBjb25zdCBjeSA9ICh5MSArIHkyKSAvIDI7XG5cbiAgICBjb25zdCBwb2ludCA9IGVsZW1lbnQucG9pbnRzW2luZGV4XTtcbiAgICBjb25zdCB7IHgsIHkgfSA9IGVsZW1lbnQ7XG4gICAgcmV0dXJuIHJvdGF0ZSh4ICsgcG9pbnRbMF0sIHkgKyBwb2ludFsxXSwgY3gsIGN5LCBlbGVtZW50LmFuZ2xlKTtcbiAgfVxuXG4gIHN0YXRpYyBwb2ludEZyb21BYnNvbHV0ZUNvb3JkcyhcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICBhYnNvbHV0ZUNvb3JkczogUG9pbnQsXG4gICk6IFBvaW50IHtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0RWxlbWVudEFic29sdXRlQ29vcmRzKGVsZW1lbnQpO1xuICAgIGNvbnN0IGN4ID0gKHgxICsgeDIpIC8gMjtcbiAgICBjb25zdCBjeSA9ICh5MSArIHkyKSAvIDI7XG4gICAgY29uc3QgW3gsIHldID0gcm90YXRlKFxuICAgICAgYWJzb2x1dGVDb29yZHNbMF0sXG4gICAgICBhYnNvbHV0ZUNvb3Jkc1sxXSxcbiAgICAgIGN4LFxuICAgICAgY3ksXG4gICAgICAtZWxlbWVudC5hbmdsZSxcbiAgICApO1xuICAgIHJldHVybiBbeCAtIGVsZW1lbnQueCwgeSAtIGVsZW1lbnQueV07XG4gIH1cblxuICBzdGF0aWMgZ2V0UG9pbnRJbmRleFVuZGVyQ3Vyc29yKFxuICAgIGVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIHpvb206IEFwcFN0YXRlW1wiem9vbVwiXSxcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBwb2ludEhhbmRsZXMgPSB0aGlzLmdldFBvaW50c0dsb2JhbENvb3JkaW5hdGVzKGVsZW1lbnQpO1xuICAgIGxldCBpZHggPSBwb2ludEhhbmRsZXMubGVuZ3RoO1xuICAgIC8vIGxvb3AgZnJvbSByaWdodCB0byBsZWZ0IGJlY2F1c2UgcG9pbnRzIG9uIHRoZSByaWdodCBhcmUgcmVuZGVyZWQgb3ZlclxuICAgIC8vIHBvaW50cyBvbiB0aGUgbGVmdCwgdGh1cyBzaG91bGQgdGFrZSBwcmVjZWRlbmNlIHdoZW4gY2xpY2tpbmcsIGlmIHRoZXlcbiAgICAvLyBvdmVybGFwXG4gICAgd2hpbGUgKC0taWR4ID4gLTEpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRIYW5kbGVzW2lkeF07XG4gICAgICBpZiAoXG4gICAgICAgIGRpc3RhbmNlMmQoeCwgeSwgcG9pbnRbMF0sIHBvaW50WzFdKSAqIHpvb20udmFsdWUgPFxuICAgICAgICAvLyArMXB4IHRvIGFjY291bnQgZm9yIG91dGxpbmUgc3Ryb2tlXG4gICAgICAgIHRoaXMuUE9JTlRfSEFORExFX1NJWkUgKyAxXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGlkeDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVBvaW50QXQoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgc2NlbmVQb2ludGVyWDogbnVtYmVyLFxuICAgIHNjZW5lUG9pbnRlclk6IG51bWJlcixcbiAgICBncmlkU2l6ZTogbnVtYmVyIHwgbnVsbCxcbiAgKTogUG9pbnQge1xuICAgIGNvbnN0IHBvaW50ZXJPbkdyaWQgPSBnZXRHcmlkUG9pbnQoc2NlbmVQb2ludGVyWCwgc2NlbmVQb2ludGVyWSwgZ3JpZFNpemUpO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRFbGVtZW50QWJzb2x1dGVDb29yZHMoZWxlbWVudCk7XG4gICAgY29uc3QgY3ggPSAoeDEgKyB4MikgLyAyO1xuICAgIGNvbnN0IGN5ID0gKHkxICsgeTIpIC8gMjtcbiAgICBjb25zdCBbcm90YXRlZFgsIHJvdGF0ZWRZXSA9IHJvdGF0ZShcbiAgICAgIHBvaW50ZXJPbkdyaWRbMF0sXG4gICAgICBwb2ludGVyT25HcmlkWzFdLFxuICAgICAgY3gsXG4gICAgICBjeSxcbiAgICAgIC1lbGVtZW50LmFuZ2xlLFxuICAgICk7XG5cbiAgICByZXR1cm4gW3JvdGF0ZWRYIC0gZWxlbWVudC54LCByb3RhdGVkWSAtIGVsZW1lbnQueV07XG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBsaW5lIHBvaW50cyBzbyB0aGF0IHRoZSBzdGFydCBwb2ludCBpcyBhdCBbMCwwXS4gVGhpcyBpc1xuICAgKiBleHBlY3RlZCBpbiB2YXJpb3VzIHBhcnRzIG9mIHRoZSBjb2RlYmFzZS4gQWxzbyByZXR1cm5zIG5ldyB4L3kgdG8gYWNjb3VudFxuICAgKiBmb3IgdGhlIHBvdGVudGlhbCBub3JtYWxpemF0aW9uLlxuICAgKi9cbiAgc3RhdGljIGdldE5vcm1hbGl6ZWRQb2ludHMoZWxlbWVudDogRXhjYWxpZHJhd0xpbmVhckVsZW1lbnQpIHtcbiAgICBjb25zdCB7IHBvaW50cyB9ID0gZWxlbWVudDtcblxuICAgIGNvbnN0IG9mZnNldFggPSBwb2ludHNbMF1bMF07XG4gICAgY29uc3Qgb2Zmc2V0WSA9IHBvaW50c1swXVsxXTtcblxuICAgIHJldHVybiB7XG4gICAgICBwb2ludHM6IHBvaW50cy5tYXAoKHBvaW50LCBfaWR4KSA9PiB7XG4gICAgICAgIHJldHVybiBbcG9pbnRbMF0gLSBvZmZzZXRYLCBwb2ludFsxXSAtIG9mZnNldFldIGFzIGNvbnN0O1xuICAgICAgfSksXG4gICAgICB4OiBlbGVtZW50LnggKyBvZmZzZXRYLFxuICAgICAgeTogZWxlbWVudC55ICsgb2Zmc2V0WSxcbiAgICB9O1xuICB9XG5cbiAgLy8gZWxlbWVudC1tdXRhdGluZyBtZXRob2RzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHN0YXRpYyBub3JtYWxpemVQb2ludHMoZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4pIHtcbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0Tm9ybWFsaXplZFBvaW50cyhlbGVtZW50KSk7XG4gIH1cblxuICBzdGF0aWMgZHVwbGljYXRlU2VsZWN0ZWRQb2ludHMoYXBwU3RhdGU6IEFwcFN0YXRlKSB7XG4gICAgaWYgKCFhcHBTdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHsgc2VsZWN0ZWRQb2ludHNJbmRpY2VzLCBlbGVtZW50SWQgfSA9IGFwcFN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50O1xuXG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChlbGVtZW50SWQpO1xuXG4gICAgaWYgKCFlbGVtZW50IHx8IHNlbGVjdGVkUG9pbnRzSW5kaWNlcyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHsgcG9pbnRzIH0gPSBlbGVtZW50O1xuXG4gICAgY29uc3QgbmV4dFNlbGVjdGVkSW5kaWNlczogbnVtYmVyW10gPSBbXTtcblxuICAgIGxldCBwb2ludEFkZGVkVG9FbmQgPSBmYWxzZTtcbiAgICBsZXQgaW5kZXhDdXJzb3IgPSAtMTtcbiAgICBjb25zdCBuZXh0UG9pbnRzID0gcG9pbnRzLnJlZHVjZSgoYWNjOiBQb2ludFtdLCBwb2ludCwgaW5kZXgpID0+IHtcbiAgICAgICsraW5kZXhDdXJzb3I7XG4gICAgICBhY2MucHVzaChwb2ludCk7XG5cbiAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSBzZWxlY3RlZFBvaW50c0luZGljZXMuaW5jbHVkZXMoaW5kZXgpO1xuICAgICAgaWYgKGlzU2VsZWN0ZWQpIHtcbiAgICAgICAgY29uc3QgbmV4dFBvaW50ID0gcG9pbnRzW2luZGV4ICsgMV07XG5cbiAgICAgICAgaWYgKCFuZXh0UG9pbnQpIHtcbiAgICAgICAgICBwb2ludEFkZGVkVG9FbmQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGFjYy5wdXNoKFxuICAgICAgICAgIG5leHRQb2ludFxuICAgICAgICAgICAgPyBbKHBvaW50WzBdICsgbmV4dFBvaW50WzBdKSAvIDIsIChwb2ludFsxXSArIG5leHRQb2ludFsxXSkgLyAyXVxuICAgICAgICAgICAgOiBbcG9pbnRbMF0sIHBvaW50WzFdXSxcbiAgICAgICAgKTtcblxuICAgICAgICBuZXh0U2VsZWN0ZWRJbmRpY2VzLnB1c2goaW5kZXhDdXJzb3IgKyAxKTtcbiAgICAgICAgKytpbmRleEN1cnNvcjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHsgcG9pbnRzOiBuZXh0UG9pbnRzIH0pO1xuXG4gICAgLy8gdGVtcCBoYWNrIHRvIGVuc3VyZSB0aGUgbGluZSBkb2Vzbid0IG1vdmUgd2hlbiBhZGRpbmcgcG9pbnQgdG8gdGhlIGVuZCxcbiAgICAvLyBwb3RlbnRpYWxseSBleHBhbmRpbmcgdGhlIGJvdW5kaW5nIGJveFxuICAgIGlmIChwb2ludEFkZGVkVG9FbmQpIHtcbiAgICAgIGNvbnN0IGxhc3RQb2ludCA9IGVsZW1lbnQucG9pbnRzW2VsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5tb3ZlUG9pbnRzKGVsZW1lbnQsIFtcbiAgICAgICAge1xuICAgICAgICAgIGluZGV4OiBlbGVtZW50LnBvaW50cy5sZW5ndGggLSAxLFxuICAgICAgICAgIHBvaW50OiBbbGFzdFBvaW50WzBdICsgMzAsIGxhc3RQb2ludFsxXSArIDMwXSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhcHBTdGF0ZToge1xuICAgICAgICAuLi5hcHBTdGF0ZSxcbiAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAuLi5hcHBTdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6IG5leHRTZWxlY3RlZEluZGljZXMsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBzdGF0aWMgZGVsZXRlUG9pbnRzKFxuICAgIGVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIHBvaW50SW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICkge1xuICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICBjb25zdCBpc0RlbGV0aW5nT3JpZ2luUG9pbnQgPSBwb2ludEluZGljZXMuaW5jbHVkZXMoMCk7XG5cbiAgICAvLyBpZiBkZWxldGluZyBmaXJzdCBwb2ludCwgbWFrZSB0aGUgbmV4dCB0byBiZSBbMCwwXSBhbmQgcmVjYWxjdWxhdGVcbiAgICAvLyBwb3NpdGlvbnMgb2YgdGhlIHJlc3Qgd2l0aCByZXNwZWN0IHRvIGl0XG4gICAgaWYgKGlzRGVsZXRpbmdPcmlnaW5Qb2ludCkge1xuICAgICAgY29uc3QgZmlyc3ROb25EZWxldGVkUG9pbnQgPSBlbGVtZW50LnBvaW50cy5maW5kKChwb2ludCwgaWR4KSA9PiB7XG4gICAgICAgIHJldHVybiAhcG9pbnRJbmRpY2VzLmluY2x1ZGVzKGlkeCk7XG4gICAgICB9KTtcbiAgICAgIGlmIChmaXJzdE5vbkRlbGV0ZWRQb2ludCkge1xuICAgICAgICBvZmZzZXRYID0gZmlyc3ROb25EZWxldGVkUG9pbnRbMF07XG4gICAgICAgIG9mZnNldFkgPSBmaXJzdE5vbkRlbGV0ZWRQb2ludFsxXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBuZXh0UG9pbnRzID0gZWxlbWVudC5wb2ludHMucmVkdWNlKChhY2M6IFBvaW50W10sIHBvaW50LCBpZHgpID0+IHtcbiAgICAgIGlmICghcG9pbnRJbmRpY2VzLmluY2x1ZGVzKGlkeCkpIHtcbiAgICAgICAgYWNjLnB1c2goXG4gICAgICAgICAgIWFjYy5sZW5ndGggPyBbMCwgMF0gOiBbcG9pbnRbMF0gLSBvZmZzZXRYLCBwb2ludFsxXSAtIG9mZnNldFldLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICBMaW5lYXJFbGVtZW50RWRpdG9yLl91cGRhdGVQb2ludHMoZWxlbWVudCwgbmV4dFBvaW50cywgb2Zmc2V0WCwgb2Zmc2V0WSk7XG4gIH1cblxuICBzdGF0aWMgYWRkUG9pbnRzKFxuICAgIGVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIHRhcmdldFBvaW50czogeyBwb2ludDogUG9pbnQgfVtdLFxuICApIHtcbiAgICBjb25zdCBvZmZzZXRYID0gMDtcbiAgICBjb25zdCBvZmZzZXRZID0gMDtcblxuICAgIGNvbnN0IG5leHRQb2ludHMgPSBbLi4uZWxlbWVudC5wb2ludHMsIC4uLnRhcmdldFBvaW50cy5tYXAoKHgpID0+IHgucG9pbnQpXTtcblxuICAgIExpbmVhckVsZW1lbnRFZGl0b3IuX3VwZGF0ZVBvaW50cyhlbGVtZW50LCBuZXh0UG9pbnRzLCBvZmZzZXRYLCBvZmZzZXRZKTtcbiAgfVxuXG4gIHN0YXRpYyBtb3ZlUG9pbnRzKFxuICAgIGVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIHRhcmdldFBvaW50czogeyBpbmRleDogbnVtYmVyOyBwb2ludDogUG9pbnQ7IGlzRHJhZ2dpbmc/OiBib29sZWFuIH1bXSxcbiAgICBvdGhlclVwZGF0ZXM/OiB7IHN0YXJ0QmluZGluZz86IFBvaW50QmluZGluZzsgZW5kQmluZGluZz86IFBvaW50QmluZGluZyB9LFxuICApIHtcbiAgICBjb25zdCB7IHBvaW50cyB9ID0gZWxlbWVudDtcblxuICAgIC8vIGluIGNhc2Ugd2UncmUgbW92aW5nIHN0YXJ0IHBvaW50LCBpbnN0ZWFkIG9mIG1vZGlmeWluZyBpdHMgcG9zaXRpb25cbiAgICAvLyB3aGljaCB3b3VsZCBicmVhayB0aGUgaW52YXJpYW50IG9mIGl0IGJlaW5nIGF0IFswLDBdLCB3ZSBtb3ZlXG4gICAgLy8gYWxsIHRoZSBvdGhlciBwb2ludHMgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiBieSBkZWx0YSB0b1xuICAgIC8vIG9mZnNldCBpdC4gV2UgZG8gdGhlIHNhbWUgd2l0aCBhY3R1YWwgZWxlbWVudC54L3kgcG9zaXRpb24sIHNvXG4gICAgLy8gdGhpcyBoYWNrcyBhcmUgY29tcGxldGVseSB0cmFuc3BhcmVudCB0byB0aGUgdXNlci5cbiAgICBsZXQgb2Zmc2V0WCA9IDA7XG4gICAgbGV0IG9mZnNldFkgPSAwO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRPcmlnaW5Qb2ludCA9IHRhcmdldFBvaW50cy5maW5kKCh7IGluZGV4IH0pID0+IGluZGV4ID09PSAwKTtcblxuICAgIGlmIChzZWxlY3RlZE9yaWdpblBvaW50KSB7XG4gICAgICBvZmZzZXRYID1cbiAgICAgICAgc2VsZWN0ZWRPcmlnaW5Qb2ludC5wb2ludFswXSAtIHBvaW50c1tzZWxlY3RlZE9yaWdpblBvaW50LmluZGV4XVswXTtcbiAgICAgIG9mZnNldFkgPVxuICAgICAgICBzZWxlY3RlZE9yaWdpblBvaW50LnBvaW50WzFdIC0gcG9pbnRzW3NlbGVjdGVkT3JpZ2luUG9pbnQuaW5kZXhdWzFdO1xuICAgIH1cblxuICAgIGNvbnN0IG5leHRQb2ludHMgPSBwb2ludHMubWFwKChwb2ludCwgaWR4KSA9PiB7XG4gICAgICBjb25zdCBzZWxlY3RlZFBvaW50RGF0YSA9IHRhcmdldFBvaW50cy5maW5kKChwKSA9PiBwLmluZGV4ID09PSBpZHgpO1xuICAgICAgaWYgKHNlbGVjdGVkUG9pbnREYXRhKSB7XG4gICAgICAgIGlmIChzZWxlY3RlZE9yaWdpblBvaW50KSB7XG4gICAgICAgICAgcmV0dXJuIHBvaW50O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGVsdGFYID1cbiAgICAgICAgICBzZWxlY3RlZFBvaW50RGF0YS5wb2ludFswXSAtIHBvaW50c1tzZWxlY3RlZFBvaW50RGF0YS5pbmRleF1bMF07XG4gICAgICAgIGNvbnN0IGRlbHRhWSA9XG4gICAgICAgICAgc2VsZWN0ZWRQb2ludERhdGEucG9pbnRbMV0gLSBwb2ludHNbc2VsZWN0ZWRQb2ludERhdGEuaW5kZXhdWzFdO1xuXG4gICAgICAgIHJldHVybiBbcG9pbnRbMF0gKyBkZWx0YVgsIHBvaW50WzFdICsgZGVsdGFZXSBhcyBjb25zdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvZmZzZXRYIHx8IG9mZnNldFlcbiAgICAgICAgPyAoW3BvaW50WzBdIC0gb2Zmc2V0WCwgcG9pbnRbMV0gLSBvZmZzZXRZXSBhcyBjb25zdClcbiAgICAgICAgOiBwb2ludDtcbiAgICB9KTtcblxuICAgIExpbmVhckVsZW1lbnRFZGl0b3IuX3VwZGF0ZVBvaW50cyhcbiAgICAgIGVsZW1lbnQsXG4gICAgICBuZXh0UG9pbnRzLFxuICAgICAgb2Zmc2V0WCxcbiAgICAgIG9mZnNldFksXG4gICAgICBvdGhlclVwZGF0ZXMsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIF91cGRhdGVQb2ludHMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgbmV4dFBvaW50czogcmVhZG9ubHkgUG9pbnRbXSxcbiAgICBvZmZzZXRYOiBudW1iZXIsXG4gICAgb2Zmc2V0WTogbnVtYmVyLFxuICAgIG90aGVyVXBkYXRlcz86IHsgc3RhcnRCaW5kaW5nPzogUG9pbnRCaW5kaW5nOyBlbmRCaW5kaW5nPzogUG9pbnRCaW5kaW5nIH0sXG4gICkge1xuICAgIGNvbnN0IG5leHRDb29yZHMgPSBnZXRFbGVtZW50UG9pbnRzQ29vcmRzKFxuICAgICAgZWxlbWVudCxcbiAgICAgIG5leHRQb2ludHMsXG4gICAgICBlbGVtZW50LnN0cm9rZVNoYXJwbmVzcyB8fCBcInJvdW5kXCIsXG4gICAgKTtcbiAgICBjb25zdCBwcmV2Q29vcmRzID0gZ2V0RWxlbWVudFBvaW50c0Nvb3JkcyhcbiAgICAgIGVsZW1lbnQsXG4gICAgICBlbGVtZW50LnBvaW50cyxcbiAgICAgIGVsZW1lbnQuc3Ryb2tlU2hhcnBuZXNzIHx8IFwicm91bmRcIixcbiAgICApO1xuICAgIGNvbnN0IG5leHRDZW50ZXJYID0gKG5leHRDb29yZHNbMF0gKyBuZXh0Q29vcmRzWzJdKSAvIDI7XG4gICAgY29uc3QgbmV4dENlbnRlclkgPSAobmV4dENvb3Jkc1sxXSArIG5leHRDb29yZHNbM10pIC8gMjtcbiAgICBjb25zdCBwcmV2Q2VudGVyWCA9IChwcmV2Q29vcmRzWzBdICsgcHJldkNvb3Jkc1syXSkgLyAyO1xuICAgIGNvbnN0IHByZXZDZW50ZXJZID0gKHByZXZDb29yZHNbMV0gKyBwcmV2Q29vcmRzWzNdKSAvIDI7XG4gICAgY29uc3QgZFggPSBwcmV2Q2VudGVyWCAtIG5leHRDZW50ZXJYO1xuICAgIGNvbnN0IGRZID0gcHJldkNlbnRlclkgLSBuZXh0Q2VudGVyWTtcbiAgICBjb25zdCByb3RhdGVkID0gcm90YXRlKG9mZnNldFgsIG9mZnNldFksIGRYLCBkWSwgZWxlbWVudC5hbmdsZSk7XG5cbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIC4uLm90aGVyVXBkYXRlcyxcbiAgICAgIHBvaW50czogbmV4dFBvaW50cyxcbiAgICAgIHg6IGVsZW1lbnQueCArIHJvdGF0ZWRbMF0sXG4gICAgICB5OiBlbGVtZW50LnkgKyByb3RhdGVkWzFdLFxuICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IG5vcm1hbGl6ZVNlbGVjdGVkUG9pbnRzID0gKFxuICBwb2ludHM6IChudW1iZXIgfCBudWxsKVtdLFxuKTogbnVtYmVyW10gfCBudWxsID0+IHtcbiAgbGV0IG5leHRQb2ludHMgPSBbXG4gICAgLi4ubmV3IFNldChwb2ludHMuZmlsdGVyKChwKSA9PiBwICE9PSBudWxsICYmIHAgIT09IC0xKSksXG4gIF0gYXMgbnVtYmVyW107XG4gIG5leHRQb2ludHMgPSBuZXh0UG9pbnRzLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgcmV0dXJuIG5leHRQb2ludHMubGVuZ3RoID8gbmV4dFBvaW50cyA6IG51bGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../element/linearElementEditor.ts\n");
2857
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"LinearElementEditor\": () => (/* binding */ LinearElementEditor)\n/* harmony export */ });\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! . */ \"../../element/index.ts\");\n/* harmony import */ var _bounds__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _binding__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./binding */ \"../../element/binding.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n\n\n\n\n\n\n\n\n\nclass LinearElementEditor {\n constructor(element, scene) {\n this.elementId = element.id;\n _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].mapElementToScene(this.elementId, scene);\n LinearElementEditor.normalizePoints(element);\n this.selectedPointsIndices = null;\n this.lastUncommittedPoint = null;\n this.isDragging = false;\n this.pointerOffset = { x: 0, y: 0 };\n this.startBindingElement = \"keep\";\n this.endBindingElement = \"keep\";\n this.pointerDownState = {\n prevSelectedPointsIndices: null,\n lastClickedPoint: -1,\n };\n this.hoverPointIndex = -1;\n }\n /**\n * @param id the `elementId` from the instance of this class (so that we can\n * statically guarantee this method returns an ExcalidrawLinearElement)\n */\n static getElement(id) {\n var _a;\n const element = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(id)) === null || _a === void 0 ? void 0 : _a.getNonDeletedElement(id);\n if (element) {\n return element;\n }\n return null;\n }\n static handleBoxSelection(event, appState, setState) {\n var _a;\n if (!appState.editingLinearElement ||\n ((_a = appState.draggingElement) === null || _a === void 0 ? void 0 : _a.type) !== \"selection\") {\n return false;\n }\n const { editingLinearElement } = appState;\n const { selectedPointsIndices, elementId } = editingLinearElement;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return false;\n }\n const [selectionX1, selectionY1, selectionX2, selectionY2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(appState.draggingElement);\n const pointsSceneCoords = LinearElementEditor.getPointsGlobalCoordinates(element);\n const nextSelectedPoints = pointsSceneCoords.reduce((acc, point, index) => {\n if ((point[0] >= selectionX1 &&\n point[0] <= selectionX2 &&\n point[1] >= selectionY1 &&\n point[1] <= selectionY2) ||\n (event.shiftKey && (selectedPointsIndices === null || selectedPointsIndices === void 0 ? void 0 : selectedPointsIndices.includes(index)))) {\n acc.push(index);\n }\n return acc;\n }, []);\n setState({\n editingLinearElement: Object.assign(Object.assign({}, editingLinearElement), { selectedPointsIndices: nextSelectedPoints.length\n ? nextSelectedPoints\n : null }),\n });\n }\n /** @returns whether point was dragged */\n static handlePointDragging(event, appState, scenePointerX, scenePointerY, maybeSuggestBinding, linearElementEditor) {\n if (!linearElementEditor) {\n return false;\n }\n const { selectedPointsIndices, elementId } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return false;\n }\n // point that's being dragged (out of all selected points)\n const draggingPoint = element.points[linearElementEditor.pointerDownState.lastClickedPoint];\n if (selectedPointsIndices && draggingPoint) {\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_8__.shouldRotateWithDiscreteAngle)(event) &&\n selectedPointsIndices.length === 1 &&\n element.points.length > 1) {\n const selectedIndex = selectedPointsIndices[0];\n const referencePoint = element.points[selectedIndex === 0 ? 1 : selectedIndex - 1];\n const [width, height] = LinearElementEditor._getShiftLockedDelta(element, referencePoint, [scenePointerX, scenePointerY], appState.gridSize);\n LinearElementEditor.movePoints(element, [\n {\n index: selectedIndex,\n point: [width + referencePoint[0], height + referencePoint[1]],\n isDragging: selectedIndex ===\n linearElementEditor.pointerDownState.lastClickedPoint,\n },\n ]);\n }\n else {\n const newDraggingPointPosition = LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, appState.gridSize);\n const deltaX = newDraggingPointPosition[0] - draggingPoint[0];\n const deltaY = newDraggingPointPosition[1] - draggingPoint[1];\n LinearElementEditor.movePoints(element, selectedPointsIndices.map((pointIndex) => {\n const newPointPosition = pointIndex ===\n linearElementEditor.pointerDownState.lastClickedPoint\n ? LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, appState.gridSize)\n : [\n element.points[pointIndex][0] + deltaX,\n element.points[pointIndex][1] + deltaY,\n ];\n return {\n index: pointIndex,\n point: newPointPosition,\n isDragging: pointIndex ===\n linearElementEditor.pointerDownState.lastClickedPoint,\n };\n }));\n }\n // suggest bindings for first and last point if selected\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_7__.isBindingElement)(element, false)) {\n const coords = [];\n const firstSelectedIndex = selectedPointsIndices[0];\n if (firstSelectedIndex === 0) {\n coords.push((0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(LinearElementEditor.getPointGlobalCoordinates(element, element.points[0])));\n }\n const lastSelectedIndex = selectedPointsIndices[selectedPointsIndices.length - 1];\n if (lastSelectedIndex === element.points.length - 1) {\n coords.push((0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(LinearElementEditor.getPointGlobalCoordinates(element, element.points[lastSelectedIndex])));\n }\n if (coords.length) {\n maybeSuggestBinding(element, coords);\n }\n }\n return true;\n }\n return false;\n }\n static handlePointerUp(event, editingLinearElement, appState) {\n var _a;\n const { elementId, selectedPointsIndices, isDragging, pointerDownState } = editingLinearElement;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return editingLinearElement;\n }\n const bindings = {};\n if (isDragging && selectedPointsIndices) {\n for (const selectedPoint of selectedPointsIndices) {\n if (selectedPoint === 0 ||\n selectedPoint === element.points.length - 1) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_0__.isPathALoop)(element.points, appState.zoom.value)) {\n LinearElementEditor.movePoints(element, [\n {\n index: selectedPoint,\n point: selectedPoint === 0\n ? element.points[element.points.length - 1]\n : element.points[0],\n },\n ]);\n }\n const bindingElement = (0,_binding__WEBPACK_IMPORTED_MODULE_5__.isBindingEnabled)(appState)\n ? (0,_binding__WEBPACK_IMPORTED_MODULE_5__.getHoveredElementForBinding)((0,_utils__WEBPACK_IMPORTED_MODULE_6__.tupleToCoors)(LinearElementEditor.getPointAtIndexGlobalCoordinates(element, selectedPoint)), _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(element))\n : null;\n bindings[selectedPoint === 0 ? \"startBindingElement\" : \"endBindingElement\"] = bindingElement;\n }\n }\n }\n return Object.assign(Object.assign(Object.assign({}, editingLinearElement), bindings), { \n // if clicking without previously dragging a point(s), and not holding\n // shift, deselect all points except the one clicked. If holding shift,\n // toggle the point.\n selectedPointsIndices: isDragging || event.shiftKey\n ? !isDragging &&\n event.shiftKey &&\n ((_a = pointerDownState.prevSelectedPointsIndices) === null || _a === void 0 ? void 0 : _a.includes(pointerDownState.lastClickedPoint))\n ? selectedPointsIndices &&\n selectedPointsIndices.filter((pointIndex) => pointIndex !== pointerDownState.lastClickedPoint)\n : selectedPointsIndices\n : (selectedPointsIndices === null || selectedPointsIndices === void 0 ? void 0 : selectedPointsIndices.includes(pointerDownState.lastClickedPoint))\n ? [pointerDownState.lastClickedPoint]\n : selectedPointsIndices, isDragging: false, pointerOffset: { x: 0, y: 0 } });\n }\n static handlePointerDown(event, appState, history, scenePointer, linearElementEditor) {\n var _a;\n const ret = {\n didAddPoint: false,\n hitElement: null,\n linearElementEditor: null,\n };\n if (!linearElementEditor) {\n return ret;\n }\n const { elementId } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return ret;\n }\n if (event.altKey && appState.editingLinearElement) {\n if (linearElementEditor.lastUncommittedPoint == null) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, {\n points: [\n ...element.points,\n LinearElementEditor.createPointAt(element, scenePointer.x, scenePointer.y, appState.gridSize),\n ],\n });\n }\n history.resumeRecording();\n ret.linearElementEditor = Object.assign(Object.assign({}, linearElementEditor), { pointerDownState: {\n prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,\n lastClickedPoint: -1,\n }, selectedPointsIndices: [element.points.length - 1], lastUncommittedPoint: null, endBindingElement: (0,_binding__WEBPACK_IMPORTED_MODULE_5__.getHoveredElementForBinding)(scenePointer, _scene_Scene__WEBPACK_IMPORTED_MODULE_4__[\"default\"].getScene(element)) });\n ret.didAddPoint = true;\n return ret;\n }\n const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, appState.zoom, scenePointer.x, scenePointer.y);\n // if we clicked on a point, set the element as hitElement otherwise\n // it would get deselected if the point is outside the hitbox area\n if (clickedPointIndex > -1) {\n ret.hitElement = element;\n }\n else {\n // You might be wandering why we are storing the binding elements on\n // LinearElementEditor and passing them in, instead of calculating them\n // from the end points of the `linearElement` - this is to allow disabling\n // binding (which needs to happen at the point the user finishes moving\n // the point).\n const { startBindingElement, endBindingElement } = linearElementEditor;\n if ((0,_binding__WEBPACK_IMPORTED_MODULE_5__.isBindingEnabled)(appState) && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_7__.isBindingElement)(element)) {\n (0,_binding__WEBPACK_IMPORTED_MODULE_5__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n }\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const targetPoint = clickedPointIndex > -1 &&\n (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(element.x + element.points[clickedPointIndex][0], element.y + element.points[clickedPointIndex][1], cx, cy, element.angle);\n const nextSelectedPointsIndices = clickedPointIndex > -1 || event.shiftKey\n ? event.shiftKey ||\n ((_a = linearElementEditor.selectedPointsIndices) === null || _a === void 0 ? void 0 : _a.includes(clickedPointIndex))\n ? normalizeSelectedPoints([\n ...(linearElementEditor.selectedPointsIndices || []),\n clickedPointIndex,\n ])\n : [clickedPointIndex]\n : null;\n ret.linearElementEditor = Object.assign(Object.assign({}, linearElementEditor), { pointerDownState: {\n prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,\n lastClickedPoint: clickedPointIndex,\n }, selectedPointsIndices: nextSelectedPointsIndices, pointerOffset: targetPoint\n ? {\n x: scenePointer.x - targetPoint[0],\n y: scenePointer.y - targetPoint[1],\n }\n : { x: 0, y: 0 } });\n return ret;\n }\n static handlePointerMove(event, scenePointerX, scenePointerY, linearElementEditor, gridSize) {\n const { elementId, lastUncommittedPoint } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId);\n if (!element) {\n return linearElementEditor;\n }\n const { points } = element;\n const lastPoint = points[points.length - 1];\n if (!event.altKey) {\n if (lastPoint === lastUncommittedPoint) {\n LinearElementEditor.deletePoints(element, [points.length - 1]);\n }\n return Object.assign(Object.assign({}, linearElementEditor), { lastUncommittedPoint: null });\n }\n let newPoint;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_8__.shouldRotateWithDiscreteAngle)(event) && points.length >= 2) {\n const lastCommittedPoint = points[points.length - 2];\n const [width, height] = LinearElementEditor._getShiftLockedDelta(element, lastCommittedPoint, [scenePointerX, scenePointerY], gridSize);\n newPoint = [\n width + lastCommittedPoint[0],\n height + lastCommittedPoint[1],\n ];\n }\n else {\n newPoint = LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, gridSize);\n }\n if (lastPoint === lastUncommittedPoint) {\n LinearElementEditor.movePoints(element, [\n {\n index: element.points.length - 1,\n point: newPoint,\n },\n ]);\n }\n else {\n LinearElementEditor.addPoints(element, [{ point: newPoint }]);\n }\n return Object.assign(Object.assign({}, linearElementEditor), { lastUncommittedPoint: element.points[element.points.length - 1] });\n }\n /** scene coords */\n static getPointGlobalCoordinates(element, point) {\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n let { x, y } = element;\n [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(x + point[0], y + point[1], cx, cy, element.angle);\n return [x, y];\n }\n /** scene coords */\n static getPointsGlobalCoordinates(element) {\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n return element.points.map((point) => {\n let { x, y } = element;\n [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(x + point[0], y + point[1], cx, cy, element.angle);\n return [x, y];\n });\n }\n static getPointAtIndexGlobalCoordinates(element, indexMaybeFromEnd) {\n const index = indexMaybeFromEnd < 0\n ? element.points.length + indexMaybeFromEnd\n : indexMaybeFromEnd;\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const point = element.points[index];\n const { x, y } = element;\n return (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(x + point[0], y + point[1], cx, cy, element.angle);\n }\n static pointFromAbsoluteCoords(element, absoluteCoords) {\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const [x, y] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(absoluteCoords[0], absoluteCoords[1], cx, cy, -element.angle);\n return [x - element.x, y - element.y];\n }\n static getPointIndexUnderCursor(element, zoom, x, y) {\n const pointHandles = this.getPointsGlobalCoordinates(element);\n let idx = pointHandles.length;\n // loop from right to left because points on the right are rendered over\n // points on the left, thus should take precedence when clicking, if they\n // overlap\n while (--idx > -1) {\n const point = pointHandles[idx];\n if ((0,_math__WEBPACK_IMPORTED_MODULE_0__.distance2d)(x, y, point[0], point[1]) * zoom.value <\n // +1px to account for outline stroke\n this.POINT_HANDLE_SIZE + 1) {\n return idx;\n }\n }\n return -1;\n }\n static createPointAt(element, scenePointerX, scenePointerY, gridSize) {\n const pointerOnGrid = (0,_math__WEBPACK_IMPORTED_MODULE_0__.getGridPoint)(scenePointerX, scenePointerY, gridSize);\n const [x1, y1, x2, y2] = (0,___WEBPACK_IMPORTED_MODULE_1__.getElementAbsoluteCoords)(element);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const [rotatedX, rotatedY] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(pointerOnGrid[0], pointerOnGrid[1], cx, cy, -element.angle);\n return [rotatedX - element.x, rotatedY - element.y];\n }\n /**\n * Normalizes line points so that the start point is at [0,0]. This is\n * expected in various parts of the codebase. Also returns new x/y to account\n * for the potential normalization.\n */\n static getNormalizedPoints(element) {\n const { points } = element;\n const offsetX = points[0][0];\n const offsetY = points[0][1];\n return {\n points: points.map((point, _idx) => {\n return [point[0] - offsetX, point[1] - offsetY];\n }),\n x: element.x + offsetX,\n y: element.y + offsetY,\n };\n }\n // element-mutating methods\n // ---------------------------------------------------------------------------\n static normalizePoints(element) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, LinearElementEditor.getNormalizedPoints(element));\n }\n static duplicateSelectedPoints(appState) {\n if (!appState.editingLinearElement) {\n return false;\n }\n const { selectedPointsIndices, elementId } = appState.editingLinearElement;\n const element = LinearElementEditor.getElement(elementId);\n if (!element || selectedPointsIndices === null) {\n return false;\n }\n const { points } = element;\n const nextSelectedIndices = [];\n let pointAddedToEnd = false;\n let indexCursor = -1;\n const nextPoints = points.reduce((acc, point, index) => {\n ++indexCursor;\n acc.push(point);\n const isSelected = selectedPointsIndices.includes(index);\n if (isSelected) {\n const nextPoint = points[index + 1];\n if (!nextPoint) {\n pointAddedToEnd = true;\n }\n acc.push(nextPoint\n ? [(point[0] + nextPoint[0]) / 2, (point[1] + nextPoint[1]) / 2]\n : [point[0], point[1]]);\n nextSelectedIndices.push(indexCursor + 1);\n ++indexCursor;\n }\n return acc;\n }, []);\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, { points: nextPoints });\n // temp hack to ensure the line doesn't move when adding point to the end,\n // potentially expanding the bounding box\n if (pointAddedToEnd) {\n const lastPoint = element.points[element.points.length - 1];\n LinearElementEditor.movePoints(element, [\n {\n index: element.points.length - 1,\n point: [lastPoint[0] + 30, lastPoint[1] + 30],\n },\n ]);\n }\n return {\n appState: Object.assign(Object.assign({}, appState), { editingLinearElement: Object.assign(Object.assign({}, appState.editingLinearElement), { selectedPointsIndices: nextSelectedIndices }) }),\n };\n }\n static deletePoints(element, pointIndices) {\n let offsetX = 0;\n let offsetY = 0;\n const isDeletingOriginPoint = pointIndices.includes(0);\n // if deleting first point, make the next to be [0,0] and recalculate\n // positions of the rest with respect to it\n if (isDeletingOriginPoint) {\n const firstNonDeletedPoint = element.points.find((point, idx) => {\n return !pointIndices.includes(idx);\n });\n if (firstNonDeletedPoint) {\n offsetX = firstNonDeletedPoint[0];\n offsetY = firstNonDeletedPoint[1];\n }\n }\n const nextPoints = element.points.reduce((acc, point, idx) => {\n if (!pointIndices.includes(idx)) {\n acc.push(!acc.length ? [0, 0] : [point[0] - offsetX, point[1] - offsetY]);\n }\n return acc;\n }, []);\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY);\n }\n static addPoints(element, targetPoints) {\n const offsetX = 0;\n const offsetY = 0;\n const nextPoints = [...element.points, ...targetPoints.map((x) => x.point)];\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY);\n }\n static movePoints(element, targetPoints, otherUpdates) {\n const { points } = element;\n // in case we're moving start point, instead of modifying its position\n // which would break the invariant of it being at [0,0], we move\n // all the other points in the opposite direction by delta to\n // offset it. We do the same with actual element.x/y position, so\n // this hacks are completely transparent to the user.\n let offsetX = 0;\n let offsetY = 0;\n const selectedOriginPoint = targetPoints.find(({ index }) => index === 0);\n if (selectedOriginPoint) {\n offsetX =\n selectedOriginPoint.point[0] + points[selectedOriginPoint.index][0];\n offsetY =\n selectedOriginPoint.point[1] + points[selectedOriginPoint.index][1];\n }\n const nextPoints = points.map((point, idx) => {\n const selectedPointData = targetPoints.find((p) => p.index === idx);\n if (selectedPointData) {\n if (selectedOriginPoint) {\n return point;\n }\n const deltaX = selectedPointData.point[0] - points[selectedPointData.index][0];\n const deltaY = selectedPointData.point[1] - points[selectedPointData.index][1];\n return [point[0] + deltaX, point[1] + deltaY];\n }\n return offsetX || offsetY\n ? [point[0] - offsetX, point[1] - offsetY]\n : point;\n });\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY, otherUpdates);\n }\n static _updatePoints(element, nextPoints, offsetX, offsetY, otherUpdates) {\n const nextCoords = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementPointsCoords)(element, nextPoints, element.strokeSharpness || \"round\");\n const prevCoords = (0,_bounds__WEBPACK_IMPORTED_MODULE_2__.getElementPointsCoords)(element, element.points, element.strokeSharpness || \"round\");\n const nextCenterX = (nextCoords[0] + nextCoords[2]) / 2;\n const nextCenterY = (nextCoords[1] + nextCoords[3]) / 2;\n const prevCenterX = (prevCoords[0] + prevCoords[2]) / 2;\n const prevCenterY = (prevCoords[1] + prevCoords[3]) / 2;\n const dX = prevCenterX - nextCenterX;\n const dY = prevCenterY - nextCenterY;\n const rotated = (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotate)(offsetX, offsetY, dX, dY, element.angle);\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_3__.mutateElement)(element, Object.assign(Object.assign({}, otherUpdates), { points: nextPoints, x: element.x + rotated[0], y: element.y + rotated[1] }));\n }\n static _getShiftLockedDelta(element, referencePoint, scenePointer, gridSize) {\n const referencePointCoords = LinearElementEditor.getPointGlobalCoordinates(element, referencePoint);\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_0__.getGridPoint)(scenePointer[0], scenePointer[1], gridSize);\n const { width, height } = (0,___WEBPACK_IMPORTED_MODULE_1__.getLockedLinearCursorAlignSize)(referencePointCoords[0], referencePointCoords[1], gridX, gridY);\n return (0,_math__WEBPACK_IMPORTED_MODULE_0__.rotatePoint)([width, height], [0, 0], -element.angle);\n }\n}\n// ---------------------------------------------------------------------------\n// static methods\n// ---------------------------------------------------------------------------\nLinearElementEditor.POINT_HANDLE_SIZE = 10;\nconst normalizeSelectedPoints = (points) => {\n let nextPoints = [\n ...new Set(points.filter((p) => p !== null && p !== -1)),\n ];\n nextPoints = nextPoints.sort((a, b) => a - b);\n return nextPoints.length ? nextPoints : null;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZWxlbWVudC9saW5lYXJFbGVtZW50RWRpdG9yLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFhaUI7QUFDNEQ7QUFDM0I7QUFFRjtBQUdiO0FBS2hCO0FBQ3FCO0FBQ1E7QUFDUTtBQUVqRCxNQUFNLG1CQUFtQjtJQXdCOUIsWUFBWSxPQUE0QyxFQUFFLEtBQVk7UUFDcEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsRUFFeEIsQ0FBQztRQUNGLHNFQUF1QixDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0MsbUJBQW1CLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTdDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUNqQyxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDcEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQztRQUNsQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsTUFBTSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRztZQUN0Qix5QkFBeUIsRUFBRSxJQUFJO1lBQy9CLGdCQUFnQixFQUFFLENBQUMsQ0FBQztTQUNyQixDQUFDO1FBQ0YsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBUUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUF5RDs7UUFDekUsTUFBTSxPQUFPLEdBQUcsbUVBQWMsQ0FBQyxFQUFFLENBQUMsMENBQUUsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0QsSUFBSSxPQUFPLEVBQUU7WUFDWCxPQUFPLE9BQThDLENBQUM7U0FDdkQ7UUFD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LHFDQUFpQixHQUFHLEVBQUUsQ0FBQztBQWswQmhDLE1BQU0sdUJBQXVCLEdBQUcsQ0FDOUIsTUFBeUIsRUFDUixFQUFFO0lBQ25CLElBQUksVUFBVSxHQUFHO1FBQ2YsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzdDLENBQUM7SUFDZCxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM5QyxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQy9DLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9lbGVtZW50L2xpbmVhckVsZW1lbnRFZGl0b3IudHM/ZmM0MyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBOb25EZWxldGVkLFxuICBFeGNhbGlkcmF3TGluZWFyRWxlbWVudCxcbiAgRXhjYWxpZHJhd0VsZW1lbnQsXG4gIFBvaW50QmluZGluZyxcbiAgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGRpc3RhbmNlMmQsXG4gIHJvdGF0ZSxcbiAgaXNQYXRoQUxvb3AsXG4gIGdldEdyaWRQb2ludCxcbiAgcm90YXRlUG9pbnQsXG59IGZyb20gXCIuLi9tYXRoXCI7XG5pbXBvcnQgeyBnZXRFbGVtZW50QWJzb2x1dGVDb29yZHMsIGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZSB9IGZyb20gXCIuXCI7XG5pbXBvcnQgeyBnZXRFbGVtZW50UG9pbnRzQ29vcmRzIH0gZnJvbSBcIi4vYm91bmRzXCI7XG5pbXBvcnQgeyBQb2ludCwgQXBwU3RhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IG11dGF0ZUVsZW1lbnQgfSBmcm9tIFwiLi9tdXRhdGVFbGVtZW50XCI7XG5pbXBvcnQgSGlzdG9yeSBmcm9tIFwiLi4vaGlzdG9yeVwiO1xuXG5pbXBvcnQgU2NlbmUgZnJvbSBcIi4uL3NjZW5lL1NjZW5lXCI7XG5pbXBvcnQge1xuICBiaW5kT3JVbmJpbmRMaW5lYXJFbGVtZW50LFxuICBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcsXG4gIGlzQmluZGluZ0VuYWJsZWQsXG59IGZyb20gXCIuL2JpbmRpbmdcIjtcbmltcG9ydCB7IHR1cGxlVG9Db29ycyB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgaXNCaW5kaW5nRWxlbWVudCB9IGZyb20gXCIuL3R5cGVDaGVja3NcIjtcbmltcG9ydCB7IHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlIH0gZnJvbSBcIi4uL2tleXNcIjtcblxuZXhwb3J0IGNsYXNzIExpbmVhckVsZW1lbnRFZGl0b3Ige1xuICBwdWJsaWMgcmVhZG9ubHkgZWxlbWVudElkOiBFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdICYge1xuICAgIF9icmFuZDogXCJleGNhbGlkcmF3TGluZWFyRWxlbWVudElkXCI7XG4gIH07XG4gIC8qKiBpbmRpY2VzICovXG4gIHB1YmxpYyByZWFkb25seSBzZWxlY3RlZFBvaW50c0luZGljZXM6IHJlYWRvbmx5IG51bWJlcltdIHwgbnVsbDtcblxuICBwdWJsaWMgcmVhZG9ubHkgcG9pbnRlckRvd25TdGF0ZTogUmVhZG9ubHk8e1xuICAgIHByZXZTZWxlY3RlZFBvaW50c0luZGljZXM6IHJlYWRvbmx5IG51bWJlcltdIHwgbnVsbDtcbiAgICAvKiogaW5kZXggKi9cbiAgICBsYXN0Q2xpY2tlZFBvaW50OiBudW1iZXI7XG4gIH0+O1xuXG4gIC8qKiB3aGV0aGVyIHlvdSdyZSBkcmFnZ2luZyBhIHBvaW50ICovXG4gIHB1YmxpYyByZWFkb25seSBpc0RyYWdnaW5nOiBib29sZWFuO1xuICBwdWJsaWMgcmVhZG9ubHkgbGFzdFVuY29tbWl0dGVkUG9pbnQ6IFBvaW50IHwgbnVsbDtcbiAgcHVibGljIHJlYWRvbmx5IHBvaW50ZXJPZmZzZXQ6IFJlYWRvbmx5PHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfT47XG4gIHB1YmxpYyByZWFkb25seSBzdGFydEJpbmRpbmdFbGVtZW50OlxuICAgIHwgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudFxuICAgIHwgbnVsbFxuICAgIHwgXCJrZWVwXCI7XG4gIHB1YmxpYyByZWFkb25seSBlbmRCaW5kaW5nRWxlbWVudDogRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCB8IG51bGwgfCBcImtlZXBcIjtcbiAgcHVibGljIHJlYWRvbmx5IGhvdmVyUG9pbnRJbmRleDogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LCBzY2VuZTogU2NlbmUpIHtcbiAgICB0aGlzLmVsZW1lbnRJZCA9IGVsZW1lbnQuaWQgYXMgc3RyaW5nICYge1xuICAgICAgX2JyYW5kOiBcImV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50SWRcIjtcbiAgICB9O1xuICAgIFNjZW5lLm1hcEVsZW1lbnRUb1NjZW5lKHRoaXMuZWxlbWVudElkLCBzY2VuZSk7XG4gICAgTGluZWFyRWxlbWVudEVkaXRvci5ub3JtYWxpemVQb2ludHMoZWxlbWVudCk7XG5cbiAgICB0aGlzLnNlbGVjdGVkUG9pbnRzSW5kaWNlcyA9IG51bGw7XG4gICAgdGhpcy5sYXN0VW5jb21taXR0ZWRQb2ludCA9IG51bGw7XG4gICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XG4gICAgdGhpcy5wb2ludGVyT2Zmc2V0ID0geyB4OiAwLCB5OiAwIH07XG4gICAgdGhpcy5zdGFydEJpbmRpbmdFbGVtZW50ID0gXCJrZWVwXCI7XG4gICAgdGhpcy5lbmRCaW5kaW5nRWxlbWVudCA9IFwia2VlcFwiO1xuICAgIHRoaXMucG9pbnRlckRvd25TdGF0ZSA9IHtcbiAgICAgIHByZXZTZWxlY3RlZFBvaW50c0luZGljZXM6IG51bGwsXG4gICAgICBsYXN0Q2xpY2tlZFBvaW50OiAtMSxcbiAgICB9O1xuICAgIHRoaXMuaG92ZXJQb2ludEluZGV4ID0gLTE7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gc3RhdGljIG1ldGhvZHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgc3RhdGljIFBPSU5UX0hBTkRMRV9TSVpFID0gMTA7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBpZCB0aGUgYGVsZW1lbnRJZGAgZnJvbSB0aGUgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyAoc28gdGhhdCB3ZSBjYW5cbiAgICogIHN0YXRpY2FsbHkgZ3VhcmFudGVlIHRoaXMgbWV0aG9kIHJldHVybnMgYW4gRXhjYWxpZHJhd0xpbmVhckVsZW1lbnQpXG4gICAqL1xuICBzdGF0aWMgZ2V0RWxlbWVudChpZDogSW5zdGFuY2VUeXBlPHR5cGVvZiBMaW5lYXJFbGVtZW50RWRpdG9yPltcImVsZW1lbnRJZFwiXSkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBTY2VuZS5nZXRTY2VuZShpZCk/LmdldE5vbkRlbGV0ZWRFbGVtZW50KGlkKTtcbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQgYXMgTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIGhhbmRsZUJveFNlbGVjdGlvbihcbiAgICBldmVudDogUG9pbnRlckV2ZW50LFxuICAgIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgICBzZXRTdGF0ZTogUmVhY3QuQ29tcG9uZW50PGFueSwgQXBwU3RhdGU+W1wic2V0U3RhdGVcIl0sXG4gICkge1xuICAgIGlmIChcbiAgICAgICFhcHBTdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgYXBwU3RhdGUuZHJhZ2dpbmdFbGVtZW50Py50eXBlICE9PSBcInNlbGVjdGlvblwiXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHsgZWRpdGluZ0xpbmVhckVsZW1lbnQgfSA9IGFwcFN0YXRlO1xuICAgIGNvbnN0IHsgc2VsZWN0ZWRQb2ludHNJbmRpY2VzLCBlbGVtZW50SWQgfSA9IGVkaXRpbmdMaW5lYXJFbGVtZW50O1xuXG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChlbGVtZW50SWQpO1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IFtzZWxlY3Rpb25YMSwgc2VsZWN0aW9uWTEsIHNlbGVjdGlvblgyLCBzZWxlY3Rpb25ZMl0gPVxuICAgICAgZ2V0RWxlbWVudEFic29sdXRlQ29vcmRzKGFwcFN0YXRlLmRyYWdnaW5nRWxlbWVudCk7XG5cbiAgICBjb25zdCBwb2ludHNTY2VuZUNvb3JkcyA9XG4gICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50c0dsb2JhbENvb3JkaW5hdGVzKGVsZW1lbnQpO1xuXG4gICAgY29uc3QgbmV4dFNlbGVjdGVkUG9pbnRzID0gcG9pbnRzU2NlbmVDb29yZHMucmVkdWNlKFxuICAgICAgKGFjYzogbnVtYmVyW10sIHBvaW50LCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKHBvaW50WzBdID49IHNlbGVjdGlvblgxICYmXG4gICAgICAgICAgICBwb2ludFswXSA8PSBzZWxlY3Rpb25YMiAmJlxuICAgICAgICAgICAgcG9pbnRbMV0gPj0gc2VsZWN0aW9uWTEgJiZcbiAgICAgICAgICAgIHBvaW50WzFdIDw9IHNlbGVjdGlvblkyKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleSAmJiBzZWxlY3RlZFBvaW50c0luZGljZXM/LmluY2x1ZGVzKGluZGV4KSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjLnB1c2goaW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICBbXSxcbiAgICApO1xuXG4gICAgc2V0U3RhdGUoe1xuICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgLi4uZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogbmV4dFNlbGVjdGVkUG9pbnRzLmxlbmd0aFxuICAgICAgICAgID8gbmV4dFNlbGVjdGVkUG9pbnRzXG4gICAgICAgICAgOiBudWxsLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB3aGV0aGVyIHBvaW50IHdhcyBkcmFnZ2VkICovXG4gIHN0YXRpYyBoYW5kbGVQb2ludERyYWdnaW5nKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICAgIHNjZW5lUG9pbnRlclg6IG51bWJlcixcbiAgICBzY2VuZVBvaW50ZXJZOiBudW1iZXIsXG4gICAgbWF5YmVTdWdnZXN0QmluZGluZzogKFxuICAgICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgICBwb2ludFNjZW5lQ29vcmRzOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH1bXSxcbiAgICApID0+IHZvaWQsXG4gICAgbGluZWFyRWxlbWVudEVkaXRvcjogTGluZWFyRWxlbWVudEVkaXRvcixcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKCFsaW5lYXJFbGVtZW50RWRpdG9yKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBzZWxlY3RlZFBvaW50c0luZGljZXMsIGVsZW1lbnRJZCB9ID0gbGluZWFyRWxlbWVudEVkaXRvcjtcbiAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KGVsZW1lbnRJZCk7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gcG9pbnQgdGhhdCdzIGJlaW5nIGRyYWdnZWQgKG91dCBvZiBhbGwgc2VsZWN0ZWQgcG9pbnRzKVxuICAgIGNvbnN0IGRyYWdnaW5nUG9pbnQgPSBlbGVtZW50LnBvaW50c1tcbiAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50XG4gICAgXSBhcyBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkO1xuICAgIGlmIChzZWxlY3RlZFBvaW50c0luZGljZXMgJiYgZHJhZ2dpbmdQb2ludCkge1xuICAgICAgaWYgKFxuICAgICAgICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCkgJiZcbiAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICBlbGVtZW50LnBvaW50cy5sZW5ndGggPiAxXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRJbmRleCA9IHNlbGVjdGVkUG9pbnRzSW5kaWNlc1swXTtcbiAgICAgICAgY29uc3QgcmVmZXJlbmNlUG9pbnQgPVxuICAgICAgICAgIGVsZW1lbnQucG9pbnRzW3NlbGVjdGVkSW5kZXggPT09IDAgPyAxIDogc2VsZWN0ZWRJbmRleCAtIDFdO1xuXG4gICAgICAgIGNvbnN0IFt3aWR0aCwgaGVpZ2h0XSA9IExpbmVhckVsZW1lbnRFZGl0b3IuX2dldFNoaWZ0TG9ja2VkRGVsdGEoXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICByZWZlcmVuY2VQb2ludCxcbiAgICAgICAgICBbc2NlbmVQb2ludGVyWCwgc2NlbmVQb2ludGVyWV0sXG4gICAgICAgICAgYXBwU3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICk7XG5cbiAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5tb3ZlUG9pbnRzKGVsZW1lbnQsIFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpbmRleDogc2VsZWN0ZWRJbmRleCxcbiAgICAgICAgICAgIHBvaW50OiBbd2lkdGggKyByZWZlcmVuY2VQb2ludFswXSwgaGVpZ2h0ICsgcmVmZXJlbmNlUG9pbnRbMV1dLFxuICAgICAgICAgICAgaXNEcmFnZ2luZzpcbiAgICAgICAgICAgICAgc2VsZWN0ZWRJbmRleCA9PT1cbiAgICAgICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5wb2ludGVyRG93blN0YXRlLmxhc3RDbGlja2VkUG9pbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuZXdEcmFnZ2luZ1BvaW50UG9zaXRpb24gPSBMaW5lYXJFbGVtZW50RWRpdG9yLmNyZWF0ZVBvaW50QXQoXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gbGluZWFyRWxlbWVudEVkaXRvci5wb2ludGVyT2Zmc2V0LngsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSAtIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlck9mZnNldC55LFxuICAgICAgICAgIGFwcFN0YXRlLmdyaWRTaXplLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGRlbHRhWCA9IG5ld0RyYWdnaW5nUG9pbnRQb3NpdGlvblswXSAtIGRyYWdnaW5nUG9pbnRbMF07XG4gICAgICAgIGNvbnN0IGRlbHRhWSA9IG5ld0RyYWdnaW5nUG9pbnRQb3NpdGlvblsxXSAtIGRyYWdnaW5nUG9pbnRbMV07XG5cbiAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5tb3ZlUG9pbnRzKFxuICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzLm1hcCgocG9pbnRJbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3UG9pbnRQb3NpdGlvbiA9XG4gICAgICAgICAgICAgIHBvaW50SW5kZXggPT09XG4gICAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50XG4gICAgICAgICAgICAgICAgPyBMaW5lYXJFbGVtZW50RWRpdG9yLmNyZWF0ZVBvaW50QXQoXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHNjZW5lUG9pbnRlclggLSBsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJPZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgICAgc2NlbmVQb2ludGVyWSAtIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlck9mZnNldC55LFxuICAgICAgICAgICAgICAgICAgICBhcHBTdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA6IChbXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucG9pbnRzW3BvaW50SW5kZXhdWzBdICsgZGVsdGFYLFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnBvaW50c1twb2ludEluZGV4XVsxXSArIGRlbHRhWSxcbiAgICAgICAgICAgICAgICAgIF0gYXMgY29uc3QpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaW5kZXg6IHBvaW50SW5kZXgsXG4gICAgICAgICAgICAgIHBvaW50OiBuZXdQb2ludFBvc2l0aW9uLFxuICAgICAgICAgICAgICBpc0RyYWdnaW5nOlxuICAgICAgICAgICAgICAgIHBvaW50SW5kZXggPT09XG4gICAgICAgICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5wb2ludGVyRG93blN0YXRlLmxhc3RDbGlja2VkUG9pbnQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBzdWdnZXN0IGJpbmRpbmdzIGZvciBmaXJzdCBhbmQgbGFzdCBwb2ludCBpZiBzZWxlY3RlZFxuICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZWxlbWVudCwgZmFsc2UpKSB7XG4gICAgICAgIGNvbnN0IGNvb3JkczogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9W10gPSBbXTtcblxuICAgICAgICBjb25zdCBmaXJzdFNlbGVjdGVkSW5kZXggPSBzZWxlY3RlZFBvaW50c0luZGljZXNbMF07XG4gICAgICAgIGlmIChmaXJzdFNlbGVjdGVkSW5kZXggPT09IDApIHtcbiAgICAgICAgICBjb29yZHMucHVzaChcbiAgICAgICAgICAgIHR1cGxlVG9Db29ycyhcbiAgICAgICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEdsb2JhbENvb3JkaW5hdGVzKFxuICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgZWxlbWVudC5wb2ludHNbMF0sXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsYXN0U2VsZWN0ZWRJbmRleCA9XG4gICAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzW3NlbGVjdGVkUG9pbnRzSW5kaWNlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RTZWxlY3RlZEluZGV4ID09PSBlbGVtZW50LnBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgY29vcmRzLnB1c2goXG4gICAgICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgIGVsZW1lbnQucG9pbnRzW2xhc3RTZWxlY3RlZEluZGV4XSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb29yZHMubGVuZ3RoKSB7XG4gICAgICAgICAgbWF5YmVTdWdnZXN0QmluZGluZyhlbGVtZW50LCBjb29yZHMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVQb2ludGVyVXAoXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogTGluZWFyRWxlbWVudEVkaXRvcixcbiAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICk6IExpbmVhckVsZW1lbnRFZGl0b3Ige1xuICAgIGNvbnN0IHsgZWxlbWVudElkLCBzZWxlY3RlZFBvaW50c0luZGljZXMsIGlzRHJhZ2dpbmcsIHBvaW50ZXJEb3duU3RhdGUgfSA9XG4gICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDtcbiAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KGVsZW1lbnRJZCk7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWRpdGluZ0xpbmVhckVsZW1lbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgYmluZGluZ3M6IE11dGFibGU8XG4gICAgICBQYXJ0aWFsPFxuICAgICAgICBQaWNrPFxuICAgICAgICAgIEluc3RhbmNlVHlwZTx0eXBlb2YgTGluZWFyRWxlbWVudEVkaXRvcj4sXG4gICAgICAgICAgXCJzdGFydEJpbmRpbmdFbGVtZW50XCIgfCBcImVuZEJpbmRpbmdFbGVtZW50XCJcbiAgICAgICAgPlxuICAgICAgPlxuICAgID4gPSB7fTtcblxuICAgIGlmIChpc0RyYWdnaW5nICYmIHNlbGVjdGVkUG9pbnRzSW5kaWNlcykge1xuICAgICAgZm9yIChjb25zdCBzZWxlY3RlZFBvaW50IG9mIHNlbGVjdGVkUG9pbnRzSW5kaWNlcykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRQb2ludCA9PT0gMCB8fFxuICAgICAgICAgIHNlbGVjdGVkUG9pbnQgPT09IGVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aEFMb29wKGVsZW1lbnQucG9pbnRzLCBhcHBTdGF0ZS56b29tLnZhbHVlKSkge1xuICAgICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5tb3ZlUG9pbnRzKGVsZW1lbnQsIFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGluZGV4OiBzZWxlY3RlZFBvaW50LFxuICAgICAgICAgICAgICAgIHBvaW50OlxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRQb2ludCA9PT0gMFxuICAgICAgICAgICAgICAgICAgICA/IGVsZW1lbnQucG9pbnRzW2VsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdXG4gICAgICAgICAgICAgICAgICAgIDogZWxlbWVudC5wb2ludHNbMF0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBiaW5kaW5nRWxlbWVudCA9IGlzQmluZGluZ0VuYWJsZWQoYXBwU3RhdGUpXG4gICAgICAgICAgICA/IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50QXRJbmRleEdsb2JhbENvb3JkaW5hdGVzKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFBvaW50ISxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBTY2VuZS5nZXRTY2VuZShlbGVtZW50KSEsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIDogbnVsbDtcblxuICAgICAgICAgIGJpbmRpbmdzW1xuICAgICAgICAgICAgc2VsZWN0ZWRQb2ludCA9PT0gMCA/IFwic3RhcnRCaW5kaW5nRWxlbWVudFwiIDogXCJlbmRCaW5kaW5nRWxlbWVudFwiXG4gICAgICAgICAgXSA9IGJpbmRpbmdFbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgLi4uYmluZGluZ3MsXG4gICAgICAvLyBpZiBjbGlja2luZyB3aXRob3V0IHByZXZpb3VzbHkgZHJhZ2dpbmcgYSBwb2ludChzKSwgYW5kIG5vdCBob2xkaW5nXG4gICAgICAvLyBzaGlmdCwgZGVzZWxlY3QgYWxsIHBvaW50cyBleGNlcHQgdGhlIG9uZSBjbGlja2VkLiBJZiBob2xkaW5nIHNoaWZ0LFxuICAgICAgLy8gdG9nZ2xlIHRoZSBwb2ludC5cbiAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczpcbiAgICAgICAgaXNEcmFnZ2luZyB8fCBldmVudC5zaGlmdEtleVxuICAgICAgICAgID8gIWlzRHJhZ2dpbmcgJiZcbiAgICAgICAgICAgIGV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnByZXZTZWxlY3RlZFBvaW50c0luZGljZXM/LmluY2x1ZGVzKFxuICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDbGlja2VkUG9pbnQsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICA/IHNlbGVjdGVkUG9pbnRzSW5kaWNlcyAmJlxuICAgICAgICAgICAgICBzZWxlY3RlZFBvaW50c0luZGljZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChwb2ludEluZGV4KSA9PlxuICAgICAgICAgICAgICAgICAgcG9pbnRJbmRleCAhPT0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50LFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICA6IHNlbGVjdGVkUG9pbnRzSW5kaWNlc1xuICAgICAgICAgIDogc2VsZWN0ZWRQb2ludHNJbmRpY2VzPy5pbmNsdWRlcyhwb2ludGVyRG93blN0YXRlLmxhc3RDbGlja2VkUG9pbnQpXG4gICAgICAgICAgPyBbcG9pbnRlckRvd25TdGF0ZS5sYXN0Q2xpY2tlZFBvaW50XVxuICAgICAgICAgIDogc2VsZWN0ZWRQb2ludHNJbmRpY2VzLFxuICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXG4gICAgICBwb2ludGVyT2Zmc2V0OiB7IHg6IDAsIHk6IDAgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGhhbmRsZVBvaW50ZXJEb3duKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgICBoaXN0b3J5OiBIaXN0b3J5LFxuICAgIHNjZW5lUG9pbnRlcjogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LFxuICAgIGxpbmVhckVsZW1lbnRFZGl0b3I6IExpbmVhckVsZW1lbnRFZGl0b3IsXG4gICk6IHtcbiAgICBkaWRBZGRQb2ludDogYm9vbGVhbjtcbiAgICBoaXRFbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PiB8IG51bGw7XG4gICAgbGluZWFyRWxlbWVudEVkaXRvcjogTGluZWFyRWxlbWVudEVkaXRvciB8IG51bGw7XG4gIH0ge1xuICAgIGNvbnN0IHJldDogUmV0dXJuVHlwZTx0eXBlb2YgTGluZWFyRWxlbWVudEVkaXRvcltcImhhbmRsZVBvaW50ZXJEb3duXCJdPiA9IHtcbiAgICAgIGRpZEFkZFBvaW50OiBmYWxzZSxcbiAgICAgIGhpdEVsZW1lbnQ6IG51bGwsXG4gICAgICBsaW5lYXJFbGVtZW50RWRpdG9yOiBudWxsLFxuICAgIH07XG5cbiAgICBpZiAoIWxpbmVhckVsZW1lbnRFZGl0b3IpIHtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgY29uc3QgeyBlbGVtZW50SWQgfSA9IGxpbmVhckVsZW1lbnRFZGl0b3I7XG4gICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChlbGVtZW50SWQpO1xuXG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgICBpZiAoZXZlbnQuYWx0S2V5ICYmIGFwcFN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICBpZiAobGluZWFyRWxlbWVudEVkaXRvci5sYXN0VW5jb21taXR0ZWRQb2ludCA9PSBudWxsKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgLi4uZWxlbWVudC5wb2ludHMsXG4gICAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmNyZWF0ZVBvaW50QXQoXG4gICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICAgICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICAgICAgICAgICAgYXBwU3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICAgICApLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIHJldC5saW5lYXJFbGVtZW50RWRpdG9yID0ge1xuICAgICAgICAuLi5saW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlOiB7XG4gICAgICAgICAgcHJldlNlbGVjdGVkUG9pbnRzSW5kaWNlczogbGluZWFyRWxlbWVudEVkaXRvci5zZWxlY3RlZFBvaW50c0luZGljZXMsXG4gICAgICAgICAgbGFzdENsaWNrZWRQb2ludDogLTEsXG4gICAgICAgIH0sXG4gICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogW2VsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdLFxuICAgICAgICBsYXN0VW5jb21taXR0ZWRQb2ludDogbnVsbCxcbiAgICAgICAgZW5kQmluZGluZ0VsZW1lbnQ6IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgICAgU2NlbmUuZ2V0U2NlbmUoZWxlbWVudCkhLFxuICAgICAgICApLFxuICAgICAgfTtcblxuICAgICAgcmV0LmRpZEFkZFBvaW50ID0gdHJ1ZTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpY2tlZFBvaW50SW5kZXggPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50SW5kZXhVbmRlckN1cnNvcihcbiAgICAgIGVsZW1lbnQsXG4gICAgICBhcHBTdGF0ZS56b29tLFxuICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICApO1xuXG4gICAgLy8gaWYgd2UgY2xpY2tlZCBvbiBhIHBvaW50LCBzZXQgdGhlIGVsZW1lbnQgYXMgaGl0RWxlbWVudCBvdGhlcndpc2VcbiAgICAvLyBpdCB3b3VsZCBnZXQgZGVzZWxlY3RlZCBpZiB0aGUgcG9pbnQgaXMgb3V0c2lkZSB0aGUgaGl0Ym94IGFyZWFcbiAgICBpZiAoY2xpY2tlZFBvaW50SW5kZXggPiAtMSkge1xuICAgICAgcmV0LmhpdEVsZW1lbnQgPSBlbGVtZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBZb3UgbWlnaHQgYmUgd2FuZGVyaW5nIHdoeSB3ZSBhcmUgc3RvcmluZyB0aGUgYmluZGluZyBlbGVtZW50cyBvblxuICAgICAgLy8gTGluZWFyRWxlbWVudEVkaXRvciBhbmQgcGFzc2luZyB0aGVtIGluLCBpbnN0ZWFkIG9mIGNhbGN1bGF0aW5nIHRoZW1cbiAgICAgIC8vIGZyb20gdGhlIGVuZCBwb2ludHMgb2YgdGhlIGBsaW5lYXJFbGVtZW50YCAtIHRoaXMgaXMgdG8gYWxsb3cgZGlzYWJsaW5nXG4gICAgICAvLyBiaW5kaW5nICh3aGljaCBuZWVkcyB0byBoYXBwZW4gYXQgdGhlIHBvaW50IHRoZSB1c2VyIGZpbmlzaGVzIG1vdmluZ1xuICAgICAgLy8gdGhlIHBvaW50KS5cbiAgICAgIGNvbnN0IHsgc3RhcnRCaW5kaW5nRWxlbWVudCwgZW5kQmluZGluZ0VsZW1lbnQgfSA9IGxpbmVhckVsZW1lbnRFZGl0b3I7XG4gICAgICBpZiAoaXNCaW5kaW5nRW5hYmxlZChhcHBTdGF0ZSkgJiYgaXNCaW5kaW5nRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICBiaW5kT3JVbmJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgc3RhcnRCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgICBlbmRCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0RWxlbWVudEFic29sdXRlQ29vcmRzKGVsZW1lbnQpO1xuICAgIGNvbnN0IGN4ID0gKHgxICsgeDIpIC8gMjtcbiAgICBjb25zdCBjeSA9ICh5MSArIHkyKSAvIDI7XG4gICAgY29uc3QgdGFyZ2V0UG9pbnQgPVxuICAgICAgY2xpY2tlZFBvaW50SW5kZXggPiAtMSAmJlxuICAgICAgcm90YXRlKFxuICAgICAgICBlbGVtZW50LnggKyBlbGVtZW50LnBvaW50c1tjbGlja2VkUG9pbnRJbmRleF1bMF0sXG4gICAgICAgIGVsZW1lbnQueSArIGVsZW1lbnQucG9pbnRzW2NsaWNrZWRQb2ludEluZGV4XVsxXSxcbiAgICAgICAgY3gsXG4gICAgICAgIGN5LFxuICAgICAgICBlbGVtZW50LmFuZ2xlLFxuICAgICAgKTtcblxuICAgIGNvbnN0IG5leHRTZWxlY3RlZFBvaW50c0luZGljZXMgPVxuICAgICAgY2xpY2tlZFBvaW50SW5kZXggPiAtMSB8fCBldmVudC5zaGlmdEtleVxuICAgICAgICA/IGV2ZW50LnNoaWZ0S2V5IHx8XG4gICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5zZWxlY3RlZFBvaW50c0luZGljZXM/LmluY2x1ZGVzKGNsaWNrZWRQb2ludEluZGV4KVxuICAgICAgICAgID8gbm9ybWFsaXplU2VsZWN0ZWRQb2ludHMoW1xuICAgICAgICAgICAgICAuLi4obGluZWFyRWxlbWVudEVkaXRvci5zZWxlY3RlZFBvaW50c0luZGljZXMgfHwgW10pLFxuICAgICAgICAgICAgICBjbGlja2VkUG9pbnRJbmRleCxcbiAgICAgICAgICAgIF0pXG4gICAgICAgICAgOiBbY2xpY2tlZFBvaW50SW5kZXhdXG4gICAgICAgIDogbnVsbDtcbiAgICByZXQubGluZWFyRWxlbWVudEVkaXRvciA9IHtcbiAgICAgIC4uLmxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICBwb2ludGVyRG93blN0YXRlOiB7XG4gICAgICAgIHByZXZTZWxlY3RlZFBvaW50c0luZGljZXM6IGxpbmVhckVsZW1lbnRFZGl0b3Iuc2VsZWN0ZWRQb2ludHNJbmRpY2VzLFxuICAgICAgICBsYXN0Q2xpY2tlZFBvaW50OiBjbGlja2VkUG9pbnRJbmRleCxcbiAgICAgIH0sXG4gICAgICBzZWxlY3RlZFBvaW50c0luZGljZXM6IG5leHRTZWxlY3RlZFBvaW50c0luZGljZXMsXG4gICAgICBwb2ludGVyT2Zmc2V0OiB0YXJnZXRQb2ludFxuICAgICAgICA/IHtcbiAgICAgICAgICAgIHg6IHNjZW5lUG9pbnRlci54IC0gdGFyZ2V0UG9pbnRbMF0sXG4gICAgICAgICAgICB5OiBzY2VuZVBvaW50ZXIueSAtIHRhcmdldFBvaW50WzFdLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB7IHg6IDAsIHk6IDAgfSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVQb2ludGVyTW92ZShcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBzY2VuZVBvaW50ZXJYOiBudW1iZXIsXG4gICAgc2NlbmVQb2ludGVyWTogbnVtYmVyLFxuICAgIGxpbmVhckVsZW1lbnRFZGl0b3I6IExpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgZ3JpZFNpemU6IG51bWJlciB8IG51bGwsXG4gICk6IExpbmVhckVsZW1lbnRFZGl0b3Ige1xuICAgIGNvbnN0IHsgZWxlbWVudElkLCBsYXN0VW5jb21taXR0ZWRQb2ludCB9ID0gbGluZWFyRWxlbWVudEVkaXRvcjtcbiAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KGVsZW1lbnRJZCk7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm4gbGluZWFyRWxlbWVudEVkaXRvcjtcbiAgICB9XG5cbiAgICBjb25zdCB7IHBvaW50cyB9ID0gZWxlbWVudDtcbiAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuXG4gICAgaWYgKCFldmVudC5hbHRLZXkpIHtcbiAgICAgIGlmIChsYXN0UG9pbnQgPT09IGxhc3RVbmNvbW1pdHRlZFBvaW50KSB7XG4gICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZGVsZXRlUG9pbnRzKGVsZW1lbnQsIFtwb2ludHMubGVuZ3RoIC0gMV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgLi4ubGluZWFyRWxlbWVudEVkaXRvciwgbGFzdFVuY29tbWl0dGVkUG9pbnQ6IG51bGwgfTtcbiAgICB9XG5cbiAgICBsZXQgbmV3UG9pbnQ6IFBvaW50O1xuXG4gICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSAmJiBwb2ludHMubGVuZ3RoID49IDIpIHtcbiAgICAgIGNvbnN0IGxhc3RDb21taXR0ZWRQb2ludCA9IHBvaW50c1twb2ludHMubGVuZ3RoIC0gMl07XG5cbiAgICAgIGNvbnN0IFt3aWR0aCwgaGVpZ2h0XSA9IExpbmVhckVsZW1lbnRFZGl0b3IuX2dldFNoaWZ0TG9ja2VkRGVsdGEoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCxcbiAgICAgICAgW3NjZW5lUG9pbnRlclgsIHNjZW5lUG9pbnRlclldLFxuICAgICAgICBncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIG5ld1BvaW50ID0gW1xuICAgICAgICB3aWR0aCArIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgaGVpZ2h0ICsgbGFzdENvbW1pdHRlZFBvaW50WzFdLFxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3UG9pbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmNyZWF0ZVBvaW50QXQoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHNjZW5lUG9pbnRlclggLSBsaW5lYXJFbGVtZW50RWRpdG9yLnBvaW50ZXJPZmZzZXQueCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSAtIGxpbmVhckVsZW1lbnRFZGl0b3IucG9pbnRlck9mZnNldC55LFxuICAgICAgICBncmlkU2l6ZSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGxhc3RQb2ludCA9PT0gbGFzdFVuY29tbWl0dGVkUG9pbnQpIHtcbiAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IubW92ZVBvaW50cyhlbGVtZW50LCBbXG4gICAgICAgIHtcbiAgICAgICAgICBpbmRleDogZWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMSxcbiAgICAgICAgICBwb2ludDogbmV3UG9pbnQsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5hZGRQb2ludHMoZWxlbWVudCwgW3sgcG9pbnQ6IG5ld1BvaW50IH1dKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ubGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgIGxhc3RVbmNvbW1pdHRlZFBvaW50OiBlbGVtZW50LnBvaW50c1tlbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIHNjZW5lIGNvb3JkcyAqL1xuICBzdGF0aWMgZ2V0UG9pbnRHbG9iYWxDb29yZGluYXRlcyhcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICBwb2ludDogUG9pbnQsXG4gICkge1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRFbGVtZW50QWJzb2x1dGVDb29yZHMoZWxlbWVudCk7XG4gICAgY29uc3QgY3ggPSAoeDEgKyB4MikgLyAyO1xuICAgIGNvbnN0IGN5ID0gKHkxICsgeTIpIC8gMjtcblxuICAgIGxldCB7IHgsIHkgfSA9IGVsZW1lbnQ7XG4gICAgW3gsIHldID0gcm90YXRlKHggKyBwb2ludFswXSwgeSArIHBvaW50WzFdLCBjeCwgY3ksIGVsZW1lbnQuYW5nbGUpO1xuICAgIHJldHVybiBbeCwgeV0gYXMgY29uc3Q7XG4gIH1cblxuICAvKiogc2NlbmUgY29vcmRzICovXG4gIHN0YXRpYyBnZXRQb2ludHNHbG9iYWxDb29yZGluYXRlcyhcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgKSB7XG4gICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IGdldEVsZW1lbnRBYnNvbHV0ZUNvb3JkcyhlbGVtZW50KTtcbiAgICBjb25zdCBjeCA9ICh4MSArIHgyKSAvIDI7XG4gICAgY29uc3QgY3kgPSAoeTEgKyB5MikgLyAyO1xuICAgIHJldHVybiBlbGVtZW50LnBvaW50cy5tYXAoKHBvaW50KSA9PiB7XG4gICAgICBsZXQgeyB4LCB5IH0gPSBlbGVtZW50O1xuICAgICAgW3gsIHldID0gcm90YXRlKHggKyBwb2ludFswXSwgeSArIHBvaW50WzFdLCBjeCwgY3ksIGVsZW1lbnQuYW5nbGUpO1xuICAgICAgcmV0dXJuIFt4LCB5XTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRQb2ludEF0SW5kZXhHbG9iYWxDb29yZGluYXRlcyhcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICBpbmRleE1heWJlRnJvbUVuZDogbnVtYmVyLCAvLyAtMSBmb3IgbGFzdCBlbGVtZW50XG4gICk6IFBvaW50IHtcbiAgICBjb25zdCBpbmRleCA9XG4gICAgICBpbmRleE1heWJlRnJvbUVuZCA8IDBcbiAgICAgICAgPyBlbGVtZW50LnBvaW50cy5sZW5ndGggKyBpbmRleE1heWJlRnJvbUVuZFxuICAgICAgICA6IGluZGV4TWF5YmVGcm9tRW5kO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRFbGVtZW50QWJzb2x1dGVDb29yZHMoZWxlbWVudCk7XG4gICAgY29uc3QgY3ggPSAoeDEgKyB4MikgLyAyO1xuICAgIGNvbnN0IGN5ID0gKHkxICsgeTIpIC8gMjtcblxuICAgIGNvbnN0IHBvaW50ID0gZWxlbWVudC5wb2ludHNbaW5kZXhdO1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gZWxlbWVudDtcbiAgICByZXR1cm4gcm90YXRlKHggKyBwb2ludFswXSwgeSArIHBvaW50WzFdLCBjeCwgY3ksIGVsZW1lbnQuYW5nbGUpO1xuICB9XG5cbiAgc3RhdGljIHBvaW50RnJvbUFic29sdXRlQ29vcmRzKFxuICAgIGVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIGFic29sdXRlQ29vcmRzOiBQb2ludCxcbiAgKTogUG9pbnQge1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRFbGVtZW50QWJzb2x1dGVDb29yZHMoZWxlbWVudCk7XG4gICAgY29uc3QgY3ggPSAoeDEgKyB4MikgLyAyO1xuICAgIGNvbnN0IGN5ID0gKHkxICsgeTIpIC8gMjtcbiAgICBjb25zdCBbeCwgeV0gPSByb3RhdGUoXG4gICAgICBhYnNvbHV0ZUNvb3Jkc1swXSxcbiAgICAgIGFic29sdXRlQ29vcmRzWzFdLFxuICAgICAgY3gsXG4gICAgICBjeSxcbiAgICAgIC1lbGVtZW50LmFuZ2xlLFxuICAgICk7XG4gICAgcmV0dXJuIFt4IC0gZWxlbWVudC54LCB5IC0gZWxlbWVudC55XTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRQb2ludEluZGV4VW5kZXJDdXJzb3IoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgem9vbTogQXBwU3RhdGVbXCJ6b29tXCJdLFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IHBvaW50SGFuZGxlcyA9IHRoaXMuZ2V0UG9pbnRzR2xvYmFsQ29vcmRpbmF0ZXMoZWxlbWVudCk7XG4gICAgbGV0IGlkeCA9IHBvaW50SGFuZGxlcy5sZW5ndGg7XG4gICAgLy8gbG9vcCBmcm9tIHJpZ2h0IHRvIGxlZnQgYmVjYXVzZSBwb2ludHMgb24gdGhlIHJpZ2h0IGFyZSByZW5kZXJlZCBvdmVyXG4gICAgLy8gcG9pbnRzIG9uIHRoZSBsZWZ0LCB0aHVzIHNob3VsZCB0YWtlIHByZWNlZGVuY2Ugd2hlbiBjbGlja2luZywgaWYgdGhleVxuICAgIC8vIG92ZXJsYXBcbiAgICB3aGlsZSAoLS1pZHggPiAtMSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBwb2ludEhhbmRsZXNbaWR4XTtcbiAgICAgIGlmIChcbiAgICAgICAgZGlzdGFuY2UyZCh4LCB5LCBwb2ludFswXSwgcG9pbnRbMV0pICogem9vbS52YWx1ZSA8XG4gICAgICAgIC8vICsxcHggdG8gYWNjb3VudCBmb3Igb3V0bGluZSBzdHJva2VcbiAgICAgICAgdGhpcy5QT0lOVF9IQU5ETEVfU0laRSArIDFcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gaWR4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlUG9pbnRBdChcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICBzY2VuZVBvaW50ZXJYOiBudW1iZXIsXG4gICAgc2NlbmVQb2ludGVyWTogbnVtYmVyLFxuICAgIGdyaWRTaXplOiBudW1iZXIgfCBudWxsLFxuICApOiBQb2ludCB7XG4gICAgY29uc3QgcG9pbnRlck9uR3JpZCA9IGdldEdyaWRQb2ludChzY2VuZVBvaW50ZXJYLCBzY2VuZVBvaW50ZXJZLCBncmlkU2l6ZSk7XG4gICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IGdldEVsZW1lbnRBYnNvbHV0ZUNvb3JkcyhlbGVtZW50KTtcbiAgICBjb25zdCBjeCA9ICh4MSArIHgyKSAvIDI7XG4gICAgY29uc3QgY3kgPSAoeTEgKyB5MikgLyAyO1xuICAgIGNvbnN0IFtyb3RhdGVkWCwgcm90YXRlZFldID0gcm90YXRlKFxuICAgICAgcG9pbnRlck9uR3JpZFswXSxcbiAgICAgIHBvaW50ZXJPbkdyaWRbMV0sXG4gICAgICBjeCxcbiAgICAgIGN5LFxuICAgICAgLWVsZW1lbnQuYW5nbGUsXG4gICAgKTtcblxuICAgIHJldHVybiBbcm90YXRlZFggLSBlbGVtZW50LngsIHJvdGF0ZWRZIC0gZWxlbWVudC55XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIGxpbmUgcG9pbnRzIHNvIHRoYXQgdGhlIHN0YXJ0IHBvaW50IGlzIGF0IFswLDBdLiBUaGlzIGlzXG4gICAqIGV4cGVjdGVkIGluIHZhcmlvdXMgcGFydHMgb2YgdGhlIGNvZGViYXNlLiBBbHNvIHJldHVybnMgbmV3IHgveSB0byBhY2NvdW50XG4gICAqIGZvciB0aGUgcG90ZW50aWFsIG5vcm1hbGl6YXRpb24uXG4gICAqL1xuICBzdGF0aWMgZ2V0Tm9ybWFsaXplZFBvaW50cyhlbGVtZW50OiBFeGNhbGlkcmF3TGluZWFyRWxlbWVudCkge1xuICAgIGNvbnN0IHsgcG9pbnRzIH0gPSBlbGVtZW50O1xuXG4gICAgY29uc3Qgb2Zmc2V0WCA9IHBvaW50c1swXVswXTtcbiAgICBjb25zdCBvZmZzZXRZID0gcG9pbnRzWzBdWzFdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBvaW50czogcG9pbnRzLm1hcCgocG9pbnQsIF9pZHgpID0+IHtcbiAgICAgICAgcmV0dXJuIFtwb2ludFswXSAtIG9mZnNldFgsIHBvaW50WzFdIC0gb2Zmc2V0WV0gYXMgY29uc3Q7XG4gICAgICB9KSxcbiAgICAgIHg6IGVsZW1lbnQueCArIG9mZnNldFgsXG4gICAgICB5OiBlbGVtZW50LnkgKyBvZmZzZXRZLFxuICAgIH07XG4gIH1cblxuICAvLyBlbGVtZW50LW11dGF0aW5nIG1ldGhvZHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgc3RhdGljIG5vcm1hbGl6ZVBvaW50cyhlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50Pikge1xuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwgTGluZWFyRWxlbWVudEVkaXRvci5nZXROb3JtYWxpemVkUG9pbnRzKGVsZW1lbnQpKTtcbiAgfVxuXG4gIHN0YXRpYyBkdXBsaWNhdGVTZWxlY3RlZFBvaW50cyhhcHBTdGF0ZTogQXBwU3RhdGUpIHtcbiAgICBpZiAoIWFwcFN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBzZWxlY3RlZFBvaW50c0luZGljZXMsIGVsZW1lbnRJZCB9ID0gYXBwU3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQ7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KGVsZW1lbnRJZCk7XG5cbiAgICBpZiAoIWVsZW1lbnQgfHwgc2VsZWN0ZWRQb2ludHNJbmRpY2VzID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBwb2ludHMgfSA9IGVsZW1lbnQ7XG5cbiAgICBjb25zdCBuZXh0U2VsZWN0ZWRJbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgbGV0IHBvaW50QWRkZWRUb0VuZCA9IGZhbHNlO1xuICAgIGxldCBpbmRleEN1cnNvciA9IC0xO1xuICAgIGNvbnN0IG5leHRQb2ludHMgPSBwb2ludHMucmVkdWNlKChhY2M6IFBvaW50W10sIHBvaW50LCBpbmRleCkgPT4ge1xuICAgICAgKytpbmRleEN1cnNvcjtcbiAgICAgIGFjYy5wdXNoKHBvaW50KTtcblxuICAgICAgY29uc3QgaXNTZWxlY3RlZCA9IHNlbGVjdGVkUG9pbnRzSW5kaWNlcy5pbmNsdWRlcyhpbmRleCk7XG4gICAgICBpZiAoaXNTZWxlY3RlZCkge1xuICAgICAgICBjb25zdCBuZXh0UG9pbnQgPSBwb2ludHNbaW5kZXggKyAxXTtcblxuICAgICAgICBpZiAoIW5leHRQb2ludCkge1xuICAgICAgICAgIHBvaW50QWRkZWRUb0VuZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgYWNjLnB1c2goXG4gICAgICAgICAgbmV4dFBvaW50XG4gICAgICAgICAgICA/IFsocG9pbnRbMF0gKyBuZXh0UG9pbnRbMF0pIC8gMiwgKHBvaW50WzFdICsgbmV4dFBvaW50WzFdKSAvIDJdXG4gICAgICAgICAgICA6IFtwb2ludFswXSwgcG9pbnRbMV1dLFxuICAgICAgICApO1xuXG4gICAgICAgIG5leHRTZWxlY3RlZEluZGljZXMucHVzaChpbmRleEN1cnNvciArIDEpO1xuICAgICAgICArK2luZGV4Q3Vyc29yO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdKTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwgeyBwb2ludHM6IG5leHRQb2ludHMgfSk7XG5cbiAgICAvLyB0ZW1wIGhhY2sgdG8gZW5zdXJlIHRoZSBsaW5lIGRvZXNuJ3QgbW92ZSB3aGVuIGFkZGluZyBwb2ludCB0byB0aGUgZW5kLFxuICAgIC8vIHBvdGVudGlhbGx5IGV4cGFuZGluZyB0aGUgYm91bmRpbmcgYm94XG4gICAgaWYgKHBvaW50QWRkZWRUb0VuZCkge1xuICAgICAgY29uc3QgbGFzdFBvaW50ID0gZWxlbWVudC5wb2ludHNbZWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV07XG4gICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLm1vdmVQb2ludHMoZWxlbWVudCwgW1xuICAgICAgICB7XG4gICAgICAgICAgaW5kZXg6IGVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDEsXG4gICAgICAgICAgcG9pbnQ6IFtsYXN0UG9pbnRbMF0gKyAzMCwgbGFzdFBvaW50WzFdICsgMzBdLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgIC4uLmFwcFN0YXRlLFxuICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgIC4uLmFwcFN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogbmV4dFNlbGVjdGVkSW5kaWNlcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBkZWxldGVQb2ludHMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgcG9pbnRJbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSxcbiAgKSB7XG4gICAgbGV0IG9mZnNldFggPSAwO1xuICAgIGxldCBvZmZzZXRZID0gMDtcblxuICAgIGNvbnN0IGlzRGVsZXRpbmdPcmlnaW5Qb2ludCA9IHBvaW50SW5kaWNlcy5pbmNsdWRlcygwKTtcblxuICAgIC8vIGlmIGRlbGV0aW5nIGZpcnN0IHBvaW50LCBtYWtlIHRoZSBuZXh0IHRvIGJlIFswLDBdIGFuZCByZWNhbGN1bGF0ZVxuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGUgcmVzdCB3aXRoIHJlc3BlY3QgdG8gaXRcbiAgICBpZiAoaXNEZWxldGluZ09yaWdpblBvaW50KSB7XG4gICAgICBjb25zdCBmaXJzdE5vbkRlbGV0ZWRQb2ludCA9IGVsZW1lbnQucG9pbnRzLmZpbmQoKHBvaW50LCBpZHgpID0+IHtcbiAgICAgICAgcmV0dXJuICFwb2ludEluZGljZXMuaW5jbHVkZXMoaWR4KTtcbiAgICAgIH0pO1xuICAgICAgaWYgKGZpcnN0Tm9uRGVsZXRlZFBvaW50KSB7XG4gICAgICAgIG9mZnNldFggPSBmaXJzdE5vbkRlbGV0ZWRQb2ludFswXTtcbiAgICAgICAgb2Zmc2V0WSA9IGZpcnN0Tm9uRGVsZXRlZFBvaW50WzFdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG5leHRQb2ludHMgPSBlbGVtZW50LnBvaW50cy5yZWR1Y2UoKGFjYzogUG9pbnRbXSwgcG9pbnQsIGlkeCkgPT4ge1xuICAgICAgaWYgKCFwb2ludEluZGljZXMuaW5jbHVkZXMoaWR4KSkge1xuICAgICAgICBhY2MucHVzaChcbiAgICAgICAgICAhYWNjLmxlbmd0aCA/IFswLCAwXSA6IFtwb2ludFswXSAtIG9mZnNldFgsIHBvaW50WzFdIC0gb2Zmc2V0WV0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdKTtcblxuICAgIExpbmVhckVsZW1lbnRFZGl0b3IuX3VwZGF0ZVBvaW50cyhlbGVtZW50LCBuZXh0UG9pbnRzLCBvZmZzZXRYLCBvZmZzZXRZKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRQb2ludHMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgdGFyZ2V0UG9pbnRzOiB7IHBvaW50OiBQb2ludCB9W10sXG4gICkge1xuICAgIGNvbnN0IG9mZnNldFggPSAwO1xuICAgIGNvbnN0IG9mZnNldFkgPSAwO1xuXG4gICAgY29uc3QgbmV4dFBvaW50cyA9IFsuLi5lbGVtZW50LnBvaW50cywgLi4udGFyZ2V0UG9pbnRzLm1hcCgoeCkgPT4geC5wb2ludCldO1xuXG4gICAgTGluZWFyRWxlbWVudEVkaXRvci5fdXBkYXRlUG9pbnRzKGVsZW1lbnQsIG5leHRQb2ludHMsIG9mZnNldFgsIG9mZnNldFkpO1xuICB9XG5cbiAgc3RhdGljIG1vdmVQb2ludHMoXG4gICAgZWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgdGFyZ2V0UG9pbnRzOiB7IGluZGV4OiBudW1iZXI7IHBvaW50OiBQb2ludDsgaXNEcmFnZ2luZz86IGJvb2xlYW4gfVtdLFxuICAgIG90aGVyVXBkYXRlcz86IHsgc3RhcnRCaW5kaW5nPzogUG9pbnRCaW5kaW5nOyBlbmRCaW5kaW5nPzogUG9pbnRCaW5kaW5nIH0sXG4gICkge1xuICAgIGNvbnN0IHsgcG9pbnRzIH0gPSBlbGVtZW50O1xuXG4gICAgLy8gaW4gY2FzZSB3ZSdyZSBtb3Zpbmcgc3RhcnQgcG9pbnQsIGluc3RlYWQgb2YgbW9kaWZ5aW5nIGl0cyBwb3NpdGlvblxuICAgIC8vIHdoaWNoIHdvdWxkIGJyZWFrIHRoZSBpbnZhcmlhbnQgb2YgaXQgYmVpbmcgYXQgWzAsMF0sIHdlIG1vdmVcbiAgICAvLyBhbGwgdGhlIG90aGVyIHBvaW50cyBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uIGJ5IGRlbHRhIHRvXG4gICAgLy8gb2Zmc2V0IGl0LiBXZSBkbyB0aGUgc2FtZSB3aXRoIGFjdHVhbCBlbGVtZW50LngveSBwb3NpdGlvbiwgc29cbiAgICAvLyB0aGlzIGhhY2tzIGFyZSBjb21wbGV0ZWx5IHRyYW5zcGFyZW50IHRvIHRoZSB1c2VyLlxuICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICBjb25zdCBzZWxlY3RlZE9yaWdpblBvaW50ID0gdGFyZ2V0UG9pbnRzLmZpbmQoKHsgaW5kZXggfSkgPT4gaW5kZXggPT09IDApO1xuXG4gICAgaWYgKHNlbGVjdGVkT3JpZ2luUG9pbnQpIHtcbiAgICAgIG9mZnNldFggPVxuICAgICAgICBzZWxlY3RlZE9yaWdpblBvaW50LnBvaW50WzBdICsgcG9pbnRzW3NlbGVjdGVkT3JpZ2luUG9pbnQuaW5kZXhdWzBdO1xuICAgICAgb2Zmc2V0WSA9XG4gICAgICAgIHNlbGVjdGVkT3JpZ2luUG9pbnQucG9pbnRbMV0gKyBwb2ludHNbc2VsZWN0ZWRPcmlnaW5Qb2ludC5pbmRleF1bMV07XG4gICAgfVxuXG4gICAgY29uc3QgbmV4dFBvaW50cyA9IHBvaW50cy5tYXAoKHBvaW50LCBpZHgpID0+IHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkUG9pbnREYXRhID0gdGFyZ2V0UG9pbnRzLmZpbmQoKHApID0+IHAuaW5kZXggPT09IGlkeCk7XG4gICAgICBpZiAoc2VsZWN0ZWRQb2ludERhdGEpIHtcbiAgICAgICAgaWYgKHNlbGVjdGVkT3JpZ2luUG9pbnQpIHtcbiAgICAgICAgICByZXR1cm4gcG9pbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZWx0YVggPVxuICAgICAgICAgIHNlbGVjdGVkUG9pbnREYXRhLnBvaW50WzBdIC0gcG9pbnRzW3NlbGVjdGVkUG9pbnREYXRhLmluZGV4XVswXTtcbiAgICAgICAgY29uc3QgZGVsdGFZID1cbiAgICAgICAgICBzZWxlY3RlZFBvaW50RGF0YS5wb2ludFsxXSAtIHBvaW50c1tzZWxlY3RlZFBvaW50RGF0YS5pbmRleF1bMV07XG5cbiAgICAgICAgcmV0dXJuIFtwb2ludFswXSArIGRlbHRhWCwgcG9pbnRbMV0gKyBkZWx0YVldIGFzIGNvbnN0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9mZnNldFggfHwgb2Zmc2V0WVxuICAgICAgICA/IChbcG9pbnRbMF0gLSBvZmZzZXRYLCBwb2ludFsxXSAtIG9mZnNldFldIGFzIGNvbnN0KVxuICAgICAgICA6IHBvaW50O1xuICAgIH0pO1xuXG4gICAgTGluZWFyRWxlbWVudEVkaXRvci5fdXBkYXRlUG9pbnRzKFxuICAgICAgZWxlbWVudCxcbiAgICAgIG5leHRQb2ludHMsXG4gICAgICBvZmZzZXRYLFxuICAgICAgb2Zmc2V0WSxcbiAgICAgIG90aGVyVXBkYXRlcyxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX3VwZGF0ZVBvaW50cyhcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICBuZXh0UG9pbnRzOiByZWFkb25seSBQb2ludFtdLFxuICAgIG9mZnNldFg6IG51bWJlcixcbiAgICBvZmZzZXRZOiBudW1iZXIsXG4gICAgb3RoZXJVcGRhdGVzPzogeyBzdGFydEJpbmRpbmc/OiBQb2ludEJpbmRpbmc7IGVuZEJpbmRpbmc/OiBQb2ludEJpbmRpbmcgfSxcbiAgKSB7XG4gICAgY29uc3QgbmV4dENvb3JkcyA9IGdldEVsZW1lbnRQb2ludHNDb29yZHMoXG4gICAgICBlbGVtZW50LFxuICAgICAgbmV4dFBvaW50cyxcbiAgICAgIGVsZW1lbnQuc3Ryb2tlU2hhcnBuZXNzIHx8IFwicm91bmRcIixcbiAgICApO1xuICAgIGNvbnN0IHByZXZDb29yZHMgPSBnZXRFbGVtZW50UG9pbnRzQ29vcmRzKFxuICAgICAgZWxlbWVudCxcbiAgICAgIGVsZW1lbnQucG9pbnRzLFxuICAgICAgZWxlbWVudC5zdHJva2VTaGFycG5lc3MgfHwgXCJyb3VuZFwiLFxuICAgICk7XG4gICAgY29uc3QgbmV4dENlbnRlclggPSAobmV4dENvb3Jkc1swXSArIG5leHRDb29yZHNbMl0pIC8gMjtcbiAgICBjb25zdCBuZXh0Q2VudGVyWSA9IChuZXh0Q29vcmRzWzFdICsgbmV4dENvb3Jkc1szXSkgLyAyO1xuICAgIGNvbnN0IHByZXZDZW50ZXJYID0gKHByZXZDb29yZHNbMF0gKyBwcmV2Q29vcmRzWzJdKSAvIDI7XG4gICAgY29uc3QgcHJldkNlbnRlclkgPSAocHJldkNvb3Jkc1sxXSArIHByZXZDb29yZHNbM10pIC8gMjtcbiAgICBjb25zdCBkWCA9IHByZXZDZW50ZXJYIC0gbmV4dENlbnRlclg7XG4gICAgY29uc3QgZFkgPSBwcmV2Q2VudGVyWSAtIG5leHRDZW50ZXJZO1xuICAgIGNvbnN0IHJvdGF0ZWQgPSByb3RhdGUob2Zmc2V0WCwgb2Zmc2V0WSwgZFgsIGRZLCBlbGVtZW50LmFuZ2xlKTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgLi4ub3RoZXJVcGRhdGVzLFxuICAgICAgcG9pbnRzOiBuZXh0UG9pbnRzLFxuICAgICAgeDogZWxlbWVudC54ICsgcm90YXRlZFswXSxcbiAgICAgIHk6IGVsZW1lbnQueSArIHJvdGF0ZWRbMV0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBfZ2V0U2hpZnRMb2NrZWREZWx0YShcbiAgICBlbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICByZWZlcmVuY2VQb2ludDogUG9pbnQsXG4gICAgc2NlbmVQb2ludGVyOiBQb2ludCxcbiAgICBncmlkU2l6ZTogbnVtYmVyIHwgbnVsbCxcbiAgKSB7XG4gICAgY29uc3QgcmVmZXJlbmNlUG9pbnRDb29yZHMgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICBlbGVtZW50LFxuICAgICAgcmVmZXJlbmNlUG9pbnQsXG4gICAgKTtcblxuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgc2NlbmVQb2ludGVyWzBdLFxuICAgICAgc2NlbmVQb2ludGVyWzFdLFxuICAgICAgZ3JpZFNpemUsXG4gICAgKTtcblxuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gZ2V0TG9ja2VkTGluZWFyQ3Vyc29yQWxpZ25TaXplKFxuICAgICAgcmVmZXJlbmNlUG9pbnRDb29yZHNbMF0sXG4gICAgICByZWZlcmVuY2VQb2ludENvb3Jkc1sxXSxcbiAgICAgIGdyaWRYLFxuICAgICAgZ3JpZFksXG4gICAgKTtcblxuICAgIHJldHVybiByb3RhdGVQb2ludChbd2lkdGgsIGhlaWdodF0sIFswLCAwXSwgLWVsZW1lbnQuYW5nbGUpO1xuICB9XG59XG5cbmNvbnN0IG5vcm1hbGl6ZVNlbGVjdGVkUG9pbnRzID0gKFxuICBwb2ludHM6IChudW1iZXIgfCBudWxsKVtdLFxuKTogbnVtYmVyW10gfCBudWxsID0+IHtcbiAgbGV0IG5leHRQb2ludHMgPSBbXG4gICAgLi4ubmV3IFNldChwb2ludHMuZmlsdGVyKChwKSA9PiBwICE9PSBudWxsICYmIHAgIT09IC0xKSksXG4gIF0gYXMgbnVtYmVyW107XG4gIG5leHRQb2ludHMgPSBuZXh0UG9pbnRzLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgcmV0dXJuIG5leHRQb2ludHMubGVuZ3RoID8gbmV4dFBvaW50cyA6IG51bGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../element/linearElementEditor.ts\n");
2858
2858
 
2859
2859
  /***/ }),
2860
2860
 
@@ -2920,7 +2920,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2920
2920
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2921
2921
 
2922
2922
  "use strict";
2923
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getLockedLinearCursorAlignSize\": () => (/* binding */ getLockedLinearCursorAlignSize),\n/* harmony export */ \"getNormalizedDimensions\": () => (/* binding */ getNormalizedDimensions),\n/* harmony export */ \"getPerfectElementSize\": () => (/* binding */ getPerfectElementSize),\n/* harmony export */ \"isInvisiblySmallElement\": () => (/* binding */ isInvisiblySmallElement),\n/* harmony export */ \"resizePerfectLineForNWHandler\": () => (/* binding */ resizePerfectLineForNWHandler)\n/* harmony export */ });\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n\n\n\nconst isInvisiblySmallElement = (element) => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isFreeDrawElement)(element)) {\n return element.points.length < 2;\n }\n return element.width === 0 && element.height === 0;\n};\n/**\n * Makes a perfect shape or diagonal/horizontal/vertical line\n */\nconst getPerfectElementSize = (elementType, width, height) => {\n const absWidth = Math.abs(width);\n const absHeight = Math.abs(height);\n if (elementType === \"line\" ||\n elementType === \"arrow\" ||\n elementType === \"freedraw\") {\n const lockedAngle = Math.round(Math.atan(absHeight / absWidth) / _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE) *\n _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE;\n if (lockedAngle === 0) {\n height = 0;\n }\n else if (lockedAngle === Math.PI / 2) {\n width = 0;\n }\n else {\n height =\n Math.round(absWidth * Math.tan(lockedAngle)) * Math.sign(height) ||\n height;\n }\n }\n else if (elementType !== \"selection\") {\n height = absWidth * Math.sign(height);\n }\n return { width, height };\n};\nconst getLockedLinearCursorAlignSize = (originX, originY, x, y) => {\n let width = x - originX;\n let height = y - originY;\n const lockedAngle = Math.round(Math.atan(height / width) / _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE) *\n _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE;\n if (lockedAngle === 0) {\n height = 0;\n }\n else if (lockedAngle === Math.PI / 2) {\n width = 0;\n }\n else {\n // locked angle line, y = mx + b => mx - y + b = 0\n const a1 = Math.tan(lockedAngle);\n const b1 = -1;\n const c1 = originY - a1 * originX;\n // line through cursor, perpendicular to locked angle line\n const a2 = -1 / a1;\n const b2 = -1;\n const c2 = y - a2 * x;\n // intersection of the two lines above\n const intersectX = Math.round((b1 * c2 - b2 * c1) / (a1 * b2 - a2 * b1));\n const intersectY = Math.round((c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1));\n // delta\n width = intersectX - originX;\n height = intersectY - originY;\n }\n return { width, height };\n};\nconst resizePerfectLineForNWHandler = (element, x, y) => {\n const anchorX = element.x + element.width;\n const anchorY = element.y + element.height;\n const distanceToAnchorX = x - anchorX;\n const distanceToAnchorY = y - anchorY;\n if (Math.abs(distanceToAnchorX) < Math.abs(distanceToAnchorY) / 2) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_0__.mutateElement)(element, {\n x: anchorX,\n width: 0,\n y,\n height: -distanceToAnchorY,\n });\n }\n else if (Math.abs(distanceToAnchorY) < Math.abs(element.width) / 2) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_0__.mutateElement)(element, {\n y: anchorY,\n height: 0,\n });\n }\n else {\n const nextHeight = Math.sign(distanceToAnchorY) *\n Math.sign(distanceToAnchorX) *\n element.width;\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_0__.mutateElement)(element, {\n x,\n y: anchorY - nextHeight,\n width: -distanceToAnchorX,\n height: nextHeight,\n });\n }\n};\nconst getNormalizedDimensions = (element) => {\n const ret = {\n width: element.width,\n height: element.height,\n x: element.x,\n y: element.y,\n };\n if (element.width < 0) {\n const nextWidth = Math.abs(element.width);\n ret.width = nextWidth;\n ret.x = element.x - nextWidth;\n }\n if (element.height < 0) {\n const nextHeight = Math.abs(element.height);\n ret.height = nextHeight;\n ret.y = element.y - nextHeight;\n }\n return ret;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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R0FBRyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7UUFDdEIsR0FBRyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztLQUMvQjtJQUVELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDdEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDNUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUM7UUFDeEIsR0FBRyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQztLQUNoQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL2VsZW1lbnQvc2l6ZUhlbHBlcnMudHM/ZTUyNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFeGNhbGlkcmF3RWxlbWVudCB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBtdXRhdGVFbGVtZW50IH0gZnJvbSBcIi4vbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHsgaXNGcmVlRHJhd0VsZW1lbnQsIGlzTGluZWFyRWxlbWVudCB9IGZyb20gXCIuL3R5cGVDaGVja3NcIjtcbmltcG9ydCB7IFNISUZUX0xPQ0tJTkdfQU5HTEUgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBBcHBTdGF0ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQgPSAoXG4gIGVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50LFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChpc0xpbmVhckVsZW1lbnQoZWxlbWVudCkgfHwgaXNGcmVlRHJhd0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZWxlbWVudC5wb2ludHMubGVuZ3RoIDwgMjtcbiAgfVxuICByZXR1cm4gZWxlbWVudC53aWR0aCA9PT0gMCAmJiBlbGVtZW50LmhlaWdodCA9PT0gMDtcbn07XG5cbi8qKlxuICogTWFrZXMgYSBwZXJmZWN0IHNoYXBlIG9yIGRpYWdvbmFsL2hvcml6b250YWwvdmVydGljYWwgbGluZVxuICovXG5leHBvcnQgY29uc3QgZ2V0UGVyZmVjdEVsZW1lbnRTaXplID0gKFxuICBlbGVtZW50VHlwZTogQXBwU3RhdGVbXCJhY3RpdmVUb29sXCJdW1widHlwZVwiXSxcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4pOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0gPT4ge1xuICBjb25zdCBhYnNXaWR0aCA9IE1hdGguYWJzKHdpZHRoKTtcbiAgY29uc3QgYWJzSGVpZ2h0ID0gTWF0aC5hYnMoaGVpZ2h0KTtcblxuICBpZiAoXG4gICAgZWxlbWVudFR5cGUgPT09IFwibGluZVwiIHx8XG4gICAgZWxlbWVudFR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgIGVsZW1lbnRUeXBlID09PSBcImZyZWVkcmF3XCJcbiAgKSB7XG4gICAgY29uc3QgbG9ja2VkQW5nbGUgPVxuICAgICAgTWF0aC5yb3VuZChNYXRoLmF0YW4oYWJzSGVpZ2h0IC8gYWJzV2lkdGgpIC8gU0hJRlRfTE9DS0lOR19BTkdMRSkgKlxuICAgICAgU0hJRlRfTE9DS0lOR19BTkdMRTtcbiAgICBpZiAobG9ja2VkQW5nbGUgPT09IDApIHtcbiAgICAgIGhlaWdodCA9IDA7XG4gICAgfSBlbHNlIGlmIChsb2NrZWRBbmdsZSA9PT0gTWF0aC5QSSAvIDIpIHtcbiAgICAgIHdpZHRoID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID1cbiAgICAgICAgTWF0aC5yb3VuZChhYnNXaWR0aCAqIE1hdGgudGFuKGxvY2tlZEFuZ2xlKSkgKiBNYXRoLnNpZ24oaGVpZ2h0KSB8fFxuICAgICAgICBoZWlnaHQ7XG4gICAgfVxuICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgaGVpZ2h0ID0gYWJzV2lkdGggKiBNYXRoLnNpZ24oaGVpZ2h0KTtcbiAgfVxuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0IH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0TG9ja2VkTGluZWFyQ3Vyc29yQWxpZ25TaXplID0gKFxuICBvcmlnaW5YOiBudW1iZXIsXG4gIG9yaWdpblk6IG51bWJlcixcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4pID0+IHtcbiAgbGV0IHdpZHRoID0geCAtIG9yaWdpblg7XG4gIGxldCBoZWlnaHQgPSB5IC0gb3JpZ2luWTtcblxuICBjb25zdCBsb2NrZWRBbmdsZSA9XG4gICAgTWF0aC5yb3VuZChNYXRoLmF0YW4oaGVpZ2h0IC8gd2lkdGgpIC8gU0hJRlRfTE9DS0lOR19BTkdMRSkgKlxuICAgIFNISUZUX0xPQ0tJTkdfQU5HTEU7XG5cbiAgaWYgKGxvY2tlZEFuZ2xlID09PSAwKSB7XG4gICAgaGVpZ2h0ID0gMDtcbiAgfSBlbHNlIGlmIChsb2NrZWRBbmdsZSA9PT0gTWF0aC5QSSAvIDIpIHtcbiAgICB3aWR0aCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gbG9ja2VkIGFuZ2xlIGxpbmUsIHkgPSBteCArIGIgPT4gbXggLSB5ICsgYiA9IDBcbiAgICBjb25zdCBhMSA9IE1hdGgudGFuKGxvY2tlZEFuZ2xlKTtcbiAgICBjb25zdCBiMSA9IC0xO1xuICAgIGNvbnN0IGMxID0gb3JpZ2luWSAtIGExICogb3JpZ2luWDtcblxuICAgIC8vIGxpbmUgdGhyb3VnaCBjdXJzb3IsIHBlcnBlbmRpY3VsYXIgdG8gbG9ja2VkIGFuZ2xlIGxpbmVcbiAgICBjb25zdCBhMiA9IC0xIC8gYTE7XG4gICAgY29uc3QgYjIgPSAtMTtcbiAgICBjb25zdCBjMiA9IHkgLSBhMiAqIHg7XG5cbiAgICAvLyBpbnRlcnNlY3Rpb24gb2YgdGhlIHR3byBsaW5lcyBhYm92ZVxuICAgIGNvbnN0IGludGVyc2VjdFggPSBNYXRoLnJvdW5kKChiMSAqIGMyIC0gYjIgKiBjMSkgLyAoYTEgKiBiMiAtIGEyICogYjEpKTtcbiAgICBjb25zdCBpbnRlcnNlY3RZID0gTWF0aC5yb3VuZCgoYzEgKiBhMiAtIGMyICogYTEpIC8gKGExICogYjIgLSBhMiAqIGIxKSk7XG5cbiAgICAvLyBkZWx0YVxuICAgIHdpZHRoID0gaW50ZXJzZWN0WCAtIG9yaWdpblg7XG4gICAgaGVpZ2h0ID0gaW50ZXJzZWN0WSAtIG9yaWdpblk7XG4gIH1cblxuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0IH07XG59O1xuXG5leHBvcnQgY29uc3QgcmVzaXplUGVyZmVjdExpbmVGb3JOV0hhbmRsZXIgPSAoXG4gIGVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50LFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbikgPT4ge1xuICBjb25zdCBhbmNob3JYID0gZWxlbWVudC54ICsgZWxlbWVudC53aWR0aDtcbiAgY29uc3QgYW5jaG9yWSA9IGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0O1xuICBjb25zdCBkaXN0YW5jZVRvQW5jaG9yWCA9IHggLSBhbmNob3JYO1xuICBjb25zdCBkaXN0YW5jZVRvQW5jaG9yWSA9IHkgLSBhbmNob3JZO1xuICBpZiAoTWF0aC5hYnMoZGlzdGFuY2VUb0FuY2hvclgpIDwgTWF0aC5hYnMoZGlzdGFuY2VUb0FuY2hvclkpIC8gMikge1xuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgeDogYW5jaG9yWCxcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgeSxcbiAgICAgIGhlaWdodDogLWRpc3RhbmNlVG9BbmNob3JZLFxuICAgIH0pO1xuICB9IGVsc2UgaWYgKE1hdGguYWJzKGRpc3RhbmNlVG9BbmNob3JZKSA8IE1hdGguYWJzKGVsZW1lbnQud2lkdGgpIC8gMikge1xuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgeTogYW5jaG9yWSxcbiAgICAgIGhlaWdodDogMCxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBuZXh0SGVpZ2h0ID1cbiAgICAgIE1hdGguc2lnbihkaXN0YW5jZVRvQW5jaG9yWSkgKlxuICAgICAgTWF0aC5zaWduKGRpc3RhbmNlVG9BbmNob3JYKSAqXG4gICAgICBlbGVtZW50LndpZHRoO1xuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgeCxcbiAgICAgIHk6IGFuY2hvclkgLSBuZXh0SGVpZ2h0LFxuICAgICAgd2lkdGg6IC1kaXN0YW5jZVRvQW5jaG9yWCxcbiAgICAgIGhlaWdodDogbmV4dEhlaWdodCxcbiAgICB9KTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGdldE5vcm1hbGl6ZWREaW1lbnNpb25zID0gKFxuICBlbGVtZW50OiBQaWNrPEV4Y2FsaWRyYXdFbGVtZW50LCBcIndpZHRoXCIgfCBcImhlaWdodFwiIHwgXCJ4XCIgfCBcInlcIj4sXG4pOiB7XG4gIHdpZHRoOiBFeGNhbGlkcmF3RWxlbWVudFtcIndpZHRoXCJdO1xuICBoZWlnaHQ6IEV4Y2FsaWRyYXdFbGVtZW50W1wiaGVpZ2h0XCJdO1xuICB4OiBFeGNhbGlkcmF3RWxlbWVudFtcInhcIl07XG4gIHk6IEV4Y2FsaWRyYXdFbGVtZW50W1wieVwiXTtcbn0gPT4ge1xuICBjb25zdCByZXQgPSB7XG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICB4OiBlbGVtZW50LngsXG4gICAgeTogZWxlbWVudC55LFxuICB9O1xuXG4gIGlmIChlbGVtZW50LndpZHRoIDwgMCkge1xuICAgIGNvbnN0IG5leHRXaWR0aCA9IE1hdGguYWJzKGVsZW1lbnQud2lkdGgpO1xuICAgIHJldC53aWR0aCA9IG5leHRXaWR0aDtcbiAgICByZXQueCA9IGVsZW1lbnQueCAtIG5leHRXaWR0aDtcbiAgfVxuXG4gIGlmIChlbGVtZW50LmhlaWdodCA8IDApIHtcbiAgICBjb25zdCBuZXh0SGVpZ2h0ID0gTWF0aC5hYnMoZWxlbWVudC5oZWlnaHQpO1xuICAgIHJldC5oZWlnaHQgPSBuZXh0SGVpZ2h0O1xuICAgIHJldC55ID0gZWxlbWVudC55IC0gbmV4dEhlaWdodDtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../element/sizeHelpers.ts\n");
2923
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getLockedLinearCursorAlignSize\": () => (/* binding */ getLockedLinearCursorAlignSize),\n/* harmony export */ \"getNormalizedDimensions\": () => (/* binding */ getNormalizedDimensions),\n/* harmony export */ \"getPerfectElementSize\": () => (/* binding */ getPerfectElementSize),\n/* harmony export */ \"isInvisiblySmallElement\": () => (/* binding */ isInvisiblySmallElement),\n/* harmony export */ \"resizePerfectLineForNWHandler\": () => (/* binding */ resizePerfectLineForNWHandler)\n/* harmony export */ });\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n\n\n\nconst isInvisiblySmallElement = (element) => {\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isLinearElement)(element) || (0,_typeChecks__WEBPACK_IMPORTED_MODULE_1__.isFreeDrawElement)(element)) {\n return element.points.length < 2;\n }\n return element.width === 0 && element.height === 0;\n};\n/**\n * Makes a perfect shape or diagonal/horizontal/vertical line\n */\nconst getPerfectElementSize = (elementType, width, height) => {\n const absWidth = Math.abs(width);\n const absHeight = Math.abs(height);\n if (elementType === \"line\" ||\n elementType === \"arrow\" ||\n elementType === \"freedraw\") {\n const lockedAngle = Math.round(Math.atan(absHeight / absWidth) / _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE) *\n _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE;\n if (lockedAngle === 0) {\n height = 0;\n }\n else if (lockedAngle === Math.PI / 2) {\n width = 0;\n }\n else {\n height = absWidth * Math.tan(lockedAngle) * Math.sign(height) || height;\n }\n }\n else if (elementType !== \"selection\") {\n height = absWidth * Math.sign(height);\n }\n return { width, height };\n};\nconst getLockedLinearCursorAlignSize = (originX, originY, x, y) => {\n let width = x - originX;\n let height = y - originY;\n const lockedAngle = Math.round(Math.atan(height / width) / _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE) *\n _constants__WEBPACK_IMPORTED_MODULE_2__.SHIFT_LOCKING_ANGLE;\n if (lockedAngle === 0) {\n height = 0;\n }\n else if (lockedAngle === Math.PI / 2) {\n width = 0;\n }\n else {\n // locked angle line, y = mx + b => mx - y + b = 0\n const a1 = Math.tan(lockedAngle);\n const b1 = -1;\n const c1 = originY - a1 * originX;\n // line through cursor, perpendicular to locked angle line\n const a2 = -1 / a1;\n const b2 = -1;\n const c2 = y - a2 * x;\n // intersection of the two lines above\n const intersectX = (b1 * c2 - b2 * c1) / (a1 * b2 - a2 * b1);\n const intersectY = (c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1);\n // delta\n width = intersectX - originX;\n height = intersectY - originY;\n }\n return { width, height };\n};\nconst resizePerfectLineForNWHandler = (element, x, y) => {\n const anchorX = element.x + element.width;\n const anchorY = element.y + element.height;\n const distanceToAnchorX = x - anchorX;\n const distanceToAnchorY = y - anchorY;\n if (Math.abs(distanceToAnchorX) < Math.abs(distanceToAnchorY) / 2) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_0__.mutateElement)(element, {\n x: anchorX,\n width: 0,\n y,\n height: -distanceToAnchorY,\n });\n }\n else if (Math.abs(distanceToAnchorY) < Math.abs(element.width) / 2) {\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_0__.mutateElement)(element, {\n y: anchorY,\n height: 0,\n });\n }\n else {\n const nextHeight = Math.sign(distanceToAnchorY) *\n Math.sign(distanceToAnchorX) *\n element.width;\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_0__.mutateElement)(element, {\n x,\n y: anchorY - nextHeight,\n width: -distanceToAnchorX,\n height: nextHeight,\n });\n }\n};\nconst getNormalizedDimensions = (element) => {\n const ret = {\n width: element.width,\n height: element.height,\n x: element.x,\n y: element.y,\n };\n if (element.width < 0) {\n const nextWidth = Math.abs(element.width);\n ret.width = nextWidth;\n ret.x = element.x - nextWidth;\n }\n if (element.height < 0) {\n const nextHeight = Math.abs(element.height);\n ret.height = nextHeight;\n ret.y = element.y - nextHeight;\n }\n return ret;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFTLENBQUM7S0FDL0I7SUFFRCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3RCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDO1FBQ3hCLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUM7S0FDaEM7SUFFRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9lbGVtZW50L3NpemVIZWxwZXJzLnRzP2U1MjYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXhjYWxpZHJhd0VsZW1lbnQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgbXV0YXRlRWxlbWVudCB9IGZyb20gXCIuL211dGF0ZUVsZW1lbnRcIjtcbmltcG9ydCB7IGlzRnJlZURyYXdFbGVtZW50LCBpc0xpbmVhckVsZW1lbnQgfSBmcm9tIFwiLi90eXBlQ2hlY2tzXCI7XG5pbXBvcnQgeyBTSElGVF9MT0NLSU5HX0FOR0xFIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQXBwU3RhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IGlzSW52aXNpYmx5U21hbGxFbGVtZW50ID0gKFxuICBlbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCxcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoaXNMaW5lYXJFbGVtZW50KGVsZW1lbnQpIHx8IGlzRnJlZURyYXdFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQucG9pbnRzLmxlbmd0aCA8IDI7XG4gIH1cbiAgcmV0dXJuIGVsZW1lbnQud2lkdGggPT09IDAgJiYgZWxlbWVudC5oZWlnaHQgPT09IDA7XG59O1xuXG4vKipcbiAqIE1ha2VzIGEgcGVyZmVjdCBzaGFwZSBvciBkaWFnb25hbC9ob3Jpem9udGFsL3ZlcnRpY2FsIGxpbmVcbiAqL1xuZXhwb3J0IGNvbnN0IGdldFBlcmZlY3RFbGVtZW50U2l6ZSA9IChcbiAgZWxlbWVudFR5cGU6IEFwcFN0YXRlW1wiYWN0aXZlVG9vbFwiXVtcInR5cGVcIl0sXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuKTogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9ID0+IHtcbiAgY29uc3QgYWJzV2lkdGggPSBNYXRoLmFicyh3aWR0aCk7XG4gIGNvbnN0IGFic0hlaWdodCA9IE1hdGguYWJzKGhlaWdodCk7XG5cbiAgaWYgKFxuICAgIGVsZW1lbnRUeXBlID09PSBcImxpbmVcIiB8fFxuICAgIGVsZW1lbnRUeXBlID09PSBcImFycm93XCIgfHxcbiAgICBlbGVtZW50VHlwZSA9PT0gXCJmcmVlZHJhd1wiXG4gICkge1xuICAgIGNvbnN0IGxvY2tlZEFuZ2xlID1cbiAgICAgIE1hdGgucm91bmQoTWF0aC5hdGFuKGFic0hlaWdodCAvIGFic1dpZHRoKSAvIFNISUZUX0xPQ0tJTkdfQU5HTEUpICpcbiAgICAgIFNISUZUX0xPQ0tJTkdfQU5HTEU7XG4gICAgaWYgKGxvY2tlZEFuZ2xlID09PSAwKSB7XG4gICAgICBoZWlnaHQgPSAwO1xuICAgIH0gZWxzZSBpZiAobG9ja2VkQW5nbGUgPT09IE1hdGguUEkgLyAyKSB7XG4gICAgICB3aWR0aCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhlaWdodCA9IGFic1dpZHRoICogTWF0aC50YW4obG9ja2VkQW5nbGUpICogTWF0aC5zaWduKGhlaWdodCkgfHwgaGVpZ2h0O1xuICAgIH1cbiAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgIGhlaWdodCA9IGFic1dpZHRoICogTWF0aC5zaWduKGhlaWdodCk7XG4gIH1cbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZSA9IChcbiAgb3JpZ2luWDogbnVtYmVyLFxuICBvcmlnaW5ZOiBudW1iZXIsXG4gIHg6IG51bWJlcixcbiAgeTogbnVtYmVyLFxuKSA9PiB7XG4gIGxldCB3aWR0aCA9IHggLSBvcmlnaW5YO1xuICBsZXQgaGVpZ2h0ID0geSAtIG9yaWdpblk7XG5cbiAgY29uc3QgbG9ja2VkQW5nbGUgPVxuICAgIE1hdGgucm91bmQoTWF0aC5hdGFuKGhlaWdodCAvIHdpZHRoKSAvIFNISUZUX0xPQ0tJTkdfQU5HTEUpICpcbiAgICBTSElGVF9MT0NLSU5HX0FOR0xFO1xuXG4gIGlmIChsb2NrZWRBbmdsZSA9PT0gMCkge1xuICAgIGhlaWdodCA9IDA7XG4gIH0gZWxzZSBpZiAobG9ja2VkQW5nbGUgPT09IE1hdGguUEkgLyAyKSB7XG4gICAgd2lkdGggPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIGxvY2tlZCBhbmdsZSBsaW5lLCB5ID0gbXggKyBiID0+IG14IC0geSArIGIgPSAwXG4gICAgY29uc3QgYTEgPSBNYXRoLnRhbihsb2NrZWRBbmdsZSk7XG4gICAgY29uc3QgYjEgPSAtMTtcbiAgICBjb25zdCBjMSA9IG9yaWdpblkgLSBhMSAqIG9yaWdpblg7XG5cbiAgICAvLyBsaW5lIHRocm91Z2ggY3Vyc29yLCBwZXJwZW5kaWN1bGFyIHRvIGxvY2tlZCBhbmdsZSBsaW5lXG4gICAgY29uc3QgYTIgPSAtMSAvIGExO1xuICAgIGNvbnN0IGIyID0gLTE7XG4gICAgY29uc3QgYzIgPSB5IC0gYTIgKiB4O1xuXG4gICAgLy8gaW50ZXJzZWN0aW9uIG9mIHRoZSB0d28gbGluZXMgYWJvdmVcbiAgICBjb25zdCBpbnRlcnNlY3RYID0gKGIxICogYzIgLSBiMiAqIGMxKSAvIChhMSAqIGIyIC0gYTIgKiBiMSk7XG4gICAgY29uc3QgaW50ZXJzZWN0WSA9IChjMSAqIGEyIC0gYzIgKiBhMSkgLyAoYTEgKiBiMiAtIGEyICogYjEpO1xuXG4gICAgLy8gZGVsdGFcbiAgICB3aWR0aCA9IGludGVyc2VjdFggLSBvcmlnaW5YO1xuICAgIGhlaWdodCA9IGludGVyc2VjdFkgLSBvcmlnaW5ZO1xuICB9XG5cbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHJlc2l6ZVBlcmZlY3RMaW5lRm9yTldIYW5kbGVyID0gKFxuICBlbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCxcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4pID0+IHtcbiAgY29uc3QgYW5jaG9yWCA9IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGg7XG4gIGNvbnN0IGFuY2hvclkgPSBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodDtcbiAgY29uc3QgZGlzdGFuY2VUb0FuY2hvclggPSB4IC0gYW5jaG9yWDtcbiAgY29uc3QgZGlzdGFuY2VUb0FuY2hvclkgPSB5IC0gYW5jaG9yWTtcbiAgaWYgKE1hdGguYWJzKGRpc3RhbmNlVG9BbmNob3JYKSA8IE1hdGguYWJzKGRpc3RhbmNlVG9BbmNob3JZKSAvIDIpIHtcbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHg6IGFuY2hvclgsXG4gICAgICB3aWR0aDogMCxcbiAgICAgIHksXG4gICAgICBoZWlnaHQ6IC1kaXN0YW5jZVRvQW5jaG9yWSxcbiAgICB9KTtcbiAgfSBlbHNlIGlmIChNYXRoLmFicyhkaXN0YW5jZVRvQW5jaG9yWSkgPCBNYXRoLmFicyhlbGVtZW50LndpZHRoKSAvIDIpIHtcbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHk6IGFuY2hvclksXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgbmV4dEhlaWdodCA9XG4gICAgICBNYXRoLnNpZ24oZGlzdGFuY2VUb0FuY2hvclkpICpcbiAgICAgIE1hdGguc2lnbihkaXN0YW5jZVRvQW5jaG9yWCkgKlxuICAgICAgZWxlbWVudC53aWR0aDtcbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHgsXG4gICAgICB5OiBhbmNob3JZIC0gbmV4dEhlaWdodCxcbiAgICAgIHdpZHRoOiAtZGlzdGFuY2VUb0FuY2hvclgsXG4gICAgICBoZWlnaHQ6IG5leHRIZWlnaHQsXG4gICAgfSk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZXROb3JtYWxpemVkRGltZW5zaW9ucyA9IChcbiAgZWxlbWVudDogUGljazxFeGNhbGlkcmF3RWxlbWVudCwgXCJ3aWR0aFwiIHwgXCJoZWlnaHRcIiB8IFwieFwiIHwgXCJ5XCI+LFxuKToge1xuICB3aWR0aDogRXhjYWxpZHJhd0VsZW1lbnRbXCJ3aWR0aFwiXTtcbiAgaGVpZ2h0OiBFeGNhbGlkcmF3RWxlbWVudFtcImhlaWdodFwiXTtcbiAgeDogRXhjYWxpZHJhd0VsZW1lbnRbXCJ4XCJdO1xuICB5OiBFeGNhbGlkcmF3RWxlbWVudFtcInlcIl07XG59ID0+IHtcbiAgY29uc3QgcmV0ID0ge1xuICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgeDogZWxlbWVudC54LFxuICAgIHk6IGVsZW1lbnQueSxcbiAgfTtcblxuICBpZiAoZWxlbWVudC53aWR0aCA8IDApIHtcbiAgICBjb25zdCBuZXh0V2lkdGggPSBNYXRoLmFicyhlbGVtZW50LndpZHRoKTtcbiAgICByZXQud2lkdGggPSBuZXh0V2lkdGg7XG4gICAgcmV0LnggPSBlbGVtZW50LnggLSBuZXh0V2lkdGg7XG4gIH1cblxuICBpZiAoZWxlbWVudC5oZWlnaHQgPCAwKSB7XG4gICAgY29uc3QgbmV4dEhlaWdodCA9IE1hdGguYWJzKGVsZW1lbnQuaGVpZ2h0KTtcbiAgICByZXQuaGVpZ2h0ID0gbmV4dEhlaWdodDtcbiAgICByZXQueSA9IGVsZW1lbnQueSAtIG5leHRIZWlnaHQ7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../element/sizeHelpers.ts\n");
2924
2924
 
2925
2925
  /***/ }),
2926
2926
 
@@ -3151,7 +3151,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3151
3151
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3152
3152
 
3153
3153
  "use strict";
3154
- 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/${\"@excalidraw/excalidraw\"}@${\"0.12.0-3d9d398\"}/dist/`;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9wdWJsaWNQYXRoLmpzLmpzIiwibWFwcGluZ3MiOiI7O0FBQXNDO0FBQ3RDLElBQUksYUFBb0IsS0FBSyxnREFBUSxFQUFFO0lBQ3JDLG9CQUFvQjtJQUNwQiw2Q0FBNkM7SUFDN0MscUJBQXVCO1FBQ3JCLE1BQU0sQ0FBQyxxQkFBcUI7WUFDNUIscUJBQXFCLHdCQUFvQixJQUFJLGdCQUF1QixRQUFRLENBQUM7Q0FDaEYiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9wdWJsaWNQYXRoLmpzP2E4N2QiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5WIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50c1wiO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBFTlYuVEVTVCkge1xuICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAvKiBnbG9iYWwgX193ZWJwYWNrX3B1YmxpY19wYXRoX186d3JpdGFibGUgKi9cbiAgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPVxuICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICBgaHR0cHM6Ly91bnBrZy5jb20vJHtwcm9jZXNzLmVudi5QS0dfTkFNRX1AJHtwcm9jZXNzLmVudi5QS0dfVkVSU0lPTn0vZGlzdC9gO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./publicPath.js\n");
3154
+ 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/${\"@excalidraw/excalidraw\"}@${\"0.12.0-45b5922\"}/dist/`;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9wdWJsaWNQYXRoLmpzLmpzIiwibWFwcGluZ3MiOiI7O0FBQXNDO0FBQ3RDLElBQUksYUFBb0IsS0FBSyxnREFBUSxFQUFFO0lBQ3JDLG9CQUFvQjtJQUNwQiw2Q0FBNkM7SUFDN0MscUJBQXVCO1FBQ3JCLE1BQU0sQ0FBQyxxQkFBcUI7WUFDNUIscUJBQXFCLHdCQUFvQixJQUFJLGdCQUF1QixRQUFRLENBQUM7Q0FDaEYiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9wdWJsaWNQYXRoLmpzP2E4N2QiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5WIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50c1wiO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBFTlYuVEVTVCkge1xuICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAvKiBnbG9iYWwgX193ZWJwYWNrX3B1YmxpY19wYXRoX186d3JpdGFibGUgKi9cbiAgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPVxuICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICBgaHR0cHM6Ly91bnBrZy5jb20vJHtwcm9jZXNzLmVudi5QS0dfTkFNRX1AJHtwcm9jZXNzLmVudi5QS0dfVkVSU0lPTn0vZGlzdC9gO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./publicPath.js\n");
3155
3155
 
3156
3156
  /***/ }),
3157
3157
 
@@ -3250,7 +3250,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3250
3250
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3251
3251
 
3252
3252
  "use strict";
3253
- 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 _appState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../data/json */ \"../../data/json.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../element/image */ \"../../element/image.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 -->`;\nconst exportToCanvas = (elements, appState, files, { exportBackground, exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, }, createCanvas = (width, height) => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width * appState.exportScale;\n canvas.height = height * appState.exportScale;\n return { canvas, scale: appState.exportScale };\n}) => __awaiter(void 0, void 0, void 0, function* () {\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n const { canvas, scale = 1 } = createCanvas(width, height);\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_5__.getDefaultAppState)();\n const { imageCache } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.updateImageCache)({\n imageCache: new Map(),\n fileIds: (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.getInitializedImageElements)(elements).map((element) => element.fileId),\n files,\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderScene)(elements, appState, null, scale, roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas), canvas, {\n viewBackgroundColor: exportBackground ? viewBackgroundColor : null,\n scrollX: -minX + exportPadding,\n scrollY: -minY + exportPadding,\n zoom: defaultAppState.zoom,\n remotePointerViewportCoords: {},\n remoteSelectedElementIds: {},\n shouldCacheIgnoreZoom: false,\n remotePointerUsernames: {},\n remotePointerUserStates: {},\n theme: appState.exportWithDarkMode ? \"dark\" : \"light\",\n imageCache,\n renderScrollbars: false,\n renderSelection: false,\n renderGrid: false,\n isExporting: true,\n });\n return canvas;\n});\nconst exportToSvg = (elements, appState, files) => __awaiter(void 0, void 0, void 0, function* () {\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: (0,_data_json__WEBPACK_IMPORTED_MODULE_6__.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/${\"@excalidraw/excalidraw\"}@${\"0.12.0-3d9d398\"}`;\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>\n @font-face {\n font-family: \"Virgil\";\n src: url(\"${assetPath}Virgil.woff2\");\n }\n @font-face {\n font-family: \"Cascadia\";\n src: url(\"${assetPath}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, exportPadding, scale) => {\n const [, , width, height] = getCanvasSize(elements, exportPadding).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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azovLy8uLi8uLi9zY2VuZS9leHBvcnQudHM/OWJmNyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcm91Z2ggZnJvbSBcInJvdWdoanMvYmluL3JvdWdoXCI7XG5pbXBvcnQgeyBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudC90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0Q29tbW9uQm91bmRzIH0gZnJvbSBcIi4uL2VsZW1lbnQvYm91bmRzXCI7XG5pbXBvcnQgeyByZW5kZXJTY2VuZSwgcmVuZGVyU2NlbmVUb1N2ZyB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJTY2VuZVwiO1xuaW1wb3J0IHsgZGlzdGFuY2UgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEFwcFN0YXRlLCBCaW5hcnlGaWxlcyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9FWFBPUlRfUEFERElORywgU1ZHX05TLCBUSEVNRV9GSUxURVIgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXREZWZhdWx0QXBwU3RhdGUgfSBmcm9tIFwiLi4vYXBwU3RhdGVcIjtcbmltcG9ydCB7IHNlcmlhbGl6ZUFzSlNPTiB9IGZyb20gXCIuLi9kYXRhL2pzb25cIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcblxuZXhwb3J0IGNvbnN0IFNWR19FWFBPUlRfVEFHID0gYDwhLS0gc3ZnLXNvdXJjZTpleGNhbGlkcmF3IC0tPmA7XG5cbmV4cG9ydCBjb25zdCBleHBvcnRUb0NhbnZhcyA9IGFzeW5jIChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gIGZpbGVzOiBCaW5hcnlGaWxlcyxcbiAge1xuICAgIGV4cG9ydEJhY2tncm91bmQsXG4gICAgZXhwb3J0UGFkZGluZyA9IERFRkFVTFRfRVhQT1JUX1BBRERJTkcsXG4gICAgdmlld0JhY2tncm91bmRDb2xvcixcbiAgfToge1xuICAgIGV4cG9ydEJhY2tncm91bmQ6IGJvb2xlYW47XG4gICAgZXhwb3J0UGFkZGluZz86IG51bWJlcjtcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG4gIH0sXG4gIGNyZWF0ZUNhbnZhczogKFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICkgPT4geyBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50OyBzY2FsZTogbnVtYmVyIH0gPSAod2lkdGgsIGhlaWdodCkgPT4ge1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgY2FudmFzLndpZHRoID0gd2lkdGggKiBhcHBTdGF0ZS5leHBvcnRTY2FsZTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0ICogYXBwU3RhdGUuZXhwb3J0U2NhbGU7XG4gICAgcmV0dXJuIHsgY2FudmFzLCBzY2FsZTogYXBwU3RhdGUuZXhwb3J0U2NhbGUgfTtcbiAgfSxcbikgPT4ge1xuICBjb25zdCBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBleHBvcnRQYWRkaW5nKTtcblxuICBjb25zdCB7IGNhbnZhcywgc2NhbGUgPSAxIH0gPSBjcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCk7XG5cbiAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG5cbiAgY29uc3QgeyBpbWFnZUNhY2hlIH0gPSBhd2FpdCB1cGRhdGVJbWFnZUNhY2hlKHtcbiAgICBpbWFnZUNhY2hlOiBuZXcgTWFwKCksXG4gICAgZmlsZUlkczogZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKGVsZW1lbnRzKS5tYXAoXG4gICAgICAoZWxlbWVudCkgPT4gZWxlbWVudC5maWxlSWQsXG4gICAgKSxcbiAgICBmaWxlcyxcbiAgfSk7XG5cbiAgcmVuZGVyU2NlbmUoZWxlbWVudHMsIGFwcFN0YXRlLCBudWxsLCBzY2FsZSwgcm91Z2guY2FudmFzKGNhbnZhcyksIGNhbnZhcywge1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IGV4cG9ydEJhY2tncm91bmQgPyB2aWV3QmFja2dyb3VuZENvbG9yIDogbnVsbCxcbiAgICBzY3JvbGxYOiAtbWluWCArIGV4cG9ydFBhZGRpbmcsXG4gICAgc2Nyb2xsWTogLW1pblkgKyBleHBvcnRQYWRkaW5nLFxuICAgIHpvb206IGRlZmF1bHRBcHBTdGF0ZS56b29tLFxuICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkczoge30sXG4gICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlLFxuICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHt9LFxuICAgIHJlbW90ZVBvaW50ZXJVc2VyU3RhdGVzOiB7fSxcbiAgICB0aGVtZTogYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlID8gXCJkYXJrXCIgOiBcImxpZ2h0XCIsXG4gICAgaW1hZ2VDYWNoZSxcbiAgICByZW5kZXJTY3JvbGxiYXJzOiBmYWxzZSxcbiAgICByZW5kZXJTZWxlY3Rpb246IGZhbHNlLFxuICAgIHJlbmRlckdyaWQ6IGZhbHNlLFxuICAgIGlzRXhwb3J0aW5nOiB0cnVlLFxuICB9KTtcblxuICByZXR1cm4gY2FudmFzO1xufTtcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFRvU3ZnID0gYXN5bmMgKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGFwcFN0YXRlOiB7XG4gICAgZXhwb3J0QmFja2dyb3VuZDogYm9vbGVhbjtcbiAgICBleHBvcnRQYWRkaW5nPzogbnVtYmVyO1xuICAgIGV4cG9ydFNjYWxlPzogbnVtYmVyO1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgICBleHBvcnRXaXRoRGFya01vZGU/OiBib29sZWFuO1xuICAgIGV4cG9ydEVtYmVkU2NlbmU/OiBib29sZWFuO1xuICB9LFxuICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsLFxuKTogUHJvbWlzZTxTVkdTVkdFbGVtZW50PiA9PiB7XG4gIGNvbnN0IHtcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICAgIGV4cG9ydFNjYWxlID0gMSxcbiAgICBleHBvcnRFbWJlZFNjZW5lLFxuICB9ID0gYXBwU3RhdGU7XG4gIGxldCBtZXRhZGF0YSA9IFwiXCI7XG4gIGlmIChleHBvcnRFbWJlZFNjZW5lKSB7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoLyogd2VicGFja0NodW5rTmFtZTogXCJpbWFnZVwiICovIFwiLi4vLi4vc3JjL2RhdGEvaW1hZ2VcIilcbiAgICAgICkuZW5jb2RlU3ZnTWV0YWRhdGEoe1xuICAgICAgICB0ZXh0OiBzZXJpYWxpemVBc0pTT04oZWxlbWVudHMsIGFwcFN0YXRlLCBmaWxlcyB8fCB7fSwgXCJsb2NhbFwiKSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuICBjb25zdCBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBleHBvcnRQYWRkaW5nKTtcblxuICAvLyBpbml0aWFsaXplIFNWRyByb290XG4gIGNvbnN0IHN2Z1Jvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCBcInN2Z1wiKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJ2ZXJzaW9uXCIsIFwiMS4xXCIpO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcInhtbG5zXCIsIFNWR19OUyk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwidmlld0JveFwiLCBgMCAwICR7d2lkdGh9ICR7aGVpZ2h0fWApO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRoICogZXhwb3J0U2NhbGV9YCk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodCAqIGV4cG9ydFNjYWxlfWApO1xuICBpZiAoYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlKSB7XG4gICAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJmaWx0ZXJcIiwgVEhFTUVfRklMVEVSKTtcbiAgfVxuXG4gIGxldCBhc3NldFBhdGggPSBcImh0dHBzOi8vZXhjYWxpZHJhdy5jb20vXCI7XG5cbiAgLy8gQXNzZXQgcGF0aCBuZWVkcyB0byBiZSBkZXRlcm1pbmVkIG9ubHkgd2hlbiB1c2luZyBwYWNrYWdlXG4gIGlmIChwcm9jZXNzLmVudi5JU19FWENBTElEUkFXX05QTV9QQUNLQUdFKSB7XG4gICAgYXNzZXRQYXRoID1cbiAgICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICAgIGBodHRwczovL3VucGtnLmNvbS8ke3Byb2Nlc3MuZW52LlBLR19OQU1FfUAke3Byb2Nlc3MuZW52LlBLR19WRVJTSU9OfWA7XG5cbiAgICBpZiAoYXNzZXRQYXRoPy5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgICAgYXNzZXRQYXRoID0gYXNzZXRQYXRoLnJlcGxhY2UoXCIvXCIsIGAke3dpbmRvdy5sb2NhdGlvbi5vcmlnaW59L2ApO1xuICAgIH1cbiAgICBhc3NldFBhdGggPSBgJHthc3NldFBhdGh9L2Rpc3QvZXhjYWxpZHJhdy1hc3NldHMvYDtcbiAgfVxuICBzdmdSb290LmlubmVySFRNTCA9IGBcbiAgJHtTVkdfRVhQT1JUX1RBR31cbiAgJHttZXRhZGF0YX1cbiAgPGRlZnM+XG4gICAgPHN0eWxlPlxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIlZpcmdpbFwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofVZpcmdpbC53b2ZmMlwiKTtcbiAgICAgIH1cbiAgICAgIEBmb250LWZhY2Uge1xuICAgICAgICBmb250LWZhbWlseTogXCJDYXNjYWRpYVwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofUNhc2NhZGlhLndvZmYyXCIpO1xuICAgICAgfVxuICAgIDwvc3R5bGU+XG4gIDwvZGVmcz5cbiAgYDtcbiAgLy8gcmVuZGVyIGJhY2tncm91bmQgcmVjdFxuICBpZiAoYXBwU3RhdGUuZXhwb3J0QmFja2dyb3VuZCAmJiB2aWV3QmFja2dyb3VuZENvbG9yKSB7XG4gICAgY29uc3QgcmVjdCA9IHN2Z1Jvb3Qub3duZXJEb2N1bWVudCEuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgXCJyZWN0XCIpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMFwiKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRofWApO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodH1gKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdmlld0JhY2tncm91bmRDb2xvcik7XG4gICAgc3ZnUm9vdC5hcHBlbmRDaGlsZChyZWN0KTtcbiAgfVxuXG4gIGNvbnN0IHJzdmcgPSByb3VnaC5zdmcoc3ZnUm9vdCk7XG4gIHJlbmRlclNjZW5lVG9TdmcoZWxlbWVudHMsIHJzdmcsIHN2Z1Jvb3QsIGZpbGVzIHx8IHt9LCB7XG4gICAgb2Zmc2V0WDogLW1pblggKyBleHBvcnRQYWRkaW5nLFxuICAgIG9mZnNldFk6IC1taW5ZICsgZXhwb3J0UGFkZGluZyxcbiAgICBleHBvcnRXaXRoRGFya01vZGU6IGFwcFN0YXRlLmV4cG9ydFdpdGhEYXJrTW9kZSxcbiAgfSk7XG5cbiAgcmV0dXJuIHN2Z1Jvb3Q7XG59O1xuXG4vLyBjYWxjdWxhdGUgc21hbGxlc3QgYXJlYSB0byBmaXQgdGhlIGNvbnRlbnRzIGluXG5jb25zdCBnZXRDYW52YXNTaXplID0gKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGV4cG9ydFBhZGRpbmc6IG51bWJlcixcbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKGVsZW1lbnRzKTtcbiAgY29uc3Qgd2lkdGggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSArIGV4cG9ydFBhZGRpbmcgKiAyO1xuICBjb25zdCBoZWlnaHQgPSBkaXN0YW5jZShtaW5ZLCBtYXhZKSArIGV4cG9ydFBhZGRpbmcgKyBleHBvcnRQYWRkaW5nO1xuXG4gIHJldHVybiBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF07XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RXhwb3J0U2l6ZSA9IChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBleHBvcnRQYWRkaW5nOiBudW1iZXIsXG4gIHNjYWxlOiBudW1iZXIsXG4pOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgWywgLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpLm1hcChcbiAgICAoZGltZW5zaW9uKSA9PiBNYXRoLnRydW5jKGRpbWVuc2lvbiAqIHNjYWxlKSxcbiAgKTtcblxuICByZXR1cm4gW3dpZHRoLCBoZWlnaHRdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../scene/export.ts\n");
3253
+ 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 _appState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../data/json */ \"../../data/json.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../element/image */ \"../../element/image.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 -->`;\nconst exportToCanvas = (elements, appState, files, { exportBackground, exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, }, createCanvas = (width, height) => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width * appState.exportScale;\n canvas.height = height * appState.exportScale;\n return { canvas, scale: appState.exportScale };\n}) => __awaiter(void 0, void 0, void 0, function* () {\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n const { canvas, scale = 1 } = createCanvas(width, height);\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_5__.getDefaultAppState)();\n const { imageCache } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.updateImageCache)({\n imageCache: new Map(),\n fileIds: (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.getInitializedImageElements)(elements).map((element) => element.fileId),\n files,\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderScene)(elements, appState, null, scale, roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas), canvas, {\n viewBackgroundColor: exportBackground ? viewBackgroundColor : null,\n scrollX: -minX + exportPadding,\n scrollY: -minY + exportPadding,\n zoom: defaultAppState.zoom,\n remotePointerViewportCoords: {},\n remoteSelectedElementIds: {},\n shouldCacheIgnoreZoom: false,\n remotePointerUsernames: {},\n remotePointerUserStates: {},\n theme: appState.exportWithDarkMode ? \"dark\" : \"light\",\n imageCache,\n renderScrollbars: false,\n renderSelection: false,\n renderGrid: false,\n isExporting: true,\n });\n return canvas;\n});\nconst exportToSvg = (elements, appState, files) => __awaiter(void 0, void 0, void 0, function* () {\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: (0,_data_json__WEBPACK_IMPORTED_MODULE_6__.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/${\"@excalidraw/excalidraw\"}@${\"0.12.0-45b5922\"}`;\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>\n @font-face {\n font-family: \"Virgil\";\n src: url(\"${assetPath}Virgil.woff2\");\n }\n @font-face {\n font-family: \"Cascadia\";\n src: url(\"${assetPath}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, exportPadding, scale) => {\n const [, , width, height] = getCanvasSize(elements, exportPadding).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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azovLy8uLi8uLi9zY2VuZS9leHBvcnQudHM/OWJmNyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcm91Z2ggZnJvbSBcInJvdWdoanMvYmluL3JvdWdoXCI7XG5pbXBvcnQgeyBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudC90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0Q29tbW9uQm91bmRzIH0gZnJvbSBcIi4uL2VsZW1lbnQvYm91bmRzXCI7XG5pbXBvcnQgeyByZW5kZXJTY2VuZSwgcmVuZGVyU2NlbmVUb1N2ZyB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJTY2VuZVwiO1xuaW1wb3J0IHsgZGlzdGFuY2UgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEFwcFN0YXRlLCBCaW5hcnlGaWxlcyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9FWFBPUlRfUEFERElORywgU1ZHX05TLCBUSEVNRV9GSUxURVIgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXREZWZhdWx0QXBwU3RhdGUgfSBmcm9tIFwiLi4vYXBwU3RhdGVcIjtcbmltcG9ydCB7IHNlcmlhbGl6ZUFzSlNPTiB9IGZyb20gXCIuLi9kYXRhL2pzb25cIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcblxuZXhwb3J0IGNvbnN0IFNWR19FWFBPUlRfVEFHID0gYDwhLS0gc3ZnLXNvdXJjZTpleGNhbGlkcmF3IC0tPmA7XG5cbmV4cG9ydCBjb25zdCBleHBvcnRUb0NhbnZhcyA9IGFzeW5jIChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gIGZpbGVzOiBCaW5hcnlGaWxlcyxcbiAge1xuICAgIGV4cG9ydEJhY2tncm91bmQsXG4gICAgZXhwb3J0UGFkZGluZyA9IERFRkFVTFRfRVhQT1JUX1BBRERJTkcsXG4gICAgdmlld0JhY2tncm91bmRDb2xvcixcbiAgfToge1xuICAgIGV4cG9ydEJhY2tncm91bmQ6IGJvb2xlYW47XG4gICAgZXhwb3J0UGFkZGluZz86IG51bWJlcjtcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG4gIH0sXG4gIGNyZWF0ZUNhbnZhczogKFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICkgPT4geyBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50OyBzY2FsZTogbnVtYmVyIH0gPSAod2lkdGgsIGhlaWdodCkgPT4ge1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgY2FudmFzLndpZHRoID0gd2lkdGggKiBhcHBTdGF0ZS5leHBvcnRTY2FsZTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0ICogYXBwU3RhdGUuZXhwb3J0U2NhbGU7XG4gICAgcmV0dXJuIHsgY2FudmFzLCBzY2FsZTogYXBwU3RhdGUuZXhwb3J0U2NhbGUgfTtcbiAgfSxcbikgPT4ge1xuICBjb25zdCBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBleHBvcnRQYWRkaW5nKTtcblxuICBjb25zdCB7IGNhbnZhcywgc2NhbGUgPSAxIH0gPSBjcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCk7XG5cbiAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG5cbiAgY29uc3QgeyBpbWFnZUNhY2hlIH0gPSBhd2FpdCB1cGRhdGVJbWFnZUNhY2hlKHtcbiAgICBpbWFnZUNhY2hlOiBuZXcgTWFwKCksXG4gICAgZmlsZUlkczogZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKGVsZW1lbnRzKS5tYXAoXG4gICAgICAoZWxlbWVudCkgPT4gZWxlbWVudC5maWxlSWQsXG4gICAgKSxcbiAgICBmaWxlcyxcbiAgfSk7XG5cbiAgcmVuZGVyU2NlbmUoZWxlbWVudHMsIGFwcFN0YXRlLCBudWxsLCBzY2FsZSwgcm91Z2guY2FudmFzKGNhbnZhcyksIGNhbnZhcywge1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IGV4cG9ydEJhY2tncm91bmQgPyB2aWV3QmFja2dyb3VuZENvbG9yIDogbnVsbCxcbiAgICBzY3JvbGxYOiAtbWluWCArIGV4cG9ydFBhZGRpbmcsXG4gICAgc2Nyb2xsWTogLW1pblkgKyBleHBvcnRQYWRkaW5nLFxuICAgIHpvb206IGRlZmF1bHRBcHBTdGF0ZS56b29tLFxuICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkczoge30sXG4gICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlLFxuICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHt9LFxuICAgIHJlbW90ZVBvaW50ZXJVc2VyU3RhdGVzOiB7fSxcbiAgICB0aGVtZTogYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlID8gXCJkYXJrXCIgOiBcImxpZ2h0XCIsXG4gICAgaW1hZ2VDYWNoZSxcbiAgICByZW5kZXJTY3JvbGxiYXJzOiBmYWxzZSxcbiAgICByZW5kZXJTZWxlY3Rpb246IGZhbHNlLFxuICAgIHJlbmRlckdyaWQ6IGZhbHNlLFxuICAgIGlzRXhwb3J0aW5nOiB0cnVlLFxuICB9KTtcblxuICByZXR1cm4gY2FudmFzO1xufTtcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFRvU3ZnID0gYXN5bmMgKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGFwcFN0YXRlOiB7XG4gICAgZXhwb3J0QmFja2dyb3VuZDogYm9vbGVhbjtcbiAgICBleHBvcnRQYWRkaW5nPzogbnVtYmVyO1xuICAgIGV4cG9ydFNjYWxlPzogbnVtYmVyO1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgICBleHBvcnRXaXRoRGFya01vZGU/OiBib29sZWFuO1xuICAgIGV4cG9ydEVtYmVkU2NlbmU/OiBib29sZWFuO1xuICB9LFxuICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsLFxuKTogUHJvbWlzZTxTVkdTVkdFbGVtZW50PiA9PiB7XG4gIGNvbnN0IHtcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICAgIGV4cG9ydFNjYWxlID0gMSxcbiAgICBleHBvcnRFbWJlZFNjZW5lLFxuICB9ID0gYXBwU3RhdGU7XG4gIGxldCBtZXRhZGF0YSA9IFwiXCI7XG4gIGlmIChleHBvcnRFbWJlZFNjZW5lKSB7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoLyogd2VicGFja0NodW5rTmFtZTogXCJpbWFnZVwiICovIFwiLi4vLi4vc3JjL2RhdGEvaW1hZ2VcIilcbiAgICAgICkuZW5jb2RlU3ZnTWV0YWRhdGEoe1xuICAgICAgICB0ZXh0OiBzZXJpYWxpemVBc0pTT04oZWxlbWVudHMsIGFwcFN0YXRlLCBmaWxlcyB8fCB7fSwgXCJsb2NhbFwiKSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuICBjb25zdCBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBleHBvcnRQYWRkaW5nKTtcblxuICAvLyBpbml0aWFsaXplIFNWRyByb290XG4gIGNvbnN0IHN2Z1Jvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCBcInN2Z1wiKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJ2ZXJzaW9uXCIsIFwiMS4xXCIpO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcInhtbG5zXCIsIFNWR19OUyk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwidmlld0JveFwiLCBgMCAwICR7d2lkdGh9ICR7aGVpZ2h0fWApO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRoICogZXhwb3J0U2NhbGV9YCk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodCAqIGV4cG9ydFNjYWxlfWApO1xuICBpZiAoYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlKSB7XG4gICAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJmaWx0ZXJcIiwgVEhFTUVfRklMVEVSKTtcbiAgfVxuXG4gIGxldCBhc3NldFBhdGggPSBcImh0dHBzOi8vZXhjYWxpZHJhdy5jb20vXCI7XG5cbiAgLy8gQXNzZXQgcGF0aCBuZWVkcyB0byBiZSBkZXRlcm1pbmVkIG9ubHkgd2hlbiB1c2luZyBwYWNrYWdlXG4gIGlmIChwcm9jZXNzLmVudi5JU19FWENBTElEUkFXX05QTV9QQUNLQUdFKSB7XG4gICAgYXNzZXRQYXRoID1cbiAgICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICAgIGBodHRwczovL3VucGtnLmNvbS8ke3Byb2Nlc3MuZW52LlBLR19OQU1FfUAke3Byb2Nlc3MuZW52LlBLR19WRVJTSU9OfWA7XG5cbiAgICBpZiAoYXNzZXRQYXRoPy5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgICAgYXNzZXRQYXRoID0gYXNzZXRQYXRoLnJlcGxhY2UoXCIvXCIsIGAke3dpbmRvdy5sb2NhdGlvbi5vcmlnaW59L2ApO1xuICAgIH1cbiAgICBhc3NldFBhdGggPSBgJHthc3NldFBhdGh9L2Rpc3QvZXhjYWxpZHJhdy1hc3NldHMvYDtcbiAgfVxuICBzdmdSb290LmlubmVySFRNTCA9IGBcbiAgJHtTVkdfRVhQT1JUX1RBR31cbiAgJHttZXRhZGF0YX1cbiAgPGRlZnM+XG4gICAgPHN0eWxlPlxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIlZpcmdpbFwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofVZpcmdpbC53b2ZmMlwiKTtcbiAgICAgIH1cbiAgICAgIEBmb250LWZhY2Uge1xuICAgICAgICBmb250LWZhbWlseTogXCJDYXNjYWRpYVwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofUNhc2NhZGlhLndvZmYyXCIpO1xuICAgICAgfVxuICAgIDwvc3R5bGU+XG4gIDwvZGVmcz5cbiAgYDtcbiAgLy8gcmVuZGVyIGJhY2tncm91bmQgcmVjdFxuICBpZiAoYXBwU3RhdGUuZXhwb3J0QmFja2dyb3VuZCAmJiB2aWV3QmFja2dyb3VuZENvbG9yKSB7XG4gICAgY29uc3QgcmVjdCA9IHN2Z1Jvb3Qub3duZXJEb2N1bWVudCEuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgXCJyZWN0XCIpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMFwiKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRofWApO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodH1gKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdmlld0JhY2tncm91bmRDb2xvcik7XG4gICAgc3ZnUm9vdC5hcHBlbmRDaGlsZChyZWN0KTtcbiAgfVxuXG4gIGNvbnN0IHJzdmcgPSByb3VnaC5zdmcoc3ZnUm9vdCk7XG4gIHJlbmRlclNjZW5lVG9TdmcoZWxlbWVudHMsIHJzdmcsIHN2Z1Jvb3QsIGZpbGVzIHx8IHt9LCB7XG4gICAgb2Zmc2V0WDogLW1pblggKyBleHBvcnRQYWRkaW5nLFxuICAgIG9mZnNldFk6IC1taW5ZICsgZXhwb3J0UGFkZGluZyxcbiAgICBleHBvcnRXaXRoRGFya01vZGU6IGFwcFN0YXRlLmV4cG9ydFdpdGhEYXJrTW9kZSxcbiAgfSk7XG5cbiAgcmV0dXJuIHN2Z1Jvb3Q7XG59O1xuXG4vLyBjYWxjdWxhdGUgc21hbGxlc3QgYXJlYSB0byBmaXQgdGhlIGNvbnRlbnRzIGluXG5jb25zdCBnZXRDYW52YXNTaXplID0gKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGV4cG9ydFBhZGRpbmc6IG51bWJlcixcbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKGVsZW1lbnRzKTtcbiAgY29uc3Qgd2lkdGggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSArIGV4cG9ydFBhZGRpbmcgKiAyO1xuICBjb25zdCBoZWlnaHQgPSBkaXN0YW5jZShtaW5ZLCBtYXhZKSArIGV4cG9ydFBhZGRpbmcgKyBleHBvcnRQYWRkaW5nO1xuXG4gIHJldHVybiBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF07XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RXhwb3J0U2l6ZSA9IChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBleHBvcnRQYWRkaW5nOiBudW1iZXIsXG4gIHNjYWxlOiBudW1iZXIsXG4pOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgWywgLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpLm1hcChcbiAgICAoZGltZW5zaW9uKSA9PiBNYXRoLnRydW5jKGRpbWVuc2lvbiAqIHNjYWxlKSxcbiAgKTtcblxuICByZXR1cm4gW3dpZHRoLCBoZWlnaHRdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../scene/export.ts\n");
3254
3254
 
3255
3255
  /***/ }),
3256
3256
 
@@ -3338,7 +3338,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3338
3338
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3339
3339
 
3340
3340
  "use strict";
3341
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"allowFullScreen\": () => (/* binding */ allowFullScreen),\n/* harmony export */ \"arrayToMap\": () => (/* binding */ arrayToMap),\n/* harmony export */ \"bytesToHexString\": () => (/* binding */ bytesToHexString),\n/* harmony export */ \"capitalizeString\": () => (/* binding */ capitalizeString),\n/* harmony export */ \"chunk\": () => (/* binding */ chunk),\n/* harmony export */ \"debounce\": () => (/* binding */ debounce),\n/* harmony export */ \"distance\": () => (/* binding */ distance),\n/* harmony export */ \"exitFullScreen\": () => (/* binding */ exitFullScreen),\n/* harmony export */ \"findIndex\": () => (/* binding */ findIndex),\n/* harmony export */ \"findLastIndex\": () => (/* binding */ findLastIndex),\n/* harmony export */ \"focusNearestParent\": () => (/* binding */ focusNearestParent),\n/* harmony export */ \"getDateTime\": () => (/* binding */ getDateTime),\n/* harmony export */ \"getFontFamilyString\": () => (/* binding */ getFontFamilyString),\n/* harmony export */ \"getFontString\": () => (/* binding */ getFontString),\n/* harmony export */ \"getFrame\": () => (/* binding */ getFrame),\n/* harmony export */ \"getGlobalCSSVariable\": () => (/* binding */ getGlobalCSSVariable),\n/* harmony export */ \"getNearestScrollableContainer\": () => (/* binding */ getNearestScrollableContainer),\n/* harmony export */ \"getShortcutKey\": () => (/* binding */ getShortcutKey),\n/* harmony export */ \"getUpdatedTimestamp\": () => (/* binding */ getUpdatedTimestamp),\n/* harmony export */ \"getVersion\": () => (/* binding */ getVersion),\n/* harmony export */ \"isFullScreen\": () => (/* binding */ isFullScreen),\n/* harmony export */ \"isInputLike\": () => (/* binding */ isInputLike),\n/* harmony export */ \"isPrimitive\": () => (/* binding */ isPrimitive),\n/* harmony export */ \"isProdEnv\": () => (/* binding */ isProdEnv),\n/* harmony export */ \"isPromiseLike\": () => (/* binding */ isPromiseLike),\n/* harmony export */ \"isRTL\": () => (/* binding */ isRTL),\n/* harmony export */ \"isTestEnv\": () => (/* binding */ isTestEnv),\n/* harmony export */ \"isToolIcon\": () => (/* binding */ isToolIcon),\n/* harmony export */ \"isTransparent\": () => (/* binding */ isTransparent),\n/* harmony export */ \"isWritableElement\": () => (/* binding */ isWritableElement),\n/* harmony export */ \"muteFSAbortError\": () => (/* binding */ muteFSAbortError),\n/* harmony export */ \"nFormatter\": () => (/* binding */ nFormatter),\n/* harmony export */ \"preventUnload\": () => (/* binding */ preventUnload),\n/* harmony export */ \"queryFocusableElements\": () => (/* binding */ queryFocusableElements),\n/* harmony export */ \"removeSelection\": () => (/* binding */ removeSelection),\n/* harmony export */ \"resetCursor\": () => (/* binding */ resetCursor),\n/* harmony export */ \"resolvablePromise\": () => (/* binding */ resolvablePromise),\n/* harmony export */ \"sceneCoordsToViewportCoords\": () => (/* binding */ sceneCoordsToViewportCoords),\n/* harmony export */ \"selectNode\": () => (/* binding */ selectNode),\n/* harmony export */ \"setCursor\": () => (/* binding */ setCursor),\n/* harmony export */ \"setCursorForShape\": () => (/* binding */ setCursorForShape),\n/* harmony export */ \"setDateTimeForTests\": () => (/* binding */ setDateTimeForTests),\n/* harmony export */ \"setEraserCursor\": () => (/* binding */ setEraserCursor),\n/* harmony export */ \"supportsEmoji\": () => (/* binding */ supportsEmoji),\n/* harmony export */ \"throttleRAF\": () => (/* binding */ throttleRAF),\n/* harmony export */ \"tupleToCoors\": () => (/* binding */ tupleToCoors),\n/* harmony export */ \"updateActiveTool\": () => (/* binding */ updateActiveTool),\n/* harmony export */ \"updateObject\": () => (/* binding */ updateObject),\n/* harmony export */ \"viewportCoordsToSceneCoords\": () => (/* binding */ viewportCoordsToSceneCoords),\n/* harmony export */ \"withBatchedUpdates\": () => (/* binding */ withBatchedUpdates),\n/* harmony export */ \"withBatchedUpdatesThrottled\": () => (/* binding */ withBatchedUpdatesThrottled),\n/* harmony export */ \"wrapEvent\": () => (/* binding */ wrapEvent)\n/* harmony export */ });\n/* harmony import */ var open_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! open-color */ \"../../../node_modules/open-color/open-color.json\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../../colors.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ \"../../constants.ts\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./keys */ \"../../keys.ts\");\n\n\n\n\n\nlet mockDateTime = null;\nconst setDateTimeForTests = (dateTime) => {\n mockDateTime = dateTime;\n};\nconst getDateTime = () => {\n if (mockDateTime) {\n return mockDateTime;\n }\n const date = new Date();\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${date.getDate()}`.padStart(2, \"0\");\n const hr = `${date.getHours()}`.padStart(2, \"0\");\n const min = `${date.getMinutes()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}-${hr}${min}`;\n};\nconst capitalizeString = (str) => str.charAt(0).toUpperCase() + str.slice(1);\nconst isToolIcon = (target) => target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\nconst isInputLike = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target instanceof HTMLSelectElement;\nconst isWritableElement = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLTextAreaElement ||\n (target instanceof HTMLInputElement &&\n (target.type === \"text\" || target.type === \"number\"));\nconst getFontFamilyString = ({ fontFamily, }) => {\n for (const [fontFamilyString, id] of Object.entries(_constants__WEBPACK_IMPORTED_MODULE_2__.FONT_FAMILY)) {\n if (id === fontFamily) {\n return `${fontFamilyString}, ${_constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT}`;\n }\n }\n return _constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT;\n};\n/** returns fontSize+fontFamily string for assignment to DOM elements */\nconst getFontString = ({ fontSize, fontFamily, }) => {\n return `${fontSize}px ${getFontFamilyString({ fontFamily })}`;\n};\nconst debounce = (fn, timeout) => {\n let handle = 0;\n let lastArgs = null;\n const ret = (...args) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n ret.flush = () => {\n clearTimeout(handle);\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n return ret;\n};\n// throttle callback to execute once per animation frame\nconst throttleRAF = (fn, opts) => {\n let timerId = null;\n let lastArgs = null;\n let lastArgsTrailing = null;\n const scheduleFunc = (args) => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n const ret = (...args) => {\n if (false) {}\n lastArgs = args;\n if (timerId === null) {\n scheduleFunc(lastArgs);\n }\n else if (opts === null || opts === void 0 ? void 0 : opts.trailing) {\n lastArgsTrailing = args;\n }\n };\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n return ret;\n};\n// https://github.com/lodash/lodash/blob/es/chunk.js\nconst chunk = (array, size) => {\n if (!array.length || size < 1) {\n return [];\n }\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n while (index < array.length) {\n result[resIndex++] = array.slice(index, (index += size));\n }\n return result;\n};\nconst selectNode = (node) => {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\nconst removeSelection = () => {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n }\n};\nconst distance = (x, y) => Math.abs(x - y);\nconst updateActiveTool = (appState, data) => {\n if (data.type === \"custom\") {\n return Object.assign(Object.assign({}, appState.activeTool), { type: \"custom\", customType: data.customType });\n }\n return Object.assign(Object.assign({}, appState.activeTool), { lastActiveToolBeforeEraser: data.lastActiveToolBeforeEraser === undefined\n ? appState.activeTool.lastActiveToolBeforeEraser\n : data.lastActiveToolBeforeEraser, type: data.type, customType: null });\n};\nconst resetCursor = (canvas) => {\n if (canvas) {\n canvas.style.cursor = \"\";\n }\n};\nconst setCursor = (canvas, cursor) => {\n if (canvas) {\n canvas.style.cursor = cursor;\n }\n};\nlet eraserCanvasCache;\nlet previewDataURL;\nconst setEraserCursor = (canvas, theme) => {\n const cursorImageSizePx = 20;\n const drawCanvas = () => {\n const isDarkTheme = theme === _constants__WEBPACK_IMPORTED_MODULE_2__.THEME.DARK;\n eraserCanvasCache = document.createElement(\"canvas\");\n eraserCanvasCache.theme = theme;\n eraserCanvasCache.height = cursorImageSizePx;\n eraserCanvasCache.width = cursorImageSizePx;\n const context = eraserCanvasCache.getContext(\"2d\");\n context.lineWidth = 1;\n context.beginPath();\n context.arc(eraserCanvasCache.width / 2, eraserCanvasCache.height / 2, 5, 0, 2 * Math.PI);\n context.fillStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.black : open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.fill();\n context.strokeStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.white : open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n context.stroke();\n previewDataURL = eraserCanvasCache.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_2__.MIME_TYPES.svg);\n };\n if (!eraserCanvasCache || eraserCanvasCache.theme !== theme) {\n drawCanvas();\n }\n setCursor(canvas, `url(${previewDataURL}) ${cursorImageSizePx / 2} ${cursorImageSizePx / 2}, auto`);\n};\nconst setCursorForShape = (canvas, appState) => {\n if (!canvas) {\n return;\n }\n if (appState.activeTool.type === \"selection\") {\n resetCursor(canvas);\n }\n else if (appState.activeTool.type === \"eraser\") {\n setEraserCursor(canvas, appState.theme);\n // do nothing if image tool is selected which suggests there's\n // a image-preview set as the cursor\n // Ignore custom type as well and let host decide\n }\n else if (![\"image\", \"custom\"].includes(appState.activeTool.type)) {\n canvas.style.cursor = _constants__WEBPACK_IMPORTED_MODULE_2__.CURSOR_TYPE.CROSSHAIR;\n }\n};\nconst isFullScreen = () => { var _a; return ((_a = document.fullscreenElement) === null || _a === void 0 ? void 0 : _a.nodeName) === \"HTML\"; };\nconst allowFullScreen = () => document.documentElement.requestFullscreen();\nconst exitFullScreen = () => document.exitFullscreen();\nconst getShortcutKey = (shortcut) => {\n shortcut = shortcut\n .replace(/\\bAlt\\b/i, \"Alt\")\n .replace(/\\bShift\\b/i, \"Shift\")\n .replace(/\\b(Enter|Return)\\b/i, \"Enter\")\n .replace(/\\bDel\\b/i, \"Delete\");\n if (_keys__WEBPACK_IMPORTED_MODULE_4__.isDarwin) {\n return shortcut\n .replace(/\\bCtrlOrCmd\\b/i, \"Cmd\")\n .replace(/\\bAlt\\b/i, \"Option\");\n }\n return shortcut.replace(/\\bCtrlOrCmd\\b/i, \"Ctrl\");\n};\nconst viewportCoordsToSceneCoords = ({ clientX, clientY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const invScale = 1 / zoom.value;\n const x = (clientX - offsetLeft) * invScale - scrollX;\n const y = (clientY - offsetTop) * invScale - scrollY;\n return { x, y };\n};\nconst sceneCoordsToViewportCoords = ({ sceneX, sceneY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return { x, y };\n};\nconst getGlobalCSSVariable = (name) => getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\nconst RS_LTR_CHARS = \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" +\n \"\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF\";\nconst RS_RTL_CHARS = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst RE_RTL_CHECK = new RegExp(`^[^${RS_LTR_CHARS}]*[${RS_RTL_CHARS}]`);\n/**\n * Checks whether first directional character is RTL. Meaning whether it starts\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\n * RTL.\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\n */\nconst isRTL = (text) => RE_RTL_CHECK.test(text);\nconst tupleToCoors = (xyTuple) => {\n const [x, y] = xyTuple;\n return { x, y };\n};\n/** use as a rejectionHandler to mute filesystem Abort errors */\nconst muteFSAbortError = (error) => {\n if ((error === null || error === void 0 ? void 0 : error.name) === \"AbortError\") {\n console.warn(error);\n return;\n }\n throw error;\n};\nconst findIndex = (array, cb, fromIndex = 0) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst findLastIndex = (array, cb, fromIndex = array.length - 1) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst isTransparent = (color) => {\n const isRGBTransparent = color.length === 5 && color.substr(4, 1) === \"0\";\n const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === \"00\";\n return (isRGBTransparent ||\n isRRGGBBTransparent ||\n color === _colors__WEBPACK_IMPORTED_MODULE_1__[\"default\"].elementBackground[0]);\n};\nconst resolvablePromise = () => {\n let resolve;\n let reject;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n promise.resolve = resolve;\n promise.reject = reject;\n return promise;\n};\n/**\n * @param func handler taking at most single parameter (event).\n */\nconst withBatchedUpdates = (func) => ((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n});\n/**\n * barches React state updates and throttles the calls to a single call per\n * animation frame\n */\nconst withBatchedUpdatesThrottled = (func) => {\n // @ts-ignore\n return throttleRAF(((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n }));\n};\n//https://stackoverflow.com/a/9462382/8418\nconst nFormatter = (num, digits) => {\n const si = [\n { value: 1, symbol: \"b\" },\n { value: 1e3, symbol: \"k\" },\n { value: 1e6, symbol: \"M\" },\n { value: 1e9, symbol: \"G\" },\n ];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n return ((num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol);\n};\nconst getVersion = () => {\n var _a;\n return (((_a = document.querySelector('meta[name=\"version\"]')) === null || _a === void 0 ? void 0 : _a.content) ||\n _constants__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_VERSION);\n};\n// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\nconst supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return false;\n }\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\";\n // Modernizr used 🐨, but it is sort of supported on Windows 7.\n // Luckily 😀 isn't supported.\n ctx.fillText(\"😀\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\nconst getNearestScrollableContainer = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n const { overflowY } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n if (hasScrollableContent &&\n (overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n overflowY === \"overlay\")) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return document;\n};\nconst focusNearestParent = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n parent = parent.parentElement;\n }\n};\nconst preventUnload = (event) => {\n event.preventDefault();\n // NOTE: modern browsers no longer allow showing a custom message here\n event.returnValue = \"\";\n};\nconst bytesToHexString = (bytes) => {\n return Array.from(bytes)\n .map((byte) => `0${byte.toString(16)}`.slice(-2))\n .join(\"\");\n};\nconst getUpdatedTimestamp = () => (isTestEnv() ? 1 : Date.now());\n/**\n * Transforms array of objects containing `id` attribute,\n * or array of ids (strings), into a Map, keyd by `id`.\n */\nconst arrayToMap = (items) => {\n return items.reduce((acc, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\nconst isTestEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-3d9d398\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"test\"; };\nconst isProdEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-3d9d398\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"production\"; };\nconst wrapEvent = (name, nativeEvent) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent,\n },\n cancelable: true,\n });\n};\nconst updateObject = (obj, updates) => {\n let didChange = false;\n for (const key in updates) {\n const value = updates[key];\n if (typeof value !== \"undefined\") {\n if (obj[key] === value &&\n // if object, always update because its attrs could have changed\n (typeof value !== \"object\" || value === null)) {\n continue;\n }\n didChange = true;\n }\n }\n if (!didChange) {\n return obj;\n }\n return Object.assign(Object.assign({}, obj), updates);\n};\nconst isPrimitive = (val) => {\n const type = typeof val;\n return val == null || (type !== \"object\" && type !== \"function\");\n};\nconst getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n }\n catch (error) {\n return \"iframe\";\n }\n};\nconst isPromiseLike = (value) => {\n return (!!value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n \"catch\" in value &&\n \"finally\" in value);\n};\nconst queryFocusableElements = (container) => {\n const focusableElements = container === null || container === void 0 ? void 0 : container.querySelectorAll(\"button, a, input, select, textarea, div[tabindex], label[tabindex]\");\n return focusableElements\n ? Array.from(focusableElements).filter((element) => element.tabIndex > -1 && !element.disabled)\n : [];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFFBQVEsSUFBSSxJQUFJLEtBQUssVUFBVSxDQUFDLENBQUM7QUFDbkUsQ0FBQyxDQUFDO0FBRUssTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUk7UUFDRixPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7S0FDdEQ7SUFBQyxPQUFPLEtBQUssRUFBRTtRQUNkLE9BQU8sUUFBUSxDQUFDO0tBQ2pCO0FBQ0gsQ0FBQyxDQUFDO0FBRUssTUFBTSxhQUFhLEdBQUcsQ0FDM0IsS0FBVSxFQUNzQyxFQUFFO0lBQ2xELE9BQU8sQ0FDTCxDQUFDLENBQUMsS0FBSztRQUNQLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFDekIsTUFBTSxJQUFJLEtBQUs7UUFDZixPQUFPLElBQUksS0FBSztRQUNoQixTQUFTLElBQUksS0FBSyxDQUNuQixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUssTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFNBQTZCLEVBQUUsRUFBRTtJQUN0RSxNQUFNLGlCQUFpQixHQUFHLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxnQkFBZ0IsQ0FDbkQsb0VBQW9FLENBQ3JFLENBQUM7SUFFRixPQUFPLGlCQUFpQjtRQUN0QixDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sQ0FDbEMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNWLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBRSxPQUE0QixDQUFDLFFBQVEsQ0FDbkU7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ1QsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL3V0aWxzLnRzPzc2M2EiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9jIGZyb20gXCJvcGVuLWNvbG9yXCI7XG5cbmltcG9ydCBjb2xvcnMgZnJvbSBcIi4vY29sb3JzXCI7XG5pbXBvcnQge1xuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9WRVJTSU9OLFxuICBFVkVOVCxcbiAgRk9OVF9GQU1JTFksXG4gIE1JTUVfVFlQRVMsXG4gIFRIRU1FLFxuICBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRm9udEZhbWlseVZhbHVlcywgRm9udFN0cmluZyB9IGZyb20gXCIuL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IEFwcFN0YXRlLCBEYXRhVVJMLCBMYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlciwgWm9vbSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyB1bnN0YWJsZV9iYXRjaGVkVXBkYXRlcyB9IGZyb20gXCJyZWFjdC1kb21cIjtcbmltcG9ydCB7IGlzRGFyd2luIH0gZnJvbSBcIi4va2V5c1wiO1xuaW1wb3J0IHsgU0hBUEVTIH0gZnJvbSBcIi4vc2hhcGVzXCI7XG5cbmxldCBtb2NrRGF0ZVRpbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgY29uc3Qgc2V0RGF0ZVRpbWVGb3JUZXN0cyA9IChkYXRlVGltZTogc3RyaW5nKSA9PiB7XG4gIG1vY2tEYXRlVGltZSA9IGRhdGVUaW1lO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldERhdGVUaW1lID0gKCkgPT4ge1xuICBpZiAobW9ja0RhdGVUaW1lKSB7XG4gICAgcmV0dXJuIG1vY2tEYXRlVGltZTtcbiAgfVxuXG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICBjb25zdCBtb250aCA9IGAke2RhdGUuZ2V0TW9udGgoKSArIDF9YC5wYWRTdGFydCgyLCBcIjBcIik7XG4gIGNvbnN0IGRheSA9IGAke2RhdGUuZ2V0RGF0ZSgpfWAucGFkU3RhcnQoMiwgXCIwXCIpO1xuICBjb25zdCBociA9IGAke2RhdGUuZ2V0SG91cnMoKX1gLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgY29uc3QgbWluID0gYCR7ZGF0ZS5nZXRNaW51dGVzKCl9YC5wYWRTdGFydCgyLCBcIjBcIik7XG5cbiAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fS0ke2hyfSR7bWlufWA7XG59O1xuXG5leHBvcnQgY29uc3QgY2FwaXRhbGl6ZVN0cmluZyA9IChzdHI6IHN0cmluZykgPT5cbiAgc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xuXG5leHBvcnQgY29uc3QgaXNUb29sSWNvbiA9IChcbiAgdGFyZ2V0OiBFbGVtZW50IHwgRXZlbnRUYXJnZXQgfCBudWxsLFxuKTogdGFyZ2V0IGlzIEhUTUxFbGVtZW50ID0+XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIHRhcmdldC5jbGFzc05hbWUuaW5jbHVkZXMoXCJUb29sSWNvblwiKTtcblxuZXhwb3J0IGNvbnN0IGlzSW5wdXRMaWtlID0gKFxuICB0YXJnZXQ6IEVsZW1lbnQgfCBFdmVudFRhcmdldCB8IG51bGwsXG4pOiB0YXJnZXQgaXNcbiAgfCBIVE1MSW5wdXRFbGVtZW50XG4gIHwgSFRNTFRleHRBcmVhRWxlbWVudFxuICB8IEhUTUxTZWxlY3RFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fFxuICB0YXJnZXQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50IHx8XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50O1xuXG5leHBvcnQgY29uc3QgaXNXcml0YWJsZUVsZW1lbnQgPSAoXG4gIHRhcmdldDogRWxlbWVudCB8IEV2ZW50VGFyZ2V0IHwgbnVsbCxcbik6IHRhcmdldCBpc1xuICB8IEhUTUxJbnB1dEVsZW1lbnRcbiAgfCBIVE1MVGV4dEFyZWFFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fFxuICAodGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJlxuICAgICh0YXJnZXQudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgdGFyZ2V0LnR5cGUgPT09IFwibnVtYmVyXCIpKTtcblxuZXhwb3J0IGNvbnN0IGdldEZvbnRGYW1pbHlTdHJpbmcgPSAoe1xuICBmb250RmFtaWx5LFxufToge1xuICBmb250RmFtaWx5OiBGb250RmFtaWx5VmFsdWVzO1xufSkgPT4ge1xuICBmb3IgKGNvbnN0IFtmb250RmFtaWx5U3RyaW5nLCBpZF0gb2YgT2JqZWN0LmVudHJpZXMoRk9OVF9GQU1JTFkpKSB7XG4gICAgaWYgKGlkID09PSBmb250RmFtaWx5KSB7XG4gICAgICByZXR1cm4gYCR7Zm9udEZhbWlseVN0cmluZ30sICR7V0lORE9XU19FTU9KSV9GQUxMQkFDS19GT05UfWA7XG4gICAgfVxuICB9XG4gIHJldHVybiBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQ7XG59O1xuXG4vKiogcmV0dXJucyBmb250U2l6ZStmb250RmFtaWx5IHN0cmluZyBmb3IgYXNzaWdubWVudCB0byBET00gZWxlbWVudHMgKi9cbmV4cG9ydCBjb25zdCBnZXRGb250U3RyaW5nID0gKHtcbiAgZm9udFNpemUsXG4gIGZvbnRGYW1pbHksXG59OiB7XG4gIGZvbnRTaXplOiBudW1iZXI7XG4gIGZvbnRGYW1pbHk6IEZvbnRGYW1pbHlWYWx1ZXM7XG59KSA9PiB7XG4gIHJldHVybiBgJHtmb250U2l6ZX1weCAke2dldEZvbnRGYW1pbHlTdHJpbmcoeyBmb250RmFtaWx5IH0pfWAgYXMgRm9udFN0cmluZztcbn07XG5cbmV4cG9ydCBjb25zdCBkZWJvdW5jZSA9IDxUIGV4dGVuZHMgYW55W10+KFxuICBmbjogKC4uLmFyZ3M6IFQpID0+IHZvaWQsXG4gIHRpbWVvdXQ6IG51bWJlcixcbikgPT4ge1xuICBsZXQgaGFuZGxlID0gMDtcbiAgbGV0IGxhc3RBcmdzOiBUIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IHJldCA9ICguLi5hcmdzOiBUKSA9PiB7XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGNsZWFyVGltZW91dChoYW5kbGUpO1xuICAgIGhhbmRsZSA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLmFyZ3MpO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9O1xuICByZXQuZmx1c2ggPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KGhhbmRsZSk7XG4gICAgaWYgKGxhc3RBcmdzKSB7XG4gICAgICBjb25zdCBfbGFzdEFyZ3MgPSBsYXN0QXJncztcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLl9sYXN0QXJncyk7XG4gICAgfVxuICB9O1xuICByZXQuY2FuY2VsID0gKCkgPT4ge1xuICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICBjbGVhclRpbWVvdXQoaGFuZGxlKTtcbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIHRocm90dGxlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgb25jZSBwZXIgYW5pbWF0aW9uIGZyYW1lXG5leHBvcnQgY29uc3QgdGhyb3R0bGVSQUYgPSA8VCBleHRlbmRzIGFueVtdPihcbiAgZm46ICguLi5hcmdzOiBUKSA9PiB2b2lkLFxuICBvcHRzPzogeyB0cmFpbGluZz86IGJvb2xlYW4gfSxcbikgPT4ge1xuICBsZXQgdGltZXJJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGxldCBsYXN0QXJnczogVCB8IG51bGwgPSBudWxsO1xuICBsZXQgbGFzdEFyZ3NUcmFpbGluZzogVCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IHNjaGVkdWxlRnVuYyA9IChhcmdzOiBUKSA9PiB7XG4gICAgdGltZXJJZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGltZXJJZCA9IG51bGw7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGlmIChsYXN0QXJnc1RyYWlsaW5nKSB7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdEFyZ3NUcmFpbGluZztcbiAgICAgICAgbGFzdEFyZ3NUcmFpbGluZyA9IG51bGw7XG4gICAgICAgIHNjaGVkdWxlRnVuYyhsYXN0QXJncyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgcmV0ID0gKC4uLmFyZ3M6IFQpID0+IHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGlmICh0aW1lcklkID09PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZUZ1bmMobGFzdEFyZ3MpO1xuICAgIH0gZWxzZSBpZiAob3B0cz8udHJhaWxpbmcpIHtcbiAgICAgIGxhc3RBcmdzVHJhaWxpbmcgPSBhcmdzO1xuICAgIH1cbiAgfTtcbiAgcmV0LmZsdXNoID0gKCkgPT4ge1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobGFzdEFyZ3MpIHtcbiAgICAgIGZuKC4uLihsYXN0QXJnc1RyYWlsaW5nIHx8IGxhc3RBcmdzKSk7XG4gICAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0LmNhbmNlbCA9ICgpID0+IHtcbiAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2Rhc2gvbG9kYXNoL2Jsb2IvZXMvY2h1bmsuanNcbmV4cG9ydCBjb25zdCBjaHVuayA9IDxUIGV4dGVuZHMgYW55PihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgc2l6ZTogbnVtYmVyLFxuKTogVFtdW10gPT4ge1xuICBpZiAoIWFycmF5Lmxlbmd0aCB8fCBzaXplIDwgMSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBsZXQgaW5kZXggPSAwO1xuICBsZXQgcmVzSW5kZXggPSAwO1xuICBjb25zdCByZXN1bHQgPSBBcnJheShNYXRoLmNlaWwoYXJyYXkubGVuZ3RoIC8gc2l6ZSkpO1xuICB3aGlsZSAoaW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBhcnJheS5zbGljZShpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdE5vZGUgPSAobm9kZTogRWxlbWVudCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKG5vZGUpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlU2VsZWN0aW9uID0gKCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBkaXN0YW5jZSA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gTWF0aC5hYnMoeCAtIHkpO1xuXG5leHBvcnQgY29uc3QgdXBkYXRlQWN0aXZlVG9vbCA9IChcbiAgYXBwU3RhdGU6IFBpY2s8QXBwU3RhdGUsIFwiYWN0aXZlVG9vbFwiPixcbiAgZGF0YTogKFxuICAgIHwgeyB0eXBlOiB0eXBlb2YgU0hBUEVTW251bWJlcl1bXCJ2YWx1ZVwiXSB8IFwiZXJhc2VyXCIgfVxuICAgIHwgeyB0eXBlOiBcImN1c3RvbVwiOyBjdXN0b21UeXBlOiBzdHJpbmcgfVxuICApICYgeyBsYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcj86IExhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyIH0sXG4pOiBBcHBTdGF0ZVtcImFjdGl2ZVRvb2xcIl0gPT4ge1xuICBpZiAoZGF0YS50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICB0eXBlOiBcImN1c3RvbVwiLFxuICAgICAgY3VzdG9tVHlwZTogZGF0YS5jdXN0b21UeXBlLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgbGFzdEFjdGl2ZVRvb2xCZWZvcmVFcmFzZXI6XG4gICAgICBkYXRhLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyID09PSB1bmRlZmluZWRcbiAgICAgICAgPyBhcHBTdGF0ZS5hY3RpdmVUb29sLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyXG4gICAgICAgIDogZGF0YS5sYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcixcbiAgICB0eXBlOiBkYXRhLnR5cGUsXG4gICAgY3VzdG9tVHlwZTogbnVsbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZXNldEN1cnNvciA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBpZiAoY2FudmFzKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IFwiXCI7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzZXRDdXJzb3IgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsIGN1cnNvcjogc3RyaW5nKSA9PiB7XG4gIGlmIChjYW52YXMpIHtcbiAgICBjYW52YXMuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xuICB9XG59O1xuXG5sZXQgZXJhc2VyQ2FudmFzQ2FjaGU6IGFueTtcbmxldCBwcmV2aWV3RGF0YVVSTDogc3RyaW5nO1xuZXhwb3J0IGNvbnN0IHNldEVyYXNlckN1cnNvciA9IChcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsXG4gIHRoZW1lOiBBcHBTdGF0ZVtcInRoZW1lXCJdLFxuKSA9PiB7XG4gIGNvbnN0IGN1cnNvckltYWdlU2l6ZVB4ID0gMjA7XG5cbiAgY29uc3QgZHJhd0NhbnZhcyA9ICgpID0+IHtcbiAgICBjb25zdCBpc0RhcmtUaGVtZSA9IHRoZW1lID09PSBUSEVNRS5EQVJLO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSA9IHRoZW1lO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLmhlaWdodCA9IGN1cnNvckltYWdlU2l6ZVB4O1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLndpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgY29uc3QgY29udGV4dCA9IGVyYXNlckNhbnZhc0NhY2hlLmdldENvbnRleHQoXCIyZFwiKSE7XG4gICAgY29udGV4dC5saW5lV2lkdGggPSAxO1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgY29udGV4dC5hcmMoXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS53aWR0aCAvIDIsXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS5oZWlnaHQgLyAyLFxuICAgICAgNSxcbiAgICAgIDAsXG4gICAgICAyICogTWF0aC5QSSxcbiAgICApO1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gaXNEYXJrVGhlbWUgPyBvYy5ibGFjayA6IG9jLndoaXRlO1xuICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBpc0RhcmtUaGVtZSA/IG9jLndoaXRlIDogb2MuYmxhY2s7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgICBwcmV2aWV3RGF0YVVSTCA9IGVyYXNlckNhbnZhc0NhY2hlLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgfTtcbiAgaWYgKCFlcmFzZXJDYW52YXNDYWNoZSB8fCBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSAhPT0gdGhlbWUpIHtcbiAgICBkcmF3Q2FudmFzKCk7XG4gIH1cblxuICBzZXRDdXJzb3IoXG4gICAgY2FudmFzLFxuICAgIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pICR7Y3Vyc29ySW1hZ2VTaXplUHggLyAyfSAke1xuICAgICAgY3Vyc29ySW1hZ2VTaXplUHggLyAyXG4gICAgfSwgYXV0b2AsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2V0Q3Vyc29yRm9yU2hhcGUgPSAoXG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4pID0+IHtcbiAgaWYgKCFjYW52YXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGFwcFN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgIHJlc2V0Q3Vyc29yKGNhbnZhcyk7XG4gIH0gZWxzZSBpZiAoYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiKSB7XG4gICAgc2V0RXJhc2VyQ3Vyc29yKGNhbnZhcywgYXBwU3RhdGUudGhlbWUpO1xuICAgIC8vIGRvIG5vdGhpbmcgaWYgaW1hZ2UgdG9vbCBpcyBzZWxlY3RlZCB3aGljaCBzdWdnZXN0cyB0aGVyZSdzXG4gICAgLy8gYSBpbWFnZS1wcmV2aWV3IHNldCBhcyB0aGUgY3Vyc29yXG4gICAgLy8gSWdub3JlIGN1c3RvbSB0eXBlIGFzIHdlbGwgYW5kIGxldCBob3N0IGRlY2lkZVxuICB9IGVsc2UgaWYgKCFbXCJpbWFnZVwiLCBcImN1c3RvbVwiXS5pbmNsdWRlcyhhcHBTdGF0ZS5hY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IENVUlNPUl9UWVBFLkNST1NTSEFJUjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGlzRnVsbFNjcmVlbiA9ICgpID0+XG4gIGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50Py5ub2RlTmFtZSA9PT0gXCJIVE1MXCI7XG5cbmV4cG9ydCBjb25zdCBhbGxvd0Z1bGxTY3JlZW4gPSAoKSA9PlxuICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGV4aXRGdWxsU2NyZWVuID0gKCkgPT4gZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGdldFNob3J0Y3V0S2V5ID0gKHNob3J0Y3V0OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBzaG9ydGN1dCA9IHNob3J0Y3V0XG4gICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIkFsdFwiKVxuICAgIC5yZXBsYWNlKC9cXGJTaGlmdFxcYi9pLCBcIlNoaWZ0XCIpXG4gICAgLnJlcGxhY2UoL1xcYihFbnRlcnxSZXR1cm4pXFxiL2ksIFwiRW50ZXJcIilcbiAgICAucmVwbGFjZSgvXFxiRGVsXFxiL2ksIFwiRGVsZXRlXCIpO1xuXG4gIGlmIChpc0Rhcndpbikge1xuICAgIHJldHVybiBzaG9ydGN1dFxuICAgICAgLnJlcGxhY2UoL1xcYkN0cmxPckNtZFxcYi9pLCBcIkNtZFwiKVxuICAgICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIk9wdGlvblwiKTtcbiAgfVxuICByZXR1cm4gc2hvcnRjdXQucmVwbGFjZSgvXFxiQ3RybE9yQ21kXFxiL2ksIFwiQ3RybFwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMgPSAoXG4gIHsgY2xpZW50WCwgY2xpZW50WSB9OiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0sXG4gIHtcbiAgICB6b29tLFxuICAgIG9mZnNldExlZnQsXG4gICAgb2Zmc2V0VG9wLFxuICAgIHNjcm9sbFgsXG4gICAgc2Nyb2xsWSxcbiAgfToge1xuICAgIHpvb206IFpvb207XG4gICAgb2Zmc2V0TGVmdDogbnVtYmVyO1xuICAgIG9mZnNldFRvcDogbnVtYmVyO1xuICAgIHNjcm9sbFg6IG51bWJlcjtcbiAgICBzY3JvbGxZOiBudW1iZXI7XG4gIH0sXG4pID0+IHtcbiAgY29uc3QgaW52U2NhbGUgPSAxIC8gem9vbS52YWx1ZTtcbiAgY29uc3QgeCA9IChjbGllbnRYIC0gb2Zmc2V0TGVmdCkgKiBpbnZTY2FsZSAtIHNjcm9sbFg7XG4gIGNvbnN0IHkgPSAoY2xpZW50WSAtIG9mZnNldFRvcCkgKiBpbnZTY2FsZSAtIHNjcm9sbFk7XG5cbiAgcmV0dXJuIHsgeCwgeSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyA9IChcbiAgeyBzY2VuZVgsIHNjZW5lWSB9OiB7IHNjZW5lWDogbnVtYmVyOyBzY2VuZVk6IG51bWJlciB9LFxuICB7XG4gICAgem9vbSxcbiAgICBvZmZzZXRMZWZ0LFxuICAgIG9mZnNldFRvcCxcbiAgICBzY3JvbGxYLFxuICAgIHNjcm9sbFksXG4gIH06IHtcbiAgICB6b29tOiBab29tO1xuICAgIG9mZnNldExlZnQ6IG51bWJlcjtcbiAgICBvZmZzZXRUb3A6IG51bWJlcjtcbiAgICBzY3JvbGxYOiBudW1iZXI7XG4gICAgc2Nyb2xsWTogbnVtYmVyO1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IHggPSAoc2NlbmVYICsgc2Nyb2xsWCkgKiB6b29tLnZhbHVlICsgb2Zmc2V0TGVmdDtcbiAgY29uc3QgeSA9IChzY2VuZVkgKyBzY3JvbGxZKSAqIHpvb20udmFsdWUgKyBvZmZzZXRUb3A7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRHbG9iYWxDU1NWYXJpYWJsZSA9IChuYW1lOiBzdHJpbmcpID0+XG4gIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKGAtLSR7bmFtZX1gKTtcblxuY29uc3QgUlNfTFRSX0NIQVJTID1cbiAgXCJBLVphLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyQjhcXHUwMzAwLVxcdTA1OTBcXHUwODAwLVxcdTFGRkZcIiArXG4gIFwiXFx1MkMwMC1cXHVGQjFDXFx1RkRGRS1cXHVGRTZGXFx1RkVGRC1cXHVGRkZGXCI7XG5jb25zdCBSU19SVExfQ0hBUlMgPSBcIlxcdTA1OTEtXFx1MDdGRlxcdUZCMUQtXFx1RkRGRFxcdUZFNzAtXFx1RkVGQ1wiO1xuY29uc3QgUkVfUlRMX0NIRUNLID0gbmV3IFJlZ0V4cChgXlteJHtSU19MVFJfQ0hBUlN9XSpbJHtSU19SVExfQ0hBUlN9XWApO1xuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBmaXJzdCBkaXJlY3Rpb25hbCBjaGFyYWN0ZXIgaXMgUlRMLiBNZWFuaW5nIHdoZXRoZXIgaXQgc3RhcnRzXG4gKiAgd2l0aCBSVEwgY2hhcmFjdGVycywgb3IgaW5kZXRlcm1pbmF0ZSAobnVtYmVycyBldGMuKSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5XG4gKiAgUlRMLlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC8xNzIyI2Rpc2N1c3Npb25fcjQzNjM0MDE3MVxuICovXG5leHBvcnQgY29uc3QgaXNSVEwgPSAodGV4dDogc3RyaW5nKSA9PiBSRV9SVExfQ0hFQ0sudGVzdCh0ZXh0KTtcblxuZXhwb3J0IGNvbnN0IHR1cGxlVG9Db29ycyA9IChcbiAgeHlUdXBsZTogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyXSxcbik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XG4gIGNvbnN0IFt4LCB5XSA9IHh5VHVwbGU7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbi8qKiB1c2UgYXMgYSByZWplY3Rpb25IYW5kbGVyIHRvIG11dGUgZmlsZXN5c3RlbSBBYm9ydCBlcnJvcnMgKi9cbmV4cG9ydCBjb25zdCBtdXRlRlNBYm9ydEVycm9yID0gKGVycm9yPzogRXJyb3IpID0+IHtcbiAgaWYgKGVycm9yPy5uYW1lID09PSBcIkFib3J0RXJyb3JcIikge1xuICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRocm93IGVycm9yO1xufTtcblxuZXhwb3J0IGNvbnN0IGZpbmRJbmRleCA9IDxUPihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgY2I6IChlbGVtZW50OiBULCBpbmRleDogbnVtYmVyLCBhcnJheTogcmVhZG9ubHkgVFtdKSA9PiBib29sZWFuLFxuICBmcm9tSW5kZXg6IG51bWJlciA9IDAsXG4pID0+IHtcbiAgaWYgKGZyb21JbmRleCA8IDApIHtcbiAgICBmcm9tSW5kZXggPSBhcnJheS5sZW5ndGggKyBmcm9tSW5kZXg7XG4gIH1cbiAgZnJvbUluZGV4ID0gTWF0aC5taW4oYXJyYXkubGVuZ3RoLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4IC0gMTtcbiAgd2hpbGUgKCsraW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICBpZiAoY2IoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbmV4cG9ydCBjb25zdCBmaW5kTGFzdEluZGV4ID0gPFQ+KFxuICBhcnJheTogcmVhZG9ubHkgVFtdLFxuICBjYjogKGVsZW1lbnQ6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiByZWFkb25seSBUW10pID0+IGJvb2xlYW4sXG4gIGZyb21JbmRleDogbnVtYmVyID0gYXJyYXkubGVuZ3RoIC0gMSxcbikgPT4ge1xuICBpZiAoZnJvbUluZGV4IDwgMCkge1xuICAgIGZyb21JbmRleCA9IGFycmF5Lmxlbmd0aCArIGZyb21JbmRleDtcbiAgfVxuICBmcm9tSW5kZXggPSBNYXRoLm1pbihhcnJheS5sZW5ndGggLSAxLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4ICsgMTtcbiAgd2hpbGUgKC0taW5kZXggPiAtMSkge1xuICAgIGlmIChjYihhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzVHJhbnNwYXJlbnQgPSAoY29sb3I6IHN0cmluZykgPT4ge1xuICBjb25zdCBpc1JHQlRyYW5zcGFyZW50ID0gY29sb3IubGVuZ3RoID09PSA1ICYmIGNvbG9yLnN1YnN0cig0LCAxKSA9PT0gXCIwXCI7XG4gIGNvbnN0IGlzUlJHR0JCVHJhbnNwYXJlbnQgPSBjb2xvci5sZW5ndGggPT09IDkgJiYgY29sb3Iuc3Vic3RyKDcsIDIpID09PSBcIjAwXCI7XG4gIHJldHVybiAoXG4gICAgaXNSR0JUcmFuc3BhcmVudCB8fFxuICAgIGlzUlJHR0JCVHJhbnNwYXJlbnQgfHxcbiAgICBjb2xvciA9PT0gY29sb3JzLmVsZW1lbnRCYWNrZ3JvdW5kWzBdXG4gICk7XG59O1xuXG5leHBvcnQgdHlwZSBSZXNvbHZhYmxlUHJvbWlzZTxUPiA9IFByb21pc2U8VD4gJiB7XG4gIHJlc29sdmU6IFtUXSBleHRlbmRzIFt1bmRlZmluZWRdID8gKHZhbHVlPzogVCkgPT4gdm9pZCA6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xufTtcbmV4cG9ydCBjb25zdCByZXNvbHZhYmxlUHJvbWlzZSA9IDxUPigpID0+IHtcbiAgbGV0IHJlc29sdmUhOiBhbnk7XG4gIGxldCByZWplY3QhOiBhbnk7XG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgcmVqZWN0ID0gX3JlamVjdDtcbiAgfSk7XG4gIChwcm9taXNlIGFzIGFueSkucmVzb2x2ZSA9IHJlc29sdmU7XG4gIChwcm9taXNlIGFzIGFueSkucmVqZWN0ID0gcmVqZWN0O1xuICByZXR1cm4gcHJvbWlzZSBhcyBSZXNvbHZhYmxlUHJvbWlzZTxUPjtcbn07XG5cbi8qKlxuICogQHBhcmFtIGZ1bmMgaGFuZGxlciB0YWtpbmcgYXQgbW9zdCBzaW5nbGUgcGFyYW1ldGVyIChldmVudCkuXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXMgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PlxuICAoKGV2ZW50KSA9PiB7XG4gICAgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMoZnVuYyBhcyBURnVuY3Rpb24sIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uO1xuXG4vKipcbiAqIGJhcmNoZXMgUmVhY3Qgc3RhdGUgdXBkYXRlcyBhbmQgdGhyb3R0bGVzIHRoZSBjYWxscyB0byBhIHNpbmdsZSBjYWxsIHBlclxuICogYW5pbWF0aW9uIGZyYW1lXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PiB7XG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIHRocm90dGxlUkFGPFBhcmFtZXRlcnM8VEZ1bmN0aW9uPj4oKChldmVudCkgPT4ge1xuICAgIHVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzKGZ1bmMsIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uKTtcbn07XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzk0NjIzODIvODQxOFxuZXhwb3J0IGNvbnN0IG5Gb3JtYXR0ZXIgPSAobnVtOiBudW1iZXIsIGRpZ2l0czogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2kgPSBbXG4gICAgeyB2YWx1ZTogMSwgc3ltYm9sOiBcImJcIiB9LFxuICAgIHsgdmFsdWU6IDFlMywgc3ltYm9sOiBcImtcIiB9LFxuICAgIHsgdmFsdWU6IDFlNiwgc3ltYm9sOiBcIk1cIiB9LFxuICAgIHsgdmFsdWU6IDFlOSwgc3ltYm9sOiBcIkdcIiB9LFxuICBdO1xuICBjb25zdCByeCA9IC9cXC4wKyR8KFxcLlswLTldKlsxLTldKTArJC87XG4gIGxldCBpbmRleDtcbiAgZm9yIChpbmRleCA9IHNpLmxlbmd0aCAtIDE7IGluZGV4ID4gMDsgaW5kZXgtLSkge1xuICAgIGlmIChudW0gPj0gc2lbaW5kZXhdLnZhbHVlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIChcbiAgICAobnVtIC8gc2lbaW5kZXhdLnZhbHVlKS50b0ZpeGVkKGRpZ2l0cykucmVwbGFjZShyeCwgXCIkMVwiKSArIHNpW2luZGV4XS5zeW1ib2xcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRWZXJzaW9uID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTE1ldGFFbGVtZW50PignbWV0YVtuYW1lPVwidmVyc2lvblwiXScpPy5jb250ZW50IHx8XG4gICAgREVGQVVMVF9WRVJTSU9OXG4gICk7XG59O1xuXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2Vtb2ppLmpzXG5leHBvcnQgY29uc3Qgc3VwcG9ydHNFbW9qaSA9ICgpID0+IHtcbiAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgaWYgKCFjdHgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgb2Zmc2V0ID0gMTI7XG4gIGN0eC5maWxsU3R5bGUgPSBcIiNmMDBcIjtcbiAgY3R4LnRleHRCYXNlbGluZSA9IFwidG9wXCI7XG4gIGN0eC5mb250ID0gXCIzMnB4IEFyaWFsXCI7XG4gIC8vIE1vZGVybml6ciB1c2VkIPCfkKgsIGJ1dCBpdCBpcyBzb3J0IG9mIHN1cHBvcnRlZCBvbiBXaW5kb3dzIDcuXG4gIC8vIEx1Y2tpbHkg8J+YgCBpc24ndCBzdXBwb3J0ZWQuXG4gIGN0eC5maWxsVGV4dChcIvCfmIBcIiwgMCwgMCk7XG4gIHJldHVybiBjdHguZ2V0SW1hZ2VEYXRhKG9mZnNldCwgb2Zmc2V0LCAxLCAxKS5kYXRhWzBdICE9PSAwO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbik6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgcmV0dXJuIGRvY3VtZW50O1xuICAgIH1cbiAgICBjb25zdCB7IG92ZXJmbG93WSB9ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcbiAgICBjb25zdCBoYXNTY3JvbGxhYmxlQ29udGVudCA9IHBhcmVudC5zY3JvbGxIZWlnaHQgPiBwYXJlbnQuY2xpZW50SGVpZ2h0O1xuICAgIGlmIChcbiAgICAgIGhhc1Njcm9sbGFibGVDb250ZW50ICYmXG4gICAgICAob3ZlcmZsb3dZID09PSBcImF1dG9cIiB8fFxuICAgICAgICBvdmVyZmxvd1kgPT09IFwic2Nyb2xsXCIgfHxcbiAgICAgICAgb3ZlcmZsb3dZID09PSBcIm92ZXJsYXlcIilcbiAgICApIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudDtcbn07XG5cbmV4cG9ydCBjb25zdCBmb2N1c05lYXJlc3RQYXJlbnQgPSAoZWxlbWVudDogSFRNTElucHV0RWxlbWVudCkgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudC50YWJJbmRleCA+IC0xKSB7XG4gICAgICBwYXJlbnQuZm9jdXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudEVsZW1lbnQ7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwcmV2ZW50VW5sb2FkID0gKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCkgPT4ge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAvLyBOT1RFOiBtb2Rlcm4gYnJvd3NlcnMgbm8gbG9uZ2VyIGFsbG93IHNob3dpbmcgYSBjdXN0b20gbWVzc2FnZSBoZXJlXG4gIGV2ZW50LnJldHVyblZhbHVlID0gXCJcIjtcbn07XG5cbmV4cG9ydCBjb25zdCBieXRlc1RvSGV4U3RyaW5nID0gKGJ5dGVzOiBVaW50OEFycmF5KSA9PiB7XG4gIHJldHVybiBBcnJheS5mcm9tKGJ5dGVzKVxuICAgIC5tYXAoKGJ5dGUpID0+IGAwJHtieXRlLnRvU3RyaW5nKDE2KX1gLnNsaWNlKC0yKSlcbiAgICAuam9pbihcIlwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVcGRhdGVkVGltZXN0YW1wID0gKCkgPT4gKGlzVGVzdEVudigpID8gMSA6IERhdGUubm93KCkpO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nIGBpZGAgYXR0cmlidXRlLFxuICogb3IgYXJyYXkgb2YgaWRzIChzdHJpbmdzKSwgaW50byBhIE1hcCwga2V5ZCBieSBgaWRgLlxuICovXG5leHBvcnQgY29uc3QgYXJyYXlUb01hcCA9IDxUIGV4dGVuZHMgeyBpZDogc3RyaW5nIH0gfCBzdHJpbmc+KFxuICBpdGVtczogcmVhZG9ubHkgVFtdLFxuKSA9PiB7XG4gIHJldHVybiBpdGVtcy5yZWR1Y2UoKGFjYzogTWFwPHN0cmluZywgVD4sIGVsZW1lbnQpID0+IHtcbiAgICBhY2Muc2V0KHR5cGVvZiBlbGVtZW50ID09PSBcInN0cmluZ1wiID8gZWxlbWVudCA6IGVsZW1lbnQuaWQsIGVsZW1lbnQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIG5ldyBNYXAoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgaXNUZXN0RW52ID0gKCkgPT5cbiAgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2Vzcy5lbnY/Lk5PREVfRU5WID09PSBcInRlc3RcIjtcblxuZXhwb3J0IGNvbnN0IGlzUHJvZEVudiA9ICgpID0+XG4gIHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MuZW52Py5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCI7XG5cbmV4cG9ydCBjb25zdCB3cmFwRXZlbnQgPSA8VCBleHRlbmRzIEV2ZW50PihuYW1lOiBFVkVOVCwgbmF0aXZlRXZlbnQ6IFQpID0+IHtcbiAgcmV0dXJuIG5ldyBDdXN0b21FdmVudChuYW1lLCB7XG4gICAgZGV0YWlsOiB7XG4gICAgICBuYXRpdmVFdmVudCxcbiAgICB9LFxuICAgIGNhbmNlbGFibGU6IHRydWUsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZU9iamVjdCA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIG9iajogVCxcbiAgdXBkYXRlczogUGFydGlhbDxUPixcbik6IFQgPT4ge1xuICBsZXQgZGlkQ2hhbmdlID0gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IGluIHVwZGF0ZXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9ICh1cGRhdGVzIGFzIGFueSlba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChvYmogYXMgYW55KVtrZXldID09PSB2YWx1ZSAmJlxuICAgICAgICAvLyBpZiBvYmplY3QsIGFsd2F5cyB1cGRhdGUgYmVjYXVzZSBpdHMgYXR0cnMgY291bGQgaGF2ZSBjaGFuZ2VkXG4gICAgICAgICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgdmFsdWUgPT09IG51bGwpXG4gICAgICApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBkaWRDaGFuZ2UgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghZGlkQ2hhbmdlKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4ub2JqLFxuICAgIC4uLnVwZGF0ZXMsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcmltaXRpdmUgPSAodmFsOiBhbnkpID0+IHtcbiAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWw7XG4gIHJldHVybiB2YWwgPT0gbnVsbCB8fCAodHlwZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlICE9PSBcImZ1bmN0aW9uXCIpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEZyYW1lID0gKCkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cuc2VsZiA9PT0gd2luZG93LnRvcCA/IFwidG9wXCIgOiBcImlmcmFtZVwiO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBcImlmcmFtZVwiO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcm9taXNlTGlrZSA9IChcbiAgdmFsdWU6IGFueSxcbik6IHZhbHVlIGlzIFByb21pc2U8UmVzb2x1dGlvblR5cGU8dHlwZW9mIHZhbHVlPj4gPT4ge1xuICByZXR1cm4gKFxuICAgICEhdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICBcInRoZW5cIiBpbiB2YWx1ZSAmJlxuICAgIFwiY2F0Y2hcIiBpbiB2YWx1ZSAmJlxuICAgIFwiZmluYWxseVwiIGluIHZhbHVlXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcXVlcnlGb2N1c2FibGVFbGVtZW50cyA9IChjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBjb25zdCBmb2N1c2FibGVFbGVtZW50cyA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oXG4gICAgXCJidXR0b24sIGEsIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBkaXZbdGFiaW5kZXhdLCBsYWJlbFt0YWJpbmRleF1cIixcbiAgKTtcblxuICByZXR1cm4gZm9jdXNhYmxlRWxlbWVudHNcbiAgICA/IEFycmF5LmZyb20oZm9jdXNhYmxlRWxlbWVudHMpLmZpbHRlcihcbiAgICAgICAgKGVsZW1lbnQpID0+XG4gICAgICAgICAgZWxlbWVudC50YWJJbmRleCA+IC0xICYmICEoZWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50KS5kaXNhYmxlZCxcbiAgICAgIClcbiAgICA6IFtdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../utils.ts\n");
3341
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"allowFullScreen\": () => (/* binding */ allowFullScreen),\n/* harmony export */ \"arrayToMap\": () => (/* binding */ arrayToMap),\n/* harmony export */ \"bytesToHexString\": () => (/* binding */ bytesToHexString),\n/* harmony export */ \"capitalizeString\": () => (/* binding */ capitalizeString),\n/* harmony export */ \"chunk\": () => (/* binding */ chunk),\n/* harmony export */ \"debounce\": () => (/* binding */ debounce),\n/* harmony export */ \"distance\": () => (/* binding */ distance),\n/* harmony export */ \"exitFullScreen\": () => (/* binding */ exitFullScreen),\n/* harmony export */ \"findIndex\": () => (/* binding */ findIndex),\n/* harmony export */ \"findLastIndex\": () => (/* binding */ findLastIndex),\n/* harmony export */ \"focusNearestParent\": () => (/* binding */ focusNearestParent),\n/* harmony export */ \"getDateTime\": () => (/* binding */ getDateTime),\n/* harmony export */ \"getFontFamilyString\": () => (/* binding */ getFontFamilyString),\n/* harmony export */ \"getFontString\": () => (/* binding */ getFontString),\n/* harmony export */ \"getFrame\": () => (/* binding */ getFrame),\n/* harmony export */ \"getGlobalCSSVariable\": () => (/* binding */ getGlobalCSSVariable),\n/* harmony export */ \"getNearestScrollableContainer\": () => (/* binding */ getNearestScrollableContainer),\n/* harmony export */ \"getShortcutKey\": () => (/* binding */ getShortcutKey),\n/* harmony export */ \"getUpdatedTimestamp\": () => (/* binding */ getUpdatedTimestamp),\n/* harmony export */ \"getVersion\": () => (/* binding */ getVersion),\n/* harmony export */ \"isFullScreen\": () => (/* binding */ isFullScreen),\n/* harmony export */ \"isInputLike\": () => (/* binding */ isInputLike),\n/* harmony export */ \"isPrimitive\": () => (/* binding */ isPrimitive),\n/* harmony export */ \"isProdEnv\": () => (/* binding */ isProdEnv),\n/* harmony export */ \"isPromiseLike\": () => (/* binding */ isPromiseLike),\n/* harmony export */ \"isRTL\": () => (/* binding */ isRTL),\n/* harmony export */ \"isTestEnv\": () => (/* binding */ isTestEnv),\n/* harmony export */ \"isToolIcon\": () => (/* binding */ isToolIcon),\n/* harmony export */ \"isTransparent\": () => (/* binding */ isTransparent),\n/* harmony export */ \"isWritableElement\": () => (/* binding */ isWritableElement),\n/* harmony export */ \"muteFSAbortError\": () => (/* binding */ muteFSAbortError),\n/* harmony export */ \"nFormatter\": () => (/* binding */ nFormatter),\n/* harmony export */ \"preventUnload\": () => (/* binding */ preventUnload),\n/* harmony export */ \"queryFocusableElements\": () => (/* binding */ queryFocusableElements),\n/* harmony export */ \"removeSelection\": () => (/* binding */ removeSelection),\n/* harmony export */ \"resetCursor\": () => (/* binding */ resetCursor),\n/* harmony export */ \"resolvablePromise\": () => (/* binding */ resolvablePromise),\n/* harmony export */ \"sceneCoordsToViewportCoords\": () => (/* binding */ sceneCoordsToViewportCoords),\n/* harmony export */ \"selectNode\": () => (/* binding */ selectNode),\n/* harmony export */ \"setCursor\": () => (/* binding */ setCursor),\n/* harmony export */ \"setCursorForShape\": () => (/* binding */ setCursorForShape),\n/* harmony export */ \"setDateTimeForTests\": () => (/* binding */ setDateTimeForTests),\n/* harmony export */ \"setEraserCursor\": () => (/* binding */ setEraserCursor),\n/* harmony export */ \"supportsEmoji\": () => (/* binding */ supportsEmoji),\n/* harmony export */ \"throttleRAF\": () => (/* binding */ throttleRAF),\n/* harmony export */ \"tupleToCoors\": () => (/* binding */ tupleToCoors),\n/* harmony export */ \"updateActiveTool\": () => (/* binding */ updateActiveTool),\n/* harmony export */ \"updateObject\": () => (/* binding */ updateObject),\n/* harmony export */ \"viewportCoordsToSceneCoords\": () => (/* binding */ viewportCoordsToSceneCoords),\n/* harmony export */ \"withBatchedUpdates\": () => (/* binding */ withBatchedUpdates),\n/* harmony export */ \"withBatchedUpdatesThrottled\": () => (/* binding */ withBatchedUpdatesThrottled),\n/* harmony export */ \"wrapEvent\": () => (/* binding */ wrapEvent)\n/* harmony export */ });\n/* harmony import */ var open_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! open-color */ \"../../../node_modules/open-color/open-color.json\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../../colors.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ \"../../constants.ts\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./keys */ \"../../keys.ts\");\n\n\n\n\n\nlet mockDateTime = null;\nconst setDateTimeForTests = (dateTime) => {\n mockDateTime = dateTime;\n};\nconst getDateTime = () => {\n if (mockDateTime) {\n return mockDateTime;\n }\n const date = new Date();\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${date.getDate()}`.padStart(2, \"0\");\n const hr = `${date.getHours()}`.padStart(2, \"0\");\n const min = `${date.getMinutes()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}-${hr}${min}`;\n};\nconst capitalizeString = (str) => str.charAt(0).toUpperCase() + str.slice(1);\nconst isToolIcon = (target) => target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\nconst isInputLike = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target instanceof HTMLSelectElement;\nconst isWritableElement = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLTextAreaElement ||\n (target instanceof HTMLInputElement &&\n (target.type === \"text\" || target.type === \"number\"));\nconst getFontFamilyString = ({ fontFamily, }) => {\n for (const [fontFamilyString, id] of Object.entries(_constants__WEBPACK_IMPORTED_MODULE_2__.FONT_FAMILY)) {\n if (id === fontFamily) {\n return `${fontFamilyString}, ${_constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT}`;\n }\n }\n return _constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT;\n};\n/** returns fontSize+fontFamily string for assignment to DOM elements */\nconst getFontString = ({ fontSize, fontFamily, }) => {\n return `${fontSize}px ${getFontFamilyString({ fontFamily })}`;\n};\nconst debounce = (fn, timeout) => {\n let handle = 0;\n let lastArgs = null;\n const ret = (...args) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n ret.flush = () => {\n clearTimeout(handle);\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n return ret;\n};\n// throttle callback to execute once per animation frame\nconst throttleRAF = (fn, opts) => {\n let timerId = null;\n let lastArgs = null;\n let lastArgsTrailing = null;\n const scheduleFunc = (args) => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n const ret = (...args) => {\n if (false) {}\n lastArgs = args;\n if (timerId === null) {\n scheduleFunc(lastArgs);\n }\n else if (opts === null || opts === void 0 ? void 0 : opts.trailing) {\n lastArgsTrailing = args;\n }\n };\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n return ret;\n};\n// https://github.com/lodash/lodash/blob/es/chunk.js\nconst chunk = (array, size) => {\n if (!array.length || size < 1) {\n return [];\n }\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n while (index < array.length) {\n result[resIndex++] = array.slice(index, (index += size));\n }\n return result;\n};\nconst selectNode = (node) => {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\nconst removeSelection = () => {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n }\n};\nconst distance = (x, y) => Math.abs(x - y);\nconst updateActiveTool = (appState, data) => {\n if (data.type === \"custom\") {\n return Object.assign(Object.assign({}, appState.activeTool), { type: \"custom\", customType: data.customType });\n }\n return Object.assign(Object.assign({}, appState.activeTool), { lastActiveToolBeforeEraser: data.lastActiveToolBeforeEraser === undefined\n ? appState.activeTool.lastActiveToolBeforeEraser\n : data.lastActiveToolBeforeEraser, type: data.type, customType: null });\n};\nconst resetCursor = (canvas) => {\n if (canvas) {\n canvas.style.cursor = \"\";\n }\n};\nconst setCursor = (canvas, cursor) => {\n if (canvas) {\n canvas.style.cursor = cursor;\n }\n};\nlet eraserCanvasCache;\nlet previewDataURL;\nconst setEraserCursor = (canvas, theme) => {\n const cursorImageSizePx = 20;\n const drawCanvas = () => {\n const isDarkTheme = theme === _constants__WEBPACK_IMPORTED_MODULE_2__.THEME.DARK;\n eraserCanvasCache = document.createElement(\"canvas\");\n eraserCanvasCache.theme = theme;\n eraserCanvasCache.height = cursorImageSizePx;\n eraserCanvasCache.width = cursorImageSizePx;\n const context = eraserCanvasCache.getContext(\"2d\");\n context.lineWidth = 1;\n context.beginPath();\n context.arc(eraserCanvasCache.width / 2, eraserCanvasCache.height / 2, 5, 0, 2 * Math.PI);\n context.fillStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.black : open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.fill();\n context.strokeStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.white : open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n context.stroke();\n previewDataURL = eraserCanvasCache.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_2__.MIME_TYPES.svg);\n };\n if (!eraserCanvasCache || eraserCanvasCache.theme !== theme) {\n drawCanvas();\n }\n setCursor(canvas, `url(${previewDataURL}) ${cursorImageSizePx / 2} ${cursorImageSizePx / 2}, auto`);\n};\nconst setCursorForShape = (canvas, appState) => {\n if (!canvas) {\n return;\n }\n if (appState.activeTool.type === \"selection\") {\n resetCursor(canvas);\n }\n else if (appState.activeTool.type === \"eraser\") {\n setEraserCursor(canvas, appState.theme);\n // do nothing if image tool is selected which suggests there's\n // a image-preview set as the cursor\n // Ignore custom type as well and let host decide\n }\n else if (![\"image\", \"custom\"].includes(appState.activeTool.type)) {\n canvas.style.cursor = _constants__WEBPACK_IMPORTED_MODULE_2__.CURSOR_TYPE.CROSSHAIR;\n }\n};\nconst isFullScreen = () => { var _a; return ((_a = document.fullscreenElement) === null || _a === void 0 ? void 0 : _a.nodeName) === \"HTML\"; };\nconst allowFullScreen = () => document.documentElement.requestFullscreen();\nconst exitFullScreen = () => document.exitFullscreen();\nconst getShortcutKey = (shortcut) => {\n shortcut = shortcut\n .replace(/\\bAlt\\b/i, \"Alt\")\n .replace(/\\bShift\\b/i, \"Shift\")\n .replace(/\\b(Enter|Return)\\b/i, \"Enter\")\n .replace(/\\bDel\\b/i, \"Delete\");\n if (_keys__WEBPACK_IMPORTED_MODULE_4__.isDarwin) {\n return shortcut\n .replace(/\\bCtrlOrCmd\\b/i, \"Cmd\")\n .replace(/\\bAlt\\b/i, \"Option\");\n }\n return shortcut.replace(/\\bCtrlOrCmd\\b/i, \"Ctrl\");\n};\nconst viewportCoordsToSceneCoords = ({ clientX, clientY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const invScale = 1 / zoom.value;\n const x = (clientX - offsetLeft) * invScale - scrollX;\n const y = (clientY - offsetTop) * invScale - scrollY;\n return { x, y };\n};\nconst sceneCoordsToViewportCoords = ({ sceneX, sceneY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return { x, y };\n};\nconst getGlobalCSSVariable = (name) => getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\nconst RS_LTR_CHARS = \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" +\n \"\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF\";\nconst RS_RTL_CHARS = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst RE_RTL_CHECK = new RegExp(`^[^${RS_LTR_CHARS}]*[${RS_RTL_CHARS}]`);\n/**\n * Checks whether first directional character is RTL. Meaning whether it starts\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\n * RTL.\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\n */\nconst isRTL = (text) => RE_RTL_CHECK.test(text);\nconst tupleToCoors = (xyTuple) => {\n const [x, y] = xyTuple;\n return { x, y };\n};\n/** use as a rejectionHandler to mute filesystem Abort errors */\nconst muteFSAbortError = (error) => {\n if ((error === null || error === void 0 ? void 0 : error.name) === \"AbortError\") {\n console.warn(error);\n return;\n }\n throw error;\n};\nconst findIndex = (array, cb, fromIndex = 0) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst findLastIndex = (array, cb, fromIndex = array.length - 1) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst isTransparent = (color) => {\n const isRGBTransparent = color.length === 5 && color.substr(4, 1) === \"0\";\n const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === \"00\";\n return (isRGBTransparent ||\n isRRGGBBTransparent ||\n color === _colors__WEBPACK_IMPORTED_MODULE_1__[\"default\"].elementBackground[0]);\n};\nconst resolvablePromise = () => {\n let resolve;\n let reject;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n promise.resolve = resolve;\n promise.reject = reject;\n return promise;\n};\n/**\n * @param func handler taking at most single parameter (event).\n */\nconst withBatchedUpdates = (func) => ((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n});\n/**\n * barches React state updates and throttles the calls to a single call per\n * animation frame\n */\nconst withBatchedUpdatesThrottled = (func) => {\n // @ts-ignore\n return throttleRAF(((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n }));\n};\n//https://stackoverflow.com/a/9462382/8418\nconst nFormatter = (num, digits) => {\n const si = [\n { value: 1, symbol: \"b\" },\n { value: 1e3, symbol: \"k\" },\n { value: 1e6, symbol: \"M\" },\n { value: 1e9, symbol: \"G\" },\n ];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n return ((num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol);\n};\nconst getVersion = () => {\n var _a;\n return (((_a = document.querySelector('meta[name=\"version\"]')) === null || _a === void 0 ? void 0 : _a.content) ||\n _constants__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_VERSION);\n};\n// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\nconst supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return false;\n }\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\";\n // Modernizr used 🐨, but it is sort of supported on Windows 7.\n // Luckily 😀 isn't supported.\n ctx.fillText(\"😀\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\nconst getNearestScrollableContainer = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n const { overflowY } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n if (hasScrollableContent &&\n (overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n overflowY === \"overlay\")) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return document;\n};\nconst focusNearestParent = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n parent = parent.parentElement;\n }\n};\nconst preventUnload = (event) => {\n event.preventDefault();\n // NOTE: modern browsers no longer allow showing a custom message here\n event.returnValue = \"\";\n};\nconst bytesToHexString = (bytes) => {\n return Array.from(bytes)\n .map((byte) => `0${byte.toString(16)}`.slice(-2))\n .join(\"\");\n};\nconst getUpdatedTimestamp = () => (isTestEnv() ? 1 : Date.now());\n/**\n * Transforms array of objects containing `id` attribute,\n * or array of ids (strings), into a Map, keyd by `id`.\n */\nconst arrayToMap = (items) => {\n return items.reduce((acc, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\nconst isTestEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-45b5922\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"test\"; };\nconst isProdEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"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\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-45b5922\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"production\"; };\nconst wrapEvent = (name, nativeEvent) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent,\n },\n cancelable: true,\n });\n};\nconst updateObject = (obj, updates) => {\n let didChange = false;\n for (const key in updates) {\n const value = updates[key];\n if (typeof value !== \"undefined\") {\n if (obj[key] === value &&\n // if object, always update because its attrs could have changed\n (typeof value !== \"object\" || value === null)) {\n continue;\n }\n didChange = true;\n }\n }\n if (!didChange) {\n return obj;\n }\n return Object.assign(Object.assign({}, obj), updates);\n};\nconst isPrimitive = (val) => {\n const type = typeof val;\n return val == null || (type !== \"object\" && type !== \"function\");\n};\nconst getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n }\n catch (error) {\n return \"iframe\";\n }\n};\nconst isPromiseLike = (value) => {\n return (!!value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n \"catch\" in value &&\n \"finally\" in value);\n};\nconst queryFocusableElements = (container) => {\n const focusableElements = container === null || container === void 0 ? void 0 : container.querySelectorAll(\"button, a, input, select, textarea, div[tabindex], label[tabindex]\");\n return focusableElements\n ? Array.from(focusableElements).filter((element) => element.tabIndex > -1 && !element.disabled)\n : [];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFFBQVEsSUFBSSxJQUFJLEtBQUssVUFBVSxDQUFDLENBQUM7QUFDbkUsQ0FBQyxDQUFDO0FBRUssTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUk7UUFDRixPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7S0FDdEQ7SUFBQyxPQUFPLEtBQUssRUFBRTtRQUNkLE9BQU8sUUFBUSxDQUFDO0tBQ2pCO0FBQ0gsQ0FBQyxDQUFDO0FBRUssTUFBTSxhQUFhLEdBQUcsQ0FDM0IsS0FBVSxFQUNzQyxFQUFFO0lBQ2xELE9BQU8sQ0FDTCxDQUFDLENBQUMsS0FBSztRQUNQLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFDekIsTUFBTSxJQUFJLEtBQUs7UUFDZixPQUFPLElBQUksS0FBSztRQUNoQixTQUFTLElBQUksS0FBSyxDQUNuQixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUssTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFNBQTZCLEVBQUUsRUFBRTtJQUN0RSxNQUFNLGlCQUFpQixHQUFHLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxnQkFBZ0IsQ0FDbkQsb0VBQW9FLENBQ3JFLENBQUM7SUFFRixPQUFPLGlCQUFpQjtRQUN0QixDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sQ0FDbEMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNWLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBRSxPQUE0QixDQUFDLFFBQVEsQ0FDbkU7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ1QsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL3V0aWxzLnRzPzc2M2EiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9jIGZyb20gXCJvcGVuLWNvbG9yXCI7XG5cbmltcG9ydCBjb2xvcnMgZnJvbSBcIi4vY29sb3JzXCI7XG5pbXBvcnQge1xuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9WRVJTSU9OLFxuICBFVkVOVCxcbiAgRk9OVF9GQU1JTFksXG4gIE1JTUVfVFlQRVMsXG4gIFRIRU1FLFxuICBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRm9udEZhbWlseVZhbHVlcywgRm9udFN0cmluZyB9IGZyb20gXCIuL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IEFwcFN0YXRlLCBEYXRhVVJMLCBMYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlciwgWm9vbSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyB1bnN0YWJsZV9iYXRjaGVkVXBkYXRlcyB9IGZyb20gXCJyZWFjdC1kb21cIjtcbmltcG9ydCB7IGlzRGFyd2luIH0gZnJvbSBcIi4va2V5c1wiO1xuaW1wb3J0IHsgU0hBUEVTIH0gZnJvbSBcIi4vc2hhcGVzXCI7XG5cbmxldCBtb2NrRGF0ZVRpbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgY29uc3Qgc2V0RGF0ZVRpbWVGb3JUZXN0cyA9IChkYXRlVGltZTogc3RyaW5nKSA9PiB7XG4gIG1vY2tEYXRlVGltZSA9IGRhdGVUaW1lO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldERhdGVUaW1lID0gKCkgPT4ge1xuICBpZiAobW9ja0RhdGVUaW1lKSB7XG4gICAgcmV0dXJuIG1vY2tEYXRlVGltZTtcbiAgfVxuXG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICBjb25zdCBtb250aCA9IGAke2RhdGUuZ2V0TW9udGgoKSArIDF9YC5wYWRTdGFydCgyLCBcIjBcIik7XG4gIGNvbnN0IGRheSA9IGAke2RhdGUuZ2V0RGF0ZSgpfWAucGFkU3RhcnQoMiwgXCIwXCIpO1xuICBjb25zdCBociA9IGAke2RhdGUuZ2V0SG91cnMoKX1gLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgY29uc3QgbWluID0gYCR7ZGF0ZS5nZXRNaW51dGVzKCl9YC5wYWRTdGFydCgyLCBcIjBcIik7XG5cbiAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fS0ke2hyfSR7bWlufWA7XG59O1xuXG5leHBvcnQgY29uc3QgY2FwaXRhbGl6ZVN0cmluZyA9IChzdHI6IHN0cmluZykgPT5cbiAgc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xuXG5leHBvcnQgY29uc3QgaXNUb29sSWNvbiA9IChcbiAgdGFyZ2V0OiBFbGVtZW50IHwgRXZlbnRUYXJnZXQgfCBudWxsLFxuKTogdGFyZ2V0IGlzIEhUTUxFbGVtZW50ID0+XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIHRhcmdldC5jbGFzc05hbWUuaW5jbHVkZXMoXCJUb29sSWNvblwiKTtcblxuZXhwb3J0IGNvbnN0IGlzSW5wdXRMaWtlID0gKFxuICB0YXJnZXQ6IEVsZW1lbnQgfCBFdmVudFRhcmdldCB8IG51bGwsXG4pOiB0YXJnZXQgaXNcbiAgfCBIVE1MSW5wdXRFbGVtZW50XG4gIHwgSFRNTFRleHRBcmVhRWxlbWVudFxuICB8IEhUTUxTZWxlY3RFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fFxuICB0YXJnZXQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50IHx8XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50O1xuXG5leHBvcnQgY29uc3QgaXNXcml0YWJsZUVsZW1lbnQgPSAoXG4gIHRhcmdldDogRWxlbWVudCB8IEV2ZW50VGFyZ2V0IHwgbnVsbCxcbik6IHRhcmdldCBpc1xuICB8IEhUTUxJbnB1dEVsZW1lbnRcbiAgfCBIVE1MVGV4dEFyZWFFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fFxuICAodGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJlxuICAgICh0YXJnZXQudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgdGFyZ2V0LnR5cGUgPT09IFwibnVtYmVyXCIpKTtcblxuZXhwb3J0IGNvbnN0IGdldEZvbnRGYW1pbHlTdHJpbmcgPSAoe1xuICBmb250RmFtaWx5LFxufToge1xuICBmb250RmFtaWx5OiBGb250RmFtaWx5VmFsdWVzO1xufSkgPT4ge1xuICBmb3IgKGNvbnN0IFtmb250RmFtaWx5U3RyaW5nLCBpZF0gb2YgT2JqZWN0LmVudHJpZXMoRk9OVF9GQU1JTFkpKSB7XG4gICAgaWYgKGlkID09PSBmb250RmFtaWx5KSB7XG4gICAgICByZXR1cm4gYCR7Zm9udEZhbWlseVN0cmluZ30sICR7V0lORE9XU19FTU9KSV9GQUxMQkFDS19GT05UfWA7XG4gICAgfVxuICB9XG4gIHJldHVybiBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQ7XG59O1xuXG4vKiogcmV0dXJucyBmb250U2l6ZStmb250RmFtaWx5IHN0cmluZyBmb3IgYXNzaWdubWVudCB0byBET00gZWxlbWVudHMgKi9cbmV4cG9ydCBjb25zdCBnZXRGb250U3RyaW5nID0gKHtcbiAgZm9udFNpemUsXG4gIGZvbnRGYW1pbHksXG59OiB7XG4gIGZvbnRTaXplOiBudW1iZXI7XG4gIGZvbnRGYW1pbHk6IEZvbnRGYW1pbHlWYWx1ZXM7XG59KSA9PiB7XG4gIHJldHVybiBgJHtmb250U2l6ZX1weCAke2dldEZvbnRGYW1pbHlTdHJpbmcoeyBmb250RmFtaWx5IH0pfWAgYXMgRm9udFN0cmluZztcbn07XG5cbmV4cG9ydCBjb25zdCBkZWJvdW5jZSA9IDxUIGV4dGVuZHMgYW55W10+KFxuICBmbjogKC4uLmFyZ3M6IFQpID0+IHZvaWQsXG4gIHRpbWVvdXQ6IG51bWJlcixcbikgPT4ge1xuICBsZXQgaGFuZGxlID0gMDtcbiAgbGV0IGxhc3RBcmdzOiBUIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IHJldCA9ICguLi5hcmdzOiBUKSA9PiB7XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGNsZWFyVGltZW91dChoYW5kbGUpO1xuICAgIGhhbmRsZSA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLmFyZ3MpO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9O1xuICByZXQuZmx1c2ggPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KGhhbmRsZSk7XG4gICAgaWYgKGxhc3RBcmdzKSB7XG4gICAgICBjb25zdCBfbGFzdEFyZ3MgPSBsYXN0QXJncztcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLl9sYXN0QXJncyk7XG4gICAgfVxuICB9O1xuICByZXQuY2FuY2VsID0gKCkgPT4ge1xuICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICBjbGVhclRpbWVvdXQoaGFuZGxlKTtcbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIHRocm90dGxlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgb25jZSBwZXIgYW5pbWF0aW9uIGZyYW1lXG5leHBvcnQgY29uc3QgdGhyb3R0bGVSQUYgPSA8VCBleHRlbmRzIGFueVtdPihcbiAgZm46ICguLi5hcmdzOiBUKSA9PiB2b2lkLFxuICBvcHRzPzogeyB0cmFpbGluZz86IGJvb2xlYW4gfSxcbikgPT4ge1xuICBsZXQgdGltZXJJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGxldCBsYXN0QXJnczogVCB8IG51bGwgPSBudWxsO1xuICBsZXQgbGFzdEFyZ3NUcmFpbGluZzogVCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IHNjaGVkdWxlRnVuYyA9IChhcmdzOiBUKSA9PiB7XG4gICAgdGltZXJJZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGltZXJJZCA9IG51bGw7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGlmIChsYXN0QXJnc1RyYWlsaW5nKSB7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdEFyZ3NUcmFpbGluZztcbiAgICAgICAgbGFzdEFyZ3NUcmFpbGluZyA9IG51bGw7XG4gICAgICAgIHNjaGVkdWxlRnVuYyhsYXN0QXJncyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgcmV0ID0gKC4uLmFyZ3M6IFQpID0+IHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGlmICh0aW1lcklkID09PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZUZ1bmMobGFzdEFyZ3MpO1xuICAgIH0gZWxzZSBpZiAob3B0cz8udHJhaWxpbmcpIHtcbiAgICAgIGxhc3RBcmdzVHJhaWxpbmcgPSBhcmdzO1xuICAgIH1cbiAgfTtcbiAgcmV0LmZsdXNoID0gKCkgPT4ge1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobGFzdEFyZ3MpIHtcbiAgICAgIGZuKC4uLihsYXN0QXJnc1RyYWlsaW5nIHx8IGxhc3RBcmdzKSk7XG4gICAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0LmNhbmNlbCA9ICgpID0+IHtcbiAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2Rhc2gvbG9kYXNoL2Jsb2IvZXMvY2h1bmsuanNcbmV4cG9ydCBjb25zdCBjaHVuayA9IDxUIGV4dGVuZHMgYW55PihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgc2l6ZTogbnVtYmVyLFxuKTogVFtdW10gPT4ge1xuICBpZiAoIWFycmF5Lmxlbmd0aCB8fCBzaXplIDwgMSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBsZXQgaW5kZXggPSAwO1xuICBsZXQgcmVzSW5kZXggPSAwO1xuICBjb25zdCByZXN1bHQgPSBBcnJheShNYXRoLmNlaWwoYXJyYXkubGVuZ3RoIC8gc2l6ZSkpO1xuICB3aGlsZSAoaW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBhcnJheS5zbGljZShpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdE5vZGUgPSAobm9kZTogRWxlbWVudCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKG5vZGUpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlU2VsZWN0aW9uID0gKCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBkaXN0YW5jZSA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gTWF0aC5hYnMoeCAtIHkpO1xuXG5leHBvcnQgY29uc3QgdXBkYXRlQWN0aXZlVG9vbCA9IChcbiAgYXBwU3RhdGU6IFBpY2s8QXBwU3RhdGUsIFwiYWN0aXZlVG9vbFwiPixcbiAgZGF0YTogKFxuICAgIHwgeyB0eXBlOiB0eXBlb2YgU0hBUEVTW251bWJlcl1bXCJ2YWx1ZVwiXSB8IFwiZXJhc2VyXCIgfVxuICAgIHwgeyB0eXBlOiBcImN1c3RvbVwiOyBjdXN0b21UeXBlOiBzdHJpbmcgfVxuICApICYgeyBsYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcj86IExhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyIH0sXG4pOiBBcHBTdGF0ZVtcImFjdGl2ZVRvb2xcIl0gPT4ge1xuICBpZiAoZGF0YS50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICB0eXBlOiBcImN1c3RvbVwiLFxuICAgICAgY3VzdG9tVHlwZTogZGF0YS5jdXN0b21UeXBlLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgbGFzdEFjdGl2ZVRvb2xCZWZvcmVFcmFzZXI6XG4gICAgICBkYXRhLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyID09PSB1bmRlZmluZWRcbiAgICAgICAgPyBhcHBTdGF0ZS5hY3RpdmVUb29sLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyXG4gICAgICAgIDogZGF0YS5sYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcixcbiAgICB0eXBlOiBkYXRhLnR5cGUsXG4gICAgY3VzdG9tVHlwZTogbnVsbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZXNldEN1cnNvciA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBpZiAoY2FudmFzKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IFwiXCI7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzZXRDdXJzb3IgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsIGN1cnNvcjogc3RyaW5nKSA9PiB7XG4gIGlmIChjYW52YXMpIHtcbiAgICBjYW52YXMuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xuICB9XG59O1xuXG5sZXQgZXJhc2VyQ2FudmFzQ2FjaGU6IGFueTtcbmxldCBwcmV2aWV3RGF0YVVSTDogc3RyaW5nO1xuZXhwb3J0IGNvbnN0IHNldEVyYXNlckN1cnNvciA9IChcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsXG4gIHRoZW1lOiBBcHBTdGF0ZVtcInRoZW1lXCJdLFxuKSA9PiB7XG4gIGNvbnN0IGN1cnNvckltYWdlU2l6ZVB4ID0gMjA7XG5cbiAgY29uc3QgZHJhd0NhbnZhcyA9ICgpID0+IHtcbiAgICBjb25zdCBpc0RhcmtUaGVtZSA9IHRoZW1lID09PSBUSEVNRS5EQVJLO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSA9IHRoZW1lO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLmhlaWdodCA9IGN1cnNvckltYWdlU2l6ZVB4O1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLndpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgY29uc3QgY29udGV4dCA9IGVyYXNlckNhbnZhc0NhY2hlLmdldENvbnRleHQoXCIyZFwiKSE7XG4gICAgY29udGV4dC5saW5lV2lkdGggPSAxO1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgY29udGV4dC5hcmMoXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS53aWR0aCAvIDIsXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS5oZWlnaHQgLyAyLFxuICAgICAgNSxcbiAgICAgIDAsXG4gICAgICAyICogTWF0aC5QSSxcbiAgICApO1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gaXNEYXJrVGhlbWUgPyBvYy5ibGFjayA6IG9jLndoaXRlO1xuICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBpc0RhcmtUaGVtZSA/IG9jLndoaXRlIDogb2MuYmxhY2s7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgICBwcmV2aWV3RGF0YVVSTCA9IGVyYXNlckNhbnZhc0NhY2hlLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgfTtcbiAgaWYgKCFlcmFzZXJDYW52YXNDYWNoZSB8fCBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSAhPT0gdGhlbWUpIHtcbiAgICBkcmF3Q2FudmFzKCk7XG4gIH1cblxuICBzZXRDdXJzb3IoXG4gICAgY2FudmFzLFxuICAgIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pICR7Y3Vyc29ySW1hZ2VTaXplUHggLyAyfSAke1xuICAgICAgY3Vyc29ySW1hZ2VTaXplUHggLyAyXG4gICAgfSwgYXV0b2AsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2V0Q3Vyc29yRm9yU2hhcGUgPSAoXG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4pID0+IHtcbiAgaWYgKCFjYW52YXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGFwcFN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgIHJlc2V0Q3Vyc29yKGNhbnZhcyk7XG4gIH0gZWxzZSBpZiAoYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiKSB7XG4gICAgc2V0RXJhc2VyQ3Vyc29yKGNhbnZhcywgYXBwU3RhdGUudGhlbWUpO1xuICAgIC8vIGRvIG5vdGhpbmcgaWYgaW1hZ2UgdG9vbCBpcyBzZWxlY3RlZCB3aGljaCBzdWdnZXN0cyB0aGVyZSdzXG4gICAgLy8gYSBpbWFnZS1wcmV2aWV3IHNldCBhcyB0aGUgY3Vyc29yXG4gICAgLy8gSWdub3JlIGN1c3RvbSB0eXBlIGFzIHdlbGwgYW5kIGxldCBob3N0IGRlY2lkZVxuICB9IGVsc2UgaWYgKCFbXCJpbWFnZVwiLCBcImN1c3RvbVwiXS5pbmNsdWRlcyhhcHBTdGF0ZS5hY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IENVUlNPUl9UWVBFLkNST1NTSEFJUjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGlzRnVsbFNjcmVlbiA9ICgpID0+XG4gIGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50Py5ub2RlTmFtZSA9PT0gXCJIVE1MXCI7XG5cbmV4cG9ydCBjb25zdCBhbGxvd0Z1bGxTY3JlZW4gPSAoKSA9PlxuICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGV4aXRGdWxsU2NyZWVuID0gKCkgPT4gZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGdldFNob3J0Y3V0S2V5ID0gKHNob3J0Y3V0OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBzaG9ydGN1dCA9IHNob3J0Y3V0XG4gICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIkFsdFwiKVxuICAgIC5yZXBsYWNlKC9cXGJTaGlmdFxcYi9pLCBcIlNoaWZ0XCIpXG4gICAgLnJlcGxhY2UoL1xcYihFbnRlcnxSZXR1cm4pXFxiL2ksIFwiRW50ZXJcIilcbiAgICAucmVwbGFjZSgvXFxiRGVsXFxiL2ksIFwiRGVsZXRlXCIpO1xuXG4gIGlmIChpc0Rhcndpbikge1xuICAgIHJldHVybiBzaG9ydGN1dFxuICAgICAgLnJlcGxhY2UoL1xcYkN0cmxPckNtZFxcYi9pLCBcIkNtZFwiKVxuICAgICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIk9wdGlvblwiKTtcbiAgfVxuICByZXR1cm4gc2hvcnRjdXQucmVwbGFjZSgvXFxiQ3RybE9yQ21kXFxiL2ksIFwiQ3RybFwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMgPSAoXG4gIHsgY2xpZW50WCwgY2xpZW50WSB9OiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0sXG4gIHtcbiAgICB6b29tLFxuICAgIG9mZnNldExlZnQsXG4gICAgb2Zmc2V0VG9wLFxuICAgIHNjcm9sbFgsXG4gICAgc2Nyb2xsWSxcbiAgfToge1xuICAgIHpvb206IFpvb207XG4gICAgb2Zmc2V0TGVmdDogbnVtYmVyO1xuICAgIG9mZnNldFRvcDogbnVtYmVyO1xuICAgIHNjcm9sbFg6IG51bWJlcjtcbiAgICBzY3JvbGxZOiBudW1iZXI7XG4gIH0sXG4pID0+IHtcbiAgY29uc3QgaW52U2NhbGUgPSAxIC8gem9vbS52YWx1ZTtcbiAgY29uc3QgeCA9IChjbGllbnRYIC0gb2Zmc2V0TGVmdCkgKiBpbnZTY2FsZSAtIHNjcm9sbFg7XG4gIGNvbnN0IHkgPSAoY2xpZW50WSAtIG9mZnNldFRvcCkgKiBpbnZTY2FsZSAtIHNjcm9sbFk7XG5cbiAgcmV0dXJuIHsgeCwgeSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyA9IChcbiAgeyBzY2VuZVgsIHNjZW5lWSB9OiB7IHNjZW5lWDogbnVtYmVyOyBzY2VuZVk6IG51bWJlciB9LFxuICB7XG4gICAgem9vbSxcbiAgICBvZmZzZXRMZWZ0LFxuICAgIG9mZnNldFRvcCxcbiAgICBzY3JvbGxYLFxuICAgIHNjcm9sbFksXG4gIH06IHtcbiAgICB6b29tOiBab29tO1xuICAgIG9mZnNldExlZnQ6IG51bWJlcjtcbiAgICBvZmZzZXRUb3A6IG51bWJlcjtcbiAgICBzY3JvbGxYOiBudW1iZXI7XG4gICAgc2Nyb2xsWTogbnVtYmVyO1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IHggPSAoc2NlbmVYICsgc2Nyb2xsWCkgKiB6b29tLnZhbHVlICsgb2Zmc2V0TGVmdDtcbiAgY29uc3QgeSA9IChzY2VuZVkgKyBzY3JvbGxZKSAqIHpvb20udmFsdWUgKyBvZmZzZXRUb3A7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRHbG9iYWxDU1NWYXJpYWJsZSA9IChuYW1lOiBzdHJpbmcpID0+XG4gIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKGAtLSR7bmFtZX1gKTtcblxuY29uc3QgUlNfTFRSX0NIQVJTID1cbiAgXCJBLVphLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyQjhcXHUwMzAwLVxcdTA1OTBcXHUwODAwLVxcdTFGRkZcIiArXG4gIFwiXFx1MkMwMC1cXHVGQjFDXFx1RkRGRS1cXHVGRTZGXFx1RkVGRC1cXHVGRkZGXCI7XG5jb25zdCBSU19SVExfQ0hBUlMgPSBcIlxcdTA1OTEtXFx1MDdGRlxcdUZCMUQtXFx1RkRGRFxcdUZFNzAtXFx1RkVGQ1wiO1xuY29uc3QgUkVfUlRMX0NIRUNLID0gbmV3IFJlZ0V4cChgXlteJHtSU19MVFJfQ0hBUlN9XSpbJHtSU19SVExfQ0hBUlN9XWApO1xuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBmaXJzdCBkaXJlY3Rpb25hbCBjaGFyYWN0ZXIgaXMgUlRMLiBNZWFuaW5nIHdoZXRoZXIgaXQgc3RhcnRzXG4gKiAgd2l0aCBSVEwgY2hhcmFjdGVycywgb3IgaW5kZXRlcm1pbmF0ZSAobnVtYmVycyBldGMuKSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5XG4gKiAgUlRMLlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC8xNzIyI2Rpc2N1c3Npb25fcjQzNjM0MDE3MVxuICovXG5leHBvcnQgY29uc3QgaXNSVEwgPSAodGV4dDogc3RyaW5nKSA9PiBSRV9SVExfQ0hFQ0sudGVzdCh0ZXh0KTtcblxuZXhwb3J0IGNvbnN0IHR1cGxlVG9Db29ycyA9IChcbiAgeHlUdXBsZTogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyXSxcbik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XG4gIGNvbnN0IFt4LCB5XSA9IHh5VHVwbGU7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbi8qKiB1c2UgYXMgYSByZWplY3Rpb25IYW5kbGVyIHRvIG11dGUgZmlsZXN5c3RlbSBBYm9ydCBlcnJvcnMgKi9cbmV4cG9ydCBjb25zdCBtdXRlRlNBYm9ydEVycm9yID0gKGVycm9yPzogRXJyb3IpID0+IHtcbiAgaWYgKGVycm9yPy5uYW1lID09PSBcIkFib3J0RXJyb3JcIikge1xuICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRocm93IGVycm9yO1xufTtcblxuZXhwb3J0IGNvbnN0IGZpbmRJbmRleCA9IDxUPihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgY2I6IChlbGVtZW50OiBULCBpbmRleDogbnVtYmVyLCBhcnJheTogcmVhZG9ubHkgVFtdKSA9PiBib29sZWFuLFxuICBmcm9tSW5kZXg6IG51bWJlciA9IDAsXG4pID0+IHtcbiAgaWYgKGZyb21JbmRleCA8IDApIHtcbiAgICBmcm9tSW5kZXggPSBhcnJheS5sZW5ndGggKyBmcm9tSW5kZXg7XG4gIH1cbiAgZnJvbUluZGV4ID0gTWF0aC5taW4oYXJyYXkubGVuZ3RoLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4IC0gMTtcbiAgd2hpbGUgKCsraW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICBpZiAoY2IoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbmV4cG9ydCBjb25zdCBmaW5kTGFzdEluZGV4ID0gPFQ+KFxuICBhcnJheTogcmVhZG9ubHkgVFtdLFxuICBjYjogKGVsZW1lbnQ6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiByZWFkb25seSBUW10pID0+IGJvb2xlYW4sXG4gIGZyb21JbmRleDogbnVtYmVyID0gYXJyYXkubGVuZ3RoIC0gMSxcbikgPT4ge1xuICBpZiAoZnJvbUluZGV4IDwgMCkge1xuICAgIGZyb21JbmRleCA9IGFycmF5Lmxlbmd0aCArIGZyb21JbmRleDtcbiAgfVxuICBmcm9tSW5kZXggPSBNYXRoLm1pbihhcnJheS5sZW5ndGggLSAxLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4ICsgMTtcbiAgd2hpbGUgKC0taW5kZXggPiAtMSkge1xuICAgIGlmIChjYihhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzVHJhbnNwYXJlbnQgPSAoY29sb3I6IHN0cmluZykgPT4ge1xuICBjb25zdCBpc1JHQlRyYW5zcGFyZW50ID0gY29sb3IubGVuZ3RoID09PSA1ICYmIGNvbG9yLnN1YnN0cig0LCAxKSA9PT0gXCIwXCI7XG4gIGNvbnN0IGlzUlJHR0JCVHJhbnNwYXJlbnQgPSBjb2xvci5sZW5ndGggPT09IDkgJiYgY29sb3Iuc3Vic3RyKDcsIDIpID09PSBcIjAwXCI7XG4gIHJldHVybiAoXG4gICAgaXNSR0JUcmFuc3BhcmVudCB8fFxuICAgIGlzUlJHR0JCVHJhbnNwYXJlbnQgfHxcbiAgICBjb2xvciA9PT0gY29sb3JzLmVsZW1lbnRCYWNrZ3JvdW5kWzBdXG4gICk7XG59O1xuXG5leHBvcnQgdHlwZSBSZXNvbHZhYmxlUHJvbWlzZTxUPiA9IFByb21pc2U8VD4gJiB7XG4gIHJlc29sdmU6IFtUXSBleHRlbmRzIFt1bmRlZmluZWRdID8gKHZhbHVlPzogVCkgPT4gdm9pZCA6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xufTtcbmV4cG9ydCBjb25zdCByZXNvbHZhYmxlUHJvbWlzZSA9IDxUPigpID0+IHtcbiAgbGV0IHJlc29sdmUhOiBhbnk7XG4gIGxldCByZWplY3QhOiBhbnk7XG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgcmVqZWN0ID0gX3JlamVjdDtcbiAgfSk7XG4gIChwcm9taXNlIGFzIGFueSkucmVzb2x2ZSA9IHJlc29sdmU7XG4gIChwcm9taXNlIGFzIGFueSkucmVqZWN0ID0gcmVqZWN0O1xuICByZXR1cm4gcHJvbWlzZSBhcyBSZXNvbHZhYmxlUHJvbWlzZTxUPjtcbn07XG5cbi8qKlxuICogQHBhcmFtIGZ1bmMgaGFuZGxlciB0YWtpbmcgYXQgbW9zdCBzaW5nbGUgcGFyYW1ldGVyIChldmVudCkuXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXMgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PlxuICAoKGV2ZW50KSA9PiB7XG4gICAgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMoZnVuYyBhcyBURnVuY3Rpb24sIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uO1xuXG4vKipcbiAqIGJhcmNoZXMgUmVhY3Qgc3RhdGUgdXBkYXRlcyBhbmQgdGhyb3R0bGVzIHRoZSBjYWxscyB0byBhIHNpbmdsZSBjYWxsIHBlclxuICogYW5pbWF0aW9uIGZyYW1lXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PiB7XG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIHRocm90dGxlUkFGPFBhcmFtZXRlcnM8VEZ1bmN0aW9uPj4oKChldmVudCkgPT4ge1xuICAgIHVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzKGZ1bmMsIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uKTtcbn07XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzk0NjIzODIvODQxOFxuZXhwb3J0IGNvbnN0IG5Gb3JtYXR0ZXIgPSAobnVtOiBudW1iZXIsIGRpZ2l0czogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2kgPSBbXG4gICAgeyB2YWx1ZTogMSwgc3ltYm9sOiBcImJcIiB9LFxuICAgIHsgdmFsdWU6IDFlMywgc3ltYm9sOiBcImtcIiB9LFxuICAgIHsgdmFsdWU6IDFlNiwgc3ltYm9sOiBcIk1cIiB9LFxuICAgIHsgdmFsdWU6IDFlOSwgc3ltYm9sOiBcIkdcIiB9LFxuICBdO1xuICBjb25zdCByeCA9IC9cXC4wKyR8KFxcLlswLTldKlsxLTldKTArJC87XG4gIGxldCBpbmRleDtcbiAgZm9yIChpbmRleCA9IHNpLmxlbmd0aCAtIDE7IGluZGV4ID4gMDsgaW5kZXgtLSkge1xuICAgIGlmIChudW0gPj0gc2lbaW5kZXhdLnZhbHVlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIChcbiAgICAobnVtIC8gc2lbaW5kZXhdLnZhbHVlKS50b0ZpeGVkKGRpZ2l0cykucmVwbGFjZShyeCwgXCIkMVwiKSArIHNpW2luZGV4XS5zeW1ib2xcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRWZXJzaW9uID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTE1ldGFFbGVtZW50PignbWV0YVtuYW1lPVwidmVyc2lvblwiXScpPy5jb250ZW50IHx8XG4gICAgREVGQVVMVF9WRVJTSU9OXG4gICk7XG59O1xuXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2Vtb2ppLmpzXG5leHBvcnQgY29uc3Qgc3VwcG9ydHNFbW9qaSA9ICgpID0+IHtcbiAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgaWYgKCFjdHgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgb2Zmc2V0ID0gMTI7XG4gIGN0eC5maWxsU3R5bGUgPSBcIiNmMDBcIjtcbiAgY3R4LnRleHRCYXNlbGluZSA9IFwidG9wXCI7XG4gIGN0eC5mb250ID0gXCIzMnB4IEFyaWFsXCI7XG4gIC8vIE1vZGVybml6ciB1c2VkIPCfkKgsIGJ1dCBpdCBpcyBzb3J0IG9mIHN1cHBvcnRlZCBvbiBXaW5kb3dzIDcuXG4gIC8vIEx1Y2tpbHkg8J+YgCBpc24ndCBzdXBwb3J0ZWQuXG4gIGN0eC5maWxsVGV4dChcIvCfmIBcIiwgMCwgMCk7XG4gIHJldHVybiBjdHguZ2V0SW1hZ2VEYXRhKG9mZnNldCwgb2Zmc2V0LCAxLCAxKS5kYXRhWzBdICE9PSAwO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbik6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgcmV0dXJuIGRvY3VtZW50O1xuICAgIH1cbiAgICBjb25zdCB7IG92ZXJmbG93WSB9ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcbiAgICBjb25zdCBoYXNTY3JvbGxhYmxlQ29udGVudCA9IHBhcmVudC5zY3JvbGxIZWlnaHQgPiBwYXJlbnQuY2xpZW50SGVpZ2h0O1xuICAgIGlmIChcbiAgICAgIGhhc1Njcm9sbGFibGVDb250ZW50ICYmXG4gICAgICAob3ZlcmZsb3dZID09PSBcImF1dG9cIiB8fFxuICAgICAgICBvdmVyZmxvd1kgPT09IFwic2Nyb2xsXCIgfHxcbiAgICAgICAgb3ZlcmZsb3dZID09PSBcIm92ZXJsYXlcIilcbiAgICApIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudDtcbn07XG5cbmV4cG9ydCBjb25zdCBmb2N1c05lYXJlc3RQYXJlbnQgPSAoZWxlbWVudDogSFRNTElucHV0RWxlbWVudCkgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudC50YWJJbmRleCA+IC0xKSB7XG4gICAgICBwYXJlbnQuZm9jdXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudEVsZW1lbnQ7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwcmV2ZW50VW5sb2FkID0gKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCkgPT4ge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAvLyBOT1RFOiBtb2Rlcm4gYnJvd3NlcnMgbm8gbG9uZ2VyIGFsbG93IHNob3dpbmcgYSBjdXN0b20gbWVzc2FnZSBoZXJlXG4gIGV2ZW50LnJldHVyblZhbHVlID0gXCJcIjtcbn07XG5cbmV4cG9ydCBjb25zdCBieXRlc1RvSGV4U3RyaW5nID0gKGJ5dGVzOiBVaW50OEFycmF5KSA9PiB7XG4gIHJldHVybiBBcnJheS5mcm9tKGJ5dGVzKVxuICAgIC5tYXAoKGJ5dGUpID0+IGAwJHtieXRlLnRvU3RyaW5nKDE2KX1gLnNsaWNlKC0yKSlcbiAgICAuam9pbihcIlwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVcGRhdGVkVGltZXN0YW1wID0gKCkgPT4gKGlzVGVzdEVudigpID8gMSA6IERhdGUubm93KCkpO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nIGBpZGAgYXR0cmlidXRlLFxuICogb3IgYXJyYXkgb2YgaWRzIChzdHJpbmdzKSwgaW50byBhIE1hcCwga2V5ZCBieSBgaWRgLlxuICovXG5leHBvcnQgY29uc3QgYXJyYXlUb01hcCA9IDxUIGV4dGVuZHMgeyBpZDogc3RyaW5nIH0gfCBzdHJpbmc+KFxuICBpdGVtczogcmVhZG9ubHkgVFtdLFxuKSA9PiB7XG4gIHJldHVybiBpdGVtcy5yZWR1Y2UoKGFjYzogTWFwPHN0cmluZywgVD4sIGVsZW1lbnQpID0+IHtcbiAgICBhY2Muc2V0KHR5cGVvZiBlbGVtZW50ID09PSBcInN0cmluZ1wiID8gZWxlbWVudCA6IGVsZW1lbnQuaWQsIGVsZW1lbnQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIG5ldyBNYXAoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgaXNUZXN0RW52ID0gKCkgPT5cbiAgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2Vzcy5lbnY/Lk5PREVfRU5WID09PSBcInRlc3RcIjtcblxuZXhwb3J0IGNvbnN0IGlzUHJvZEVudiA9ICgpID0+XG4gIHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MuZW52Py5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCI7XG5cbmV4cG9ydCBjb25zdCB3cmFwRXZlbnQgPSA8VCBleHRlbmRzIEV2ZW50PihuYW1lOiBFVkVOVCwgbmF0aXZlRXZlbnQ6IFQpID0+IHtcbiAgcmV0dXJuIG5ldyBDdXN0b21FdmVudChuYW1lLCB7XG4gICAgZGV0YWlsOiB7XG4gICAgICBuYXRpdmVFdmVudCxcbiAgICB9LFxuICAgIGNhbmNlbGFibGU6IHRydWUsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZU9iamVjdCA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIG9iajogVCxcbiAgdXBkYXRlczogUGFydGlhbDxUPixcbik6IFQgPT4ge1xuICBsZXQgZGlkQ2hhbmdlID0gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IGluIHVwZGF0ZXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9ICh1cGRhdGVzIGFzIGFueSlba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChvYmogYXMgYW55KVtrZXldID09PSB2YWx1ZSAmJlxuICAgICAgICAvLyBpZiBvYmplY3QsIGFsd2F5cyB1cGRhdGUgYmVjYXVzZSBpdHMgYXR0cnMgY291bGQgaGF2ZSBjaGFuZ2VkXG4gICAgICAgICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgdmFsdWUgPT09IG51bGwpXG4gICAgICApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBkaWRDaGFuZ2UgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghZGlkQ2hhbmdlKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4ub2JqLFxuICAgIC4uLnVwZGF0ZXMsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcmltaXRpdmUgPSAodmFsOiBhbnkpID0+IHtcbiAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWw7XG4gIHJldHVybiB2YWwgPT0gbnVsbCB8fCAodHlwZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlICE9PSBcImZ1bmN0aW9uXCIpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEZyYW1lID0gKCkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cuc2VsZiA9PT0gd2luZG93LnRvcCA/IFwidG9wXCIgOiBcImlmcmFtZVwiO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBcImlmcmFtZVwiO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcm9taXNlTGlrZSA9IChcbiAgdmFsdWU6IGFueSxcbik6IHZhbHVlIGlzIFByb21pc2U8UmVzb2x1dGlvblR5cGU8dHlwZW9mIHZhbHVlPj4gPT4ge1xuICByZXR1cm4gKFxuICAgICEhdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICBcInRoZW5cIiBpbiB2YWx1ZSAmJlxuICAgIFwiY2F0Y2hcIiBpbiB2YWx1ZSAmJlxuICAgIFwiZmluYWxseVwiIGluIHZhbHVlXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcXVlcnlGb2N1c2FibGVFbGVtZW50cyA9IChjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBjb25zdCBmb2N1c2FibGVFbGVtZW50cyA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oXG4gICAgXCJidXR0b24sIGEsIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBkaXZbdGFiaW5kZXhdLCBsYWJlbFt0YWJpbmRleF1cIixcbiAgKTtcblxuICByZXR1cm4gZm9jdXNhYmxlRWxlbWVudHNcbiAgICA/IEFycmF5LmZyb20oZm9jdXNhYmxlRWxlbWVudHMpLmZpbHRlcihcbiAgICAgICAgKGVsZW1lbnQpID0+XG4gICAgICAgICAgZWxlbWVudC50YWJJbmRleCA+IC0xICYmICEoZWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50KS5kaXNhYmxlZCxcbiAgICAgIClcbiAgICA6IFtdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../utils.ts\n");
3342
3342
 
3343
3343
  /***/ }),
3344
3344