@zsviczian/excalidraw 0.10.0-textfix-7 → 0.10.0-textfix-11

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.
@@ -1783,7 +1783,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1783
1783
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1784
1784
 
1785
1785
  "use strict";
1786
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"useIsMobile\": () => (/* binding */ useIsMobile),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\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 roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_3__ = __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.dev.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data/json */ \"../../data/json.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__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer */ \"../../renderer/index.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 _Stats__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Stats */ \"../../components/Stats.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_42__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst IsMobileContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(false);\r\nconst useIsMobile = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(IsMobileContext);\r\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\r\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\r\nlet didTapTwice = false;\r\nlet tappedTwiceTimer = 0;\r\nlet cursorX = 0;\r\nlet cursorY = 0;\r\nlet isHoldingSpace = false;\r\nlet isPanning = false;\r\nlet isDraggingScrollBar = false;\r\nlet currentScrollBars = { horizontal: null, vertical: null };\r\nlet touchTimeout = 0;\r\nlet invalidateContextMenu = false;\r\nlet lastPointerUp = null;\r\nconst gesture = {\r\n pointers: new Map(),\r\n lastCenter: null,\r\n initialDistance: null,\r\n initialScale: null,\r\n};\r\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\r\n constructor(props) {\r\n var _a;\r\n super(props);\r\n this.canvas = null;\r\n this.rc = null;\r\n this.unmounted = false;\r\n this.isMobile = false;\r\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\r\n this.files = {};\r\n this.imageCache = new Map();\r\n this.focusContainer = () => {\r\n var _a;\r\n if (this.props.autoFocus) {\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\r\n }\r\n };\r\n this.getSceneElementsIncludingDeleted = () => {\r\n return this.scene.getElementsIncludingDeleted();\r\n };\r\n this.getSceneElements = () => {\r\n return this.scene.getElements();\r\n };\r\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\r\n var _a, _b, _c, _d, _e, _f;\r\n if (this.unmounted || actionResult === false) {\r\n return;\r\n }\r\n let editingElement = null;\r\n if (actionResult.elements) {\r\n actionResult.elements.forEach((element) => {\r\n var _a;\r\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\r\n this.state.editingElement !== element &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n editingElement = element;\r\n }\r\n });\r\n this.scene.replaceAllElements(actionResult.elements);\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n }\r\n if (actionResult.files) {\r\n this.files = actionResult.replaceFiles\r\n ? actionResult.files\r\n : Object.assign(Object.assign({}, this.files), actionResult.files);\r\n this.addNewImagesToImageCache();\r\n }\r\n if (actionResult.appState || editingElement) {\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\r\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\r\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\r\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_11__.THEME.LIGHT;\r\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;\r\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\r\n viewModeEnabled = this.props.viewModeEnabled;\r\n }\r\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\r\n zenModeEnabled = this.props.zenModeEnabled;\r\n }\r\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\r\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null;\r\n }\r\n if (typeof this.props.theme !== \"undefined\") {\r\n theme = this.props.theme;\r\n }\r\n if (typeof this.props.name !== \"undefined\") {\r\n name = this.props.name;\r\n }\r\n this.setState((state) => {\r\n var _a;\r\n // using Object.assign instead of spread to fool TS 4.2.2+ into\r\n // regarding the resulting type as not containing undefined\r\n // (which the following expression will never contain)\r\n return Object.assign(actionResult.appState || {}, {\r\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\r\n viewModeEnabled,\r\n zenModeEnabled,\r\n gridSize,\r\n theme,\r\n name,\r\n });\r\n }, () => {\r\n if (actionResult.syncHistory) {\r\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\r\n }\r\n });\r\n }\r\n });\r\n // Lifecycle\r\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isHoldingSpace = false;\r\n this.setState({ isBindingEnabled: true });\r\n });\r\n this.onUnload = () => {\r\n this.onBlur();\r\n };\r\n this.disableEvent = (event) => {\r\n event.preventDefault();\r\n };\r\n this.onFontLoaded = () => {\r\n this.scene.getElementsIncludingDeleted().forEach((element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n });\r\n this.onSceneUpdated();\r\n };\r\n this.importLibraryFromUrl = (url, token) => __awaiter(this, void 0, void 0, function* () {\r\n if (window.location.hash.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary)) {\r\n const hash = new URLSearchParams(window.location.hash.slice(1));\r\n hash.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `#${hash.toString()}`);\r\n }\r\n else if (window.location.search.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary)) {\r\n const query = new URLSearchParams(window.location.search);\r\n query.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `?${query.toString()}`);\r\n }\r\n try {\r\n const request = yield fetch(decodeURIComponent(url));\r\n const blob = yield request.blob();\r\n const json = JSON.parse(yield blob.text());\r\n if (!(0,_data_json__WEBPACK_IMPORTED_MODULE_13__.isValidLibrary)(json)) {\r\n throw new Error();\r\n }\r\n if (token === this.id ||\r\n window.confirm((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.confirmAddLibrary\", {\r\n numShapes: (json.libraryItems || json.library || []).length,\r\n }))) {\r\n yield this.library.importLibrary(blob, \"published\");\r\n // hack to rerender the library items after import\r\n if (this.state.isLibraryOpen) {\r\n this.setState({ isLibraryOpen: false });\r\n }\r\n this.setState({ isLibraryOpen: true });\r\n }\r\n }\r\n catch (error) {\r\n window.alert((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.errorLoadingLibrary\"));\r\n console.error(error);\r\n }\r\n finally {\r\n this.focusContainer();\r\n }\r\n });\r\n this.resetHistory = () => {\r\n this.history.clear();\r\n };\r\n /**\r\n * Resets scene & history.\r\n * ! Do not use to clear scene user action !\r\n */\r\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\r\n this.scene.replaceAllElements([]);\r\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\r\n this.resetHistory();\r\n });\r\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\r\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\r\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\r\n if (!launchParams.files.length) {\r\n return;\r\n }\r\n const fileHandle = launchParams.files[0];\r\n const blob = yield fileHandle.getFile();\r\n blob.handle = fileHandle;\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(blob, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n }));\r\n }\r\n if (!this.state.isLoading) {\r\n this.setState({ isLoading: true });\r\n }\r\n let initialData = null;\r\n try {\r\n initialData = (yield this.props.initialData) || null;\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\r\n this.libraryItemsFromStorage = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreLibraryItems)(initialData.libraryItems, \"unpublished\");\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n initialData = {\r\n appState: {\r\n errorMessage: error.message ||\r\n \"Encountered an error during importing or restoring scene data\",\r\n },\r\n };\r\n }\r\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null);\r\n scene.appState = Object.assign(Object.assign({}, scene.appState), { elementType: scene.appState.elementType === \"image\"\r\n ? \"selection\"\r\n : scene.appState.elementType, isLoading: false });\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\r\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));\r\n }\r\n this.resetHistory();\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\r\n const libraryUrl = \r\n // current\r\n new URLSearchParams(window.location.hash.slice(1)).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary) ||\r\n // legacy, kept for compat reasons\r\n new URLSearchParams(window.location.search).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n if (libraryUrl) {\r\n yield this.importLibraryFromUrl(libraryUrl);\r\n }\r\n });\r\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n this.scene\r\n .getElementsIncludingDeleted()\r\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\r\n this.setState({});\r\n });\r\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\r\n this.setState((state) => {\r\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\r\n return null;\r\n }\r\n return { offsetTop, offsetLeft };\r\n });\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.SCROLL_TIMEOUT);\r\n // Copy/paste\r\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.cutAll();\r\n event.preventDefault();\r\n });\r\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.copyAll();\r\n event.preventDefault();\r\n });\r\n this.cutAll = () => {\r\n this.copyAll();\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected);\r\n };\r\n this.copyAll = () => {\r\n (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.copyToClipboard)(this.scene.getElements(), this.state, this.files);\r\n };\r\n this.onTapStart = (event) => {\r\n if (!didTapTwice) {\r\n didTapTwice = true;\r\n clearTimeout(tappedTwiceTimer);\r\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_11__.TAP_TWICE_TIMEOUT);\r\n return;\r\n }\r\n // insert text only if we tapped twice with a single finger\r\n // event.touches.length === 1 will also prevent inserting text when user's zooming\r\n if (didTapTwice && event.touches.length === 1) {\r\n const [touch] = event.touches;\r\n // @ts-ignore\r\n this.handleCanvasDoubleClick({\r\n clientX: touch.clientX,\r\n clientY: touch.clientY,\r\n });\r\n didTapTwice = false;\r\n clearTimeout(tappedTwiceTimer);\r\n }\r\n event.preventDefault();\r\n if (event.touches.length === 2) {\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n }\r\n };\r\n this.onTapEnd = (event) => {\r\n if (event.touches.length > 0) {\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n }\r\n };\r\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\r\n var _b, _c;\r\n // #686\r\n const target = document.activeElement;\r\n const isExcalidrawActive = (_b = this.excalidrawContainerRef.current) === null || _b === void 0 ? void 0 : _b.contains(target);\r\n if (!isExcalidrawActive) {\r\n return;\r\n }\r\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\r\n if (\r\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\r\n // thus these checks don't make sense\r\n event &&\r\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\r\n return;\r\n }\r\n // must be called in the same frame (thus before any awaits) as the paste\r\n // event else some browsers (FF...) will clear the clipboardData\r\n // (something something security)\r\n let file = (_c = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _c === void 0 ? void 0 : _c.files[0];\r\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.parseClipboard)(event);\r\n if (!file && data.text) {\r\n const string = data.text.trim();\r\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\r\n // ignore SVG validation/normalization which will be done during image\r\n // initialization\r\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(string);\r\n }\r\n }\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n if (this.props.onPaste) {\r\n try {\r\n if ((yield this.props.onPaste(data, event)) === false) {\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n }\r\n }\r\n if (data.errorMessage) {\r\n this.setState({ errorMessage: data.errorMessage });\r\n }\r\n else if (data.spreadsheet) {\r\n this.setState({\r\n pasteDialog: {\r\n data: data.spreadsheet,\r\n shown: true,\r\n },\r\n });\r\n }\r\n else if (data.elements) {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: data.elements,\r\n files: data.files || null,\r\n position: \"cursor\",\r\n });\r\n }\r\n else if (data.text) {\r\n this.addTextFromPaste(data.text);\r\n }\r\n this.selectShapeTool(\"selection\");\r\n event === null || event === void 0 ? void 0 : event.preventDefault();\r\n }));\r\n this.addElementsFromPasteOrLibrary = (opts) => {\r\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\r\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\r\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\r\n const clientX = typeof opts.position === \"object\"\r\n ? opts.position.clientX\r\n : opts.position === \"cursor\"\r\n ? cursorX\r\n : this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = typeof opts.position === \"object\"\r\n ? opts.position.clientY\r\n : opts.position === \"cursor\"\r\n ? cursorY\r\n : this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const dx = x - elementsCenterX;\r\n const dy = y - elementsCenterY;\r\n const groupIdMap = new Map();\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\r\n const oldIdToDuplicatedId = new Map();\r\n const newElements = elements.map((element) => {\r\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\r\n x: element.x + gridX - minX,\r\n y: element.y + gridY - minY,\r\n });\r\n oldIdToDuplicatedId.set(element.id, newElement.id);\r\n return newElement;\r\n });\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\r\n const nextElements = [\r\n ...this.scene.getElementsIncludingDeleted(),\r\n ...newElements,\r\n ];\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\r\n if (opts.files) {\r\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\r\n }\r\n this.scene.replaceAllElements(nextElements);\r\n this.history.resumeRecording();\r\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: false, selectedElementIds: newElements.reduce((map, element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.containerId) {\r\n map[element.id] = true;\r\n }\r\n return map;\r\n }, {}), selectedGroupIds: {} }), this.scene.getElements()), () => {\r\n if (opts.files) {\r\n this.addNewImagesToImageCache();\r\n }\r\n });\r\n this.selectShapeTool(\"selection\");\r\n };\r\n // Collaboration\r\n this.setAppState = (obj) => {\r\n this.setState(obj);\r\n };\r\n this.removePointer = (event) => {\r\n // remove touch handler for context menu on touch devices\r\n if (event.pointerType === \"touch\" && touchTimeout) {\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n invalidateContextMenu = false;\r\n }\r\n gesture.pointers.delete(event.pointerId);\r\n };\r\n this.toggleLock = () => {\r\n this.setState((prevState) => {\r\n return {\r\n elementLocked: !prevState.elementLocked,\r\n elementType: prevState.elementLocked\r\n ? \"selection\"\r\n : prevState.elementType,\r\n };\r\n });\r\n };\r\n this.toggleZenMode = () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode);\r\n };\r\n this.toggleStats = () => {\r\n if (!this.state.showStats) {\r\n (0,_analytics__WEBPACK_IMPORTED_MODULE_8__.trackEvent)(\"dialog\", \"stats\");\r\n }\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats);\r\n };\r\n this.scrollToContent = (target = this.scene.getElements()) => {\r\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\r\n };\r\n this.clearToast = () => {\r\n this.setState({ toastMessage: null });\r\n };\r\n this.setToastMessage = (toastMessage) => {\r\n this.setState({ toastMessage });\r\n };\r\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const webShareTargetCache = yield caches.open(\"web-share-target\");\r\n const file = yield webShareTargetCache.match(\"shared-file\");\r\n if (file) {\r\n const blob = yield file.blob();\r\n this.loadFileToCanvas(blob);\r\n yield webShareTargetCache.delete(\"shared-file\");\r\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, window.location.pathname);\r\n }\r\n }\r\n catch (error) {\r\n this.setState({ errorMessage: error.message });\r\n }\r\n });\r\n /** adds supplied files to existing files in the appState */\r\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\r\n const filesMap = files.reduce((acc, fileData) => {\r\n acc.set(fileData.id, fileData);\r\n return acc;\r\n }, new Map());\r\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\r\n // bump versions for elements that reference added files so that\r\n // we/host apps can detect the change, and invalidate the image & shape\r\n // cache\r\n this.scene.getElements().forEach((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n filesMap.has(element.fileId)) {\r\n this.imageCache.delete(element.fileId);\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.bumpVersion)(element);\r\n }\r\n });\r\n this.scene.informMutation();\r\n this.addNewImagesToImageCache();\r\n });\r\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\r\n if (sceneData.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n if (sceneData.appState) {\r\n this.setState(sceneData.appState);\r\n }\r\n if (sceneData.elements) {\r\n this.scene.replaceAllElements(sceneData.elements);\r\n }\r\n if (sceneData.collaborators) {\r\n this.setState({ collaborators: sceneData.collaborators });\r\n }\r\n });\r\n this.onSceneUpdated = () => {\r\n this.setState({});\r\n };\r\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n cursorX = event.clientX;\r\n cursorY = event.clientY;\r\n });\r\n // Input handling\r\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // normalize `event.key` when CapsLock is pressed #2372\r\n if (\"Proxy\" in window &&\r\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\r\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\r\n event = new Proxy(event, {\r\n get(ev, prop) {\r\n const value = ev[prop];\r\n if (typeof value === \"function\") {\r\n // fix for Proxies hijacking `this`\r\n return value.bind(ev);\r\n }\r\n return prop === \"key\"\r\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\r\n // it back\r\n event.shiftKey\r\n ? ev.key.toUpperCase()\r\n : ev.key.toLowerCase()\r\n : value;\r\n },\r\n });\r\n }\r\n if (((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) && event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\r\n // case: using arrows to move between buttons\r\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\r\n this.setState({\r\n showHelpDialog: true,\r\n });\r\n }\r\n if (this.actionManager.handleKeyDown(event)) {\r\n return;\r\n }\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: false });\r\n }\r\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\r\n this.setState({ isLibraryOpen: !this.state.isLibraryOpen });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const step = (this.state.gridSize &&\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT\r\n : this.state.gridSize)) ||\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT);\r\n const selectedElements = this.scene\r\n .getElements()\r\n .filter((element) => this.state.selectedElementIds[element.id]);\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\r\n offsetX = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\r\n offsetX = step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\r\n offsetY = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\r\n offsetY = step;\r\n }\r\n selectedElements.forEach((element) => {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n x: element.x + offsetX,\r\n y: element.y + offsetY,\r\n });\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\r\n simultaneouslyUpdated: selectedElements,\r\n });\r\n });\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n event.preventDefault();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n }\r\n else if (selectedElements.length === 1 &&\r\n !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n const selectedElement = selectedElements[0];\r\n this.startTextEditing({\r\n sceneX: selectedElement.x + selectedElement.width / 2,\r\n sceneY: selectedElement.y + selectedElement.height / 2,\r\n shouldBind: true,\r\n });\r\n event.preventDefault();\r\n return;\r\n }\r\n }\r\n else if (!event.ctrlKey &&\r\n !event.altKey &&\r\n !event.metaKey &&\r\n this.state.draggingElement === null) {\r\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\r\n if (shape) {\r\n this.selectShapeTool(shape);\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\r\n this.toggleLock();\r\n }\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\r\n isHoldingSpace = true;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (this.state.elementType === \"selection\" &&\r\n !selectedElements.length) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\r\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.elementType) ||\r\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\r\n this.setState({ openPopup: \"backgroundColorPicker\" });\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n this.setState({ openPopup: \"strokeColorPicker\" });\r\n }\r\n }\r\n });\r\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (this.state.elementType === \"selection\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n isHoldingSpace = false;\r\n }\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: true });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\r\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n });\r\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n gesture.initialScale = this.state.zoom.value;\r\n });\r\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n // onGestureChange only has zoom factor but not the center.\r\n // If we're on iPad or iPhone, then we recognize multi-touch and will\r\n // zoom in at the right location on the touchMove handler already.\r\n // On Macbook, we don't have those events so will zoom in at the\r\n // current location instead.\r\n if (gesture.pointers.size === 2) {\r\n return;\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (initialScale) {\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale), zoom, { left: offsetLeft, top: offsetTop }, { x: cursorX, y: cursorY }),\r\n }));\r\n }\r\n });\r\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n gesture.initialScale = null;\r\n });\r\n this.startTextEditing = ({ sceneX, sceneY, shouldBind, insertAtParentCenter = true, }) => {\r\n var _a;\r\n let parentCenterPosition = insertAtParentCenter &&\r\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n // bind to container when shouldBind is true or\r\n // clicked on center of container\r\n const container = shouldBind || parentCenterPosition\r\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene.getElements(), sceneX, sceneY, \"text\")\r\n : null;\r\n let existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\r\n // consider bounded text element if container present\r\n if (container) {\r\n const boundTextElementId = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getBoundTextElementId)(container);\r\n if (boundTextElementId) {\r\n existingTextElement = this.scene.getElement(boundTextElementId);\r\n }\r\n }\r\n if (!existingTextElement && container) {\r\n const fontString = {\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n };\r\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const newHeight = Math.max(container.height, minHeight);\r\n const newWidth = Math.max(container.width, minWidth);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\r\n sceneX = container.x + newWidth / 2;\r\n sceneY = container.y + newHeight / 2;\r\n if (parentCenterPosition) {\r\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n }\r\n }\r\n const element = existingTextElement\r\n ? existingTextElement\r\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x: parentCenterPosition\r\n ? parentCenterPosition.elementCenterX\r\n : sceneX,\r\n y: parentCenterPosition\r\n ? parentCenterPosition.elementCenterY\r\n : sceneY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text: \"\",\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: parentCenterPosition\r\n ? \"center\"\r\n : this.state.currentItemTextAlign,\r\n verticalAlign: parentCenterPosition\r\n ? \"middle\"\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n containerId: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\r\n });\r\n this.setState({ editingElement: element });\r\n if (existingTextElement) {\r\n // if text element is no longer centered to a container, reset\r\n // verticalAlign to default because it's currently internal-only\r\n if (!parentCenterPosition || element.textAlign !== \"center\") {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, { verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN });\r\n }\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n // case: creating new text not centered to parent elemenent → offset Y\r\n // so that the text is centered to cursor position\r\n if (!parentCenterPosition) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n y: element.y - element.baseline / 2,\r\n });\r\n }\r\n }\r\n this.setState({\r\n editingElement: element,\r\n });\r\n this.handleTextWysiwyg(element, {\r\n isExistingElement: !!existingTextElement,\r\n });\r\n };\r\n this.handleCanvasDoubleClick = (event) => {\r\n // case: double-clicking with arrow/line tool selected would both create\r\n // text and enter multiElement mode\r\n if (this.state.multiElement) {\r\n return;\r\n }\r\n // we should only be able to double click when mode is selection\r\n if (this.state.elementType !== \"selection\") {\r\n return;\r\n }\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n return;\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\r\n if (selectedGroupIds.length > 0) {\r\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\r\n const selectedGroupId = hitElement &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\r\n if (selectedGroupId) {\r\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.getElements()));\r\n return;\r\n }\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1) {\r\n const selectedElement = selectedElements[0];\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\r\n if (canBindText) {\r\n sceneX = selectedElement.x + selectedElement.width / 2;\r\n sceneY = selectedElement.y + selectedElement.height / 2;\r\n }\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n }\r\n };\r\n this.handleCanvasPointerMove = (event) => {\r\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\r\n if (gesture.pointers.has(event.pointerId)) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (gesture.pointers.size === 2 &&\r\n gesture.lastCenter &&\r\n initialScale &&\r\n gesture.initialDistance) {\r\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n const deltaX = center.x - gesture.lastCenter.x;\r\n const deltaY = center.y - gesture.lastCenter.y;\r\n gesture.lastCenter = center;\r\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n const scaleFactor = distance / gesture.initialDistance;\r\n this.setState(({ zoom, scrollX, scrollY, offsetLeft, offsetTop }) => ({\r\n scrollX: scrollX + deltaX / zoom.value,\r\n scrollY: scrollY + deltaY / zoom.value,\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor), zoom, { left: offsetLeft, top: offsetTop }, center),\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n }\r\n else {\r\n gesture.lastCenter =\r\n gesture.initialDistance =\r\n gesture.initialScale =\r\n null;\r\n }\r\n if (isHoldingSpace || isPanning || isDraggingScrollBar) {\r\n return;\r\n }\r\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\r\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\r\n if (!this.state.draggingElement && !this.state.multiElement) {\r\n if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\r\n if (this.state.editingLinearElement &&\r\n !this.state.editingLinearElement.isDragging) {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state.editingLinearElement, this.state.gridSize);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({ editingLinearElement });\r\n }\r\n if (editingLinearElement.lastUncommittedPoint != null) {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n else {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.elementType)) {\r\n // Hovering with a selected tool or creating new linear element via click\r\n // and point\r\n const { draggingElement } = this.state;\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\r\n }\r\n else {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n }\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n const { x: rx, y: ry } = multiElement;\r\n const { points, lastCommittedPoint } = multiElement;\r\n const lastPoint = points[points.length - 1];\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n if (lastPoint === lastCommittedPoint) {\r\n // if we haven't yet created a temp point and we're beyond commit-zone\r\n // threshold, add a point\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\r\n });\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n // in this branch, we're inside the commit zone, and no uncommitted\r\n // point exists. Thus do nothing (don't add/remove points).\r\n }\r\n }\r\n else if (points.length > 2 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: points.slice(0, -1),\r\n });\r\n }\r\n else {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n // update last uncommitted point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [\r\n ...points.slice(0, -1),\r\n [scenePointerX - rx, scenePointerY - ry],\r\n ],\r\n });\r\n }\r\n return;\r\n }\r\n const hasDeselectedButton = Boolean(event.buttons);\r\n if (hasDeselectedButton ||\r\n (this.state.elementType !== \"selection\" &&\r\n this.state.elementType !== \"text\")) {\r\n return;\r\n }\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 &&\r\n !isOverScrollBar &&\r\n !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType &&\r\n elementWithTransformHandleType.transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\r\n return;\r\n }\r\n }\r\n else if (selectedElements.length > 1 && !isOverScrollBar) {\r\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);\r\n if (transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType,\r\n }));\r\n return;\r\n }\r\n }\r\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\r\n if (this.state.elementType === \"text\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n }\r\n else if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n else if (this.state.editingLinearElement) {\r\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(this.state.editingLinearElement.elementId);\r\n if (element &&\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\r\n scenePointer.x,\r\n scenePointer.y,\r\n ])) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n }\r\n else if (\r\n // if using cmd/ctrl, we're not dragging\r\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\r\n (hitElement ||\r\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements))) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n };\r\n // set touch moving for mobile context menu\r\n this.handleTouchMove = (event) => {\r\n invalidateContextMenu = true;\r\n };\r\n this.handleCanvasPointerDown = (event) => {\r\n // remove any active selection when we start to interact with canvas\r\n // (mainly, we care about removing selection outside the component which\r\n // would prevent our copy handling otherwise)\r\n const selection = document.getSelection();\r\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\r\n selection.removeAllRanges();\r\n }\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\r\n this.maybeCleanupAfterMissingPointerUp(event);\r\n if (isPanning) {\r\n return;\r\n }\r\n this.setState({\r\n lastPointerDownWith: event.pointerType,\r\n cursorButton: \"down\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"down\");\r\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\r\n return;\r\n }\r\n // only handle left mouse button or touch\r\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN &&\r\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.TOUCH) {\r\n return;\r\n }\r\n this.updateGestureOnPointerDown(event);\r\n // don't select while panning\r\n if (gesture.pointers.size > 1) {\r\n return;\r\n }\r\n // State for the duration of a pointer interaction, which starts with a\r\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\r\n const pointerDownState = this.initialPointerDownState(event);\r\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\r\n return;\r\n }\r\n this.clearSelectionIfNotUsingSelection();\r\n this.updateBindingEnabledOnPointerMove(event);\r\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\r\n return;\r\n }\r\n if (this.state.elementType === \"text\") {\r\n this.handleTextOnPointerDown(event, pointerDownState);\r\n return;\r\n }\r\n else if (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\") {\r\n this.handleLinearElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else if (this.state.elementType === \"image\") {\r\n // reset image preview on pointerdown\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n if (!this.state.pendingImageElement) {\r\n return;\r\n }\r\n this.setState({\r\n draggingElement: this.state.pendingImageElement,\r\n editingElement: this.state.pendingImageElement,\r\n pendingImageElement: null,\r\n multiElement: null,\r\n });\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(this.state.pendingImageElement, {\r\n x,\r\n y,\r\n });\r\n }\r\n else if (this.state.elementType === \"freedraw\") {\r\n this.handleFreeDrawElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else {\r\n this.createGenericElementOnPointerDown(this.state.elementType, pointerDownState);\r\n }\r\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\r\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\r\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\r\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\r\n lastPointerUp = onPointerUp;\r\n if (!this.state.viewModeEnabled) {\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, onKeyDown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, onKeyUp);\r\n pointerDownState.eventListeners.onMove = onPointerMove;\r\n pointerDownState.eventListeners.onUp = onPointerUp;\r\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\r\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\r\n }\r\n };\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\r\n // deal with opening context menu on touch devices\r\n if (event.pointerType === \"touch\") {\r\n invalidateContextMenu = false;\r\n if (touchTimeout) {\r\n // If there's already a touchTimeout, this means that there's another\r\n // touch down and we are doing another touch, so we shouldn't open the\r\n // context menu.\r\n invalidateContextMenu = true;\r\n }\r\n else {\r\n // open the context menu with the first touch's clientX and clientY\r\n // if the touch is not moving\r\n touchTimeout = window.setTimeout(() => {\r\n touchTimeout = 0;\r\n if (!invalidateContextMenu) {\r\n this.handleCanvasContextMenu(event);\r\n }\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.TOUCH_CTX_MENU_TIMEOUT);\r\n }\r\n }\r\n };\r\n // Returns whether the event is a panning\r\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\r\n if (!(gesture.pointers.size === 0 &&\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.WHEEL ||\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\r\n this.state.viewModeEnabled))) {\r\n return false;\r\n }\r\n isPanning = true;\r\n let nextPastePrevented = false;\r\n const isLinux = /Linux/.test(window.navigator.platform);\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n let { clientX: lastX, clientY: lastY } = event;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const deltaX = lastX - event.clientX;\r\n const deltaY = lastY - event.clientY;\r\n lastX = event.clientX;\r\n lastY = event.clientY;\r\n /*\r\n * Prevent paste event if we move while middle clicking on Linux.\r\n * See issue #1383.\r\n */\r\n if (isLinux &&\r\n !nextPastePrevented &&\r\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\r\n nextPastePrevented = true;\r\n /* Prevent the next paste event */\r\n const preventNextPaste = (event) => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n event.stopPropagation();\r\n };\r\n /*\r\n * Reenable next paste in case of disabled middle click paste for\r\n * any reason:\r\n * - rigth click paste\r\n * - empty clipboard\r\n */\r\n const enableNextPaste = () => {\r\n setTimeout(() => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }, 100);\r\n };\r\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }\r\n this.setState({\r\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\r\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\r\n });\r\n });\r\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\r\n lastPointerUp = null;\r\n isPanning = false;\r\n if (!isHoldingSpace) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n }));\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove, {\r\n passive: true,\r\n });\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n return true;\r\n };\r\n this.clearSelectionIfNotUsingSelection = () => {\r\n if (this.state.elementType !== \"selection\") {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n };\r\n /**\r\n * @returns whether the pointer event has been completely handled\r\n */\r\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\r\n var _a;\r\n if (this.state.elementType === \"selection\") {\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType != null) {\r\n this.setState({\r\n resizingElement: elementWithTransformHandleType.element,\r\n });\r\n pointerDownState.resize.handleType =\r\n elementWithTransformHandleType.transformHandleType;\r\n }\r\n }\r\n else if (selectedElements.length > 1) {\r\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);\r\n }\r\n if (pointerDownState.resize.handleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType: pointerDownState.resize.handleType,\r\n }));\r\n pointerDownState.resize.isResizing = true;\r\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));\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\r\n selectedElements[0].points.length === 2) {\r\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\r\n }\r\n }\r\n else {\r\n if (this.state.editingLinearElement) {\r\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, (appState) => this.setState(appState), this.history, pointerDownState.origin);\r\n if (ret.hitElement) {\r\n pointerDownState.hit.element = ret.hitElement;\r\n }\r\n if (ret.didAddPoint) {\r\n return true;\r\n }\r\n }\r\n // hitElement may already be set above, so check first\r\n pointerDownState.hit.element =\r\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n if (pointerDownState.hit.element) {\r\n pointerDownState.hit.hasHitElementInside =\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y]);\r\n }\r\n // For overlapped elements one position may hit\r\n // multiple elements\r\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n const hitElement = pointerDownState.hit.element;\r\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hitElement === null || !someHitElementIsSelected) &&\r\n !event.shiftKey &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.clearSelection(hitElement);\r\n }\r\n if (this.state.editingLinearElement) {\r\n this.setState({\r\n selectedElementIds: {\r\n [this.state.editingLinearElement.elementId]: true,\r\n },\r\n });\r\n // If we click on something\r\n }\r\n else if (hitElement != null) {\r\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\r\n // mark as not completely handled so as to allow dragging etc.\r\n return false;\r\n }\r\n // deselect if item is selected\r\n // if shift is not clicked, this will always return true\r\n // otherwise, it will trigger selection based on current\r\n // state of the box\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n // if we are currently editing a group, exiting editing mode and deselect the group.\r\n if (this.state.editingGroupId &&\r\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n // Add hit element to selection. At this point if we're not holding\r\n // SHIFT the previously selected element(s) were deselected above\r\n // (make sure you use setState updater to use latest state)\r\n if (!someHitElementIsSelected &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.setState((prevState) => {\r\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }) }), this.scene.getElements());\r\n });\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n }\r\n }\r\n this.setState({\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n }\r\n return false;\r\n };\r\n this.handleTextOnPointerDown = (event, pointerDownState) => {\r\n // if we're currently still editing text, clicking outside\r\n // should only finalize it, not create another (irrespective\r\n // of state.elementLocked)\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\r\n return;\r\n }\r\n let sceneX = pointerDownState.origin.x;\r\n let sceneY = pointerDownState.origin.y;\r\n const element = this.getElementAtPosition(sceneX, sceneY, {\r\n includeBoundTextElement: true,\r\n });\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\r\n if (canBindText) {\r\n sceneX = element.x + element.width / 2;\r\n sceneY = element.y + element.height / 2;\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!this.state.elementLocked) {\r\n this.setState({\r\n elementType: \"selection\",\r\n });\r\n }\r\n };\r\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n // Begin a mark capture. This does not have to update state yet.\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\r\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n simulatePressure: event.pressure === 0.5,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n const pressures = element.simulatePressure\r\n ? element.pressures\r\n : [...element.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [[0, 0]],\r\n pressures,\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n };\r\n this.createImageElement = ({ sceneX, sceneY, }) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\r\n type: \"image\",\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n });\r\n return element;\r\n };\r\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n // finalize if completing a loop\r\n if (multiElement.type === \"line\" &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\r\n // clicking inside commit zone → finalize arrow\r\n if (multiElement.points.length > 1 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\r\n }));\r\n // clicking outside commit zone → update reference for last committed\r\n // point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\r\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\r\n an arrow, we want it to be null for both. Otherwise, we want it to use the\r\n values from appState. */\r\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\r\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\r\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\r\n : [null, null];\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n startArrowhead,\r\n endArrowhead,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [...element.points, [0, 0]],\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n };\r\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n });\r\n if (element.type === \"selection\") {\r\n this.setState({\r\n selectionElement: element,\r\n draggingElement: element,\r\n });\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n multiElement: null,\r\n draggingElement: element,\r\n editingElement: element,\r\n });\r\n }\r\n };\r\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\r\n var _d, _e, _f, _g;\r\n // at this point this should be guaranteed image file, but we do this check\r\n // to satisfy TS down the line\r\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(imageFile)) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\r\n }\r\n const mimeType = imageFile.type;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\r\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.normalizeSVG)(yield imageFile.text()), imageFile.name);\r\n }\r\n catch (error) {\r\n console.warn(error);\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\r\n }\r\n }\r\n // generate image id (by default the file digest) before any\r\n // resizing/compression takes place to keep it more portable\r\n const fileId = yield (((_e = (_d = this.props).generateIdForFile) === null || _e === void 0 ? void 0 : _e.call(_d, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.generateIdFromFile)(imageFile));\r\n if (!fileId) {\r\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\r\n }\r\n const existingFileData = this.files[fileId];\r\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\r\n try {\r\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\r\n });\r\n }\r\n catch (error) {\r\n console.error(\"error trying to resing image file on insertion\", error);\r\n }\r\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\r\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\r\n }));\r\n }\r\n }\r\n if (showCursorImagePreview) {\r\n const dataURL = (_f = this.files[fileId]) === null || _f === void 0 ? void 0 : _f.dataURL;\r\n // optimization so that we don't unnecessarily resize the original\r\n // full-size file for cursor preview\r\n // (it's much faster to convert the resized dataURL to File)\r\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.dataURLToFile)(dataURL);\r\n this.setImagePreviewCursor(resizedFile || imageFile);\r\n }\r\n const dataURL = ((_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imageFile));\r\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\r\n fileId,\r\n }, false);\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n var _h, _j;\r\n try {\r\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\r\n mimeType,\r\n id: fileId,\r\n dataURL,\r\n created: Date.now(),\r\n } });\r\n const cachedImageData = this.imageCache.get(fileId);\r\n if (!cachedImageData) {\r\n this.addNewImagesToImageCache();\r\n yield this.updateImageCache([imageElement]);\r\n }\r\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\r\n yield cachedImageData.image;\r\n }\r\n if (((_h = this.state.pendingImageElement) === null || _h === void 0 ? void 0 : _h.id) !== imageElement.id &&\r\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\r\n this.initializeImageDimensions(imageElement, true);\r\n }\r\n resolve(imageElement);\r\n }\r\n catch (error) {\r\n console.error(error);\r\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\r\n }\r\n finally {\r\n if (!showCursorImagePreview) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n }\r\n }));\r\n });\r\n /**\r\n * inserts image into elements array and rerenders\r\n */\r\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n imageElement,\r\n ]);\r\n try {\r\n yield this.initializeImage({\r\n imageFile,\r\n imageElement,\r\n showCursorImagePreview,\r\n });\r\n }\r\n catch (error) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n isDeleted: true,\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n this.setState({\r\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\r\n });\r\n }\r\n });\r\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\r\n // mustn't be larger than 128 px\r\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\r\n const cursorImageSizePx = 96;\r\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: cursorImageSizePx,\r\n });\r\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imagePreview);\r\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\r\n // a small canvas\r\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.loadHTMLImageElement)(previewDataURL);\r\n let height = Math.min(img.height, cursorImageSizePx);\r\n let width = height * (img.width / img.height);\r\n if (width > cursorImageSizePx) {\r\n width = cursorImageSizePx;\r\n height = width * (img.height / img.width);\r\n }\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.height = height;\r\n canvas.width = width;\r\n const context = canvas.getContext(\"2d\");\r\n context.drawImage(img, 0, 0, width, height);\r\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg);\r\n }\r\n if (this.state.pendingImageElement) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\r\n }\r\n });\r\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const clientX = this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.fileOpen)({\r\n description: \"Image\",\r\n extensions: [\"jpg\", \"png\", \"svg\", \"gif\"],\r\n });\r\n const imageElement = this.createImageElement({\r\n sceneX: x,\r\n sceneY: y,\r\n });\r\n if (insertOnCanvasDirectly) {\r\n this.insertImageElement(imageElement, imageFile);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({\r\n selectedElementIds: { [imageElement.id]: true },\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n else {\r\n this.setState({\r\n pendingImageElement: imageElement,\r\n }, () => {\r\n this.insertImageElement(imageElement, imageFile, \r\n /* showCursorImagePreview */ true);\r\n });\r\n }\r\n }\r\n catch (error) {\r\n if (error.name !== \"AbortError\") {\r\n console.error(error);\r\n }\r\n else {\r\n console.warn(error);\r\n }\r\n this.setState({\r\n pendingImageElement: null,\r\n editingElement: null,\r\n elementType: \"selection\",\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n });\r\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\r\n var _a;\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\r\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n if (!image || image instanceof Promise) {\r\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value) {\r\n const placeholderSize = 100 / this.state.zoom.value;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n x: imageElement.x - placeholderSize / 2,\r\n y: imageElement.y - placeholderSize / 2,\r\n width: placeholderSize,\r\n height: placeholderSize,\r\n });\r\n }\r\n return;\r\n }\r\n if (forceNaturalSize ||\r\n // if user-created bounding box is below threshold, assume the\r\n // intention was to click instead of drag, and use the image's\r\n // intrinsic size\r\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\r\n const minHeight = Math.max(this.state.height - 120, 160);\r\n // max 65% of canvas height, clamped to <300px, vh - 120px>\r\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\r\n const height = Math.min(image.naturalHeight, maxHeight);\r\n const width = height * (image.naturalWidth / image.naturalHeight);\r\n // add current imageElement width/height to account for previous centering\r\n // of the placholder image\r\n const x = imageElement.x + imageElement.width / 2 - width / 2;\r\n const y = imageElement.y + imageElement.height / 2 - height / 2;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\r\n }\r\n };\r\n /** updates image cache, refreshing updated elements and/or setting status\r\n to error for images that fail during <img> element creation */\r\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.updateImageCache)({\r\n imageCache: this.imageCache,\r\n fileIds: elements.map((element) => element.fileId),\r\n files,\r\n });\r\n if (updatedFiles.size || erroredFiles.size) {\r\n for (const element of elements) {\r\n if (updatedFiles.has(element.fileId)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n }\r\n }\r\n if (erroredFiles.size) {\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n erroredFiles.has(element.fileId)) {\r\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\r\n status: \"error\",\r\n });\r\n }\r\n return element;\r\n }));\r\n }\r\n return { updatedFiles, erroredFiles };\r\n });\r\n /** adds new images to imageCache and re-renders if needed */\r\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.getInitializedImageElements)(this.scene.getElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\r\n if (uncachedImageElements.length) {\r\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\r\n if (updatedFiles.size) {\r\n this.scene.informMutation();\r\n }\r\n }\r\n });\r\n /** generally you should use `addNewImagesToImageCache()` directly if you need\r\n * to render new images. This is just a failsafe */\r\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default()(() => {\r\n this.addNewImagesToImageCache();\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.IMAGE_RENDER_TIMEOUT);\r\n this.updateBindingEnabledOnPointerMove = (event) => {\r\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\r\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\r\n this.setState({ isBindingEnabled: shouldEnableBinding });\r\n }\r\n };\r\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\r\n this.setState({\r\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\r\n });\r\n };\r\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \r\n /** scene coords */\r\n pointerCoords, \r\n // During line creation the start binding hasn't been written yet\r\n // into `linearElement`\r\n oppositeBindingBoundElement) => {\r\n if (!pointerCoords.length) {\r\n return;\r\n }\r\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\r\n if (hoveredBindableElement != null &&\r\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\r\n acc.push(hoveredBindableElement);\r\n }\r\n return acc;\r\n }, []);\r\n this.setState({ suggestedBindings });\r\n };\r\n this.handleCanvasRef = (canvas) => {\r\n var _a, _b, _c;\r\n // canvas is null when unmounting\r\n if (canvas !== null) {\r\n this.canvas = canvas;\r\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__[\"default\"].canvas(this.canvas);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel, {\r\n passive: false,\r\n });\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n else {\r\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel);\r\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n };\r\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\r\n var _k, _l;\r\n try {\r\n const file = event.dataTransfer.files[0];\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n // first attempt to decode scene from the image if it's embedded\r\n // ---------------------------------------------------------------------\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted());\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n return;\r\n }\r\n catch (error) {\r\n if (error.name !== \"EncodingError\") {\r\n throw error;\r\n }\r\n }\r\n }\r\n // if no scene is embedded or we fail for whatever reason, fall back\r\n // to importing as regular image\r\n // ---------------------------------------------------------------------\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n return this.setState({\r\n isLoading: false,\r\n errorMessage: error.message,\r\n });\r\n }\r\n const libraryShapes = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib);\r\n if (libraryShapes !== \"\") {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: JSON.parse(libraryShapes),\r\n position: event,\r\n files: null,\r\n });\r\n return;\r\n }\r\n const file = (_k = event.dataTransfer) === null || _k === void 0 ? void 0 : _k.files[0];\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib ||\r\n ((_l = file === null || file === void 0 ? void 0 : file.name) === null || _l === void 0 ? void 0 : _l.endsWith(\".excalidrawlib\"))) {\r\n this.library\r\n .importLibrary(file)\r\n .then(() => {\r\n // Close and then open to get the libraries updated\r\n this.setState({ isLibraryOpen: false });\r\n this.setState({ isLibraryOpen: true });\r\n })\r\n .catch((error) => this.setState({ isLoading: false, errorMessage: error.message }));\r\n // default: assume an Excalidraw file regardless of extension/MimeType\r\n }\r\n else {\r\n this.setState({ isLoading: true });\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n yield this.loadFileToCanvas(file);\r\n }\r\n });\r\n this.loadFileToCanvas = (file) => {\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n };\r\n this.handleCanvasContextMenu = (event) => {\r\n event.preventDefault();\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const element = this.getElementAtPosition(x, y, { preferSelected: true });\r\n const type = element ? \"element\" : \"canvas\";\r\n const container = this.excalidrawContainerRef.current;\r\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\r\n const left = event.clientX - offsetLeft;\r\n const top = event.clientY - offsetTop;\r\n if (element && !this.state.selectedElementIds[element.id]) {\r\n this.setState({ selectedElementIds: { [element.id]: true } }, () => {\r\n this._openContextMenu({ top, left }, type);\r\n });\r\n }\r\n else {\r\n this._openContextMenu({ top, left }, type);\r\n }\r\n };\r\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\r\n var _a;\r\n const draggingElement = this.state.draggingElement;\r\n const pointerCoords = pointerDownState.lastCoords;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"selection\") {\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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));\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\r\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n const aspectRatio = image && !(image instanceof Promise)\r\n ? image.width / image.height\r\n : null;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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)\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\r\n this.maybeSuggestBindingForAll([draggingElement]);\r\n }\r\n };\r\n this.maybeHandleResize = (pointerDownState, event) => {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const transformHandleType = pointerDownState.resize.handleType;\r\n this.setState({\r\n // TODO: rename this state field to \"isScaling\" to distinguish\r\n // it from the generic \"isResizing\" which includes scaling and\r\n // rotating\r\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\r\n isRotating: transformHandleType === \"rotation\",\r\n });\r\n const pointerCoords = pointerDownState.lastCoords;\r\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);\r\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])\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n return true;\r\n }\r\n return false;\r\n };\r\n /** @private use this.handleCanvasContextMenu */\r\n this._openContextMenu = ({ left, top, }, type) => {\r\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const separator = \"separator\";\r\n const elements = this.scene.getElements();\r\n const options = [];\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng);\r\n }\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg);\r\n }\r\n if (type === \"canvas\") {\r\n const viewModeOptions = [\r\n ...options,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ];\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: viewModeOptions,\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && navigator.clipboard && separator,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg,\r\n ((_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) ||\r\n (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0)) &&\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSelectAll,\r\n separator,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n else if (type === \"element\") {\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy, ...options],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCut,\r\n this.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy,\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && separator,\r\n ...options,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyStyles,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionPasteStyles,\r\n separator,\r\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup,\r\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup,\r\n (maybeGroupAction || maybeUngroupAction) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionAddToLibrary,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendBackward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringForward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendToBack,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringToFront,\r\n separator,\r\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal,\r\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical,\r\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDuplicateSelection,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n };\r\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n if (isPanning) {\r\n return;\r\n }\r\n const { deltaX, deltaY } = event;\r\n const { selectedElementIds, previousSelectedElementIds } = this.state;\r\n // note that event.ctrlKey is necessary to handle pinch zooming\r\n if (event.metaKey || event.ctrlKey) {\r\n const sign = Math.sign(deltaY);\r\n const MAX_STEP = 10;\r\n let delta = Math.abs(deltaY);\r\n if (delta > MAX_STEP) {\r\n delta = MAX_STEP;\r\n }\r\n delta *= sign;\r\n if (Object.keys(previousSelectedElementIds).length !== 0) {\r\n setTimeout(() => {\r\n this.setState({\r\n selectedElementIds: previousSelectedElementIds,\r\n previousSelectedElementIds: {},\r\n });\r\n }, 1000);\r\n }\r\n let newZoom = this.state.zoom.value - delta / 100;\r\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\r\n newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign;\r\n // round to nearest step\r\n newZoom = Math.round(newZoom * _constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100) / (_constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100);\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom), zoom, { left: offsetLeft, top: offsetTop }, {\r\n x: cursorX,\r\n y: cursorY,\r\n }),\r\n selectedElementIds: {},\r\n previousSelectedElementIds: Object.keys(selectedElementIds).length !== 0\r\n ? selectedElementIds\r\n : previousSelectedElementIds,\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n return;\r\n }\r\n // scroll horizontally when shift pressed\r\n if (event.shiftKey) {\r\n this.setState(({ zoom, scrollX }) => ({\r\n // on Mac, shift+wheel tends to result in deltaX\r\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\r\n }));\r\n return;\r\n }\r\n this.setState(({ zoom, scrollX, scrollY }) => ({\r\n scrollX: scrollX - deltaX / zoom.value,\r\n scrollY: scrollY - deltaY / zoom.value,\r\n }));\r\n });\r\n this.savePointer = (x, y, button) => {\r\n var _a, _b;\r\n if (!x || !y) {\r\n return;\r\n }\r\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\r\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\r\n // sometimes the pointer goes off screen\r\n }\r\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\r\n pointer,\r\n button,\r\n pointersMap: gesture.pointers,\r\n });\r\n };\r\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n if (!this.unmounted) {\r\n this.setState({ shouldCacheIgnoreZoom: false });\r\n }\r\n }, 300);\r\n this.updateDOMRect = (cb) => {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\r\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\r\n if (width === currentWidth &&\r\n height === currentHeight &&\r\n offsetLeft === currentOffsetLeft &&\r\n offsetTop === currentOffsetTop) {\r\n if (cb) {\r\n cb();\r\n }\r\n return;\r\n }\r\n this.setState({\r\n width,\r\n height,\r\n offsetLeft,\r\n offsetTop,\r\n }, () => {\r\n cb && cb();\r\n });\r\n }\r\n };\r\n this.refresh = () => {\r\n this.setState(Object.assign({}, this.getCanvasOffsets()));\r\n };\r\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)();\r\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\r\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\r\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight });\r\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_46__.nanoid)();\r\n if (excalidrawRef) {\r\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\r\n const api = {\r\n ready: true,\r\n readyPromise,\r\n updateScene: this.updateScene,\r\n addFiles: this.addFiles,\r\n resetScene: this.resetScene,\r\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\r\n history: {\r\n clear: this.resetHistory,\r\n },\r\n scrollToContent: this.scrollToContent,\r\n getSceneElements: this.getSceneElements,\r\n getAppState: () => this.state,\r\n getFiles: () => this.files,\r\n refresh: this.refresh,\r\n importLibrary: this.importLibraryFromUrl,\r\n setToastMessage: this.setToastMessage,\r\n id: this.id,\r\n };\r\n if (typeof excalidrawRef === \"function\") {\r\n excalidrawRef(api);\r\n }\r\n else {\r\n excalidrawRef.current = api;\r\n }\r\n readyPromise.resolve(api);\r\n }\r\n this.excalidrawContainerValue = {\r\n container: this.excalidrawContainerRef.current,\r\n id: this.id,\r\n };\r\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\r\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\r\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\r\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_6__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\r\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_7__.actions);\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createUndoAction)(this.history));\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createRedoAction)(this.history));\r\n }\r\n renderCanvas() {\r\n const canvasScale = window.devicePixelRatio;\r\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\r\n const canvasWidth = canvasDOMWidth * canvasScale;\r\n const canvasHeight = canvasDOMHeight * canvasScale;\r\n if (viewModeEnabled) {\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n cursor: _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n render() {\r\n var _a, _b;\r\n const { zenModeEnabled, viewModeEnabled } = this.state;\r\n const { onCollabButtonClick, renderTopRightUI, renderFooter, renderCustomStats, } = this.props;\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(\"excalidraw excalidraw-container\", {\r\n \"excalidraw--view-mode\": viewModeEnabled,\r\n \"excalidraw--mobile\": this.isMobile,\r\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)(IsMobileContext.Provider, Object.assign({ value: this.isMobile }, { 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.getElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\r\n elements,\r\n position: \"center\",\r\n files: null,\r\n }), zenModeEnabled: zenModeEnabled, toggleZenMode: this.toggleZenMode, langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating || false, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, viewModeEnabled: viewModeEnabled, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\r\n zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\r\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 }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }, void 0), this.state.showStats && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stats__WEBPACK_IMPORTED_MODULE_37__.Stats, { appState: this.state, setAppState: this.setAppState, elements: this.scene.getElements(), onClose: this.toggleStats, renderCustomStats: renderCustomStats }, void 0)), this.state.toastMessage !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_38__.Toast, { message: this.state.toastMessage, clearToast: this.clearToast }, void 0)), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() }, void 0)] }), void 0) }), void 0) }), void 0));\r\n }\r\n componentDidMount() {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function* () {\r\n this.excalidrawContainerValue.container =\r\n this.excalidrawContainerRef.current;\r\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n const setState = this.setState.bind(this);\r\n Object.defineProperties(window.h, {\r\n state: {\r\n configurable: true,\r\n get: () => {\r\n return this.state;\r\n },\r\n },\r\n setState: {\r\n configurable: true,\r\n value: (...args) => {\r\n return this.setState(...args);\r\n },\r\n },\r\n app: {\r\n configurable: true,\r\n value: this,\r\n },\r\n history: {\r\n configurable: true,\r\n value: this.history,\r\n },\r\n });\r\n }\r\n this.scene.addCallback(this.onSceneUpdated);\r\n this.addEventListeners();\r\n if (this.excalidrawContainerRef.current) {\r\n this.focusContainer();\r\n }\r\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n // compute isMobile state\r\n // ---------------------------------------------------------------------\r\n const { width, height } = this.excalidrawContainerRef.current.getBoundingClientRect();\r\n this.isMobile =\r\n width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT ||\r\n (height < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE);\r\n // refresh offsets\r\n // ---------------------------------------------------------------------\r\n this.updateDOMRect();\r\n });\r\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\r\n }\r\n else if (window.matchMedia) {\r\n const mediaQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\r\n const handler = () => (this.isMobile = mediaQuery.matches);\r\n mediaQuery.addListener(handler);\r\n this.detachIsMobileMqHandler = () => mediaQuery.removeListener(handler);\r\n }\r\n const searchParams = new URLSearchParams(window.location.search.slice(1));\r\n if (searchParams.has(\"web-share-target\")) {\r\n // Obtain a file that was shared via the Web Share Target API.\r\n this.restoreFileFromShare();\r\n }\r\n else {\r\n this.updateDOMRect(this.initializeScene);\r\n }\r\n });\r\n }\r\n componentWillUnmount() {\r\n var _a;\r\n this.files = {};\r\n this.imageCache.clear();\r\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\r\n this.unmounted = true;\r\n this.removeEventListeners();\r\n this.scene.destroy();\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n }\r\n removeEventListeners() {\r\n var _a, _b;\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n (_a = this.nearestScrollableContainer) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n (_b = this.detachIsMobileMqHandler) === null || _b === void 0 ? void 0 : _b.call(this);\r\n }\r\n addEventListeners() {\r\n var _a, _b;\r\n this.removeEventListeners();\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer); // #3553\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n if (this.props.handleKeyboardGlobally) {\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp, { passive: true });\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\r\n // rerender text elements on font load to fix #637 && #1553\r\n (_b = (_a = document.fonts) === null || _a === void 0 ? void 0 : _a.addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, \"loadingdone\", this.onFontLoaded);\r\n // Safari-only desktop pinch zoom\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n if (this.props.detectScroll) {\r\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\r\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n }\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n }\r\n componentDidUpdate(prevProps, prevState) {\r\n var _a, _b, _c;\r\n if (prevProps.langCode !== this.props.langCode) {\r\n this.updateLanguage();\r\n }\r\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\r\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\r\n }\r\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\r\n this.addEventListeners();\r\n this.deselectElements();\r\n }\r\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\r\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\r\n }\r\n if (prevProps.theme !== this.props.theme && this.props.theme) {\r\n this.setState({ theme: this.props.theme });\r\n }\r\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\r\n this.setState({\r\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null,\r\n });\r\n }\r\n if (this.props.name && prevProps.name !== this.props.name) {\r\n this.setState({\r\n name: this.props.name,\r\n });\r\n }\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\r\n if (this.state.editingLinearElement &&\r\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\r\n // defer so that the commitToHistory flag isn't reset via current update\r\n setTimeout(() => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n const { multiElement } = prevState;\r\n if (prevState.elementType !== this.state.elementType &&\r\n multiElement != null &&\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement)) {\r\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)));\r\n }\r\n const cursorButton = {};\r\n const pointerViewportCoords = {};\r\n const remoteSelectedElementIds = {};\r\n const pointerUsernames = {};\r\n const pointerUserStates = {};\r\n this.state.collaborators.forEach((user, socketId) => {\r\n if (user.selectedElementIds) {\r\n for (const id of Object.keys(user.selectedElementIds)) {\r\n if (!(id in remoteSelectedElementIds)) {\r\n remoteSelectedElementIds[id] = [];\r\n }\r\n remoteSelectedElementIds[id].push(socketId);\r\n }\r\n }\r\n if (!user.pointer) {\r\n return;\r\n }\r\n if (user.username) {\r\n pointerUsernames[socketId] = user.username;\r\n }\r\n if (user.userState) {\r\n pointerUserStates[socketId] = user.userState;\r\n }\r\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: user.pointer.x,\r\n sceneY: user.pointer.y,\r\n }, this.state);\r\n cursorButton[socketId] = user.button;\r\n });\r\n const renderingElements = this.scene.getElements().filter((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\r\n if (\r\n // not placed on canvas yet (but in elements array)\r\n this.state.pendingImageElement &&\r\n element.id === this.state.pendingImageElement.id) {\r\n return false;\r\n }\r\n }\r\n // don't render text element that's being currently edited (it's\r\n // rendered on remote only)\r\n return (!this.state.editingElement ||\r\n this.state.editingElement.type !== \"text\" ||\r\n element.id !== this.state.editingElement.id);\r\n });\r\n const { atLeastOneVisibleElement, scrollBars } = (0,_renderer__WEBPACK_IMPORTED_MODULE_28__.renderScene)(renderingElements, this.state, this.state.selectionElement, window.devicePixelRatio, this.rc, this.canvas, {\r\n scrollX: this.state.scrollX,\r\n scrollY: this.state.scrollY,\r\n viewBackgroundColor: this.state.viewBackgroundColor,\r\n zoom: this.state.zoom,\r\n remotePointerViewportCoords: pointerViewportCoords,\r\n remotePointerButton: cursorButton,\r\n remoteSelectedElementIds,\r\n remotePointerUsernames: pointerUsernames,\r\n remotePointerUserStates: pointerUserStates,\r\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\r\n theme: this.state.theme,\r\n imageCache: this.imageCache,\r\n isExporting: false,\r\n renderScrollbars: !this.isMobile,\r\n });\r\n if (scrollBars) {\r\n currentScrollBars = scrollBars;\r\n }\r\n const scrolledOutside = \r\n // hide when editing text\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? false\r\n : !atLeastOneVisibleElement && renderingElements.length > 0;\r\n if (this.state.scrolledOutside !== scrolledOutside) {\r\n this.setState({ scrolledOutside });\r\n }\r\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\r\n this.scheduleImageRefresh();\r\n // Do not notify consumers if we're still loading the scene. Among other\r\n // potential issues, this fixes a case where the tab isn't focused during\r\n // init, which would trigger onChange with empty elements, which would then\r\n // override whatever is in localStorage currently.\r\n if (!this.state.isLoading) {\r\n (_c = (_b = this.props).onChange) === null || _c === void 0 ? void 0 : _c.call(_b, this.scene.getElementsIncludingDeleted(), this.state, this.files);\r\n }\r\n }\r\n static resetTapTwice() {\r\n didTapTwice = false;\r\n }\r\n addTextFromPaste(text) {\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x,\r\n y,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text,\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: this.state.currentItemTextAlign,\r\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n });\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({ selectedElementIds: { [element.id]: true } });\r\n this.history.resumeRecording();\r\n }\r\n selectShapeTool(elementType) {\r\n if (!isHoldingSpace) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, elementType);\r\n }\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\r\n this.focusContainer();\r\n }\r\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(elementType)) {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n if (elementType === \"image\") {\r\n this.onImageAction();\r\n }\r\n if (elementType !== \"selection\") {\r\n this.setState({\r\n elementType,\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n else {\r\n this.setState({ elementType });\r\n }\r\n }\r\n handleTextWysiwyg(element, { isExistingElement = false, }) {\r\n const updateElement = (text, originalText, isDeleted = false, updateDimensions = false) => {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\r\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\r\n text,\r\n isDeleted,\r\n originalText,\r\n }, updateDimensions);\r\n }\r\n return _element;\r\n }),\r\n ]);\r\n };\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\r\n id: element.id,\r\n appState: this.state,\r\n canvas: this.canvas,\r\n getViewportCoords: (x, y) => {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: x,\r\n sceneY: y,\r\n }, this.state);\r\n return [\r\n viewportX,\r\n viewportY, // - this.state.offsetTop, //* (2 - this.state.zoom.value),\r\n ];\r\n },\r\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\r\n updateElement(text, text, false, !element.containerId);\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\r\n }\r\n }),\r\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\r\n const isDeleted = !text.trim();\r\n updateElement(text, originalText, isDeleted, true);\r\n // select the created text element only if submitting via keyboard\r\n // (when submitting via click it should act as signal to deselect)\r\n if (!isDeleted && viaKeyboard) {\r\n const elementIdToSelect = element.containerId\r\n ? element.containerId\r\n : element.id;\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\r\n }));\r\n }\r\n if (isDeleted) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getElements(), [element]);\r\n }\r\n if (!isDeleted || isExistingElement) {\r\n this.history.resumeRecording();\r\n }\r\n this.setState({\r\n draggingElement: null,\r\n editingElement: null,\r\n });\r\n if (this.state.elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n this.focusContainer();\r\n }),\r\n element,\r\n excalidrawContainer: this.excalidrawContainerRef.current,\r\n });\r\n // deselect all other elements when inserting text\r\n this.deselectElements();\r\n // do an initial update to re-initialize element position since we were\r\n // modifying element's x/y for sake of editor (case: syncing to remote)\r\n updateElement(element.text, element.originalText);\r\n }\r\n deselectElements() {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n getTextElementAtPosition(x, y) {\r\n const element = this.getElementAtPosition(x, y, {\r\n includeBoundTextElement: true,\r\n });\r\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\r\n return element;\r\n }\r\n return null;\r\n }\r\n getElementAtPosition(x, y, opts) {\r\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement);\r\n if (allHitElements.length > 1) {\r\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\r\n for (let index = allHitElements.length - 1; index > -1; index--) {\r\n if (this.state.selectedElementIds[allHitElements[index].id]) {\r\n return allHitElements[index];\r\n }\r\n }\r\n }\r\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\r\n // If we're hitting element with highest z-index only on its bounding box\r\n // while also hitting other element figure, the latter should be considered.\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\r\n ? allHitElements[allHitElements.length - 2]\r\n : elementWithHighestZIndex;\r\n }\r\n if (allHitElements.length === 1) {\r\n return allHitElements[0];\r\n }\r\n return null;\r\n }\r\n getElementsAtPosition(x, y, includeBoundTextElement = false) {\r\n const elements = includeBoundTextElement\r\n ? this.scene.getElements()\r\n : this.scene\r\n .getElements()\r\n .filter((element) => !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId));\r\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\r\n }\r\n maybeCleanupAfterMissingPointerUp(event) {\r\n if (lastPointerUp !== null) {\r\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\r\n // this can happen when a contextual menu or alert is triggered. In order to avoid\r\n // being in a weird state, we clean up on the next pointerdown\r\n lastPointerUp(event);\r\n }\r\n }\r\n updateGestureOnPointerDown(event) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n if (gesture.pointers.size === 2) {\r\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n gesture.initialScale = this.state.zoom.value;\r\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n }\r\n }\r\n initialPointerDownState(event) {\r\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return {\r\n origin,\r\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\r\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\r\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\r\n // we need to duplicate because we'll be updating this state\r\n lastCoords: Object.assign({}, origin),\r\n originalElements: this.scene.getElements().reduce((acc, element) => {\r\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\r\n return acc;\r\n }, new Map()),\r\n resize: {\r\n handleType: false,\r\n isResizing: false,\r\n offset: { x: 0, y: 0 },\r\n arrowDirection: \"origin\",\r\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\r\n },\r\n hit: {\r\n element: null,\r\n allHitElements: [],\r\n wasAddedToSelection: false,\r\n hasBeenDuplicated: false,\r\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\r\n hasHitElementInside: false,\r\n },\r\n drag: {\r\n hasOccurred: false,\r\n offset: null,\r\n },\r\n eventListeners: {\r\n onMove: null,\r\n onUp: null,\r\n onKeyUp: null,\r\n onKeyDown: null,\r\n },\r\n boxSelection: {\r\n hasOccurred: false,\r\n },\r\n };\r\n }\r\n // Returns whether the event is a dragging a scrollbar\r\n handleDraggingScrollBar(event, pointerDownState) {\r\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\r\n return false;\r\n }\r\n isDraggingScrollBar = true;\r\n pointerDownState.lastCoords.x = event.clientX;\r\n pointerDownState.lastCoords.y = event.clientY;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\r\n });\r\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isDraggingScrollBar = false;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n lastPointerUp = null;\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n });\r\n lastPointerUp = onPointerUp;\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n return true;\r\n }\r\n isASelectedElement(hitElement) {\r\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\r\n }\r\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\r\n if (selectedElements.length < 2) {\r\n return false;\r\n }\r\n // How many pixels off the shape boundary we still consider a hit\r\n const threshold = 10 / this.state.zoom.value;\r\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return (point.x > x1 - threshold &&\r\n point.x < x2 + threshold &&\r\n point.y > y1 - threshold &&\r\n point.y < y2 + threshold);\r\n }\r\n onKeyDownFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onKeyUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // Prevents focus from escaping excalidraw tab\r\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onPointerMoveFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a, _b;\r\n // We need to initialize dragOffsetXY only after we've updated\r\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\r\n // event handler should hopefully ensure we're already working with\r\n // the updated state.\r\n if (pointerDownState.drag.offset === null) {\r\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.getElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\r\n }\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\r\n return;\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n // for arrows/lines, don't start dragging until a given threshold\r\n // to ensure we don't create a 2-point arrow by mistake when\r\n // user clicks mouse in a way that it moves a tiny bit (thus\r\n // triggering pointermove)\r\n if (!pointerDownState.drag.hasOccurred &&\r\n (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\")) {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD) {\r\n return;\r\n }\r\n }\r\n if (pointerDownState.resize.isResizing) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return true;\r\n }\r\n }\r\n if (this.state.editingLinearElement) {\r\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(this.state, (appState) => this.setState(appState), pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\r\n });\r\n if (didDrag) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n return;\r\n }\r\n }\r\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hasHitASelectedElement ||\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\r\n // this allows for box-selecting points when clicking inside the\r\n // line's bounding box\r\n (!this.state.editingLinearElement || !event.shiftKey) &&\r\n // box-selecting without shift when editing line, not clicking on a line\r\n (!this.state.editingLinearElement ||\r\n ((_a = this.state.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !==\r\n ((_b = pointerDownState.hit.element) === null || _b === void 0 ? void 0 : _b.id) ||\r\n pointerDownState.hit.hasHitElementInside)) {\r\n // Marking that click was used for dragging to check\r\n // if elements should be deselected on pointerup\r\n pointerDownState.drag.hasOccurred = true;\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\r\n // it would have weird results (stuff jumping all over the screen)\r\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\r\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);\r\n const [dragDistanceX, dragDistanceY] = [\r\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\r\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\r\n ];\r\n // We only drag in one direction if shift is pressed\r\n const lockDirection = event.shiftKey;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY);\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n // We duplicate the selected element if alt is pressed on pointer move\r\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\r\n // Move the currently selected elements to the top of the z index stack, and\r\n // put the duplicates where the selected elements used to be.\r\n // (the origin point where the dragging started)\r\n pointerDownState.hit.hasBeenDuplicated = true;\r\n const nextElements = [];\r\n const elementsToAppend = [];\r\n const groupIdMap = new Map();\r\n const oldIdToDuplicatedId = new Map();\r\n const hitElement = pointerDownState.hit.element;\r\n const elements = this.scene.getElementsIncludingDeleted();\r\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\r\n for (const element of elements) {\r\n if (selectedElementIds.includes(element.id) ||\r\n // case: the state.selectedElementIds might not have been\r\n // updated yet by the time this mousemove event is fired\r\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\r\n pointerDownState.hit.wasAddedToSelection)) {\r\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\r\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);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\r\n x: duplicatedElement.x + (originDragX - dragX),\r\n y: duplicatedElement.y + (originDragY - dragY),\r\n });\r\n nextElements.push(duplicatedElement);\r\n elementsToAppend.push(element);\r\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\r\n }\r\n else {\r\n nextElements.push(element);\r\n }\r\n }\r\n const nextSceneElements = [...nextElements, ...elementsToAppend];\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\r\n this.scene.replaceAllElements(nextSceneElements);\r\n }\r\n return;\r\n }\r\n }\r\n // It is very important to read this.state within each move event,\r\n // otherwise we would read a stale one!\r\n const draggingElement = this.state.draggingElement;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"freedraw\") {\r\n const points = draggingElement.points;\r\n const dx = pointerCoords.x - draggingElement.x;\r\n const dy = pointerCoords.y - draggingElement.y;\r\n const pressures = draggingElement.simulatePressure\r\n ? draggingElement.pressures\r\n : [...draggingElement.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n });\r\n }\r\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n pointerDownState.drag.hasOccurred = true;\r\n const points = draggingElement.points;\r\n let dx = gridX - draggingElement.x;\r\n let dy = gridY - draggingElement.y;\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\r\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getPerfectElementSize)(this.state.elementType, dx, dy));\r\n }\r\n if (points.length === 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, { points: [...points, [dx, dy]] });\r\n }\r\n else if (points.length > 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points.slice(0, -1), [dx, dy]],\r\n });\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n // When creating a linear element by dragging\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\r\n }\r\n }\r\n else {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n }\r\n if (this.state.elementType === \"selection\") {\r\n pointerDownState.boxSelection.hasOccurred = true;\r\n const elements = this.scene.getElements();\r\n if (!event.shiftKey &&\r\n // allows for box-selecting points (without shift)\r\n !this.state.editingLinearElement &&\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\r\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\r\n [pointerDownState.hit.element.id]: true,\r\n } }), this.scene.getElements()));\r\n }\r\n else {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n }\r\n // box-select line editor points\r\n if (this.state.editingLinearElement) {\r\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\r\n // regular box-select\r\n }\r\n else {\r\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\r\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((map, element) => {\r\n map[element.id] = true;\r\n return map;\r\n }, {})), (pointerDownState.hit.element\r\n ? {\r\n // if using ctrl/cmd, select the hitElement only if we\r\n // haven't box-selected anything else\r\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\r\n }\r\n : null)) }), this.scene.getElements()));\r\n }\r\n }\r\n });\r\n }\r\n // Returns whether the pointer move happened over either scrollbar\r\n handlePointerMoveOverScrollbars(event, pointerDownState) {\r\n if (pointerDownState.scrollbars.isOverHorizontal) {\r\n const x = event.clientX;\r\n const dx = x - pointerDownState.lastCoords.x;\r\n this.setState({\r\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.x = x;\r\n return true;\r\n }\r\n if (pointerDownState.scrollbars.isOverVertical) {\r\n const y = event.clientY;\r\n const dy = y - pointerDownState.lastCoords.y;\r\n this.setState({\r\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.y = y;\r\n return true;\r\n }\r\n return false;\r\n }\r\n onPointerUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\r\n var _a, _b;\r\n const { draggingElement, resizingElement, multiElement, elementType, elementLocked, isResizing, isRotating, } = this.state;\r\n this.setState({\r\n isResizing: false,\r\n isRotating: false,\r\n resizingElement: null,\r\n selectionElement: null,\r\n cursorButton: \"up\",\r\n // text elements are reset on finalize, and resetting on pointerup\r\n // may cause issues with double taps\r\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? this.state.editingElement\r\n : null,\r\n });\r\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\r\n // Handle end of dragging a point of a linear element, might close a loop\r\n // and sets binding element\r\n if (this.state.editingLinearElement) {\r\n if (!pointerDownState.boxSelection.hasOccurred &&\r\n (((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\r\n this.state.editingLinearElement.elementId ||\r\n !pointerDownState.hit.hasHitElementInside)) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n else {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({\r\n editingLinearElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n }\r\n }\r\n lastPointerUp = null;\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\r\n if (this.state.pendingImageElement) {\r\n this.setState({ pendingImageElement: null });\r\n }\r\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n const points = draggingElement.points;\r\n let dx = pointerCoords.x - draggingElement.x;\r\n let dy = pointerCoords.y - draggingElement.y;\r\n // Allows dots to avoid being flagged as infinitely small\r\n if (dx === points[0][0] && dy === points[0][1]) {\r\n dy += 0.0001;\r\n dx += 0.0001;\r\n }\r\n const pressures = draggingElement.simulatePressure\r\n ? []\r\n : [...draggingElement.pressures, childEvent.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n lastCommittedPoint: [dx, dy],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\r\n const imageElement = draggingElement;\r\n try {\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n catch (error) {\r\n console.error(error);\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== imageElement.id));\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n if (draggingElement.points.length > 1) {\r\n this.history.resumeRecording();\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n if (!pointerDownState.drag.hasOccurred &&\r\n draggingElement &&\r\n !multiElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [\r\n ...draggingElement.points,\r\n [\r\n pointerCoords.x - draggingElement.x,\r\n pointerCoords.y - draggingElement.y,\r\n ],\r\n ],\r\n });\r\n this.setState({\r\n multiElement: draggingElement,\r\n editingElement: this.state.draggingElement,\r\n });\r\n }\r\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\r\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\r\n }\r\n this.setState({ suggestedBindings: [], startBoundElement: null });\r\n if (!elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n elementType: \"selection\",\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n else {\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n }\r\n return;\r\n }\r\n if (elementType !== \"selection\" &&\r\n draggingElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\r\n // remove invisible element which was added in onPointerDown\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\r\n this.setState({\r\n draggingElement: null,\r\n });\r\n return;\r\n }\r\n if (draggingElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\r\n }\r\n if (resizingElement) {\r\n this.history.resumeRecording();\r\n }\r\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== resizingElement.id));\r\n }\r\n // Code below handles selection when element(s) weren't\r\n // drag or added to selection on pointer down phase.\r\n const hitElement = pointerDownState.hit.element;\r\n if (hitElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !pointerDownState.hit.wasAddedToSelection &&\r\n // if we're editing a line, pointerup shouldn't switch selection if\r\n // box selected\r\n (!this.state.editingLinearElement ||\r\n !pointerDownState.boxSelection.hasOccurred)) {\r\n // when inside line editor, shift selects points instead\r\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\r\n if (this.state.selectedElementIds[hitElement.id]) {\r\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\r\n // We want to unselect all groups hitElement is part of\r\n // as well as all elements that are part of the groups\r\n // hitElement is part of\r\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\r\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getElements(), groupId))\r\n .map((element) => ({ [element.id]: false }))\r\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\r\n this.setState((_prevState) => ({\r\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\r\n .map((gId) => ({ [gId]: false }))\r\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\r\n }));\r\n }\r\n else {\r\n // remove element from selection while\r\n // keeping prev elements selected\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false }) }), this.scene.getElements()));\r\n }\r\n }\r\n else {\r\n // add element to selection while\r\n // keeping prev elements selected\r\n this.setState((_prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\r\n }));\r\n }\r\n }\r\n else {\r\n this.setState((prevState) => (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true } }), this.scene.getElements()))));\r\n }\r\n }\r\n if (!this.state.editingLinearElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !this.state.isResizing &&\r\n ((hitElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\r\n (!hitElement &&\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\r\n // Deselect selected elements\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n return;\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\" && draggingElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\r\n }));\r\n }\r\n if (elementType !== \"selection\" ||\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getElements(), this.state)) {\r\n this.history.resumeRecording();\r\n }\r\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\r\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\r\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state));\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n elementType: \"selection\",\r\n });\r\n }\r\n else {\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n });\r\n }\r\n });\r\n }\r\n maybeSuggestBindingForAll(selectedElements) {\r\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\r\n this.setState({ suggestedBindings });\r\n }\r\n clearSelection(hitElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n // Continue editing the same group if the user selected a different\r\n // element from it\r\n editingGroupId: prevState.editingGroupId &&\r\n hitElement != null &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\r\n ? prevState.editingGroupId\r\n : null,\r\n }));\r\n this.setState({\r\n selectedElementIds: {},\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n getTextWysiwygSnappedToCenterPosition(x, y, appState, canvas, scale) {\r\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\r\n if (elementClickedInside) {\r\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\r\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\r\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\r\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_11__.TEXT_TO_CENTER_SNAP_THRESHOLD;\r\n if (isSnappedToCenter) {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\r\n return { viewportX, viewportY, elementCenterX, elementCenterY };\r\n }\r\n }\r\n }\r\n getCanvasOffsets() {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { left, top } = excalidrawContainer.getBoundingClientRect();\r\n return {\r\n offsetLeft: left,\r\n offsetTop: top,\r\n };\r\n }\r\n return {\r\n offsetLeft: 0,\r\n offsetTop: 0,\r\n };\r\n }\r\n updateLanguage() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\r\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\r\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\r\n this.setAppState({});\r\n });\r\n }\r\n}\r\nApp.defaultProps = {\r\n // needed for tests to pass since we directly render App in many tests\r\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_UI_OPTIONS,\r\n};\r\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n window.h = window.h || {};\r\n Object.defineProperties(window.h, {\r\n elements: {\r\n configurable: true,\r\n get() {\r\n return this.app.scene.getElementsIncludingDeleted();\r\n },\r\n set(elements) {\r\n return this.app.scene.replaceAllElements(elements);\r\n },\r\n },\r\n });\r\n}\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QyxRQUFRLENBQUMsQ0FBQztZQUNyRCxDQUFDO1NBQ0Y7S0FDRixDQUFDLENBQUM7Q0FDSjtBQUNELGlFQUFlLEdBQUcsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9jb21wb25lbnRzL0FwcC50c3g/MDA3MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ29udGV4dCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgUm91Z2hDYW52YXMgfSBmcm9tIFwicm91Z2hqcy9iaW4vY2FudmFzXCI7XG5pbXBvcnQgcm91Z2ggZnJvbSBcInJvdWdoanMvYmluL3JvdWdoXCI7XG5pbXBvcnQgY2xzeCBmcm9tIFwiY2xzeFwiO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSBcIm5hbm9pZFwiO1xuXG5pbXBvcnQge1xuICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICBhY3Rpb25Db3B5LFxuICBhY3Rpb25Db3B5QXNQbmcsXG4gIGFjdGlvbkNvcHlBc1N2ZyxcbiAgYWN0aW9uQ29weVN0eWxlcyxcbiAgYWN0aW9uQ3V0LFxuICBhY3Rpb25EZWxldGVTZWxlY3RlZCxcbiAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICBhY3Rpb25GaW5hbGl6ZSxcbiAgYWN0aW9uRmxpcEhvcml6b250YWwsXG4gIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgYWN0aW9uR3JvdXAsXG4gIGFjdGlvblBhc3RlU3R5bGVzLFxuICBhY3Rpb25TZWxlY3RBbGwsXG4gIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgYWN0aW9uU2VuZFRvQmFjayxcbiAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gIGFjdGlvblRvZ2dsZVN0YXRzLFxuICBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICBhY3Rpb25Vbmdyb3VwLFxufSBmcm9tIFwiLi4vYWN0aW9uc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVkb0FjdGlvbiwgY3JlYXRlVW5kb0FjdGlvbiB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvbkhpc3RvcnlcIjtcbmltcG9ydCB7IEFjdGlvbk1hbmFnZXIgfSBmcm9tIFwiLi4vYWN0aW9ucy9tYW5hZ2VyXCI7XG5pbXBvcnQgeyBhY3Rpb25zIH0gZnJvbSBcIi4uL2FjdGlvbnMvcmVnaXN0ZXJcIjtcbmltcG9ydCB7IEFjdGlvblJlc3VsdCB9IGZyb20gXCIuLi9hY3Rpb25zL3R5cGVzXCI7XG5pbXBvcnQgeyB0cmFja0V2ZW50IH0gZnJvbSBcIi4uL2FuYWx5dGljc1wiO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdEFwcFN0YXRlIH0gZnJvbSBcIi4uL2FwcFN0YXRlXCI7XG5pbXBvcnQge1xuICBjb3B5VG9DbGlwYm9hcmQsXG4gIHBhcnNlQ2xpcGJvYXJkLFxuICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYixcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCxcbn0gZnJvbSBcIi4uL2NsaXBib2FyZFwiO1xuaW1wb3J0IHtcbiAgQVBQX05BTUUsXG4gIENVUlNPUl9UWVBFLFxuICBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gIERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgRFJBR0dJTkdfVEhSRVNIT0xELFxuICBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRU5WLFxuICBFVkVOVCxcbiAgR1JJRF9TSVpFLFxuICBJTUFHRV9SRU5ERVJfVElNRU9VVCxcbiAgTElORV9DT05GSVJNX1RIUkVTSE9MRCxcbiAgTUFYX0FMTE9XRURfRklMRV9CWVRFUyxcbiAgTUlNRV9UWVBFUyxcbiAgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9QT1JUUkFJVCxcbiAgUE9JTlRFUl9CVVRUT04sXG4gIFNDUk9MTF9USU1FT1VULFxuICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgVEVYVF9UT19DRU5URVJfU05BUF9USFJFU0hPTEQsXG4gIFRIRU1FLFxuICBUT1VDSF9DVFhfTUVOVV9USU1FT1VULFxuICBVUkxfSEFTSF9LRVlTLFxuICBVUkxfUVVFUllfS0VZUyxcbiAgWk9PTV9TVEVQLFxufSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBsb2FkRnJvbUJsb2IgfSBmcm9tIFwiLi4vZGF0YVwiO1xuaW1wb3J0IHsgaXNWYWxpZExpYnJhcnkgfSBmcm9tIFwiLi4vZGF0YS9qc29uXCI7XG5pbXBvcnQgTGlicmFyeSBmcm9tIFwiLi4vZGF0YS9saWJyYXJ5XCI7XG5pbXBvcnQgeyByZXN0b3JlLCByZXN0b3JlRWxlbWVudHMsIHJlc3RvcmVMaWJyYXJ5SXRlbXMgfSBmcm9tIFwiLi4vZGF0YS9yZXN0b3JlXCI7XG5pbXBvcnQge1xuICBkcmFnTmV3RWxlbWVudCxcbiAgZHJhZ1NlbGVjdGVkRWxlbWVudHMsXG4gIGR1cGxpY2F0ZUVsZW1lbnQsXG4gIGdldENvbW1vbkJvdW5kcyxcbiAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50LFxuICBnZXREcmFnT2Zmc2V0WFksXG4gIGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgZ2V0Tm9ybWFsaXplZERpbWVuc2lvbnMsXG4gIGdldFBlcmZlY3RFbGVtZW50U2l6ZSxcbiAgZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24sXG4gIGdldFJlc2l6ZU9mZnNldFhZLFxuICBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyxcbiAgaGl0VGVzdCxcbiAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50LFxuICBpc0ludmlzaWJseVNtYWxsRWxlbWVudCxcbiAgaXNOb25EZWxldGVkRWxlbWVudCxcbiAgaXNUZXh0RWxlbWVudCxcbiAgbmV3RWxlbWVudCxcbiAgbmV3TGluZWFyRWxlbWVudCxcbiAgbmV3VGV4dEVsZW1lbnQsXG4gIG5ld0ltYWdlRWxlbWVudCxcbiAgdGV4dFd5c2l3eWcsXG4gIHRyYW5zZm9ybUVsZW1lbnRzLFxuICB1cGRhdGVUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4uL2VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMsXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbixcbiAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uLFxuICBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyxcbiAgZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nLFxuICBpc0JpbmRpbmdFbmFibGVkLFxuICBpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQsXG4gIG1heWJlQmluZExpbmVhckVsZW1lbnQsXG4gIHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQsXG4gIHVuYmluZExpbmVhckVsZW1lbnRzLFxuICB1cGRhdGVCb3VuZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZWxlbWVudC9iaW5kaW5nXCI7XG5pbXBvcnQgeyBMaW5lYXJFbGVtZW50RWRpdG9yIH0gZnJvbSBcIi4uL2VsZW1lbnQvbGluZWFyRWxlbWVudEVkaXRvclwiO1xuaW1wb3J0IHtcbiAgYnVtcFZlcnNpb24sXG4gIG11dGF0ZUVsZW1lbnQsXG4gIG5ld0VsZW1lbnRXaXRoLFxufSBmcm9tIFwiLi4vZWxlbWVudC9tdXRhdGVFbGVtZW50XCI7XG5pbXBvcnQgeyBkZWVwQ29weUVsZW1lbnQsIG5ld0ZyZWVEcmF3RWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50L25ld0VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGhhc0JvdW5kVGV4dEVsZW1lbnQsXG4gIGlzQmluZGluZ0VsZW1lbnQsXG4gIGlzQmluZGluZ0VsZW1lbnRUeXBlLFxuICBpc0ltYWdlRWxlbWVudCxcbiAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50LFxuICBpc0xpbmVhckVsZW1lbnRUeXBlLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlQ2hlY2tzXCI7XG5pbXBvcnQge1xuICBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50LFxuICBFeGNhbGlkcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0ZyZWVEcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50LFxuICBFeGNhbGlkcmF3TGluZWFyRWxlbWVudCxcbiAgRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICBOb25EZWxldGVkLFxuICBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEZpbGVJZCxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IGdldENlbnRlciwgZ2V0RGlzdGFuY2UgfSBmcm9tIFwiLi4vZ2VzdHVyZVwiO1xuaW1wb3J0IHtcbiAgZWRpdEdyb3VwRm9yU2VsZWN0ZWRFbGVtZW50LFxuICBnZXRFbGVtZW50c0luR3JvdXAsXG4gIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQsXG4gIGdldFNlbGVjdGVkR3JvdXBJZHMsXG4gIGlzRWxlbWVudEluR3JvdXAsXG4gIGlzU2VsZWN0ZWRWaWFHcm91cCxcbiAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2dyb3Vwc1wiO1xuaW1wb3J0IEhpc3RvcnkgZnJvbSBcIi4uL2hpc3RvcnlcIjtcbmltcG9ydCB7IGRlZmF1bHRMYW5nLCBnZXRMYW5ndWFnZSwgbGFuZ3VhZ2VzLCBzZXRMYW5ndWFnZSwgdCB9IGZyb20gXCIuLi9pMThuXCI7XG5pbXBvcnQge1xuICBDT0RFUyxcbiAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcixcbiAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyxcbiAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUsXG4gIGlzQXJyb3dLZXksXG4gIEtFWVMsXG59IGZyb20gXCIuLi9rZXlzXCI7XG5pbXBvcnQgeyBkaXN0YW5jZTJkLCBnZXRHcmlkUG9pbnQsIGlzUGF0aEFMb29wIH0gZnJvbSBcIi4uL21hdGhcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lIH0gZnJvbSBcIi4uL3JlbmRlcmVyXCI7XG5pbXBvcnQgeyBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50IH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlckVsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZVNjcm9sbENlbnRlcixcbiAgZ2V0RWxlbWVudENvbnRhaW5pbmdQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNBdFBvc2l0aW9uLFxuICBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbixcbiAgZ2V0Tm9ybWFsaXplZFpvb20sXG4gIGdldFNlbGVjdGVkRWxlbWVudHMsXG4gIGhhc0JhY2tncm91bmQsXG4gIGlzT3ZlclNjcm9sbEJhcnMsXG4gIGlzU29tZUVsZW1lbnRTZWxlY3RlZCxcbn0gZnJvbSBcIi4uL3NjZW5lXCI7XG5pbXBvcnQgU2NlbmUgZnJvbSBcIi4uL3NjZW5lL1NjZW5lXCI7XG5pbXBvcnQgeyBSZW5kZXJDb25maWcsIFNjcm9sbEJhcnMgfSBmcm9tIFwiLi4vc2NlbmUvdHlwZXNcIjtcbmltcG9ydCB7IGdldE5ld1pvb20gfSBmcm9tIFwiLi4vc2NlbmUvem9vbVwiO1xuaW1wb3J0IHsgZmluZFNoYXBlQnlLZXkgfSBmcm9tIFwiLi4vc2hhcGVzXCI7XG5pbXBvcnQge1xuICBBcHBDbGFzc1Byb3BlcnRpZXMsXG4gIEFwcFByb3BzLFxuICBBcHBTdGF0ZSxcbiAgQmluYXJ5RmlsZURhdGEsXG4gIERhdGFVUkwsXG4gIEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJLFxuICBCaW5hcnlGaWxlcyxcbiAgR2VzdHVyZSxcbiAgR2VzdHVyZUV2ZW50LFxuICBMaWJyYXJ5SXRlbXMsXG4gIFBvaW50ZXJEb3duU3RhdGUsXG4gIFNjZW5lRGF0YSxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBkZWJvdW5jZSxcbiAgZGlzdGFuY2UsXG4gIGdldEZvbnRTdHJpbmcsXG4gIGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLFxuICBpc0lucHV0TGlrZSxcbiAgaXNUb29sSWNvbixcbiAgaXNXcml0YWJsZUVsZW1lbnQsXG4gIHJlc2V0Q3Vyc29yLFxuICByZXNvbHZhYmxlUHJvbWlzZSxcbiAgc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzLFxuICBzZXRDdXJzb3IsXG4gIHNldEN1cnNvckZvclNoYXBlLFxuICB0dXBsZVRvQ29vcnMsXG4gIHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyxcbiAgd2l0aEJhdGNoZWRVcGRhdGVzLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCBDb250ZXh0TWVudSwgeyBDb250ZXh0TWVudU9wdGlvbiB9IGZyb20gXCIuL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgTGF5ZXJVSSBmcm9tIFwiLi9MYXllclVJXCI7XG5pbXBvcnQgeyBTdGF0cyB9IGZyb20gXCIuL1N0YXRzXCI7XG5pbXBvcnQgeyBUb2FzdCB9IGZyb20gXCIuL1RvYXN0XCI7XG5pbXBvcnQgeyBhY3Rpb25Ub2dnbGVWaWV3TW9kZSB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvblRvZ2dsZVZpZXdNb2RlXCI7XG5pbXBvcnQge1xuICBkYXRhVVJMVG9GaWxlLFxuICBnZW5lcmF0ZUlkRnJvbUZpbGUsXG4gIGdldERhdGFVUkwsXG4gIGlzU3VwcG9ydGVkSW1hZ2VGaWxlLFxuICByZXNpemVJbWFnZUZpbGUsXG4gIFNWR1N0cmluZ1RvRmlsZSxcbn0gZnJvbSBcIi4uL2RhdGEvYmxvYlwiO1xuaW1wb3J0IHtcbiAgZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzLFxuICBsb2FkSFRNTEltYWdlRWxlbWVudCxcbiAgbm9ybWFsaXplU1ZHLFxuICB1cGRhdGVJbWFnZUNhY2hlIGFzIF91cGRhdGVJbWFnZUNhY2hlLFxufSBmcm9tIFwiLi4vZWxlbWVudC9pbWFnZVwiO1xuaW1wb3J0IHRocm90dGxlIGZyb20gXCJsb2Rhc2gudGhyb3R0bGVcIjtcbmltcG9ydCB7IGZpbGVPcGVuLCBuYXRpdmVGaWxlU3lzdGVtU3VwcG9ydGVkIH0gZnJvbSBcIi4uL2RhdGEvZmlsZXN5c3RlbVwiO1xuaW1wb3J0IHtcbiAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0QXBwcm94TWluTGluZUhlaWdodCxcbiAgZ2V0QXBwcm94TWluTGluZVdpZHRoLFxuICBnZXRCb3VuZFRleHRFbGVtZW50SWQsXG59IGZyb20gXCIuLi9lbGVtZW50L3RleHRFbGVtZW50XCI7XG5pbXBvcnQgeyBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveCB9IGZyb20gXCIuLi9lbGVtZW50L2NvbGxpc2lvblwiO1xuXG5jb25zdCBJc01vYmlsZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0KGZhbHNlKTtcbmV4cG9ydCBjb25zdCB1c2VJc01vYmlsZSA9ICgpID0+IHVzZUNvbnRleHQoSXNNb2JpbGVDb250ZXh0KTtcbmNvbnN0IEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDx7XG4gIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICBpZDogc3RyaW5nIHwgbnVsbDtcbn0+KHsgY29udGFpbmVyOiBudWxsLCBpZDogbnVsbCB9KTtcbmV4cG9ydCBjb25zdCB1c2VFeGNhbGlkcmF3Q29udGFpbmVyID0gKCkgPT5cbiAgdXNlQ29udGV4dChFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCk7XG5cbmxldCBkaWRUYXBUd2ljZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IHRhcHBlZFR3aWNlVGltZXIgPSAwO1xubGV0IGN1cnNvclggPSAwO1xubGV0IGN1cnNvclkgPSAwO1xubGV0IGlzSG9sZGluZ1NwYWNlOiBib29sZWFuID0gZmFsc2U7XG5sZXQgaXNQYW5uaW5nOiBib29sZWFuID0gZmFsc2U7XG5sZXQgaXNEcmFnZ2luZ1Njcm9sbEJhcjogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGN1cnJlbnRTY3JvbGxCYXJzOiBTY3JvbGxCYXJzID0geyBob3Jpem9udGFsOiBudWxsLCB2ZXJ0aWNhbDogbnVsbCB9O1xubGV0IHRvdWNoVGltZW91dCA9IDA7XG5sZXQgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbmxldCBsYXN0UG9pbnRlclVwOiAoKGV2ZW50OiBhbnkpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5jb25zdCBnZXN0dXJlOiBHZXN0dXJlID0ge1xuICBwb2ludGVyczogbmV3IE1hcCgpLFxuICBsYXN0Q2VudGVyOiBudWxsLFxuICBpbml0aWFsRGlzdGFuY2U6IG51bGwsXG4gIGluaXRpYWxTY2FsZTogbnVsbCxcbn07XG5cbmNsYXNzIEFwcCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxBcHBQcm9wcywgQXBwU3RhdGU+IHtcbiAgY2FudmFzOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJjYW52YXNcIl0gPSBudWxsO1xuICByYzogUm91Z2hDYW52YXMgfCBudWxsID0gbnVsbDtcbiAgdW5tb3VudGVkOiBib29sZWFuID0gZmFsc2U7XG4gIGFjdGlvbk1hbmFnZXI6IEFjdGlvbk1hbmFnZXI7XG4gIGlzTW9iaWxlID0gZmFsc2U7XG4gIGRldGFjaElzTW9iaWxlTXFIYW5kbGVyPzogKCkgPT4gdm9pZDtcblxuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJSZWYgPSBSZWFjdC5jcmVhdGVSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgcHVibGljIHN0YXRpYyBkZWZhdWx0UHJvcHM6IFBhcnRpYWw8QXBwUHJvcHM+ID0ge1xuICAgIC8vIG5lZWRlZCBmb3IgdGVzdHMgdG8gcGFzcyBzaW5jZSB3ZSBkaXJlY3RseSByZW5kZXIgQXBwIGluIG1hbnkgdGVzdHNcbiAgICBVSU9wdGlvbnM6IERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgfTtcblxuICBwcml2YXRlIHNjZW5lOiBTY2VuZTtcbiAgcHJpdmF0ZSByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyBsaWJyYXJ5OiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJsaWJyYXJ5XCJdO1xuICBwdWJsaWMgbGlicmFyeUl0ZW1zRnJvbVN0b3JhZ2U6IExpYnJhcnlJdGVtcyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICBwcml2YXRlIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gIHByaXZhdGUgZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlOiB7XG4gICAgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG4gICAgaWQ6IHN0cmluZztcbiAgfTtcblxuICBwdWJsaWMgZmlsZXM6IEJpbmFyeUZpbGVzID0ge307XG4gIHB1YmxpYyBpbWFnZUNhY2hlOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJpbWFnZUNhY2hlXCJdID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBBcHBQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICBjb25zdCBkZWZhdWx0QXBwU3RhdGUgPSBnZXREZWZhdWx0QXBwU3RhdGUoKTtcbiAgICBjb25zdCB7XG4gICAgICBleGNhbGlkcmF3UmVmLFxuICAgICAgdmlld01vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICB6ZW5Nb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgZ3JpZE1vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICB0aGVtZSA9IGRlZmF1bHRBcHBTdGF0ZS50aGVtZSxcbiAgICAgIG5hbWUgPSBkZWZhdWx0QXBwU3RhdGUubmFtZSxcbiAgICB9ID0gcHJvcHM7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIC4uLmRlZmF1bHRBcHBTdGF0ZSxcbiAgICAgIHRoZW1lLFxuICAgICAgaXNMb2FkaW5nOiB0cnVlLFxuICAgICAgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCksXG4gICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICB6ZW5Nb2RlRW5hYmxlZCxcbiAgICAgIGdyaWRTaXplOiBncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsLFxuICAgICAgbmFtZSxcbiAgICAgIHdpZHRoOiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0LFxuICAgIH07XG5cbiAgICB0aGlzLmlkID0gbmFub2lkKCk7XG5cbiAgICBpZiAoZXhjYWxpZHJhd1JlZikge1xuICAgICAgY29uc3QgcmVhZHlQcm9taXNlID1cbiAgICAgICAgKFwiY3VycmVudFwiIGluIGV4Y2FsaWRyYXdSZWYgJiYgZXhjYWxpZHJhd1JlZi5jdXJyZW50Py5yZWFkeVByb21pc2UpIHx8XG4gICAgICAgIHJlc29sdmFibGVQcm9taXNlPEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJPigpO1xuXG4gICAgICBjb25zdCBhcGk6IEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJID0ge1xuICAgICAgICByZWFkeTogdHJ1ZSxcbiAgICAgICAgcmVhZHlQcm9taXNlLFxuICAgICAgICB1cGRhdGVTY2VuZTogdGhpcy51cGRhdGVTY2VuZSxcbiAgICAgICAgYWRkRmlsZXM6IHRoaXMuYWRkRmlsZXMsXG4gICAgICAgIHJlc2V0U2NlbmU6IHRoaXMucmVzZXRTY2VuZSxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQ6IHRoaXMuZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQsXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBjbGVhcjogdGhpcy5yZXNldEhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICAgIHNjcm9sbFRvQ29udGVudDogdGhpcy5zY3JvbGxUb0NvbnRlbnQsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHM6IHRoaXMuZ2V0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgZ2V0QXBwU3RhdGU6ICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAgIGdldEZpbGVzOiAoKSA9PiB0aGlzLmZpbGVzLFxuICAgICAgICByZWZyZXNoOiB0aGlzLnJlZnJlc2gsXG4gICAgICAgIGltcG9ydExpYnJhcnk6IHRoaXMuaW1wb3J0TGlicmFyeUZyb21VcmwsXG4gICAgICAgIHNldFRvYXN0TWVzc2FnZTogdGhpcy5zZXRUb2FzdE1lc3NhZ2UsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgfSBhcyBjb25zdDtcbiAgICAgIGlmICh0eXBlb2YgZXhjYWxpZHJhd1JlZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYoYXBpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYuY3VycmVudCA9IGFwaTtcbiAgICAgIH1cbiAgICAgIHJlYWR5UHJvbWlzZS5yZXNvbHZlKGFwaSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUgPSB7XG4gICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgfTtcblxuICAgIHRoaXMuc2NlbmUgPSBuZXcgU2NlbmUoKTtcbiAgICB0aGlzLmxpYnJhcnkgPSBuZXcgTGlicmFyeSh0aGlzKTtcbiAgICB0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeSgpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlciA9IG5ldyBBY3Rpb25NYW5hZ2VyKFxuICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0LFxuICAgICAgKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICgpID0+IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLFxuICAgICk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWxsKGFjdGlvbnMpO1xuXG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVVuZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVJlZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNhbnZhcygpIHtcbiAgICBjb25zdCBjYW52YXNTY2FsZSA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgIH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY2FudmFzRE9NV2lkdGggKiBjYW52YXNTY2FsZTtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjYW52YXNET01IZWlnaHQgKiBjYW52YXNTY2FsZTtcbiAgICBpZiAodmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Y2FudmFzXG4gICAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgICAgICBjdXJzb3I6IENVUlNPUl9UWVBFLkdSQUIsXG4gICAgICAgICAgfX1cbiAgICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgPlxuICAgICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICAgIDwvY2FudmFzPlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxjYW52YXNcbiAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgIH19XG4gICAgICAgIHdpZHRoPXtjYW52YXNXaWR0aH1cbiAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgIG9uQ29udGV4dE1lbnU9e3RoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnV9XG4gICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgIG9uRG91YmxlQ2xpY2s9e3RoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2t9XG4gICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgIG9uUG9pbnRlckNhbmNlbD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICA+XG4gICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICA8L2NhbnZhcz5cbiAgICApO1xuICB9XG5cbiAgcHVibGljIHJlbmRlcigpIHtcbiAgICBjb25zdCB7IHplbk1vZGVFbmFibGVkLCB2aWV3TW9kZUVuYWJsZWQgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICBjb25zdCB7XG4gICAgICBvbkNvbGxhYkJ1dHRvbkNsaWNrLFxuICAgICAgcmVuZGVyVG9wUmlnaHRVSSxcbiAgICAgIHJlbmRlckZvb3RlcixcbiAgICAgIHJlbmRlckN1c3RvbVN0YXRzLFxuICAgIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3NOYW1lPXtjbHN4KFwiZXhjYWxpZHJhdyBleGNhbGlkcmF3LWNvbnRhaW5lclwiLCB7XG4gICAgICAgICAgXCJleGNhbGlkcmF3LS12aWV3LW1vZGVcIjogdmlld01vZGVFbmFibGVkLFxuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tbW9iaWxlXCI6IHRoaXMuaXNNb2JpbGUsXG4gICAgICAgIH0pfVxuICAgICAgICByZWY9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZn1cbiAgICAgICAgb25Ecm9wPXt0aGlzLmhhbmRsZUFwcE9uRHJvcH1cbiAgICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICAgIG9uS2V5RG93bj17XG4gICAgICAgICAgdGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5ID8gdW5kZWZpbmVkIDogdGhpcy5vbktleURvd25cbiAgICAgICAgfVxuICAgICAgPlxuICAgICAgICA8RXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgICB2YWx1ZT17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWV9XG4gICAgICAgID5cbiAgICAgICAgICA8SXNNb2JpbGVDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLmlzTW9iaWxlfT5cbiAgICAgICAgICAgIDxMYXllclVJXG4gICAgICAgICAgICAgIGNhbnZhcz17dGhpcy5jYW52YXN9XG4gICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICBmaWxlcz17dGhpcy5maWxlc31cbiAgICAgICAgICAgICAgc2V0QXBwU3RhdGU9e3RoaXMuc2V0QXBwU3RhdGV9XG4gICAgICAgICAgICAgIGFjdGlvbk1hbmFnZXI9e3RoaXMuYWN0aW9uTWFuYWdlcn1cbiAgICAgICAgICAgICAgZWxlbWVudHM9e3RoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKX1cbiAgICAgICAgICAgICAgb25Db2xsYWJCdXR0b25DbGljaz17b25Db2xsYWJCdXR0b25DbGlja31cbiAgICAgICAgICAgICAgb25Mb2NrVG9nZ2xlPXt0aGlzLnRvZ2dsZUxvY2t9XG4gICAgICAgICAgICAgIG9uSW5zZXJ0RWxlbWVudHM9eyhlbGVtZW50cykgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFwiY2VudGVyXCIsXG4gICAgICAgICAgICAgICAgICBmaWxlczogbnVsbCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkPXt6ZW5Nb2RlRW5hYmxlZH1cbiAgICAgICAgICAgICAgdG9nZ2xlWmVuTW9kZT17dGhpcy50b2dnbGVaZW5Nb2RlfVxuICAgICAgICAgICAgICBsYW5nQ29kZT17Z2V0TGFuZ3VhZ2UoKS5jb2RlfVxuICAgICAgICAgICAgICBpc0NvbGxhYm9yYXRpbmc9e3RoaXMucHJvcHMuaXNDb2xsYWJvcmF0aW5nIHx8IGZhbHNlfVxuICAgICAgICAgICAgICByZW5kZXJUb3BSaWdodFVJPXtyZW5kZXJUb3BSaWdodFVJfVxuICAgICAgICAgICAgICByZW5kZXJDdXN0b21Gb290ZXI9e3JlbmRlckZvb3Rlcn1cbiAgICAgICAgICAgICAgdmlld01vZGVFbmFibGVkPXt2aWV3TW9kZUVuYWJsZWR9XG4gICAgICAgICAgICAgIHNob3dFeGl0WmVuTW9kZUJ0bj17XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHM/Lnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgemVuTW9kZUVuYWJsZWRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzaG93VGhlbWVCdG49e1xuICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzPy50aGVtZSA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmNhbnZhc0FjdGlvbnMudGhlbWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsaWJyYXJ5UmV0dXJuVXJsPXt0aGlzLnByb3BzLmxpYnJhcnlSZXR1cm5Vcmx9XG4gICAgICAgICAgICAgIFVJT3B0aW9ucz17dGhpcy5wcm9wcy5VSU9wdGlvbnN9XG4gICAgICAgICAgICAgIGZvY3VzQ29udGFpbmVyPXt0aGlzLmZvY3VzQ29udGFpbmVyfVxuICAgICAgICAgICAgICBsaWJyYXJ5PXt0aGlzLmxpYnJhcnl9XG4gICAgICAgICAgICAgIGlkPXt0aGlzLmlkfVxuICAgICAgICAgICAgICBvbkltYWdlQWN0aW9uPXt0aGlzLm9uSW1hZ2VBY3Rpb259XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJleGNhbGlkcmF3LXRleHRFZGl0b3JDb250YWluZXJcIiAvPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJleGNhbGlkcmF3LWNvbnRleHRNZW51Q29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLnNob3dTdGF0cyAmJiAoXG4gICAgICAgICAgICAgIDxTdGF0c1xuICAgICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgIGVsZW1lbnRzPXt0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCl9XG4gICAgICAgICAgICAgICAgb25DbG9zZT17dGhpcy50b2dnbGVTdGF0c31cbiAgICAgICAgICAgICAgICByZW5kZXJDdXN0b21TdGF0cz17cmVuZGVyQ3VzdG9tU3RhdHN9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge3RoaXMuc3RhdGUudG9hc3RNZXNzYWdlICE9PSBudWxsICYmIChcbiAgICAgICAgICAgICAgPFRvYXN0XG4gICAgICAgICAgICAgICAgbWVzc2FnZT17dGhpcy5zdGF0ZS50b2FzdE1lc3NhZ2V9XG4gICAgICAgICAgICAgICAgY2xlYXJUb2FzdD17dGhpcy5jbGVhclRvYXN0fVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxtYWluPnt0aGlzLnJlbmRlckNhbnZhcygpfTwvbWFpbj5cbiAgICAgICAgICA8L0lzTW9iaWxlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgPC9FeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZm9jdXNDb250YWluZXI6IEFwcENsYXNzUHJvcGVydGllc1tcImZvY3VzQ29udGFpbmVyXCJdID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnByb3BzLmF1dG9Gb2N1cykge1xuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmZvY3VzKCk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50cyA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpO1xuICB9O1xuXG4gIHByaXZhdGUgc3luY0FjdGlvblJlc3VsdCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoYWN0aW9uUmVzdWx0OiBBY3Rpb25SZXN1bHQpID0+IHtcbiAgICAgIGlmICh0aGlzLnVubW91bnRlZCB8fCBhY3Rpb25SZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGVkaXRpbmdFbGVtZW50OiBBcHBTdGF0ZVtcImVkaXRpbmdFbGVtZW50XCJdIHwgbnVsbCA9IG51bGw7XG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKSB7XG4gICAgICAgIGFjdGlvblJlc3VsdC5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudD8uaWQgPT09IGVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgIT09IGVsZW1lbnQgJiZcbiAgICAgICAgICAgIGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhhY3Rpb25SZXN1bHQuZWxlbWVudHMpO1xuICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmZpbGVzKSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSBhY3Rpb25SZXN1bHQucmVwbGFjZUZpbGVzXG4gICAgICAgICAgPyBhY3Rpb25SZXN1bHQuZmlsZXNcbiAgICAgICAgICA6IHsgLi4udGhpcy5maWxlcywgLi4uYWN0aW9uUmVzdWx0LmZpbGVzIH07XG4gICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwgZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmlld01vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udmlld01vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgemVuTW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy56ZW5Nb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IGdyaWRTaXplID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uZ3JpZFNpemUgfHwgbnVsbDtcbiAgICAgICAgbGV0IHRoZW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udGhlbWUgfHwgVEhFTUUuTElHSFQ7XG4gICAgICAgIGxldCBuYW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8ubmFtZSA/PyB0aGlzLnN0YXRlLm5hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHplbk1vZGVFbmFibGVkID0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBncmlkU2l6ZSA9IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy50aGVtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHRoZW1lID0gdGhpcy5wcm9wcy50aGVtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5uYW1lICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgbmFtZSA9IHRoaXMucHJvcHMubmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgLy8gdXNpbmcgT2JqZWN0LmFzc2lnbiBpbnN0ZWFkIG9mIHNwcmVhZCB0byBmb29sIFRTIDQuMi4yKyBpbnRvXG4gICAgICAgICAgICAvLyByZWdhcmRpbmcgdGhlIHJlc3VsdGluZyB0eXBlIGFzIG5vdCBjb250YWluaW5nIHVuZGVmaW5lZFxuICAgICAgICAgICAgLy8gKHdoaWNoIHRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbiB3aWxsIG5ldmVyIGNvbnRhaW4pXG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwge30sIHtcbiAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgfHwgYWN0aW9uUmVzdWx0LmFwcFN0YXRlPy5lZGl0aW5nRWxlbWVudCB8fCBudWxsLFxuICAgICAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgICAgICAgICBncmlkU2l6ZSxcbiAgICAgICAgICAgICAgdGhlbWUsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGlmIChhY3Rpb25SZXN1bHQuc3luY0hpc3RvcnkpIHtcbiAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnNldEN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIC8vIExpZmVjeWNsZVxuXG4gIHByaXZhdGUgb25CbHVyID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBwcml2YXRlIG9uVW5sb2FkID0gKCkgPT4ge1xuICAgIHRoaXMub25CbHVyKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRXZlbnQ6IEV2ZW50TGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuXG4gIHByaXZhdGUgb25Gb250TG9hZGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm9uU2NlbmVVcGRhdGVkKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBpbXBvcnRMaWJyYXJ5RnJvbVVybCA9IGFzeW5jICh1cmw6IHN0cmluZywgdG9rZW4/OiBzdHJpbmcgfCBudWxsKSA9PiB7XG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoLmluY2x1ZGVzKFVSTF9IQVNIX0tFWVMuYWRkTGlicmFyeSkpIHtcbiAgICAgIGNvbnN0IGhhc2ggPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5oYXNoLnNsaWNlKDEpKTtcbiAgICAgIGhhc2guZGVsZXRlKFVSTF9IQVNIX0tFWVMuYWRkTGlicmFyeSk7XG4gICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoe30sIEFQUF9OQU1FLCBgIyR7aGFzaC50b1N0cmluZygpfWApO1xuICAgIH0gZWxzZSBpZiAod2luZG93LmxvY2F0aW9uLnNlYXJjaC5pbmNsdWRlcyhVUkxfUVVFUllfS0VZUy5hZGRMaWJyYXJ5KSkge1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpO1xuICAgICAgcXVlcnkuZGVsZXRlKFVSTF9RVUVSWV9LRVlTLmFkZExpYnJhcnkpO1xuICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCBBUFBfTkFNRSwgYD8ke3F1ZXJ5LnRvU3RyaW5nKCl9YCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBhd2FpdCBmZXRjaChkZWNvZGVVUklDb21wb25lbnQodXJsKSk7XG4gICAgICBjb25zdCBibG9iID0gYXdhaXQgcmVxdWVzdC5ibG9iKCk7XG4gICAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZShhd2FpdCBibG9iLnRleHQoKSk7XG4gICAgICBpZiAoIWlzVmFsaWRMaWJyYXJ5KGpzb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICB0b2tlbiA9PT0gdGhpcy5pZCB8fFxuICAgICAgICB3aW5kb3cuY29uZmlybShcbiAgICAgICAgICB0KFwiYWxlcnRzLmNvbmZpcm1BZGRMaWJyYXJ5XCIsIHtcbiAgICAgICAgICAgIG51bVNoYXBlczogKGpzb24ubGlicmFyeUl0ZW1zIHx8IGpzb24ubGlicmFyeSB8fCBbXSkubGVuZ3RoLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5saWJyYXJ5LmltcG9ydExpYnJhcnkoYmxvYiwgXCJwdWJsaXNoZWRcIik7XG4gICAgICAgIC8vIGhhY2sgdG8gcmVyZW5kZXIgdGhlIGxpYnJhcnkgaXRlbXMgYWZ0ZXIgaW1wb3J0XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4pIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogZmFsc2UgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IHRydWUgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgd2luZG93LmFsZXJ0KHQoXCJhbGVydHMuZXJyb3JMb2FkaW5nTGlicmFyeVwiKSk7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHJlc2V0SGlzdG9yeSA9ICgpID0+IHtcbiAgICB0aGlzLmhpc3RvcnkuY2xlYXIoKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzZXRzIHNjZW5lICYgaGlzdG9yeS5cbiAgICogISBEbyBub3QgdXNlIHRvIGNsZWFyIHNjZW5lIHVzZXIgYWN0aW9uICFcbiAgICovXG4gIHByaXZhdGUgcmVzZXRTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAob3B0cz86IHsgcmVzZXRMb2FkaW5nU3RhdGU6IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW10pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldERlZmF1bHRBcHBTdGF0ZSgpLFxuICAgICAgICBpc0xvYWRpbmc6IG9wdHM/LnJlc2V0TG9hZGluZ1N0YXRlID8gZmFsc2UgOiBzdGF0ZS5pc0xvYWRpbmcsXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVNjZW5lID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChcImxhdW5jaFF1ZXVlXCIgaW4gd2luZG93ICYmIFwiTGF1bmNoUGFyYW1zXCIgaW4gd2luZG93KSB7XG4gICAgICAod2luZG93IGFzIGFueSkubGF1bmNoUXVldWUuc2V0Q29uc3VtZXIoXG4gICAgICAgIGFzeW5jIChsYXVuY2hQYXJhbXM6IHsgZmlsZXM6IGFueVtdIH0pID0+IHtcbiAgICAgICAgICBpZiAoIWxhdW5jaFBhcmFtcy5maWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZmlsZUhhbmRsZSA9IGxhdW5jaFBhcmFtcy5maWxlc1swXTtcbiAgICAgICAgICBjb25zdCBibG9iOiBCbG9iID0gYXdhaXQgZmlsZUhhbmRsZS5nZXRGaWxlKCk7XG4gICAgICAgICAgYmxvYi5oYW5kbGUgPSBmaWxlSGFuZGxlO1xuICAgICAgICAgIGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgIGJsb2IsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoc2NlbmUpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgICAgICAgLi4uKHNjZW5lLmFwcFN0YXRlIHx8IHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiBmYWxzZSwgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgfVxuICAgIGxldCBpbml0aWFsRGF0YSA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGluaXRpYWxEYXRhID0gKGF3YWl0IHRoaXMucHJvcHMuaW5pdGlhbERhdGEpIHx8IG51bGw7XG4gICAgICBpZiAoaW5pdGlhbERhdGE/LmxpYnJhcnlJdGVtcykge1xuICAgICAgICB0aGlzLmxpYnJhcnlJdGVtc0Zyb21TdG9yYWdlID0gcmVzdG9yZUxpYnJhcnlJdGVtcyhcbiAgICAgICAgICBpbml0aWFsRGF0YS5saWJyYXJ5SXRlbXMsXG4gICAgICAgICAgXCJ1bnB1Ymxpc2hlZFwiLFxuICAgICAgICApIGFzIExpYnJhcnlJdGVtcztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIGluaXRpYWxEYXRhID0ge1xuICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgIGVycm9yTWVzc2FnZTpcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHxcbiAgICAgICAgICAgIFwiRW5jb3VudGVyZWQgYW4gZXJyb3IgZHVyaW5nIGltcG9ydGluZyBvciByZXN0b3Jpbmcgc2NlbmUgZGF0YVwiLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZSA9IHJlc3RvcmUoaW5pdGlhbERhdGEsIG51bGwsIG51bGwpO1xuXG4gICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgIGVsZW1lbnRUeXBlOlxuICAgICAgICBzY2VuZS5hcHBTdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJpbWFnZVwiXG4gICAgICAgICAgPyBcInNlbGVjdGlvblwiXG4gICAgICAgICAgOiBzY2VuZS5hcHBTdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgfTtcbiAgICBpZiAoaW5pdGlhbERhdGE/LnNjcm9sbFRvQ29udGVudCkge1xuICAgICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAuLi5jYWxjdWxhdGVTY3JvbGxDZW50ZXIoXG4gICAgICAgICAgc2NlbmUuZWxlbWVudHMsXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAgICAgICB3aWR0aDogdGhpcy5zdGF0ZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5zdGF0ZS5oZWlnaHQsXG4gICAgICAgICAgICBvZmZzZXRUb3A6IHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICAgICAgb2Zmc2V0TGVmdDogdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgLi4uc2NlbmUsXG4gICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBsaWJyYXJ5VXJsID1cbiAgICAgIC8vIGN1cnJlbnRcbiAgICAgIG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLmhhc2guc2xpY2UoMSkpLmdldChcbiAgICAgICAgVVJMX0hBU0hfS0VZUy5hZGRMaWJyYXJ5LFxuICAgICAgKSB8fFxuICAgICAgLy8gbGVnYWN5LCBrZXB0IGZvciBjb21wYXQgcmVhc29uc1xuICAgICAgbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKS5nZXQoXG4gICAgICAgIFVSTF9RVUVSWV9LRVlTLmFkZExpYnJhcnksXG4gICAgICApO1xuXG4gICAgaWYgKGxpYnJhcnlVcmwpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW1wb3J0TGlicmFyeUZyb21VcmwobGlicmFyeVVybCk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZS5jb250YWluZXIgPVxuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG5cbiAgICBpZiAoXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLlRFU1QgfHxcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuREVWRUxPUE1FTlRcbiAgICApIHtcbiAgICAgIGNvbnN0IHNldFN0YXRlID0gdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICAgICAgc3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBzZXRTdGF0ZToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogKC4uLmFyZ3M6IFBhcmFtZXRlcnM8dHlwZW9mIHNldFN0YXRlPikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoLi4uYXJncyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYXBwOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLFxuICAgICAgICB9LFxuICAgICAgICBoaXN0b3J5OiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLmhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLmFkZENhbGxiYWNrKHRoaXMub25TY2VuZVVwZGF0ZWQpO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcblxuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cblxuICAgIGlmIChcIlJlc2l6ZU9ic2VydmVyXCIgaW4gd2luZG93ICYmIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgIC8vIGNvbXB1dGUgaXNNb2JpbGUgc3RhdGVcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID1cbiAgICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMuaXNNb2JpbGUgPVxuICAgICAgICAgIHdpZHRoIDwgTVFfTUFYX1dJRFRIX1BPUlRSQUlUIHx8XG4gICAgICAgICAgKGhlaWdodCA8IE1RX01BWF9IRUlHSFRfTEFORFNDQVBFICYmIHdpZHRoIDwgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSk7XG4gICAgICAgIC8vIHJlZnJlc2ggb2Zmc2V0c1xuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy51cGRhdGVET01SZWN0KCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/Lm9ic2VydmUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH0gZWxzZSBpZiAod2luZG93Lm1hdGNoTWVkaWEpIHtcbiAgICAgIGNvbnN0IG1lZGlhUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtYXgtd2lkdGg6ICR7TVFfTUFYX1dJRFRIX1BPUlRSQUlUfXB4KSwgKG1heC1oZWlnaHQ6ICR7TVFfTUFYX0hFSUdIVF9MQU5EU0NBUEV9cHgpIGFuZCAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9MQU5EU0NBUEV9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gKCkgPT4gKHRoaXMuaXNNb2JpbGUgPSBtZWRpYVF1ZXJ5Lm1hdGNoZXMpO1xuICAgICAgbWVkaWFRdWVyeS5hZGRMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXIgPSAoKSA9PiBtZWRpYVF1ZXJ5LnJlbW92ZUxpc3RlbmVyKGhhbmRsZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaC5zbGljZSgxKSk7XG5cbiAgICBpZiAoc2VhcmNoUGFyYW1zLmhhcyhcIndlYi1zaGFyZS10YXJnZXRcIikpIHtcbiAgICAgIC8vIE9idGFpbiBhIGZpbGUgdGhhdCB3YXMgc2hhcmVkIHZpYSB0aGUgV2ViIFNoYXJlIFRhcmdldCBBUEkuXG4gICAgICB0aGlzLnJlc3RvcmVGaWxlRnJvbVNoYXJlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCh0aGlzLmluaXRpYWxpemVTY2VuZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgIHRoaXMuZmlsZXMgPSB7fTtcbiAgICB0aGlzLmltYWdlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy51bm1vdW50ZWQgPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNjZW5lLmRlc3Ryb3koKTtcbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICB9XG5cbiAgcHJpdmF0ZSBvblJlc2l6ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgdGhpcy5zY2VuZVxuICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcj8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULlNDUk9MTCxcbiAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIHRoaXMub25LZXlEb3duLCBmYWxzZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULk1PVVNFX01PVkUsXG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbixcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgdGhpcy5vbktleVVwKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5SRVNJWkUsIHRoaXMub25SZXNpemUsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5VTkxPQUQsIHRoaXMub25VbmxvYWQsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0aGlzLm9uQmx1ciwgZmFsc2UpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkRSQUdfT1ZFUiwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5EUk9QLCB0aGlzLmRpc2FibGVFdmVudCwgZmFsc2UpO1xuXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgdGhpcy5kZXRhY2hJc01vYmlsZU1xSGFuZGxlcj8uKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEV2ZW50TGlzdGVuZXJzKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRoaXMucmVtb3ZlUG9pbnRlcik7IC8vICMzNTUzXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DT1BZLCB0aGlzLm9uQ29weSk7XG4gICAgaWYgKHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSkge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIH1cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCB0aGlzLm9uS2V5VXAsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuTU9VU0VfTU9WRSxcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uLFxuICAgICk7XG4gICAgLy8gcmVyZW5kZXIgdGV4dCBlbGVtZW50cyBvbiBmb250IGxvYWQgdG8gZml4ICM2MzcgJiYgIzE1NTNcbiAgICBkb2N1bWVudC5mb250cz8uYWRkRXZlbnRMaXN0ZW5lcj8uKFwibG9hZGluZ2RvbmVcIiwgdGhpcy5vbkZvbnRMb2FkZWQpO1xuICAgIC8vIFNhZmFyaS1vbmx5IGRlc2t0b3AgcGluY2ggem9vbVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX1NUQVJULFxuICAgICAgdGhpcy5vbkdlc3R1cmVTdGFydCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0NIQU5HRSxcbiAgICAgIHRoaXMub25HZXN0dXJlQ2hhbmdlIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfRU5ELFxuICAgICAgdGhpcy5vbkdlc3R1cmVFbmQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIGlmICh0aGlzLnByb3BzLmRldGVjdFNjcm9sbCkge1xuICAgICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lciA9IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyKFxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICApO1xuICAgICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgICApO1xuICAgIH1cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5SRVNJWkUsIHRoaXMub25SZXNpemUsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5VTkxPQUQsIHRoaXMub25VbmxvYWQsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0aGlzLm9uQmx1ciwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkRSQUdfT1ZFUiwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5EUk9QLCB0aGlzLmRpc2FibGVFdmVudCwgZmFsc2UpO1xuICB9XG5cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogQXBwUHJvcHMsIHByZXZTdGF0ZTogQXBwU3RhdGUpIHtcbiAgICBpZiAocHJldlByb3BzLmxhbmdDb2RlICE9PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxhbmd1YWdlKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlld01vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMudmlld01vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2U3RhdGUudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHplbk1vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy50aGVtZSAhPT0gdGhpcy5wcm9wcy50aGVtZSAmJiB0aGlzLnByb3BzLnRoZW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdGhlbWU6IHRoaXMucHJvcHMudGhlbWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZ3JpZFNpemU6IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb3BzLm5hbWUgJiYgcHJldlByb3BzLm5hbWUgIT09IHRoaXMucHJvcHMubmFtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG5hbWU6IHRoaXMucHJvcHMubmFtZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jbGFzc0xpc3QudG9nZ2xlKFxuICAgICAgXCJ0aGVtZS0tZGFya1wiLFxuICAgICAgdGhpcy5zdGF0ZS50aGVtZSA9PT0gXCJkYXJrXCIsXG4gICAgKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF1cbiAgICApIHtcbiAgICAgIC8vIGRlZmVyIHNvIHRoYXQgdGhlIGNvbW1pdFRvSGlzdG9yeSBmbGFnIGlzbid0IHJlc2V0IHZpYSBjdXJyZW50IHVwZGF0ZVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gcHJldlN0YXRlO1xuICAgIGlmIChcbiAgICAgIHByZXZTdGF0ZS5lbGVtZW50VHlwZSAhPT0gdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAmJlxuICAgICAgbXVsdGlFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgIGlzQmluZGluZ0VsZW1lbnQobXVsdGlFbGVtZW50KVxuICAgICkge1xuICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEF0SW5kZXhHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgICAgIC0xLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnNvckJ1dHRvbjoge1xuICAgICAgW2lkOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgfSA9IHt9O1xuICAgIGNvbnN0IHBvaW50ZXJWaWV3cG9ydENvb3JkczogUmVuZGVyQ29uZmlnW1wicmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzXCJdID1cbiAgICAgIHt9O1xuICAgIGNvbnN0IHJlbW90ZVNlbGVjdGVkRWxlbWVudElkczogUmVuZGVyQ29uZmlnW1wicmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzXCJdID1cbiAgICAgIHt9O1xuICAgIGNvbnN0IHBvaW50ZXJVc2VybmFtZXM6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGNvbnN0IHBvaW50ZXJVc2VyU3RhdGVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICB0aGlzLnN0YXRlLmNvbGxhYm9yYXRvcnMuZm9yRWFjaCgodXNlciwgc29ja2V0SWQpID0+IHtcbiAgICAgIGlmICh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIE9iamVjdC5rZXlzKHVzZXIuc2VsZWN0ZWRFbGVtZW50SWRzKSkge1xuICAgICAgICAgIGlmICghKGlkIGluIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0gPSBbXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzW2lkXS5wdXNoKHNvY2tldElkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCF1c2VyLnBvaW50ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXIudXNlcm5hbWUpIHtcbiAgICAgICAgcG9pbnRlclVzZXJuYW1lc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJuYW1lO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXIudXNlclN0YXRlKSB7XG4gICAgICAgIHBvaW50ZXJVc2VyU3RhdGVzW3NvY2tldElkXSA9IHVzZXIudXNlclN0YXRlO1xuICAgICAgfVxuICAgICAgcG9pbnRlclZpZXdwb3J0Q29vcmRzW3NvY2tldElkXSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAge1xuICAgICAgICAgIHNjZW5lWDogdXNlci5wb2ludGVyLngsXG4gICAgICAgICAgc2NlbmVZOiB1c2VyLnBvaW50ZXIueSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBjdXJzb3JCdXR0b25bc29ja2V0SWRdID0gdXNlci5idXR0b247XG4gICAgfSk7XG4gICAgY29uc3QgcmVuZGVyaW5nRWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCkuZmlsdGVyKChlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoaXNJbWFnZUVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIC8vIG5vdCBwbGFjZWQgb24gY2FudmFzIHlldCAoYnV0IGluIGVsZW1lbnRzIGFycmF5KVxuICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCAmJlxuICAgICAgICAgIGVsZW1lbnQuaWQgPT09IHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudC5pZFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGRvbid0IHJlbmRlciB0ZXh0IGVsZW1lbnQgdGhhdCdzIGJlaW5nIGN1cnJlbnRseSBlZGl0ZWQgKGl0J3NcbiAgICAgIC8vIHJlbmRlcmVkIG9uIHJlbW90ZSBvbmx5KVxuICAgICAgcmV0dXJuIChcbiAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgfHxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC50eXBlICE9PSBcInRleHRcIiB8fFxuICAgICAgICBlbGVtZW50LmlkICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50LmlkXG4gICAgICApO1xuICAgIH0pO1xuICAgIGNvbnN0IHsgYXRMZWFzdE9uZVZpc2libGVFbGVtZW50LCBzY3JvbGxCYXJzIH0gPSByZW5kZXJTY2VuZShcbiAgICAgIHJlbmRlcmluZ0VsZW1lbnRzLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIHRoaXMuc3RhdGUuc2VsZWN0aW9uRWxlbWVudCxcbiAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgdGhpcy5yYyEsXG4gICAgICB0aGlzLmNhbnZhcyEsXG4gICAgICB7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZLFxuICAgICAgICB2aWV3QmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLnZpZXdCYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIHpvb206IHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgcmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzOiBwb2ludGVyVmlld3BvcnRDb29yZHMsXG4gICAgICAgIHJlbW90ZVBvaW50ZXJCdXR0b246IGN1cnNvckJ1dHRvbixcbiAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICByZW1vdGVQb2ludGVyVXNlcm5hbWVzOiBwb2ludGVyVXNlcm5hbWVzLFxuICAgICAgICByZW1vdGVQb2ludGVyVXNlclN0YXRlczogcG9pbnRlclVzZXJTdGF0ZXMsXG4gICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdGhpcy5zdGF0ZS5zaG91bGRDYWNoZUlnbm9yZVpvb20sXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICAgIGlzRXhwb3J0aW5nOiBmYWxzZSxcbiAgICAgICAgcmVuZGVyU2Nyb2xsYmFyczogIXRoaXMuaXNNb2JpbGUsXG4gICAgICB9LFxuICAgICk7XG4gICAgaWYgKHNjcm9sbEJhcnMpIHtcbiAgICAgIGN1cnJlbnRTY3JvbGxCYXJzID0gc2Nyb2xsQmFycztcbiAgICB9XG4gICAgY29uc3Qgc2Nyb2xsZWRPdXRzaWRlID1cbiAgICAgIC8vIGhpZGUgd2hlbiBlZGl0aW5nIHRleHRcbiAgICAgIGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgPyBmYWxzZVxuICAgICAgICA6ICFhdExlYXN0T25lVmlzaWJsZUVsZW1lbnQgJiYgcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoID4gMDtcbiAgICBpZiAodGhpcy5zdGF0ZS5zY3JvbGxlZE91dHNpZGUgIT09IHNjcm9sbGVkT3V0c2lkZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNjcm9sbGVkT3V0c2lkZSB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmhpc3RvcnkucmVjb3JkKHRoaXMuc3RhdGUsIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkpO1xuXG4gICAgdGhpcy5zY2hlZHVsZUltYWdlUmVmcmVzaCgpO1xuXG4gICAgLy8gRG8gbm90IG5vdGlmeSBjb25zdW1lcnMgaWYgd2UncmUgc3RpbGwgbG9hZGluZyB0aGUgc2NlbmUuIEFtb25nIG90aGVyXG4gICAgLy8gcG90ZW50aWFsIGlzc3VlcywgdGhpcyBmaXhlcyBhIGNhc2Ugd2hlcmUgdGhlIHRhYiBpc24ndCBmb2N1c2VkIGR1cmluZ1xuICAgIC8vIGluaXQsIHdoaWNoIHdvdWxkIHRyaWdnZXIgb25DaGFuZ2Ugd2l0aCBlbXB0eSBlbGVtZW50cywgd2hpY2ggd291bGQgdGhlblxuICAgIC8vIG92ZXJyaWRlIHdoYXRldmVyIGlzIGluIGxvY2FsU3RvcmFnZSBjdXJyZW50bHkuXG4gICAgaWYgKCF0aGlzLnN0YXRlLmlzTG9hZGluZykge1xuICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZT8uKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmZpbGVzLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uU2Nyb2xsID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGNvbnN0IHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSB0aGlzLmdldENhbnZhc09mZnNldHMoKTtcbiAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgaWYgKHN0YXRlLm9mZnNldExlZnQgPT09IG9mZnNldExlZnQgJiYgc3RhdGUub2Zmc2V0VG9wID09PSBvZmZzZXRUb3ApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBvZmZzZXRUb3AsIG9mZnNldExlZnQgfTtcbiAgICB9KTtcbiAgfSwgU0NST0xMX1RJTUVPVVQpO1xuXG4gIC8vIENvcHkvcGFzdGVcblxuICBwcml2YXRlIG9uQ3V0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1dEFsbCgpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25Db3B5ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9KTtcblxuICBwcml2YXRlIGN1dEFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25EZWxldGVTZWxlY3RlZCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb3B5QWxsID0gKCkgPT4ge1xuICAgIGNvcHlUb0NsaXBib2FyZCh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUsIHRoaXMuZmlsZXMpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIHJlc2V0VGFwVHdpY2UoKSB7XG4gICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25UYXBTdGFydCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmICghZGlkVGFwVHdpY2UpIHtcbiAgICAgIGRpZFRhcFR3aWNlID0gdHJ1ZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICAgIHRhcHBlZFR3aWNlVGltZXIgPSB3aW5kb3cuc2V0VGltZW91dChcbiAgICAgICAgQXBwLnJlc2V0VGFwVHdpY2UsXG4gICAgICAgIFRBUF9UV0lDRV9USU1FT1VULFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gaW5zZXJ0IHRleHQgb25seSBpZiB3ZSB0YXBwZWQgdHdpY2Ugd2l0aCBhIHNpbmdsZSBmaW5nZXJcbiAgICAvLyBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSB3aWxsIGFsc28gcHJldmVudCBpbnNlcnRpbmcgdGV4dCB3aGVuIHVzZXIncyB6b29taW5nXG4gICAgaWYgKGRpZFRhcFR3aWNlICYmIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb25zdCBbdG91Y2hdID0gZXZlbnQudG91Y2hlcztcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHRoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2soe1xuICAgICAgICBjbGllbnRYOiB0b3VjaC5jbGllbnRYLFxuICAgICAgICBjbGllbnRZOiB0b3VjaC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvblRhcEVuZCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5wcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHBhc3RlRnJvbUNsaXBib2FyZCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICBhc3luYyAoZXZlbnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbCkgPT4ge1xuICAgICAgLy8gIzY4NlxuICAgICAgY29uc3QgdGFyZ2V0ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IGlzRXhjYWxpZHJhd0FjdGl2ZSA9XG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jb250YWlucyh0YXJnZXQpO1xuICAgICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBlbGVtZW50VW5kZXJDdXJzb3IgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGN1cnNvclgsIGN1cnNvclkpO1xuICAgICAgaWYgKFxuICAgICAgICAvLyBpZiBubyBDbGlwYm9hcmRFdmVudCBzdXBwbGllZCwgYXNzdW1lIHdlJ3JlIHBhc3RpbmcgdmlhIGNvbnRleHRNZW51XG4gICAgICAgIC8vIHRodXMgdGhlc2UgY2hlY2tzIGRvbid0IG1ha2Ugc2Vuc2VcbiAgICAgICAgZXZlbnQgJiZcbiAgICAgICAgKCEoZWxlbWVudFVuZGVyQ3Vyc29yIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHx8XG4gICAgICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG11c3QgYmUgY2FsbGVkIGluIHRoZSBzYW1lIGZyYW1lICh0aHVzIGJlZm9yZSBhbnkgYXdhaXRzKSBhcyB0aGUgcGFzdGVcbiAgICAgIC8vIGV2ZW50IGVsc2Ugc29tZSBicm93c2VycyAoRkYuLi4pIHdpbGwgY2xlYXIgdGhlIGNsaXBib2FyZERhdGFcbiAgICAgIC8vIChzb21ldGhpbmcgc29tZXRoaW5nIHNlY3VyaXR5KVxuICAgICAgbGV0IGZpbGUgPSBldmVudD8uY2xpcGJvYXJkRGF0YT8uZmlsZXNbMF07XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBwYXJzZUNsaXBib2FyZChldmVudCk7XG5cbiAgICAgIGlmICghZmlsZSAmJiBkYXRhLnRleHQpIHtcbiAgICAgICAgY29uc3Qgc3RyaW5nID0gZGF0YS50ZXh0LnRyaW0oKTtcbiAgICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKFwiPHN2Z1wiKSAmJiBzdHJpbmcuZW5kc1dpdGgoXCI8L3N2Zz5cIikpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgU1ZHIHZhbGlkYXRpb24vbm9ybWFsaXphdGlvbiB3aGljaCB3aWxsIGJlIGRvbmUgZHVyaW5nIGltYWdlXG4gICAgICAgICAgLy8gaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICBmaWxlID0gU1ZHU3RyaW5nVG9GaWxlKHN0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpKSB7XG4gICAgICAgIGNvbnN0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHsgc2NlbmVYLCBzY2VuZVkgfSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgZmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5wcm9wcy5vblBhc3RlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3BzLm9uUGFzdGUoZGF0YSwgZXZlbnQpKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRhdGEuZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGRhdGEuZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnNwcmVhZHNoZWV0KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHBhc3RlRGlhbG9nOiB7XG4gICAgICAgICAgICBkYXRhOiBkYXRhLnNwcmVhZHNoZWV0LFxuICAgICAgICAgICAgc2hvd246IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgZWxlbWVudHM6IGRhdGEuZWxlbWVudHMsXG4gICAgICAgICAgZmlsZXM6IGRhdGEuZmlsZXMgfHwgbnVsbCxcbiAgICAgICAgICBwb3NpdGlvbjogXCJjdXJzb3JcIixcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEudGV4dCkge1xuICAgICAgICB0aGlzLmFkZFRleHRGcm9tUGFzdGUoZGF0YS50ZXh0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VsZWN0U2hhcGVUb29sKFwic2VsZWN0aW9uXCIpO1xuICAgICAgZXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5ID0gKG9wdHM6IHtcbiAgICBlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXTtcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsO1xuICAgIHBvc2l0aW9uOiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0gfCBcImN1cnNvclwiIHwgXCJjZW50ZXJcIjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gcmVzdG9yZUVsZW1lbnRzKG9wdHMuZWxlbWVudHMsIG51bGwpO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhlbGVtZW50cyk7XG5cbiAgICBjb25zdCBlbGVtZW50c0NlbnRlclggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSAvIDI7XG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJZID0gZGlzdGFuY2UobWluWSwgbWF4WSkgLyAyO1xuXG4gICAgY29uc3QgY2xpZW50WCA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WFxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JYXG4gICAgICAgIDogdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgY29uc3QgY2xpZW50WSA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WVxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JZXG4gICAgICAgIDogdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3QgZHggPSB4IC0gZWxlbWVudHNDZW50ZXJYO1xuICAgIGNvbnN0IGR5ID0geSAtIGVsZW1lbnRzQ2VudGVyWTtcbiAgICBjb25zdCBncm91cElkTWFwID0gbmV3IE1hcCgpO1xuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoZHgsIGR5LCB0aGlzLnN0YXRlLmdyaWRTaXplKTtcblxuICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgbmV3RWxlbWVudHMgPSBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkdXBsaWNhdGVFbGVtZW50KFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkLFxuICAgICAgICBncm91cElkTWFwLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICB7XG4gICAgICAgICAgeDogZWxlbWVudC54ICsgZ3JpZFggLSBtaW5YLFxuICAgICAgICAgIHk6IGVsZW1lbnQueSArIGdyaWRZIC0gbWluWSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBuZXdFbGVtZW50LmlkKTtcbiAgICAgIHJldHVybiBuZXdFbGVtZW50O1xuICAgIH0pO1xuICAgIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24obmV3RWxlbWVudHMsIGVsZW1lbnRzLCBvbGRJZFRvRHVwbGljYXRlZElkKTtcbiAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgLi4ubmV3RWxlbWVudHMsXG4gICAgXTtcbiAgICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24obmV4dEVsZW1lbnRzLCBlbGVtZW50cywgb2xkSWRUb0R1cGxpY2F0ZWRJZCk7XG5cbiAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4ub3B0cy5maWxlcyB9O1xuICAgIH1cblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRFbGVtZW50cyk7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB7XG4gICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICBpc0xpYnJhcnlPcGVuOiBmYWxzZSxcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld0VsZW1lbnRzLnJlZHVjZSgobWFwLCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiAhZWxlbWVudC5jb250YWluZXJJZCkge1xuICAgICAgICAgICAgICBtYXBbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgICAgICB9LCB7fSBhcyBhbnkpLFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICApLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLnNlbGVjdFNoYXBlVG9vbChcInNlbGVjdGlvblwiKTtcbiAgfTtcblxuICBwcml2YXRlIGFkZFRleHRGcm9tUGFzdGUodGV4dDogYW55KSB7XG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdUZXh0RWxlbWVudCh7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgdGV4dCxcbiAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIHRleHRBbGlnbjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVRleHRBbGlnbixcbiAgICAgIHZlcnRpY2FsQWxpZ246IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgfVxuXG4gIC8vIENvbGxhYm9yYXRpb25cblxuICBzZXRBcHBTdGF0ZSA9IChvYmo6IGFueSkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUob2JqKTtcbiAgfTtcblxuICByZW1vdmVQb2ludGVyID0gKGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTEVsZW1lbnQ+IHwgUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgLy8gcmVtb3ZlIHRvdWNoIGhhbmRsZXIgZm9yIGNvbnRleHQgbWVudSBvbiB0b3VjaCBkZXZpY2VzXG4gICAgaWYgKGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIgJiYgdG91Y2hUaW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICAgIHRvdWNoVGltZW91dCA9IDA7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXN0dXJlLnBvaW50ZXJzLmRlbGV0ZShldmVudC5wb2ludGVySWQpO1xuICB9O1xuXG4gIHRvZ2dsZUxvY2sgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbGVtZW50TG9ja2VkOiAhcHJldlN0YXRlLmVsZW1lbnRMb2NrZWQsXG4gICAgICAgIGVsZW1lbnRUeXBlOiBwcmV2U3RhdGUuZWxlbWVudExvY2tlZFxuICAgICAgICAgID8gXCJzZWxlY3Rpb25cIlxuICAgICAgICAgIDogcHJldlN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICB0b2dnbGVaZW5Nb2RlID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvblRvZ2dsZVplbk1vZGUpO1xuICB9O1xuXG4gIHRvZ2dsZVN0YXRzID0gKCkgPT4ge1xuICAgIGlmICghdGhpcy5zdGF0ZS5zaG93U3RhdHMpIHtcbiAgICAgIHRyYWNrRXZlbnQoXCJkaWFsb2dcIiwgXCJzdGF0c1wiKTtcbiAgICB9XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uVG9nZ2xlU3RhdHMpO1xuICB9O1xuXG4gIHNjcm9sbFRvQ29udGVudCA9IChcbiAgICB0YXJnZXQ6XG4gICAgICB8IEV4Y2FsaWRyYXdFbGVtZW50XG4gICAgICB8IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10gPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICBBcnJheS5pc0FycmF5KHRhcmdldCkgPyB0YXJnZXQgOiBbdGFyZ2V0XSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICApLFxuICAgIH0pO1xuICB9O1xuXG4gIGNsZWFyVG9hc3QgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHRvYXN0TWVzc2FnZTogbnVsbCB9KTtcbiAgfTtcblxuICBzZXRUb2FzdE1lc3NhZ2UgPSAodG9hc3RNZXNzYWdlOiBzdHJpbmcpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgdG9hc3RNZXNzYWdlIH0pO1xuICB9O1xuXG4gIHJlc3RvcmVGaWxlRnJvbVNoYXJlID0gYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB3ZWJTaGFyZVRhcmdldENhY2hlID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpO1xuXG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5tYXRjaChcInNoYXJlZC1maWxlXCIpO1xuICAgICAgaWYgKGZpbGUpIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IGF3YWl0IGZpbGUuYmxvYigpO1xuICAgICAgICB0aGlzLmxvYWRGaWxlVG9DYW52YXMoYmxvYik7XG4gICAgICAgIGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUuZGVsZXRlKFwic2hhcmVkLWZpbGVcIik7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBBUFBfTkFNRSwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKiogYWRkcyBzdXBwbGllZCBmaWxlcyB0byBleGlzdGluZyBmaWxlcyBpbiB0aGUgYXBwU3RhdGUgKi9cbiAgcHVibGljIGFkZEZpbGVzOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSVtcImFkZEZpbGVzXCJdID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChmaWxlcykgPT4ge1xuICAgICAgY29uc3QgZmlsZXNNYXAgPSBmaWxlcy5yZWR1Y2UoKGFjYywgZmlsZURhdGEpID0+IHtcbiAgICAgICAgYWNjLnNldChmaWxlRGF0YS5pZCwgZmlsZURhdGEpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IE1hcDxGaWxlSWQsIEJpbmFyeUZpbGVEYXRhPigpKTtcblxuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4uT2JqZWN0LmZyb21FbnRyaWVzKGZpbGVzTWFwKSB9O1xuXG4gICAgICAvLyBidW1wIHZlcnNpb25zIGZvciBlbGVtZW50cyB0aGF0IHJlZmVyZW5jZSBhZGRlZCBmaWxlcyBzbyB0aGF0XG4gICAgICAvLyB3ZS9ob3N0IGFwcHMgY2FuIGRldGVjdCB0aGUgY2hhbmdlLCBhbmQgaW52YWxpZGF0ZSB0aGUgaW1hZ2UgJiBzaGFwZVxuICAgICAgLy8gY2FjaGVcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgZmlsZXNNYXAuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZGVsZXRlKGVsZW1lbnQuZmlsZUlkKTtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgIGJ1bXBWZXJzaW9uKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcblxuICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICB9LFxuICApO1xuXG4gIHB1YmxpYyB1cGRhdGVTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICA8SyBleHRlbmRzIGtleW9mIEFwcFN0YXRlPihzY2VuZURhdGE6IHtcbiAgICAgIGVsZW1lbnRzPzogU2NlbmVEYXRhW1wiZWxlbWVudHNcIl07XG4gICAgICBhcHBTdGF0ZT86IFBpY2s8QXBwU3RhdGUsIEs+IHwgbnVsbDtcbiAgICAgIGNvbGxhYm9yYXRvcnM/OiBTY2VuZURhdGFbXCJjb2xsYWJvcmF0b3JzXCJdO1xuICAgICAgY29tbWl0VG9IaXN0b3J5PzogU2NlbmVEYXRhW1wiY29tbWl0VG9IaXN0b3J5XCJdO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChzY2VuZURhdGEuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5hcHBTdGF0ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHNjZW5lRGF0YS5hcHBTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoc2NlbmVEYXRhLmVsZW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5jb2xsYWJvcmF0b3JzKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb2xsYWJvcmF0b3JzOiBzY2VuZURhdGEuY29sbGFib3JhdG9ycyB9KTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25TY2VuZVVwZGF0ZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjdXJzb3JYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGN1cnNvclkgPSBldmVudC5jbGllbnRZO1xuICAgIH0sXG4gICk7XG5cbiAgLy8gSW5wdXQgaGFuZGxpbmdcblxuICBwcml2YXRlIG9uS2V5RG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IFJlYWN0LktleWJvYXJkRXZlbnQgfCBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBub3JtYWxpemUgYGV2ZW50LmtleWAgd2hlbiBDYXBzTG9jayBpcyBwcmVzc2VkICMyMzcyXG4gICAgICBpZiAoXG4gICAgICAgIFwiUHJveHlcIiBpbiB3aW5kb3cgJiZcbiAgICAgICAgKCghZXZlbnQuc2hpZnRLZXkgJiYgL15bQS1aXSQvLnRlc3QoZXZlbnQua2V5KSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXkgJiYgL15bYS16XSQvLnRlc3QoZXZlbnQua2V5KSkpXG4gICAgICApIHtcbiAgICAgICAgZXZlbnQgPSBuZXcgUHJveHkoZXZlbnQsIHtcbiAgICAgICAgICBnZXQoZXY6IGFueSwgcHJvcCkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBldltwcm9wXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAvLyBmaXggZm9yIFByb3hpZXMgaGlqYWNraW5nIGB0aGlzYFxuICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYmluZChldik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvcCA9PT0gXCJrZXlcIlxuICAgICAgICAgICAgICA/IC8vIENhcHNMb2NrIGludmVydHMgY2FwaXRhbGl6YXRpb24gYmFzZWQgb24gU2hpZnRLZXksIHNvIGludmVydFxuICAgICAgICAgICAgICAgIC8vIGl0IGJhY2tcbiAgICAgICAgICAgICAgICBldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICAgID8gZXYua2V5LnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgICAgICA6IGV2LmtleS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgIDogdmFsdWU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgKGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkgJiYgZXZlbnQua2V5ICE9PSBLRVlTLkVTQ0FQRSkgfHxcbiAgICAgICAgLy8gY2FzZTogdXNpbmcgYXJyb3dzIHRvIG1vdmUgYmV0d2VlbiBidXR0b25zXG4gICAgICAgIChpc0Fycm93S2V5KGV2ZW50LmtleSkgJiYgaXNJbnB1dExpa2UoZXZlbnQudGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUVVFU1RJT05fTUFSSykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzaG93SGVscERpYWxvZzogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmFjdGlvbk1hbmFnZXIuaGFuZGxlS2V5RG93bihldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgdGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmNvZGUgPT09IENPREVTLlpFUk8pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46ICF0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4gfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9XG4gICAgICAgICAgKHRoaXMuc3RhdGUuZ3JpZFNpemUgJiZcbiAgICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICA/IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVFxuICAgICAgICAgICAgICA6IHRoaXMuc3RhdGUuZ3JpZFNpemUpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgPyBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgIDogRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5UKTtcblxuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gdGhpcy5zY2VuZVxuICAgICAgICAgIC5nZXRFbGVtZW50cygpXG4gICAgICAgICAgLmZpbHRlcigoZWxlbWVudCkgPT4gdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbZWxlbWVudC5pZF0pO1xuXG4gICAgICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICAgICAgbGV0IG9mZnNldFkgPSAwO1xuXG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfTEVGVCkge1xuICAgICAgICAgIG9mZnNldFggPSAtc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfUklHSFQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfVVApIHtcbiAgICAgICAgICBvZmZzZXRZID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0RPV04pIHtcbiAgICAgICAgICBvZmZzZXRZID0gc3RlcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICAgICAgeDogZWxlbWVudC54ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgIHk6IGVsZW1lbnQueSArIG9mZnNldFksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHNpbXVsdGFuZW91c2x5VXBkYXRlZDogc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5FTlRFUikge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICFpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcblxuICAgICAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgICAgICBzY2VuZVg6IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMixcbiAgICAgICAgICAgIHNjZW5lWTogc2VsZWN0ZWRFbGVtZW50LnkgKyBzZWxlY3RlZEVsZW1lbnQuaGVpZ2h0IC8gMixcbiAgICAgICAgICAgIHNob3VsZEJpbmQ6IHRydWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICFldmVudC5jdHJsS2V5ICYmXG4gICAgICAgICFldmVudC5hbHRLZXkgJiZcbiAgICAgICAgIWV2ZW50Lm1ldGFLZXkgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgPT09IG51bGxcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzaGFwZSA9IGZpbmRTaGFwZUJ5S2V5KGV2ZW50LmtleSk7XG4gICAgICAgIGlmIChzaGFwZSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0U2hhcGVUb29sKHNoYXBlKTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuUSkge1xuICAgICAgICAgIHRoaXMudG9nZ2xlTG9jaygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFICYmIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBpc0hvbGRpbmdTcGFjZSA9IHRydWU7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkcgfHwgZXZlbnQua2V5ID09PSBLRVlTLlMpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgICAgIXNlbGVjdGVkRWxlbWVudHMubGVuZ3RoXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBldmVudC5rZXkgPT09IEtFWVMuRyAmJlxuICAgICAgICAgIChoYXNCYWNrZ3JvdW5kKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpIHx8XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLnNvbWUoKGVsZW1lbnQpID0+IGhhc0JhY2tncm91bmQoZWxlbWVudC50eXBlKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwiYmFja2dyb3VuZENvbG9yUGlja2VyXCIgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5Qb3B1cDogXCJzdHJva2VDb2xvclBpY2tlclwiIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uS2V5VXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSkge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gICAgfVxuICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKVxuICAgICAgICA/IGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cylcbiAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgfVxuICB9KTtcblxuICBwcml2YXRlIHNlbGVjdFNoYXBlVG9vbChlbGVtZW50VHlwZTogQXBwU3RhdGVbXCJlbGVtZW50VHlwZVwiXSkge1xuICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCBlbGVtZW50VHlwZSk7XG4gICAgfVxuICAgIGlmIChpc1Rvb2xJY29uKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgfVxuICAgIGlmICghaXNMaW5lYXJFbGVtZW50VHlwZShlbGVtZW50VHlwZSkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgfVxuICAgIGlmIChlbGVtZW50VHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICB0aGlzLm9uSW1hZ2VBY3Rpb24oKTtcbiAgICB9XG4gICAgaWYgKGVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZWxlbWVudFR5cGUsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgZWxlbWVudFR5cGUgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkdlc3R1cmVTdGFydCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgIH0pO1xuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICB9KTtcblxuICBwcml2YXRlIG9uR2VzdHVyZUNoYW5nZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAvLyBvbkdlc3R1cmVDaGFuZ2Ugb25seSBoYXMgem9vbSBmYWN0b3IgYnV0IG5vdCB0aGUgY2VudGVyLlxuICAgIC8vIElmIHdlJ3JlIG9uIGlQYWQgb3IgaVBob25lLCB0aGVuIHdlIHJlY29nbml6ZSBtdWx0aS10b3VjaCBhbmQgd2lsbFxuICAgIC8vIHpvb20gaW4gYXQgdGhlIHJpZ2h0IGxvY2F0aW9uIG9uIHRoZSB0b3VjaE1vdmUgaGFuZGxlciBhbHJlYWR5LlxuICAgIC8vIE9uIE1hY2Jvb2ssIHdlIGRvbid0IGhhdmUgdGhvc2UgZXZlbnRzIHNvIHdpbGwgem9vbSBpbiBhdCB0aGVcbiAgICAvLyBjdXJyZW50IGxvY2F0aW9uIGluc3RlYWQuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChpbml0aWFsU2NhbGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pID0+ICh7XG4gICAgICAgIHpvb206IGdldE5ld1pvb20oXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZFpvb20oaW5pdGlhbFNjYWxlICogZXZlbnQuc2NhbGUpLFxuICAgICAgICAgIHpvb20sXG4gICAgICAgICAgeyBsZWZ0OiBvZmZzZXRMZWZ0LCB0b3A6IG9mZnNldFRvcCB9LFxuICAgICAgICAgIHsgeDogY3Vyc29yWCwgeTogY3Vyc29yWSB9LFxuICAgICAgICApLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBvbkdlc3R1cmVFbmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgIH0pO1xuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gbnVsbDtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0V3lzaXd5ZyhcbiAgICBlbGVtZW50OiBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gICAge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQgPSBmYWxzZSxcbiAgICB9OiB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudCA9IChcbiAgICAgIHRleHQ6IHN0cmluZyxcbiAgICAgIG9yaWdpbmFsVGV4dDogc3RyaW5nLFxuICAgICAgaXNEZWxldGVkID0gZmFsc2UsXG4gICAgICB1cGRhdGVEaW1lbnNpb25zID0gZmFsc2UsXG4gICAgKSA9PiB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChfZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChfZWxlbWVudC5pZCA9PT0gZWxlbWVudC5pZCAmJiBpc1RleHRFbGVtZW50KF9lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVRleHRFbGVtZW50KFxuICAgICAgICAgICAgICBfZWxlbWVudCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgICAgaXNEZWxldGVkLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsVGV4dCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdXBkYXRlRGltZW5zaW9ucyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBfZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICBdKTtcbiAgICB9O1xuXG4gICAgdGV4dFd5c2l3eWcoe1xuICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgIGNhbnZhczogdGhpcy5jYW52YXMsXG4gICAgICBnZXRWaWV3cG9ydENvb3JkczogKHgsIHkpID0+IHtcbiAgICAgICAgY29uc3QgeyB4OiB2aWV3cG9ydFgsIHk6IHZpZXdwb3J0WSB9ID0gc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNjZW5lWDogeCxcbiAgICAgICAgICAgIHNjZW5lWTogeSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgdmlld3BvcnRYLCAvLyAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCwgLy8qICgyIC0gdGhpcy5zdGF0ZS56b29tLnZhbHVlKSxcbiAgICAgICAgICB2aWV3cG9ydFksIC8vIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsIC8vKiAoMiAtIHRoaXMuc3RhdGUuem9vbS52YWx1ZSksXG4gICAgICAgIF07XG4gICAgICB9LFxuICAgICAgb25DaGFuZ2U6IHdpdGhCYXRjaGVkVXBkYXRlcygodGV4dCkgPT4ge1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIHRleHQsIGZhbHNlLCAhZWxlbWVudC5jb250YWluZXJJZCk7XG4gICAgICAgIGlmIChpc05vbkRlbGV0ZWRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgdXBkYXRlQm91bmRFbGVtZW50cyhlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBvblN1Ym1pdDogd2l0aEJhdGNoZWRVcGRhdGVzKCh7IHRleHQsIHZpYUtleWJvYXJkLCBvcmlnaW5hbFRleHQgfSkgPT4ge1xuICAgICAgICBjb25zdCBpc0RlbGV0ZWQgPSAhdGV4dC50cmltKCk7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgb3JpZ2luYWxUZXh0LCBpc0RlbGV0ZWQsIHRydWUpO1xuICAgICAgICAvLyBzZWxlY3QgdGhlIGNyZWF0ZWQgdGV4dCBlbGVtZW50IG9ubHkgaWYgc3VibWl0dGluZyB2aWEga2V5Ym9hcmRcbiAgICAgICAgLy8gKHdoZW4gc3VibWl0dGluZyB2aWEgY2xpY2sgaXQgc2hvdWxkIGFjdCBhcyBzaWduYWwgdG8gZGVzZWxlY3QpXG4gICAgICAgIGlmICghaXNEZWxldGVkICYmIHZpYUtleWJvYXJkKSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudElkVG9TZWxlY3QgPSBlbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgICAgICA/IGVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgICAgIDogZWxlbWVudC5pZDtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgW2VsZW1lbnRJZFRvU2VsZWN0XTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RlbGV0ZWQpIHtcbiAgICAgICAgICBmaXhCaW5kaW5nc0FmdGVyRGVsZXRpb24odGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCBbZWxlbWVudF0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNEZWxldGVkIHx8IGlzRXhpc3RpbmdFbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudExvY2tlZCkge1xuICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICAgIH0pLFxuICAgICAgZWxlbWVudCxcbiAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgIH0pO1xuICAgIC8vIGRlc2VsZWN0IGFsbCBvdGhlciBlbGVtZW50cyB3aGVuIGluc2VydGluZyB0ZXh0XG4gICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG5cbiAgICAvLyBkbyBhbiBpbml0aWFsIHVwZGF0ZSB0byByZS1pbml0aWFsaXplIGVsZW1lbnQgcG9zaXRpb24gc2luY2Ugd2Ugd2VyZVxuICAgIC8vIG1vZGlmeWluZyBlbGVtZW50J3MgeC95IGZvciBzYWtlIG9mIGVkaXRvciAoY2FzZTogc3luY2luZyB0byByZW1vdGUpXG4gICAgdXBkYXRlRWxlbWVudChlbGVtZW50LnRleHQsIGVsZW1lbnQub3JpZ2luYWxUZXh0KTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzZWxlY3RFbGVtZW50cygpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3VGV4dEVsZW1lbnQ+IHwgbnVsbCB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oeCwgeSwge1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBpZiAoZWxlbWVudCAmJiBpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmICFlbGVtZW50LmlzRGVsZXRlZCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIG9wdHM/OiB7XG4gICAgICAvKiogaWYgdHJ1ZSwgcmV0dXJucyB0aGUgZmlyc3Qgc2VsZWN0ZWQgZWxlbWVudCAod2l0aCBoaWdoZXN0IHotaW5kZXgpXG4gICAgICAgIG9mIGFsbCBoaXQgZWxlbWVudHMgKi9cbiAgICAgIHByZWZlclNlbGVjdGVkPzogYm9vbGVhbjtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50PzogYm9vbGVhbjtcbiAgICB9LFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGFsbEhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIG9wdHM/LmluY2x1ZGVCb3VuZFRleHRFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKGFsbEhpdEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGlmIChvcHRzPy5wcmVmZXJTZWxlY3RlZCkge1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IGFsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDE7IGluZGV4ID4gLTE7IGluZGV4LS0pIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbYWxsSGl0RWxlbWVudHNbaW5kZXhdLmlkXSkge1xuICAgICAgICAgICAgcmV0dXJuIGFsbEhpdEVsZW1lbnRzW2luZGV4XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleCA9XG4gICAgICAgIGFsbEhpdEVsZW1lbnRzW2FsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgLy8gSWYgd2UncmUgaGl0dGluZyBlbGVtZW50IHdpdGggaGlnaGVzdCB6LWluZGV4IG9ubHkgb24gaXRzIGJvdW5kaW5nIGJveFxuICAgICAgLy8gd2hpbGUgYWxzbyBoaXR0aW5nIG90aGVyIGVsZW1lbnQgZmlndXJlLCB0aGUgbGF0dGVyIHNob3VsZCBiZSBjb25zaWRlcmVkLlxuICAgICAgcmV0dXJuIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgKVxuICAgICAgICA/IGFsbEhpdEVsZW1lbnRzW2FsbEhpdEVsZW1lbnRzLmxlbmd0aCAtIDJdXG4gICAgICAgIDogZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4O1xuICAgIH1cbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbMF07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogYm9vbGVhbiA9IGZhbHNlLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IGluY2x1ZGVCb3VuZFRleHRFbGVtZW50XG4gICAgICA/IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKVxuICAgICAgOiB0aGlzLnNjZW5lXG4gICAgICAgICAgLmdldEVsZW1lbnRzKClcbiAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+ICEoaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiBlbGVtZW50LmNvbnRhaW5lcklkKSxcbiAgICAgICAgICApO1xuICAgIHJldHVybiBnZXRFbGVtZW50c0F0UG9zaXRpb24oZWxlbWVudHMsIChlbGVtZW50KSA9PlxuICAgICAgaGl0VGVzdChlbGVtZW50LCB0aGlzLnN0YXRlLCB4LCB5KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFRleHRFZGl0aW5nID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICAgIHNob3VsZEJpbmQsXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgPSB0cnVlLFxuICB9OiB7XG4gICAgLyoqIFggcG9zaXRpb24gdG8gaW5zZXJ0IHRleHQgYXQgKi9cbiAgICBzY2VuZVg6IG51bWJlcjtcbiAgICAvKiogWSBwb3NpdGlvbiB0byBpbnNlcnQgdGV4dCBhdCAqL1xuICAgIHNjZW5lWTogbnVtYmVyO1xuICAgIHNob3VsZEJpbmQ6IGJvb2xlYW47XG4gICAgLyoqIHdoZXRoZXIgdG8gYXR0ZW1wdCB0byBpbnNlcnQgYXQgZWxlbWVudCBjZW50ZXIgaWYgYXBwbGljYWJsZSAqL1xuICAgIGluc2VydEF0UGFyZW50Q2VudGVyPzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIGxldCBwYXJlbnRDZW50ZXJQb3NpdGlvbiA9XG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlciAmJlxuICAgICAgdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgKTtcblxuICAgIC8vIGJpbmQgdG8gY29udGFpbmVyIHdoZW4gc2hvdWxkQmluZCBpcyB0cnVlIG9yXG4gICAgLy8gY2xpY2tlZCBvbiBjZW50ZXIgb2YgY29udGFpbmVyXG4gICAgY29uc3QgY29udGFpbmVyID1cbiAgICAgIHNob3VsZEJpbmQgfHwgcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgPyBnZXRFbGVtZW50Q29udGFpbmluZ1Bvc2l0aW9uKFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgc2NlbmVYLFxuICAgICAgICAgICAgc2NlbmVZLFxuICAgICAgICAgICAgXCJ0ZXh0XCIsXG4gICAgICAgICAgKVxuICAgICAgICA6IG51bGw7XG5cbiAgICBsZXQgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcblxuICAgIC8vIGNvbnNpZGVyIGJvdW5kZWQgdGV4dCBlbGVtZW50IGlmIGNvbnRhaW5lciBwcmVzZW50XG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgY29uc3QgYm91bmRUZXh0RWxlbWVudElkID0gZ2V0Qm91bmRUZXh0RWxlbWVudElkKGNvbnRhaW5lcik7XG4gICAgICBpZiAoYm91bmRUZXh0RWxlbWVudElkKSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnQoXG4gICAgICAgICAgYm91bmRUZXh0RWxlbWVudElkLFxuICAgICAgICApIGFzIEV4Y2FsaWRyYXdUZXh0RWxlbWVudDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFleGlzdGluZ1RleHRFbGVtZW50ICYmIGNvbnRhaW5lcikge1xuICAgICAgY29uc3QgZm9udFN0cmluZyA9IHtcbiAgICAgICAgZm9udFNpemU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250U2l6ZSxcbiAgICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB9O1xuICAgICAgY29uc3QgbWluV2lkdGggPSBnZXRBcHByb3hNaW5MaW5lV2lkdGgoZ2V0Rm9udFN0cmluZyhmb250U3RyaW5nKSk7XG4gICAgICBjb25zdCBtaW5IZWlnaHQgPSBnZXRBcHByb3hNaW5MaW5lSGVpZ2h0KGdldEZvbnRTdHJpbmcoZm9udFN0cmluZykpO1xuICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gTWF0aC5tYXgoY29udGFpbmVyLmhlaWdodCwgbWluSGVpZ2h0KTtcbiAgICAgIGNvbnN0IG5ld1dpZHRoID0gTWF0aC5tYXgoY29udGFpbmVyLndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IG5ld0hlaWdodCwgd2lkdGg6IG5ld1dpZHRoIH0pO1xuICAgICAgc2NlbmVYID0gY29udGFpbmVyLnggKyBuZXdXaWR0aCAvIDI7XG4gICAgICBzY2VuZVkgPSBjb250YWluZXIueSArIG5ld0hlaWdodCAvIDI7XG4gICAgICBpZiAocGFyZW50Q2VudGVyUG9zaXRpb24pIHtcbiAgICAgICAgcGFyZW50Q2VudGVyUG9zaXRpb24gPSB0aGlzLmdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgICAgICAgc2NlbmVYLFxuICAgICAgICAgIHNjZW5lWSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnQgPSBleGlzdGluZ1RleHRFbGVtZW50XG4gICAgICA/IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgIDogbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgICAgIHg6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJYXG4gICAgICAgICAgICA6IHNjZW5lWCxcbiAgICAgICAgICB5OiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBwYXJlbnRDZW50ZXJQb3NpdGlvbi5lbGVtZW50Q2VudGVyWVxuICAgICAgICAgICAgOiBzY2VuZVksXG4gICAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgICAgIHRleHQ6IFwiXCIsXG4gICAgICAgICAgZm9udFNpemU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250U2l6ZSxcbiAgICAgICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgICAgICB0ZXh0QWxpZ246IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IFwiY2VudGVyXCJcbiAgICAgICAgICAgIDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVRleHRBbGlnbixcbiAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBcIm1pZGRsZVwiXG4gICAgICAgICAgICA6IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgICAgICAgY29udGFpbmVySWQ6IGNvbnRhaW5lcj8uaWQgPz8gdW5kZWZpbmVkLFxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nRWxlbWVudDogZWxlbWVudCB9KTtcblxuICAgIGlmIChleGlzdGluZ1RleHRFbGVtZW50KSB7XG4gICAgICAvLyBpZiB0ZXh0IGVsZW1lbnQgaXMgbm8gbG9uZ2VyIGNlbnRlcmVkIHRvIGEgY29udGFpbmVyLCByZXNldFxuICAgICAgLy8gdmVydGljYWxBbGlnbiB0byBkZWZhdWx0IGJlY2F1c2UgaXQncyBjdXJyZW50bHkgaW50ZXJuYWwtb25seVxuICAgICAgaWYgKCFwYXJlbnRDZW50ZXJQb3NpdGlvbiB8fCBlbGVtZW50LnRleHRBbGlnbiAhPT0gXCJjZW50ZXJcIikge1xuICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHsgdmVydGljYWxBbGlnbjogREVGQVVMVF9WRVJUSUNBTF9BTElHTiB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG5cbiAgICAgIC8vIGNhc2U6IGNyZWF0aW5nIG5ldyB0ZXh0IG5vdCBjZW50ZXJlZCB0byBwYXJlbnQgZWxlbWVuZW50IOKGkiBvZmZzZXQgWVxuICAgICAgLy8gc28gdGhhdCB0aGUgdGV4dCBpcyBjZW50ZXJlZCB0byBjdXJzb3IgcG9zaXRpb25cbiAgICAgIGlmICghcGFyZW50Q2VudGVyUG9zaXRpb24pIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgICAgeTogZWxlbWVudC55IC0gZWxlbWVudC5iYXNlbGluZSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmhhbmRsZVRleHRXeXNpd3lnKGVsZW1lbnQsIHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50OiAhIWV4aXN0aW5nVGV4dEVsZW1lbnQsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNEb3VibGVDbGljayA9IChcbiAgICBldmVudDogUmVhY3QuTW91c2VFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIGNhc2U6IGRvdWJsZS1jbGlja2luZyB3aXRoIGFycm93L2xpbmUgdG9vbCBzZWxlY3RlZCB3b3VsZCBib3RoIGNyZWF0ZVxuICAgIC8vIHRleHQgYW5kIGVudGVyIG11bHRpRWxlbWVudCBtb2RlXG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHdlIHNob3VsZCBvbmx5IGJlIGFibGUgdG8gZG91YmxlIGNsaWNrIHdoZW4gbW9kZSBpcyBzZWxlY3Rpb25cbiAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmIGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSkge1xuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT0gc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuXG4gICAgbGV0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIGV2ZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkcyA9IGdldFNlbGVjdGVkR3JvdXBJZHModGhpcy5zdGF0ZSk7XG5cbiAgICBpZiAoc2VsZWN0ZWRHcm91cElkcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG5cbiAgICAgIGNvbnN0IHNlbGVjdGVkR3JvdXBJZCA9XG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgZ2V0U2VsZWN0ZWRHcm91cElkRm9yRWxlbWVudChoaXRFbGVtZW50LCB0aGlzLnN0YXRlLnNlbGVjdGVkR3JvdXBJZHMpO1xuXG4gICAgICBpZiAoc2VsZWN0ZWRHcm91cElkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBzZWxlY3RlZEdyb3VwSWQsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudCEuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuICAgICAgICBjb25zdCBjYW5CaW5kVGV4dCA9IGhhc0JvdW5kVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50KTtcbiAgICAgICAgaWYgKGNhbkJpbmRUZXh0KSB7XG4gICAgICAgICAgc2NlbmVYID0gc2VsZWN0ZWRFbGVtZW50LnggKyBzZWxlY3RlZEVsZW1lbnQud2lkdGggLyAyO1xuICAgICAgICAgIHNjZW5lWSA9IHNlbGVjdGVkRWxlbWVudC55ICsgc2VsZWN0ZWRFbGVtZW50LmhlaWdodCAvIDI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgICBzaG91bGRCaW5kOiBmYWxzZSxcbiAgICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI6ICFldmVudC5hbHRLZXksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCB0aGlzLnN0YXRlLmN1cnNvckJ1dHRvbik7XG5cbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5oYXMoZXZlbnQucG9pbnRlcklkKSkge1xuICAgICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoXG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIgJiZcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciAmJlxuICAgICAgaW5pdGlhbFNjYWxlICYmXG4gICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZVxuICAgICkge1xuICAgICAgY29uc3QgY2VudGVyID0gZ2V0Q2VudGVyKGdlc3R1cmUucG9pbnRlcnMpO1xuICAgICAgY29uc3QgZGVsdGFYID0gY2VudGVyLnggLSBnZXN0dXJlLmxhc3RDZW50ZXIueDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGNlbnRlci55IC0gZ2VzdHVyZS5sYXN0Q2VudGVyLnk7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPSBjZW50ZXI7XG5cbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZ2V0RGlzdGFuY2UoQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSk7XG4gICAgICBjb25zdCBzY2FsZUZhY3RvciA9IGRpc3RhbmNlIC8gZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2U7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCwgc2Nyb2xsWSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pID0+ICh7XG4gICAgICAgIHNjcm9sbFg6IHNjcm9sbFggKyBkZWx0YVggLyB6b29tLnZhbHVlLFxuICAgICAgICBzY3JvbGxZOiBzY3JvbGxZICsgZGVsdGFZIC8gem9vbS52YWx1ZSxcbiAgICAgICAgem9vbTogZ2V0TmV3Wm9vbShcbiAgICAgICAgICBnZXROb3JtYWxpemVkWm9vbShpbml0aWFsU2NhbGUgKiBzY2FsZUZhY3RvciksXG4gICAgICAgICAgem9vbSxcbiAgICAgICAgICB7IGxlZnQ6IG9mZnNldExlZnQsIHRvcDogb2Zmc2V0VG9wIH0sXG4gICAgICAgICAgY2VudGVyLFxuICAgICAgICApLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9XG4gICAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPVxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGlzSG9sZGluZ1NwYWNlIHx8IGlzUGFubmluZyB8fCBpc0RyYWdnaW5nU2Nyb2xsQmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMgPSBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICk7XG4gICAgY29uc3QgaXNPdmVyU2Nyb2xsQmFyID0gaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMuaXNPdmVyRWl0aGVyO1xuICAgIGlmICghdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHsgeDogc2NlbmVQb2ludGVyWCwgeTogc2NlbmVQb2ludGVyWSB9ID0gc2NlbmVQb2ludGVyO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICkge1xuICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJNb3ZlKFxuICAgICAgICBldmVudCxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG4gICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdMaW5lYXJFbGVtZW50IH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50Lmxhc3RVbmNvbW1pdHRlZFBvaW50ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3Ioc2NlbmVQb2ludGVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzQmluZGluZ0VsZW1lbnRUeXBlKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpKSB7XG4gICAgICAvLyBIb3ZlcmluZyB3aXRoIGEgc2VsZWN0ZWQgdG9vbCBvciBjcmVhdGluZyBuZXcgbGluZWFyIGVsZW1lbnQgdmlhIGNsaWNrXG4gICAgICAvLyBhbmQgcG9pbnRcbiAgICAgIGNvbnN0IHsgZHJhZ2dpbmdFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBbc2NlbmVQb2ludGVyXSxcbiAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3Ioc2NlbmVQb2ludGVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnkgfSA9IG11bHRpRWxlbWVudDtcblxuICAgICAgY29uc3QgeyBwb2ludHMsIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuICAgICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcblxuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuXG4gICAgICBpZiAobGFzdFBvaW50ID09PSBsYXN0Q29tbWl0dGVkUG9pbnQpIHtcbiAgICAgICAgLy8gaWYgd2UgaGF2ZW4ndCB5ZXQgY3JlYXRlZCBhIHRlbXAgcG9pbnQgYW5kIHdlJ3JlIGJleW9uZCBjb21taXQtem9uZVxuICAgICAgICAvLyB0aHJlc2hvbGQsIGFkZCBhIHBvaW50XG4gICAgICAgIGlmIChcbiAgICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyWCAtIHJ4LFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyWSAtIHJ5LFxuICAgICAgICAgICAgbGFzdFBvaW50WzBdLFxuICAgICAgICAgICAgbGFzdFBvaW50WzFdLFxuICAgICAgICAgICkgPj0gTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbc2NlbmVQb2ludGVyWCAtIHJ4LCBzY2VuZVBvaW50ZXJZIC0gcnldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICAgIC8vIGluIHRoaXMgYnJhbmNoLCB3ZSdyZSBpbnNpZGUgdGhlIGNvbW1pdCB6b25lLCBhbmQgbm8gdW5jb21taXR0ZWRcbiAgICAgICAgICAvLyBwb2ludCBleGlzdHMuIFRodXMgZG8gbm90aGluZyAoZG9uJ3QgYWRkL3JlbW92ZSBwb2ludHMpLlxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBwb2ludHMubGVuZ3RoID4gMiAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IHBvaW50cy5zbGljZSgwLCAtMSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzUGF0aEFMb29wKHBvaW50cywgdGhpcy5zdGF0ZS56b29tLnZhbHVlKSkge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdXBkYXRlIGxhc3QgdW5jb21taXR0ZWQgcG9pbnRcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgIC4uLnBvaW50cy5zbGljZSgwLCAtMSksXG4gICAgICAgICAgICBbc2NlbmVQb2ludGVyWCAtIHJ4LCBzY2VuZVBvaW50ZXJZIC0gcnldLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaGFzRGVzZWxlY3RlZEJ1dHRvbiA9IEJvb2xlYW4oZXZlbnQuYnV0dG9ucyk7XG4gICAgaWYgKFxuICAgICAgaGFzRGVzZWxlY3RlZEJ1dHRvbiB8fFxuICAgICAgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAhPT0gXCJ0ZXh0XCIpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSk7XG4gICAgaWYgKFxuICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICFpc092ZXJTY3JvbGxCYXIgJiZcbiAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50XG4gICAgKSB7XG4gICAgICBjb25zdCBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgPSBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUoXG4gICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgKTtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICYmXG4gICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS50cmFuc2Zvcm1IYW5kbGVUeXBlXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudChlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUpLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEgJiYgIWlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyksXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKHRyYW5zZm9ybUhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICk7XG4gICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICBzZXRDdXJzb3IoXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICBpc1RleHRFbGVtZW50KGhpdEVsZW1lbnQpID8gQ1VSU09SX1RZUEUuVEVYVCA6IENVUlNPUl9UWVBFLkNST1NTSEFJUixcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICB9IGVsc2UgaWYgKGlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldEVsZW1lbnQoXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkLFxuICAgICAgKTtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudCAmJlxuICAgICAgICBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveChlbGVtZW50LCB0aGlzLnN0YXRlLCBbXG4gICAgICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICAgIF0pXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIC8vIGlmIHVzaW5nIGNtZC9jdHJsLCB3ZSdyZSBub3QgZHJhZ2dpbmdcbiAgICAgICFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJlxuICAgICAgKGhpdEVsZW1lbnQgfHxcbiAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgKSlcbiAgICApIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfVxuICB9O1xuXG4gIC8vIHNldCB0b3VjaCBtb3ZpbmcgZm9yIG1vYmlsZSBjb250ZXh0IG1lbnVcbiAgcHJpdmF0ZSBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQ6IFJlYWN0LlRvdWNoRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+KSA9PiB7XG4gICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gdHJ1ZTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICAvLyByZW1vdmUgYW55IGFjdGl2ZSBzZWxlY3Rpb24gd2hlbiB3ZSBzdGFydCB0byBpbnRlcmFjdCB3aXRoIGNhbnZhc1xuICAgIC8vIChtYWlubHksIHdlIGNhcmUgYWJvdXQgcmVtb3Zpbmcgc2VsZWN0aW9uIG91dHNpZGUgdGhlIGNvbXBvbmVudCB3aGljaFxuICAgIC8vICB3b3VsZCBwcmV2ZW50IG91ciBjb3B5IGhhbmRsaW5nIG90aGVyd2lzZSlcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsZWN0aW9uPy5hbmNob3JOb2RlKSB7XG4gICAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5tYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyhldmVudCk7XG4gICAgdGhpcy5tYXliZUNsZWFudXBBZnRlck1pc3NpbmdQb2ludGVyVXAoZXZlbnQpO1xuXG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgbGFzdFBvaW50ZXJEb3duV2l0aDogZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICBjdXJzb3JCdXR0b246IFwiZG93blwiLFxuICAgIH0pO1xuICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJkb3duXCIpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlQ2FudmFzUGFuVXNpbmdXaGVlbE9yU3BhY2VEcmFnKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG9ubHkgaGFuZGxlIGxlZnQgbW91c2UgYnV0dG9uIG9yIHRvdWNoXG4gICAgaWYgKFxuICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmXG4gICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLlRPVUNIXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVHZXN0dXJlT25Qb2ludGVyRG93bihldmVudCk7XG5cbiAgICAvLyBkb24ndCBzZWxlY3Qgd2hpbGUgcGFubmluZ1xuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPiAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU3RhdGUgZm9yIHRoZSBkdXJhdGlvbiBvZiBhIHBvaW50ZXIgaW50ZXJhY3Rpb24sIHdoaWNoIHN0YXJ0cyB3aXRoIGFcbiAgICAvLyBwb2ludGVyRG93biBldmVudCwgZW5kcyB3aXRoIGEgcG9pbnRlclVwIGV2ZW50IChvciBhbm90aGVyIHBvaW50ZXJEb3duKVxuICAgIGNvbnN0IHBvaW50ZXJEb3duU3RhdGUgPSB0aGlzLmluaXRpYWxQb2ludGVyRG93blN0YXRlKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZURyYWdnaW5nU2Nyb2xsQmFyKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2xlYXJTZWxlY3Rpb25JZk5vdFVzaW5nU2VsZWN0aW9uKCk7XG4gICAgdGhpcy51cGRhdGVCaW5kaW5nRW5hYmxlZE9uUG9pbnRlck1vdmUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlU2VsZWN0aW9uT25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlVGV4dE9uUG9pbnRlckRvd24oZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcImFycm93XCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwibGluZVwiXG4gICAgKSB7XG4gICAgICB0aGlzLmhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgIC8vIHJlc2V0IGltYWdlIHByZXZpZXcgb24gcG9pbnRlcmRvd25cbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQ1JPU1NIQUlSKTtcblxuICAgICAgaWYgKCF0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQsXG4gICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnQ6IG51bGwsXG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgICBtdXRhdGVFbGVtZW50KHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCwge1xuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlRnJlZURyYXdFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNyZWF0ZUdlbmVyaWNFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9XG4gICAgICB0aGlzLm9uUG9pbnRlck1vdmVGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyVXAgPVxuICAgICAgdGhpcy5vblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvbktleURvd24gPSB0aGlzLm9uS2V5RG93bkZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgY29uc3Qgb25LZXlVcCA9IHRoaXMub25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBsYXN0UG9pbnRlclVwID0gb25Qb2ludGVyVXA7XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgb25LZXlEb3duKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCBvbktleVVwKTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlID0gb25Qb2ludGVyTW92ZTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCA9IG9uUG9pbnRlclVwO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleVVwID0gb25LZXlVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duID0gb25LZXlEb3duO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBkZWFsIHdpdGggb3BlbmluZyBjb250ZXh0IG1lbnUgb24gdG91Y2ggZGV2aWNlc1xuICAgIGlmIChldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiKSB7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcblxuICAgICAgaWYgKHRvdWNoVGltZW91dCkge1xuICAgICAgICAvLyBJZiB0aGVyZSdzIGFscmVhZHkgYSB0b3VjaFRpbWVvdXQsIHRoaXMgbWVhbnMgdGhhdCB0aGVyZSdzIGFub3RoZXJcbiAgICAgICAgLy8gdG91Y2ggZG93biBhbmQgd2UgYXJlIGRvaW5nIGFub3RoZXIgdG91Y2gsIHNvIHdlIHNob3VsZG4ndCBvcGVuIHRoZVxuICAgICAgICAvLyBjb250ZXh0IG1lbnUuXG4gICAgICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvcGVuIHRoZSBjb250ZXh0IG1lbnUgd2l0aCB0aGUgZmlyc3QgdG91Y2gncyBjbGllbnRYIGFuZCBjbGllbnRZXG4gICAgICAgIC8vIGlmIHRoZSB0b3VjaCBpcyBub3QgbW92aW5nXG4gICAgICAgIHRvdWNoVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgICAgICAgIGlmICghaW52YWxpZGF0ZUNvbnRleHRNZW51KSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51KGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIFRPVUNIX0NUWF9NRU5VX1RJTUVPVVQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgaWYgKGxhc3RQb2ludGVyVXAgIT09IG51bGwpIHtcbiAgICAgIC8vIFVuZm9ydHVuYXRlbHksIHNvbWV0aW1lcyB3ZSBkb24ndCBnZXQgYSBwb2ludGVydXAgYWZ0ZXIgYSBwb2ludGVyZG93bixcbiAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29udGV4dHVhbCBtZW51IG9yIGFsZXJ0IGlzIHRyaWdnZXJlZC4gSW4gb3JkZXIgdG8gYXZvaWRcbiAgICAgIC8vIGJlaW5nIGluIGEgd2VpcmQgc3RhdGUsIHdlIGNsZWFuIHVwIG9uIHRoZSBuZXh0IHBvaW50ZXJkb3duXG4gICAgICBsYXN0UG9pbnRlclVwKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgcGFubmluZ1xuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKFxuICAgICAgIShcbiAgICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAwICYmXG4gICAgICAgIChldmVudC5idXR0b24gPT09IFBPSU5URVJfQlVUVE9OLldIRUVMIHx8XG4gICAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uTUFJTiAmJiBpc0hvbGRpbmdTcGFjZSkgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZClcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaXNQYW5uaW5nID0gdHJ1ZTtcblxuICAgIGxldCBuZXh0UGFzdGVQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICBjb25zdCBpc0xpbnV4ID0gL0xpbnV4Ly50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm0pO1xuXG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCQklORyk7XG4gICAgbGV0IHsgY2xpZW50WDogbGFzdFgsIGNsaWVudFk6IGxhc3RZIH0gPSBldmVudDtcbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBkZWx0YVggPSBsYXN0WCAtIGV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBkZWx0YVkgPSBsYXN0WSAtIGV2ZW50LmNsaWVudFk7XG4gICAgICBsYXN0WCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBsYXN0WSA9IGV2ZW50LmNsaWVudFk7XG5cbiAgICAgIC8qXG4gICAgICAgKiBQcmV2ZW50IHBhc3RlIGV2ZW50IGlmIHdlIG1vdmUgd2hpbGUgbWlkZGxlIGNsaWNraW5nIG9uIExpbnV4LlxuICAgICAgICogU2VlIGlzc3VlICMxMzgzLlxuICAgICAgICovXG4gICAgICBpZiAoXG4gICAgICAgIGlzTGludXggJiZcbiAgICAgICAgIW5leHRQYXN0ZVByZXZlbnRlZCAmJlxuICAgICAgICAoTWF0aC5hYnMoZGVsdGFYKSA+IDEgfHwgTWF0aC5hYnMoZGVsdGFZKSA+IDEpXG4gICAgICApIHtcbiAgICAgICAgbmV4dFBhc3RlUHJldmVudGVkID0gdHJ1ZTtcblxuICAgICAgICAvKiBQcmV2ZW50IHRoZSBuZXh0IHBhc3RlIGV2ZW50ICovXG4gICAgICAgIGNvbnN0IHByZXZlbnROZXh0UGFzdGUgPSAoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKlxuICAgICAgICAgKiBSZWVuYWJsZSBuZXh0IHBhc3RlIGluIGNhc2Ugb2YgZGlzYWJsZWQgbWlkZGxlIGNsaWNrIHBhc3RlIGZvclxuICAgICAgICAgKiBhbnkgcmVhc29uOlxuICAgICAgICAgKiAtIHJpZ3RoIGNsaWNrIHBhc3RlXG4gICAgICAgICAqIC0gZW1wdHkgY2xpcGJvYXJkXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBlbmFibGVOZXh0UGFzdGUgPSAoKSA9PiB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgZW5hYmxlTmV4dFBhc3RlKTtcbiAgICAgICAgICB9LCAxMDApO1xuICAgICAgICB9O1xuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIGVuYWJsZU5leHRQYXN0ZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFggLSBkZWx0YVggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGRlbHRhWSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNvbnN0IHRlYXJkb3duID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgICAgKGxhc3RQb2ludGVyVXAgPSAoKSA9PiB7XG4gICAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuICAgICAgICBpc1Bhbm5pbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKCFpc0hvbGRpbmdTcGFjZSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGVhcmRvd24pO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0ZWFyZG93bik7XG4gICAgICB9KSxcbiAgICApO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUsIHtcbiAgICAgIHBhc3NpdmU6IHRydWUsXG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGVhcmRvd24pO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlR2VzdHVyZU9uUG9pbnRlckRvd24oXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQge1xuICAgIGdlc3R1cmUucG9pbnRlcnMuc2V0KGV2ZW50LnBvaW50ZXJJZCwge1xuICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgfSk7XG5cbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAyKSB7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlID0gZ2V0RGlzdGFuY2UoXG4gICAgICAgIEFycmF5LmZyb20oZ2VzdHVyZS5wb2ludGVycy52YWx1ZXMoKSksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IFBvaW50ZXJEb3duU3RhdGUge1xuICAgIGNvbnN0IG9yaWdpbiA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9yaWdpbixcbiAgICAgIHdpdGhDbWRPckN0cmw6IGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdLFxuICAgICAgb3JpZ2luSW5HcmlkOiB0dXBsZVRvQ29vcnMoXG4gICAgICAgIGdldEdyaWRQb2ludChvcmlnaW4ueCwgb3JpZ2luLnksIHRoaXMuc3RhdGUuZ3JpZFNpemUpLFxuICAgICAgKSxcbiAgICAgIHNjcm9sbGJhcnM6IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICAgIGN1cnJlbnRTY3JvbGxCYXJzLFxuICAgICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgICApLFxuICAgICAgLy8gd2UgbmVlZCB0byBkdXBsaWNhdGUgYmVjYXVzZSB3ZSdsbCBiZSB1cGRhdGluZyB0aGlzIHN0YXRlXG4gICAgICBsYXN0Q29vcmRzOiB7IC4uLm9yaWdpbiB9LFxuICAgICAgb3JpZ2luYWxFbGVtZW50czogdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLnJlZHVjZSgoYWNjLCBlbGVtZW50KSA9PiB7XG4gICAgICAgIGFjYy5zZXQoZWxlbWVudC5pZCwgZGVlcENvcHlFbGVtZW50KGVsZW1lbnQpKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIG5ldyBNYXAoKSBhcyBQb2ludGVyRG93blN0YXRlW1wib3JpZ2luYWxFbGVtZW50c1wiXSksXG4gICAgICByZXNpemU6IHtcbiAgICAgICAgaGFuZGxlVHlwZTogZmFsc2UsXG4gICAgICAgIGlzUmVzaXppbmc6IGZhbHNlLFxuICAgICAgICBvZmZzZXQ6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICBhcnJvd0RpcmVjdGlvbjogXCJvcmlnaW5cIixcbiAgICAgICAgY2VudGVyOiB7IHg6IChtYXhYICsgbWluWCkgLyAyLCB5OiAobWF4WSArIG1pblkpIC8gMiB9LFxuICAgICAgfSxcbiAgICAgIGhpdDoge1xuICAgICAgICBlbGVtZW50OiBudWxsLFxuICAgICAgICBhbGxIaXRFbGVtZW50czogW10sXG4gICAgICAgIHdhc0FkZGVkVG9TZWxlY3Rpb246IGZhbHNlLFxuICAgICAgICBoYXNCZWVuRHVwbGljYXRlZDogZmFsc2UsXG4gICAgICAgIGhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzOlxuICAgICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICksXG4gICAgICAgIGhhc0hpdEVsZW1lbnRJbnNpZGU6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGRyYWc6IHtcbiAgICAgICAgaGFzT2NjdXJyZWQ6IGZhbHNlLFxuICAgICAgICBvZmZzZXQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZXZlbnRMaXN0ZW5lcnM6IHtcbiAgICAgICAgb25Nb3ZlOiBudWxsLFxuICAgICAgICBvblVwOiBudWxsLFxuICAgICAgICBvbktleVVwOiBudWxsLFxuICAgICAgICBvbktleURvd246IG51bGwsXG4gICAgICB9LFxuICAgICAgYm94U2VsZWN0aW9uOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBkcmFnZ2luZyBhIHNjcm9sbGJhclxuICBwcml2YXRlIGhhbmRsZURyYWdnaW5nU2Nyb2xsQmFyKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChcbiAgICAgICEocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3ZlckVpdGhlciAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgPSB0cnVlO1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gZXZlbnQuY2xpZW50WDtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IGV2ZW50LmNsaWVudFk7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5oYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgPSBmYWxzZTtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcbiAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwidXBcIik7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgIH0pO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2VsZWN0aW9uSWZOb3RVc2luZ1NlbGVjdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHJldHVybnMgd2hldGhlciB0aGUgcG9pbnRlciBldmVudCBoYXMgYmVlbiBjb21wbGV0ZWx5IGhhbmRsZWRcbiAgICovXG4gIHByaXZhdGUgaGFuZGxlU2VsZWN0aW9uT25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCk7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSk7XG4gICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlID1cbiAgICAgICAgICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUoXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgcmVzaXppbmdFbGVtZW50OiBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUuZWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlID1cbiAgICAgICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS50cmFuc2Zvcm1IYW5kbGVUeXBlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgICAgZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpLFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGU6IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmlzUmVzaXppbmcgPSB0cnVlO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQgPSB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgZ2V0UmVzaXplT2Zmc2V0WFkoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgIGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSAmJlxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0ucG9pbnRzLmxlbmd0aCA9PT0gMlxuICAgICAgICApIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbiA9IGdldFJlc2l6ZUFycm93RGlyZWN0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCByZXQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJEb3duKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgKGFwcFN0YXRlKSA9PiB0aGlzLnNldFN0YXRlKGFwcFN0YXRlKSxcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJldC5oaXRFbGVtZW50KSB7XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID0gcmV0LmhpdEVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQuZGlkQWRkUG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGhpdEVsZW1lbnQgbWF5IGFscmVhZHkgYmUgc2V0IGFib3ZlLCBzbyBjaGVjayBmaXJzdFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID8/XG4gICAgICAgICAgdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQpIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlID1cbiAgICAgICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KFxuICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCwgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueV0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIG92ZXJsYXBwZWQgZWxlbWVudHMgb25lIHBvc2l0aW9uIG1heSBoaXRcbiAgICAgICAgLy8gbXVsdGlwbGUgZWxlbWVudHNcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT5cbiAgICAgICAgICAgIHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAoaGl0RWxlbWVudCA9PT0gbnVsbCB8fCAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkKSAmJlxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICBbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBJZiB3ZSBjbGljayBvbiBzb21ldGhpbmdcbiAgICAgICAgfSBlbHNlIGlmIChoaXRFbGVtZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAvLyBvbiBDTUQvQ1RSTCwgZHJpbGwgZG93biB0byBoaXQgZWxlbWVudCByZWdhcmRsZXNzIG9mIGdyb3VwcyBldGMuXG4gICAgICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICAuLi5lZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQocHJldlN0YXRlLCBoaXRFbGVtZW50KSxcbiAgICAgICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgLy8gbWFyayBhcyBub3QgY29tcGxldGVseSBoYW5kbGVkIHNvIGFzIHRvIGFsbG93IGRyYWdnaW5nIGV0Yy5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBkZXNlbGVjdCBpZiBpdGVtIGlzIHNlbGVjdGVkXG4gICAgICAgICAgLy8gaWYgc2hpZnQgaXMgbm90IGNsaWNrZWQsIHRoaXMgd2lsbCBhbHdheXMgcmV0dXJuIHRydWVcbiAgICAgICAgICAvLyBvdGhlcndpc2UsIGl0IHdpbGwgdHJpZ2dlciBzZWxlY3Rpb24gYmFzZWQgb24gY3VycmVudFxuICAgICAgICAgIC8vIHN0YXRlIG9mIHRoZSBib3hcbiAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgY3VycmVudGx5IGVkaXRpbmcgYSBncm91cCwgZXhpdGluZyBlZGl0aW5nIG1vZGUgYW5kIGRlc2VsZWN0IHRoZSBncm91cC5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICAgICAgICAhaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBZGQgaGl0IGVsZW1lbnQgdG8gc2VsZWN0aW9uLiBBdCB0aGlzIHBvaW50IGlmIHdlJ3JlIG5vdCBob2xkaW5nXG4gICAgICAgICAgICAvLyBTSElGVCB0aGUgcHJldmlvdXNseSBzZWxlY3RlZCBlbGVtZW50KHMpIHdlcmUgZGVzZWxlY3RlZCBhYm92ZVxuICAgICAgICAgICAgLy8gKG1ha2Ugc3VyZSB5b3UgdXNlIHNldFN0YXRlIHVwZGF0ZXIgdG8gdXNlIGxhdGVzdCBzdGF0ZSlcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgIXNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCAmJlxuICAgICAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIGlzQVNlbGVjdGVkRWxlbWVudChoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGl0RWxlbWVudCAhPSBudWxsICYmIHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICBwb2ludDogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSG93IG1hbnkgcGl4ZWxzIG9mZiB0aGUgc2hhcGUgYm91bmRhcnkgd2Ugc3RpbGwgY29uc2lkZXIgYSBoaXRcbiAgICBjb25zdCB0aHJlc2hvbGQgPSAxMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHJldHVybiAoXG4gICAgICBwb2ludC54ID4geDEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnggPCB4MiArIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueSA+IHkxIC0gdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55IDwgeTIgKyB0aHJlc2hvbGRcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBpZiB3ZSdyZSBjdXJyZW50bHkgc3RpbGwgZWRpdGluZyB0ZXh0LCBjbGlja2luZyBvdXRzaWRlXG4gICAgLy8gc2hvdWxkIG9ubHkgZmluYWxpemUgaXQsIG5vdCBjcmVhdGUgYW5vdGhlciAoaXJyZXNwZWN0aXZlXG4gICAgLy8gb2Ygc3RhdGUuZWxlbWVudExvY2tlZClcbiAgICBpZiAoaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgc2NlbmVYID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueDtcbiAgICBsZXQgc2NlbmVZID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZLCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNhbkJpbmRUZXh0ID0gaGFzQm91bmRUZXh0RWxlbWVudChlbGVtZW50KTtcbiAgICBpZiAoY2FuQmluZFRleHQpIHtcbiAgICAgIHNjZW5lWCA9IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgLyAyO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgc2NlbmVYLFxuICAgICAgc2NlbmVZLFxuICAgICAgc2hvdWxkQmluZDogZmFsc2UsXG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICB9KTtcblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICBpZiAoIXRoaXMuc3RhdGUuZWxlbWVudExvY2tlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVsZW1lbnRUeXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlRnJlZURyYXdFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0ZyZWVEcmF3RWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKSA9PiB7XG4gICAgLy8gQmVnaW4gYSBtYXJrIGNhcHR1cmUuIFRoaXMgZG9lcyBub3QgaGF2ZSB0byB1cGRhdGUgc3RhdGUgeWV0LlxuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICBudWxsLFxuICAgICk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3RnJlZURyYXdFbGVtZW50KHtcbiAgICAgIHR5cGU6IGVsZW1lbnRUeXBlLFxuICAgICAgeDogZ3JpZFgsXG4gICAgICB5OiBncmlkWSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtTGluZWFyU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgc2ltdWxhdGVQcmVzc3VyZTogZXZlbnQucHJlc3N1cmUgPT09IDAuNSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBwcmVzc3VyZXMgPSBlbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgID8gZWxlbWVudC5wcmVzc3VyZXNcbiAgICAgIDogWy4uLmVsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHBvaW50czogW1swLCAwXV0sXG4gICAgICBwcmVzc3VyZXMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUltYWdlRWxlbWVudCA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgfToge1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIHNjZW5lWTogbnVtYmVyO1xuICB9KSA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoc2NlbmVYLCBzY2VuZVksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ltYWdlRWxlbWVudCh7XG4gICAgICB0eXBlOiBcImltYWdlXCIsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3TGluZWFyRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgLy8gZmluYWxpemUgaWYgY29tcGxldGluZyBhIGxvb3BcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnR5cGUgPT09IFwibGluZVwiICYmXG4gICAgICAgIGlzUGF0aEFMb29wKG11bHRpRWxlbWVudC5wb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSlcbiAgICAgICkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDpcbiAgICAgICAgICAgIG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSwgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIC8vIGNsaWNraW5nIGluc2lkZSBjb21taXQgem9uZSDihpIgZmluYWxpemUgYXJyb3dcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggPiAxICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSByeCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFttdWx0aUVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgLy8gY2xpY2tpbmcgb3V0c2lkZSBjb21taXQgem9uZSDihpIgdXBkYXRlIHJlZmVyZW5jZSBmb3IgbGFzdCBjb21taXR0ZWRcbiAgICAgIC8vIHBvaW50XG4gICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgIH0pO1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvKiBJZiBhcnJvdyBpcyBwcmUtYXJyb3doZWFkcywgaXQgd2lsbCBoYXZlIHVuZGVmaW5lZCBmb3IgYm90aCBzdGFydCBhbmQgZW5kIGFycm93aGVhZHMuXG4gICAgICBJZiBzbywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBzdGFydCBhbmQgXCJhcnJvd1wiIGZvciBlbmQuIElmIHRoZSBsaW5lYXIgaXRlbSBpcyBub3RcbiAgICAgIGFuIGFycm93LCB3ZSB3YW50IGl0IHRvIGJlIG51bGwgZm9yIGJvdGguIE90aGVyd2lzZSwgd2Ugd2FudCBpdCB0byB1c2UgdGhlXG4gICAgICB2YWx1ZXMgZnJvbSBhcHBTdGF0ZS4gKi9cblxuICAgICAgY29uc3QgeyBjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IFtzdGFydEFycm93aGVhZCwgZW5kQXJyb3doZWFkXSA9XG4gICAgICAgIGVsZW1lbnRUeXBlID09PSBcImFycm93XCJcbiAgICAgICAgICA/IFtjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZF1cbiAgICAgICAgICA6IFtudWxsLCBudWxsXTtcblxuICAgICAgY29uc3QgZWxlbWVudCA9IG5ld0xpbmVhckVsZW1lbnQoe1xuICAgICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgICAgeDogZ3JpZFgsXG4gICAgICAgIHk6IGdyaWRZLFxuICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtTGluZWFyU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgICBzdGFydEFycm93aGVhZCxcbiAgICAgICAgZW5kQXJyb3doZWFkLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgW2VsZW1lbnQuaWRdOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICBwb2ludHM6IFsuLi5lbGVtZW50LnBvaW50cywgWzAsIDBdXSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYm91bmRFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICk7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBjcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdHZW5lcmljRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgKTtcbiAgICBjb25zdCBlbGVtZW50ID0gbmV3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICB9KTtcblxuICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3Rpb25FbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgbXVsdGlFbGVtZW50OiBudWxsLFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25LZXlEb3duRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG9uS2V5VXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIC8vIFByZXZlbnRzIGZvY3VzIGZyb20gZXNjYXBpbmcgZXhjYWxpZHJhdyB0YWJcbiAgICAgIGV2ZW50LmtleSA9PT0gS0VZUy5BTFQgJiYgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyTW92ZUZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gaW5pdGlhbGl6ZSBkcmFnT2Zmc2V0WFkgb25seSBhZnRlciB3ZSd2ZSB1cGRhdGVkXG4gICAgICAvLyBgc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzYCBvbiBwb2ludGVyRG93bi4gRG9pbmcgaXQgaGVyZSBpbiBwb2ludGVyTW92ZVxuICAgICAgLy8gZXZlbnQgaGFuZGxlciBzaG91bGQgaG9wZWZ1bGx5IGVuc3VyZSB3ZSdyZSBhbHJlYWR5IHdvcmtpbmcgd2l0aFxuICAgICAgLy8gdGhlIHVwZGF0ZWQgc3RhdGUuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9PT0gbnVsbCkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldERyYWdPZmZzZXRYWShcbiAgICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHModGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvLyBmb3IgYXJyb3dzL2xpbmVzLCBkb24ndCBzdGFydCBkcmFnZ2luZyB1bnRpbCBhIGdpdmVuIHRocmVzaG9sZFxuICAgICAgLy8gdG8gZW5zdXJlIHdlIGRvbid0IGNyZWF0ZSBhIDItcG9pbnQgYXJyb3cgYnkgbWlzdGFrZSB3aGVuXG4gICAgICAvLyB1c2VyIGNsaWNrcyBtb3VzZSBpbiBhIHdheSB0aGF0IGl0IG1vdmVzIGEgdGlueSBiaXQgKHRodXNcbiAgICAgIC8vIHRyaWdnZXJpbmcgcG9pbnRlcm1vdmUpXG4gICAgICBpZiAoXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwibGluZVwiKVxuICAgICAgKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSA8IERSQUdHSU5HX1RIUkVTSE9MRFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmlzUmVzaXppbmcpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBkaWREcmFnID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludERyYWdnaW5nKFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKGFwcFN0YXRlKSA9PiB0aGlzLnNldFN0YXRlKGFwcFN0YXRlKSxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgIChlbGVtZW50LCBwb2ludHNTY2VuZUNvb3JkcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgcG9pbnRzU2NlbmVDb29yZHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRpZERyYWcpIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgaGFzSGl0QVNlbGVjdGVkRWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmFsbEhpdEVsZW1lbnRzLnNvbWUoXG4gICAgICAgIChlbGVtZW50KSA9PiB0aGlzLmlzQVNlbGVjdGVkRWxlbWVudChlbGVtZW50KSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgKGhhc0hpdEFTZWxlY3RlZEVsZW1lbnQgfHxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cykgJiZcbiAgICAgICAgLy8gdGhpcyBhbGxvd3MgZm9yIGJveC1zZWxlY3RpbmcgcG9pbnRzIHdoZW4gY2xpY2tpbmcgaW5zaWRlIHRoZVxuICAgICAgICAvLyBsaW5lJ3MgYm91bmRpbmcgYm94XG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fCAhZXZlbnQuc2hpZnRLZXkpICYmXG4gICAgICAgIC8vIGJveC1zZWxlY3Rpbmcgd2l0aG91dCBzaGlmdCB3aGVuIGVkaXRpbmcgbGluZSwgbm90IGNsaWNraW5nIG9uIGEgbGluZVxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50Py5lbGVtZW50SWQgIT09XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50Py5pZCB8fFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUpXG4gICAgICApIHtcbiAgICAgICAgLy8gTWFya2luZyB0aGF0IGNsaWNrIHdhcyB1c2VkIGZvciBkcmFnZ2luZyB0byBjaGVja1xuICAgICAgICAvLyBpZiBlbGVtZW50cyBzaG91bGQgYmUgZGVzZWxlY3RlZCBvbiBwb2ludGVydXBcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIC8vIHByZXZlbnQgZHJhZ2dpbmcgZXZlbiBpZiB3ZSdyZSBubyBsb25nZXIgaG9sZGluZyBjbWQvY3RybCBvdGhlcndpc2VcbiAgICAgICAgLy8gaXQgd291bGQgaGF2ZSB3ZWlyZCByZXN1bHRzIChzdHVmZiBqdW1waW5nIGFsbCBvdmVyIHRoZSBzY3JlZW4pXG4gICAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDAgJiYgIXBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCkge1xuICAgICAgICAgIGNvbnN0IFtkcmFnWCwgZHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgW2RyYWdEaXN0YW5jZVgsIGRyYWdEaXN0YW5jZVldID0gW1xuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCksXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55KSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgLy8gV2Ugb25seSBkcmFnIGluIG9uZSBkaXJlY3Rpb24gaWYgc2hpZnQgaXMgcHJlc3NlZFxuICAgICAgICAgIGNvbnN0IGxvY2tEaXJlY3Rpb24gPSBldmVudC5zaGlmdEtleTtcblxuICAgICAgICAgIGRyYWdTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgICBkcmFnWCxcbiAgICAgICAgICAgIGRyYWdZLFxuICAgICAgICAgICAgbG9ja0RpcmVjdGlvbixcbiAgICAgICAgICAgIGRyYWdEaXN0YW5jZVgsXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2VZLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgICAgICAgLy8gV2UgZHVwbGljYXRlIHRoZSBzZWxlY3RlZCBlbGVtZW50IGlmIGFsdCBpcyBwcmVzc2VkIG9uIHBvaW50ZXIgbW92ZVxuICAgICAgICAgIGlmIChldmVudC5hbHRLZXkgJiYgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0JlZW5EdXBsaWNhdGVkKSB7XG4gICAgICAgICAgICAvLyBNb3ZlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZWxlbWVudHMgdG8gdGhlIHRvcCBvZiB0aGUgeiBpbmRleCBzdGFjaywgYW5kXG4gICAgICAgICAgICAvLyBwdXQgdGhlIGR1cGxpY2F0ZXMgd2hlcmUgdGhlIHNlbGVjdGVkIGVsZW1lbnRzIHVzZWQgdG8gYmUuXG4gICAgICAgICAgICAvLyAodGhlIG9yaWdpbiBwb2ludCB3aGVyZSB0aGUgZHJhZ2dpbmcgc3RhcnRlZClcblxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzVG9BcHBlbmQgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwSWRNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBvbGRJZFRvRHVwbGljYXRlZElkID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRJZHM6IEFycmF5PEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0+ID1cbiAgICAgICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSwgdHJ1ZSkubWFwKFxuICAgICAgICAgICAgICAgIChlbGVtZW50KSA9PiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkcy5pbmNsdWRlcyhlbGVtZW50LmlkKSB8fFxuICAgICAgICAgICAgICAgIC8vIGNhc2U6IHRoZSBzdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMgbWlnaHQgbm90IGhhdmUgYmVlblxuICAgICAgICAgICAgICAgIC8vIHVwZGF0ZWQgeWV0IGJ5IHRoZSB0aW1lIHRoaXMgbW91c2Vtb3ZlIGV2ZW50IGlzIGZpcmVkXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQuaWQgPT09IGhpdEVsZW1lbnQ/LmlkICYmXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkdXBsaWNhdGVkRWxlbWVudCA9IGR1cGxpY2F0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkLFxuICAgICAgICAgICAgICAgICAgZ3JvdXBJZE1hcCxcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3JpZ2luRHJhZ1gsIG9yaWdpbkRyYWdZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHVwbGljYXRlZEVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICAgIHg6IGR1cGxpY2F0ZWRFbGVtZW50LnggKyAob3JpZ2luRHJhZ1ggLSBkcmFnWCksXG4gICAgICAgICAgICAgICAgICB5OiBkdXBsaWNhdGVkRWxlbWVudC55ICsgKG9yaWdpbkRyYWdZIC0gZHJhZ1kpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG5leHRFbGVtZW50cy5wdXNoKGR1cGxpY2F0ZWRFbGVtZW50KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZC5zZXQoZWxlbWVudC5pZCwgZHVwbGljYXRlZEVsZW1lbnQuaWQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5leHRFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBuZXh0U2NlbmVFbGVtZW50cyA9IFsuLi5uZXh0RWxlbWVudHMsIC4uLmVsZW1lbnRzVG9BcHBlbmRdO1xuICAgICAgICAgICAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbihcbiAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLFxuICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLFxuICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbihcbiAgICAgICAgICAgICAgbmV4dFNjZW5lRWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICAgIFwiZHVwbGljYXRlc1NlcnZlQXNPbGRcIixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhuZXh0U2NlbmVFbGVtZW50cyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJdCBpcyB2ZXJ5IGltcG9ydGFudCB0byByZWFkIHRoaXMuc3RhdGUgd2l0aGluIGVhY2ggbW92ZSBldmVudCxcbiAgICAgIC8vIG90aGVyd2lzZSB3ZSB3b3VsZCByZWFkIGEgc3RhbGUgb25lIVxuICAgICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGNvbnN0IGR4ID0gcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGNvbnN0IGR5ID0gcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgY29uc3QgcHJlc3N1cmVzID0gZHJhZ2dpbmdFbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgICAgICA/IGRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXNcbiAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChpc0xpbmVhckVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBsZXQgZHggPSBncmlkWCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBncmlkWSAtIGRyYWdnaW5nRWxlbWVudC55O1xuXG4gICAgICAgIGlmIChzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCkgJiYgcG9pbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICh7IHdpZHRoOiBkeCwgaGVpZ2h0OiBkeSB9ID0gZ2V0UGVyZmVjdEVsZW1lbnRTaXplKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgICAgIGR4LFxuICAgICAgICAgICAgZHksXG4gICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7IHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cy5zbGljZSgwLCAtMSksIFtkeCwgZHldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgICAvLyBXaGVuIGNyZWF0aW5nIGEgbGluZWFyIGVsZW1lbnQgYnkgZHJhZ2dpbmdcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgW3BvaW50ZXJDb29yZHNdLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zdGFydEJvdW5kRWxlbWVudCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgICAvLyBhbGxvd3MgZm9yIGJveC1zZWxlY3RpbmcgcG9pbnRzICh3aXRob3V0IHNoaWZ0KVxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKGVsZW1lbnRzLCB0aGlzLnN0YXRlKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsICYmIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGJveC1zZWxlY3QgbGluZSBlZGl0b3IgcG9pbnRzXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVCb3hTZWxlY3Rpb24oXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlLmJpbmQodGhpcyksXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyByZWd1bGFyIGJveC1zZWxlY3RcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50c1dpdGhpblNlbGVjdGlvbiA9IGdldEVsZW1lbnRzV2l0aGluU2VsZWN0aW9uKFxuICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLnJlZHVjZSgobWFwLCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG1hcFtlbGVtZW50LmlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXA7XG4gICAgICAgICAgICAgICAgICB9LCB7fSBhcyBhbnkpLFxuICAgICAgICAgICAgICAgICAgLi4uKHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB1c2luZyBjdHJsL2NtZCwgc2VsZWN0IHRoZSBoaXRFbGVtZW50IG9ubHkgaWYgd2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmVuJ3QgYm94LXNlbGVjdGVkIGFueXRoaW5nIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LmlkXTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIWVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDogbnVsbCksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgbW92ZSBoYXBwZW5lZCBvdmVyIGVpdGhlciBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJIb3Jpem9udGFsKSB7XG4gICAgICBjb25zdCB4ID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGR4ID0geCAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54O1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGR4IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHg7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3ZlclZlcnRpY2FsKSB7XG4gICAgICBjb25zdCB5ID0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGNvbnN0IGR5ID0geSAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55O1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGR5IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGNoaWxkRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudCxcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICBlbGVtZW50VHlwZSxcbiAgICAgICAgZWxlbWVudExvY2tlZCxcbiAgICAgICAgaXNSZXNpemluZyxcbiAgICAgICAgaXNSb3RhdGluZyxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIGlzUm90YXRpbmc6IGZhbHNlLFxuICAgICAgICByZXNpemluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICAvLyB0ZXh0IGVsZW1lbnRzIGFyZSByZXNldCBvbiBmaW5hbGl6ZSwgYW5kIHJlc2V0dGluZyBvbiBwb2ludGVydXBcbiAgICAgICAgLy8gbWF5IGNhdXNlIGlzc3VlcyB3aXRoIGRvdWJsZSB0YXBzXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgIG11bHRpRWxlbWVudCB8fCBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnRcbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGNoaWxkRXZlbnQuY2xpZW50WCwgY2hpbGRFdmVudC5jbGllbnRZLCBcInVwXCIpO1xuXG4gICAgICAvLyBIYW5kbGUgZW5kIG9mIGRyYWdnaW5nIGEgcG9pbnQgb2YgYSBsaW5lYXIgZWxlbWVudCwgbWlnaHQgY2xvc2UgYSBsb29wXG4gICAgICAvLyBhbmQgc2V0cyBiaW5kaW5nIGVsZW1lbnRcbiAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgICAocG9pbnRlckRvd25TdGF0ZS5oaXQ/LmVsZW1lbnQ/LmlkICE9PVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgfHxcbiAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJVcChcbiAgICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG5cbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5QT0lOVEVSX01PVkUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25Nb3ZlISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuUE9JTlRFUl9VUCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vblVwISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuS0VZRE9XTixcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleURvd24hLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5LRVlVUCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleVVwISxcbiAgICAgICk7XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBlbmRpbmdJbWFnZUVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQ/LnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBsZXQgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgLy8gQWxsb3dzIGRvdHMgdG8gYXZvaWQgYmVpbmcgZmxhZ2dlZCBhcyBpbmZpbml0ZWx5IHNtYWxsXG4gICAgICAgIGlmIChkeCA9PT0gcG9pbnRzWzBdWzBdICYmIGR5ID09PSBwb2ludHNbMF1bMV0pIHtcbiAgICAgICAgICBkeSArPSAwLjAwMDE7XG4gICAgICAgICAgZHggKz0gMC4wMDAxO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJlc3N1cmVzID0gZHJhZ2dpbmdFbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiBbLi4uZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlcywgY2hpbGRFdmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBbZHgsIGR5XSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc0ltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IGRyYWdnaW5nRWxlbWVudDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgICAgeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiBlbC5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0xpbmVhckVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50IS5wb2ludHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgICAgICFtdWx0aUVsZW1lbnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgICAuLi5kcmFnZ2luZ0VsZW1lbnQucG9pbnRzLFxuICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50LngsXG4gICAgICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50LnksXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbXVsdGlFbGVtZW50OiBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBlZGl0aW5nRWxlbWVudDogdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmICFtdWx0aUVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpICYmXG4gICAgICAgICAgICBpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10sIHN0YXJ0Qm91bmRFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICAgIGlmICghZWxlbWVudExvY2tlZCkge1xuICAgICAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgIGVsZW1lbnRUeXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgICBpc0ludmlzaWJseVNtYWxsRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgLy8gcmVtb3ZlIGludmlzaWJsZSBlbGVtZW50IHdoaWNoIHdhcyBhZGRlZCBpbiBvblBvaW50ZXJEb3duXG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuc2xpY2UoMCwgLTEpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZERpbWVuc2lvbnMoZHJhZ2dpbmdFbGVtZW50KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNpemluZ0VsZW1lbnQgJiYgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQocmVzaXppbmdFbGVtZW50KSkge1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiBlbC5pZCAhPT0gcmVzaXppbmdFbGVtZW50LmlkKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29kZSBiZWxvdyBoYW5kbGVzIHNlbGVjdGlvbiB3aGVuIGVsZW1lbnQocykgd2VyZW4ndFxuICAgICAgLy8gZHJhZyBvciBhZGRlZCB0byBzZWxlY3Rpb24gb24gcG9pbnRlciBkb3duIHBoYXNlLlxuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICBpZiAoXG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiAmJlxuICAgICAgICAvLyBpZiB3ZSdyZSBlZGl0aW5nIGEgbGluZSwgcG9pbnRlcnVwIHNob3VsZG4ndCBzd2l0Y2ggc2VsZWN0aW9uIGlmXG4gICAgICAgIC8vIGJveCBzZWxlY3RlZFxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQpXG4gICAgICApIHtcbiAgICAgICAgLy8gd2hlbiBpbnNpZGUgbGluZSBlZGl0b3IsIHNoaWZ0IHNlbGVjdHMgcG9pbnRzIGluc3RlYWRcbiAgICAgICAgaWYgKGNoaWxkRXZlbnQuc2hpZnRLZXkgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIGlmIChpc1NlbGVjdGVkVmlhR3JvdXAodGhpcy5zdGF0ZSwgaGl0RWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgLy8gV2Ugd2FudCB0byB1bnNlbGVjdCBhbGwgZ3JvdXBzIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICAvLyBhcyB3ZWxsIGFzIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBncm91cHNcbiAgICAgICAgICAgICAgLy8gaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIGNvbnN0IGlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyA9IGhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAuZmxhdE1hcCgoZ3JvdXBJZCkgPT5cbiAgICAgICAgICAgICAgICAgIGdldEVsZW1lbnRzSW5Hcm91cCh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIGdyb3VwSWQpLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAubWFwKChlbGVtZW50KSA9PiAoeyBbZWxlbWVudC5pZF06IGZhbHNlIH0pKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXZJZCwgYWNjKSA9PiAoeyAuLi5wcmV2SWQsIC4uLmFjYyB9KSwge30pO1xuXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKF9wcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge1xuICAgICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5oaXRFbGVtZW50Lmdyb3VwSWRzXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGdJZCkgPT4gKHsgW2dJZF06IGZhbHNlIH0pKVxuICAgICAgICAgICAgICAgICAgICAucmVkdWNlKChwcmV2LCBhY2MpID0+ICh7IC4uLnByZXYsIC4uLmFjYyB9KSwge30pLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyByZW1vdmUgZWxlbWVudCBmcm9tIHNlbGVjdGlvbiB3aGlsZVxuICAgICAgICAgICAgICAvLyBrZWVwaW5nIHByZXYgZWxlbWVudHMgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gYWRkIGVsZW1lbnQgdG8gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAvLyBrZWVwaW5nIHByZXYgZWxlbWVudHMgc2VsZWN0ZWRcblxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgLi4uc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2hpdEVsZW1lbnQuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5pc1Jlc2l6aW5nICYmXG4gICAgICAgICgoaGl0RWxlbWVudCAmJlxuICAgICAgICAgIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSkgfHxcbiAgICAgICAgICAoIWhpdEVsZW1lbnQgJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSlcbiAgICAgICkge1xuICAgICAgICAvLyBEZXNlbGVjdCBzZWxlY3RlZCBlbGVtZW50c1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICghZWxlbWVudExvY2tlZCAmJiBlbGVtZW50VHlwZSAhPT0gXCJmcmVlZHJhd1wiICYmIGRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiIHx8XG4gICAgICAgIGlzU29tZUVsZW1lbnRTZWxlY3RlZCh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkIHx8IGlzUmVzaXppbmcgfHwgaXNSb3RhdGluZykge1xuICAgICAgICAoaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKVxuICAgICAgICAgID8gYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMpKFxuICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHModGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50TG9ja2VkICYmIGVsZW1lbnRUeXBlICE9PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgIGVsZW1lbnRUeXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2UgPSBhc3luYyAoe1xuICAgIGltYWdlRmlsZSxcbiAgICBpbWFnZUVsZW1lbnQ6IF9pbWFnZUVsZW1lbnQsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldyA9IGZhbHNlLFxuICB9OiB7XG4gICAgaW1hZ2VGaWxlOiBGaWxlO1xuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudDtcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3PzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIC8vIGF0IHRoaXMgcG9pbnQgdGhpcyBzaG91bGQgYmUgZ3VhcmFudGVlZCBpbWFnZSBmaWxlLCBidXQgd2UgZG8gdGhpcyBjaGVja1xuICAgIC8vIHRvIHNhdGlzZnkgVFMgZG93biB0aGUgbGluZVxuICAgIGlmICghaXNTdXBwb3J0ZWRJbWFnZUZpbGUoaW1hZ2VGaWxlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMudW5zdXBwb3J0ZWRGaWxlVHlwZVwiKSk7XG4gICAgfVxuICAgIGNvbnN0IG1pbWVUeXBlID0gaW1hZ2VGaWxlLnR5cGU7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIFwid2FpdFwiKTtcblxuICAgIGlmIChtaW1lVHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IFNWR1N0cmluZ1RvRmlsZShcbiAgICAgICAgICBhd2FpdCBub3JtYWxpemVTVkcoYXdhaXQgaW1hZ2VGaWxlLnRleHQoKSksXG4gICAgICAgICAgaW1hZ2VGaWxlLm5hbWUsXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnN2Z0ltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGdlbmVyYXRlIGltYWdlIGlkIChieSBkZWZhdWx0IHRoZSBmaWxlIGRpZ2VzdCkgYmVmb3JlIGFueVxuICAgIC8vIHJlc2l6aW5nL2NvbXByZXNzaW9uIHRha2VzIHBsYWNlIHRvIGtlZXAgaXQgbW9yZSBwb3J0YWJsZVxuICAgIGNvbnN0IGZpbGVJZCA9IGF3YWl0ICgodGhpcy5wcm9wcy5nZW5lcmF0ZUlkRm9yRmlsZT8uKFxuICAgICAgaW1hZ2VGaWxlLFxuICAgICkgYXMgUHJvbWlzZTxGaWxlSWQ+KSB8fCBnZW5lcmF0ZUlkRnJvbUZpbGUoaW1hZ2VGaWxlKSk7XG5cbiAgICBpZiAoIWZpbGVJZCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkNvdWxkbid0IGdlbmVyYXRlIGZpbGUgaWQgb3IgdGhlIHN1cHBsaWVkIGBnZW5lcmF0ZUlkRm9yRmlsZWAgZGlkbid0IHJlc29sdmUgdG8gb25lLlwiLFxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nRmlsZURhdGEgPSB0aGlzLmZpbGVzW2ZpbGVJZF07XG4gICAgaWYgKCFleGlzdGluZ0ZpbGVEYXRhPy5kYXRhVVJMKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBhd2FpdCByZXNpemVJbWFnZUZpbGUoaW1hZ2VGaWxlLCB7XG4gICAgICAgICAgbWF4V2lkdGhPckhlaWdodDogREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIHRyeWluZyB0byByZXNpbmcgaW1hZ2UgZmlsZSBvbiBpbnNlcnRpb25cIiwgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW1hZ2VGaWxlLnNpemUgPiBNQVhfQUxMT1dFRF9GSUxFX0JZVEVTKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICB0KFwiZXJyb3JzLmZpbGVUb29CaWdcIiwge1xuICAgICAgICAgICAgbWF4U2l6ZTogYCR7TWF0aC50cnVuYyhNQVhfQUxMT1dFRF9GSUxFX0JZVEVTIC8gMTAyNCAvIDEwMjQpfU1CYCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvd0N1cnNvckltYWdlUHJldmlldykge1xuICAgICAgY29uc3QgZGF0YVVSTCA9IHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTDtcbiAgICAgIC8vIG9wdGltaXphdGlvbiBzbyB0aGF0IHdlIGRvbid0IHVubmVjZXNzYXJpbHkgcmVzaXplIHRoZSBvcmlnaW5hbFxuICAgICAgLy8gZnVsbC1zaXplIGZpbGUgZm9yIGN1cnNvciBwcmV2aWV3XG4gICAgICAvLyAoaXQncyBtdWNoIGZhc3RlciB0byBjb252ZXJ0IHRoZSByZXNpemVkIGRhdGFVUkwgdG8gRmlsZSlcbiAgICAgIGNvbnN0IHJlc2l6ZWRGaWxlID0gZGF0YVVSTCAmJiBkYXRhVVJMVG9GaWxlKGRhdGFVUkwpO1xuXG4gICAgICB0aGlzLnNldEltYWdlUHJldmlld0N1cnNvcihyZXNpemVkRmlsZSB8fCBpbWFnZUZpbGUpO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFVUkwgPVxuICAgICAgdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMIHx8IChhd2FpdCBnZXREYXRhVVJMKGltYWdlRmlsZSkpO1xuXG4gICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gbXV0YXRlRWxlbWVudChcbiAgICAgIF9pbWFnZUVsZW1lbnQsXG4gICAgICB7XG4gICAgICAgIGZpbGVJZCxcbiAgICAgIH0sXG4gICAgICBmYWxzZSxcbiAgICApIGFzIE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50PjtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD4+KFxuICAgICAgYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuZmlsZXMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmZpbGVzLFxuICAgICAgICAgICAgW2ZpbGVJZF06IHtcbiAgICAgICAgICAgICAgbWltZVR5cGUsXG4gICAgICAgICAgICAgIGlkOiBmaWxlSWQsXG4gICAgICAgICAgICAgIGRhdGFVUkwsXG4gICAgICAgICAgICAgIGNyZWF0ZWQ6IERhdGUubm93KCksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY2FjaGVkSW1hZ2VEYXRhID0gdGhpcy5pbWFnZUNhY2hlLmdldChmaWxlSWQpO1xuICAgICAgICAgIGlmICghY2FjaGVkSW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFtpbWFnZUVsZW1lbnRdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNhY2hlZEltYWdlRGF0YT8uaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBhd2FpdCBjYWNoZWRJbWFnZURhdGEuaW1hZ2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudD8uaWQgIT09IGltYWdlRWxlbWVudC5pZCAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ/LmlkICE9PSBpbWFnZUVsZW1lbnQuaWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQsIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGltYWdlRWxlbWVudCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSkpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmICghc2hvd0N1cnNvckltYWdlUHJldmlldykge1xuICAgICAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBpbnNlcnRzIGltYWdlIGludG8gZWxlbWVudHMgYXJyYXkgYW5kIHJlcmVuZGVyc1xuICAgKi9cbiAgcHJpdmF0ZSBpbnNlcnRJbWFnZUVsZW1lbnQgPSBhc3luYyAoXG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICAgIGltYWdlRmlsZTogRmlsZSxcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3PzogYm9vbGVhbixcbiAgKSA9PiB7XG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIGltYWdlRWxlbWVudCxcbiAgICBdKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXRpYWxpemVJbWFnZSh7XG4gICAgICAgIGltYWdlRmlsZSxcbiAgICAgICAgaW1hZ2VFbGVtZW50LFxuICAgICAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgaXNEZWxldGVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIHx8IHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHNldEltYWdlUHJldmlld0N1cnNvciA9IGFzeW5jIChpbWFnZUZpbGU6IEZpbGUpID0+IHtcbiAgICAvLyBtdXN0bid0IGJlIGxhcmdlciB0aGFuIDEyOCBweFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9DU1NfQmFzaWNfVXNlcl9JbnRlcmZhY2UvVXNpbmdfVVJMX3ZhbHVlc19mb3JfdGhlX2N1cnNvcl9wcm9wZXJ0eVxuICAgIGNvbnN0IGN1cnNvckltYWdlU2l6ZVB4ID0gOTY7XG5cbiAgICBjb25zdCBpbWFnZVByZXZpZXcgPSBhd2FpdCByZXNpemVJbWFnZUZpbGUoaW1hZ2VGaWxlLCB7XG4gICAgICBtYXhXaWR0aE9ySGVpZ2h0OiBjdXJzb3JJbWFnZVNpemVQeCxcbiAgICB9KTtcblxuICAgIGxldCBwcmV2aWV3RGF0YVVSTCA9IGF3YWl0IGdldERhdGFVUkwoaW1hZ2VQcmV2aWV3KTtcblxuICAgIC8vIFNWRyBjYW5ub3QgYmUgcmVzaXplZCB2aWEgYHJlc2l6ZUltYWdlRmlsZWAgc28gd2UgcmVzaXplIGJ5IHJlbmRlcmluZyB0b1xuICAgIC8vIGEgc21hbGwgY2FudmFzXG4gICAgaWYgKGltYWdlRmlsZS50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgY29uc3QgaW1nID0gYXdhaXQgbG9hZEhUTUxJbWFnZUVsZW1lbnQocHJldmlld0RhdGFVUkwpO1xuXG4gICAgICBsZXQgaGVpZ2h0ID0gTWF0aC5taW4oaW1nLmhlaWdodCwgY3Vyc29ySW1hZ2VTaXplUHgpO1xuICAgICAgbGV0IHdpZHRoID0gaGVpZ2h0ICogKGltZy53aWR0aCAvIGltZy5oZWlnaHQpO1xuXG4gICAgICBpZiAod2lkdGggPiBjdXJzb3JJbWFnZVNpemVQeCkge1xuICAgICAgICB3aWR0aCA9IGN1cnNvckltYWdlU2l6ZVB4O1xuICAgICAgICBoZWlnaHQgPSB3aWR0aCAqIChpbWcuaGVpZ2h0IC8gaW1nLndpZHRoKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICBjYW52YXMud2lkdGggPSB3aWR0aDtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpITtcblxuICAgICAgY29udGV4dC5kcmF3SW1hZ2UoaW1nLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgcHJldmlld0RhdGFVUkwgPSBjYW52YXMudG9EYXRhVVJMKE1JTUVfVFlQRVMuc3ZnKSBhcyBEYXRhVVJMO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgYHVybCgke3ByZXZpZXdEYXRhVVJMfSkgNCA0LCBhdXRvYCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25JbWFnZUFjdGlvbiA9IGFzeW5jIChcbiAgICB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHkgfSA9IHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseTogZmFsc2UgfSxcbiAgKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNsaWVudFggPSB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdDtcbiAgICAgIGNvbnN0IGNsaWVudFkgPSB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcDtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2VGaWxlID0gYXdhaXQgZmlsZU9wZW4oe1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJbWFnZVwiLFxuICAgICAgICBleHRlbnNpb25zOiBbXCJqcGdcIiwgXCJwbmdcIiwgXCJzdmdcIiwgXCJnaWZcIl0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoe1xuICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgIHNjZW5lWTogeSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaW5zZXJ0T25DYW52YXNEaXJlY3RseSkge1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGltYWdlRmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnQ6IGltYWdlRWxlbWVudCxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KFxuICAgICAgICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgICAgICAgIGltYWdlRmlsZSxcbiAgICAgICAgICAgICAgLyogc2hvd0N1cnNvckltYWdlUHJldmlldyAqLyB0cnVlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkFib3J0RXJyb3JcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICB9XG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBlZGl0aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBlbGVtZW50VHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyA9IChcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gICAgZm9yY2VOYXR1cmFsU2l6ZSA9IGZhbHNlLFxuICApID0+IHtcbiAgICBjb25zdCBpbWFnZSA9XG4gICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCkgJiZcbiAgICAgIHRoaXMuaW1hZ2VDYWNoZS5nZXQoaW1hZ2VFbGVtZW50LmZpbGVJZCk/LmltYWdlO1xuXG4gICAgaWYgKCFpbWFnZSB8fCBpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgIGlmIChcbiAgICAgICAgaW1hZ2VFbGVtZW50LndpZHRoIDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlICYmXG4gICAgICAgIGltYWdlRWxlbWVudC5oZWlnaHQgPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWVcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwbGFjZWhvbGRlclNpemUgPSAxMDAgLyB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7XG4gICAgICAgICAgeDogaW1hZ2VFbGVtZW50LnggLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHk6IGltYWdlRWxlbWVudC55IC0gcGxhY2Vob2xkZXJTaXplIC8gMixcbiAgICAgICAgICB3aWR0aDogcGxhY2Vob2xkZXJTaXplLFxuICAgICAgICAgIGhlaWdodDogcGxhY2Vob2xkZXJTaXplLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGZvcmNlTmF0dXJhbFNpemUgfHxcbiAgICAgIC8vIGlmIHVzZXItY3JlYXRlZCBib3VuZGluZyBib3ggaXMgYmVsb3cgdGhyZXNob2xkLCBhc3N1bWUgdGhlXG4gICAgICAvLyBpbnRlbnRpb24gd2FzIHRvIGNsaWNrIGluc3RlYWQgb2YgZHJhZywgYW5kIHVzZSB0aGUgaW1hZ2Unc1xuICAgICAgLy8gaW50cmluc2ljIHNpemVcbiAgICAgIChpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSlcbiAgICApIHtcbiAgICAgIGNvbnN0IG1pbkhlaWdodCA9IE1hdGgubWF4KHRoaXMuc3RhdGUuaGVpZ2h0IC0gMTIwLCAxNjApO1xuICAgICAgLy8gbWF4IDY1JSBvZiBjYW52YXMgaGVpZ2h0LCBjbGFtcGVkIHRvIDwzMDBweCwgdmggLSAxMjBweD5cbiAgICAgIGNvbnN0IG1heEhlaWdodCA9IE1hdGgubWluKFxuICAgICAgICBtaW5IZWlnaHQsXG4gICAgICAgIE1hdGguZmxvb3IodGhpcy5zdGF0ZS5oZWlnaHQgKiAwLjUpIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5taW4oaW1hZ2UubmF0dXJhbEhlaWdodCwgbWF4SGVpZ2h0KTtcbiAgICAgIGNvbnN0IHdpZHRoID0gaGVpZ2h0ICogKGltYWdlLm5hdHVyYWxXaWR0aCAvIGltYWdlLm5hdHVyYWxIZWlnaHQpO1xuXG4gICAgICAvLyBhZGQgY3VycmVudCBpbWFnZUVsZW1lbnQgd2lkdGgvaGVpZ2h0IHRvIGFjY291bnQgZm9yIHByZXZpb3VzIGNlbnRlcmluZ1xuICAgICAgLy8gb2YgdGhlIHBsYWNob2xkZXIgaW1hZ2VcbiAgICAgIGNvbnN0IHggPSBpbWFnZUVsZW1lbnQueCArIGltYWdlRWxlbWVudC53aWR0aCAvIDIgLSB3aWR0aCAvIDI7XG4gICAgICBjb25zdCB5ID0gaW1hZ2VFbGVtZW50LnkgKyBpbWFnZUVsZW1lbnQuaGVpZ2h0IC8gMiAtIGhlaWdodCAvIDI7XG5cbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7IHgsIHksIHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiB1cGRhdGVzIGltYWdlIGNhY2hlLCByZWZyZXNoaW5nIHVwZGF0ZWQgZWxlbWVudHMgYW5kL29yIHNldHRpbmcgc3RhdHVzXG4gICAgICB0byBlcnJvciBmb3IgaW1hZ2VzIHRoYXQgZmFpbCBkdXJpbmcgPGltZz4gZWxlbWVudCBjcmVhdGlvbiAqL1xuICBwcml2YXRlIHVwZGF0ZUltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdLFxuICAgIGZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgeyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9ID0gYXdhaXQgX3VwZGF0ZUltYWdlQ2FjaGUoe1xuICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgZmlsZUlkczogZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiBlbGVtZW50LmZpbGVJZCksXG4gICAgICBmaWxlcyxcbiAgICB9KTtcbiAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUgfHwgZXJyb3JlZEZpbGVzLnNpemUpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICBpZiAodXBkYXRlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZCkpIHtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgICAgZXJyb3JlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGVtZW50LCB7XG4gICAgICAgICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdXBkYXRlZEZpbGVzLCBlcnJvcmVkRmlsZXMgfTtcbiAgfTtcblxuICAvKiogYWRkcyBuZXcgaW1hZ2VzIHRvIGltYWdlQ2FjaGUgYW5kIHJlLXJlbmRlcnMgaWYgbmVlZGVkICovXG4gIHByaXZhdGUgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudHM6IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdID0gZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICksXG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgdW5jYWNoZWRJbWFnZUVsZW1lbnRzID0gaW1hZ2VFbGVtZW50cy5maWx0ZXIoXG4gICAgICAoZWxlbWVudCkgPT4gIWVsZW1lbnQuaXNEZWxldGVkICYmICF0aGlzLmltYWdlQ2FjaGUuaGFzKGVsZW1lbnQuZmlsZUlkKSxcbiAgICApO1xuXG4gICAgaWYgKHVuY2FjaGVkSW1hZ2VFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHsgdXBkYXRlZEZpbGVzIH0gPSBhd2FpdCB0aGlzLnVwZGF0ZUltYWdlQ2FjaGUoXG4gICAgICAgIHVuY2FjaGVkSW1hZ2VFbGVtZW50cyxcbiAgICAgICAgZmlsZXMsXG4gICAgICApO1xuICAgICAgaWYgKHVwZGF0ZWRGaWxlcy5zaXplKSB7XG4gICAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqIGdlbmVyYWxseSB5b3Ugc2hvdWxkIHVzZSBgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKClgIGRpcmVjdGx5IGlmIHlvdSBuZWVkXG4gICAqICB0byByZW5kZXIgbmV3IGltYWdlcy4gVGhpcyBpcyBqdXN0IGEgZmFpbHNhZmUgICovXG4gIHByaXZhdGUgc2NoZWR1bGVJbWFnZVJlZnJlc2ggPSB0aHJvdHRsZSgoKSA9PiB7XG4gICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgfSwgSU1BR0VfUkVOREVSX1RJTUVPVVQpO1xuXG4gIHByaXZhdGUgdXBkYXRlQmluZGluZ0VuYWJsZWRPblBvaW50ZXJNb3ZlID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICBjb25zdCBzaG91bGRFbmFibGVCaW5kaW5nID0gc2hvdWxkRW5hYmxlQmluZGluZ0ZvclBvaW50ZXJFdmVudChldmVudCk7XG4gICAgaWYgKHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCAhPT0gc2hvdWxkRW5hYmxlQmluZGluZykge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHNob3VsZEVuYWJsZUJpbmRpbmcgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yID0gKHBvaW50ZXJDb29yZHM6IHtcbiAgICB4OiBudW1iZXI7XG4gICAgeTogbnVtYmVyO1xuICB9KTogdm9pZCA9PiB7XG4gICAgY29uc3QgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICB0aGlzLnNjZW5lLFxuICAgICk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzdWdnZXN0ZWRCaW5kaW5nczpcbiAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCAhPSBudWxsID8gW2hvdmVyZWRCaW5kYWJsZUVsZW1lbnRdIDogW10sXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyA9IChcbiAgICBsaW5lYXJFbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICAvKiogc2NlbmUgY29vcmRzICovXG4gICAgcG9pbnRlckNvb3Jkczoge1xuICAgICAgeDogbnVtYmVyO1xuICAgICAgeTogbnVtYmVyO1xuICAgIH1bXSxcbiAgICAvLyBEdXJpbmcgbGluZSBjcmVhdGlvbiB0aGUgc3RhcnQgYmluZGluZyBoYXNuJ3QgYmVlbiB3cml0dGVuIHlldFxuICAgIC8vIGludG8gYGxpbmVhckVsZW1lbnRgXG4gICAgb3Bwb3NpdGVCaW5kaW5nQm91bmRFbGVtZW50PzogRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCB8IG51bGwsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICghcG9pbnRlckNvb3Jkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IHBvaW50ZXJDb29yZHMucmVkdWNlKFxuICAgICAgKGFjYzogTm9uRGVsZXRlZDxFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50PltdLCBjb29yZHMpID0+IHtcbiAgICAgICAgY29uc3QgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgICBjb29yZHMsXG4gICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICAgICFpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQoXG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgb3Bwb3NpdGVCaW5kaW5nQm91bmRFbGVtZW50Py5pZCxcbiAgICAgICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQsXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICBhY2MucHVzaChob3ZlcmVkQmluZGFibGVFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIFtdLFxuICAgICk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3MgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHN1Z2dlc3RlZEJpbmRpbmdzID0gZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbihoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAvLyBDb250aW51ZSBlZGl0aW5nIHRoZSBzYW1lIGdyb3VwIGlmIHRoZSB1c2VyIHNlbGVjdGVkIGEgZGlmZmVyZW50XG4gICAgICAvLyBlbGVtZW50IGZyb20gaXRcbiAgICAgIGVkaXRpbmdHcm91cElkOlxuICAgICAgICBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWQgJiZcbiAgICAgICAgaGl0RWxlbWVudCAhPSBudWxsICYmXG4gICAgICAgIGlzRWxlbWVudEluR3JvdXAoaGl0RWxlbWVudCwgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgID8gcHJldlN0YXRlLmVkaXRpbmdHcm91cElkXG4gICAgICAgICAgOiBudWxsLFxuICAgIH0pKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1JlZiA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB7XG4gICAgLy8gY2FudmFzIGlzIG51bGwgd2hlbiB1bm1vdW50aW5nXG4gICAgaWYgKGNhbnZhcyAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5jYW52YXMgPSBjYW52YXM7XG4gICAgICB0aGlzLnJjID0gcm91Z2guY2FudmFzKHRoaXMuY2FudmFzKTtcblxuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5XSEVFTCwgdGhpcy5oYW5kbGVXaGVlbCwge1xuICAgICAgICBwYXNzaXZlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9TVEFSVCwgdGhpcy5vblRhcFN0YXJ0KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9FTkQsIHRoaXMub25UYXBFbmQpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUFwcE9uRHJvcCA9IGFzeW5jIChldmVudDogUmVhY3QuRHJhZ0V2ZW50PEhUTUxEaXZFbGVtZW50PikgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBmaWxlID0gZXZlbnQuZGF0YVRyYW5zZmVyLmZpbGVzWzBdO1xuXG4gICAgICBpZiAoaXNTdXBwb3J0ZWRJbWFnZUZpbGUoZmlsZSkpIHtcbiAgICAgICAgLy8gZmlyc3QgYXR0ZW1wdCB0byBkZWNvZGUgc2NlbmUgZnJvbSB0aGUgaW1hZ2UgaWYgaXQncyBlbWJlZGRlZFxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgICAgICBpZiAoZmlsZT8udHlwZSA9PT0gTUlNRV9UWVBFUy5wbmcgfHwgZmlsZT8udHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUZpbGVTeXN0ZW1TdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIHdpbGwgb25seSB3b3JrIGFzIG9mIENocm9tZSA4NixcbiAgICAgICAgICAgICAgICAvLyBidXQgY2FuIGJlIHNhZmVseSBpZ25vcmVkIG9uIG9sZGVyIHJlbGVhc2VzLlxuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBldmVudC5kYXRhVHJhbnNmZXIuaXRlbXNbMF07XG4gICAgICAgICAgICAgICAgKGZpbGUgYXMgYW55KS5oYW5kbGUgPSBhd2FpdCAoXG4gICAgICAgICAgICAgICAgICBpdGVtIGFzIGFueVxuICAgICAgICAgICAgICAgICkuZ2V0QXNGaWxlU3lzdGVtSGFuZGxlKCk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IubmFtZSwgZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc2NlbmUgPSBhd2FpdCBsb2FkRnJvbUJsb2IoXG4gICAgICAgICAgICAgIGZpbGUsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgICAgICAgICAgLi4uc2NlbmUsXG4gICAgICAgICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgICAgICAgLi4uKHNjZW5lLmFwcFN0YXRlIHx8IHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHJlcGxhY2VGaWxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgIT09IFwiRW5jb2RpbmdFcnJvclwiKSB7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIG5vIHNjZW5lIGlzIGVtYmVkZGVkIG9yIHdlIGZhaWwgZm9yIHdoYXRldmVyIHJlYXNvbiwgZmFsbCBiYWNrXG4gICAgICAgIC8vIHRvIGltcG9ydGluZyBhcyByZWd1bGFyIGltYWdlXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGNvbnN0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICBldmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHsgc2NlbmVYLCBzY2VuZVkgfSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgZmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgbGlicmFyeVNoYXBlcyA9IGV2ZW50LmRhdGFUcmFuc2Zlci5nZXREYXRhKE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYik7XG4gICAgaWYgKGxpYnJhcnlTaGFwZXMgIT09IFwiXCIpIHtcbiAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICBlbGVtZW50czogSlNPTi5wYXJzZShsaWJyYXJ5U2hhcGVzKSxcbiAgICAgICAgcG9zaXRpb246IGV2ZW50LFxuICAgICAgICBmaWxlczogbnVsbCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbGUgPSBldmVudC5kYXRhVHJhbnNmZXI/LmZpbGVzWzBdO1xuICAgIGlmIChcbiAgICAgIGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYiB8fFxuICAgICAgZmlsZT8ubmFtZT8uZW5kc1dpdGgoXCIuZXhjYWxpZHJhd2xpYlwiKVxuICAgICkge1xuICAgICAgdGhpcy5saWJyYXJ5XG4gICAgICAgIC5pbXBvcnRMaWJyYXJ5KGZpbGUpXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAvLyBDbG9zZSBhbmQgdGhlbiBvcGVuIHRvIGdldCB0aGUgbGlicmFyaWVzIHVwZGF0ZWRcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogZmFsc2UgfSk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IHRydWUgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogZmFsc2UsIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KSxcbiAgICAgICAgKTtcbiAgICAgIC8vIGRlZmF1bHQ6IGFzc3VtZSBhbiBFeGNhbGlkcmF3IGZpbGUgcmVnYXJkbGVzcyBvZiBleHRlbnNpb24vTWltZVR5cGVcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgIGlmIChuYXRpdmVGaWxlU3lzdGVtU3VwcG9ydGVkKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gVGhpcyB3aWxsIG9ubHkgd29yayBhcyBvZiBDaHJvbWUgODYsXG4gICAgICAgICAgLy8gYnV0IGNhbiBiZSBzYWZlbHkgaWdub3JlZCBvbiBvbGRlciByZWxlYXNlcy5cbiAgICAgICAgICBjb25zdCBpdGVtID0gZXZlbnQuZGF0YVRyYW5zZmVyLml0ZW1zWzBdO1xuICAgICAgICAgIChmaWxlIGFzIGFueSkuaGFuZGxlID0gYXdhaXQgKGl0ZW0gYXMgYW55KS5nZXRBc0ZpbGVTeXN0ZW1IYW5kbGUoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvci5uYW1lLCBlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUpO1xuICAgIH1cbiAgfTtcblxuICBsb2FkRmlsZVRvQ2FudmFzID0gKGZpbGU6IEJsb2IpID0+IHtcbiAgICBsb2FkRnJvbUJsb2IoZmlsZSwgdGhpcy5zdGF0ZSwgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSlcbiAgICAgIC50aGVuKChzY2VuZSkgPT4ge1xuICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgIC4uLnNjZW5lLFxuICAgICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgICAuLi4oc2NlbmUuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiBmYWxzZSwgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNDb250ZXh0TWVudSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7IHByZWZlclNlbGVjdGVkOiB0cnVlIH0pO1xuXG4gICAgY29uc3QgdHlwZSA9IGVsZW1lbnQgPyBcImVsZW1lbnRcIiA6IFwiY2FudmFzXCI7XG5cbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCE7XG4gICAgY29uc3QgeyB0b3A6IG9mZnNldFRvcCwgbGVmdDogb2Zmc2V0TGVmdCB9ID1cbiAgICAgIGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBsZWZ0ID0gZXZlbnQuY2xpZW50WCAtIG9mZnNldExlZnQ7XG4gICAgY29uc3QgdG9wID0gZXZlbnQuY2xpZW50WSAtIG9mZnNldFRvcDtcblxuICAgIGlmIChlbGVtZW50ICYmICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1tlbGVtZW50LmlkXSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbZWxlbWVudC5pZF06IHRydWUgfSB9LCAoKSA9PiB7XG4gICAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9vcGVuQ29udGV4dE1lbnUoeyB0b3AsIGxlZnQgfSwgdHlwZSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQsXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGRyYWdnaW5nRWxlbWVudCA9IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50O1xuICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHM7XG4gICAgaWYgKCFkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICBkcmFnTmV3RWxlbWVudChcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCwgcG9pbnRlckNvb3Jkcy54KSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSwgcG9pbnRlckNvb3Jkcy55KSxcbiAgICAgICAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2UgPVxuICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkgJiZcbiAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChkcmFnZ2luZ0VsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG4gICAgICBjb25zdCBhc3BlY3RSYXRpbyA9XG4gICAgICAgIGltYWdlICYmICEoaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICAgID8gaW1hZ2Uud2lkdGggLyBpbWFnZS5oZWlnaHRcbiAgICAgICAgICA6IG51bGw7XG5cbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksXG4gICAgICAgIGdyaWRYLFxuICAgICAgICBncmlkWSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCwgZ3JpZFgpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LCBncmlkWSksXG4gICAgICAgIGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBhc3BlY3RSYXRpbyxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChbZHJhZ2dpbmdFbGVtZW50XSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVIYW5kbGVSZXNpemUgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IHRyYW5zZm9ybUhhbmRsZVR5cGUgPSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLy8gVE9ETzogcmVuYW1lIHRoaXMgc3RhdGUgZmllbGQgdG8gXCJpc1NjYWxpbmdcIiB0byBkaXN0aW5ndWlzaFxuICAgICAgLy8gaXQgZnJvbSB0aGUgZ2VuZXJpYyBcImlzUmVzaXppbmdcIiB3aGljaCBpbmNsdWRlcyBzY2FsaW5nIGFuZFxuICAgICAgLy8gcm90YXRpbmdcbiAgICAgIGlzUmVzaXppbmc6IHRyYW5zZm9ybUhhbmRsZVR5cGUgJiYgdHJhbnNmb3JtSGFuZGxlVHlwZSAhPT0gXCJyb3RhdGlvblwiLFxuICAgICAgaXNSb3RhdGluZzogdHJhbnNmb3JtSGFuZGxlVHlwZSA9PT0gXCJyb3RhdGlvblwiLFxuICAgIH0pO1xuICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHM7XG4gICAgY29uc3QgW3Jlc2l6ZVgsIHJlc2l6ZVldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0LngsXG4gICAgICBwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQueSxcbiAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICB0cmFuc2Zvcm1FbGVtZW50cyhcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuYXJyb3dEaXJlY3Rpb24sXG4gICAgICAgIHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmIGlzSW1hZ2VFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICAgPyAhc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudClcbiAgICAgICAgICA6IHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICByZXNpemVYLFxuICAgICAgICByZXNpemVZLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5jZW50ZXIueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuY2VudGVyLnksXG4gICAgICApXG4gICAgKSB7XG4gICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIC8qKiBAcHJpdmF0ZSB1c2UgdGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudSAqL1xuICBwcml2YXRlIF9vcGVuQ29udGV4dE1lbnUgPSAoXG4gICAge1xuICAgICAgbGVmdCxcbiAgICAgIHRvcCxcbiAgICB9OiB7XG4gICAgICBsZWZ0OiBudW1iZXI7XG4gICAgICB0b3A6IG51bWJlcjtcbiAgICB9LFxuICAgIHR5cGU6IFwiY2FudmFzXCIgfCBcImVsZW1lbnRcIixcbiAgKSA9PiB7XG4gICAgY29uc3QgbWF5YmVHcm91cEFjdGlvbiA9IGFjdGlvbkdyb3VwLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZVVuZ3JvdXBBY3Rpb24gPSBhY3Rpb25Vbmdyb3VwLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZUZsaXBIb3Jpem9udGFsID0gYWN0aW9uRmxpcEhvcml6b250YWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcFZlcnRpY2FsID0gYWN0aW9uRmxpcFZlcnRpY2FsLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBzZXBhcmF0b3IgPSBcInNlcGFyYXRvclwiO1xuXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCk7XG5cbiAgICBjb25zdCBvcHRpb25zOiBDb250ZXh0TWVudU9wdGlvbltdID0gW107XG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNQbmcpO1xuICAgIH1cblxuICAgIGlmIChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNTdmcpO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gXCJjYW52YXNcIikge1xuICAgICAgY29uc3Qgdmlld01vZGVPcHRpb25zID0gW1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiYgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgYWN0aW9uVG9nZ2xlVmlld01vZGUsXG4gICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgXTtcblxuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IHZpZXdNb2RlT3B0aW9ucyxcbiAgICAgICAgICB0b3AsXG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICBhY3Rpb25NYW5hZ2VyOiB0aGlzLmFjdGlvbk1hbmFnZXIsXG4gICAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogW1xuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJlxuICAgICAgICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcInBhc3RlXCIsXG4gICAgICAgICAgICAgICAgcGVyZm9ybTogKGVsZW1lbnRzLCBhcHBTdGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKG51bGwpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZXh0SXRlbUxhYmVsOiBcImxhYmVscy5wYXN0ZVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmXG4gICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgYWN0aW9uQ29weUFzUG5nLFxuICAgICAgICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJlxuICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGFjdGlvbkNvcHlBc1N2ZyxcbiAgICAgICAgICAgICgocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkgfHxcbiAgICAgICAgICAgICAgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkpICYmXG4gICAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbGVjdEFsbCxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlVmlld01vZGUsXG4gICAgICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImVsZW1lbnRcIikge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksIC4uLm9wdGlvbnNdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmIGFjdGlvbkN1dCxcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiYgbmF2aWdhdG9yLmNsaXBib2FyZCAmJiBhY3Rpb25Db3B5LFxuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJlxuICAgICAgICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcInBhc3RlXCIsXG4gICAgICAgICAgICAgICAgcGVyZm9ybTogKGVsZW1lbnRzLCBhcHBTdGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKG51bGwpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZXh0SXRlbUxhYmVsOiBcImxhYmVscy5wYXN0ZVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uQ29weVN0eWxlcyxcbiAgICAgICAgICAgIGFjdGlvblBhc3RlU3R5bGVzLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgbWF5YmVHcm91cEFjdGlvbiAmJiBhY3Rpb25Hcm91cCxcbiAgICAgICAgICAgIG1heWJlVW5ncm91cEFjdGlvbiAmJiBhY3Rpb25Vbmdyb3VwLFxuICAgICAgICAgICAgKG1heWJlR3JvdXBBY3Rpb24gfHwgbWF5YmVVbmdyb3VwQWN0aW9uKSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gICAgICAgICAgICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gICAgICAgICAgICBhY3Rpb25TZW5kVG9CYWNrLFxuICAgICAgICAgICAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgbWF5YmVGbGlwSG9yaXpvbnRhbCAmJiBhY3Rpb25GbGlwSG9yaXpvbnRhbCxcbiAgICAgICAgICAgIG1heWJlRmxpcFZlcnRpY2FsICYmIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgICAgICAgICAgIChtYXliZUZsaXBIb3Jpem9udGFsIHx8IG1heWJlRmxpcFZlcnRpY2FsKSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25EdXBsaWNhdGVTZWxlY3Rpb24sXG4gICAgICAgICAgICBhY3Rpb25EZWxldGVTZWxlY3RlZCxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlV2hlZWwgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBXaGVlbEV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmIChpc1Bhbm5pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGRlbHRhWCwgZGVsdGFZIH0gPSBldmVudDtcbiAgICBjb25zdCB7IHNlbGVjdGVkRWxlbWVudElkcywgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMgfSA9IHRoaXMuc3RhdGU7XG4gICAgLy8gbm90ZSB0aGF0IGV2ZW50LmN0cmxLZXkgaXMgbmVjZXNzYXJ5IHRvIGhhbmRsZSBwaW5jaCB6b29taW5nXG4gICAgaWYgKGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleSkge1xuICAgICAgY29uc3Qgc2lnbiA9IE1hdGguc2lnbihkZWx0YVkpO1xuICAgICAgY29uc3QgTUFYX1NURVAgPSAxMDtcbiAgICAgIGxldCBkZWx0YSA9IE1hdGguYWJzKGRlbHRhWSk7XG4gICAgICBpZiAoZGVsdGEgPiBNQVhfU1RFUCkge1xuICAgICAgICBkZWx0YSA9IE1BWF9TVEVQO1xuICAgICAgfVxuICAgICAgZGVsdGEgKj0gc2lnbjtcbiAgICAgIGlmIChPYmplY3Qua2V5cyhwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcykubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgMTAwMCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBuZXdab29tID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlIC0gZGVsdGEgLyAxMDA7XG4gICAgICAvLyBpbmNyZWFzZSB6b29tIHN0ZXBzIHRoZSBtb3JlIHpvb21lZC1pbiB3ZSBhcmUgKGFwcGxpZXMgdG8gPjEwMCUgb25seSlcbiAgICAgIG5ld1pvb20gKz0gTWF0aC5sb2cxMChNYXRoLm1heCgxLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSAqIC1zaWduO1xuICAgICAgLy8gcm91bmQgdG8gbmVhcmVzdCBzdGVwXG4gICAgICBuZXdab29tID0gTWF0aC5yb3VuZChuZXdab29tICogWk9PTV9TVEVQICogMTAwKSAvIChaT09NX1NURVAgKiAxMDApO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIG9mZnNldExlZnQsIG9mZnNldFRvcCB9KSA9PiAoe1xuICAgICAgICB6b29tOiBnZXROZXdab29tKFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWRab29tKG5ld1pvb20pLFxuICAgICAgICAgIHpvb20sXG4gICAgICAgICAgeyBsZWZ0OiBvZmZzZXRMZWZ0LCB0b3A6IG9mZnNldFRvcCB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHg6IGN1cnNvclgsXG4gICAgICAgICAgICB5OiBjdXJzb3JZLFxuICAgICAgICAgIH0sXG4gICAgICAgICksXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOlxuICAgICAgICAgIE9iamVjdC5rZXlzKHNlbGVjdGVkRWxlbWVudElkcykubGVuZ3RoICE9PSAwXG4gICAgICAgICAgICA/IHNlbGVjdGVkRWxlbWVudElkc1xuICAgICAgICAgICAgOiBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHNjcm9sbCBob3Jpem9udGFsbHkgd2hlbiBzaGlmdCBwcmVzc2VkXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIHNjcm9sbFggfSkgPT4gKHtcbiAgICAgICAgLy8gb24gTWFjLCBzaGlmdCt3aGVlbCB0ZW5kcyB0byByZXN1bHQgaW4gZGVsdGFYXG4gICAgICAgIHNjcm9sbFg6IHNjcm9sbFggLSAoZGVsdGFZIHx8IGRlbHRhWCkgLyB6b29tLnZhbHVlLFxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCwgc2Nyb2xsWSB9KSA9PiAoe1xuICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIGRlbHRhWCAvIHpvb20udmFsdWUsXG4gICAgICBzY3JvbGxZOiBzY3JvbGxZIC0gZGVsdGFZIC8gem9vbS52YWx1ZSxcbiAgICB9KSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCxcbiAgICBzY2FsZTogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBlbGVtZW50Q2xpY2tlZEluc2lkZSA9IGdldEVsZW1lbnRDb250YWluaW5nUG9zaXRpb24oXG4gICAgICB0aGlzLnNjZW5lXG4gICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAuZmlsdGVyKChlbGVtZW50KSA9PiAhaXNUZXh0RWxlbWVudChlbGVtZW50KSksXG4gICAgICB4LFxuICAgICAgeSxcbiAgICApO1xuICAgIGlmIChlbGVtZW50Q2xpY2tlZEluc2lkZSkge1xuICAgICAgY29uc3QgZWxlbWVudENlbnRlclggPVxuICAgICAgICBlbGVtZW50Q2xpY2tlZEluc2lkZS54ICsgZWxlbWVudENsaWNrZWRJbnNpZGUud2lkdGggLyAyO1xuICAgICAgY29uc3QgZWxlbWVudENlbnRlclkgPVxuICAgICAgICBlbGVtZW50Q2xpY2tlZEluc2lkZS55ICsgZWxlbWVudENsaWNrZWRJbnNpZGUuaGVpZ2h0IC8gMjtcbiAgICAgIGNvbnN0IGRpc3RhbmNlVG9DZW50ZXIgPSBNYXRoLmh5cG90KFxuICAgICAgICB4IC0gZWxlbWVudENlbnRlclgsXG4gICAgICAgIHkgLSBlbGVtZW50Q2VudGVyWSxcbiAgICAgICk7XG4gICAgICBjb25zdCBpc1NuYXBwZWRUb0NlbnRlciA9XG4gICAgICAgIGRpc3RhbmNlVG9DZW50ZXIgPCBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRDtcbiAgICAgIGlmIChpc1NuYXBwZWRUb0NlbnRlcikge1xuICAgICAgICBjb25zdCB7IHg6IHZpZXdwb3J0WCwgeTogdmlld3BvcnRZIH0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgICAgeyBzY2VuZVg6IGVsZW1lbnRDZW50ZXJYLCBzY2VuZVk6IGVsZW1lbnRDZW50ZXJZIH0sXG4gICAgICAgICAgYXBwU3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IHZpZXdwb3J0WCwgdmlld3BvcnRZLCBlbGVtZW50Q2VudGVyWCwgZWxlbWVudENlbnRlclkgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNhdmVQb2ludGVyID0gKHg6IG51bWJlciwgeTogbnVtYmVyLCBidXR0b246IFwidXBcIiB8IFwiZG93blwiKSA9PiB7XG4gICAgaWYgKCF4IHx8ICF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IHgsIGNsaWVudFk6IHkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChpc05hTihwb2ludGVyLngpIHx8IGlzTmFOKHBvaW50ZXIueSkpIHtcbiAgICAgIC8vIHNvbWV0aW1lcyB0aGUgcG9pbnRlciBnb2VzIG9mZiBzY3JlZW5cbiAgICB9XG5cbiAgICB0aGlzLnByb3BzLm9uUG9pbnRlclVwZGF0ZT8uKHtcbiAgICAgIHBvaW50ZXIsXG4gICAgICBidXR0b24sXG4gICAgICBwb2ludGVyc01hcDogZ2VzdHVyZS5wb2ludGVycyxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGlmICghdGhpcy51bm1vdW50ZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlIH0pO1xuICAgIH1cbiAgfSwgMzAwKTtcblxuICBwcml2YXRlIHVwZGF0ZURPTVJlY3QgPSAoY2I/OiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aCxcbiAgICAgICAgaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBvZmZzZXRMZWZ0LFxuICAgICAgICB0b3A6IG9mZnNldFRvcCxcbiAgICAgIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aDogY3VycmVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGN1cnJlbnRIZWlnaHQsXG4gICAgICAgIG9mZnNldFRvcDogY3VycmVudE9mZnNldFRvcCxcbiAgICAgICAgb2Zmc2V0TGVmdDogY3VycmVudE9mZnNldExlZnQsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgaWYgKFxuICAgICAgICB3aWR0aCA9PT0gY3VycmVudFdpZHRoICYmXG4gICAgICAgIGhlaWdodCA9PT0gY3VycmVudEhlaWdodCAmJlxuICAgICAgICBvZmZzZXRMZWZ0ID09PSBjdXJyZW50T2Zmc2V0TGVmdCAmJlxuICAgICAgICBvZmZzZXRUb3AgPT09IGN1cnJlbnRPZmZzZXRUb3BcbiAgICAgICkge1xuICAgICAgICBpZiAoY2IpIHtcbiAgICAgICAgICBjYigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICBvZmZzZXRMZWZ0LFxuICAgICAgICAgIG9mZnNldFRvcCxcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGNiICYmIGNiKCk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgcmVmcmVzaCA9ICgpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCkgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRDYW52YXNPZmZzZXRzKCk6IFBpY2s8QXBwU3RhdGUsIFwib2Zmc2V0VG9wXCIgfCBcIm9mZnNldExlZnRcIj4ge1xuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IGV4Y2FsaWRyYXdDb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb2Zmc2V0TGVmdDogbGVmdCxcbiAgICAgICAgb2Zmc2V0VG9wOiB0b3AsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb2Zmc2V0TGVmdDogMCxcbiAgICAgIG9mZnNldFRvcDogMCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVMYW5ndWFnZSgpIHtcbiAgICBjb25zdCBjdXJyZW50TGFuZyA9XG4gICAgICBsYW5ndWFnZXMuZmluZCgobGFuZykgPT4gbGFuZy5jb2RlID09PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB8fFxuICAgICAgZGVmYXVsdExhbmc7XG4gICAgYXdhaXQgc2V0TGFuZ3VhZ2UoY3VycmVudExhbmcpO1xuICAgIHRoaXMuc2V0QXBwU3RhdGUoe30pO1xuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBURVNUIEhPT0tTXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBXaW5kb3cge1xuICAgIGg6IHtcbiAgICAgIGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdO1xuICAgICAgc3RhdGU6IEFwcFN0YXRlO1xuICAgICAgc2V0U3RhdGU6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdO1xuICAgICAgYXBwOiBJbnN0YW5jZVR5cGU8dHlwZW9mIEFwcD47XG4gICAgICBoaXN0b3J5OiBIaXN0b3J5O1xuICAgIH07XG4gIH1cbn1cblxuaWYgKFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLlRFU1QgfHxcbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVFxuKSB7XG4gIHdpbmRvdy5oID0gd2luZG93LmggfHwgKHt9IGFzIFdpbmRvd1tcImhcIl0pO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgZWxlbWVudHM6IHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpO1xuICAgICAgfSxcbiAgICAgIHNldChlbGVtZW50czogRXhjYWxpZHJhd0VsZW1lbnRbXSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHAuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGVsZW1lbnRzKTtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG59XG5leHBvcnQgZGVmYXVsdCBBcHA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
1786
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"useIsMobile\": () => (/* binding */ useIsMobile),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\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 roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_3__ = __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.dev.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data/json */ \"../../data/json.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__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer */ \"../../renderer/index.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 _Stats__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Stats */ \"../../components/Stats.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_42__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst IsMobileContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(false);\r\nconst useIsMobile = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(IsMobileContext);\r\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\r\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\r\nlet didTapTwice = false;\r\nlet tappedTwiceTimer = 0;\r\nlet cursorX = 0;\r\nlet cursorY = 0;\r\nlet isHoldingSpace = false;\r\nlet isPanning = false;\r\nlet isDraggingScrollBar = false;\r\nlet currentScrollBars = { horizontal: null, vertical: null };\r\nlet touchTimeout = 0;\r\nlet invalidateContextMenu = false;\r\nlet lastPointerUp = null;\r\nconst gesture = {\r\n pointers: new Map(),\r\n lastCenter: null,\r\n initialDistance: null,\r\n initialScale: null,\r\n};\r\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\r\n constructor(props) {\r\n var _a;\r\n super(props);\r\n this.canvas = null;\r\n this.rc = null;\r\n this.unmounted = false;\r\n this.isMobile = false;\r\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\r\n this.files = {};\r\n this.imageCache = new Map();\r\n this.focusContainer = () => {\r\n var _a;\r\n if (this.props.autoFocus) {\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\r\n }\r\n };\r\n this.getSceneElementsIncludingDeleted = () => {\r\n return this.scene.getElementsIncludingDeleted();\r\n };\r\n this.getSceneElements = () => {\r\n return this.scene.getElements();\r\n };\r\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\r\n var _a, _b, _c, _d, _e, _f;\r\n if (this.unmounted || actionResult === false) {\r\n return;\r\n }\r\n let editingElement = null;\r\n if (actionResult.elements) {\r\n actionResult.elements.forEach((element) => {\r\n var _a;\r\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\r\n this.state.editingElement !== element &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n editingElement = element;\r\n }\r\n });\r\n this.scene.replaceAllElements(actionResult.elements);\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n }\r\n if (actionResult.files) {\r\n this.files = actionResult.replaceFiles\r\n ? actionResult.files\r\n : Object.assign(Object.assign({}, this.files), actionResult.files);\r\n this.addNewImagesToImageCache();\r\n }\r\n if (actionResult.appState || editingElement) {\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\r\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\r\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\r\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_11__.THEME.LIGHT;\r\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;\r\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\r\n viewModeEnabled = this.props.viewModeEnabled;\r\n }\r\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\r\n zenModeEnabled = this.props.zenModeEnabled;\r\n }\r\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\r\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null;\r\n }\r\n if (typeof this.props.theme !== \"undefined\") {\r\n theme = this.props.theme;\r\n }\r\n if (typeof this.props.name !== \"undefined\") {\r\n name = this.props.name;\r\n }\r\n this.setState((state) => {\r\n var _a;\r\n // using Object.assign instead of spread to fool TS 4.2.2+ into\r\n // regarding the resulting type as not containing undefined\r\n // (which the following expression will never contain)\r\n return Object.assign(actionResult.appState || {}, {\r\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\r\n viewModeEnabled,\r\n zenModeEnabled,\r\n gridSize,\r\n theme,\r\n name,\r\n });\r\n }, () => {\r\n if (actionResult.syncHistory) {\r\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\r\n }\r\n });\r\n }\r\n });\r\n // Lifecycle\r\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isHoldingSpace = false;\r\n this.setState({ isBindingEnabled: true });\r\n });\r\n this.onUnload = () => {\r\n this.onBlur();\r\n };\r\n this.disableEvent = (event) => {\r\n event.preventDefault();\r\n };\r\n this.onFontLoaded = () => {\r\n this.scene.getElementsIncludingDeleted().forEach((element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n });\r\n this.onSceneUpdated();\r\n };\r\n this.importLibraryFromUrl = (url, token) => __awaiter(this, void 0, void 0, function* () {\r\n if (window.location.hash.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary)) {\r\n const hash = new URLSearchParams(window.location.hash.slice(1));\r\n hash.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `#${hash.toString()}`);\r\n }\r\n else if (window.location.search.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary)) {\r\n const query = new URLSearchParams(window.location.search);\r\n query.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `?${query.toString()}`);\r\n }\r\n try {\r\n const request = yield fetch(decodeURIComponent(url));\r\n const blob = yield request.blob();\r\n const json = JSON.parse(yield blob.text());\r\n if (!(0,_data_json__WEBPACK_IMPORTED_MODULE_13__.isValidLibrary)(json)) {\r\n throw new Error();\r\n }\r\n if (token === this.id ||\r\n window.confirm((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.confirmAddLibrary\", {\r\n numShapes: (json.libraryItems || json.library || []).length,\r\n }))) {\r\n yield this.library.importLibrary(blob, \"published\");\r\n // hack to rerender the library items after import\r\n if (this.state.isLibraryOpen) {\r\n this.setState({ isLibraryOpen: false });\r\n }\r\n this.setState({ isLibraryOpen: true });\r\n }\r\n }\r\n catch (error) {\r\n window.alert((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.errorLoadingLibrary\"));\r\n console.error(error);\r\n }\r\n finally {\r\n this.focusContainer();\r\n }\r\n });\r\n this.resetHistory = () => {\r\n this.history.clear();\r\n };\r\n /**\r\n * Resets scene & history.\r\n * ! Do not use to clear scene user action !\r\n */\r\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\r\n this.scene.replaceAllElements([]);\r\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\r\n this.resetHistory();\r\n });\r\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\r\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\r\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\r\n if (!launchParams.files.length) {\r\n return;\r\n }\r\n const fileHandle = launchParams.files[0];\r\n const blob = yield fileHandle.getFile();\r\n blob.handle = fileHandle;\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(blob, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n }));\r\n }\r\n if (!this.state.isLoading) {\r\n this.setState({ isLoading: true });\r\n }\r\n let initialData = null;\r\n try {\r\n initialData = (yield this.props.initialData) || null;\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\r\n this.libraryItemsFromStorage = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreLibraryItems)(initialData.libraryItems, \"unpublished\");\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n initialData = {\r\n appState: {\r\n errorMessage: error.message ||\r\n \"Encountered an error during importing or restoring scene data\",\r\n },\r\n };\r\n }\r\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null);\r\n scene.appState = Object.assign(Object.assign({}, scene.appState), { elementType: scene.appState.elementType === \"image\"\r\n ? \"selection\"\r\n : scene.appState.elementType, isLoading: false });\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\r\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));\r\n }\r\n this.resetHistory();\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\r\n const libraryUrl = \r\n // current\r\n new URLSearchParams(window.location.hash.slice(1)).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary) ||\r\n // legacy, kept for compat reasons\r\n new URLSearchParams(window.location.search).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n if (libraryUrl) {\r\n yield this.importLibraryFromUrl(libraryUrl);\r\n }\r\n });\r\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n this.scene\r\n .getElementsIncludingDeleted()\r\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\r\n this.setState({});\r\n });\r\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\r\n this.setState((state) => {\r\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\r\n return null;\r\n }\r\n return { offsetTop, offsetLeft };\r\n });\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.SCROLL_TIMEOUT);\r\n // Copy/paste\r\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.cutAll();\r\n event.preventDefault();\r\n });\r\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.copyAll();\r\n event.preventDefault();\r\n });\r\n this.cutAll = () => {\r\n this.copyAll();\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected);\r\n };\r\n this.copyAll = () => {\r\n (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.copyToClipboard)(this.scene.getElements(), this.state, this.files);\r\n };\r\n this.onTapStart = (event) => {\r\n if (!didTapTwice) {\r\n didTapTwice = true;\r\n clearTimeout(tappedTwiceTimer);\r\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_11__.TAP_TWICE_TIMEOUT);\r\n return;\r\n }\r\n // insert text only if we tapped twice with a single finger\r\n // event.touches.length === 1 will also prevent inserting text when user's zooming\r\n if (didTapTwice && event.touches.length === 1) {\r\n const [touch] = event.touches;\r\n // @ts-ignore\r\n this.handleCanvasDoubleClick({\r\n clientX: touch.clientX,\r\n clientY: touch.clientY,\r\n });\r\n didTapTwice = false;\r\n clearTimeout(tappedTwiceTimer);\r\n }\r\n event.preventDefault();\r\n if (event.touches.length === 2) {\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n }\r\n };\r\n this.onTapEnd = (event) => {\r\n if (event.touches.length > 0) {\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n }\r\n };\r\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\r\n var _b, _c;\r\n // #686\r\n const target = document.activeElement;\r\n const isExcalidrawActive = (_b = this.excalidrawContainerRef.current) === null || _b === void 0 ? void 0 : _b.contains(target);\r\n if (!isExcalidrawActive) {\r\n return;\r\n }\r\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\r\n if (\r\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\r\n // thus these checks don't make sense\r\n event &&\r\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\r\n return;\r\n }\r\n // must be called in the same frame (thus before any awaits) as the paste\r\n // event else some browsers (FF...) will clear the clipboardData\r\n // (something something security)\r\n let file = (_c = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _c === void 0 ? void 0 : _c.files[0];\r\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.parseClipboard)(event);\r\n if (!file && data.text) {\r\n const string = data.text.trim();\r\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\r\n // ignore SVG validation/normalization which will be done during image\r\n // initialization\r\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(string);\r\n }\r\n }\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n if (this.props.onPaste) {\r\n try {\r\n if ((yield this.props.onPaste(data, event)) === false) {\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n }\r\n }\r\n if (data.errorMessage) {\r\n this.setState({ errorMessage: data.errorMessage });\r\n }\r\n else if (data.spreadsheet) {\r\n this.setState({\r\n pasteDialog: {\r\n data: data.spreadsheet,\r\n shown: true,\r\n },\r\n });\r\n }\r\n else if (data.elements) {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: data.elements,\r\n files: data.files || null,\r\n position: \"cursor\",\r\n });\r\n }\r\n else if (data.text) {\r\n this.addTextFromPaste(data.text);\r\n }\r\n this.selectShapeTool(\"selection\");\r\n event === null || event === void 0 ? void 0 : event.preventDefault();\r\n }));\r\n this.addElementsFromPasteOrLibrary = (opts) => {\r\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\r\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\r\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\r\n const clientX = typeof opts.position === \"object\"\r\n ? opts.position.clientX\r\n : opts.position === \"cursor\"\r\n ? cursorX\r\n : this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = typeof opts.position === \"object\"\r\n ? opts.position.clientY\r\n : opts.position === \"cursor\"\r\n ? cursorY\r\n : this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const dx = x - elementsCenterX;\r\n const dy = y - elementsCenterY;\r\n const groupIdMap = new Map();\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\r\n const oldIdToDuplicatedId = new Map();\r\n const newElements = elements.map((element) => {\r\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\r\n x: element.x + gridX - minX,\r\n y: element.y + gridY - minY,\r\n });\r\n oldIdToDuplicatedId.set(element.id, newElement.id);\r\n return newElement;\r\n });\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\r\n const nextElements = [\r\n ...this.scene.getElementsIncludingDeleted(),\r\n ...newElements,\r\n ];\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\r\n if (opts.files) {\r\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\r\n }\r\n this.scene.replaceAllElements(nextElements);\r\n this.history.resumeRecording();\r\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: false, selectedElementIds: newElements.reduce((map, element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.containerId) {\r\n map[element.id] = true;\r\n }\r\n return map;\r\n }, {}), selectedGroupIds: {} }), this.scene.getElements()), () => {\r\n if (opts.files) {\r\n this.addNewImagesToImageCache();\r\n }\r\n });\r\n this.selectShapeTool(\"selection\");\r\n };\r\n // Collaboration\r\n this.setAppState = (obj) => {\r\n this.setState(obj);\r\n };\r\n this.removePointer = (event) => {\r\n // remove touch handler for context menu on touch devices\r\n if (event.pointerType === \"touch\" && touchTimeout) {\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n invalidateContextMenu = false;\r\n }\r\n gesture.pointers.delete(event.pointerId);\r\n };\r\n this.toggleLock = () => {\r\n this.setState((prevState) => {\r\n return {\r\n elementLocked: !prevState.elementLocked,\r\n elementType: prevState.elementLocked\r\n ? \"selection\"\r\n : prevState.elementType,\r\n };\r\n });\r\n };\r\n this.toggleZenMode = () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode);\r\n };\r\n this.toggleStats = () => {\r\n if (!this.state.showStats) {\r\n (0,_analytics__WEBPACK_IMPORTED_MODULE_8__.trackEvent)(\"dialog\", \"stats\");\r\n }\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats);\r\n };\r\n this.scrollToContent = (target = this.scene.getElements()) => {\r\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\r\n };\r\n this.clearToast = () => {\r\n this.setState({ toastMessage: null });\r\n };\r\n this.setToastMessage = (toastMessage) => {\r\n this.setState({ toastMessage });\r\n };\r\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const webShareTargetCache = yield caches.open(\"web-share-target\");\r\n const file = yield webShareTargetCache.match(\"shared-file\");\r\n if (file) {\r\n const blob = yield file.blob();\r\n this.loadFileToCanvas(blob);\r\n yield webShareTargetCache.delete(\"shared-file\");\r\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, window.location.pathname);\r\n }\r\n }\r\n catch (error) {\r\n this.setState({ errorMessage: error.message });\r\n }\r\n });\r\n /** adds supplied files to existing files in the appState */\r\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\r\n const filesMap = files.reduce((acc, fileData) => {\r\n acc.set(fileData.id, fileData);\r\n return acc;\r\n }, new Map());\r\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\r\n // bump versions for elements that reference added files so that\r\n // we/host apps can detect the change, and invalidate the image & shape\r\n // cache\r\n this.scene.getElements().forEach((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n filesMap.has(element.fileId)) {\r\n this.imageCache.delete(element.fileId);\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.bumpVersion)(element);\r\n }\r\n });\r\n this.scene.informMutation();\r\n this.addNewImagesToImageCache();\r\n });\r\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\r\n if (sceneData.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n if (sceneData.appState) {\r\n this.setState(sceneData.appState);\r\n }\r\n if (sceneData.elements) {\r\n this.scene.replaceAllElements(sceneData.elements);\r\n }\r\n if (sceneData.collaborators) {\r\n this.setState({ collaborators: sceneData.collaborators });\r\n }\r\n });\r\n this.onSceneUpdated = () => {\r\n this.setState({});\r\n };\r\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n cursorX = event.clientX;\r\n cursorY = event.clientY;\r\n });\r\n // Input handling\r\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // normalize `event.key` when CapsLock is pressed #2372\r\n if (\"Proxy\" in window &&\r\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\r\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\r\n event = new Proxy(event, {\r\n get(ev, prop) {\r\n const value = ev[prop];\r\n if (typeof value === \"function\") {\r\n // fix for Proxies hijacking `this`\r\n return value.bind(ev);\r\n }\r\n return prop === \"key\"\r\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\r\n // it back\r\n event.shiftKey\r\n ? ev.key.toUpperCase()\r\n : ev.key.toLowerCase()\r\n : value;\r\n },\r\n });\r\n }\r\n if (((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) && event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\r\n // case: using arrows to move between buttons\r\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\r\n this.setState({\r\n showHelpDialog: true,\r\n });\r\n }\r\n if (this.actionManager.handleKeyDown(event)) {\r\n return;\r\n }\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: false });\r\n }\r\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\r\n this.setState({ isLibraryOpen: !this.state.isLibraryOpen });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const step = (this.state.gridSize &&\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT\r\n : this.state.gridSize)) ||\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT);\r\n const selectedElements = this.scene\r\n .getElements()\r\n .filter((element) => this.state.selectedElementIds[element.id]);\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\r\n offsetX = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\r\n offsetX = step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\r\n offsetY = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\r\n offsetY = step;\r\n }\r\n selectedElements.forEach((element) => {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n x: element.x + offsetX,\r\n y: element.y + offsetY,\r\n });\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\r\n simultaneouslyUpdated: selectedElements,\r\n });\r\n });\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n event.preventDefault();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n }\r\n else if (selectedElements.length === 1 &&\r\n !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n const selectedElement = selectedElements[0];\r\n this.startTextEditing({\r\n sceneX: selectedElement.x + selectedElement.width / 2,\r\n sceneY: selectedElement.y + selectedElement.height / 2,\r\n shouldBind: true,\r\n });\r\n event.preventDefault();\r\n return;\r\n }\r\n }\r\n else if (!event.ctrlKey &&\r\n !event.altKey &&\r\n !event.metaKey &&\r\n this.state.draggingElement === null) {\r\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\r\n if (shape) {\r\n this.selectShapeTool(shape);\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\r\n this.toggleLock();\r\n }\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\r\n isHoldingSpace = true;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (this.state.elementType === \"selection\" &&\r\n !selectedElements.length) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\r\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.elementType) ||\r\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\r\n this.setState({ openPopup: \"backgroundColorPicker\" });\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n this.setState({ openPopup: \"strokeColorPicker\" });\r\n }\r\n }\r\n });\r\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (this.state.elementType === \"selection\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n isHoldingSpace = false;\r\n }\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: true });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\r\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n });\r\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n gesture.initialScale = this.state.zoom.value;\r\n });\r\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n // onGestureChange only has zoom factor but not the center.\r\n // If we're on iPad or iPhone, then we recognize multi-touch and will\r\n // zoom in at the right location on the touchMove handler already.\r\n // On Macbook, we don't have those events so will zoom in at the\r\n // current location instead.\r\n if (gesture.pointers.size === 2) {\r\n return;\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (initialScale) {\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale), zoom, { left: offsetLeft, top: offsetTop }, { x: cursorX, y: cursorY }),\r\n }));\r\n }\r\n });\r\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n gesture.initialScale = null;\r\n });\r\n this.startTextEditing = ({ sceneX, sceneY, shouldBind, insertAtParentCenter = true, }) => {\r\n var _a;\r\n let parentCenterPosition = insertAtParentCenter &&\r\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n // bind to container when shouldBind is true or\r\n // clicked on center of container\r\n const container = shouldBind || parentCenterPosition\r\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene.getElements(), sceneX, sceneY, \"text\")\r\n : null;\r\n let existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\r\n // consider bounded text element if container present\r\n if (container) {\r\n const boundTextElementId = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getBoundTextElementId)(container);\r\n if (boundTextElementId) {\r\n existingTextElement = this.scene.getElement(boundTextElementId);\r\n }\r\n }\r\n if (!existingTextElement && container) {\r\n const fontString = {\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n };\r\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const newHeight = Math.max(container.height, minHeight);\r\n const newWidth = Math.max(container.width, minWidth);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\r\n sceneX = container.x + newWidth / 2;\r\n sceneY = container.y + newHeight / 2;\r\n if (parentCenterPosition) {\r\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n }\r\n }\r\n const element = existingTextElement\r\n ? existingTextElement\r\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x: parentCenterPosition\r\n ? parentCenterPosition.elementCenterX\r\n : sceneX,\r\n y: parentCenterPosition\r\n ? parentCenterPosition.elementCenterY\r\n : sceneY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text: \"\",\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: parentCenterPosition\r\n ? \"center\"\r\n : this.state.currentItemTextAlign,\r\n verticalAlign: parentCenterPosition\r\n ? \"middle\"\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n containerId: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\r\n });\r\n this.setState({ editingElement: element });\r\n if (existingTextElement) {\r\n // if text element is no longer centered to a container, reset\r\n // verticalAlign to default because it's currently internal-only\r\n if (!parentCenterPosition || element.textAlign !== \"center\") {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, { verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN });\r\n }\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n // case: creating new text not centered to parent elemenent → offset Y\r\n // so that the text is centered to cursor position\r\n if (!parentCenterPosition) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n y: element.y - element.baseline / 2,\r\n });\r\n }\r\n }\r\n this.setState({\r\n editingElement: element,\r\n });\r\n this.handleTextWysiwyg(element, {\r\n isExistingElement: !!existingTextElement,\r\n });\r\n };\r\n this.handleCanvasDoubleClick = (event) => {\r\n // case: double-clicking with arrow/line tool selected would both create\r\n // text and enter multiElement mode\r\n if (this.state.multiElement) {\r\n return;\r\n }\r\n // we should only be able to double click when mode is selection\r\n if (this.state.elementType !== \"selection\") {\r\n return;\r\n }\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n return;\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\r\n if (selectedGroupIds.length > 0) {\r\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\r\n const selectedGroupId = hitElement &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\r\n if (selectedGroupId) {\r\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.getElements()));\r\n return;\r\n }\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1) {\r\n const selectedElement = selectedElements[0];\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\r\n if (canBindText) {\r\n sceneX = selectedElement.x + selectedElement.width / 2;\r\n sceneY = selectedElement.y + selectedElement.height / 2;\r\n }\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n }\r\n };\r\n this.handleCanvasPointerMove = (event) => {\r\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\r\n if (gesture.pointers.has(event.pointerId)) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (gesture.pointers.size === 2 &&\r\n gesture.lastCenter &&\r\n initialScale &&\r\n gesture.initialDistance) {\r\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n const deltaX = center.x - gesture.lastCenter.x;\r\n const deltaY = center.y - gesture.lastCenter.y;\r\n gesture.lastCenter = center;\r\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n const scaleFactor = distance / gesture.initialDistance;\r\n this.setState(({ zoom, scrollX, scrollY, offsetLeft, offsetTop }) => ({\r\n scrollX: scrollX + deltaX / zoom.value,\r\n scrollY: scrollY + deltaY / zoom.value,\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor), zoom, { left: offsetLeft, top: offsetTop }, center),\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n }\r\n else {\r\n gesture.lastCenter =\r\n gesture.initialDistance =\r\n gesture.initialScale =\r\n null;\r\n }\r\n if (isHoldingSpace || isPanning || isDraggingScrollBar) {\r\n return;\r\n }\r\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\r\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\r\n if (!this.state.draggingElement && !this.state.multiElement) {\r\n if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\r\n if (this.state.editingLinearElement &&\r\n !this.state.editingLinearElement.isDragging) {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state.editingLinearElement, this.state.gridSize);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({ editingLinearElement });\r\n }\r\n if (editingLinearElement.lastUncommittedPoint != null) {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n else {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.elementType)) {\r\n // Hovering with a selected tool or creating new linear element via click\r\n // and point\r\n const { draggingElement } = this.state;\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\r\n }\r\n else {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n }\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n const { x: rx, y: ry } = multiElement;\r\n const { points, lastCommittedPoint } = multiElement;\r\n const lastPoint = points[points.length - 1];\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n if (lastPoint === lastCommittedPoint) {\r\n // if we haven't yet created a temp point and we're beyond commit-zone\r\n // threshold, add a point\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\r\n });\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n // in this branch, we're inside the commit zone, and no uncommitted\r\n // point exists. Thus do nothing (don't add/remove points).\r\n }\r\n }\r\n else if (points.length > 2 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: points.slice(0, -1),\r\n });\r\n }\r\n else {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n // update last uncommitted point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [\r\n ...points.slice(0, -1),\r\n [scenePointerX - rx, scenePointerY - ry],\r\n ],\r\n });\r\n }\r\n return;\r\n }\r\n const hasDeselectedButton = Boolean(event.buttons);\r\n if (hasDeselectedButton ||\r\n (this.state.elementType !== \"selection\" &&\r\n this.state.elementType !== \"text\")) {\r\n return;\r\n }\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 &&\r\n !isOverScrollBar &&\r\n !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType &&\r\n elementWithTransformHandleType.transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\r\n return;\r\n }\r\n }\r\n else if (selectedElements.length > 1 && !isOverScrollBar) {\r\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);\r\n if (transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType,\r\n }));\r\n return;\r\n }\r\n }\r\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\r\n if (this.state.elementType === \"text\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n }\r\n else if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n else if (this.state.editingLinearElement) {\r\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(this.state.editingLinearElement.elementId);\r\n if (element &&\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\r\n scenePointer.x,\r\n scenePointer.y,\r\n ])) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n }\r\n else if (\r\n // if using cmd/ctrl, we're not dragging\r\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\r\n (hitElement ||\r\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements))) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n };\r\n // set touch moving for mobile context menu\r\n this.handleTouchMove = (event) => {\r\n invalidateContextMenu = true;\r\n };\r\n this.handleCanvasPointerDown = (event) => {\r\n // remove any active selection when we start to interact with canvas\r\n // (mainly, we care about removing selection outside the component which\r\n // would prevent our copy handling otherwise)\r\n const selection = document.getSelection();\r\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\r\n selection.removeAllRanges();\r\n }\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\r\n this.maybeCleanupAfterMissingPointerUp(event);\r\n if (isPanning) {\r\n return;\r\n }\r\n this.setState({\r\n lastPointerDownWith: event.pointerType,\r\n cursorButton: \"down\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"down\");\r\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\r\n return;\r\n }\r\n // only handle left mouse button or touch\r\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN &&\r\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.TOUCH) {\r\n return;\r\n }\r\n this.updateGestureOnPointerDown(event);\r\n // don't select while panning\r\n if (gesture.pointers.size > 1) {\r\n return;\r\n }\r\n // State for the duration of a pointer interaction, which starts with a\r\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\r\n const pointerDownState = this.initialPointerDownState(event);\r\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\r\n return;\r\n }\r\n this.clearSelectionIfNotUsingSelection();\r\n this.updateBindingEnabledOnPointerMove(event);\r\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\r\n return;\r\n }\r\n if (this.state.elementType === \"text\") {\r\n this.handleTextOnPointerDown(event, pointerDownState);\r\n return;\r\n }\r\n else if (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\") {\r\n this.handleLinearElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else if (this.state.elementType === \"image\") {\r\n // reset image preview on pointerdown\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n if (!this.state.pendingImageElement) {\r\n return;\r\n }\r\n this.setState({\r\n draggingElement: this.state.pendingImageElement,\r\n editingElement: this.state.pendingImageElement,\r\n pendingImageElement: null,\r\n multiElement: null,\r\n });\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(this.state.pendingImageElement, {\r\n x,\r\n y,\r\n });\r\n }\r\n else if (this.state.elementType === \"freedraw\") {\r\n this.handleFreeDrawElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else {\r\n this.createGenericElementOnPointerDown(this.state.elementType, pointerDownState);\r\n }\r\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\r\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\r\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\r\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\r\n lastPointerUp = onPointerUp;\r\n if (!this.state.viewModeEnabled) {\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, onKeyDown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, onKeyUp);\r\n pointerDownState.eventListeners.onMove = onPointerMove;\r\n pointerDownState.eventListeners.onUp = onPointerUp;\r\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\r\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\r\n }\r\n };\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\r\n // deal with opening context menu on touch devices\r\n if (event.pointerType === \"touch\") {\r\n invalidateContextMenu = false;\r\n if (touchTimeout) {\r\n // If there's already a touchTimeout, this means that there's another\r\n // touch down and we are doing another touch, so we shouldn't open the\r\n // context menu.\r\n invalidateContextMenu = true;\r\n }\r\n else {\r\n // open the context menu with the first touch's clientX and clientY\r\n // if the touch is not moving\r\n touchTimeout = window.setTimeout(() => {\r\n touchTimeout = 0;\r\n if (!invalidateContextMenu) {\r\n this.handleCanvasContextMenu(event);\r\n }\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.TOUCH_CTX_MENU_TIMEOUT);\r\n }\r\n }\r\n };\r\n // Returns whether the event is a panning\r\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\r\n if (!(gesture.pointers.size === 0 &&\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.WHEEL ||\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\r\n this.state.viewModeEnabled))) {\r\n return false;\r\n }\r\n isPanning = true;\r\n let nextPastePrevented = false;\r\n const isLinux = /Linux/.test(window.navigator.platform);\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n let { clientX: lastX, clientY: lastY } = event;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const deltaX = lastX - event.clientX;\r\n const deltaY = lastY - event.clientY;\r\n lastX = event.clientX;\r\n lastY = event.clientY;\r\n /*\r\n * Prevent paste event if we move while middle clicking on Linux.\r\n * See issue #1383.\r\n */\r\n if (isLinux &&\r\n !nextPastePrevented &&\r\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\r\n nextPastePrevented = true;\r\n /* Prevent the next paste event */\r\n const preventNextPaste = (event) => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n event.stopPropagation();\r\n };\r\n /*\r\n * Reenable next paste in case of disabled middle click paste for\r\n * any reason:\r\n * - rigth click paste\r\n * - empty clipboard\r\n */\r\n const enableNextPaste = () => {\r\n setTimeout(() => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }, 100);\r\n };\r\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }\r\n this.setState({\r\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\r\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\r\n });\r\n });\r\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\r\n lastPointerUp = null;\r\n isPanning = false;\r\n if (!isHoldingSpace) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n }));\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove, {\r\n passive: true,\r\n });\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n return true;\r\n };\r\n this.clearSelectionIfNotUsingSelection = () => {\r\n if (this.state.elementType !== \"selection\") {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n };\r\n /**\r\n * @returns whether the pointer event has been completely handled\r\n */\r\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\r\n var _a;\r\n if (this.state.elementType === \"selection\") {\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType != null) {\r\n this.setState({\r\n resizingElement: elementWithTransformHandleType.element,\r\n });\r\n pointerDownState.resize.handleType =\r\n elementWithTransformHandleType.transformHandleType;\r\n }\r\n }\r\n else if (selectedElements.length > 1) {\r\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);\r\n }\r\n if (pointerDownState.resize.handleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType: pointerDownState.resize.handleType,\r\n }));\r\n pointerDownState.resize.isResizing = true;\r\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));\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\r\n selectedElements[0].points.length === 2) {\r\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\r\n }\r\n }\r\n else {\r\n if (this.state.editingLinearElement) {\r\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, (appState) => this.setState(appState), this.history, pointerDownState.origin);\r\n if (ret.hitElement) {\r\n pointerDownState.hit.element = ret.hitElement;\r\n }\r\n if (ret.didAddPoint) {\r\n return true;\r\n }\r\n }\r\n // hitElement may already be set above, so check first\r\n pointerDownState.hit.element =\r\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n if (pointerDownState.hit.element) {\r\n pointerDownState.hit.hasHitElementInside =\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y]);\r\n }\r\n // For overlapped elements one position may hit\r\n // multiple elements\r\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n const hitElement = pointerDownState.hit.element;\r\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hitElement === null || !someHitElementIsSelected) &&\r\n !event.shiftKey &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.clearSelection(hitElement);\r\n }\r\n if (this.state.editingLinearElement) {\r\n this.setState({\r\n selectedElementIds: {\r\n [this.state.editingLinearElement.elementId]: true,\r\n },\r\n });\r\n // If we click on something\r\n }\r\n else if (hitElement != null) {\r\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\r\n // mark as not completely handled so as to allow dragging etc.\r\n return false;\r\n }\r\n // deselect if item is selected\r\n // if shift is not clicked, this will always return true\r\n // otherwise, it will trigger selection based on current\r\n // state of the box\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n // if we are currently editing a group, exiting editing mode and deselect the group.\r\n if (this.state.editingGroupId &&\r\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n // Add hit element to selection. At this point if we're not holding\r\n // SHIFT the previously selected element(s) were deselected above\r\n // (make sure you use setState updater to use latest state)\r\n if (!someHitElementIsSelected &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.setState((prevState) => {\r\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }) }), this.scene.getElements());\r\n });\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n }\r\n }\r\n this.setState({\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n }\r\n return false;\r\n };\r\n this.handleTextOnPointerDown = (event, pointerDownState) => {\r\n // if we're currently still editing text, clicking outside\r\n // should only finalize it, not create another (irrespective\r\n // of state.elementLocked)\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\r\n return;\r\n }\r\n let sceneX = pointerDownState.origin.x;\r\n let sceneY = pointerDownState.origin.y;\r\n const element = this.getElementAtPosition(sceneX, sceneY, {\r\n includeBoundTextElement: true,\r\n });\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\r\n if (canBindText) {\r\n sceneX = element.x + element.width / 2;\r\n sceneY = element.y + element.height / 2;\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!this.state.elementLocked) {\r\n this.setState({\r\n elementType: \"selection\",\r\n });\r\n }\r\n };\r\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n // Begin a mark capture. This does not have to update state yet.\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\r\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n simulatePressure: event.pressure === 0.5,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n const pressures = element.simulatePressure\r\n ? element.pressures\r\n : [...element.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [[0, 0]],\r\n pressures,\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n };\r\n this.createImageElement = ({ sceneX, sceneY, }) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\r\n type: \"image\",\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n });\r\n return element;\r\n };\r\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n // finalize if completing a loop\r\n if (multiElement.type === \"line\" &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\r\n // clicking inside commit zone → finalize arrow\r\n if (multiElement.points.length > 1 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\r\n }));\r\n // clicking outside commit zone → update reference for last committed\r\n // point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\r\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\r\n an arrow, we want it to be null for both. Otherwise, we want it to use the\r\n values from appState. */\r\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\r\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\r\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\r\n : [null, null];\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n startArrowhead,\r\n endArrowhead,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [...element.points, [0, 0]],\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n };\r\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n });\r\n if (element.type === \"selection\") {\r\n this.setState({\r\n selectionElement: element,\r\n draggingElement: element,\r\n });\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n multiElement: null,\r\n draggingElement: element,\r\n editingElement: element,\r\n });\r\n }\r\n };\r\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\r\n var _d, _e, _f, _g;\r\n // at this point this should be guaranteed image file, but we do this check\r\n // to satisfy TS down the line\r\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(imageFile)) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\r\n }\r\n const mimeType = imageFile.type;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\r\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.normalizeSVG)(yield imageFile.text()), imageFile.name);\r\n }\r\n catch (error) {\r\n console.warn(error);\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\r\n }\r\n }\r\n // generate image id (by default the file digest) before any\r\n // resizing/compression takes place to keep it more portable\r\n const fileId = yield (((_e = (_d = this.props).generateIdForFile) === null || _e === void 0 ? void 0 : _e.call(_d, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.generateIdFromFile)(imageFile));\r\n if (!fileId) {\r\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\r\n }\r\n const existingFileData = this.files[fileId];\r\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\r\n try {\r\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\r\n });\r\n }\r\n catch (error) {\r\n console.error(\"error trying to resing image file on insertion\", error);\r\n }\r\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\r\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\r\n }));\r\n }\r\n }\r\n if (showCursorImagePreview) {\r\n const dataURL = (_f = this.files[fileId]) === null || _f === void 0 ? void 0 : _f.dataURL;\r\n // optimization so that we don't unnecessarily resize the original\r\n // full-size file for cursor preview\r\n // (it's much faster to convert the resized dataURL to File)\r\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.dataURLToFile)(dataURL);\r\n this.setImagePreviewCursor(resizedFile || imageFile);\r\n }\r\n const dataURL = ((_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imageFile));\r\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\r\n fileId,\r\n }, false);\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n var _h, _j;\r\n try {\r\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\r\n mimeType,\r\n id: fileId,\r\n dataURL,\r\n created: Date.now(),\r\n } });\r\n const cachedImageData = this.imageCache.get(fileId);\r\n if (!cachedImageData) {\r\n this.addNewImagesToImageCache();\r\n yield this.updateImageCache([imageElement]);\r\n }\r\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\r\n yield cachedImageData.image;\r\n }\r\n if (((_h = this.state.pendingImageElement) === null || _h === void 0 ? void 0 : _h.id) !== imageElement.id &&\r\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\r\n this.initializeImageDimensions(imageElement, true);\r\n }\r\n resolve(imageElement);\r\n }\r\n catch (error) {\r\n console.error(error);\r\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\r\n }\r\n finally {\r\n if (!showCursorImagePreview) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n }\r\n }));\r\n });\r\n /**\r\n * inserts image into elements array and rerenders\r\n */\r\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n imageElement,\r\n ]);\r\n try {\r\n yield this.initializeImage({\r\n imageFile,\r\n imageElement,\r\n showCursorImagePreview,\r\n });\r\n }\r\n catch (error) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n isDeleted: true,\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n this.setState({\r\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\r\n });\r\n }\r\n });\r\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\r\n // mustn't be larger than 128 px\r\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\r\n const cursorImageSizePx = 96;\r\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: cursorImageSizePx,\r\n });\r\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imagePreview);\r\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\r\n // a small canvas\r\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.loadHTMLImageElement)(previewDataURL);\r\n let height = Math.min(img.height, cursorImageSizePx);\r\n let width = height * (img.width / img.height);\r\n if (width > cursorImageSizePx) {\r\n width = cursorImageSizePx;\r\n height = width * (img.height / img.width);\r\n }\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.height = height;\r\n canvas.width = width;\r\n const context = canvas.getContext(\"2d\");\r\n context.drawImage(img, 0, 0, width, height);\r\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg);\r\n }\r\n if (this.state.pendingImageElement) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\r\n }\r\n });\r\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const clientX = this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.fileOpen)({\r\n description: \"Image\",\r\n extensions: [\"jpg\", \"png\", \"svg\", \"gif\"],\r\n });\r\n const imageElement = this.createImageElement({\r\n sceneX: x,\r\n sceneY: y,\r\n });\r\n if (insertOnCanvasDirectly) {\r\n this.insertImageElement(imageElement, imageFile);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({\r\n selectedElementIds: { [imageElement.id]: true },\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n else {\r\n this.setState({\r\n pendingImageElement: imageElement,\r\n }, () => {\r\n this.insertImageElement(imageElement, imageFile, \r\n /* showCursorImagePreview */ true);\r\n });\r\n }\r\n }\r\n catch (error) {\r\n if (error.name !== \"AbortError\") {\r\n console.error(error);\r\n }\r\n else {\r\n console.warn(error);\r\n }\r\n this.setState({\r\n pendingImageElement: null,\r\n editingElement: null,\r\n elementType: \"selection\",\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n });\r\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\r\n var _a;\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\r\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n if (!image || image instanceof Promise) {\r\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value) {\r\n const placeholderSize = 100 / this.state.zoom.value;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n x: imageElement.x - placeholderSize / 2,\r\n y: imageElement.y - placeholderSize / 2,\r\n width: placeholderSize,\r\n height: placeholderSize,\r\n });\r\n }\r\n return;\r\n }\r\n if (forceNaturalSize ||\r\n // if user-created bounding box is below threshold, assume the\r\n // intention was to click instead of drag, and use the image's\r\n // intrinsic size\r\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\r\n const minHeight = Math.max(this.state.height - 120, 160);\r\n // max 65% of canvas height, clamped to <300px, vh - 120px>\r\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\r\n const height = Math.min(image.naturalHeight, maxHeight);\r\n const width = height * (image.naturalWidth / image.naturalHeight);\r\n // add current imageElement width/height to account for previous centering\r\n // of the placholder image\r\n const x = imageElement.x + imageElement.width / 2 - width / 2;\r\n const y = imageElement.y + imageElement.height / 2 - height / 2;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\r\n }\r\n };\r\n /** updates image cache, refreshing updated elements and/or setting status\r\n to error for images that fail during <img> element creation */\r\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.updateImageCache)({\r\n imageCache: this.imageCache,\r\n fileIds: elements.map((element) => element.fileId),\r\n files,\r\n });\r\n if (updatedFiles.size || erroredFiles.size) {\r\n for (const element of elements) {\r\n if (updatedFiles.has(element.fileId)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n }\r\n }\r\n if (erroredFiles.size) {\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n erroredFiles.has(element.fileId)) {\r\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\r\n status: \"error\",\r\n });\r\n }\r\n return element;\r\n }));\r\n }\r\n return { updatedFiles, erroredFiles };\r\n });\r\n /** adds new images to imageCache and re-renders if needed */\r\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.getInitializedImageElements)(this.scene.getElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\r\n if (uncachedImageElements.length) {\r\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\r\n if (updatedFiles.size) {\r\n this.scene.informMutation();\r\n }\r\n }\r\n });\r\n /** generally you should use `addNewImagesToImageCache()` directly if you need\r\n * to render new images. This is just a failsafe */\r\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default()(() => {\r\n this.addNewImagesToImageCache();\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.IMAGE_RENDER_TIMEOUT);\r\n this.updateBindingEnabledOnPointerMove = (event) => {\r\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\r\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\r\n this.setState({ isBindingEnabled: shouldEnableBinding });\r\n }\r\n };\r\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\r\n this.setState({\r\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\r\n });\r\n };\r\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \r\n /** scene coords */\r\n pointerCoords, \r\n // During line creation the start binding hasn't been written yet\r\n // into `linearElement`\r\n oppositeBindingBoundElement) => {\r\n if (!pointerCoords.length) {\r\n return;\r\n }\r\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\r\n if (hoveredBindableElement != null &&\r\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\r\n acc.push(hoveredBindableElement);\r\n }\r\n return acc;\r\n }, []);\r\n this.setState({ suggestedBindings });\r\n };\r\n this.handleCanvasRef = (canvas) => {\r\n var _a, _b, _c;\r\n // canvas is null when unmounting\r\n if (canvas !== null) {\r\n this.canvas = canvas;\r\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__[\"default\"].canvas(this.canvas);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel, {\r\n passive: false,\r\n });\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n else {\r\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel);\r\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n };\r\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\r\n var _k, _l;\r\n try {\r\n const file = event.dataTransfer.files[0];\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n // first attempt to decode scene from the image if it's embedded\r\n // ---------------------------------------------------------------------\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted());\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n return;\r\n }\r\n catch (error) {\r\n if (error.name !== \"EncodingError\") {\r\n throw error;\r\n }\r\n }\r\n }\r\n // if no scene is embedded or we fail for whatever reason, fall back\r\n // to importing as regular image\r\n // ---------------------------------------------------------------------\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n return this.setState({\r\n isLoading: false,\r\n errorMessage: error.message,\r\n });\r\n }\r\n const libraryShapes = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib);\r\n if (libraryShapes !== \"\") {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: JSON.parse(libraryShapes),\r\n position: event,\r\n files: null,\r\n });\r\n return;\r\n }\r\n const file = (_k = event.dataTransfer) === null || _k === void 0 ? void 0 : _k.files[0];\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib ||\r\n ((_l = file === null || file === void 0 ? void 0 : file.name) === null || _l === void 0 ? void 0 : _l.endsWith(\".excalidrawlib\"))) {\r\n this.library\r\n .importLibrary(file)\r\n .then(() => {\r\n // Close and then open to get the libraries updated\r\n this.setState({ isLibraryOpen: false });\r\n this.setState({ isLibraryOpen: true });\r\n })\r\n .catch((error) => this.setState({ isLoading: false, errorMessage: error.message }));\r\n // default: assume an Excalidraw file regardless of extension/MimeType\r\n }\r\n else {\r\n this.setState({ isLoading: true });\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n yield this.loadFileToCanvas(file);\r\n }\r\n });\r\n this.loadFileToCanvas = (file) => {\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n };\r\n this.handleCanvasContextMenu = (event) => {\r\n event.preventDefault();\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const element = this.getElementAtPosition(x, y, { preferSelected: true });\r\n const type = element ? \"element\" : \"canvas\";\r\n const container = this.excalidrawContainerRef.current;\r\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\r\n const left = event.clientX - offsetLeft;\r\n const top = event.clientY - offsetTop;\r\n if (element && !this.state.selectedElementIds[element.id]) {\r\n this.setState({ selectedElementIds: { [element.id]: true } }, () => {\r\n this._openContextMenu({ top, left }, type);\r\n });\r\n }\r\n else {\r\n this._openContextMenu({ top, left }, type);\r\n }\r\n };\r\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\r\n var _a;\r\n const draggingElement = this.state.draggingElement;\r\n const pointerCoords = pointerDownState.lastCoords;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"selection\") {\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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));\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\r\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n const aspectRatio = image && !(image instanceof Promise)\r\n ? image.width / image.height\r\n : null;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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)\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\r\n this.maybeSuggestBindingForAll([draggingElement]);\r\n }\r\n };\r\n this.maybeHandleResize = (pointerDownState, event) => {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const transformHandleType = pointerDownState.resize.handleType;\r\n this.setState({\r\n // TODO: rename this state field to \"isScaling\" to distinguish\r\n // it from the generic \"isResizing\" which includes scaling and\r\n // rotating\r\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\r\n isRotating: transformHandleType === \"rotation\",\r\n });\r\n const pointerCoords = pointerDownState.lastCoords;\r\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);\r\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])\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n return true;\r\n }\r\n return false;\r\n };\r\n /** @private use this.handleCanvasContextMenu */\r\n this._openContextMenu = ({ left, top, }, type) => {\r\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const separator = \"separator\";\r\n const elements = this.scene.getElements();\r\n const options = [];\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng);\r\n }\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg);\r\n }\r\n if (type === \"canvas\") {\r\n const viewModeOptions = [\r\n ...options,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ];\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: viewModeOptions,\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && navigator.clipboard && separator,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg,\r\n ((_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) ||\r\n (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0)) &&\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSelectAll,\r\n separator,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n else if (type === \"element\") {\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy, ...options],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCut,\r\n this.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy,\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && separator,\r\n ...options,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyStyles,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionPasteStyles,\r\n separator,\r\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup,\r\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup,\r\n (maybeGroupAction || maybeUngroupAction) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionAddToLibrary,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendBackward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringForward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendToBack,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringToFront,\r\n separator,\r\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal,\r\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical,\r\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDuplicateSelection,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n };\r\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n if (isPanning) {\r\n return;\r\n }\r\n const { deltaX, deltaY } = event;\r\n const { selectedElementIds, previousSelectedElementIds } = this.state;\r\n // note that event.ctrlKey is necessary to handle pinch zooming\r\n if (event.metaKey || event.ctrlKey) {\r\n const sign = Math.sign(deltaY);\r\n const MAX_STEP = 10;\r\n let delta = Math.abs(deltaY);\r\n if (delta > MAX_STEP) {\r\n delta = MAX_STEP;\r\n }\r\n delta *= sign;\r\n if (Object.keys(previousSelectedElementIds).length !== 0) {\r\n setTimeout(() => {\r\n this.setState({\r\n selectedElementIds: previousSelectedElementIds,\r\n previousSelectedElementIds: {},\r\n });\r\n }, 1000);\r\n }\r\n let newZoom = this.state.zoom.value - delta / 100;\r\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\r\n newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign;\r\n // round to nearest step\r\n newZoom = Math.round(newZoom * _constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100) / (_constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100);\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom), zoom, { left: offsetLeft, top: offsetTop }, {\r\n x: cursorX,\r\n y: cursorY,\r\n }),\r\n selectedElementIds: {},\r\n previousSelectedElementIds: Object.keys(selectedElementIds).length !== 0\r\n ? selectedElementIds\r\n : previousSelectedElementIds,\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n return;\r\n }\r\n // scroll horizontally when shift pressed\r\n if (event.shiftKey) {\r\n this.setState(({ zoom, scrollX }) => ({\r\n // on Mac, shift+wheel tends to result in deltaX\r\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\r\n }));\r\n return;\r\n }\r\n this.setState(({ zoom, scrollX, scrollY }) => ({\r\n scrollX: scrollX - deltaX / zoom.value,\r\n scrollY: scrollY - deltaY / zoom.value,\r\n }));\r\n });\r\n this.savePointer = (x, y, button) => {\r\n var _a, _b;\r\n if (!x || !y) {\r\n return;\r\n }\r\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\r\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\r\n // sometimes the pointer goes off screen\r\n }\r\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\r\n pointer,\r\n button,\r\n pointersMap: gesture.pointers,\r\n });\r\n };\r\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n if (!this.unmounted) {\r\n this.setState({ shouldCacheIgnoreZoom: false });\r\n }\r\n }, 300);\r\n this.updateDOMRect = (cb) => {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\r\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\r\n if (width === currentWidth &&\r\n height === currentHeight &&\r\n offsetLeft === currentOffsetLeft &&\r\n offsetTop === currentOffsetTop) {\r\n if (cb) {\r\n cb();\r\n }\r\n return;\r\n }\r\n this.setState({\r\n width,\r\n height,\r\n offsetLeft,\r\n offsetTop,\r\n }, () => {\r\n cb && cb();\r\n });\r\n }\r\n };\r\n this.refresh = () => {\r\n this.setState(Object.assign({}, this.getCanvasOffsets()));\r\n };\r\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)();\r\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\r\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\r\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight });\r\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_46__.nanoid)();\r\n if (excalidrawRef) {\r\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\r\n const api = {\r\n ready: true,\r\n readyPromise,\r\n updateScene: this.updateScene,\r\n addFiles: this.addFiles,\r\n resetScene: this.resetScene,\r\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\r\n history: {\r\n clear: this.resetHistory,\r\n },\r\n scrollToContent: this.scrollToContent,\r\n getSceneElements: this.getSceneElements,\r\n getAppState: () => this.state,\r\n getFiles: () => this.files,\r\n refresh: this.refresh,\r\n importLibrary: this.importLibraryFromUrl,\r\n setToastMessage: this.setToastMessage,\r\n id: this.id,\r\n };\r\n if (typeof excalidrawRef === \"function\") {\r\n excalidrawRef(api);\r\n }\r\n else {\r\n excalidrawRef.current = api;\r\n }\r\n readyPromise.resolve(api);\r\n }\r\n this.excalidrawContainerValue = {\r\n container: this.excalidrawContainerRef.current,\r\n id: this.id,\r\n };\r\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\r\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\r\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\r\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_6__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\r\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_7__.actions);\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createUndoAction)(this.history));\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createRedoAction)(this.history));\r\n }\r\n renderCanvas() {\r\n const canvasScale = window.devicePixelRatio;\r\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\r\n const canvasWidth = canvasDOMWidth * canvasScale;\r\n const canvasHeight = canvasDOMHeight * canvasScale;\r\n if (viewModeEnabled) {\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n cursor: _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n render() {\r\n var _a, _b;\r\n const { zenModeEnabled, viewModeEnabled } = this.state;\r\n const { onCollabButtonClick, renderTopRightUI, renderFooter, renderCustomStats, } = this.props;\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(\"excalidraw excalidraw-container\", {\r\n \"excalidraw--view-mode\": viewModeEnabled,\r\n \"excalidraw--mobile\": this.isMobile,\r\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)(IsMobileContext.Provider, Object.assign({ value: this.isMobile }, { 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.getElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\r\n elements,\r\n position: \"center\",\r\n files: null,\r\n }), zenModeEnabled: zenModeEnabled, toggleZenMode: this.toggleZenMode, langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating || false, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, viewModeEnabled: viewModeEnabled, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\r\n zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\r\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 }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }, void 0), this.state.showStats && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stats__WEBPACK_IMPORTED_MODULE_37__.Stats, { appState: this.state, setAppState: this.setAppState, elements: this.scene.getElements(), onClose: this.toggleStats, renderCustomStats: renderCustomStats }, void 0)), this.state.toastMessage !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_38__.Toast, { message: this.state.toastMessage, clearToast: this.clearToast }, void 0)), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() }, void 0)] }), void 0) }), void 0) }), void 0));\r\n }\r\n componentDidMount() {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function* () {\r\n this.excalidrawContainerValue.container =\r\n this.excalidrawContainerRef.current;\r\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n const setState = this.setState.bind(this);\r\n Object.defineProperties(window.h, {\r\n state: {\r\n configurable: true,\r\n get: () => {\r\n return this.state;\r\n },\r\n },\r\n setState: {\r\n configurable: true,\r\n value: (...args) => {\r\n return this.setState(...args);\r\n },\r\n },\r\n app: {\r\n configurable: true,\r\n value: this,\r\n },\r\n history: {\r\n configurable: true,\r\n value: this.history,\r\n },\r\n });\r\n }\r\n this.scene.addCallback(this.onSceneUpdated);\r\n this.addEventListeners();\r\n if (this.excalidrawContainerRef.current) {\r\n this.focusContainer();\r\n }\r\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n // compute isMobile state\r\n // ---------------------------------------------------------------------\r\n const { width, height } = this.excalidrawContainerRef.current.getBoundingClientRect();\r\n this.isMobile =\r\n width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT ||\r\n (height < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE);\r\n // refresh offsets\r\n // ---------------------------------------------------------------------\r\n this.updateDOMRect();\r\n });\r\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\r\n }\r\n else if (window.matchMedia) {\r\n const mediaQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\r\n const handler = () => (this.isMobile = mediaQuery.matches);\r\n mediaQuery.addListener(handler);\r\n this.detachIsMobileMqHandler = () => mediaQuery.removeListener(handler);\r\n }\r\n const searchParams = new URLSearchParams(window.location.search.slice(1));\r\n if (searchParams.has(\"web-share-target\")) {\r\n // Obtain a file that was shared via the Web Share Target API.\r\n this.restoreFileFromShare();\r\n }\r\n else {\r\n this.updateDOMRect(this.initializeScene);\r\n }\r\n });\r\n }\r\n componentWillUnmount() {\r\n var _a;\r\n this.files = {};\r\n this.imageCache.clear();\r\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\r\n this.unmounted = true;\r\n this.removeEventListeners();\r\n this.scene.destroy();\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n }\r\n removeEventListeners() {\r\n var _a, _b;\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n (_a = this.nearestScrollableContainer) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n (_b = this.detachIsMobileMqHandler) === null || _b === void 0 ? void 0 : _b.call(this);\r\n }\r\n addEventListeners() {\r\n var _a, _b;\r\n this.removeEventListeners();\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer); // #3553\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n if (this.props.handleKeyboardGlobally) {\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp, { passive: true });\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\r\n // rerender text elements on font load to fix #637 && #1553\r\n (_b = (_a = document.fonts) === null || _a === void 0 ? void 0 : _a.addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, \"loadingdone\", this.onFontLoaded);\r\n // Safari-only desktop pinch zoom\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n if (this.props.detectScroll) {\r\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\r\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n }\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n }\r\n componentDidUpdate(prevProps, prevState) {\r\n var _a, _b, _c;\r\n if (prevProps.langCode !== this.props.langCode) {\r\n this.updateLanguage();\r\n }\r\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\r\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\r\n }\r\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\r\n this.addEventListeners();\r\n this.deselectElements();\r\n }\r\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\r\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\r\n }\r\n if (prevProps.theme !== this.props.theme && this.props.theme) {\r\n this.setState({ theme: this.props.theme });\r\n }\r\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\r\n this.setState({\r\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null,\r\n });\r\n }\r\n if (this.props.name && prevProps.name !== this.props.name) {\r\n this.setState({\r\n name: this.props.name,\r\n });\r\n }\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\r\n if (this.state.editingLinearElement &&\r\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\r\n // defer so that the commitToHistory flag isn't reset via current update\r\n setTimeout(() => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n const { multiElement } = prevState;\r\n if (prevState.elementType !== this.state.elementType &&\r\n multiElement != null &&\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement)) {\r\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)));\r\n }\r\n const cursorButton = {};\r\n const pointerViewportCoords = {};\r\n const remoteSelectedElementIds = {};\r\n const pointerUsernames = {};\r\n const pointerUserStates = {};\r\n this.state.collaborators.forEach((user, socketId) => {\r\n if (user.selectedElementIds) {\r\n for (const id of Object.keys(user.selectedElementIds)) {\r\n if (!(id in remoteSelectedElementIds)) {\r\n remoteSelectedElementIds[id] = [];\r\n }\r\n remoteSelectedElementIds[id].push(socketId);\r\n }\r\n }\r\n if (!user.pointer) {\r\n return;\r\n }\r\n if (user.username) {\r\n pointerUsernames[socketId] = user.username;\r\n }\r\n if (user.userState) {\r\n pointerUserStates[socketId] = user.userState;\r\n }\r\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: user.pointer.x,\r\n sceneY: user.pointer.y,\r\n }, this.state);\r\n cursorButton[socketId] = user.button;\r\n });\r\n const renderingElements = this.scene.getElements().filter((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\r\n if (\r\n // not placed on canvas yet (but in elements array)\r\n this.state.pendingImageElement &&\r\n element.id === this.state.pendingImageElement.id) {\r\n return false;\r\n }\r\n }\r\n // don't render text element that's being currently edited (it's\r\n // rendered on remote only)\r\n return (!this.state.editingElement ||\r\n this.state.editingElement.type !== \"text\" ||\r\n element.id !== this.state.editingElement.id);\r\n });\r\n const { atLeastOneVisibleElement, scrollBars } = (0,_renderer__WEBPACK_IMPORTED_MODULE_28__.renderScene)(renderingElements, this.state, this.state.selectionElement, window.devicePixelRatio, this.rc, this.canvas, {\r\n scrollX: this.state.scrollX,\r\n scrollY: this.state.scrollY,\r\n viewBackgroundColor: this.state.viewBackgroundColor,\r\n zoom: this.state.zoom,\r\n remotePointerViewportCoords: pointerViewportCoords,\r\n remotePointerButton: cursorButton,\r\n remoteSelectedElementIds,\r\n remotePointerUsernames: pointerUsernames,\r\n remotePointerUserStates: pointerUserStates,\r\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\r\n theme: this.state.theme,\r\n imageCache: this.imageCache,\r\n isExporting: false,\r\n renderScrollbars: !this.isMobile,\r\n });\r\n if (scrollBars) {\r\n currentScrollBars = scrollBars;\r\n }\r\n const scrolledOutside = \r\n // hide when editing text\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? false\r\n : !atLeastOneVisibleElement && renderingElements.length > 0;\r\n if (this.state.scrolledOutside !== scrolledOutside) {\r\n this.setState({ scrolledOutside });\r\n }\r\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\r\n this.scheduleImageRefresh();\r\n // Do not notify consumers if we're still loading the scene. Among other\r\n // potential issues, this fixes a case where the tab isn't focused during\r\n // init, which would trigger onChange with empty elements, which would then\r\n // override whatever is in localStorage currently.\r\n if (!this.state.isLoading) {\r\n (_c = (_b = this.props).onChange) === null || _c === void 0 ? void 0 : _c.call(_b, this.scene.getElementsIncludingDeleted(), this.state, this.files);\r\n }\r\n }\r\n static resetTapTwice() {\r\n didTapTwice = false;\r\n }\r\n addTextFromPaste(text) {\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x,\r\n y,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text,\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: this.state.currentItemTextAlign,\r\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n });\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({ selectedElementIds: { [element.id]: true } });\r\n this.history.resumeRecording();\r\n }\r\n selectShapeTool(elementType) {\r\n if (!isHoldingSpace) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, elementType);\r\n }\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\r\n this.focusContainer();\r\n }\r\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(elementType)) {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n if (elementType === \"image\") {\r\n this.onImageAction();\r\n }\r\n if (elementType !== \"selection\") {\r\n this.setState({\r\n elementType,\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n else {\r\n this.setState({ elementType });\r\n }\r\n }\r\n handleTextWysiwyg(element, { isExistingElement = false, }) {\r\n const updateElement = (text, originalText, isDeleted = false, updateDimensions = false) => {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\r\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\r\n text,\r\n isDeleted,\r\n originalText,\r\n }, updateDimensions);\r\n }\r\n return _element;\r\n }),\r\n ]);\r\n };\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\r\n id: element.id,\r\n appState: this.state,\r\n canvas: this.canvas,\r\n getViewportCoords: (x, y) => {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: x,\r\n sceneY: y,\r\n }, this.state);\r\n return [\r\n viewportX - this.state.offsetLeft,\r\n viewportY - this.state.offsetTop, //* (2 - this.state.zoom.value),\r\n ];\r\n },\r\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\r\n updateElement(text, text, false, !element.containerId);\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\r\n }\r\n }),\r\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\r\n const isDeleted = !text.trim();\r\n updateElement(text, originalText, isDeleted, true);\r\n // select the created text element only if submitting via keyboard\r\n // (when submitting via click it should act as signal to deselect)\r\n if (!isDeleted && viaKeyboard) {\r\n const elementIdToSelect = element.containerId\r\n ? element.containerId\r\n : element.id;\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\r\n }));\r\n }\r\n if (isDeleted) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getElements(), [element]);\r\n }\r\n if (!isDeleted || isExistingElement) {\r\n this.history.resumeRecording();\r\n }\r\n this.setState({\r\n draggingElement: null,\r\n editingElement: null,\r\n });\r\n if (this.state.elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n this.focusContainer();\r\n }),\r\n element,\r\n excalidrawContainer: this.excalidrawContainerRef.current,\r\n });\r\n // deselect all other elements when inserting text\r\n this.deselectElements();\r\n // do an initial update to re-initialize element position since we were\r\n // modifying element's x/y for sake of editor (case: syncing to remote)\r\n updateElement(element.text, element.originalText);\r\n }\r\n deselectElements() {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n getTextElementAtPosition(x, y) {\r\n const element = this.getElementAtPosition(x, y, {\r\n includeBoundTextElement: true,\r\n });\r\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\r\n return element;\r\n }\r\n return null;\r\n }\r\n getElementAtPosition(x, y, opts) {\r\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement);\r\n if (allHitElements.length > 1) {\r\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\r\n for (let index = allHitElements.length - 1; index > -1; index--) {\r\n if (this.state.selectedElementIds[allHitElements[index].id]) {\r\n return allHitElements[index];\r\n }\r\n }\r\n }\r\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\r\n // If we're hitting element with highest z-index only on its bounding box\r\n // while also hitting other element figure, the latter should be considered.\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\r\n ? allHitElements[allHitElements.length - 2]\r\n : elementWithHighestZIndex;\r\n }\r\n if (allHitElements.length === 1) {\r\n return allHitElements[0];\r\n }\r\n return null;\r\n }\r\n getElementsAtPosition(x, y, includeBoundTextElement = false) {\r\n const elements = includeBoundTextElement\r\n ? this.scene.getElements()\r\n : this.scene\r\n .getElements()\r\n .filter((element) => !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId));\r\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\r\n }\r\n maybeCleanupAfterMissingPointerUp(event) {\r\n if (lastPointerUp !== null) {\r\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\r\n // this can happen when a contextual menu or alert is triggered. In order to avoid\r\n // being in a weird state, we clean up on the next pointerdown\r\n lastPointerUp(event);\r\n }\r\n }\r\n updateGestureOnPointerDown(event) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n if (gesture.pointers.size === 2) {\r\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n gesture.initialScale = this.state.zoom.value;\r\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n }\r\n }\r\n initialPointerDownState(event) {\r\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return {\r\n origin,\r\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\r\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\r\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\r\n // we need to duplicate because we'll be updating this state\r\n lastCoords: Object.assign({}, origin),\r\n originalElements: this.scene.getElements().reduce((acc, element) => {\r\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\r\n return acc;\r\n }, new Map()),\r\n resize: {\r\n handleType: false,\r\n isResizing: false,\r\n offset: { x: 0, y: 0 },\r\n arrowDirection: \"origin\",\r\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\r\n },\r\n hit: {\r\n element: null,\r\n allHitElements: [],\r\n wasAddedToSelection: false,\r\n hasBeenDuplicated: false,\r\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\r\n hasHitElementInside: false,\r\n },\r\n drag: {\r\n hasOccurred: false,\r\n offset: null,\r\n },\r\n eventListeners: {\r\n onMove: null,\r\n onUp: null,\r\n onKeyUp: null,\r\n onKeyDown: null,\r\n },\r\n boxSelection: {\r\n hasOccurred: false,\r\n },\r\n };\r\n }\r\n // Returns whether the event is a dragging a scrollbar\r\n handleDraggingScrollBar(event, pointerDownState) {\r\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\r\n return false;\r\n }\r\n isDraggingScrollBar = true;\r\n pointerDownState.lastCoords.x = event.clientX;\r\n pointerDownState.lastCoords.y = event.clientY;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\r\n });\r\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isDraggingScrollBar = false;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n lastPointerUp = null;\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n });\r\n lastPointerUp = onPointerUp;\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n return true;\r\n }\r\n isASelectedElement(hitElement) {\r\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\r\n }\r\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\r\n if (selectedElements.length < 2) {\r\n return false;\r\n }\r\n // How many pixels off the shape boundary we still consider a hit\r\n const threshold = 10 / this.state.zoom.value;\r\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return (point.x > x1 - threshold &&\r\n point.x < x2 + threshold &&\r\n point.y > y1 - threshold &&\r\n point.y < y2 + threshold);\r\n }\r\n onKeyDownFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onKeyUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // Prevents focus from escaping excalidraw tab\r\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onPointerMoveFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a, _b;\r\n // We need to initialize dragOffsetXY only after we've updated\r\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\r\n // event handler should hopefully ensure we're already working with\r\n // the updated state.\r\n if (pointerDownState.drag.offset === null) {\r\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.getElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\r\n }\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\r\n return;\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n // for arrows/lines, don't start dragging until a given threshold\r\n // to ensure we don't create a 2-point arrow by mistake when\r\n // user clicks mouse in a way that it moves a tiny bit (thus\r\n // triggering pointermove)\r\n if (!pointerDownState.drag.hasOccurred &&\r\n (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\")) {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD) {\r\n return;\r\n }\r\n }\r\n if (pointerDownState.resize.isResizing) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return true;\r\n }\r\n }\r\n if (this.state.editingLinearElement) {\r\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(this.state, (appState) => this.setState(appState), pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\r\n });\r\n if (didDrag) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n return;\r\n }\r\n }\r\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hasHitASelectedElement ||\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\r\n // this allows for box-selecting points when clicking inside the\r\n // line's bounding box\r\n (!this.state.editingLinearElement || !event.shiftKey) &&\r\n // box-selecting without shift when editing line, not clicking on a line\r\n (!this.state.editingLinearElement ||\r\n ((_a = this.state.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !==\r\n ((_b = pointerDownState.hit.element) === null || _b === void 0 ? void 0 : _b.id) ||\r\n pointerDownState.hit.hasHitElementInside)) {\r\n // Marking that click was used for dragging to check\r\n // if elements should be deselected on pointerup\r\n pointerDownState.drag.hasOccurred = true;\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\r\n // it would have weird results (stuff jumping all over the screen)\r\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\r\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);\r\n const [dragDistanceX, dragDistanceY] = [\r\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\r\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\r\n ];\r\n // We only drag in one direction if shift is pressed\r\n const lockDirection = event.shiftKey;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY);\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n // We duplicate the selected element if alt is pressed on pointer move\r\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\r\n // Move the currently selected elements to the top of the z index stack, and\r\n // put the duplicates where the selected elements used to be.\r\n // (the origin point where the dragging started)\r\n pointerDownState.hit.hasBeenDuplicated = true;\r\n const nextElements = [];\r\n const elementsToAppend = [];\r\n const groupIdMap = new Map();\r\n const oldIdToDuplicatedId = new Map();\r\n const hitElement = pointerDownState.hit.element;\r\n const elements = this.scene.getElementsIncludingDeleted();\r\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\r\n for (const element of elements) {\r\n if (selectedElementIds.includes(element.id) ||\r\n // case: the state.selectedElementIds might not have been\r\n // updated yet by the time this mousemove event is fired\r\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\r\n pointerDownState.hit.wasAddedToSelection)) {\r\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\r\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);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\r\n x: duplicatedElement.x + (originDragX - dragX),\r\n y: duplicatedElement.y + (originDragY - dragY),\r\n });\r\n nextElements.push(duplicatedElement);\r\n elementsToAppend.push(element);\r\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\r\n }\r\n else {\r\n nextElements.push(element);\r\n }\r\n }\r\n const nextSceneElements = [...nextElements, ...elementsToAppend];\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\r\n this.scene.replaceAllElements(nextSceneElements);\r\n }\r\n return;\r\n }\r\n }\r\n // It is very important to read this.state within each move event,\r\n // otherwise we would read a stale one!\r\n const draggingElement = this.state.draggingElement;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"freedraw\") {\r\n const points = draggingElement.points;\r\n const dx = pointerCoords.x - draggingElement.x;\r\n const dy = pointerCoords.y - draggingElement.y;\r\n const pressures = draggingElement.simulatePressure\r\n ? draggingElement.pressures\r\n : [...draggingElement.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n });\r\n }\r\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n pointerDownState.drag.hasOccurred = true;\r\n const points = draggingElement.points;\r\n let dx = gridX - draggingElement.x;\r\n let dy = gridY - draggingElement.y;\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\r\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getPerfectElementSize)(this.state.elementType, dx, dy));\r\n }\r\n if (points.length === 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, { points: [...points, [dx, dy]] });\r\n }\r\n else if (points.length > 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points.slice(0, -1), [dx, dy]],\r\n });\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n // When creating a linear element by dragging\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\r\n }\r\n }\r\n else {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n }\r\n if (this.state.elementType === \"selection\") {\r\n pointerDownState.boxSelection.hasOccurred = true;\r\n const elements = this.scene.getElements();\r\n if (!event.shiftKey &&\r\n // allows for box-selecting points (without shift)\r\n !this.state.editingLinearElement &&\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\r\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\r\n [pointerDownState.hit.element.id]: true,\r\n } }), this.scene.getElements()));\r\n }\r\n else {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n }\r\n // box-select line editor points\r\n if (this.state.editingLinearElement) {\r\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\r\n // regular box-select\r\n }\r\n else {\r\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\r\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((map, element) => {\r\n map[element.id] = true;\r\n return map;\r\n }, {})), (pointerDownState.hit.element\r\n ? {\r\n // if using ctrl/cmd, select the hitElement only if we\r\n // haven't box-selected anything else\r\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\r\n }\r\n : null)) }), this.scene.getElements()));\r\n }\r\n }\r\n });\r\n }\r\n // Returns whether the pointer move happened over either scrollbar\r\n handlePointerMoveOverScrollbars(event, pointerDownState) {\r\n if (pointerDownState.scrollbars.isOverHorizontal) {\r\n const x = event.clientX;\r\n const dx = x - pointerDownState.lastCoords.x;\r\n this.setState({\r\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.x = x;\r\n return true;\r\n }\r\n if (pointerDownState.scrollbars.isOverVertical) {\r\n const y = event.clientY;\r\n const dy = y - pointerDownState.lastCoords.y;\r\n this.setState({\r\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.y = y;\r\n return true;\r\n }\r\n return false;\r\n }\r\n onPointerUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\r\n var _a, _b;\r\n const { draggingElement, resizingElement, multiElement, elementType, elementLocked, isResizing, isRotating, } = this.state;\r\n this.setState({\r\n isResizing: false,\r\n isRotating: false,\r\n resizingElement: null,\r\n selectionElement: null,\r\n cursorButton: \"up\",\r\n // text elements are reset on finalize, and resetting on pointerup\r\n // may cause issues with double taps\r\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? this.state.editingElement\r\n : null,\r\n });\r\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\r\n // Handle end of dragging a point of a linear element, might close a loop\r\n // and sets binding element\r\n if (this.state.editingLinearElement) {\r\n if (!pointerDownState.boxSelection.hasOccurred &&\r\n (((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\r\n this.state.editingLinearElement.elementId ||\r\n !pointerDownState.hit.hasHitElementInside)) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n else {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({\r\n editingLinearElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n }\r\n }\r\n lastPointerUp = null;\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\r\n if (this.state.pendingImageElement) {\r\n this.setState({ pendingImageElement: null });\r\n }\r\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n const points = draggingElement.points;\r\n let dx = pointerCoords.x - draggingElement.x;\r\n let dy = pointerCoords.y - draggingElement.y;\r\n // Allows dots to avoid being flagged as infinitely small\r\n if (dx === points[0][0] && dy === points[0][1]) {\r\n dy += 0.0001;\r\n dx += 0.0001;\r\n }\r\n const pressures = draggingElement.simulatePressure\r\n ? []\r\n : [...draggingElement.pressures, childEvent.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n lastCommittedPoint: [dx, dy],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\r\n const imageElement = draggingElement;\r\n try {\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n catch (error) {\r\n console.error(error);\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== imageElement.id));\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n if (draggingElement.points.length > 1) {\r\n this.history.resumeRecording();\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n if (!pointerDownState.drag.hasOccurred &&\r\n draggingElement &&\r\n !multiElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [\r\n ...draggingElement.points,\r\n [\r\n pointerCoords.x - draggingElement.x,\r\n pointerCoords.y - draggingElement.y,\r\n ],\r\n ],\r\n });\r\n this.setState({\r\n multiElement: draggingElement,\r\n editingElement: this.state.draggingElement,\r\n });\r\n }\r\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\r\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\r\n }\r\n this.setState({ suggestedBindings: [], startBoundElement: null });\r\n if (!elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n elementType: \"selection\",\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n else {\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n }\r\n return;\r\n }\r\n if (elementType !== \"selection\" &&\r\n draggingElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\r\n // remove invisible element which was added in onPointerDown\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\r\n this.setState({\r\n draggingElement: null,\r\n });\r\n return;\r\n }\r\n if (draggingElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\r\n }\r\n if (resizingElement) {\r\n this.history.resumeRecording();\r\n }\r\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== resizingElement.id));\r\n }\r\n // Code below handles selection when element(s) weren't\r\n // drag or added to selection on pointer down phase.\r\n const hitElement = pointerDownState.hit.element;\r\n if (hitElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !pointerDownState.hit.wasAddedToSelection &&\r\n // if we're editing a line, pointerup shouldn't switch selection if\r\n // box selected\r\n (!this.state.editingLinearElement ||\r\n !pointerDownState.boxSelection.hasOccurred)) {\r\n // when inside line editor, shift selects points instead\r\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\r\n if (this.state.selectedElementIds[hitElement.id]) {\r\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\r\n // We want to unselect all groups hitElement is part of\r\n // as well as all elements that are part of the groups\r\n // hitElement is part of\r\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\r\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getElements(), groupId))\r\n .map((element) => ({ [element.id]: false }))\r\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\r\n this.setState((_prevState) => ({\r\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\r\n .map((gId) => ({ [gId]: false }))\r\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\r\n }));\r\n }\r\n else {\r\n // remove element from selection while\r\n // keeping prev elements selected\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false }) }), this.scene.getElements()));\r\n }\r\n }\r\n else {\r\n // add element to selection while\r\n // keeping prev elements selected\r\n this.setState((_prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\r\n }));\r\n }\r\n }\r\n else {\r\n this.setState((prevState) => (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true } }), this.scene.getElements()))));\r\n }\r\n }\r\n if (!this.state.editingLinearElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !this.state.isResizing &&\r\n ((hitElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\r\n (!hitElement &&\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\r\n // Deselect selected elements\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n return;\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\" && draggingElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\r\n }));\r\n }\r\n if (elementType !== \"selection\" ||\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getElements(), this.state)) {\r\n this.history.resumeRecording();\r\n }\r\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\r\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\r\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state));\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n elementType: \"selection\",\r\n });\r\n }\r\n else {\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n });\r\n }\r\n });\r\n }\r\n maybeSuggestBindingForAll(selectedElements) {\r\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\r\n this.setState({ suggestedBindings });\r\n }\r\n clearSelection(hitElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n // Continue editing the same group if the user selected a different\r\n // element from it\r\n editingGroupId: prevState.editingGroupId &&\r\n hitElement != null &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\r\n ? prevState.editingGroupId\r\n : null,\r\n }));\r\n this.setState({\r\n selectedElementIds: {},\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n getTextWysiwygSnappedToCenterPosition(x, y, appState, canvas, scale) {\r\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\r\n if (elementClickedInside) {\r\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\r\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\r\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\r\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_11__.TEXT_TO_CENTER_SNAP_THRESHOLD;\r\n if (isSnappedToCenter) {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\r\n return { viewportX, viewportY, elementCenterX, elementCenterY };\r\n }\r\n }\r\n }\r\n getCanvasOffsets() {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { left, top } = excalidrawContainer.getBoundingClientRect();\r\n return {\r\n offsetLeft: left,\r\n offsetTop: top,\r\n };\r\n }\r\n return {\r\n offsetLeft: 0,\r\n offsetTop: 0,\r\n };\r\n }\r\n updateLanguage() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\r\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\r\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\r\n this.setAppState({});\r\n });\r\n }\r\n}\r\nApp.defaultProps = {\r\n // needed for tests to pass since we directly render App in many tests\r\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_UI_OPTIONS,\r\n};\r\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n window.h = window.h || {};\r\n Object.defineProperties(window.h, {\r\n elements: {\r\n configurable: true,\r\n get() {\r\n return this.app.scene.getElementsIncludingDeleted();\r\n },\r\n set(elements) {\r\n return this.app.scene.replaceAllElements(elements);\r\n },\r\n },\r\n });\r\n}\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUMsUUFBNkI7Z0JBQy9CLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckQsQ0FBQztTQUNGO0tBQ0YsQ0FBQyxDQUFDO0NBQ0o7QUFDRCxpRUFBZSxHQUFHLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vY29tcG9uZW50cy9BcHAudHN4PzAwNzAiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHVzZUNvbnRleHQgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IFJvdWdoQ2FudmFzIH0gZnJvbSBcInJvdWdoanMvYmluL2NhbnZhc1wiO1xuaW1wb3J0IHJvdWdoIGZyb20gXCJyb3VnaGpzL2Jpbi9yb3VnaFwiO1xuaW1wb3J0IGNsc3ggZnJvbSBcImNsc3hcIjtcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gXCJuYW5vaWRcIjtcblxuaW1wb3J0IHtcbiAgYWN0aW9uQWRkVG9MaWJyYXJ5LFxuICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gIGFjdGlvbkJyaW5nVG9Gcm9udCxcbiAgYWN0aW9uQ29weSxcbiAgYWN0aW9uQ29weUFzUG5nLFxuICBhY3Rpb25Db3B5QXNTdmcsXG4gIGFjdGlvbkNvcHlTdHlsZXMsXG4gIGFjdGlvbkN1dCxcbiAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgYWN0aW9uRmluYWxpemUsXG4gIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICBhY3Rpb25GbGlwVmVydGljYWwsXG4gIGFjdGlvbkdyb3VwLFxuICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgYWN0aW9uU2VsZWN0QWxsLFxuICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gIGFjdGlvblNlbmRUb0JhY2ssXG4gIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgYWN0aW9uVW5ncm91cCxcbn0gZnJvbSBcIi4uL2FjdGlvbnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZG9BY3Rpb24sIGNyZWF0ZVVuZG9BY3Rpb24gfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25IaXN0b3J5XCI7XG5pbXBvcnQgeyBBY3Rpb25NYW5hZ2VyIH0gZnJvbSBcIi4uL2FjdGlvbnMvbWFuYWdlclwiO1xuaW1wb3J0IHsgYWN0aW9ucyB9IGZyb20gXCIuLi9hY3Rpb25zL3JlZ2lzdGVyXCI7XG5pbXBvcnQgeyBBY3Rpb25SZXN1bHQgfSBmcm9tIFwiLi4vYWN0aW9ucy90eXBlc1wiO1xuaW1wb3J0IHsgdHJhY2tFdmVudCB9IGZyb20gXCIuLi9hbmFseXRpY3NcIjtcbmltcG9ydCB7IGdldERlZmF1bHRBcHBTdGF0ZSB9IGZyb20gXCIuLi9hcHBTdGF0ZVwiO1xuaW1wb3J0IHtcbiAgY29weVRvQ2xpcGJvYXJkLFxuICBwYXJzZUNsaXBib2FyZCxcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IsXG4gIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQsXG59IGZyb20gXCIuLi9jbGlwYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFQUF9OQU1FLFxuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICBERUZBVUxUX1VJX09QVElPTlMsXG4gIERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gIERSQUdHSU5HX1RIUkVTSE9MRCxcbiAgRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5ULFxuICBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVOVixcbiAgRVZFTlQsXG4gIEdSSURfU0laRSxcbiAgSU1BR0VfUkVOREVSX1RJTUVPVVQsXG4gIExJTkVfQ09ORklSTV9USFJFU0hPTEQsXG4gIE1BWF9BTExPV0VEX0ZJTEVfQllURVMsXG4gIE1JTUVfVFlQRVMsXG4gIE1RX01BWF9IRUlHSFRfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfUE9SVFJBSVQsXG4gIFBPSU5URVJfQlVUVE9OLFxuICBTQ1JPTExfVElNRU9VVCxcbiAgVEFQX1RXSUNFX1RJTUVPVVQsXG4gIFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xELFxuICBUSEVNRSxcbiAgVE9VQ0hfQ1RYX01FTlVfVElNRU9VVCxcbiAgVVJMX0hBU0hfS0VZUyxcbiAgVVJMX1FVRVJZX0tFWVMsXG4gIFpPT01fU1RFUCxcbn0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgbG9hZEZyb21CbG9iIH0gZnJvbSBcIi4uL2RhdGFcIjtcbmltcG9ydCB7IGlzVmFsaWRMaWJyYXJ5IH0gZnJvbSBcIi4uL2RhdGEvanNvblwiO1xuaW1wb3J0IExpYnJhcnkgZnJvbSBcIi4uL2RhdGEvbGlicmFyeVwiO1xuaW1wb3J0IHsgcmVzdG9yZSwgcmVzdG9yZUVsZW1lbnRzLCByZXN0b3JlTGlicmFyeUl0ZW1zIH0gZnJvbSBcIi4uL2RhdGEvcmVzdG9yZVwiO1xuaW1wb3J0IHtcbiAgZHJhZ05ld0VsZW1lbnQsXG4gIGRyYWdTZWxlY3RlZEVsZW1lbnRzLFxuICBkdXBsaWNhdGVFbGVtZW50LFxuICBnZXRDb21tb25Cb3VuZHMsXG4gIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCxcbiAgZ2V0RHJhZ09mZnNldFhZLFxuICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gIGdldE5vcm1hbGl6ZWREaW1lbnNpb25zLFxuICBnZXRQZXJmZWN0RWxlbWVudFNpemUsXG4gIGdldFJlc2l6ZUFycm93RGlyZWN0aW9uLFxuICBnZXRSZXNpemVPZmZzZXRYWSxcbiAgZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMsXG4gIGhpdFRlc3QsXG4gIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudCxcbiAgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQsXG4gIGlzTm9uRGVsZXRlZEVsZW1lbnQsXG4gIGlzVGV4dEVsZW1lbnQsXG4gIG5ld0VsZW1lbnQsXG4gIG5ld0xpbmVhckVsZW1lbnQsXG4gIG5ld1RleHRFbGVtZW50LFxuICBuZXdJbWFnZUVsZW1lbnQsXG4gIHRleHRXeXNpd3lnLFxuICB0cmFuc2Zvcm1FbGVtZW50cyxcbiAgdXBkYXRlVGV4dEVsZW1lbnQsXG59IGZyb20gXCIuLi9lbGVtZW50XCI7XG5pbXBvcnQge1xuICBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzLFxuICBmaXhCaW5kaW5nc0FmdGVyRGVsZXRpb24sXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcsXG4gIGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyxcbiAgaXNCaW5kaW5nRW5hYmxlZCxcbiAgaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kLFxuICBtYXliZUJpbmRMaW5lYXJFbGVtZW50LFxuICBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50LFxuICB1bmJpbmRMaW5lYXJFbGVtZW50cyxcbiAgdXBkYXRlQm91bmRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvYmluZGluZ1wiO1xuaW1wb3J0IHsgTGluZWFyRWxlbWVudEVkaXRvciB9IGZyb20gXCIuLi9lbGVtZW50L2xpbmVhckVsZW1lbnRFZGl0b3JcIjtcbmltcG9ydCB7XG4gIGJ1bXBWZXJzaW9uLFxuICBtdXRhdGVFbGVtZW50LFxuICBuZXdFbGVtZW50V2l0aCxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHsgZGVlcENvcHlFbGVtZW50LCBuZXdGcmVlRHJhd0VsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudC9uZXdFbGVtZW50XCI7XG5pbXBvcnQge1xuICBoYXNCb3VuZFRleHRFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50VHlwZSxcbiAgaXNJbWFnZUVsZW1lbnQsXG4gIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQsXG4gIGlzTGluZWFyRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50VHlwZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZUNoZWNrc1wiO1xuaW1wb3J0IHtcbiAgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdHZW5lcmljRWxlbWVudCxcbiAgRXhjYWxpZHJhd0xpbmVhckVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgTm9uRGVsZXRlZCxcbiAgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICBGaWxlSWQsXG59IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDZW50ZXIsIGdldERpc3RhbmNlIH0gZnJvbSBcIi4uL2dlc3R1cmVcIjtcbmltcG9ydCB7XG4gIGVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudCxcbiAgZ2V0RWxlbWVudHNJbkdyb3VwLFxuICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50LFxuICBnZXRTZWxlY3RlZEdyb3VwSWRzLFxuICBpc0VsZW1lbnRJbkdyb3VwLFxuICBpc1NlbGVjdGVkVmlhR3JvdXAsXG4gIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMsXG59IGZyb20gXCIuLi9ncm91cHNcIjtcbmltcG9ydCBIaXN0b3J5IGZyb20gXCIuLi9oaXN0b3J5XCI7XG5pbXBvcnQgeyBkZWZhdWx0TGFuZywgZ2V0TGFuZ3VhZ2UsIGxhbmd1YWdlcywgc2V0TGFuZ3VhZ2UsIHQgfSBmcm9tIFwiLi4vaTE4blwiO1xuaW1wb3J0IHtcbiAgQ09ERVMsXG4gIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIsXG4gIHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8sXG4gIHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlLFxuICBpc0Fycm93S2V5LFxuICBLRVlTLFxufSBmcm9tIFwiLi4va2V5c1wiO1xuaW1wb3J0IHsgZGlzdGFuY2UyZCwgZ2V0R3JpZFBvaW50LCBpc1BhdGhBTG9vcCB9IGZyb20gXCIuLi9tYXRoXCI7XG5pbXBvcnQgeyByZW5kZXJTY2VuZSB9IGZyb20gXCIuLi9yZW5kZXJlclwiO1xuaW1wb3J0IHsgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudCB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJFbGVtZW50XCI7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVTY3JvbGxDZW50ZXIsXG4gIGdldEVsZW1lbnRDb250YWluaW5nUG9zaXRpb24sXG4gIGdldEVsZW1lbnRzQXRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24sXG4gIGdldE5vcm1hbGl6ZWRab29tLFxuICBnZXRTZWxlY3RlZEVsZW1lbnRzLFxuICBoYXNCYWNrZ3JvdW5kLFxuICBpc092ZXJTY3JvbGxCYXJzLFxuICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQsXG59IGZyb20gXCIuLi9zY2VuZVwiO1xuaW1wb3J0IFNjZW5lIGZyb20gXCIuLi9zY2VuZS9TY2VuZVwiO1xuaW1wb3J0IHsgUmVuZGVyQ29uZmlnLCBTY3JvbGxCYXJzIH0gZnJvbSBcIi4uL3NjZW5lL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXROZXdab29tIH0gZnJvbSBcIi4uL3NjZW5lL3pvb21cIjtcbmltcG9ydCB7IGZpbmRTaGFwZUJ5S2V5IH0gZnJvbSBcIi4uL3NoYXBlc1wiO1xuaW1wb3J0IHtcbiAgQXBwQ2xhc3NQcm9wZXJ0aWVzLFxuICBBcHBQcm9wcyxcbiAgQXBwU3RhdGUsXG4gIEJpbmFyeUZpbGVEYXRhLFxuICBEYXRhVVJMLFxuICBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSxcbiAgQmluYXJ5RmlsZXMsXG4gIEdlc3R1cmUsXG4gIEdlc3R1cmVFdmVudCxcbiAgTGlicmFyeUl0ZW1zLFxuICBQb2ludGVyRG93blN0YXRlLFxuICBTY2VuZURhdGEsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZGVib3VuY2UsXG4gIGRpc3RhbmNlLFxuICBnZXRGb250U3RyaW5nLFxuICBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcixcbiAgaXNJbnB1dExpa2UsXG4gIGlzVG9vbEljb24sXG4gIGlzV3JpdGFibGVFbGVtZW50LFxuICByZXNldEN1cnNvcixcbiAgcmVzb2x2YWJsZVByb21pc2UsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyxcbiAgc2V0Q3Vyc29yLFxuICBzZXRDdXJzb3JGb3JTaGFwZSxcbiAgdHVwbGVUb0Nvb3JzLFxuICB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMsXG4gIHdpdGhCYXRjaGVkVXBkYXRlcyxcbn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgQ29udGV4dE1lbnUsIHsgQ29udGV4dE1lbnVPcHRpb24gfSBmcm9tIFwiLi9Db250ZXh0TWVudVwiO1xuaW1wb3J0IExheWVyVUkgZnJvbSBcIi4vTGF5ZXJVSVwiO1xuaW1wb3J0IHsgU3RhdHMgfSBmcm9tIFwiLi9TdGF0c1wiO1xuaW1wb3J0IHsgVG9hc3QgfSBmcm9tIFwiLi9Ub2FzdFwiO1xuaW1wb3J0IHsgYWN0aW9uVG9nZ2xlVmlld01vZGUgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25Ub2dnbGVWaWV3TW9kZVwiO1xuaW1wb3J0IHtcbiAgZGF0YVVSTFRvRmlsZSxcbiAgZ2VuZXJhdGVJZEZyb21GaWxlLFxuICBnZXREYXRhVVJMLFxuICBpc1N1cHBvcnRlZEltYWdlRmlsZSxcbiAgcmVzaXplSW1hZ2VGaWxlLFxuICBTVkdTdHJpbmdUb0ZpbGUsXG59IGZyb20gXCIuLi9kYXRhL2Jsb2JcIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgbG9hZEhUTUxJbWFnZUVsZW1lbnQsXG4gIG5vcm1hbGl6ZVNWRyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSBhcyBfdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcbmltcG9ydCB0aHJvdHRsZSBmcm9tIFwibG9kYXNoLnRocm90dGxlXCI7XG5pbXBvcnQgeyBmaWxlT3BlbiwgbmF0aXZlRmlsZVN5c3RlbVN1cHBvcnRlZCB9IGZyb20gXCIuLi9kYXRhL2ZpbGVzeXN0ZW1cIjtcbmltcG9ydCB7XG4gIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24sXG4gIGdldEFwcHJveE1pbkxpbmVIZWlnaHQsXG4gIGdldEFwcHJveE1pbkxpbmVXaWR0aCxcbiAgZ2V0Qm91bmRUZXh0RWxlbWVudElkLFxufSBmcm9tIFwiLi4vZWxlbWVudC90ZXh0RWxlbWVudFwiO1xuaW1wb3J0IHsgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3ggfSBmcm9tIFwiLi4vZWxlbWVudC9jb2xsaXNpb25cIjtcblxuY29uc3QgSXNNb2JpbGVDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dChmYWxzZSk7XG5leHBvcnQgY29uc3QgdXNlSXNNb2JpbGUgPSAoKSA9PiB1c2VDb250ZXh0KElzTW9iaWxlQ29udGV4dCk7XG5jb25zdCBFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8e1xuICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgaWQ6IHN0cmluZyB8IG51bGw7XG59Pih7IGNvbnRhaW5lcjogbnVsbCwgaWQ6IG51bGwgfSk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd0NvbnRhaW5lciA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQpO1xuXG5sZXQgZGlkVGFwVHdpY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCB0YXBwZWRUd2ljZVRpbWVyID0gMDtcbmxldCBjdXJzb3JYID0gMDtcbmxldCBjdXJzb3JZID0gMDtcbmxldCBpc0hvbGRpbmdTcGFjZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzUGFubmluZzogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzRHJhZ2dpbmdTY3JvbGxCYXI6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBjdXJyZW50U2Nyb2xsQmFyczogU2Nyb2xsQmFycyA9IHsgaG9yaXpvbnRhbDogbnVsbCwgdmVydGljYWw6IG51bGwgfTtcbmxldCB0b3VjaFRpbWVvdXQgPSAwO1xubGV0IGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG5sZXQgbGFzdFBvaW50ZXJVcDogKChldmVudDogYW55KSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuY29uc3QgZ2VzdHVyZTogR2VzdHVyZSA9IHtcbiAgcG9pbnRlcnM6IG5ldyBNYXAoKSxcbiAgbGFzdENlbnRlcjogbnVsbCxcbiAgaW5pdGlhbERpc3RhbmNlOiBudWxsLFxuICBpbml0aWFsU2NhbGU6IG51bGwsXG59O1xuXG5jbGFzcyBBcHAgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8QXBwUHJvcHMsIEFwcFN0YXRlPiB7XG4gIGNhbnZhczogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiY2FudmFzXCJdID0gbnVsbDtcbiAgcmM6IFJvdWdoQ2FudmFzIHwgbnVsbCA9IG51bGw7XG4gIHVubW91bnRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBhY3Rpb25NYW5hZ2VyOiBBY3Rpb25NYW5hZ2VyO1xuICBpc01vYmlsZSA9IGZhbHNlO1xuICBkZXRhY2hJc01vYmlsZU1xSGFuZGxlcj86ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBleGNhbGlkcmF3Q29udGFpbmVyUmVmID0gUmVhY3QuY3JlYXRlUmVmPEhUTUxEaXZFbGVtZW50PigpO1xuXG4gIHB1YmxpYyBzdGF0aWMgZGVmYXVsdFByb3BzOiBQYXJ0aWFsPEFwcFByb3BzPiA9IHtcbiAgICAvLyBuZWVkZWQgZm9yIHRlc3RzIHRvIHBhc3Mgc2luY2Ugd2UgZGlyZWN0bHkgcmVuZGVyIEFwcCBpbiBtYW55IHRlc3RzXG4gICAgVUlPcHRpb25zOiBERUZBVUxUX1VJX09QVElPTlMsXG4gIH07XG5cbiAgcHJpdmF0ZSBzY2VuZTogU2NlbmU7XG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyOiBIVE1MRWxlbWVudCB8IERvY3VtZW50IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgbGlicmFyeTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wibGlicmFyeVwiXTtcbiAgcHVibGljIGxpYnJhcnlJdGVtc0Zyb21TdG9yYWdlOiBMaWJyYXJ5SXRlbXMgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBoaXN0b3J5OiBIaXN0b3J5O1xuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZToge1xuICAgIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICAgIGlkOiBzdHJpbmc7XG4gIH07XG5cbiAgcHVibGljIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHt9O1xuICBwdWJsaWMgaW1hZ2VDYWNoZTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiaW1hZ2VDYWNoZVwiXSA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQXBwUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG4gICAgY29uc3Qge1xuICAgICAgZXhjYWxpZHJhd1JlZixcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgemVuTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIGdyaWRNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgdGhlbWUgPSBkZWZhdWx0QXBwU3RhdGUudGhlbWUsXG4gICAgICBuYW1lID0gZGVmYXVsdEFwcFN0YXRlLm5hbWUsXG4gICAgfSA9IHByb3BzO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi5kZWZhdWx0QXBwU3RhdGUsXG4gICAgICB0aGVtZSxcbiAgICAgIGlzTG9hZGluZzogdHJ1ZSxcbiAgICAgIC4uLnRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpLFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICBncmlkU2l6ZTogZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIG5hbWUsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICB9O1xuXG4gICAgdGhpcy5pZCA9IG5hbm9pZCgpO1xuXG4gICAgaWYgKGV4Y2FsaWRyYXdSZWYpIHtcbiAgICAgIGNvbnN0IHJlYWR5UHJvbWlzZSA9XG4gICAgICAgIChcImN1cnJlbnRcIiBpbiBleGNhbGlkcmF3UmVmICYmIGV4Y2FsaWRyYXdSZWYuY3VycmVudD8ucmVhZHlQcm9taXNlKSB8fFxuICAgICAgICByZXNvbHZhYmxlUHJvbWlzZTxFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQST4oKTtcblxuICAgICAgY29uc3QgYXBpOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSA9IHtcbiAgICAgICAgcmVhZHk6IHRydWUsXG4gICAgICAgIHJlYWR5UHJvbWlzZSxcbiAgICAgICAgdXBkYXRlU2NlbmU6IHRoaXMudXBkYXRlU2NlbmUsXG4gICAgICAgIGFkZEZpbGVzOiB0aGlzLmFkZEZpbGVzLFxuICAgICAgICByZXNldFNjZW5lOiB0aGlzLnJlc2V0U2NlbmUsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkOiB0aGlzLmdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkLFxuICAgICAgICBoaXN0b3J5OiB7XG4gICAgICAgICAgY2xlYXI6IHRoaXMucmVzZXRIaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgICBzY3JvbGxUb0NvbnRlbnQ6IHRoaXMuc2Nyb2xsVG9Db250ZW50LFxuICAgICAgICBnZXRTY2VuZUVsZW1lbnRzOiB0aGlzLmdldFNjZW5lRWxlbWVudHMsXG4gICAgICAgIGdldEFwcFN0YXRlOiAoKSA9PiB0aGlzLnN0YXRlLFxuICAgICAgICBnZXRGaWxlczogKCkgPT4gdGhpcy5maWxlcyxcbiAgICAgICAgcmVmcmVzaDogdGhpcy5yZWZyZXNoLFxuICAgICAgICBpbXBvcnRMaWJyYXJ5OiB0aGlzLmltcG9ydExpYnJhcnlGcm9tVXJsLFxuICAgICAgICBzZXRUb2FzdE1lc3NhZ2U6IHRoaXMuc2V0VG9hc3RNZXNzYWdlLFxuICAgICAgICBpZDogdGhpcy5pZCxcbiAgICAgIH0gYXMgY29uc3Q7XG4gICAgICBpZiAodHlwZW9mIGV4Y2FsaWRyYXdSZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBleGNhbGlkcmF3UmVmKGFwaSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGNhbGlkcmF3UmVmLmN1cnJlbnQgPSBhcGk7XG4gICAgICB9XG4gICAgICByZWFkeVByb21pc2UucmVzb2x2ZShhcGkpO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlID0ge1xuICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCxcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgIH07XG5cbiAgICB0aGlzLnNjZW5lID0gbmV3IFNjZW5lKCk7XG4gICAgdGhpcy5saWJyYXJ5ID0gbmV3IExpYnJhcnkodGhpcyk7XG4gICAgdGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIgPSBuZXcgQWN0aW9uTWFuYWdlcihcbiAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCxcbiAgICAgICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAoKSA9PiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcyxcbiAgICApO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFsbChhY3Rpb25zKTtcblxuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVVbmRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVSZWRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJDYW52YXMoKSB7XG4gICAgY29uc3QgY2FudmFzU2NhbGUgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICB9ID0gdGhpcy5zdGF0ZTtcbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhc0RPTVdpZHRoICogY2FudmFzU2NhbGU7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY2FudmFzRE9NSGVpZ2h0ICogY2FudmFzU2NhbGU7XG4gICAgaWYgKHZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPGNhbnZhc1xuICAgICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICAgICAgY3Vyc29yOiBDVVJTT1JfVFlQRS5HUkFCLFxuICAgICAgICAgIH19XG4gICAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgICAgb25Qb2ludGVyQ2FuY2VsPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgID5cbiAgICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgICA8L2NhbnZhcz5cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiAoXG4gICAgICA8Y2FudmFzXG4gICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICB9fVxuICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICByZWY9e3RoaXMuaGFuZGxlQ2FudmFzUmVmfVxuICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICBvblBvaW50ZXJEb3duPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJEb3dufVxuICAgICAgICBvbkRvdWJsZUNsaWNrPXt0aGlzLmhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrfVxuICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICBvblBvaW50ZXJVcD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgPlxuICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgPC9jYW52YXM+XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZW5kZXIoKSB7XG4gICAgY29uc3QgeyB6ZW5Nb2RlRW5hYmxlZCwgdmlld01vZGVFbmFibGVkIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgY29uc3Qge1xuICAgICAgb25Db2xsYWJCdXR0b25DbGljayxcbiAgICAgIHJlbmRlclRvcFJpZ2h0VUksXG4gICAgICByZW5kZXJGb290ZXIsXG4gICAgICByZW5kZXJDdXN0b21TdGF0cyxcbiAgICB9ID0gdGhpcy5wcm9wcztcblxuICAgIHJldHVybiAoXG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT17Y2xzeChcImV4Y2FsaWRyYXcgZXhjYWxpZHJhdy1jb250YWluZXJcIiwge1xuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tdmlldy1tb2RlXCI6IHZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLW1vYmlsZVwiOiB0aGlzLmlzTW9iaWxlLFxuICAgICAgICB9KX1cbiAgICAgICAgcmVmPXt0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWZ9XG4gICAgICAgIG9uRHJvcD17dGhpcy5oYW5kbGVBcHBPbkRyb3B9XG4gICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgICBvbktleURvd249e1xuICAgICAgICAgIHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSA/IHVuZGVmaW5lZCA6IHRoaXMub25LZXlEb3duXG4gICAgICAgIH1cbiAgICAgID5cbiAgICAgICAgPEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0LlByb3ZpZGVyXG4gICAgICAgICAgdmFsdWU9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlfVxuICAgICAgICA+XG4gICAgICAgICAgPElzTW9iaWxlQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dGhpcy5pc01vYmlsZX0+XG4gICAgICAgICAgICA8TGF5ZXJVSVxuICAgICAgICAgICAgICBjYW52YXM9e3RoaXMuY2FudmFzfVxuICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgZmlsZXM9e3RoaXMuZmlsZXN9XG4gICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICBhY3Rpb25NYW5hZ2VyPXt0aGlzLmFjdGlvbk1hbmFnZXJ9XG4gICAgICAgICAgICAgIGVsZW1lbnRzPXt0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCl9XG4gICAgICAgICAgICAgIG9uQ29sbGFiQnV0dG9uQ2xpY2s9e29uQ29sbGFiQnV0dG9uQ2xpY2t9XG4gICAgICAgICAgICAgIG9uTG9ja1RvZ2dsZT17dGhpcy50b2dnbGVMb2NrfVxuICAgICAgICAgICAgICBvbkluc2VydEVsZW1lbnRzPXsoZWxlbWVudHMpID0+XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgICAgICAgZmlsZXM6IG51bGwsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZD17emVuTW9kZUVuYWJsZWR9XG4gICAgICAgICAgICAgIHRvZ2dsZVplbk1vZGU9e3RoaXMudG9nZ2xlWmVuTW9kZX1cbiAgICAgICAgICAgICAgbGFuZ0NvZGU9e2dldExhbmd1YWdlKCkuY29kZX1cbiAgICAgICAgICAgICAgaXNDb2xsYWJvcmF0aW5nPXt0aGlzLnByb3BzLmlzQ29sbGFib3JhdGluZyB8fCBmYWxzZX1cbiAgICAgICAgICAgICAgcmVuZGVyVG9wUmlnaHRVST17cmVuZGVyVG9wUmlnaHRVSX1cbiAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tRm9vdGVyPXtyZW5kZXJGb290ZXJ9XG4gICAgICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZD17dmlld01vZGVFbmFibGVkfVxuICAgICAgICAgICAgICBzaG93RXhpdFplbk1vZGVCdG49e1xuICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzPy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2hvd1RoZW1lQnRuPXtcbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8udGhlbWUgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5jYW52YXNBY3Rpb25zLnRoZW1lXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGlicmFyeVJldHVyblVybD17dGhpcy5wcm9wcy5saWJyYXJ5UmV0dXJuVXJsfVxuICAgICAgICAgICAgICBVSU9wdGlvbnM9e3RoaXMucHJvcHMuVUlPcHRpb25zfVxuICAgICAgICAgICAgICBmb2N1c0NvbnRhaW5lcj17dGhpcy5mb2N1c0NvbnRhaW5lcn1cbiAgICAgICAgICAgICAgbGlicmFyeT17dGhpcy5saWJyYXJ5fVxuICAgICAgICAgICAgICBpZD17dGhpcy5pZH1cbiAgICAgICAgICAgICAgb25JbWFnZUFjdGlvbj17dGhpcy5vbkltYWdlQWN0aW9ufVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy10ZXh0RWRpdG9yQ29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy1jb250ZXh0TWVudUNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICB7dGhpcy5zdGF0ZS5zaG93U3RhdHMgJiYgKFxuICAgICAgICAgICAgICA8U3RhdHNcbiAgICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgICBzZXRBcHBTdGF0ZT17dGhpcy5zZXRBcHBTdGF0ZX1cbiAgICAgICAgICAgICAgICBlbGVtZW50cz17dGhpcy5zY2VuZS5nZXRFbGVtZW50cygpfVxuICAgICAgICAgICAgICAgIG9uQ2xvc2U9e3RoaXMudG9nZ2xlU3RhdHN9XG4gICAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tU3RhdHM9e3JlbmRlckN1c3RvbVN0YXRzfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLnRvYXN0TWVzc2FnZSAhPT0gbnVsbCAmJiAoXG4gICAgICAgICAgICAgIDxUb2FzdFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U9e3RoaXMuc3RhdGUudG9hc3RNZXNzYWdlfVxuICAgICAgICAgICAgICAgIGNsZWFyVG9hc3Q9e3RoaXMuY2xlYXJUb2FzdH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8bWFpbj57dGhpcy5yZW5kZXJDYW52YXMoKX08L21haW4+XG4gICAgICAgICAgPC9Jc01vYmlsZUNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgIDwvRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGZvY3VzQ29udGFpbmVyOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJmb2N1c0NvbnRhaW5lclwiXSA9ICgpID0+IHtcbiAgICBpZiAodGhpcy5wcm9wcy5hdXRvRm9jdXMpIHtcbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gIH07XG5cbiAgcHVibGljIGdldFNjZW5lRWxlbWVudHMgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcbiAgfTtcblxuICBwcml2YXRlIHN5bmNBY3Rpb25SZXN1bHQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGFjdGlvblJlc3VsdDogQWN0aW9uUmVzdWx0KSA9PiB7XG4gICAgICBpZiAodGhpcy51bm1vdW50ZWQgfHwgYWN0aW9uUmVzdWx0ID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBlZGl0aW5nRWxlbWVudDogQXBwU3RhdGVbXCJlZGl0aW5nRWxlbWVudFwiXSB8IG51bGwgPSBudWxsO1xuICAgICAgaWYgKGFjdGlvblJlc3VsdC5lbGVtZW50cykge1xuICAgICAgICBhY3Rpb25SZXN1bHQuZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQ/LmlkID09PSBlbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50ICE9PSBlbGVtZW50ICYmXG4gICAgICAgICAgICBpc05vbkRlbGV0ZWRFbGVtZW50KGVsZW1lbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBlZGl0aW5nRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKTtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGFjdGlvblJlc3VsdC5maWxlcykge1xuICAgICAgICB0aGlzLmZpbGVzID0gYWN0aW9uUmVzdWx0LnJlcGxhY2VGaWxlc1xuICAgICAgICAgID8gYWN0aW9uUmVzdWx0LmZpbGVzXG4gICAgICAgICAgOiB7IC4uLnRoaXMuZmlsZXMsIC4uLmFjdGlvblJlc3VsdC5maWxlcyB9O1xuICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmFwcFN0YXRlIHx8IGVkaXRpbmdFbGVtZW50KSB7XG4gICAgICAgIGlmIChhY3Rpb25SZXN1bHQuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHZpZXdNb2RlRW5hYmxlZCA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LnZpZXdNb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IHplbk1vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uemVuTW9kZUVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGxldCBncmlkU2l6ZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LmdyaWRTaXplIHx8IG51bGw7XG4gICAgICAgIGxldCB0aGVtZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LnRoZW1lIHx8IFRIRU1FLkxJR0hUO1xuICAgICAgICBsZXQgbmFtZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/Lm5hbWUgPz8gdGhpcy5zdGF0ZS5uYW1lO1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdmlld01vZGVFbmFibGVkID0gdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZCA9IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgZ3JpZFNpemUgPSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMudGhlbWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB0aGVtZSA9IHRoaXMucHJvcHMudGhlbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMubmFtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIG5hbWUgPSB0aGlzLnByb3BzLm5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIC8vIHVzaW5nIE9iamVjdC5hc3NpZ24gaW5zdGVhZCBvZiBzcHJlYWQgdG8gZm9vbCBUUyA0LjIuMisgaW50b1xuICAgICAgICAgICAgLy8gcmVnYXJkaW5nIHRoZSByZXN1bHRpbmcgdHlwZSBhcyBub3QgY29udGFpbmluZyB1bmRlZmluZWRcbiAgICAgICAgICAgIC8vICh3aGljaCB0aGUgZm9sbG93aW5nIGV4cHJlc3Npb24gd2lsbCBuZXZlciBjb250YWluKVxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oYWN0aW9uUmVzdWx0LmFwcFN0YXRlIHx8IHt9LCB7XG4gICAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50IHx8IGFjdGlvblJlc3VsdC5hcHBTdGF0ZT8uZWRpdGluZ0VsZW1lbnQgfHwgbnVsbCxcbiAgICAgICAgICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZCxcbiAgICAgICAgICAgICAgZ3JpZFNpemUsXG4gICAgICAgICAgICAgIHRoZW1lLFxuICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LnN5bmNIaXN0b3J5KSB7XG4gICAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5zZXRDdXJyZW50U3RhdGUoXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICAvLyBMaWZlY3ljbGVcblxuICBwcml2YXRlIG9uQmx1ciA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgaXNIb2xkaW5nU3BhY2UgPSBmYWxzZTtcbiAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogdHJ1ZSB9KTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBvblVubG9hZCA9ICgpID0+IHtcbiAgICB0aGlzLm9uQmx1cigpO1xuICB9O1xuXG4gIHByaXZhdGUgZGlzYWJsZUV2ZW50OiBFdmVudExpc3RlbmVyID0gKGV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfTtcblxuICBwcml2YXRlIG9uRm9udExvYWRlZCA9ICgpID0+IHtcbiAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgIGlmIChpc1RleHRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vblNjZW5lVXBkYXRlZCgpO1xuICB9O1xuXG4gIHByaXZhdGUgaW1wb3J0TGlicmFyeUZyb21VcmwgPSBhc3luYyAodXJsOiBzdHJpbmcsIHRva2VuPzogc3RyaW5nIHwgbnVsbCkgPT4ge1xuICAgIGlmICh3aW5kb3cubG9jYXRpb24uaGFzaC5pbmNsdWRlcyhVUkxfSEFTSF9LRVlTLmFkZExpYnJhcnkpKSB7XG4gICAgICBjb25zdCBoYXNoID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uaGFzaC5zbGljZSgxKSk7XG4gICAgICBoYXNoLmRlbGV0ZShVUkxfSEFTSF9LRVlTLmFkZExpYnJhcnkpO1xuICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCBBUFBfTkFNRSwgYCMke2hhc2gudG9TdHJpbmcoKX1gKTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5jbHVkZXMoVVJMX1FVRVJZX0tFWVMuYWRkTGlicmFyeSkpIHtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcbiAgICAgIHF1ZXJ5LmRlbGV0ZShVUkxfUVVFUllfS0VZUy5hZGRMaWJyYXJ5KTtcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwgQVBQX05BTUUsIGA/JHtxdWVyeS50b1N0cmluZygpfWApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gYXdhaXQgZmV0Y2goZGVjb2RlVVJJQ29tcG9uZW50KHVybCkpO1xuICAgICAgY29uc3QgYmxvYiA9IGF3YWl0IHJlcXVlc3QuYmxvYigpO1xuICAgICAgY29uc3QganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgYmxvYi50ZXh0KCkpO1xuICAgICAgaWYgKCFpc1ZhbGlkTGlicmFyeShqc29uKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgdG9rZW4gPT09IHRoaXMuaWQgfHxcbiAgICAgICAgd2luZG93LmNvbmZpcm0oXG4gICAgICAgICAgdChcImFsZXJ0cy5jb25maXJtQWRkTGlicmFyeVwiLCB7XG4gICAgICAgICAgICBudW1TaGFwZXM6IChqc29uLmxpYnJhcnlJdGVtcyB8fCBqc29uLmxpYnJhcnkgfHwgW10pLmxlbmd0aCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubGlicmFyeS5pbXBvcnRMaWJyYXJ5KGJsb2IsIFwicHVibGlzaGVkXCIpO1xuICAgICAgICAvLyBoYWNrIHRvIHJlcmVuZGVyIHRoZSBsaWJyYXJ5IGl0ZW1zIGFmdGVyIGltcG9ydFxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiB0cnVlIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHdpbmRvdy5hbGVydCh0KFwiYWxlcnRzLmVycm9yTG9hZGluZ0xpYnJhcnlcIikpO1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEhpc3RvcnkgPSAoKSA9PiB7XG4gICAgdGhpcy5oaXN0b3J5LmNsZWFyKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlc2V0cyBzY2VuZSAmIGhpc3RvcnkuXG4gICAqICEgRG8gbm90IHVzZSB0byBjbGVhciBzY2VuZSB1c2VyIGFjdGlvbiAhXG4gICAqL1xuICBwcml2YXRlIHJlc2V0U2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKG9wdHM/OiB7IHJlc2V0TG9hZGluZ1N0YXRlOiBib29sZWFuIH0pID0+IHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXREZWZhdWx0QXBwU3RhdGUoKSxcbiAgICAgICAgaXNMb2FkaW5nOiBvcHRzPy5yZXNldExvYWRpbmdTdGF0ZSA/IGZhbHNlIDogc3RhdGUuaXNMb2FkaW5nLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGluaXRpYWxpemVTY2VuZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAoXCJsYXVuY2hRdWV1ZVwiIGluIHdpbmRvdyAmJiBcIkxhdW5jaFBhcmFtc1wiIGluIHdpbmRvdykge1xuICAgICAgKHdpbmRvdyBhcyBhbnkpLmxhdW5jaFF1ZXVlLnNldENvbnN1bWVyKFxuICAgICAgICBhc3luYyAobGF1bmNoUGFyYW1zOiB7IGZpbGVzOiBhbnlbXSB9KSA9PiB7XG4gICAgICAgICAgaWYgKCFsYXVuY2hQYXJhbXMuZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpbGVIYW5kbGUgPSBsYXVuY2hQYXJhbXMuZmlsZXNbMF07XG4gICAgICAgICAgY29uc3QgYmxvYjogQmxvYiA9IGF3YWl0IGZpbGVIYW5kbGUuZ2V0RmlsZSgpO1xuICAgICAgICAgIGJsb2IuaGFuZGxlID0gZmlsZUhhbmRsZTtcbiAgICAgICAgICBsb2FkRnJvbUJsb2IoXG4gICAgICAgICAgICBibG9iLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHNjZW5lKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgICAgICAgLi4uc2NlbmUsXG4gICAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogZmFsc2UsIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgIH1cbiAgICBsZXQgaW5pdGlhbERhdGEgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBpbml0aWFsRGF0YSA9IChhd2FpdCB0aGlzLnByb3BzLmluaXRpYWxEYXRhKSB8fCBudWxsO1xuICAgICAgaWYgKGluaXRpYWxEYXRhPy5saWJyYXJ5SXRlbXMpIHtcbiAgICAgICAgdGhpcy5saWJyYXJ5SXRlbXNGcm9tU3RvcmFnZSA9IHJlc3RvcmVMaWJyYXJ5SXRlbXMoXG4gICAgICAgICAgaW5pdGlhbERhdGEubGlicmFyeUl0ZW1zLFxuICAgICAgICAgIFwidW5wdWJsaXNoZWRcIixcbiAgICAgICAgKSBhcyBMaWJyYXJ5SXRlbXM7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICBpbml0aWFsRGF0YSA9IHtcbiAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICBlcnJvck1lc3NhZ2U6XG4gICAgICAgICAgICBlcnJvci5tZXNzYWdlIHx8XG4gICAgICAgICAgICBcIkVuY291bnRlcmVkIGFuIGVycm9yIGR1cmluZyBpbXBvcnRpbmcgb3IgcmVzdG9yaW5nIHNjZW5lIGRhdGFcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc2NlbmUgPSByZXN0b3JlKGluaXRpYWxEYXRhLCBudWxsLCBudWxsKTtcblxuICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICBlbGVtZW50VHlwZTpcbiAgICAgICAgc2NlbmUuYXBwU3RhdGUuZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VcIlxuICAgICAgICAgID8gXCJzZWxlY3Rpb25cIlxuICAgICAgICAgIDogc2NlbmUuYXBwU3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxUb0NvbnRlbnQpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICAgIHNjZW5lLmVsZW1lbnRzLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAgICAgd2lkdGg6IHRoaXMuc3RhdGUud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuc3RhdGUuaGVpZ2h0LFxuICAgICAgICAgICAgb2Zmc2V0VG9wOiB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgICAgIG9mZnNldExlZnQ6IHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgIC4uLnNjZW5lLFxuICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbGlicmFyeVVybCA9XG4gICAgICAvLyBjdXJyZW50XG4gICAgICBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5oYXNoLnNsaWNlKDEpKS5nZXQoXG4gICAgICAgIFVSTF9IQVNIX0tFWVMuYWRkTGlicmFyeSxcbiAgICAgICkgfHxcbiAgICAgIC8vIGxlZ2FjeSwga2VwdCBmb3IgY29tcGF0IHJlYXNvbnNcbiAgICAgIG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCkuZ2V0KFxuICAgICAgICBVUkxfUVVFUllfS0VZUy5hZGRMaWJyYXJ5LFxuICAgICAgKTtcblxuICAgIGlmIChsaWJyYXJ5VXJsKSB7XG4gICAgICBhd2FpdCB0aGlzLmltcG9ydExpYnJhcnlGcm9tVXJsKGxpYnJhcnlVcmwpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgYXN5bmMgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUuY29udGFpbmVyID1cbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuXG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5URVNUIHx8XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4gICAgKSB7XG4gICAgICBjb25zdCBzZXRTdGF0ZSA9IHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2V0U3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6ICguLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiBzZXRTdGF0ZT4pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKC4uLmFyZ3MpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFwcDoge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcyxcbiAgICAgICAgfSxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcy5oaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5hZGRDYWxsYmFjayh0aGlzLm9uU2NlbmVVcGRhdGVkKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoXCJSZXNpemVPYnNlcnZlclwiIGluIHdpbmRvdyAmJiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAvLyBjb21wdXRlIGlzTW9iaWxlIHN0YXRlXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9XG4gICAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB0aGlzLmlzTW9iaWxlID1cbiAgICAgICAgICB3aWR0aCA8IE1RX01BWF9XSURUSF9QT1JUUkFJVCB8fFxuICAgICAgICAgIChoZWlnaHQgPCBNUV9NQVhfSEVJR0hUX0xBTkRTQ0FQRSAmJiB3aWR0aCA8IE1RX01BWF9XSURUSF9MQU5EU0NBUEUpO1xuICAgICAgICAvLyByZWZyZXNoIG9mZnNldHNcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCgpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5vYnNlcnZlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKSB7XG4gICAgICBjb25zdCBtZWRpYVF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9QT1JUUkFJVH1weCksIChtYXgtaGVpZ2h0OiAke01RX01BWF9IRUlHSFRfTEFORFNDQVBFfXB4KSBhbmQgKG1heC13aWR0aDogJHtNUV9NQVhfV0lEVEhfTEFORFNDQVBFfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+ICh0aGlzLmlzTW9iaWxlID0gbWVkaWFRdWVyeS5tYXRjaGVzKTtcbiAgICAgIG1lZGlhUXVlcnkuYWRkTGlzdGVuZXIoaGFuZGxlcik7XG4gICAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyID0gKCkgPT4gbWVkaWFRdWVyeS5yZW1vdmVMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc2xpY2UoMSkpO1xuXG4gICAgaWYgKHNlYXJjaFBhcmFtcy5oYXMoXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpKSB7XG4gICAgICAvLyBPYnRhaW4gYSBmaWxlIHRoYXQgd2FzIHNoYXJlZCB2aWEgdGhlIFdlYiBTaGFyZSBUYXJnZXQgQVBJLlxuICAgICAgdGhpcy5yZXN0b3JlRmlsZUZyb21TaGFyZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURPTVJlY3QodGhpcy5pbml0aWFsaXplU2NlbmUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICB0aGlzLmZpbGVzID0ge307XG4gICAgdGhpcy5pbWFnZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMudW5tb3VudGVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zY2VuZS5kZXN0cm95KCk7XG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgfVxuXG4gIHByaXZhdGUgb25SZXNpemUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIHRoaXMuc2NlbmVcbiAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgLmZvckVhY2goKGVsZW1lbnQpID0+IGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9KTtcblxuICBwcml2YXRlIHJlbW92ZUV2ZW50TGlzdGVuZXJzKCkge1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5EUkFHX09WRVIsIHRoaXMuZGlzYWJsZUV2ZW50LCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuRFJPUCwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcblxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX1NUQVJULFxuICAgICAgdGhpcy5vbkdlc3R1cmVTdGFydCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0NIQU5HRSxcbiAgICAgIHRoaXMub25HZXN0dXJlQ2hhbmdlIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfRU5ELFxuICAgICAgdGhpcy5vbkdlc3R1cmVFbmQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcblxuICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXI/LigpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpOyAvLyAjMzU1M1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGlmICh0aGlzLnByb3BzLmhhbmRsZUtleWJvYXJkR2xvYmFsbHkpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgdGhpcy5vbktleURvd24sIGZhbHNlKTtcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgdGhpcy5vbktleVVwLCB7IHBhc3NpdmU6IHRydWUgfSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULk1PVVNFX01PVkUsXG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbixcbiAgICApO1xuICAgIC8vIHJlcmVuZGVyIHRleHQgZWxlbWVudHMgb24gZm9udCBsb2FkIHRvIGZpeCAjNjM3ICYmICMxNTUzXG4gICAgZG9jdW1lbnQuZm9udHM/LmFkZEV2ZW50TGlzdGVuZXI/LihcImxvYWRpbmdkb25lXCIsIHRoaXMub25Gb250TG9hZGVkKTtcbiAgICAvLyBTYWZhcmktb25seSBkZXNrdG9wIHBpbmNoIHpvb21cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ1VULCB0aGlzLm9uQ3V0KTtcbiAgICBpZiAodGhpcy5wcm9wcy5kZXRlY3RTY3JvbGwpIHtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIgPSBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcihcbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgKTtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuU0NST0xMLFxuICAgICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICAgKTtcbiAgICB9XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5EUkFHX09WRVIsIHRoaXMuZGlzYWJsZUV2ZW50LCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuRFJPUCwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcbiAgfVxuXG4gIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IEFwcFByb3BzLCBwcmV2U3RhdGU6IEFwcFN0YXRlKSB7XG4gICAgaWYgKHByZXZQcm9wcy5sYW5nQ29kZSAhPT0gdGhpcy5wcm9wcy5sYW5nQ29kZSkge1xuICAgICAgdGhpcy51cGRhdGVMYW5ndWFnZSgpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpZXdNb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCB9KTtcbiAgICB9XG5cbiAgICBpZiAocHJldlN0YXRlLnZpZXdNb2RlRW5hYmxlZCAhPT0gdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB6ZW5Nb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudGhlbWUgIT09IHRoaXMucHJvcHMudGhlbWUgJiYgdGhpcy5wcm9wcy50aGVtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHRoZW1lOiB0aGlzLnByb3BzLnRoZW1lIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGdyaWRTaXplOiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9wcy5uYW1lICYmIHByZXZQcm9wcy5uYW1lICE9PSB0aGlzLnByb3BzLm5hbWUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBuYW1lOiB0aGlzLnByb3BzLm5hbWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY2xhc3NMaXN0LnRvZ2dsZShcbiAgICAgIFwidGhlbWUtLWRhcmtcIixcbiAgICAgIHRoaXMuc3RhdGUudGhlbWUgPT09IFwiZGFya1wiLFxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdXG4gICAgKSB7XG4gICAgICAvLyBkZWZlciBzbyB0aGF0IHRoZSBjb21taXRUb0hpc3RvcnkgZmxhZyBpc24ndCByZXNldCB2aWEgY3VycmVudCB1cGRhdGVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHByZXZTdGF0ZTtcbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuZWxlbWVudFR5cGUgIT09IHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgJiZcbiAgICAgIG11bHRpRWxlbWVudCAhPSBudWxsICYmXG4gICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpICYmXG4gICAgICBpc0JpbmRpbmdFbGVtZW50KG11bHRpRWxlbWVudClcbiAgICApIHtcbiAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRBdEluZGV4R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgICAgICAtMSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJzb3JCdXR0b246IHtcbiAgICAgIFtpZDogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVmlld3BvcnRDb29yZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlcm5hbWVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlclN0YXRlczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgdGhpcy5zdGF0ZS5jb2xsYWJvcmF0b3JzLmZvckVhY2goKHVzZXIsIHNvY2tldElkKSA9PiB7XG4gICAgICBpZiAodXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICBpZiAoIShpZCBpbiByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0ucHVzaChzb2NrZXRJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghdXNlci5wb2ludGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICAgIHBvaW50ZXJVc2VybmFtZXNbc29ja2V0SWRdID0gdXNlci51c2VybmFtZTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJTdGF0ZSkge1xuICAgICAgICBwb2ludGVyVXNlclN0YXRlc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJTdGF0ZTtcbiAgICAgIH1cbiAgICAgIHBvaW50ZXJWaWV3cG9ydENvb3Jkc1tzb2NrZXRJZF0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgIHtcbiAgICAgICAgICBzY2VuZVg6IHVzZXIucG9pbnRlci54LFxuICAgICAgICAgIHNjZW5lWTogdXNlci5wb2ludGVyLnksXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY3Vyc29yQnV0dG9uW3NvY2tldElkXSA9IHVzZXIuYnV0dG9uO1xuICAgIH0pO1xuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLmZpbHRlcigoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAvLyBub3QgcGxhY2VkIG9uIGNhbnZhcyB5ZXQgKGJ1dCBpbiBlbGVtZW50cyBhcnJheSlcbiAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQgJiZcbiAgICAgICAgICBlbGVtZW50LmlkID09PSB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQuaWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBkb24ndCByZW5kZXIgdGV4dCBlbGVtZW50IHRoYXQncyBiZWluZyBjdXJyZW50bHkgZWRpdGVkIChpdCdzXG4gICAgICAvLyByZW5kZXJlZCBvbiByZW1vdGUgb25seSlcbiAgICAgIHJldHVybiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQudHlwZSAhPT0gXCJ0ZXh0XCIgfHxcbiAgICAgICAgZWxlbWVudC5pZCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC5pZFxuICAgICAgKTtcbiAgICB9KTtcbiAgICBjb25zdCB7IGF0TGVhc3RPbmVWaXNpYmxlRWxlbWVudCwgc2Nyb2xsQmFycyB9ID0gcmVuZGVyU2NlbmUoXG4gICAgICByZW5kZXJpbmdFbGVtZW50cyxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICB0aGlzLnN0YXRlLnNlbGVjdGlvbkVsZW1lbnQsXG4gICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgIHRoaXMucmMhLFxuICAgICAgdGhpcy5jYW52YXMhLFxuICAgICAge1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFgsXG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSxcbiAgICAgICAgdmlld0JhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yLFxuICAgICAgICB6b29tOiB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3JkczogcG9pbnRlclZpZXdwb3J0Q29vcmRzLFxuICAgICAgICByZW1vdGVQb2ludGVyQnV0dG9uOiBjdXJzb3JCdXR0b24sXG4gICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJuYW1lczogcG9pbnRlclVzZXJuYW1lcyxcbiAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJTdGF0ZXM6IHBvaW50ZXJVc2VyU3RhdGVzLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRoaXMuc3RhdGUuc2hvdWxkQ2FjaGVJZ25vcmVab29tLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgICBpc0V4cG9ydGluZzogZmFsc2UsXG4gICAgICAgIHJlbmRlclNjcm9sbGJhcnM6ICF0aGlzLmlzTW9iaWxlLFxuICAgICAgfSxcbiAgICApO1xuICAgIGlmIChzY3JvbGxCYXJzKSB7XG4gICAgICBjdXJyZW50U2Nyb2xsQmFycyA9IHNjcm9sbEJhcnM7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbGVkT3V0c2lkZSA9XG4gICAgICAvLyBoaWRlIHdoZW4gZWRpdGluZyB0ZXh0XG4gICAgICBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgID8gZmFsc2VcbiAgICAgICAgOiAhYXRMZWFzdE9uZVZpc2libGVFbGVtZW50ICYmIHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCA+IDA7XG4gICAgaWYgKHRoaXMuc3RhdGUuc2Nyb2xsZWRPdXRzaWRlICE9PSBzY3JvbGxlZE91dHNpZGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzY3JvbGxlZE91dHNpZGUgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5oaXN0b3J5LnJlY29yZCh0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKTtcblxuICAgIHRoaXMuc2NoZWR1bGVJbWFnZVJlZnJlc2goKTtcblxuICAgIC8vIERvIG5vdCBub3RpZnkgY29uc3VtZXJzIGlmIHdlJ3JlIHN0aWxsIGxvYWRpbmcgdGhlIHNjZW5lLiBBbW9uZyBvdGhlclxuICAgIC8vIHBvdGVudGlhbCBpc3N1ZXMsIHRoaXMgZml4ZXMgYSBjYXNlIHdoZXJlIHRoZSB0YWIgaXNuJ3QgZm9jdXNlZCBkdXJpbmdcbiAgICAvLyBpbml0LCB3aGljaCB3b3VsZCB0cmlnZ2VyIG9uQ2hhbmdlIHdpdGggZW1wdHkgZWxlbWVudHMsIHdoaWNoIHdvdWxkIHRoZW5cbiAgICAvLyBvdmVycmlkZSB3aGF0ZXZlciBpcyBpbiBsb2NhbFN0b3JhZ2UgY3VycmVudGx5LlxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMucHJvcHMub25DaGFuZ2U/LihcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5maWxlcyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblNjcm9sbCA9IGRlYm91bmNlKCgpID0+IHtcbiAgICBjb25zdCB7IG9mZnNldFRvcCwgb2Zmc2V0TGVmdCB9ID0gdGhpcy5nZXRDYW52YXNPZmZzZXRzKCk7XG4gICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+IHtcbiAgICAgIGlmIChzdGF0ZS5vZmZzZXRMZWZ0ID09PSBvZmZzZXRMZWZ0ICYmIHN0YXRlLm9mZnNldFRvcCA9PT0gb2Zmc2V0VG9wKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH07XG4gICAgfSk7XG4gIH0sIFNDUk9MTF9USU1FT1VUKTtcblxuICAvLyBDb3B5L3Bhc3RlXG5cbiAgcHJpdmF0ZSBvbkN1dCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jdXRBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9KTtcblxuICBwcml2YXRlIG9uQ29weSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb3B5QWxsKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBjdXRBbGwgPSAoKSA9PiB7XG4gICAgdGhpcy5jb3B5QWxsKCk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRGVsZXRlU2VsZWN0ZWQpO1xuICB9O1xuXG4gIHByaXZhdGUgY29weUFsbCA9ICgpID0+IHtcbiAgICBjb3B5VG9DbGlwYm9hcmQodGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCB0aGlzLnN0YXRlLCB0aGlzLmZpbGVzKTtcbiAgfTtcblxuICBwcml2YXRlIHN0YXRpYyByZXNldFRhcFR3aWNlKCkge1xuICAgIGRpZFRhcFR3aWNlID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uVGFwU3RhcnQgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICBpZiAoIWRpZFRhcFR3aWNlKSB7XG4gICAgICBkaWRUYXBUd2ljZSA9IHRydWU7XG4gICAgICBjbGVhclRpbWVvdXQodGFwcGVkVHdpY2VUaW1lcik7XG4gICAgICB0YXBwZWRUd2ljZVRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoXG4gICAgICAgIEFwcC5yZXNldFRhcFR3aWNlLFxuICAgICAgICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGluc2VydCB0ZXh0IG9ubHkgaWYgd2UgdGFwcGVkIHR3aWNlIHdpdGggYSBzaW5nbGUgZmluZ2VyXG4gICAgLy8gZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEgd2lsbCBhbHNvIHByZXZlbnQgaW5zZXJ0aW5nIHRleHQgd2hlbiB1c2VyJ3Mgem9vbWluZ1xuICAgIGlmIChkaWRUYXBUd2ljZSAmJiBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgW3RvdWNoXSA9IGV2ZW50LnRvdWNoZXM7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB0aGlzLmhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrKHtcbiAgICAgICAgY2xpZW50WDogdG91Y2guY2xpZW50WCxcbiAgICAgICAgY2xpZW50WTogdG91Y2guY2xpZW50WSxcbiAgICAgIH0pO1xuICAgICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICB9XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25UYXBFbmQgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBwYXN0ZUZyb21DbGlwYm9hcmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgYXN5bmMgKGV2ZW50OiBDbGlwYm9hcmRFdmVudCB8IG51bGwpID0+IHtcbiAgICAgIC8vICM2ODZcbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPVxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnModGFyZ2V0KTtcbiAgICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWxlbWVudFVuZGVyQ3Vyc29yID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChjdXJzb3JYLCBjdXJzb3JZKTtcbiAgICAgIGlmIChcbiAgICAgICAgLy8gaWYgbm8gQ2xpcGJvYXJkRXZlbnQgc3VwcGxpZWQsIGFzc3VtZSB3ZSdyZSBwYXN0aW5nIHZpYSBjb250ZXh0TWVudVxuICAgICAgICAvLyB0aHVzIHRoZXNlIGNoZWNrcyBkb24ndCBtYWtlIHNlbnNlXG4gICAgICAgIGV2ZW50ICYmXG4gICAgICAgICghKGVsZW1lbnRVbmRlckN1cnNvciBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB8fFxuICAgICAgICAgIGlzV3JpdGFibGVFbGVtZW50KHRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBtdXN0IGJlIGNhbGxlZCBpbiB0aGUgc2FtZSBmcmFtZSAodGh1cyBiZWZvcmUgYW55IGF3YWl0cykgYXMgdGhlIHBhc3RlXG4gICAgICAvLyBldmVudCBlbHNlIHNvbWUgYnJvd3NlcnMgKEZGLi4uKSB3aWxsIGNsZWFyIHRoZSBjbGlwYm9hcmREYXRhXG4gICAgICAvLyAoc29tZXRoaW5nIHNvbWV0aGluZyBzZWN1cml0eSlcbiAgICAgIGxldCBmaWxlID0gZXZlbnQ/LmNsaXBib2FyZERhdGE/LmZpbGVzWzBdO1xuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcGFyc2VDbGlwYm9hcmQoZXZlbnQpO1xuXG4gICAgICBpZiAoIWZpbGUgJiYgZGF0YS50ZXh0KSB7XG4gICAgICAgIGNvbnN0IHN0cmluZyA9IGRhdGEudGV4dC50cmltKCk7XG4gICAgICAgIGlmIChzdHJpbmcuc3RhcnRzV2l0aChcIjxzdmdcIikgJiYgc3RyaW5nLmVuZHNXaXRoKFwiPC9zdmc+XCIpKSB7XG4gICAgICAgICAgLy8gaWdub3JlIFNWRyB2YWxpZGF0aW9uL25vcm1hbGl6YXRpb24gd2hpY2ggd2lsbCBiZSBkb25lIGR1cmluZyBpbWFnZVxuICAgICAgICAgIC8vIGluaXRpYWxpemF0aW9uXG4gICAgICAgICAgZmlsZSA9IFNWR1N0cmluZ1RvRmlsZShzdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucHJvcHMub25QYXN0ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICgoYXdhaXQgdGhpcy5wcm9wcy5vblBhc3RlKGRhdGEsIGV2ZW50KSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkYXRhLmVycm9yTWVzc2FnZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBkYXRhLmVycm9yTWVzc2FnZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5zcHJlYWRzaGVldCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBwYXN0ZURpYWxvZzoge1xuICAgICAgICAgICAgZGF0YTogZGF0YS5zcHJlYWRzaGVldCxcbiAgICAgICAgICAgIHNob3duOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkYXRhLmVsZW1lbnRzLFxuICAgICAgICAgIGZpbGVzOiBkYXRhLmZpbGVzIHx8IG51bGwsXG4gICAgICAgICAgcG9zaXRpb246IFwiY3Vyc29yXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnRleHQpIHtcbiAgICAgICAgdGhpcy5hZGRUZXh0RnJvbVBhc3RlKGRhdGEudGV4dCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNlbGVjdFNoYXBlVG9vbChcInNlbGVjdGlvblwiKTtcbiAgICAgIGV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBhZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSA9IChvcHRzOiB7XG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzIHwgbnVsbDtcbiAgICBwb3NpdGlvbjogeyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9IHwgXCJjdXJzb3JcIiB8IFwiY2VudGVyXCI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHJlc3RvcmVFbGVtZW50cyhvcHRzLmVsZW1lbnRzLCBudWxsKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoZWxlbWVudHMpO1xuXG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJYID0gZGlzdGFuY2UobWluWCwgbWF4WCkgLyAyO1xuICAgIGNvbnN0IGVsZW1lbnRzQ2VudGVyWSA9IGRpc3RhbmNlKG1pblksIG1heFkpIC8gMjtcblxuICAgIGNvbnN0IGNsaWVudFggPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFhcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWFxuICAgICAgICA6IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgIGNvbnN0IGNsaWVudFkgPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFlcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWVxuICAgICAgICA6IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGR4ID0geCAtIGVsZW1lbnRzQ2VudGVyWDtcbiAgICBjb25zdCBkeSA9IHkgLSBlbGVtZW50c0NlbnRlclk7XG4gICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcblxuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KGR4LCBkeSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBvbGRJZFRvRHVwbGljYXRlZElkID0gbmV3IE1hcCgpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnRzID0gZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBuZXdFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCxcbiAgICAgICAgZ3JvdXBJZE1hcCxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgICAge1xuICAgICAgICAgIHg6IGVsZW1lbnQueCArIGdyaWRYIC0gbWluWCxcbiAgICAgICAgICB5OiBlbGVtZW50LnkgKyBncmlkWSAtIG1pblksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZC5zZXQoZWxlbWVudC5pZCwgbmV3RWxlbWVudC5pZCk7XG4gICAgICByZXR1cm4gbmV3RWxlbWVudDtcbiAgICB9KTtcbiAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKG5ld0VsZW1lbnRzLCBlbGVtZW50cywgb2xkSWRUb0R1cGxpY2F0ZWRJZCk7XG4gICAgY29uc3QgbmV4dEVsZW1lbnRzID0gW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIC4uLm5ld0VsZW1lbnRzLFxuICAgIF07XG4gICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKG5leHRFbGVtZW50cywgZWxlbWVudHMsIG9sZElkVG9EdXBsaWNhdGVkSWQpO1xuXG4gICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLm9wdHMuZmlsZXMgfTtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhuZXh0RWxlbWVudHMpO1xuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAge1xuICAgICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgICAgaXNMaWJyYXJ5T3BlbjogZmFsc2UsXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBuZXdFbGVtZW50cy5yZWR1Y2UoKG1hcCwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgIWVsZW1lbnQuY29udGFpbmVySWQpIHtcbiAgICAgICAgICAgICAgbWFwW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtYXA7XG4gICAgICAgICAgfSwge30gYXMgYW55KSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgKSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5zZWxlY3RTaGFwZVRvb2woXCJzZWxlY3Rpb25cIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBhZGRUZXh0RnJvbVBhc3RlKHRleHQ6IGFueSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHRleHQsXG4gICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB0ZXh0QWxpZ246IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIGVsZW1lbnQsXG4gICAgXSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbZWxlbWVudC5pZF06IHRydWUgfSB9KTtcbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gIH1cblxuICAvLyBDb2xsYWJvcmF0aW9uXG5cbiAgc2V0QXBwU3RhdGUgPSAob2JqOiBhbnkpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKG9iaik7XG4gIH07XG5cbiAgcmVtb3ZlUG9pbnRlciA9IChldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxFbGVtZW50PiB8IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgIC8vIHJlbW92ZSB0b3VjaCBoYW5kbGVyIGZvciBjb250ZXh0IG1lbnUgb24gdG91Y2ggZGV2aWNlc1xuICAgIGlmIChldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiICYmIHRvdWNoVGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2VzdHVyZS5wb2ludGVycy5kZWxldGUoZXZlbnQucG9pbnRlcklkKTtcbiAgfTtcblxuICB0b2dnbGVMb2NrID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWxlbWVudExvY2tlZDogIXByZXZTdGF0ZS5lbGVtZW50TG9ja2VkLFxuICAgICAgICBlbGVtZW50VHlwZTogcHJldlN0YXRlLmVsZW1lbnRMb2NrZWRcbiAgICAgICAgICA/IFwic2VsZWN0aW9uXCJcbiAgICAgICAgICA6IHByZXZTdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH07XG5cbiAgdG9nZ2xlWmVuTW9kZSA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25Ub2dnbGVaZW5Nb2RlKTtcbiAgfTtcblxuICB0b2dnbGVTdGF0cyA9ICgpID0+IHtcbiAgICBpZiAoIXRoaXMuc3RhdGUuc2hvd1N0YXRzKSB7XG4gICAgICB0cmFja0V2ZW50KFwiZGlhbG9nXCIsIFwic3RhdHNcIik7XG4gICAgfVxuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvblRvZ2dsZVN0YXRzKTtcbiAgfTtcblxuICBzY3JvbGxUb0NvbnRlbnQgPSAoXG4gICAgdGFyZ2V0OlxuICAgICAgfCBFeGNhbGlkcmF3RWxlbWVudFxuICAgICAgfCByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC4uLmNhbGN1bGF0ZVNjcm9sbENlbnRlcihcbiAgICAgICAgQXJyYXkuaXNBcnJheSh0YXJnZXQpID8gdGFyZ2V0IDogW3RhcmdldF0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgKSxcbiAgICB9KTtcbiAgfTtcblxuICBjbGVhclRvYXN0ID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyB0b2FzdE1lc3NhZ2U6IG51bGwgfSk7XG4gIH07XG5cbiAgc2V0VG9hc3RNZXNzYWdlID0gKHRvYXN0TWVzc2FnZTogc3RyaW5nKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHRvYXN0TWVzc2FnZSB9KTtcbiAgfTtcblxuICByZXN0b3JlRmlsZUZyb21TaGFyZSA9IGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgd2ViU2hhcmVUYXJnZXRDYWNoZSA9IGF3YWl0IGNhY2hlcy5vcGVuKFwid2ViLXNoYXJlLXRhcmdldFwiKTtcblxuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUubWF0Y2goXCJzaGFyZWQtZmlsZVwiKTtcbiAgICAgIGlmIChmaWxlKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBhd2FpdCBmaWxlLmJsb2IoKTtcbiAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGJsb2IpO1xuICAgICAgICBhd2FpdCB3ZWJTaGFyZVRhcmdldENhY2hlLmRlbGV0ZShcInNoYXJlZC1maWxlXCIpO1xuICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgQVBQX05BTUUsIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIGFkZHMgc3VwcGxpZWQgZmlsZXMgdG8gZXhpc3RpbmcgZmlsZXMgaW4gdGhlIGFwcFN0YXRlICovXG4gIHB1YmxpYyBhZGRGaWxlczogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUElbXCJhZGRGaWxlc1wiXSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZmlsZXMpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVzTWFwID0gZmlsZXMucmVkdWNlKChhY2MsIGZpbGVEYXRhKSA9PiB7XG4gICAgICAgIGFjYy5zZXQoZmlsZURhdGEuaWQsIGZpbGVEYXRhKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIG5ldyBNYXA8RmlsZUlkLCBCaW5hcnlGaWxlRGF0YT4oKSk7XG5cbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLk9iamVjdC5mcm9tRW50cmllcyhmaWxlc01hcCkgfTtcblxuICAgICAgLy8gYnVtcCB2ZXJzaW9ucyBmb3IgZWxlbWVudHMgdGhhdCByZWZlcmVuY2UgYWRkZWQgZmlsZXMgc28gdGhhdFxuICAgICAgLy8gd2UvaG9zdCBhcHBzIGNhbiBkZXRlY3QgdGhlIGNoYW5nZSwgYW5kIGludmFsaWRhdGUgdGhlIGltYWdlICYgc2hhcGVcbiAgICAgIC8vIGNhY2hlXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgIGZpbGVzTWFwLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmRlbGV0ZShlbGVtZW50LmZpbGVJZCk7XG4gICAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICBidW1wVmVyc2lvbihlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG5cbiAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgfSxcbiAgKTtcblxuICBwdWJsaWMgdXBkYXRlU2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgPEsgZXh0ZW5kcyBrZXlvZiBBcHBTdGF0ZT4oc2NlbmVEYXRhOiB7XG4gICAgICBlbGVtZW50cz86IFNjZW5lRGF0YVtcImVsZW1lbnRzXCJdO1xuICAgICAgYXBwU3RhdGU/OiBQaWNrPEFwcFN0YXRlLCBLPiB8IG51bGw7XG4gICAgICBjb2xsYWJvcmF0b3JzPzogU2NlbmVEYXRhW1wiY29sbGFib3JhdG9yc1wiXTtcbiAgICAgIGNvbW1pdFRvSGlzdG9yeT86IFNjZW5lRGF0YVtcImNvbW1pdFRvSGlzdG9yeVwiXTtcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoc2NlbmVEYXRhLmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuYXBwU3RhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShzY2VuZURhdGEuYXBwU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NlbmVEYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKHNjZW5lRGF0YS5lbGVtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuY29sbGFib3JhdG9ycykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29sbGFib3JhdG9yczogc2NlbmVEYXRhLmNvbGxhYm9yYXRvcnMgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uU2NlbmVVcGRhdGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgY3Vyc29yWCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBjdXJzb3JZID0gZXZlbnQuY2xpZW50WTtcbiAgICB9LFxuICApO1xuXG4gIC8vIElucHV0IGhhbmRsaW5nXG5cbiAgcHJpdmF0ZSBvbktleURvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBSZWFjdC5LZXlib2FyZEV2ZW50IHwgS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gbm9ybWFsaXplIGBldmVudC5rZXlgIHdoZW4gQ2Fwc0xvY2sgaXMgcHJlc3NlZCAjMjM3MlxuICAgICAgaWYgKFxuICAgICAgICBcIlByb3h5XCIgaW4gd2luZG93ICYmXG4gICAgICAgICgoIWV2ZW50LnNoaWZ0S2V5ICYmIC9eW0EtWl0kLy50ZXN0KGV2ZW50LmtleSkpIHx8XG4gICAgICAgICAgKGV2ZW50LnNoaWZ0S2V5ICYmIC9eW2Etel0kLy50ZXN0KGV2ZW50LmtleSkpKVxuICAgICAgKSB7XG4gICAgICAgIGV2ZW50ID0gbmV3IFByb3h5KGV2ZW50LCB7XG4gICAgICAgICAgZ2V0KGV2OiBhbnksIHByb3ApIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXZbcHJvcF07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgLy8gZml4IGZvciBQcm94aWVzIGhpamFja2luZyBgdGhpc2BcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmJpbmQoZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb3AgPT09IFwia2V5XCJcbiAgICAgICAgICAgICAgPyAvLyBDYXBzTG9jayBpbnZlcnRzIGNhcGl0YWxpemF0aW9uIGJhc2VkIG9uIFNoaWZ0S2V5LCBzbyBpbnZlcnRcbiAgICAgICAgICAgICAgICAvLyBpdCBiYWNrXG4gICAgICAgICAgICAgICAgZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgICA/IGV2LmtleS50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICAgICAgOiBldi5rZXkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICA6IHZhbHVlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIChpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpICYmIGV2ZW50LmtleSAhPT0gS0VZUy5FU0NBUEUpIHx8XG4gICAgICAgIC8vIGNhc2U6IHVzaW5nIGFycm93cyB0byBtb3ZlIGJldHdlZW4gYnV0dG9uc1xuICAgICAgICAoaXNBcnJvd0tleShldmVudC5rZXkpICYmIGlzSW5wdXRMaWtlKGV2ZW50LnRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlFVRVNUSU9OX01BUkspIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2hvd0hlbHBEaWFsb2c6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hY3Rpb25NYW5hZ2VyLmhhbmRsZUtleURvd24oZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmIHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5jb2RlID09PSBDT0RFUy5aRVJPKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiAhdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAgICh0aGlzLnN0YXRlLmdyaWRTaXplICYmXG4gICAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgPyBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmdyaWRTaXplKSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgID8gRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5UXG4gICAgICAgICAgICA6IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IHRoaXMuc2NlbmVcbiAgICAgICAgICAuZ2V0RWxlbWVudHMoKVxuICAgICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2VsZW1lbnQuaWRdKTtcblxuICAgICAgICBsZXQgb2Zmc2V0WCA9IDA7XG4gICAgICAgIGxldCBvZmZzZXRZID0gMDtcblxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0xFRlQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1JJR0hUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IHN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1VQKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19ET1dOKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IHN0ZXA7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHg6IGVsZW1lbnQueCArIG9mZnNldFgsXG4gICAgICAgICAgICB5OiBlbGVtZW50LnkgKyBvZmZzZXRZLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdXBkYXRlQm91bmRFbGVtZW50cyhlbGVtZW50LCB7XG4gICAgICAgICAgICBzaW11bHRhbmVvdXNseVVwZGF0ZWQ6IHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuRU5URVIpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT0gc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAhaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG5cbiAgICAgICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICAgICAgc2NlbmVYOiBzZWxlY3RlZEVsZW1lbnQueCArIHNlbGVjdGVkRWxlbWVudC53aWR0aCAvIDIsXG4gICAgICAgICAgICBzY2VuZVk6IHNlbGVjdGVkRWxlbWVudC55ICsgc2VsZWN0ZWRFbGVtZW50LmhlaWdodCAvIDIsXG4gICAgICAgICAgICBzaG91bGRCaW5kOiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAhZXZlbnQuY3RybEtleSAmJlxuICAgICAgICAhZXZlbnQuYWx0S2V5ICYmXG4gICAgICAgICFldmVudC5tZXRhS2V5ICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50ID09PSBudWxsXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBmaW5kU2hhcGVCeUtleShldmVudC5rZXkpO1xuICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdFNoYXBlVG9vbChzaGFwZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlEpIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZUxvY2soKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSAmJiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDApIHtcbiAgICAgICAgaXNIb2xkaW5nU3BhY2UgPSB0cnVlO1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5HIHx8IGV2ZW50LmtleSA9PT0gS0VZUy5TKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICAgICFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkcgJiZcbiAgICAgICAgICAoaGFzQmFja2dyb3VuZCh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKSB8fFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PiBoYXNCYWNrZ3JvdW5kKGVsZW1lbnQudHlwZSkpKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgb3BlblBvcHVwOiBcImJhY2tncm91bmRDb2xvclBpY2tlclwiIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUykge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwic3Ryb2tlQ29sb3JQaWNrZXJcIiB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBvbktleVVwID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuU1BBQ0UpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmICF0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgIH1cbiAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpXG4gICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBzZWxlY3RTaGFwZVRvb2woZWxlbWVudFR5cGU6IEFwcFN0YXRlW1wiZWxlbWVudFR5cGVcIl0pIHtcbiAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgZWxlbWVudFR5cGUpO1xuICAgIH1cbiAgICBpZiAoaXNUb29sSWNvbihkb2N1bWVudC5hY3RpdmVFbGVtZW50KSkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cbiAgICBpZiAoIWlzTGluZWFyRWxlbWVudFR5cGUoZWxlbWVudFR5cGUpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgICBpZiAoZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgdGhpcy5vbkltYWdlQWN0aW9uKCk7XG4gICAgfVxuICAgIGlmIChlbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVsZW1lbnRUeXBlLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVsZW1lbnRUeXBlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25HZXN0dXJlU3RhcnQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICB9KTtcbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBvbkdlc3R1cmVDaGFuZ2UgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gb25HZXN0dXJlQ2hhbmdlIG9ubHkgaGFzIHpvb20gZmFjdG9yIGJ1dCBub3QgdGhlIGNlbnRlci5cbiAgICAvLyBJZiB3ZSdyZSBvbiBpUGFkIG9yIGlQaG9uZSwgdGhlbiB3ZSByZWNvZ25pemUgbXVsdGktdG91Y2ggYW5kIHdpbGxcbiAgICAvLyB6b29tIGluIGF0IHRoZSByaWdodCBsb2NhdGlvbiBvbiB0aGUgdG91Y2hNb3ZlIGhhbmRsZXIgYWxyZWFkeS5cbiAgICAvLyBPbiBNYWNib29rLCB3ZSBkb24ndCBoYXZlIHRob3NlIGV2ZW50cyBzbyB3aWxsIHpvb20gaW4gYXQgdGhlXG4gICAgLy8gY3VycmVudCBsb2NhdGlvbiBpbnN0ZWFkLlxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoaW5pdGlhbFNjYWxlKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIG9mZnNldExlZnQsIG9mZnNldFRvcCB9KSA9PiAoe1xuICAgICAgICB6b29tOiBnZXROZXdab29tKFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIGV2ZW50LnNjYWxlKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIHsgbGVmdDogb2Zmc2V0TGVmdCwgdG9wOiBvZmZzZXRUb3AgfSxcbiAgICAgICAgICB7IHg6IGN1cnNvclgsIHk6IGN1cnNvclkgfSxcbiAgICAgICAgKSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgb25HZXN0dXJlRW5kID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5wcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICB9KTtcbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IG51bGw7XG4gIH0pO1xuXG4gIHByaXZhdGUgaGFuZGxlVGV4dFd5c2l3eWcoXG4gICAgZWxlbWVudDogRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICAgIHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50ID0gZmFsc2UsXG4gICAgfToge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZUVsZW1lbnQgPSAoXG4gICAgICB0ZXh0OiBzdHJpbmcsXG4gICAgICBvcmlnaW5hbFRleHQ6IHN0cmluZyxcbiAgICAgIGlzRGVsZXRlZCA9IGZhbHNlLFxuICAgICAgdXBkYXRlRGltZW5zaW9ucyA9IGZhbHNlLFxuICAgICkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoX2VsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoX2VsZW1lbnQuaWQgPT09IGVsZW1lbnQuaWQgJiYgaXNUZXh0RWxlbWVudChfZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVUZXh0RWxlbWVudChcbiAgICAgICAgICAgICAgX2VsZW1lbnQsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgIGlzRGVsZXRlZCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbFRleHQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHVwZGF0ZURpbWVuc2lvbnMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX2VsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgfTtcblxuICAgIHRleHRXeXNpd3lnKHtcbiAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICBjYW52YXM6IHRoaXMuY2FudmFzLFxuICAgICAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4LCB5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgICAgICBzY2VuZVk6IHksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHZpZXdwb3J0WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCwgLy8qICgyIC0gdGhpcy5zdGF0ZS56b29tLnZhbHVlKSxcbiAgICAgICAgICB2aWV3cG9ydFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCwgLy8qICgyIC0gdGhpcy5zdGF0ZS56b29tLnZhbHVlKSxcbiAgICAgICAgXTtcbiAgICAgIH0sXG4gICAgICBvbkNoYW5nZTogd2l0aEJhdGNoZWRVcGRhdGVzKCh0ZXh0KSA9PiB7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgdGV4dCwgZmFsc2UsICFlbGVtZW50LmNvbnRhaW5lcklkKTtcbiAgICAgICAgaWYgKGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICAgIG9uU3VibWl0OiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKHsgdGV4dCwgdmlhS2V5Ym9hcmQsIG9yaWdpbmFsVGV4dCB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGlzRGVsZXRlZCA9ICF0ZXh0LnRyaW0oKTtcbiAgICAgICAgdXBkYXRlRWxlbWVudCh0ZXh0LCBvcmlnaW5hbFRleHQsIGlzRGVsZXRlZCwgdHJ1ZSk7XG4gICAgICAgIC8vIHNlbGVjdCB0aGUgY3JlYXRlZCB0ZXh0IGVsZW1lbnQgb25seSBpZiBzdWJtaXR0aW5nIHZpYSBrZXlib2FyZFxuICAgICAgICAvLyAod2hlbiBzdWJtaXR0aW5nIHZpYSBjbGljayBpdCBzaG91bGQgYWN0IGFzIHNpZ25hbCB0byBkZXNlbGVjdClcbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgJiYgdmlhS2V5Ym9hcmQpIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50SWRUb1NlbGVjdCA9IGVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgICAgID8gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgOiBlbGVtZW50LmlkO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICBbZWxlbWVudElkVG9TZWxlY3RdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVsZXRlZCkge1xuICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbih0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIFtlbGVtZW50XSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgfHwgaXNFeGlzdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50TG9ja2VkKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgICAgfSksXG4gICAgICBlbGVtZW50LFxuICAgICAgZXhjYWxpZHJhd0NvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQsXG4gICAgfSk7XG4gICAgLy8gZGVzZWxlY3QgYWxsIG90aGVyIGVsZW1lbnRzIHdoZW4gaW5zZXJ0aW5nIHRleHRcbiAgICB0aGlzLmRlc2VsZWN0RWxlbWVudHMoKTtcblxuICAgIC8vIGRvIGFuIGluaXRpYWwgdXBkYXRlIHRvIHJlLWluaXRpYWxpemUgZWxlbWVudCBwb3NpdGlvbiBzaW5jZSB3ZSB3ZXJlXG4gICAgLy8gbW9kaWZ5aW5nIGVsZW1lbnQncyB4L3kgZm9yIHNha2Ugb2YgZWRpdG9yIChjYXNlOiBzeW5jaW5nIHRvIHJlbW90ZSlcbiAgICB1cGRhdGVFbGVtZW50KGVsZW1lbnQudGV4dCwgZWxlbWVudC5vcmlnaW5hbFRleHQpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXNlbGVjdEVsZW1lbnRzKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdUZXh0RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGlmIChlbGVtZW50ICYmIGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgIWVsZW1lbnQuaXNEZWxldGVkKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgb3B0cz86IHtcbiAgICAgIC8qKiBpZiB0cnVlLCByZXR1cm5zIHRoZSBmaXJzdCBzZWxlY3RlZCBlbGVtZW50ICh3aXRoIGhpZ2hlc3Qgei1pbmRleClcbiAgICAgICAgb2YgYWxsIGhpdCBlbGVtZW50cyAqL1xuICAgICAgcHJlZmVyU2VsZWN0ZWQ/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+IHwgbnVsbCB7XG4gICAgY29uc3QgYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgb3B0cz8uaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQsXG4gICAgKTtcbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKG9wdHM/LnByZWZlclNlbGVjdGVkKSB7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMTsgaW5kZXggPiAtMTsgaW5kZXgtLSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1thbGxIaXRFbGVtZW50c1tpbmRleF0uaWRdKSB7XG4gICAgICAgICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbaW5kZXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4ID1cbiAgICAgICAgYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMV07XG4gICAgICAvLyBJZiB3ZSdyZSBoaXR0aW5nIGVsZW1lbnQgd2l0aCBoaWdoZXN0IHotaW5kZXggb25seSBvbiBpdHMgYm91bmRpbmcgYm94XG4gICAgICAvLyB3aGlsZSBhbHNvIGhpdHRpbmcgb3RoZXIgZWxlbWVudCBmaWd1cmUsIHRoZSBsYXR0ZXIgc2hvdWxkIGJlIGNvbnNpZGVyZWQuXG4gICAgICByZXR1cm4gaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXgsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICApXG4gICAgICAgID8gYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMl1cbiAgICAgICAgOiBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXg7XG4gICAgfVxuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1swXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiBib29sZWFuID0gZmFsc2UsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnRcbiAgICAgID8gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpXG4gICAgICA6IHRoaXMuc2NlbmVcbiAgICAgICAgICAuZ2V0RWxlbWVudHMoKVxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAoZWxlbWVudCkgPT4gIShpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmIGVsZW1lbnQuY29udGFpbmVySWQpLFxuICAgICAgICAgICk7XG4gICAgcmV0dXJuIGdldEVsZW1lbnRzQXRQb3NpdGlvbihlbGVtZW50cywgKGVsZW1lbnQpID0+XG4gICAgICBoaXRUZXN0KGVsZW1lbnQsIHRoaXMuc3RhdGUsIHgsIHkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0VGV4dEVkaXRpbmcgPSAoe1xuICAgIHNjZW5lWCxcbiAgICBzY2VuZVksXG4gICAgc2hvdWxkQmluZCxcbiAgICBpbnNlcnRBdFBhcmVudENlbnRlciA9IHRydWUsXG4gIH06IHtcbiAgICAvKiogWCBwb3NpdGlvbiB0byBpbnNlcnQgdGV4dCBhdCAqL1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIC8qKiBZIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVZOiBudW1iZXI7XG4gICAgc2hvdWxkQmluZDogYm9vbGVhbjtcbiAgICAvKiogd2hldGhlciB0byBhdHRlbXB0IHRvIGluc2VydCBhdCBlbGVtZW50IGNlbnRlciBpZiBhcHBsaWNhYmxlICovXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgbGV0IHBhcmVudENlbnRlclBvc2l0aW9uID1cbiAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyICYmXG4gICAgICB0aGlzLmdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICApO1xuXG4gICAgLy8gYmluZCB0byBjb250YWluZXIgd2hlbiBzaG91bGRCaW5kIGlzIHRydWUgb3JcbiAgICAvLyBjbGlja2VkIG9uIGNlbnRlciBvZiBjb250YWluZXJcbiAgICBjb25zdCBjb250YWluZXIgPVxuICAgICAgc2hvdWxkQmluZCB8fCBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICA/IGdldEVsZW1lbnRDb250YWluaW5nUG9zaXRpb24oXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICBzY2VuZVgsXG4gICAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgICBcInRleHRcIixcbiAgICAgICAgICApXG4gICAgICAgIDogbnVsbDtcblxuICAgIGxldCBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5nZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuXG4gICAgLy8gY29uc2lkZXIgYm91bmRlZCB0ZXh0IGVsZW1lbnQgaWYgY29udGFpbmVyIHByZXNlbnRcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBjb25zdCBib3VuZFRleHRFbGVtZW50SWQgPSBnZXRCb3VuZFRleHRFbGVtZW50SWQoY29udGFpbmVyKTtcbiAgICAgIGlmIChib3VuZFRleHRFbGVtZW50SWQpIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudChcbiAgICAgICAgICBib3VuZFRleHRFbGVtZW50SWQsXG4gICAgICAgICkgYXMgRXhjYWxpZHJhd1RleHRFbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWV4aXN0aW5nVGV4dEVsZW1lbnQgJiYgY29udGFpbmVyKSB7XG4gICAgICBjb25zdCBmb250U3RyaW5nID0ge1xuICAgICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIH07XG4gICAgICBjb25zdCBtaW5XaWR0aCA9IGdldEFwcHJveE1pbkxpbmVXaWR0aChnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpKTtcbiAgICAgIGNvbnN0IG1pbkhlaWdodCA9IGdldEFwcHJveE1pbkxpbmVIZWlnaHQoZ2V0Rm9udFN0cmluZyhmb250U3RyaW5nKSk7XG4gICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1heChjb250YWluZXIuaGVpZ2h0LCBtaW5IZWlnaHQpO1xuICAgICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLm1heChjb250YWluZXIud2lkdGgsIG1pbldpZHRoKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7IGhlaWdodDogbmV3SGVpZ2h0LCB3aWR0aDogbmV3V2lkdGggfSk7XG4gICAgICBzY2VuZVggPSBjb250YWluZXIueCArIG5ld1dpZHRoIC8gMjtcbiAgICAgIHNjZW5lWSA9IGNvbnRhaW5lci55ICsgbmV3SGVpZ2h0IC8gMjtcbiAgICAgIGlmIChwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgICBwYXJlbnRDZW50ZXJQb3NpdGlvbiA9IHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgICBzY2VuZVgsXG4gICAgICAgICAgc2NlbmVZLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudCA9IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgID8gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgOiBuZXdUZXh0RWxlbWVudCh7XG4gICAgICAgICAgeDogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlclhcbiAgICAgICAgICAgIDogc2NlbmVYLFxuICAgICAgICAgIHk6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJZXG4gICAgICAgICAgICA6IHNjZW5lWSxcbiAgICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgICAgICAgdGV4dDogXCJcIixcbiAgICAgICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgICAgIHRleHRBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gXCJjZW50ZXJcIlxuICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtVGV4dEFsaWduLFxuICAgICAgICAgIHZlcnRpY2FsQWxpZ246IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IFwibWlkZGxlXCJcbiAgICAgICAgICAgIDogREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgICAgICAgICBjb250YWluZXJJZDogY29udGFpbmVyPy5pZCA/PyB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdFbGVtZW50OiBlbGVtZW50IH0pO1xuXG4gICAgaWYgKGV4aXN0aW5nVGV4dEVsZW1lbnQpIHtcbiAgICAgIC8vIGlmIHRleHQgZWxlbWVudCBpcyBubyBsb25nZXIgY2VudGVyZWQgdG8gYSBjb250YWluZXIsIHJlc2V0XG4gICAgICAvLyB2ZXJ0aWNhbEFsaWduIHRvIGRlZmF1bHQgYmVjYXVzZSBpdCdzIGN1cnJlbnRseSBpbnRlcm5hbC1vbmx5XG4gICAgICBpZiAoIXBhcmVudENlbnRlclBvc2l0aW9uIHx8IGVsZW1lbnQudGV4dEFsaWduICE9PSBcImNlbnRlclwiKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwgeyB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcblxuICAgICAgLy8gY2FzZTogY3JlYXRpbmcgbmV3IHRleHQgbm90IGNlbnRlcmVkIHRvIHBhcmVudCBlbGVtZW5lbnQg4oaSIG9mZnNldCBZXG4gICAgICAvLyBzbyB0aGF0IHRoZSB0ZXh0IGlzIGNlbnRlcmVkIHRvIGN1cnNvciBwb3NpdGlvblxuICAgICAgaWYgKCFwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICB5OiBlbGVtZW50LnkgLSBlbGVtZW50LmJhc2VsaW5lIC8gMixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlVGV4dFd5c2l3eWcoZWxlbWVudCwge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ6ICEhZXhpc3RpbmdUZXh0RWxlbWVudCxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Nb3VzZUV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gY2FzZTogZG91YmxlLWNsaWNraW5nIHdpdGggYXJyb3cvbGluZSB0b29sIHNlbGVjdGVkIHdvdWxkIGJvdGggY3JlYXRlXG4gICAgLy8gdGV4dCBhbmQgZW50ZXIgbXVsdGlFbGVtZW50IG1vZGVcbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gd2Ugc2hvdWxkIG9ubHkgYmUgYWJsZSB0byBkb3VibGUgY2xpY2sgd2hlbiBtb2RlIGlzIHNlbGVjdGlvblxuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICApLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG5cbiAgICBsZXQgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgZXZlbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWRzID0gZ2V0U2VsZWN0ZWRHcm91cElkcyh0aGlzLnN0YXRlKTtcblxuICAgIGlmIChzZWxlY3RlZEdyb3VwSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcblxuICAgICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkID1cbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50KGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cElkcyk7XG5cbiAgICAgIGlmIChzZWxlY3RlZEdyb3VwSWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IHNlbGVjdGVkR3JvdXBJZCxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50IS5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiAhdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG4gICAgICAgIGNvbnN0IGNhbkJpbmRUZXh0ID0gaGFzQm91bmRUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnQpO1xuICAgICAgICBpZiAoY2FuQmluZFRleHQpIHtcbiAgICAgICAgICBzY2VuZVggPSBzZWxlY3RlZEVsZW1lbnQueCArIHNlbGVjdGVkRWxlbWVudC53aWR0aCAvIDI7XG4gICAgICAgICAgc2NlbmVZID0gc2VsZWN0ZWRFbGVtZW50LnkgKyBzZWxlY3RlZEVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHNob3VsZEJpbmQ6IGZhbHNlLFxuICAgICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIHRoaXMuc3RhdGUuY3Vyc29yQnV0dG9uKTtcblxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLmhhcyhldmVudC5wb2ludGVySWQpKSB7XG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMiAmJlxuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyICYmXG4gICAgICBpbml0aWFsU2NhbGUgJiZcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlXG4gICAgKSB7XG4gICAgICBjb25zdCBjZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBjb25zdCBkZWx0YVggPSBjZW50ZXIueCAtIGdlc3R1cmUubGFzdENlbnRlci54O1xuICAgICAgY29uc3QgZGVsdGFZID0gY2VudGVyLnkgLSBnZXN0dXJlLmxhc3RDZW50ZXIueTtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGNlbnRlcjtcblxuICAgICAgY29uc3QgZGlzdGFuY2UgPSBnZXREaXN0YW5jZShBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpKTtcbiAgICAgIGNvbnN0IHNjYWxlRmFjdG9yID0gZGlzdGFuY2UgLyBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZLCBvZmZzZXRMZWZ0LCBvZmZzZXRUb3AgfSkgPT4gKHtcbiAgICAgICAgc2Nyb2xsWDogc2Nyb2xsWCArIGRlbHRhWCAvIHpvb20udmFsdWUsXG4gICAgICAgIHNjcm9sbFk6IHNjcm9sbFkgKyBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgICAgICB6b29tOiBnZXROZXdab29tKFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIHNjYWxlRmFjdG9yKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIHsgbGVmdDogb2Zmc2V0TGVmdCwgdG9wOiBvZmZzZXRUb3AgfSxcbiAgICAgICAgICBjZW50ZXIsXG4gICAgICAgICksXG4gICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdHJ1ZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9XG4gICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoaXNIb2xkaW5nU3BhY2UgfHwgaXNQYW5uaW5nIHx8IGlzRHJhZ2dpbmdTY3JvbGxCYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycyA9IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgKTtcbiAgICBjb25zdCBpc092ZXJTY3JvbGxCYXIgPSBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycy5pc092ZXJFaXRoZXI7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3QgeyB4OiBzY2VuZVBvaW50ZXJYLCB5OiBzY2VuZVBvaW50ZXJZIH0gPSBzY2VuZVBvaW50ZXI7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5pc0RyYWdnaW5nXG4gICAgKSB7XG4gICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlck1vdmUoXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0xpbmVhckVsZW1lbnQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQubGFzdFVuY29tbWl0dGVkUG9pbnQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNCaW5kaW5nRWxlbWVudFR5cGUodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSkpIHtcbiAgICAgIC8vIEhvdmVyaW5nIHdpdGggYSBzZWxlY3RlZCB0b29sIG9yIGNyZWF0aW5nIG5ldyBsaW5lYXIgZWxlbWVudCB2aWEgY2xpY2tcbiAgICAgIC8vIGFuZCBwb2ludFxuICAgICAgY29uc3QgeyBkcmFnZ2luZ0VsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXJdLFxuICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICBjb25zdCB7IHBvaW50cywgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG4gICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuXG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG5cbiAgICAgIGlmIChsYXN0UG9pbnQgPT09IGxhc3RDb21taXR0ZWRQb2ludCkge1xuICAgICAgICAvLyBpZiB3ZSBoYXZlbid0IHlldCBjcmVhdGVkIGEgdGVtcCBwb2ludCBhbmQgd2UncmUgYmV5b25kIGNvbW1pdC16b25lXG4gICAgICAgIC8vIHRocmVzaG9sZCwgYWRkIGEgcG9pbnRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgICBsYXN0UG9pbnRbMF0sXG4gICAgICAgICAgICBsYXN0UG9pbnRbMV0sXG4gICAgICAgICAgKSA+PSBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtzY2VuZVBvaW50ZXJYIC0gcngsIHNjZW5lUG9pbnRlclkgLSByeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgICAgLy8gaW4gdGhpcyBicmFuY2gsIHdlJ3JlIGluc2lkZSB0aGUgY29tbWl0IHpvbmUsIGFuZCBubyB1bmNvbW1pdHRlZFxuICAgICAgICAgIC8vIHBvaW50IGV4aXN0cy4gVGh1cyBkbyBub3RoaW5nIChkb24ndCBhZGQvcmVtb3ZlIHBvaW50cykuXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHBvaW50cy5sZW5ndGggPiAyICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogcG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNQYXRoQUxvb3AocG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB1cGRhdGUgbGFzdCB1bmNvbW1pdHRlZCBwb2ludFxuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgICAgIFtzY2VuZVBvaW50ZXJYIC0gcngsIHNjZW5lUG9pbnRlclkgLSByeV0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNEZXNlbGVjdGVkQnV0dG9uID0gQm9vbGVhbihldmVudC5idXR0b25zKTtcbiAgICBpZiAoXG4gICAgICBoYXNEZXNlbGVjdGVkQnV0dG9uIHx8XG4gICAgICAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInRleHRcIilcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICBpZiAoXG4gICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgIWlzT3ZlclNjcm9sbEJhciAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnRcbiAgICApIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgJiZcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGVcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSAmJiAhaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAodHJhbnNmb3JtSGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcbiAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgIHNldEN1cnNvcihcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgIGlzVGV4dEVsZW1lbnQoaGl0RWxlbWVudCkgPyBDVVJTT1JfVFlQRS5URVhUIDogQ1VSU09SX1RZUEUuQ1JPU1NIQUlSLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgIH0gZWxzZSBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50ICYmXG4gICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KGVsZW1lbnQsIHRoaXMuc3RhdGUsIFtcbiAgICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICAgICAgXSlcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgLy8gaWYgdXNpbmcgY21kL2N0cmwsIHdlJ3JlIG5vdCBkcmFnZ2luZ1xuICAgICAgIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmXG4gICAgICAoaGl0RWxlbWVudCB8fFxuICAgICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICApKVxuICAgICkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICB9XG4gIH07XG5cbiAgLy8gc2V0IHRvdWNoIG1vdmluZyBmb3IgbW9iaWxlIGNvbnRleHQgbWVudVxuICBwcml2YXRlIGhhbmRsZVRvdWNoTW92ZSA9IChldmVudDogUmVhY3QuVG91Y2hFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4pID0+IHtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIHJlbW92ZSBhbnkgYWN0aXZlIHNlbGVjdGlvbiB3aGVuIHdlIHN0YXJ0IHRvIGludGVyYWN0IHdpdGggY2FudmFzXG4gICAgLy8gKG1haW5seSwgd2UgY2FyZSBhYm91dCByZW1vdmluZyBzZWxlY3Rpb24gb3V0c2lkZSB0aGUgY29tcG9uZW50IHdoaWNoXG4gICAgLy8gIHdvdWxkIHByZXZlbnQgb3VyIGNvcHkgaGFuZGxpbmcgb3RoZXJ3aXNlKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWxlY3Rpb24/LmFuY2hvck5vZGUpIHtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICB9XG5cbiAgICB0aGlzLm1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzKGV2ZW50KTtcbiAgICB0aGlzLm1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChldmVudCk7XG5cbiAgICBpZiAoaXNQYW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBsYXN0UG9pbnRlckRvd25XaXRoOiBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgIGN1cnNvckJ1dHRvbjogXCJkb3duXCIsXG4gICAgfSk7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcImRvd25cIik7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVDYW52YXNQYW5Vc2luZ1doZWVsT3JTcGFjZURyYWcoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gb25seSBoYW5kbGUgbGVmdCBtb3VzZSBidXR0b24gb3IgdG91Y2hcbiAgICBpZiAoXG4gICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiZcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uVE9VQ0hcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKGV2ZW50KTtcblxuICAgIC8vIGRvbid0IHNlbGVjdCB3aGlsZSBwYW5uaW5nXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA+IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGF0ZSBmb3IgdGhlIGR1cmF0aW9uIG9mIGEgcG9pbnRlciBpbnRlcmFjdGlvbiwgd2hpY2ggc3RhcnRzIHdpdGggYVxuICAgIC8vIHBvaW50ZXJEb3duIGV2ZW50LCBlbmRzIHdpdGggYSBwb2ludGVyVXAgZXZlbnQgKG9yIGFub3RoZXIgcG9pbnRlckRvd24pXG4gICAgY29uc3QgcG9pbnRlckRvd25TdGF0ZSA9IHRoaXMuaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInRleHRcIikge1xuICAgICAgdGhpcy5oYW5kbGVUZXh0T25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJsaW5lXCJcbiAgICApIHtcbiAgICAgIHRoaXMuaGFuZGxlTGluZWFyRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIGV2ZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgLy8gcmVzZXQgaW1hZ2UgcHJldmlldyBvbiBwb2ludGVyZG93blxuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5DUk9TU0hBSVIpO1xuXG4gICAgICBpZiAoIXRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudDogbnVsbCxcbiAgICAgICAgbXVsdGlFbGVtZW50OiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgdGhpcy5oYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID1cbiAgICAgIHRoaXMub25Qb2ludGVyTW92ZUZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9XG4gICAgICB0aGlzLm9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uS2V5RG93biA9IHRoaXMub25LZXlEb3duRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcbiAgICBjb25zdCBvbktleVVwID0gdGhpcy5vbktleVVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIGlmICghdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCBvbktleURvd24pO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIG9uS2V5VXApO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUgPSBvblBvaW50ZXJNb3ZlO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vblVwID0gb25Qb2ludGVyVXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAgPSBvbktleVVwO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleURvd24gPSBvbktleURvd247XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVPcGVuQ29udGV4dE1lbnVBZnRlclBvaW50ZXJEb3duT25Ub3VjaERldmljZXMgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGRlYWwgd2l0aCBvcGVuaW5nIGNvbnRleHQgbWVudSBvbiB0b3VjaCBkZXZpY2VzXG4gICAgaWYgKGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIpIHtcbiAgICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG4gICAgICBpZiAodG91Y2hUaW1lb3V0KSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3MgYWxyZWFkeSBhIHRvdWNoVGltZW91dCwgdGhpcyBtZWFucyB0aGF0IHRoZXJlJ3MgYW5vdGhlclxuICAgICAgICAvLyB0b3VjaCBkb3duIGFuZCB3ZSBhcmUgZG9pbmcgYW5vdGhlciB0b3VjaCwgc28gd2Ugc2hvdWxkbid0IG9wZW4gdGhlXG4gICAgICAgIC8vIGNvbnRleHQgbWVudS5cbiAgICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9wZW4gdGhlIGNvbnRleHQgbWVudSB3aXRoIHRoZSBmaXJzdCB0b3VjaCdzIGNsaWVudFggYW5kIGNsaWVudFlcbiAgICAgICAgLy8gaWYgdGhlIHRvdWNoIGlzIG5vdCBtb3ZpbmdcbiAgICAgICAgdG91Y2hUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRvdWNoVGltZW91dCA9IDA7XG4gICAgICAgICAgaWYgKCFpbnZhbGlkYXRlQ29udGV4dE1lbnUpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUoZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgVE9VQ0hfQ1RYX01FTlVfVElNRU9VVCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVDbGVhbnVwQWZ0ZXJNaXNzaW5nUG9pbnRlclVwKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBpZiAobGFzdFBvaW50ZXJVcCAhPT0gbnVsbCkge1xuICAgICAgLy8gVW5mb3J0dW5hdGVseSwgc29tZXRpbWVzIHdlIGRvbid0IGdldCBhIHBvaW50ZXJ1cCBhZnRlciBhIHBvaW50ZXJkb3duLFxuICAgICAgLy8gdGhpcyBjYW4gaGFwcGVuIHdoZW4gYSBjb250ZXh0dWFsIG1lbnUgb3IgYWxlcnQgaXMgdHJpZ2dlcmVkLiBJbiBvcmRlciB0byBhdm9pZFxuICAgICAgLy8gYmVpbmcgaW4gYSB3ZWlyZCBzdGF0ZSwgd2UgY2xlYW4gdXAgb24gdGhlIG5leHQgcG9pbnRlcmRvd25cbiAgICAgIGxhc3RQb2ludGVyVXAoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBwYW5uaW5nXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUGFuVXNpbmdXaGVlbE9yU3BhY2VEcmFnID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAoXG4gICAgICAhKFxuICAgICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDAgJiZcbiAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uV0hFRUwgfHxcbiAgICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmIGlzSG9sZGluZ1NwYWNlKSB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKVxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuXG4gICAgbGV0IG5leHRQYXN0ZVByZXZlbnRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGlzTGludXggPSAvTGludXgvLnRlc3Qod2luZG93Lm5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICBsZXQgeyBjbGllbnRYOiBsYXN0WCwgY2xpZW50WTogbGFzdFkgfSA9IGV2ZW50O1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGxhc3RYIC0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGxhc3RZIC0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGxhc3RYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGxhc3RZID0gZXZlbnQuY2xpZW50WTtcblxuICAgICAgLypcbiAgICAgICAqIFByZXZlbnQgcGFzdGUgZXZlbnQgaWYgd2UgbW92ZSB3aGlsZSBtaWRkbGUgY2xpY2tpbmcgb24gTGludXguXG4gICAgICAgKiBTZWUgaXNzdWUgIzEzODMuXG4gICAgICAgKi9cbiAgICAgIGlmIChcbiAgICAgICAgaXNMaW51eCAmJlxuICAgICAgICAhbmV4dFBhc3RlUHJldmVudGVkICYmXG4gICAgICAgIChNYXRoLmFicyhkZWx0YVgpID4gMSB8fCBNYXRoLmFicyhkZWx0YVkpID4gMSlcbiAgICAgICkge1xuICAgICAgICBuZXh0UGFzdGVQcmV2ZW50ZWQgPSB0cnVlO1xuXG4gICAgICAgIC8qIFByZXZlbnQgdGhlIG5leHQgcGFzdGUgZXZlbnQgKi9cbiAgICAgICAgY29uc3QgcHJldmVudE5leHRQYXN0ZSA9IChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIFJlZW5hYmxlIG5leHQgcGFzdGUgaW4gY2FzZSBvZiBkaXNhYmxlZCBtaWRkbGUgY2xpY2sgcGFzdGUgZm9yXG4gICAgICAgICAqIGFueSByZWFzb246XG4gICAgICAgICAqIC0gcmlndGggY2xpY2sgcGFzdGVcbiAgICAgICAgICogLSBlbXB0eSBjbGlwYm9hcmRcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGVuYWJsZU5leHRQYXN0ZSA9ICgpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgZW5hYmxlTmV4dFBhc3RlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGRlbHRhWCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZGVsdGFZIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgY29uc3QgdGVhcmRvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgICAobGFzdFBvaW50ZXJVcCA9ICgpID0+IHtcbiAgICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICAgIGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSwge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVHZXN0dXJlT25Qb2ludGVyRG93bihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICB9KTtcblxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIpIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPSBnZXREaXN0YW5jZShcbiAgICAgICAgQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsUG9pbnRlckRvd25TdGF0ZShcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogUG9pbnRlckRvd25TdGF0ZSB7XG4gICAgY29uc3Qgb3JpZ2luID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgb3JpZ2luLFxuICAgICAgd2l0aENtZE9yQ3RybDogZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0sXG4gICAgICBvcmlnaW5JbkdyaWQ6IHR1cGxlVG9Db29ycyhcbiAgICAgICAgZ2V0R3JpZFBvaW50KG9yaWdpbi54LCBvcmlnaW4ueSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSksXG4gICAgICApLFxuICAgICAgc2Nyb2xsYmFyczogaXNPdmVyU2Nyb2xsQmFycyhcbiAgICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgIGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICksXG4gICAgICAvLyB3ZSBuZWVkIHRvIGR1cGxpY2F0ZSBiZWNhdXNlIHdlJ2xsIGJlIHVwZGF0aW5nIHRoaXMgc3RhdGVcbiAgICAgIGxhc3RDb29yZHM6IHsgLi4ub3JpZ2luIH0sXG4gICAgICBvcmlnaW5hbEVsZW1lbnRzOiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCkucmVkdWNlKChhY2MsIGVsZW1lbnQpID0+IHtcbiAgICAgICAgYWNjLnNldChlbGVtZW50LmlkLCBkZWVwQ29weUVsZW1lbnQoZWxlbWVudCkpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IE1hcCgpIGFzIFBvaW50ZXJEb3duU3RhdGVbXCJvcmlnaW5hbEVsZW1lbnRzXCJdKSxcbiAgICAgIHJlc2l6ZToge1xuICAgICAgICBoYW5kbGVUeXBlOiBmYWxzZSxcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIG9mZnNldDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgIGFycm93RGlyZWN0aW9uOiBcIm9yaWdpblwiLFxuICAgICAgICBjZW50ZXI6IHsgeDogKG1heFggKyBtaW5YKSAvIDIsIHk6IChtYXhZICsgbWluWSkgLyAyIH0sXG4gICAgICB9LFxuICAgICAgaGl0OiB7XG4gICAgICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGFsbEhpdEVsZW1lbnRzOiBbXSxcbiAgICAgICAgd2FzQWRkZWRUb1NlbGVjdGlvbjogZmFsc2UsXG4gICAgICAgIGhhc0JlZW5EdXBsaWNhdGVkOiBmYWxzZSxcbiAgICAgICAgaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHM6XG4gICAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgKSxcbiAgICAgICAgaGFzSGl0RWxlbWVudEluc2lkZTogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZHJhZzoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICAgIG9mZnNldDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBldmVudExpc3RlbmVyczoge1xuICAgICAgICBvbk1vdmU6IG51bGwsXG4gICAgICAgIG9uVXA6IG51bGwsXG4gICAgICAgIG9uS2V5VXA6IG51bGwsXG4gICAgICAgIG9uS2V5RG93bjogbnVsbCxcbiAgICAgIH0sXG4gICAgICBib3hTZWxlY3Rpb246IHtcbiAgICAgICAgaGFzT2NjdXJyZWQ6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBldmVudCBpcyBhIGRyYWdnaW5nIGEgc2Nyb2xsYmFyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKFxuICAgICAgIShwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyRWl0aGVyICYmICF0aGlzLnN0YXRlLm11bHRpRWxlbWVudClcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaXNEcmFnZ2luZ1Njcm9sbEJhciA9IHRydWU7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBldmVudC5jbGllbnRYO1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gZXZlbnQuY2xpZW50WTtcbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyVXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgICAgaXNEcmFnZ2luZ1Njcm9sbEJhciA9IGZhbHNlO1xuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgfSk7XG5cbiAgICBsYXN0UG9pbnRlclVwID0gb25Qb2ludGVyVXA7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb25JZk5vdFVzaW5nU2VsZWN0aW9uID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIGV2ZW50IGhhcyBiZWVuIGNvbXBsZXRlbHkgaGFuZGxlZFxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgPVxuICAgICAgICAgIGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICByZXNpemluZ0VsZW1lbnQ6IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS5lbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUgPVxuICAgICAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUgPSBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyhcbiAgICAgICAgICBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyksXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoe1xuICAgICAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZTogcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXRSZXNpemVPZmZzZXRYWShcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pICYmXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXS5wb2ludHMubGVuZ3RoID09PSAyXG4gICAgICAgICkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uID0gZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IHJldCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlckRvd24oXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAoYXBwU3RhdGUpID0+IHRoaXMuc2V0U3RhdGUoYXBwU3RhdGUpLFxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAocmV0LmhpdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPSByZXQuaGl0RWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJldC5kaWRBZGRQb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaGl0RWxlbWVudCBtYXkgYWxyZWFkeSBiZSBzZXQgYWJvdmUsIHNvIGNoZWNrIGZpcnN0XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPz9cbiAgICAgICAgICB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKTtcblxuICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUgPVxuICAgICAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goXG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55XSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3Igb3ZlcmxhcHBlZCBlbGVtZW50cyBvbmUgcG9zaXRpb24gbWF5IGhpdFxuICAgICAgICAvLyBtdWx0aXBsZSBlbGVtZW50c1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgY29uc3Qgc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PlxuICAgICAgICAgICAgdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChoaXRFbGVtZW50ID09PSBudWxsIHx8ICFzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQpICYmXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIElmIHdlIGNsaWNrIG9uIHNvbWV0aGluZ1xuICAgICAgICB9IGVsc2UgaWYgKGhpdEVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgIC8vIG9uIENNRC9DVFJMLCBkcmlsbCBkb3duIHRvIGhpdCBlbGVtZW50IHJlZ2FyZGxlc3Mgb2YgZ3JvdXBzIGV0Yy5cbiAgICAgICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIC4uLmVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudChwcmV2U3RhdGUsIGhpdEVsZW1lbnQpLFxuICAgICAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAvLyBtYXJrIGFzIG5vdCBjb21wbGV0ZWx5IGhhbmRsZWQgc28gYXMgdG8gYWxsb3cgZHJhZ2dpbmcgZXRjLlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlc2VsZWN0IGlmIGl0ZW0gaXMgc2VsZWN0ZWRcbiAgICAgICAgICAvLyBpZiBzaGlmdCBpcyBub3QgY2xpY2tlZCwgdGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZVxuICAgICAgICAgIC8vIG90aGVyd2lzZSwgaXQgd2lsbCB0cmlnZ2VyIHNlbGVjdGlvbiBiYXNlZCBvbiBjdXJyZW50XG4gICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGJveFxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBjdXJyZW50bHkgZWRpdGluZyBhIGdyb3VwLCBleGl0aW5nIGVkaXRpbmcgbW9kZSBhbmQgZGVzZWxlY3QgdGhlIGdyb3VwLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgICAgICAgICFpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBoaXQgZWxlbWVudCB0byBzZWxlY3Rpb24uIEF0IHRoaXMgcG9pbnQgaWYgd2UncmUgbm90IGhvbGRpbmdcbiAgICAgICAgICAgIC8vIFNISUZUIHRoZSBwcmV2aW91c2x5IHNlbGVjdGVkIGVsZW1lbnQocykgd2VyZSBkZXNlbGVjdGVkIGFib3ZlXG4gICAgICAgICAgICAvLyAobWFrZSBzdXJlIHlvdSB1c2Ugc2V0U3RhdGUgdXBkYXRlciB0byB1c2UgbGF0ZXN0IHN0YXRlKVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkICYmXG4gICAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgaXNBU2VsZWN0ZWRFbGVtZW50KGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBoaXRFbGVtZW50ICE9IG51bGwgJiYgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF07XG4gIH1cblxuICBwcml2YXRlIGlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgIHBvaW50OiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIb3cgbWFueSBwaXhlbHMgb2ZmIHRoZSBzaGFwZSBib3VuZGFyeSB3ZSBzdGlsbCBjb25zaWRlciBhIGhpdFxuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvaW50LnggPiB4MSAtIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueCA8IHgyICsgdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55ID4geTEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnkgPCB5MiArIHRocmVzaG9sZFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRleHRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGlmIHdlJ3JlIGN1cnJlbnRseSBzdGlsbCBlZGl0aW5nIHRleHQsIGNsaWNraW5nIG91dHNpZGVcbiAgICAvLyBzaG91bGQgb25seSBmaW5hbGl6ZSBpdCwgbm90IGNyZWF0ZSBhbm90aGVyIChpcnJlc3BlY3RpdmVcbiAgICAvLyBvZiBzdGF0ZS5lbGVtZW50TG9ja2VkKVxuICAgIGlmIChpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBzY2VuZVggPSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54O1xuICAgIGxldCBzY2VuZVkgPSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55O1xuXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVksIHtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY2FuQmluZFRleHQgPSBoYXNCb3VuZFRleHRFbGVtZW50KGVsZW1lbnQpO1xuICAgIGlmIChjYW5CaW5kVGV4dCkge1xuICAgICAgc2NlbmVYID0gZWxlbWVudC54ICsgZWxlbWVudC53aWR0aCAvIDI7XG4gICAgICBzY2VuZVkgPSBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCAvIDI7XG4gICAgfVxuICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICBzY2VuZVgsXG4gICAgICBzY2VuZVksXG4gICAgICBzaG91bGRCaW5kOiBmYWxzZSxcbiAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyOiAhZXZlbnQuYWx0S2V5LFxuICAgIH0pO1xuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgIGlmICghdGhpcy5zdGF0ZS5lbGVtZW50TG9ja2VkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICAvLyBCZWdpbiBhIG1hcmsgY2FwdHVyZS4gVGhpcyBkb2VzIG5vdCBoYXZlIHRvIHVwZGF0ZSBzdGF0ZSB5ZXQuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIG51bGwsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdGcmVlRHJhd0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICBzaW11bGF0ZVByZXNzdXJlOiBldmVudC5wcmVzc3VyZSA9PT0gMC41LFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIGNvbnN0IHByZXNzdXJlcyA9IGVsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgPyBlbGVtZW50LnByZXNzdXJlc1xuICAgICAgOiBbLi4uZWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgcG9pbnRzOiBbWzAsIDBdXSxcbiAgICAgIHByZXNzdXJlcyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlSW1hZ2VFbGVtZW50ID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICB9OiB7XG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgc2NlbmVZOiBudW1iZXI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChzY2VuZVgsIHNjZW5lWSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3SW1hZ2VFbGVtZW50KHtcbiAgICAgIHR5cGU6IFwiaW1hZ2VcIixcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICB9KTtcblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlTGluZWFyRWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICAvLyBmaW5hbGl6ZSBpZiBjb21wbGV0aW5nIGEgbG9vcFxuICAgICAgaWYgKFxuICAgICAgICBtdWx0aUVsZW1lbnQudHlwZSA9PT0gXCJsaW5lXCIgJiZcbiAgICAgICAgaXNQYXRoQUxvb3AobXVsdGlFbGVtZW50LnBvaW50cywgdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICAgKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OlxuICAgICAgICAgICAgbXVsdGlFbGVtZW50LnBvaW50c1ttdWx0aUVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgeDogcngsIHk6IHJ5LCBsYXN0Q29tbWl0dGVkUG9pbnQgfSA9IG11bHRpRWxlbWVudDtcblxuICAgICAgLy8gY2xpY2tpbmcgaW5zaWRlIGNvbW1pdCB6b25lIOKGkiBmaW5hbGl6ZSBhcnJvd1xuICAgICAgaWYgKFxuICAgICAgICBtdWx0aUVsZW1lbnQucG9pbnRzLmxlbmd0aCA+IDEgJiZcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50ICYmXG4gICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHJ4LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSByeSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMF0sXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzFdLFxuICAgICAgICApIDwgTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgW211bHRpRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgICAvLyBjbGlja2luZyBvdXRzaWRlIGNvbW1pdCB6b25lIOKGkiB1cGRhdGUgcmVmZXJlbmNlIGZvciBsYXN0IGNvbW1pdHRlZFxuICAgICAgLy8gcG9pbnRcbiAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDogbXVsdGlFbGVtZW50LnBvaW50c1ttdWx0aUVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdLFxuICAgICAgfSk7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIC8qIElmIGFycm93IGlzIHByZS1hcnJvd2hlYWRzLCBpdCB3aWxsIGhhdmUgdW5kZWZpbmVkIGZvciBib3RoIHN0YXJ0IGFuZCBlbmQgYXJyb3doZWFkcy5cbiAgICAgIElmIHNvLCB3ZSB3YW50IGl0IHRvIGJlIG51bGwgZm9yIHN0YXJ0IGFuZCBcImFycm93XCIgZm9yIGVuZC4gSWYgdGhlIGxpbmVhciBpdGVtIGlzIG5vdFxuICAgICAgYW4gYXJyb3csIHdlIHdhbnQgaXQgdG8gYmUgbnVsbCBmb3IgYm90aC4gT3RoZXJ3aXNlLCB3ZSB3YW50IGl0IHRvIHVzZSB0aGVcbiAgICAgIHZhbHVlcyBmcm9tIGFwcFN0YXRlLiAqL1xuXG4gICAgICBjb25zdCB7IGN1cnJlbnRJdGVtU3RhcnRBcnJvd2hlYWQsIGN1cnJlbnRJdGVtRW5kQXJyb3doZWFkIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgY29uc3QgW3N0YXJ0QXJyb3doZWFkLCBlbmRBcnJvd2hlYWRdID1cbiAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiYXJyb3dcIlxuICAgICAgICAgID8gW2N1cnJlbnRJdGVtU3RhcnRBcnJvd2hlYWQsIGN1cnJlbnRJdGVtRW5kQXJyb3doZWFkXVxuICAgICAgICAgIDogW251bGwsIG51bGxdO1xuXG4gICAgICBjb25zdCBlbGVtZW50ID0gbmV3TGluZWFyRWxlbWVudCh7XG4gICAgICAgIHR5cGU6IGVsZW1lbnRUeXBlLFxuICAgICAgICB4OiBncmlkWCxcbiAgICAgICAgeTogZ3JpZFksXG4gICAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICAgIHN0YXJ0QXJyb3doZWFkLFxuICAgICAgICBlbmRBcnJvd2hlYWQsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgIHBvaW50czogWy4uLmVsZW1lbnQucG9pbnRzLCBbMCwgMF1dLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgKTtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIHN0YXJ0Qm91bmRFbGVtZW50OiBib3VuZEVsZW1lbnQsXG4gICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUdlbmVyaWNFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdFbGVtZW50KHtcbiAgICAgIHR5cGU6IGVsZW1lbnRUeXBlLFxuICAgICAgeDogZ3JpZFgsXG4gICAgICB5OiBncmlkWSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gUHJldmVudHMgZm9jdXMgZnJvbSBlc2NhcGluZyBleGNhbGlkcmF3IHRhYlxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkFMVCAmJiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgLy8gV2UgbmVlZCB0byBpbml0aWFsaXplIGRyYWdPZmZzZXRYWSBvbmx5IGFmdGVyIHdlJ3ZlIHVwZGF0ZWRcbiAgICAgIC8vIGBzdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNgIG9uIHBvaW50ZXJEb3duLiBEb2luZyBpdCBoZXJlIGluIHBvaW50ZXJNb3ZlXG4gICAgICAvLyBldmVudCBoYW5kbGVyIHNob3VsZCBob3BlZnVsbHkgZW5zdXJlIHdlJ3JlIGFscmVhZHkgd29ya2luZyB3aXRoXG4gICAgICAvLyB0aGUgdXBkYXRlZCBzdGF0ZS5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0ID09PSBudWxsKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPSB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgZ2V0RHJhZ09mZnNldFhZKFxuICAgICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIC8vIGZvciBhcnJvd3MvbGluZXMsIGRvbid0IHN0YXJ0IGRyYWdnaW5nIHVudGlsIGEgZ2l2ZW4gdGhyZXNob2xkXG4gICAgICAvLyB0byBlbnN1cmUgd2UgZG9uJ3QgY3JlYXRlIGEgMi1wb2ludCBhcnJvdyBieSBtaXN0YWtlIHdoZW5cbiAgICAgIC8vIHVzZXIgY2xpY2tzIG1vdXNlIGluIGEgd2F5IHRoYXQgaXQgbW92ZXMgYSB0aW55IGJpdCAodGh1c1xuICAgICAgLy8gdHJpZ2dlcmluZyBwb2ludGVybW92ZSlcbiAgICAgIGlmIChcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiIHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJsaW5lXCIpXG4gICAgICApIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApIDwgRFJBR0dJTkdfVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZykge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRpZERyYWcgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50RHJhZ2dpbmcoXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAoYXBwU3RhdGUpID0+IHRoaXMuc2V0U3RhdGUoYXBwU3RhdGUpLFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKGVsZW1lbnQsIHBvaW50c1NjZW5lQ29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBwb2ludHNTY2VuZUNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGlkRHJhZykge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBoYXNIaXRBU2VsZWN0ZWRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZShcbiAgICAgICAgKGVsZW1lbnQpID0+IHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgKTtcblxuICAgICAgaWYgKFxuICAgICAgICAoaGFzSGl0QVNlbGVjdGVkRWxlbWVudCB8fFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSAmJlxuICAgICAgICAvLyB0aGlzIGFsbG93cyBmb3IgYm94LXNlbGVjdGluZyBwb2ludHMgd2hlbiBjbGlja2luZyBpbnNpZGUgdGhlXG4gICAgICAgIC8vIGxpbmUncyBib3VuZGluZyBib3hcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8ICFldmVudC5zaGlmdEtleSkgJiZcbiAgICAgICAgLy8gYm94LXNlbGVjdGluZyB3aXRob3V0IHNoaWZ0IHdoZW4gZWRpdGluZyBsaW5lLCBub3QgY2xpY2tpbmcgb24gYSBsaW5lXG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT1cbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ/LmlkIHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0RWxlbWVudEluc2lkZSlcbiAgICAgICkge1xuICAgICAgICAvLyBNYXJraW5nIHRoYXQgY2xpY2sgd2FzIHVzZWQgZm9yIGRyYWdnaW5nIHRvIGNoZWNrXG4gICAgICAgIC8vIGlmIGVsZW1lbnRzIHNob3VsZCBiZSBkZXNlbGVjdGVkIG9uIHBvaW50ZXJ1cFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgLy8gcHJldmVudCBkcmFnZ2luZyBldmVuIGlmIHdlJ3JlIG5vIGxvbmdlciBob2xkaW5nIGNtZC9jdHJsIG90aGVyd2lzZVxuICAgICAgICAvLyBpdCB3b3VsZCBoYXZlIHdlaXJkIHJlc3VsdHMgKHN0dWZmIGp1bXBpbmcgYWxsIG92ZXIgdGhlIHNjcmVlbilcbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMCAmJiAhcG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsKSB7XG4gICAgICAgICAgY29uc3QgW2RyYWdYLCBkcmFnWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBbZHJhZ0Rpc3RhbmNlWCwgZHJhZ0Rpc3RhbmNlWV0gPSBbXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54KSxcbiAgICAgICAgICAgIE1hdGguYWJzKHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkpLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICAvLyBXZSBvbmx5IGRyYWcgaW4gb25lIGRpcmVjdGlvbiBpZiBzaGlmdCBpcyBwcmVzc2VkXG4gICAgICAgICAgY29uc3QgbG9ja0RpcmVjdGlvbiA9IGV2ZW50LnNoaWZ0S2V5O1xuXG4gICAgICAgICAgZHJhZ1NlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdYLFxuICAgICAgICAgICAgZHJhZ1ksXG4gICAgICAgICAgICBsb2NrRGlyZWN0aW9uLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWCxcbiAgICAgICAgICAgIGRyYWdEaXN0YW5jZVksXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgICAvLyBXZSBkdXBsaWNhdGUgdGhlIHNlbGVjdGVkIGVsZW1lbnQgaWYgYWx0IGlzIHByZXNzZWQgb24gcG9pbnRlciBtb3ZlXG4gICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSAmJiAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQpIHtcbiAgICAgICAgICAgIC8vIE1vdmUgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBlbGVtZW50cyB0byB0aGUgdG9wIG9mIHRoZSB6IGluZGV4IHN0YWNrLCBhbmRcbiAgICAgICAgICAgIC8vIHB1dCB0aGUgZHVwbGljYXRlcyB3aGVyZSB0aGUgc2VsZWN0ZWQgZWxlbWVudHMgdXNlZCB0byBiZS5cbiAgICAgICAgICAgIC8vICh0aGUgb3JpZ2luIHBvaW50IHdoZXJlIHRoZSBkcmFnZ2luZyBzdGFydGVkKVxuXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHNUb0FwcGVuZCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudElkczogQXJyYXk8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXT4gPVxuICAgICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlLCB0cnVlKS5tYXAoXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQpID0+IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzLmluY2x1ZGVzKGVsZW1lbnQuaWQpIHx8XG4gICAgICAgICAgICAgICAgLy8gY2FzZTogdGhlIHN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyBtaWdodCBub3QgaGF2ZSBiZWVuXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlZCB5ZXQgYnkgdGhlIHRpbWUgdGhpcyBtb3VzZW1vdmUgZXZlbnQgaXMgZmlyZWRcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24pXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZWRFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgICAgICAgICAgICBncm91cElkTWFwLFxuICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtvcmlnaW5EcmFnWCwgb3JpZ2luRHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChkdXBsaWNhdGVkRWxlbWVudCwge1xuICAgICAgICAgICAgICAgICAgeDogZHVwbGljYXRlZEVsZW1lbnQueCArIChvcmlnaW5EcmFnWCAtIGRyYWdYKSxcbiAgICAgICAgICAgICAgICAgIHk6IGR1cGxpY2F0ZWRFbGVtZW50LnkgKyAob3JpZ2luRHJhZ1kgLSBkcmFnWSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZHVwbGljYXRlZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBkdXBsaWNhdGVkRWxlbWVudC5pZCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5leHRTY2VuZUVsZW1lbnRzID0gWy4uLm5leHRFbGVtZW50cywgLi4uZWxlbWVudHNUb0FwcGVuZF07XG4gICAgICAgICAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0RWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICAgXCJkdXBsaWNhdGVzU2VydmVBc09sZFwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRTY2VuZUVsZW1lbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEl0IGlzIHZlcnkgaW1wb3J0YW50IHRvIHJlYWQgdGhpcy5zdGF0ZSB3aXRoaW4gZWFjaCBtb3ZlIGV2ZW50LFxuICAgICAgLy8gb3RoZXJ3aXNlIHdlIHdvdWxkIHJlYWQgYSBzdGFsZSBvbmUhXG4gICAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgY29uc3QgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgY29uc3QgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlc1xuICAgICAgICAgIDogWy4uLmRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IGdyaWRYIC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGxldCBkeSA9IGdyaWRZIC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSAmJiBwb2ludHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgKHsgd2lkdGg6IGR4LCBoZWlnaHQ6IGR5IH0gPSBnZXRQZXJmZWN0RWxlbWVudFNpemUoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICAgICAgZHgsXG4gICAgICAgICAgICBkeSxcbiAgICAgICAgICApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb2ludHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHsgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0gfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSwgW2R4LCBkeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICAgIC8vIFdoZW4gY3JlYXRpbmcgYSBsaW5lYXIgZWxlbWVudCBieSBkcmFnZ2luZ1xuICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBbcG9pbnRlckNvb3Jkc10sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgIC8vIGFsbG93cyBmb3IgYm94LXNlbGVjdGluZyBwb2ludHMgKHdpdGhvdXQgc2hpZnQpXG4gICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQoZWxlbWVudHMsIHRoaXMuc3RhdGUpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLndpdGhDbWRPckN0cmwgJiYgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gYm94LXNlbGVjdCBsaW5lIGVkaXRvciBwb2ludHNcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZUJveFNlbGVjdGlvbihcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHJlZ3VsYXIgYm94LXNlbGVjdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uID0gZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24oXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ucmVkdWNlKChtYXAsIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbWFwW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgICAgICAgICAgICAgIH0sIHt9IGFzIGFueSksXG4gICAgICAgICAgICAgICAgICAuLi4ocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHVzaW5nIGN0cmwvY21kLCBzZWxlY3QgdGhlIGhpdEVsZW1lbnQgb25seSBpZiB3ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGF2ZW4ndCBib3gtc2VsZWN0ZWQgYW55dGhpbmcgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQuaWRdOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAhZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgOiBudWxsKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgcG9pbnRlciBtb3ZlIGhhcHBlbmVkIG92ZXIgZWl0aGVyIHNjcm9sbGJhclxuICBwcml2YXRlIGhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3Zlckhvcml6b250YWwpIHtcbiAgICAgIGNvbnN0IHggPSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZHggPSB4IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLng7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZHggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0geDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyVmVydGljYWwpIHtcbiAgICAgIGNvbnN0IHkgPSBldmVudC5jbGllbnRZO1xuICAgICAgY29uc3QgZHkgPSB5IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZHkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0geTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoY2hpbGRFdmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgcmVzaXppbmdFbGVtZW50LFxuICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgIGVsZW1lbnRUeXBlLFxuICAgICAgICBlbGVtZW50TG9ja2VkLFxuICAgICAgICBpc1Jlc2l6aW5nLFxuICAgICAgICBpc1JvdGF0aW5nLFxuICAgICAgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgaXNSb3RhdGluZzogZmFsc2UsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogbnVsbCxcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIC8vIHRleHQgZWxlbWVudHMgYXJlIHJlc2V0IG9uIGZpbmFsaXplLCBhbmQgcmVzZXR0aW5nIG9uIHBvaW50ZXJ1cFxuICAgICAgICAvLyBtYXkgY2F1c2UgaXNzdWVzIHdpdGggZG91YmxlIHRhcHNcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgbXVsdGlFbGVtZW50IHx8IGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgICAgID8gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudFxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoY2hpbGRFdmVudC5jbGllbnRYLCBjaGlsZEV2ZW50LmNsaWVudFksIFwidXBcIik7XG5cbiAgICAgIC8vIEhhbmRsZSBlbmQgb2YgZHJhZ2dpbmcgYSBwb2ludCBvZiBhIGxpbmVhciBlbGVtZW50LCBtaWdodCBjbG9zZSBhIGxvb3BcbiAgICAgIC8vIGFuZCBzZXRzIGJpbmRpbmcgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCB8fFxuICAgICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlclVwKFxuICAgICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50ICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcblxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfTU9WRSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5QT0lOVEVSX1VQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5LRVlET1dOLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWVVQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAhLFxuICAgICAgKTtcblxuICAgICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgcGVuZGluZ0ltYWdlRWxlbWVudDogbnVsbCB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudD8udHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICAvLyBBbGxvd3MgZG90cyB0byBhdm9pZCBiZWluZyBmbGFnZ2VkIGFzIGluZmluaXRlbHkgc21hbGxcbiAgICAgICAgaWYgKGR4ID09PSBwb2ludHNbMF1bMF0gJiYgZHkgPT09IHBvaW50c1swXVsxXSkge1xuICAgICAgICAgIGR5ICs9IDAuMDAwMTtcbiAgICAgICAgICBkeCArPSAwLjAwMDE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBjaGlsZEV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IFtkeCwgZHldLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICB7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSBpbWFnZUVsZW1lbnQuaWQpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQhLnBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgICAgIW11bHRpRWxlbWVudFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAgIC4uLmRyYWdnaW5nRWxlbWVudC5wb2ludHMsXG4gICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQ6IGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiYgIW11bHRpRWxlbWVudCkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSwgc3RhcnRCb3VuZEVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICAgICAgaWYgKCFlbGVtZW50TG9ja2VkKSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW3RoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICkge1xuICAgICAgICAvLyByZW1vdmUgaW52aXNpYmxlIGVsZW1lbnQgd2hpY2ggd2FzIGFkZGVkIGluIG9uUG9pbnRlckRvd25cbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5zbGljZSgwLCAtMSksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyhkcmFnZ2luZ0VsZW1lbnQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCAmJiBpc0ludmlzaWJseVNtYWxsRWxlbWVudChyZXNpemluZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSByZXNpemluZ0VsZW1lbnQuaWQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDb2RlIGJlbG93IGhhbmRsZXMgc2VsZWN0aW9uIHdoZW4gZWxlbWVudChzKSB3ZXJlbid0XG4gICAgICAvLyBkcmFnIG9yIGFkZGVkIHRvIHNlbGVjdGlvbiBvbiBwb2ludGVyIGRvd24gcGhhc2UuXG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgIGlmIChcbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uICYmXG4gICAgICAgIC8vIGlmIHdlJ3JlIGVkaXRpbmcgYSBsaW5lLCBwb2ludGVydXAgc2hvdWxkbid0IHN3aXRjaCBzZWxlY3Rpb24gaWZcbiAgICAgICAgLy8gYm94IHNlbGVjdGVkXG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZClcbiAgICAgICkge1xuICAgICAgICAvLyB3aGVuIGluc2lkZSBsaW5lIGVkaXRvciwgc2hpZnQgc2VsZWN0cyBwb2ludHMgaW5zdGVhZFxuICAgICAgICBpZiAoY2hpbGRFdmVudC5zaGlmdEtleSAmJiAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSkge1xuICAgICAgICAgICAgaWYgKGlzU2VsZWN0ZWRWaWFHcm91cCh0aGlzLnN0YXRlLCBoaXRFbGVtZW50KSkge1xuICAgICAgICAgICAgICAvLyBXZSB3YW50IHRvIHVuc2VsZWN0IGFsbCBncm91cHMgaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIC8vIGFzIHdlbGwgYXMgYWxsIGVsZW1lbnRzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGdyb3Vwc1xuICAgICAgICAgICAgICAvLyBoaXRFbGVtZW50IGlzIHBhcnQgb2ZcbiAgICAgICAgICAgICAgY29uc3QgaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzID0gaGl0RWxlbWVudC5ncm91cElkc1xuICAgICAgICAgICAgICAgIC5mbGF0TWFwKChncm91cElkKSA9PlxuICAgICAgICAgICAgICAgICAgZ2V0RWxlbWVudHNJbkdyb3VwKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgZ3JvdXBJZCksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5tYXAoKGVsZW1lbnQpID0+ICh7IFtlbGVtZW50LmlkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldklkLCBhY2MpID0+ICh7IC4uLnByZXZJZCwgLi4uYWNjIH0pLCB7fSk7XG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZ0lkKSA9PiAoeyBbZ0lkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXYsIGFjYykgPT4gKHsgLi4ucHJldiwgLi4uYWNjIH0pLCB7fSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIHJlbW92ZSBlbGVtZW50IGZyb20gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBhZGQgZWxlbWVudCB0byBzZWxlY3Rpb24gd2hpbGVcbiAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAuLi5zZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICF0aGlzLnN0YXRlLmlzUmVzaXppbmcgJiZcbiAgICAgICAgKChoaXRFbGVtZW50ICYmXG4gICAgICAgICAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApKSB8fFxuICAgICAgICAgICghaGl0RWxlbWVudCAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpKVxuICAgICAgKSB7XG4gICAgICAgIC8vIERlc2VsZWN0IHNlbGVjdGVkIGVsZW1lbnRzXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50TG9ja2VkICYmIGVsZW1lbnRUeXBlICE9PSBcImZyZWVkcmF3XCIgJiYgZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICBbZHJhZ2dpbmdFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIgfHxcbiAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgdGhpcy5zdGF0ZSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgfHwgaXNSZXNpemluZyB8fCBpc1JvdGF0aW5nKSB7XG4gICAgICAgIChpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cykoXG4gICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnRMb2NrZWQgJiYgZWxlbWVudFR5cGUgIT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVJbWFnZSA9IGFzeW5jICh7XG4gICAgaW1hZ2VGaWxlLFxuICAgIGltYWdlRWxlbWVudDogX2ltYWdlRWxlbWVudCxcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ID0gZmFsc2UsXG4gIH06IHtcbiAgICBpbWFnZUZpbGU6IEZpbGU7XG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50O1xuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgLy8gYXQgdGhpcyBwb2ludCB0aGlzIHNob3VsZCBiZSBndWFyYW50ZWVkIGltYWdlIGZpbGUsIGJ1dCB3ZSBkbyB0aGlzIGNoZWNrXG4gICAgLy8gdG8gc2F0aXNmeSBUUyBkb3duIHRoZSBsaW5lXG4gICAgaWYgKCFpc1N1cHBvcnRlZEltYWdlRmlsZShpbWFnZUZpbGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy51bnN1cHBvcnRlZEZpbGVUeXBlXCIpKTtcbiAgICB9XG4gICAgY29uc3QgbWltZVR5cGUgPSBpbWFnZUZpbGUudHlwZTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgXCJ3YWl0XCIpO1xuXG4gICAgaWYgKG1pbWVUeXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW1hZ2VGaWxlID0gU1ZHU3RyaW5nVG9GaWxlKFxuICAgICAgICAgIGF3YWl0IG5vcm1hbGl6ZVNWRyhhd2FpdCBpbWFnZUZpbGUudGV4dCgpKSxcbiAgICAgICAgICBpbWFnZUZpbGUubmFtZSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMuc3ZnSW1hZ2VJbnNlcnRFcnJvclwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZ2VuZXJhdGUgaW1hZ2UgaWQgKGJ5IGRlZmF1bHQgdGhlIGZpbGUgZGlnZXN0KSBiZWZvcmUgYW55XG4gICAgLy8gcmVzaXppbmcvY29tcHJlc3Npb24gdGFrZXMgcGxhY2UgdG8ga2VlcCBpdCBtb3JlIHBvcnRhYmxlXG4gICAgY29uc3QgZmlsZUlkID0gYXdhaXQgKCh0aGlzLnByb3BzLmdlbmVyYXRlSWRGb3JGaWxlPy4oXG4gICAgICBpbWFnZUZpbGUsXG4gICAgKSBhcyBQcm9taXNlPEZpbGVJZD4pIHx8IGdlbmVyYXRlSWRGcm9tRmlsZShpbWFnZUZpbGUpKTtcblxuICAgIGlmICghZmlsZUlkKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiQ291bGRuJ3QgZ2VuZXJhdGUgZmlsZSBpZCBvciB0aGUgc3VwcGxpZWQgYGdlbmVyYXRlSWRGb3JGaWxlYCBkaWRuJ3QgcmVzb2x2ZSB0byBvbmUuXCIsXG4gICAgICApO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdGaWxlRGF0YSA9IHRoaXMuZmlsZXNbZmlsZUlkXTtcbiAgICBpZiAoIWV4aXN0aW5nRmlsZURhdGE/LmRhdGFVUkwpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgICAgICBtYXhXaWR0aE9ySGVpZ2h0OiBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiZXJyb3IgdHJ5aW5nIHRvIHJlc2luZyBpbWFnZSBmaWxlIG9uIGluc2VydGlvblwiLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbWFnZUZpbGUuc2l6ZSA+IE1BWF9BTExPV0VEX0ZJTEVfQllURVMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIHQoXCJlcnJvcnMuZmlsZVRvb0JpZ1wiLCB7XG4gICAgICAgICAgICBtYXhTaXplOiBgJHtNYXRoLnRydW5jKE1BWF9BTExPV0VEX0ZJTEVfQllURVMgLyAxMDI0IC8gMTAyNCl9TUJgLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICBjb25zdCBkYXRhVVJMID0gdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMO1xuICAgICAgLy8gb3B0aW1pemF0aW9uIHNvIHRoYXQgd2UgZG9uJ3QgdW5uZWNlc3NhcmlseSByZXNpemUgdGhlIG9yaWdpbmFsXG4gICAgICAvLyBmdWxsLXNpemUgZmlsZSBmb3IgY3Vyc29yIHByZXZpZXdcbiAgICAgIC8vIChpdCdzIG11Y2ggZmFzdGVyIHRvIGNvbnZlcnQgdGhlIHJlc2l6ZWQgZGF0YVVSTCB0byBGaWxlKVxuICAgICAgY29uc3QgcmVzaXplZEZpbGUgPSBkYXRhVVJMICYmIGRhdGFVUkxUb0ZpbGUoZGF0YVVSTCk7XG5cbiAgICAgIHRoaXMuc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yKHJlc2l6ZWRGaWxlIHx8IGltYWdlRmlsZSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YVVSTCA9XG4gICAgICB0aGlzLmZpbGVzW2ZpbGVJZF0/LmRhdGFVUkwgfHwgKGF3YWl0IGdldERhdGFVUkwoaW1hZ2VGaWxlKSk7XG5cbiAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSBtdXRhdGVFbGVtZW50KFxuICAgICAgX2ltYWdlRWxlbWVudCxcbiAgICAgIHtcbiAgICAgICAgZmlsZUlkLFxuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICkgYXMgTm9uRGVsZXRlZDxJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ+O1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50Pj4oXG4gICAgICBhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5maWxlcyA9IHtcbiAgICAgICAgICAgIC4uLnRoaXMuZmlsZXMsXG4gICAgICAgICAgICBbZmlsZUlkXToge1xuICAgICAgICAgICAgICBtaW1lVHlwZSxcbiAgICAgICAgICAgICAgaWQ6IGZpbGVJZCxcbiAgICAgICAgICAgICAgZGF0YVVSTCxcbiAgICAgICAgICAgICAgY3JlYXRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjYWNoZWRJbWFnZURhdGEgPSB0aGlzLmltYWdlQ2FjaGUuZ2V0KGZpbGVJZCk7XG4gICAgICAgICAgaWYgKCFjYWNoZWRJbWFnZURhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUltYWdlQ2FjaGUoW2ltYWdlRWxlbWVudF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2FjaGVkSW1hZ2VEYXRhPy5pbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIGF3YWl0IGNhY2hlZEltYWdlRGF0YS5pbWFnZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50Py5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudD8uaWQgIT09IGltYWdlRWxlbWVudC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgaWYgKCFzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGluc2VydHMgaW1hZ2UgaW50byBlbGVtZW50cyBhcnJheSBhbmQgcmVyZW5kZXJzXG4gICAqL1xuICBwcml2YXRlIGluc2VydEltYWdlRWxlbWVudCA9IGFzeW5jIChcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gICAgaW1hZ2VGaWxlOiBGaWxlLFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuLFxuICApID0+IHtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgaW1hZ2VFbGVtZW50LFxuICAgIF0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZUltYWdlKHtcbiAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICBpc0RlbGV0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfHwgdChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yID0gYXN5bmMgKGltYWdlRmlsZTogRmlsZSkgPT4ge1xuICAgIC8vIG11c3RuJ3QgYmUgbGFyZ2VyIHRoYW4gMTI4IHB4XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NTU19CYXNpY19Vc2VyX0ludGVyZmFjZS9Vc2luZ19VUkxfdmFsdWVzX2Zvcl90aGVfY3Vyc29yX3Byb3BlcnR5XG4gICAgY29uc3QgY3Vyc29ySW1hZ2VTaXplUHggPSA5NjtcblxuICAgIGNvbnN0IGltYWdlUHJldmlldyA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IGN1cnNvckltYWdlU2l6ZVB4LFxuICAgIH0pO1xuXG4gICAgbGV0IHByZXZpZXdEYXRhVVJMID0gYXdhaXQgZ2V0RGF0YVVSTChpbWFnZVByZXZpZXcpO1xuXG4gICAgLy8gU1ZHIGNhbm5vdCBiZSByZXNpemVkIHZpYSBgcmVzaXplSW1hZ2VGaWxlYCBzbyB3ZSByZXNpemUgYnkgcmVuZGVyaW5nIHRvXG4gICAgLy8gYSBzbWFsbCBjYW52YXNcbiAgICBpZiAoaW1hZ2VGaWxlLnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICBjb25zdCBpbWcgPSBhd2FpdCBsb2FkSFRNTEltYWdlRWxlbWVudChwcmV2aWV3RGF0YVVSTCk7XG5cbiAgICAgIGxldCBoZWlnaHQgPSBNYXRoLm1pbihpbWcuaGVpZ2h0LCBjdXJzb3JJbWFnZVNpemVQeCk7XG4gICAgICBsZXQgd2lkdGggPSBoZWlnaHQgKiAoaW1nLndpZHRoIC8gaW1nLmhlaWdodCk7XG5cbiAgICAgIGlmICh3aWR0aCA+IGN1cnNvckltYWdlU2l6ZVB4KSB7XG4gICAgICAgIHdpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgICAgIGhlaWdodCA9IHdpZHRoICogKGltZy5oZWlnaHQgLyBpbWcud2lkdGgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuXG4gICAgICBjb250ZXh0LmRyYXdJbWFnZShpbWcsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICBwcmV2aWV3RGF0YVVSTCA9IGNhbnZhcy50b0RhdGFVUkwoTUlNRV9UWVBFUy5zdmcpIGFzIERhdGFVUkw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBgdXJsKCR7cHJldmlld0RhdGFVUkx9KSA0IDQsIGF1dG9gKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbkltYWdlQWN0aW9uID0gYXN5bmMgKFxuICAgIHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseSB9ID0geyBpbnNlcnRPbkNhbnZhc0RpcmVjdGx5OiBmYWxzZSB9LFxuICApID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY2xpZW50WCA9IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgICAgY29uc3QgY2xpZW50WSA9IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgeyBjbGllbnRYLCBjbGllbnRZIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZUZpbGUgPSBhd2FpdCBmaWxlT3Blbih7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkltYWdlXCIsXG4gICAgICAgIGV4dGVuc2lvbnM6IFtcImpwZ1wiLCBcInBuZ1wiLCBcInN2Z1wiLCBcImdpZlwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7XG4gICAgICAgIHNjZW5lWDogeCxcbiAgICAgICAgc2NlbmVZOiB5LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChpbnNlcnRPbkNhbnZhc0RpcmVjdGx5KSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgaW1hZ2VGaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudDogaW1hZ2VFbGVtZW50LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoXG4gICAgICAgICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICAgICAgICAvKiBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ICovIHRydWUsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgaWYgKGVycm9yLm5hbWUgIT09IFwiQWJvcnRFcnJvclwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVsZW1lbnRUeXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zID0gKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBmb3JjZU5hdHVyYWxTaXplID0gZmFsc2UsXG4gICkgPT4ge1xuICAgIGNvbnN0IGltYWdlID1cbiAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50KSAmJlxuICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChpbWFnZUVsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG5cbiAgICBpZiAoIWltYWdlIHx8IGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgaWYgKFxuICAgICAgICBpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyU2l6ZSA9IDEwMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgICB4OiBpbWFnZUVsZW1lbnQueCAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgeTogaW1hZ2VFbGVtZW50LnkgLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHdpZHRoOiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgICAgaGVpZ2h0OiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgZm9yY2VOYXR1cmFsU2l6ZSB8fFxuICAgICAgLy8gaWYgdXNlci1jcmVhdGVkIGJvdW5kaW5nIGJveCBpcyBiZWxvdyB0aHJlc2hvbGQsIGFzc3VtZSB0aGVcbiAgICAgIC8vIGludGVudGlvbiB3YXMgdG8gY2xpY2sgaW5zdGVhZCBvZiBkcmFnLCBhbmQgdXNlIHRoZSBpbWFnZSdzXG4gICAgICAvLyBpbnRyaW5zaWMgc2l6ZVxuICAgICAgKGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICkge1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5oZWlnaHQgLSAxMjAsIDE2MCk7XG4gICAgICAvLyBtYXggNjUlIG9mIGNhbnZhcyBoZWlnaHQsIGNsYW1wZWQgdG8gPDMwMHB4LCB2aCAtIDEyMHB4PlxuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gTWF0aC5taW4oXG4gICAgICAgIG1pbkhlaWdodCxcbiAgICAgICAgTWF0aC5mbG9vcih0aGlzLnN0YXRlLmhlaWdodCAqIDAuNSkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1pbihpbWFnZS5uYXR1cmFsSGVpZ2h0LCBtYXhIZWlnaHQpO1xuICAgICAgY29uc3Qgd2lkdGggPSBoZWlnaHQgKiAoaW1hZ2UubmF0dXJhbFdpZHRoIC8gaW1hZ2UubmF0dXJhbEhlaWdodCk7XG5cbiAgICAgIC8vIGFkZCBjdXJyZW50IGltYWdlRWxlbWVudCB3aWR0aC9oZWlnaHQgdG8gYWNjb3VudCBmb3IgcHJldmlvdXMgY2VudGVyaW5nXG4gICAgICAvLyBvZiB0aGUgcGxhY2hvbGRlciBpbWFnZVxuICAgICAgY29uc3QgeCA9IGltYWdlRWxlbWVudC54ICsgaW1hZ2VFbGVtZW50LndpZHRoIC8gMiAtIHdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IHkgPSBpbWFnZUVsZW1lbnQueSArIGltYWdlRWxlbWVudC5oZWlnaHQgLyAyIC0gaGVpZ2h0IC8gMjtcblxuICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHsgeCwgeSwgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIHVwZGF0ZXMgaW1hZ2UgY2FjaGUsIHJlZnJlc2hpbmcgdXBkYXRlZCBlbGVtZW50cyBhbmQvb3Igc2V0dGluZyBzdGF0dXNcbiAgICAgIHRvIGVycm9yIGZvciBpbWFnZXMgdGhhdCBmYWlsIGR1cmluZyA8aW1nPiBlbGVtZW50IGNyZWF0aW9uICovXG4gIHByaXZhdGUgdXBkYXRlSW1hZ2VDYWNoZSA9IGFzeW5jIChcbiAgICBlbGVtZW50czogcmVhZG9ubHkgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10sXG4gICAgZmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcywgZXJyb3JlZEZpbGVzIH0gPSBhd2FpdCBfdXBkYXRlSW1hZ2VDYWNoZSh7XG4gICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICBmaWxlSWRzOiBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IGVsZW1lbnQuZmlsZUlkKSxcbiAgICAgIGZpbGVzLFxuICAgIH0pO1xuICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSB8fCBlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKSB7XG4gICAgICAgIGlmICh1cGRhdGVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKSkge1xuICAgICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVycm9yZWRGaWxlcy5zaXplKSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgICBlcnJvcmVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9O1xuICB9O1xuXG4gIC8qKiBhZGRzIG5ldyBpbWFnZXMgdG8gaW1hZ2VDYWNoZSBhbmQgcmUtcmVuZGVycyBpZiBuZWVkZWQgKi9cbiAgcHJpdmF0ZSBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgaW1hZ2VFbGVtZW50czogSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10gPSBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgKSxcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB1bmNhY2hlZEltYWdlRWxlbWVudHMgPSBpbWFnZUVsZW1lbnRzLmZpbHRlcihcbiAgICAgIChlbGVtZW50KSA9PiAhZWxlbWVudC5pc0RlbGV0ZWQgJiYgIXRoaXMuaW1hZ2VDYWNoZS5oYXMoZWxlbWVudC5maWxlSWQpLFxuICAgICk7XG5cbiAgICBpZiAodW5jYWNoZWRJbWFnZUVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29uc3QgeyB1cGRhdGVkRmlsZXMgfSA9IGF3YWl0IHRoaXMudXBkYXRlSW1hZ2VDYWNoZShcbiAgICAgICAgdW5jYWNoZWRJbWFnZUVsZW1lbnRzLFxuICAgICAgICBmaWxlcyxcbiAgICAgICk7XG4gICAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5pbmZvcm1NdXRhdGlvbigpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKiogZ2VuZXJhbGx5IHlvdSBzaG91bGQgdXNlIGBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKWAgZGlyZWN0bHkgaWYgeW91IG5lZWRcbiAgICogIHRvIHJlbmRlciBuZXcgaW1hZ2VzLiBUaGlzIGlzIGp1c3QgYSBmYWlsc2FmZSAgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZUltYWdlUmVmcmVzaCA9IHRocm90dGxlKCgpID0+IHtcbiAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICB9LCBJTUFHRV9SRU5ERVJfVElNRU9VVCk7XG5cbiAgcHJpdmF0ZSB1cGRhdGVCaW5kaW5nRW5hYmxlZE9uUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGNvbnN0IHNob3VsZEVuYWJsZUJpbmRpbmcgPSBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50KGV2ZW50KTtcbiAgICBpZiAodGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkICE9PSBzaG91bGRFbmFibGVCaW5kaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogc2hvdWxkRW5hYmxlQmluZGluZyB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3IgPSAocG9pbnRlckNvb3Jkczoge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gIH0pOiB2b2lkID0+IHtcbiAgICBjb25zdCBob3ZlcmVkQmluZGFibGVFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOlxuICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgPyBbaG92ZXJlZEJpbmRhYmxlRWxlbWVudF0gOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzID0gKFxuICAgIGxpbmVhckVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIC8qKiBzY2VuZSBjb29yZHMgKi9cbiAgICBwb2ludGVyQ29vcmRzOiB7XG4gICAgICB4OiBudW1iZXI7XG4gICAgICB5OiBudW1iZXI7XG4gICAgfVtdLFxuICAgIC8vIER1cmluZyBsaW5lIGNyZWF0aW9uIHRoZSBzdGFydCBiaW5kaW5nIGhhc24ndCBiZWVuIHdyaXR0ZW4geWV0XG4gICAgLy8gaW50byBgbGluZWFyRWxlbWVudGBcbiAgICBvcHBvc2l0ZUJpbmRpbmdCb3VuZEVsZW1lbnQ/OiBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50IHwgbnVsbCxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKCFwb2ludGVyQ29vcmRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN1Z2dlc3RlZEJpbmRpbmdzID0gcG9pbnRlckNvb3Jkcy5yZWR1Y2UoXG4gICAgICAoYWNjOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQ+W10sIGNvb3JkcykgPT4ge1xuICAgICAgICBjb25zdCBob3ZlcmVkQmluZGFibGVFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgICAgIGNvb3JkcyxcbiAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCAhPSBudWxsICYmXG4gICAgICAgICAgIWlzTGluZWFyRWxlbWVudFNpbXBsZUFuZEFscmVhZHlCb3VuZChcbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBvcHBvc2l0ZUJpbmRpbmdCb3VuZEVsZW1lbnQ/LmlkLFxuICAgICAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCxcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIGFjYy5wdXNoKGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgW10sXG4gICAgKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoXG4gICAgc2VsZWN0ZWRFbGVtZW50czogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD5bXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3MgfSk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgIC8vIENvbnRpbnVlIGVkaXRpbmcgdGhlIHNhbWUgZ3JvdXAgaWYgdGhlIHVzZXIgc2VsZWN0ZWQgYSBkaWZmZXJlbnRcbiAgICAgIC8vIGVsZW1lbnQgZnJvbSBpdFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6XG4gICAgICAgIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICBoaXRFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgPyBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWRcbiAgICAgICAgICA6IG51bGwsXG4gICAgfSkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUmVmID0gKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQpID0+IHtcbiAgICAvLyBjYW52YXMgaXMgbnVsbCB3aGVuIHVubW91bnRpbmdcbiAgICBpZiAoY2FudmFzICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICAgIHRoaXMucmMgPSByb3VnaC5jYW52YXModGhpcy5jYW52YXMpO1xuXG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsLCB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9FTkQsIHRoaXMub25UYXBFbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5XSEVFTCwgdGhpcy5oYW5kbGVXaGVlbCk7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9TVEFSVCwgdGhpcy5vblRhcFN0YXJ0KTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQXBwT25Ecm9wID0gYXN5bmMgKGV2ZW50OiBSZWFjdC5EcmFnRXZlbnQ8SFRNTERpdkVsZW1lbnQ+KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGZpbGUgPSBldmVudC5kYXRhVHJhbnNmZXIuZmlsZXNbMF07XG5cbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICAvLyBmaXJzdCBhdHRlbXB0IHRvIGRlY29kZSBzY2VuZSBmcm9tIHRoZSBpbWFnZSBpZiBpdCdzIGVtYmVkZGVkXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGlmIChmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnBuZyB8fCBmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlRmlsZVN5c3RlbVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBvbmx5IHdvcmsgYXMgb2YgQ2hyb21lIDg2LFxuICAgICAgICAgICAgICAgIC8vIGJ1dCBjYW4gYmUgc2FmZWx5IGlnbm9yZWQgb24gb2xkZXIgcmVsZWFzZXMuXG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IGV2ZW50LmRhdGFUcmFuc2Zlci5pdGVtc1swXTtcbiAgICAgICAgICAgICAgICAoZmlsZSBhcyBhbnkpLmhhbmRsZSA9IGF3YWl0IChcbiAgICAgICAgICAgICAgICAgIGl0ZW0gYXMgYW55XG4gICAgICAgICAgICAgICAgKS5nZXRBc0ZpbGVTeXN0ZW1IYW5kbGUoKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvci5uYW1lLCBlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzY2VuZSA9IGF3YWl0IGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAuLi4oc2NlbmUuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJFbmNvZGluZ0Vycm9yXCIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm8gc2NlbmUgaXMgZW1iZWRkZWQgb3Igd2UgZmFpbCBmb3Igd2hhdGV2ZXIgcmVhc29uLCBmYWxsIGJhY2tcbiAgICAgICAgLy8gdG8gaW1wb3J0aW5nIGFzIHJlZ3VsYXIgaW1hZ2VcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBsaWJyYXJ5U2hhcGVzID0gZXZlbnQuZGF0YVRyYW5zZmVyLmdldERhdGEoTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliKTtcbiAgICBpZiAobGlicmFyeVNoYXBlcyAhPT0gXCJcIikge1xuICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgIGVsZW1lbnRzOiBKU09OLnBhcnNlKGxpYnJhcnlTaGFwZXMpLFxuICAgICAgICBwb3NpdGlvbjogZXZlbnQsXG4gICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZSA9IGV2ZW50LmRhdGFUcmFuc2Zlcj8uZmlsZXNbMF07XG4gICAgaWYgKFxuICAgICAgZmlsZT8udHlwZSA9PT0gTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliIHx8XG4gICAgICBmaWxlPy5uYW1lPy5lbmRzV2l0aChcIi5leGNhbGlkcmF3bGliXCIpXG4gICAgKSB7XG4gICAgICB0aGlzLmxpYnJhcnlcbiAgICAgICAgLmltcG9ydExpYnJhcnkoZmlsZSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIENsb3NlIGFuZCB0aGVuIG9wZW4gdG8gZ2V0IHRoZSBsaWJyYXJpZXMgdXBkYXRlZFxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiBmYWxzZSB9KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogdHJ1ZSB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT5cbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiBmYWxzZSwgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pLFxuICAgICAgICApO1xuICAgICAgLy8gZGVmYXVsdDogYXNzdW1lIGFuIEV4Y2FsaWRyYXcgZmlsZSByZWdhcmRsZXNzIG9mIGV4dGVuc2lvbi9NaW1lVHlwZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgaWYgKG5hdGl2ZUZpbGVTeXN0ZW1TdXBwb3J0ZWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBUaGlzIHdpbGwgb25seSB3b3JrIGFzIG9mIENocm9tZSA4NixcbiAgICAgICAgICAvLyBidXQgY2FuIGJlIHNhZmVseSBpZ25vcmVkIG9uIG9sZGVyIHJlbGVhc2VzLlxuICAgICAgICAgIGNvbnN0IGl0ZW0gPSBldmVudC5kYXRhVHJhbnNmZXIuaXRlbXNbMF07XG4gICAgICAgICAgKGZpbGUgYXMgYW55KS5oYW5kbGUgPSBhd2FpdCAoaXRlbSBhcyBhbnkpLmdldEFzRmlsZVN5c3RlbUhhbmRsZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGVycm9yLm5hbWUsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmxvYWRGaWxlVG9DYW52YXMoZmlsZSk7XG4gICAgfVxuICB9O1xuXG4gIGxvYWRGaWxlVG9DYW52YXMgPSAoZmlsZTogQmxvYikgPT4ge1xuICAgIGxvYWRGcm9tQmxvYihmaWxlLCB0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKVxuICAgICAgLnRoZW4oKHNjZW5lKSA9PiB7XG4gICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgLi4uc2NlbmUsXG4gICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IGZhbHNlLCBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0NvbnRleHRNZW51ID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHsgcHJlZmVyU2VsZWN0ZWQ6IHRydWUgfSk7XG5cbiAgICBjb25zdCB0eXBlID0gZWxlbWVudCA/IFwiZWxlbWVudFwiIDogXCJjYW52YXNcIjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ITtcbiAgICBjb25zdCB7IHRvcDogb2Zmc2V0VG9wLCBsZWZ0OiBvZmZzZXRMZWZ0IH0gPVxuICAgICAgY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGxlZnQgPSBldmVudC5jbGllbnRYIC0gb2Zmc2V0TGVmdDtcbiAgICBjb25zdCB0b3AgPSBldmVudC5jbGllbnRZIC0gb2Zmc2V0VG9wO1xuXG4gICAgaWYgKGVsZW1lbnQgJiYgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2VsZW1lbnQuaWRdKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9IH0sICgpID0+IHtcbiAgICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZURyYWdOZXdHZW5lcmljRWxlbWVudCA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZHJhZ2dpbmdFbGVtZW50LnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyQ29vcmRzLngpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LCBwb2ludGVyQ29vcmRzLnkpLFxuICAgICAgICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZSA9XG4gICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSAmJlxuICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGRyYWdnaW5nRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcbiAgICAgIGNvbnN0IGFzcGVjdFJhdGlvID1cbiAgICAgICAgaW1hZ2UgJiYgIShpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpXG4gICAgICAgICAgPyBpbWFnZS53aWR0aCAvIGltYWdlLmhlaWdodFxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueSxcbiAgICAgICAgZ3JpZFgsXG4gICAgICAgIGdyaWRZLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC54LCBncmlkWCksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksIGdyaWRZKSxcbiAgICAgICAgaXNJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICAgIGFzcGVjdFJhdGlvLFxuICAgICAgKTtcblxuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKFtkcmFnZ2luZ0VsZW1lbnRdKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZUhhbmRsZVJlc2l6ZSA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGU7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAvLyBUT0RPOiByZW5hbWUgdGhpcyBzdGF0ZSBmaWVsZCB0byBcImlzU2NhbGluZ1wiIHRvIGRpc3Rpbmd1aXNoXG4gICAgICAvLyBpdCBmcm9tIHRoZSBnZW5lcmljIFwiaXNSZXNpemluZ1wiIHdoaWNoIGluY2x1ZGVzIHNjYWxpbmcgYW5kXG4gICAgICAvLyByb3RhdGluZ1xuICAgICAgaXNSZXNpemluZzogdHJhbnNmb3JtSGFuZGxlVHlwZSAmJiB0cmFuc2Zvcm1IYW5kbGVUeXBlICE9PSBcInJvdGF0aW9uXCIsXG4gICAgICBpc1JvdGF0aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlID09PSBcInJvdGF0aW9uXCIsXG4gICAgfSk7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBjb25zdCBbcmVzaXplWCwgcmVzaXplWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQueCxcbiAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGlmIChcbiAgICAgIHRyYW5zZm9ybUVsZW1lbnRzKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbixcbiAgICAgICAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNJbWFnZUVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHJlc2l6ZVgsXG4gICAgICAgIHJlc2l6ZVksXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5jZW50ZXIueSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLyoqIEBwcml2YXRlIHVzZSB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51ICovXG4gIHByaXZhdGUgX29wZW5Db250ZXh0TWVudSA9IChcbiAgICB7XG4gICAgICBsZWZ0LFxuICAgICAgdG9wLFxuICAgIH06IHtcbiAgICAgIGxlZnQ6IG51bWJlcjtcbiAgICAgIHRvcDogbnVtYmVyO1xuICAgIH0sXG4gICAgdHlwZTogXCJjYW52YXNcIiB8IFwiZWxlbWVudFwiLFxuICApID0+IHtcbiAgICBjb25zdCBtYXliZUdyb3VwQWN0aW9uID0gYWN0aW9uR3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlVW5ncm91cEFjdGlvbiA9IGFjdGlvblVuZ3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcEhvcml6b250YWwgPSBhY3Rpb25GbGlwSG9yaXpvbnRhbC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3QgbWF5YmVGbGlwVmVydGljYWwgPSBhY3Rpb25GbGlwVmVydGljYWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IHNlcGFyYXRvciA9IFwic2VwYXJhdG9yXCI7XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcblxuICAgIGNvbnN0IG9wdGlvbnM6IENvbnRleHRNZW51T3B0aW9uW10gPSBbXTtcbiAgICBpZiAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1BuZyk7XG4gICAgfVxuXG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1N2Zyk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSBcImNhbnZhc1wiKSB7XG4gICAgICBjb25zdCB2aWV3TW9kZU9wdGlvbnMgPSBbXG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJiBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gICAgICBdO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogdmlld01vZGVPcHRpb25zLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiZcbiAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBhY3Rpb25Db3B5QXNQbmcsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmXG4gICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgYWN0aW9uQ29weUFzU3ZnLFxuICAgICAgICAgICAgKChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB8fFxuICAgICAgICAgICAgICAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSkgJiZcbiAgICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uU2VsZWN0QWxsLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZWxlbWVudFwiKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogW25hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSwgLi4ub3B0aW9uc10sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiYgYWN0aW9uQ3V0LFxuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25Db3B5U3R5bGVzLFxuICAgICAgICAgICAgYWN0aW9uUGFzdGVTdHlsZXMsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBtYXliZUdyb3VwQWN0aW9uICYmIGFjdGlvbkdyb3VwLFxuICAgICAgICAgICAgbWF5YmVVbmdyb3VwQWN0aW9uICYmIGFjdGlvblVuZ3JvdXAsXG4gICAgICAgICAgICAobWF5YmVHcm91cEFjdGlvbiB8fCBtYXliZVVuZ3JvdXBBY3Rpb24pICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgICAgICAgICAgIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgICAgICAgICAgIGFjdGlvblNlbmRUb0JhY2ssXG4gICAgICAgICAgICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBtYXliZUZsaXBIb3Jpem9udGFsICYmIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICAgICAgICAgICAgbWF5YmVGbGlwVmVydGljYWwgJiYgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICAgICAgICAgICAgKG1heWJlRmxpcEhvcml6b250YWwgfHwgbWF5YmVGbGlwVmVydGljYWwpICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgICAgICAgICAgIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVXaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGVsdGFYLCBkZWx0YVkgfSA9IGV2ZW50O1xuICAgIGNvbnN0IHsgc2VsZWN0ZWRFbGVtZW50SWRzLCBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyB9ID0gdGhpcy5zdGF0ZTtcbiAgICAvLyBub3RlIHRoYXQgZXZlbnQuY3RybEtleSBpcyBuZWNlc3NhcnkgdG8gaGFuZGxlIHBpbmNoIHpvb21pbmdcbiAgICBpZiAoZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5KSB7XG4gICAgICBjb25zdCBzaWduID0gTWF0aC5zaWduKGRlbHRhWSk7XG4gICAgICBjb25zdCBNQVhfU1RFUCA9IDEwO1xuICAgICAgbGV0IGRlbHRhID0gTWF0aC5hYnMoZGVsdGFZKTtcbiAgICAgIGlmIChkZWx0YSA+IE1BWF9TVEVQKSB7XG4gICAgICAgIGRlbHRhID0gTUFYX1NURVA7XG4gICAgICB9XG4gICAgICBkZWx0YSAqPSBzaWduO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzKS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCAxMDAwKTtcbiAgICAgIH1cblxuICAgICAgbGV0IG5ld1pvb20gPSB0aGlzLnN0YXRlLnpvb20udmFsdWUgLSBkZWx0YSAvIDEwMDtcbiAgICAgIC8vIGluY3JlYXNlIHpvb20gc3RlcHMgdGhlIG1vcmUgem9vbWVkLWluIHdlIGFyZSAoYXBwbGllcyB0byA+MTAwJSBvbmx5KVxuICAgICAgbmV3Wm9vbSArPSBNYXRoLmxvZzEwKE1hdGgubWF4KDEsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpICogLXNpZ247XG4gICAgICAvLyByb3VuZCB0byBuZWFyZXN0IHN0ZXBcbiAgICAgIG5ld1pvb20gPSBNYXRoLnJvdW5kKG5ld1pvb20gKiBaT09NX1NURVAgKiAxMDApIC8gKFpPT01fU1RFUCAqIDEwMCk7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pID0+ICh7XG4gICAgICAgIHpvb206IGdldE5ld1pvb20oXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZFpvb20obmV3Wm9vbSksXG4gICAgICAgICAgem9vbSxcbiAgICAgICAgICB7IGxlZnQ6IG9mZnNldExlZnQsIHRvcDogb2Zmc2V0VG9wIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgeDogY3Vyc29yWCxcbiAgICAgICAgICAgIHk6IGN1cnNvclksXG4gICAgICAgICAgfSxcbiAgICAgICAgKSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6XG4gICAgICAgICAgT2JqZWN0LmtleXMoc2VsZWN0ZWRFbGVtZW50SWRzKS5sZW5ndGggIT09IDBcbiAgICAgICAgICAgID8gc2VsZWN0ZWRFbGVtZW50SWRzXG4gICAgICAgICAgICA6IHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc2Nyb2xsIGhvcml6b250YWxseSB3aGVuIHNoaWZ0IHByZXNzZWRcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCB9KSA9PiAoe1xuICAgICAgICAvLyBvbiBNYWMsIHNoaWZ0K3doZWVsIHRlbmRzIHRvIHJlc3VsdCBpbiBkZWx0YVhcbiAgICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIChkZWx0YVkgfHwgZGVsdGFYKSAvIHpvb20udmFsdWUsXG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZIH0pID0+ICh7XG4gICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gZGVsdGFYIC8gem9vbS52YWx1ZSxcbiAgICAgIHNjcm9sbFk6IHNjcm9sbFkgLSBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBnZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICAgIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICAgIHNjYWxlOiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IGVsZW1lbnRDbGlja2VkSW5zaWRlID0gZ2V0RWxlbWVudENvbnRhaW5pbmdQb3NpdGlvbihcbiAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+ICFpc1RleHRFbGVtZW50KGVsZW1lbnQpKSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICk7XG4gICAgaWYgKGVsZW1lbnRDbGlja2VkSW5zaWRlKSB7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWCA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnggKyBlbGVtZW50Q2xpY2tlZEluc2lkZS53aWR0aCAvIDI7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWSA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnkgKyBlbGVtZW50Q2xpY2tlZEluc2lkZS5oZWlnaHQgLyAyO1xuICAgICAgY29uc3QgZGlzdGFuY2VUb0NlbnRlciA9IE1hdGguaHlwb3QoXG4gICAgICAgIHggLSBlbGVtZW50Q2VudGVyWCxcbiAgICAgICAgeSAtIGVsZW1lbnRDZW50ZXJZLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzU25hcHBlZFRvQ2VudGVyID1cbiAgICAgICAgZGlzdGFuY2VUb0NlbnRlciA8IFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xEO1xuICAgICAgaWYgKGlzU25hcHBlZFRvQ2VudGVyKSB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7IHNjZW5lWDogZWxlbWVudENlbnRlclgsIHNjZW5lWTogZWxlbWVudENlbnRlclkgfSxcbiAgICAgICAgICBhcHBTdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgdmlld3BvcnRYLCB2aWV3cG9ydFksIGVsZW1lbnRDZW50ZXJYLCBlbGVtZW50Q2VudGVyWSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2F2ZVBvaW50ZXIgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIGJ1dHRvbjogXCJ1cFwiIHwgXCJkb3duXCIpID0+IHtcbiAgICBpZiAoIXggfHwgIXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKGlzTmFOKHBvaW50ZXIueCkgfHwgaXNOYU4ocG9pbnRlci55KSkge1xuICAgICAgLy8gc29tZXRpbWVzIHRoZSBwb2ludGVyIGdvZXMgb2ZmIHNjcmVlblxuICAgIH1cblxuICAgIHRoaXMucHJvcHMub25Qb2ludGVyVXBkYXRlPy4oe1xuICAgICAgcG9pbnRlcixcbiAgICAgIGJ1dHRvbixcbiAgICAgIHBvaW50ZXJzTWFwOiBnZXN0dXJlLnBvaW50ZXJzLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQgPSBkZWJvdW5jZSgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLnVubW91bnRlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3VsZENhY2hlSWdub3JlWm9vbTogZmFsc2UgfSk7XG4gICAgfVxuICB9LCAzMDApO1xuXG4gIHByaXZhdGUgdXBkYXRlRE9NUmVjdCA9IChjYj86ICgpID0+IHZvaWQpID0+IHtcbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICBjb25zdCBleGNhbGlkcmF3Q29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IG9mZnNldExlZnQsXG4gICAgICAgIHRvcDogb2Zmc2V0VG9wLFxuICAgICAgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoOiBjdXJyZW50V2lkdGgsXG4gICAgICAgIGhlaWdodDogY3VycmVudEhlaWdodCxcbiAgICAgICAgb2Zmc2V0VG9wOiBjdXJyZW50T2Zmc2V0VG9wLFxuICAgICAgICBvZmZzZXRMZWZ0OiBjdXJyZW50T2Zmc2V0TGVmdCxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHdpZHRoID09PSBjdXJyZW50V2lkdGggJiZcbiAgICAgICAgaGVpZ2h0ID09PSBjdXJyZW50SGVpZ2h0ICYmXG4gICAgICAgIG9mZnNldExlZnQgPT09IGN1cnJlbnRPZmZzZXRMZWZ0ICYmXG4gICAgICAgIG9mZnNldFRvcCA9PT0gY3VycmVudE9mZnNldFRvcFxuICAgICAgKSB7XG4gICAgICAgIGlmIChjYikge1xuICAgICAgICAgIGNiKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIG9mZnNldExlZnQsXG4gICAgICAgICAgb2Zmc2V0VG9wLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY2IgJiYgY2IoKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyByZWZyZXNoID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSB9KTtcbiAgfTtcblxuICBwcml2YXRlIGdldENhbnZhc09mZnNldHMoKTogUGljazxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXRMZWZ0OiBsZWZ0LFxuICAgICAgICBvZmZzZXRUb3A6IHRvcCxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRMZWZ0OiAwLFxuICAgICAgb2Zmc2V0VG9wOiAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUxhbmd1YWdlKCkge1xuICAgIGNvbnN0IGN1cnJlbnRMYW5nID1cbiAgICAgIGxhbmd1YWdlcy5maW5kKChsYW5nKSA9PiBsYW5nLmNvZGUgPT09IHRoaXMucHJvcHMubGFuZ0NvZGUpIHx8XG4gICAgICBkZWZhdWx0TGFuZztcbiAgICBhd2FpdCBzZXRMYW5ndWFnZShjdXJyZW50TGFuZyk7XG4gICAgdGhpcy5zZXRBcHBTdGF0ZSh7fSk7XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRFU1QgSE9PS1Ncbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgaDoge1xuICAgICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgICBzdGF0ZTogQXBwU3RhdGU7XG4gICAgICBzZXRTdGF0ZTogUmVhY3QuQ29tcG9uZW50PGFueSwgQXBwU3RhdGU+W1wic2V0U3RhdGVcIl07XG4gICAgICBhcHA6IEluc3RhbmNlVHlwZTx0eXBlb2YgQXBwPjtcbiAgICAgIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gICAgfTtcbiAgfVxufVxuXG5pZiAoXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4pIHtcbiAgd2luZG93LmggPSB3aW5kb3cuaCB8fCAoe30gYXMgV2luZG93W1wiaFwiXSk7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICBlbGVtZW50czoge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHAuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gICAgICB9LFxuICAgICAgc2V0KGVsZW1lbnRzOiBFeGNhbGlkcmF3RWxlbWVudFtdKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcC5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cbmV4cG9ydCBkZWZhdWx0IEFwcDtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
1787
1787
 
1788
1788
  /***/ }),
1789
1789
 
@@ -2542,7 +2542,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2542
2542
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2543
2543
 
2544
2544
  "use strict";
2545
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"textWysiwyg\": () => (/* binding */ textWysiwyg)\n/* harmony export */ });\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst normalizeText = (text) => {\r\n return (text\r\n // replace tabs with spaces so they render and measure correctly\r\n .replace(/\\t/g, \" \")\r\n // normalize newlines\r\n .replace(/\\r?\\n|\\r/g, \"\\n\"));\r\n};\r\nconst getTransform = (width, height, angle, appState, maxWidth, maxHeight) => {\r\n const { zoom, offsetTop, offsetLeft } = appState;\r\n const degree = (180 * angle) / Math.PI;\r\n // offsets must be multiplied by 2 to account for the division by 2 of\r\n // the whole expression afterwards\r\n let translateX = ((width - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n let translateY = ((height - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n if (width > maxWidth && zoom.value !== 1) {\r\n translateX = ((maxWidth - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n }\r\n if (height > maxHeight && zoom.value !== 1) {\r\n translateY = ((maxHeight - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n }\r\n return `translate(${translateX}px, ${translateY}px) scale(${zoom.value}) rotate(${degree}deg)`;\r\n};\r\nconst textWysiwyg = ({ id, appState, onChange, onSubmit, getViewportCoords, element, canvas, excalidrawContainer, }) => {\r\n const textPropertiesUpdated = (updatedElement, editable) => {\r\n const currentFont = editable.style.fontFamily.replaceAll('\"', \"\");\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontFamilyString)({ fontFamily: updatedElement.fontFamily }) !==\r\n currentFont) {\r\n return true;\r\n }\r\n if (`${updatedElement.fontSize}px` !== editable.style.fontSize) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n let originalContainerHeight;\r\n let approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(element)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(element))\r\n : 0;\r\n const updateWysiwygStyle = () => {\r\n var _a, _b;\r\n const updatedElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(id);\r\n if (updatedElement && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)) {\r\n let coordX = updatedElement.x;\r\n let coordY = updatedElement.y;\r\n let container = (updatedElement === null || updatedElement === void 0 ? void 0 : updatedElement.containerId)\r\n ? _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement).getElement(updatedElement.containerId)\r\n : null;\r\n let maxWidth = updatedElement.width;\r\n let maxHeight = updatedElement.height;\r\n let width = updatedElement.width;\r\n const height = editable.scrollHeight === 0\r\n ? updatedElement.height\r\n : editable.scrollHeight;\r\n if (container && updatedElement.containerId) {\r\n const propertiesUpdated = textPropertiesUpdated(updatedElement, editable);\r\n if (propertiesUpdated) {\r\n const currentContainer = (_b = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement)) === null || _b === void 0 ? void 0 : _b.getElement(updatedElement.containerId);\r\n approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement))\r\n : 0;\r\n if (updatedElement.height > currentContainer.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2) {\r\n const nextHeight = updatedElement.height + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n originalContainerHeight = nextHeight;\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: nextHeight });\r\n container = Object.assign(Object.assign({}, container), { height: nextHeight });\r\n }\r\n editable.style.height = `${updatedElement.height}px`;\r\n }\r\n if (!originalContainerHeight) {\r\n originalContainerHeight = container.height;\r\n }\r\n maxWidth = container.width - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n maxHeight = container.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n width = maxWidth;\r\n // The coordinates of text box set a distance of\r\n // 30px to preserve padding\r\n coordX = container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING;\r\n // autogrow container height if text exceeds\r\n if (editable.scrollHeight > maxHeight) {\r\n const diff = Math.min(editable.scrollHeight - maxHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height + diff });\r\n return;\r\n }\r\n else if (\r\n // autoshrink container height until original container height\r\n // is reached when text is removed\r\n container.height > originalContainerHeight &&\r\n editable.scrollHeight < maxHeight) {\r\n const diff = Math.min(maxHeight - editable.scrollHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height - diff });\r\n }\r\n // Start pushing text upward until a diff of 30px (padding)\r\n // is reached\r\n else {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n if (lines > 1 || propertiesUpdated) {\r\n // vertically center align the text\r\n coordY =\r\n container.y + container.height / 2 - editable.scrollHeight / 2;\r\n }\r\n }\r\n }\r\n const [viewportX, viewportY] = getViewportCoords(coordX, coordY);\r\n const { textAlign, angle } = updatedElement;\r\n editable.value = updatedElement.originalText || updatedElement.text;\r\n const lines = updatedElement.originalText.split(\"\\n\");\r\n const lineHeight = updatedElement.containerId\r\n ? approxLineHeight\r\n : updatedElement.height / lines.length;\r\n if (!container) {\r\n maxWidth =\r\n (appState.width - appState.offsetLeft - viewportX - 8) / appState.zoom.value -\r\n // margin-right of parent if any\r\n Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2));\r\n }\r\n // Make sure text editor height doesn't go beyond viewport\r\n const editorMaxHeight = (appState.height - appState.offsetTop - viewportY) / appState.zoom.value;\r\n console.log({ maxWidth, editorMaxHeight, width, height, viewportX, viewportY });\r\n Object.assign(editable.style, {\r\n font: (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement),\r\n // must be defined *after* font ¯\\_(ツ)_/¯\r\n lineHeight: `${lineHeight}px`,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n left: `${viewportX}px`,\r\n top: `${viewportY}px`,\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight),\r\n textAlign,\r\n color: updatedElement.strokeColor,\r\n opacity: updatedElement.opacity / 100,\r\n filter: \"var(--theme-filter)\",\r\n maxWidth: `${maxWidth}px`,\r\n maxHeight: `${editorMaxHeight}px`,\r\n });\r\n }\r\n };\r\n const editable = document.createElement(\"textarea\");\r\n editable.dir = \"auto\";\r\n editable.tabIndex = 0;\r\n editable.dataset.type = \"wysiwyg\";\r\n // prevent line wrapping on Safari\r\n editable.wrap = \"off\";\r\n editable.classList.add(\"excalidraw-wysiwyg\");\r\n let whiteSpace = \"pre\";\r\n let wordBreak = \"normal\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element)) {\r\n whiteSpace = \"pre-wrap\";\r\n wordBreak = \"break-word\";\r\n }\r\n Object.assign(editable.style, {\r\n position: \"absolute\",\r\n display: \"inline-block\",\r\n minHeight: \"1em\",\r\n backfaceVisibility: \"hidden\",\r\n margin: 0,\r\n padding: 0,\r\n border: 0,\r\n outline: 0,\r\n resize: \"none\",\r\n background: \"transparent\",\r\n overflow: \"hidden\",\r\n // must be specified because in dark mode canvas creates a stacking context\r\n zIndex: \"var(--zIndex-wysiwyg)\",\r\n wordBreak,\r\n // prevent line wrapping (`whitespace: nowrap` doesn't work on FF)\r\n whiteSpace,\r\n overflowWrap: \"break-word\",\r\n });\r\n updateWysiwygStyle();\r\n if (onChange) {\r\n editable.oninput = () => {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n // auto increase height only when lines > 1 so its\r\n // measured correctly and vertically alignes for\r\n // first line as well as setting height to \"auto\"\r\n // doubles the height as soon as user starts typing\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element) && lines > 1) {\r\n editable.style.height = \"auto\";\r\n editable.style.height = `${editable.scrollHeight}px`;\r\n }\r\n onChange(normalizeText(editable.value));\r\n };\r\n }\r\n editable.onkeydown = (event) => {\r\n event.stopPropagation();\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ESCAPE) {\r\n event.preventDefault();\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ENTER && event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD]) {\r\n event.preventDefault();\r\n if (event.isComposing || event.keyCode === 229) {\r\n return;\r\n }\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.TAB ||\r\n (event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD] &&\r\n (event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT ||\r\n event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_RIGHT))) {\r\n event.preventDefault();\r\n if (event.shiftKey || event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT) {\r\n outdent();\r\n }\r\n else {\r\n indent();\r\n }\r\n // We must send an input event to resize the element\r\n editable.dispatchEvent(new Event(\"input\"));\r\n }\r\n };\r\n const TAB_SIZE = 4;\r\n const TAB = \" \".repeat(TAB_SIZE);\r\n const RE_LEADING_TAB = new RegExp(`^ {1,${TAB_SIZE}}`);\r\n const indent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex);\r\n value = `${startValue}${TAB}${endValue}`;\r\n });\r\n editable.value = value;\r\n editable.selectionStart = selectionStart + TAB_SIZE;\r\n editable.selectionEnd = selectionEnd + TAB_SIZE * linesStartIndices.length;\r\n };\r\n const outdent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n const removedTabs = [];\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const tabMatch = value\r\n .slice(startIndex, startIndex + TAB_SIZE)\r\n .match(RE_LEADING_TAB);\r\n if (tabMatch) {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex + tabMatch[0].length);\r\n // Delete a tab from the line\r\n value = `${startValue}${endValue}`;\r\n removedTabs.push(startIndex);\r\n }\r\n });\r\n editable.value = value;\r\n if (removedTabs.length) {\r\n if (selectionStart > removedTabs[removedTabs.length - 1]) {\r\n editable.selectionStart = Math.max(selectionStart - TAB_SIZE, removedTabs[removedTabs.length - 1]);\r\n }\r\n else {\r\n // If the cursor is before the first tab removed, ex:\r\n // Line| #1\r\n // Line #2\r\n // Lin|e #3\r\n // we should reset the selectionStart to his initial value.\r\n editable.selectionStart = selectionStart;\r\n }\r\n editable.selectionEnd = Math.max(editable.selectionStart, selectionEnd - TAB_SIZE * removedTabs.length);\r\n }\r\n };\r\n /**\r\n * @returns indeces of start positions of selected lines, in reverse order\r\n */\r\n const getSelectedLinesStartIndices = () => {\r\n let { selectionStart, selectionEnd, value } = editable;\r\n // chars before selectionStart on the same line\r\n const startOffset = value.slice(0, selectionStart).match(/[^\\n]*$/)[0]\r\n .length;\r\n // put caret at the start of the line\r\n selectionStart = selectionStart - startOffset;\r\n const selected = value.slice(selectionStart, selectionEnd);\r\n return selected\r\n .split(\"\\n\")\r\n .reduce((startIndices, line, idx, lines) => startIndices.concat(idx\r\n ? // curr line index is prev line's start + prev line's length + \\n\r\n startIndices[idx - 1] + lines[idx - 1].length + 1\r\n : // first selected line\r\n selectionStart), [])\r\n .reverse();\r\n };\r\n const stopEvent = (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n };\r\n // using a state variable instead of passing it to the handleSubmit callback\r\n // so that we don't need to create separate a callback for event handlers\r\n let submittedViaKeyboard = false;\r\n const handleSubmit = () => {\r\n var _a, _b;\r\n // cleanup must be run before onSubmit otherwise when app blurs the wysiwyg\r\n // it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the\r\n // wysiwyg on update\r\n cleanup();\r\n const updateElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(element.id);\r\n if (!updateElement) {\r\n return;\r\n }\r\n let wrappedText = \"\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && (updateElement === null || updateElement === void 0 ? void 0 : updateElement.containerId)) {\r\n const container = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updateElement).getElement(updateElement.containerId);\r\n if (container) {\r\n wrappedText = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.wrapText)(editable.value, (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updateElement), container.width);\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && updateElement.containerId) {\r\n const editorHeight = Number(editable.style.height.slice(0, -2));\r\n if (editable.value) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(updateElement, {\r\n // vertically center align\r\n y: container.y + container.height / 2 - editorHeight / 2,\r\n height: editorHeight,\r\n width: Number(editable.style.width.slice(0, -2)),\r\n // preserve padding\r\n x: container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING,\r\n });\r\n const boundTextElementId = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getBoundTextElementId)(container);\r\n if (!boundTextElementId || boundTextElementId !== element.id) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (container.boundElements || []).concat({\r\n type: \"text\",\r\n id: element.id,\r\n }),\r\n });\r\n }\r\n }\r\n else {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (_b = container.boundElements) === null || _b === void 0 ? void 0 : _b.filter((ele) => ele.type !== \"text\"),\r\n });\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n wrappedText = editable.value;\r\n }\r\n onSubmit({\r\n text: normalizeText(wrappedText),\r\n viaKeyboard: submittedViaKeyboard,\r\n originalText: editable.value,\r\n });\r\n };\r\n const cleanup = () => {\r\n if (isDestroyed) {\r\n return;\r\n }\r\n isDestroyed = true;\r\n // remove events to ensure they don't late-fire\r\n editable.onblur = null;\r\n editable.oninput = null;\r\n editable.onkeydown = null;\r\n if (observer) {\r\n observer.disconnect();\r\n }\r\n window.removeEventListener(\"resize\", updateWysiwygStyle);\r\n window.removeEventListener(\"wheel\", stopEvent, true);\r\n window.removeEventListener(\"pointerdown\", onPointerDown);\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n window.removeEventListener(\"blur\", handleSubmit);\r\n unbindUpdate();\r\n editable.remove();\r\n };\r\n const bindBlurEvent = (event) => {\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n // Deferred so that the pointerdown that initiates the wysiwyg doesn't\r\n // trigger the blur on ensuing pointerup.\r\n // Also to handle cases such as picking a color which would trigger a blur\r\n // in that same tick.\r\n const target = event === null || event === void 0 ? void 0 : event.target;\r\n const isTargetColorPicker = target instanceof HTMLInputElement &&\r\n target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(target);\r\n setTimeout(() => {\r\n editable.onblur = handleSubmit;\r\n if (target && isTargetColorPicker) {\r\n target.onblur = () => {\r\n editable.focus();\r\n };\r\n }\r\n // case: clicking on the same property → no change → no update → no focus\r\n if (!isTargetColorPicker) {\r\n editable.focus();\r\n }\r\n });\r\n };\r\n // prevent blur when changing properties from the menu\r\n const onPointerDown = (event) => {\r\n const isTargetColorPicker = event.target instanceof HTMLInputElement &&\r\n event.target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target);\r\n if (((event.target instanceof HTMLElement ||\r\n event.target instanceof SVGElement) &&\r\n event.target.closest(`.${_constants__WEBPACK_IMPORTED_MODULE_4__.CLASSES.SHAPE_ACTIONS_MENU}`) &&\r\n !(0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target)) ||\r\n isTargetColorPicker) {\r\n editable.onblur = null;\r\n window.addEventListener(\"pointerup\", bindBlurEvent);\r\n // handle edge-case where pointerup doesn't fire e.g. due to user\r\n // alt-tabbing away\r\n window.addEventListener(\"blur\", handleSubmit);\r\n }\r\n };\r\n // handle updates of textElement properties of editing element\r\n const unbindUpdate = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element).addCallback(() => {\r\n var _a;\r\n updateWysiwygStyle();\r\n const isColorPickerActive = !!((_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest(\".color-picker-input\"));\r\n if (!isColorPickerActive) {\r\n editable.focus();\r\n }\r\n });\r\n // ---------------------------------------------------------------------------\r\n let isDestroyed = false;\r\n // select on init (focusing is done separately inside the bindBlurEvent()\r\n // because we need it to happen *after* the blur event from `pointerdown`)\r\n editable.select();\r\n bindBlurEvent();\r\n // reposition wysiwyg in case of canvas is resized. Using ResizeObserver\r\n // is preferred so we catch changes from host, where window may not resize.\r\n let observer = null;\r\n if (canvas && \"ResizeObserver\" in window) {\r\n observer = new window.ResizeObserver(() => {\r\n updateWysiwygStyle();\r\n });\r\n observer.observe(canvas);\r\n }\r\n else {\r\n window.addEventListener(\"resize\", updateWysiwygStyle);\r\n }\r\n window.addEventListener(\"pointerdown\", onPointerDown);\r\n window.addEventListener(\"wheel\", stopEvent, {\r\n passive: false,\r\n capture: true,\r\n });\r\n excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.querySelector(\".excalidraw-textEditorContainer\").appendChild(editable);\r\n};\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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SSxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBRXhCLHlFQUF5RTtJQUN6RSwwRUFBMEU7SUFDMUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLGFBQWEsRUFBRSxDQUFDO0lBRWhCLHdFQUF3RTtJQUN4RSwyRUFBMkU7SUFDM0UsSUFBSSxRQUFRLEdBQTBCLElBQUksQ0FBQztJQUMzQyxJQUFJLE1BQU0sSUFBSSxnQkFBZ0IsSUFBSSxNQUFNLEVBQUU7UUFDeEMsUUFBUSxHQUFHLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUU7WUFDeEMsa0JBQWtCLEVBQUUsQ0FBQztRQUN2QixDQUFDLENBQUMsQ0FBQztRQUNILFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7S0FDMUI7U0FBTTtRQUNMLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztLQUN2RDtJQUVELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDdEQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUU7UUFDMUMsT0FBTyxFQUFFLEtBQUs7UUFDZCxPQUFPLEVBQUUsSUFBSTtLQUNkLENBQUMsQ0FBQztJQUNILG1CQUFtQixhQUFuQixtQkFBbUIsdUJBQW5CLG1CQUFtQixDQUNmLGFBQWEsQ0FBQyxpQ0FBaUMsRUFDaEQsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNCLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9lbGVtZW50L3RleHRXeXNpd3lnLnRzeD84ZjRkIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENPREVTLCBLRVlTIH0gZnJvbSBcIi4uL2tleXNcIjtcbmltcG9ydCB7XG4gIGlzV3JpdGFibGVFbGVtZW50LFxuICBnZXRGb250U3RyaW5nLFxuICBnZXRGb250RmFtaWx5U3RyaW5nLFxuICBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMsXG59IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IFNjZW5lIGZyb20gXCIuLi9zY2VuZS9TY2VuZVwiO1xuaW1wb3J0IHsgaXNCb3VuZFRvQ29udGFpbmVyLCBpc1RleHRFbGVtZW50IH0gZnJvbSBcIi4vdHlwZUNoZWNrc1wiO1xuaW1wb3J0IHsgQ0xBU1NFUywgUEFERElORyB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBBcHBTdGF0ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgbXV0YXRlRWxlbWVudCB9IGZyb20gXCIuL211dGF0ZUVsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGdldEFwcHJveExpbmVIZWlnaHQsXG4gIGdldEJvdW5kVGV4dEVsZW1lbnRJZCxcbiAgd3JhcFRleHQsXG59IGZyb20gXCIuL3RleHRFbGVtZW50XCI7XG5cbmNvbnN0IG5vcm1hbGl6ZVRleHQgPSAodGV4dDogc3RyaW5nKSA9PiB7XG4gIHJldHVybiAoXG4gICAgdGV4dFxuICAgICAgLy8gcmVwbGFjZSB0YWJzIHdpdGggc3BhY2VzIHNvIHRoZXkgcmVuZGVyIGFuZCBtZWFzdXJlIGNvcnJlY3RseVxuICAgICAgLnJlcGxhY2UoL1xcdC9nLCBcIiAgICAgICAgXCIpXG4gICAgICAvLyBub3JtYWxpemUgbmV3bGluZXNcbiAgICAgIC5yZXBsYWNlKC9cXHI/XFxufFxcci9nLCBcIlxcblwiKVxuICApO1xufTtcblxuY29uc3QgZ2V0VHJhbnNmb3JtID0gKFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgYW5nbGU6IG51bWJlcixcbiAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICBtYXhXaWR0aDogbnVtYmVyLFxuICBtYXhIZWlnaHQ6IG51bWJlcixcbikgPT4ge1xuICBjb25zdCB7IHpvb20sIG9mZnNldFRvcCwgb2Zmc2V0TGVmdCB9ID0gYXBwU3RhdGU7XG4gIGNvbnN0IGRlZ3JlZSA9ICgxODAgKiBhbmdsZSkgLyBNYXRoLlBJO1xuICAvLyBvZmZzZXRzIG11c3QgYmUgbXVsdGlwbGllZCBieSAyIHRvIGFjY291bnQgZm9yIHRoZSBkaXZpc2lvbiBieSAyIG9mXG4gIC8vIHRoZSB3aG9sZSBleHByZXNzaW9uIGFmdGVyd2FyZHNcbiAgbGV0IHRyYW5zbGF0ZVggPSAoKHdpZHRoIC0gb2Zmc2V0TGVmdCAqIDIpICogKHpvb20udmFsdWUgLSAxKSkgLyAyO1xuICBsZXQgdHJhbnNsYXRlWSA9ICgoaGVpZ2h0IC0gb2Zmc2V0VG9wICogMikgKiAoem9vbS52YWx1ZSAtIDEpKSAvIDI7XG4gIGlmICh3aWR0aCA+IG1heFdpZHRoICYmIHpvb20udmFsdWUgIT09IDEpIHtcbiAgICB0cmFuc2xhdGVYID0gKChtYXhXaWR0aCAtIG9mZnNldExlZnQgKiAyKSAqICh6b29tLnZhbHVlIC0gMSkpIC8gMlxuICB9XG4gIGlmIChoZWlnaHQgPiBtYXhIZWlnaHQgJiYgem9vbS52YWx1ZSAhPT0gMSkge1xuICAgIHRyYW5zbGF0ZVkgPSAoKG1heEhlaWdodCAtIG9mZnNldFRvcCAqIDIpICogKHpvb20udmFsdWUgLSAxKSkgLyAyO1xuICB9XG4gIHJldHVybiBgdHJhbnNsYXRlKCR7dHJhbnNsYXRlWH1weCwgJHt0cmFuc2xhdGVZfXB4KSBzY2FsZSgke3pvb20udmFsdWV9KSByb3RhdGUoJHtkZWdyZWV9ZGVnKWA7XG59O1xuXG5leHBvcnQgY29uc3QgdGV4dFd5c2l3eWcgPSAoe1xuICBpZCxcbiAgYXBwU3RhdGUsXG4gIG9uQ2hhbmdlLFxuICBvblN1Ym1pdCxcbiAgZ2V0Vmlld3BvcnRDb29yZHMsXG4gIGVsZW1lbnQsXG4gIGNhbnZhcyxcbiAgZXhjYWxpZHJhd0NvbnRhaW5lcixcbn06IHtcbiAgaWQ6IEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl07XG4gIGFwcFN0YXRlOiBBcHBTdGF0ZTtcbiAgb25DaGFuZ2U/OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuICBvblN1Ym1pdDogKGRhdGE6IHtcbiAgICB0ZXh0OiBzdHJpbmc7XG4gICAgdmlhS2V5Ym9hcmQ6IGJvb2xlYW47XG4gICAgb3JpZ2luYWxUZXh0OiBzdHJpbmc7XG4gIH0pID0+IHZvaWQ7XG4gIGdldFZpZXdwb3J0Q29vcmRzOiAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IFtudW1iZXIsIG51bWJlcl07XG4gIGVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50O1xuICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbDtcbiAgZXhjYWxpZHJhd0NvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xufSkgPT4ge1xuICBjb25zdCB0ZXh0UHJvcGVydGllc1VwZGF0ZWQgPSAoXG4gICAgdXBkYXRlZEVsZW1lbnQ6IEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgICBlZGl0YWJsZTogSFRNTFRleHRBcmVhRWxlbWVudCxcbiAgKSA9PiB7XG4gICAgY29uc3QgY3VycmVudEZvbnQgPSBlZGl0YWJsZS5zdHlsZS5mb250RmFtaWx5LnJlcGxhY2VBbGwoJ1wiJywgXCJcIik7XG4gICAgaWYgKFxuICAgICAgZ2V0Rm9udEZhbWlseVN0cmluZyh7IGZvbnRGYW1pbHk6IHVwZGF0ZWRFbGVtZW50LmZvbnRGYW1pbHkgfSkgIT09XG4gICAgICBjdXJyZW50Rm9udFxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChgJHt1cGRhdGVkRWxlbWVudC5mb250U2l6ZX1weGAgIT09IGVkaXRhYmxlLnN0eWxlLmZvbnRTaXplKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICBsZXQgb3JpZ2luYWxDb250YWluZXJIZWlnaHQ6IG51bWJlcjtcbiAgbGV0IGFwcHJveExpbmVIZWlnaHQgPSBpc1RleHRFbGVtZW50KGVsZW1lbnQpXG4gICAgPyBnZXRBcHByb3hMaW5lSGVpZ2h0KGdldEZvbnRTdHJpbmcoZWxlbWVudCkpXG4gICAgOiAwO1xuXG4gIGNvbnN0IHVwZGF0ZVd5c2l3eWdTdHlsZSA9ICgpID0+IHtcbiAgICBjb25zdCB1cGRhdGVkRWxlbWVudCA9IFNjZW5lLmdldFNjZW5lKGVsZW1lbnQpPy5nZXRFbGVtZW50KGlkKTtcbiAgICBpZiAodXBkYXRlZEVsZW1lbnQgJiYgaXNUZXh0RWxlbWVudCh1cGRhdGVkRWxlbWVudCkpIHtcbiAgICAgIGxldCBjb29yZFggPSB1cGRhdGVkRWxlbWVudC54O1xuICAgICAgbGV0IGNvb3JkWSA9IHVwZGF0ZWRFbGVtZW50Lnk7XG4gICAgICBsZXQgY29udGFpbmVyID0gdXBkYXRlZEVsZW1lbnQ/LmNvbnRhaW5lcklkXG4gICAgICAgID8gU2NlbmUuZ2V0U2NlbmUodXBkYXRlZEVsZW1lbnQpIS5nZXRFbGVtZW50KHVwZGF0ZWRFbGVtZW50LmNvbnRhaW5lcklkKVxuICAgICAgICA6IG51bGw7XG4gICAgICBsZXQgbWF4V2lkdGggPSB1cGRhdGVkRWxlbWVudC53aWR0aDtcblxuICAgICAgbGV0IG1heEhlaWdodCA9IHVwZGF0ZWRFbGVtZW50LmhlaWdodDtcbiAgICAgIGxldCB3aWR0aCA9IHVwZGF0ZWRFbGVtZW50LndpZHRoO1xuICAgICAgY29uc3QgaGVpZ2h0ID1cbiAgICAgICAgZWRpdGFibGUuc2Nyb2xsSGVpZ2h0ID09PSAwXG4gICAgICAgICAgPyB1cGRhdGVkRWxlbWVudC5oZWlnaHRcbiAgICAgICAgICA6IGVkaXRhYmxlLnNjcm9sbEhlaWdodDtcbiAgICAgIGlmIChjb250YWluZXIgJiYgdXBkYXRlZEVsZW1lbnQuY29udGFpbmVySWQpIHtcbiAgICAgICAgY29uc3QgcHJvcGVydGllc1VwZGF0ZWQgPSB0ZXh0UHJvcGVydGllc1VwZGF0ZWQoXG4gICAgICAgICAgdXBkYXRlZEVsZW1lbnQsXG4gICAgICAgICAgZWRpdGFibGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHByb3BlcnRpZXNVcGRhdGVkKSB7XG4gICAgICAgICAgY29uc3QgY3VycmVudENvbnRhaW5lciA9IFNjZW5lLmdldFNjZW5lKHVwZGF0ZWRFbGVtZW50KT8uZ2V0RWxlbWVudChcbiAgICAgICAgICAgIHVwZGF0ZWRFbGVtZW50LmNvbnRhaW5lcklkLFxuICAgICAgICAgICkgYXMgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudDtcbiAgICAgICAgICBhcHByb3hMaW5lSGVpZ2h0ID0gaXNUZXh0RWxlbWVudCh1cGRhdGVkRWxlbWVudClcbiAgICAgICAgICAgID8gZ2V0QXBwcm94TGluZUhlaWdodChnZXRGb250U3RyaW5nKHVwZGF0ZWRFbGVtZW50KSlcbiAgICAgICAgICAgIDogMDtcbiAgICAgICAgICBpZiAodXBkYXRlZEVsZW1lbnQuaGVpZ2h0ID4gY3VycmVudENvbnRhaW5lci5oZWlnaHQgLSBQQURESU5HICogMikge1xuICAgICAgICAgICAgY29uc3QgbmV4dEhlaWdodCA9IHVwZGF0ZWRFbGVtZW50LmhlaWdodCArIFBBRERJTkcgKiAyO1xuICAgICAgICAgICAgb3JpZ2luYWxDb250YWluZXJIZWlnaHQgPSBuZXh0SGVpZ2h0O1xuICAgICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBuZXh0SGVpZ2h0IH0pO1xuICAgICAgICAgICAgY29udGFpbmVyID0geyAuLi5jb250YWluZXIsIGhlaWdodDogbmV4dEhlaWdodCB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBlZGl0YWJsZS5zdHlsZS5oZWlnaHQgPSBgJHt1cGRhdGVkRWxlbWVudC5oZWlnaHR9cHhgO1xuICAgICAgICB9XG4gICAgICAgIGlmICghb3JpZ2luYWxDb250YWluZXJIZWlnaHQpIHtcbiAgICAgICAgICBvcmlnaW5hbENvbnRhaW5lckhlaWdodCA9IGNvbnRhaW5lci5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgbWF4V2lkdGggPSBjb250YWluZXIud2lkdGggLSBQQURESU5HICogMjtcbiAgICAgICAgbWF4SGVpZ2h0ID0gY29udGFpbmVyLmhlaWdodCAtIFBBRERJTkcgKiAyO1xuICAgICAgICB3aWR0aCA9IG1heFdpZHRoO1xuICAgICAgICAvLyBUaGUgY29vcmRpbmF0ZXMgb2YgdGV4dCBib3ggc2V0IGEgZGlzdGFuY2Ugb2ZcbiAgICAgICAgLy8gMzBweCB0byBwcmVzZXJ2ZSBwYWRkaW5nXG4gICAgICAgIGNvb3JkWCA9IGNvbnRhaW5lci54ICsgUEFERElORztcblxuICAgICAgICAvLyBhdXRvZ3JvdyBjb250YWluZXIgaGVpZ2h0IGlmIHRleHQgZXhjZWVkc1xuICAgICAgICBpZiAoZWRpdGFibGUuc2Nyb2xsSGVpZ2h0ID4gbWF4SGVpZ2h0KSB7XG4gICAgICAgICAgY29uc3QgZGlmZiA9IE1hdGgubWluKFxuICAgICAgICAgICAgZWRpdGFibGUuc2Nyb2xsSGVpZ2h0IC0gbWF4SGVpZ2h0LFxuICAgICAgICAgICAgYXBwcm94TGluZUhlaWdodCxcbiAgICAgICAgICApO1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7IGhlaWdodDogY29udGFpbmVyLmhlaWdodCArIGRpZmYgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIC8vIGF1dG9zaHJpbmsgY29udGFpbmVyIGhlaWdodCB1bnRpbCBvcmlnaW5hbCBjb250YWluZXIgaGVpZ2h0XG4gICAgICAgICAgLy8gaXMgcmVhY2hlZCB3aGVuIHRleHQgaXMgcmVtb3ZlZFxuICAgICAgICAgIGNvbnRhaW5lci5oZWlnaHQgPiBvcmlnaW5hbENvbnRhaW5lckhlaWdodCAmJlxuICAgICAgICAgIGVkaXRhYmxlLnNjcm9sbEhlaWdodCA8IG1heEhlaWdodFxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBkaWZmID0gTWF0aC5taW4oXG4gICAgICAgICAgICBtYXhIZWlnaHQgLSBlZGl0YWJsZS5zY3JvbGxIZWlnaHQsXG4gICAgICAgICAgICBhcHByb3hMaW5lSGVpZ2h0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBjb250YWluZXIuaGVpZ2h0IC0gZGlmZiB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBTdGFydCBwdXNoaW5nIHRleHQgdXB3YXJkIHVudGlsIGEgZGlmZiBvZiAzMHB4IChwYWRkaW5nKVxuICAgICAgICAvLyBpcyByZWFjaGVkXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGxpbmVzID0gZWRpdGFibGUuc2Nyb2xsSGVpZ2h0IC8gYXBwcm94TGluZUhlaWdodDtcblxuICAgICAgICAgIGlmIChsaW5lcyA+IDEgfHwgcHJvcGVydGllc1VwZGF0ZWQpIHtcbiAgICAgICAgICAgIC8vIHZlcnRpY2FsbHkgY2VudGVyIGFsaWduIHRoZSB0ZXh0XG4gICAgICAgICAgICBjb29yZFkgPVxuICAgICAgICAgICAgICBjb250YWluZXIueSArIGNvbnRhaW5lci5oZWlnaHQgLyAyIC0gZWRpdGFibGUuc2Nyb2xsSGVpZ2h0IC8gMjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IFt2aWV3cG9ydFgsIHZpZXdwb3J0WV0gPSBnZXRWaWV3cG9ydENvb3Jkcyhjb29yZFgsIGNvb3JkWSk7XG4gICAgICBjb25zdCB7IHRleHRBbGlnbiwgYW5nbGUgfSA9IHVwZGF0ZWRFbGVtZW50O1xuXG4gICAgICBlZGl0YWJsZS52YWx1ZSA9IHVwZGF0ZWRFbGVtZW50Lm9yaWdpbmFsVGV4dCB8fCB1cGRhdGVkRWxlbWVudC50ZXh0O1xuICAgICAgY29uc3QgbGluZXMgPSB1cGRhdGVkRWxlbWVudC5vcmlnaW5hbFRleHQuc3BsaXQoXCJcXG5cIik7XG4gICAgICBjb25zdCBsaW5lSGVpZ2h0ID0gdXBkYXRlZEVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgPyBhcHByb3hMaW5lSGVpZ2h0XG4gICAgICAgIDogdXBkYXRlZEVsZW1lbnQuaGVpZ2h0IC8gbGluZXMubGVuZ3RoO1xuICAgICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgICAgbWF4V2lkdGggPVxuICAgICAgICAgICggYXBwU3RhdGUud2lkdGggLSBhcHBTdGF0ZS5vZmZzZXRMZWZ0IC0gdmlld3BvcnRYIC0gOCkgLyBhcHBTdGF0ZS56b29tLnZhbHVlIC1cbiAgICAgICAgICAvLyBtYXJnaW4tcmlnaHQgb2YgcGFyZW50IGlmIGFueVxuICAgICAgICAgIE51bWJlcihcbiAgICAgICAgICAgIGdldENvbXB1dGVkU3R5bGUoXG4gICAgICAgICAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI/LnBhcmVudE5vZGUgYXMgRWxlbWVudCxcbiAgICAgICAgICAgICkubWFyZ2luUmlnaHQuc2xpY2UoMCwgLTIpLFxuICAgICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIE1ha2Ugc3VyZSB0ZXh0IGVkaXRvciBoZWlnaHQgZG9lc24ndCBnbyBiZXlvbmQgdmlld3BvcnRcbiAgICAgIGNvbnN0IGVkaXRvck1heEhlaWdodCA9XG4gICAgICAgIChhcHBTdGF0ZS5oZWlnaHQgLSBhcHBTdGF0ZS5vZmZzZXRUb3AgLSB2aWV3cG9ydFkpIC8gYXBwU3RhdGUuem9vbS52YWx1ZTtcblxuICAgICAgY29uc29sZS5sb2coe21heFdpZHRoLGVkaXRvck1heEhlaWdodCx3aWR0aCxoZWlnaHQsdmlld3BvcnRYLHZpZXdwb3J0WX0pO1xuICAgICAgT2JqZWN0LmFzc2lnbihlZGl0YWJsZS5zdHlsZSwge1xuICAgICAgICBmb250OiBnZXRGb250U3RyaW5nKHVwZGF0ZWRFbGVtZW50KSxcbiAgICAgICAgLy8gbXVzdCBiZSBkZWZpbmVkICphZnRlciogZm9udCDCr1xcXyjjg4QpXy/Cr1xuICAgICAgICBsaW5lSGVpZ2h0OiBgJHtsaW5lSGVpZ2h0fXB4YCxcbiAgICAgICAgd2lkdGg6IGAke3dpZHRofXB4YCxcbiAgICAgICAgaGVpZ2h0OiBgJHtoZWlnaHR9cHhgLFxuICAgICAgICBsZWZ0OiBgJHt2aWV3cG9ydFh9cHhgLFxuICAgICAgICB0b3A6IGAke3ZpZXdwb3J0WX1weGAsXG4gICAgICAgIHRyYW5zZm9ybTogZ2V0VHJhbnNmb3JtKFxuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICBhbmdsZSxcbiAgICAgICAgICBhcHBTdGF0ZSxcbiAgICAgICAgICBtYXhXaWR0aCxcbiAgICAgICAgICBlZGl0b3JNYXhIZWlnaHQsXG4gICAgICAgICksXG4gICAgICAgIHRleHRBbGlnbixcbiAgICAgICAgY29sb3I6IHVwZGF0ZWRFbGVtZW50LnN0cm9rZUNvbG9yLFxuICAgICAgICBvcGFjaXR5OiB1cGRhdGVkRWxlbWVudC5vcGFjaXR5IC8gMTAwLFxuICAgICAgICBmaWx0ZXI6IFwidmFyKC0tdGhlbWUtZmlsdGVyKVwiLFxuICAgICAgICBtYXhXaWR0aDogYCR7bWF4V2lkdGh9cHhgLFxuICAgICAgICBtYXhIZWlnaHQ6IGAke2VkaXRvck1heEhlaWdodH1weGAsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZWRpdGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGV4dGFyZWFcIik7XG5cbiAgZWRpdGFibGUuZGlyID0gXCJhdXRvXCI7XG4gIGVkaXRhYmxlLnRhYkluZGV4ID0gMDtcbiAgZWRpdGFibGUuZGF0YXNldC50eXBlID0gXCJ3eXNpd3lnXCI7XG4gIC8vIHByZXZlbnQgbGluZSB3cmFwcGluZyBvbiBTYWZhcmlcbiAgZWRpdGFibGUud3JhcCA9IFwib2ZmXCI7XG4gIGVkaXRhYmxlLmNsYXNzTGlzdC5hZGQoXCJleGNhbGlkcmF3LXd5c2l3eWdcIik7XG5cbiAgbGV0IHdoaXRlU3BhY2UgPSBcInByZVwiO1xuICBsZXQgd29yZEJyZWFrID0gXCJub3JtYWxcIjtcblxuICBpZiAoaXNCb3VuZFRvQ29udGFpbmVyKGVsZW1lbnQpKSB7XG4gICAgd2hpdGVTcGFjZSA9IFwicHJlLXdyYXBcIjtcbiAgICB3b3JkQnJlYWsgPSBcImJyZWFrLXdvcmRcIjtcbiAgfVxuICBPYmplY3QuYXNzaWduKGVkaXRhYmxlLnN0eWxlLCB7XG4gICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICBkaXNwbGF5OiBcImlubGluZS1ibG9ja1wiLFxuICAgIG1pbkhlaWdodDogXCIxZW1cIixcbiAgICBiYWNrZmFjZVZpc2liaWxpdHk6IFwiaGlkZGVuXCIsXG4gICAgbWFyZ2luOiAwLFxuICAgIHBhZGRpbmc6IDAsXG4gICAgYm9yZGVyOiAwLFxuICAgIG91dGxpbmU6IDAsXG4gICAgcmVzaXplOiBcIm5vbmVcIixcbiAgICBiYWNrZ3JvdW5kOiBcInRyYW5zcGFyZW50XCIsXG4gICAgb3ZlcmZsb3c6IFwiaGlkZGVuXCIsXG4gICAgLy8gbXVzdCBiZSBzcGVjaWZpZWQgYmVjYXVzZSBpbiBkYXJrIG1vZGUgY2FudmFzIGNyZWF0ZXMgYSBzdGFja2luZyBjb250ZXh0XG4gICAgekluZGV4OiBcInZhcigtLXpJbmRleC13eXNpd3lnKVwiLFxuICAgIHdvcmRCcmVhayxcbiAgICAvLyBwcmV2ZW50IGxpbmUgd3JhcHBpbmcgKGB3aGl0ZXNwYWNlOiBub3dyYXBgIGRvZXNuJ3Qgd29yayBvbiBGRilcbiAgICB3aGl0ZVNwYWNlLFxuICAgIG92ZXJmbG93V3JhcDogXCJicmVhay13b3JkXCIsXG4gIH0pO1xuICB1cGRhdGVXeXNpd3lnU3R5bGUoKTtcblxuICBpZiAob25DaGFuZ2UpIHtcbiAgICBlZGl0YWJsZS5vbmlucHV0ID0gKCkgPT4ge1xuICAgICAgY29uc3QgbGluZXMgPSBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLyBhcHByb3hMaW5lSGVpZ2h0O1xuICAgICAgLy8gYXV0byBpbmNyZWFzZSBoZWlnaHQgb25seSB3aGVuIGxpbmVzICA+IDEgc28gaXRzXG4gICAgICAvLyBtZWFzdXJlZCBjb3JyZWN0bHkgYW5kIHZlcnRpY2FsbHkgYWxpZ25lcyBmb3JcbiAgICAgIC8vIGZpcnN0IGxpbmUgYXMgd2VsbCBhcyBzZXR0aW5nIGhlaWdodCB0byBcImF1dG9cIlxuICAgICAgLy8gZG91YmxlcyB0aGUgaGVpZ2h0IGFzIHNvb24gYXMgdXNlciBzdGFydHMgdHlwaW5nXG4gICAgICBpZiAoaXNCb3VuZFRvQ29udGFpbmVyKGVsZW1lbnQpICYmIGxpbmVzID4gMSkge1xuICAgICAgICBlZGl0YWJsZS5zdHlsZS5oZWlnaHQgPSBcImF1dG9cIjtcbiAgICAgICAgZWRpdGFibGUuc3R5bGUuaGVpZ2h0ID0gYCR7ZWRpdGFibGUuc2Nyb2xsSGVpZ2h0fXB4YDtcbiAgICAgIH1cbiAgICAgIG9uQ2hhbmdlKG5vcm1hbGl6ZVRleHQoZWRpdGFibGUudmFsdWUpKTtcbiAgICB9O1xuICB9XG5cbiAgZWRpdGFibGUub25rZXlkb3duID0gKGV2ZW50KSA9PiB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5FU0NBUEUpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBzdWJtaXR0ZWRWaWFLZXlib2FyZCA9IHRydWU7XG4gICAgICBoYW5kbGVTdWJtaXQoKTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5FTlRFUiAmJiBldmVudFtLRVlTLkNUUkxfT1JfQ01EXSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmIChldmVudC5pc0NvbXBvc2luZyB8fCBldmVudC5rZXlDb2RlID09PSAyMjkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3VibWl0dGVkVmlhS2V5Ym9hcmQgPSB0cnVlO1xuICAgICAgaGFuZGxlU3VibWl0KCk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGV2ZW50LmtleSA9PT0gS0VZUy5UQUIgfHxcbiAgICAgIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJlxuICAgICAgICAoZXZlbnQuY29kZSA9PT0gQ09ERVMuQlJBQ0tFVF9MRUZUIHx8XG4gICAgICAgICAgZXZlbnQuY29kZSA9PT0gQ09ERVMuQlJBQ0tFVF9SSUdIVCkpXG4gICAgKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5IHx8IGV2ZW50LmNvZGUgPT09IENPREVTLkJSQUNLRVRfTEVGVCkge1xuICAgICAgICBvdXRkZW50KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmRlbnQoKTtcbiAgICAgIH1cbiAgICAgIC8vIFdlIG11c3Qgc2VuZCBhbiBpbnB1dCBldmVudCB0byByZXNpemUgdGhlIGVsZW1lbnRcbiAgICAgIGVkaXRhYmxlLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIikpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBUQUJfU0laRSA9IDQ7XG4gIGNvbnN0IFRBQiA9IFwiIFwiLnJlcGVhdChUQUJfU0laRSk7XG4gIGNvbnN0IFJFX0xFQURJTkdfVEFCID0gbmV3IFJlZ0V4cChgXiB7MSwke1RBQl9TSVpFfX1gKTtcbiAgY29uc3QgaW5kZW50ID0gKCkgPT4ge1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCB9ID0gZWRpdGFibGU7XG4gICAgY29uc3QgbGluZXNTdGFydEluZGljZXMgPSBnZXRTZWxlY3RlZExpbmVzU3RhcnRJbmRpY2VzKCk7XG5cbiAgICBsZXQgdmFsdWUgPSBlZGl0YWJsZS52YWx1ZTtcbiAgICBsaW5lc1N0YXJ0SW5kaWNlcy5mb3JFYWNoKChzdGFydEluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0VmFsdWUgPSB2YWx1ZS5zbGljZSgwLCBzdGFydEluZGV4KTtcbiAgICAgIGNvbnN0IGVuZFZhbHVlID0gdmFsdWUuc2xpY2Uoc3RhcnRJbmRleCk7XG5cbiAgICAgIHZhbHVlID0gYCR7c3RhcnRWYWx1ZX0ke1RBQn0ke2VuZFZhbHVlfWA7XG4gICAgfSk7XG5cbiAgICBlZGl0YWJsZS52YWx1ZSA9IHZhbHVlO1xuXG4gICAgZWRpdGFibGUuc2VsZWN0aW9uU3RhcnQgPSBzZWxlY3Rpb25TdGFydCArIFRBQl9TSVpFO1xuICAgIGVkaXRhYmxlLnNlbGVjdGlvbkVuZCA9IHNlbGVjdGlvbkVuZCArIFRBQl9TSVpFICogbGluZXNTdGFydEluZGljZXMubGVuZ3RoO1xuICB9O1xuXG4gIGNvbnN0IG91dGRlbnQgPSAoKSA9PiB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kIH0gPSBlZGl0YWJsZTtcbiAgICBjb25zdCBsaW5lc1N0YXJ0SW5kaWNlcyA9IGdldFNlbGVjdGVkTGluZXNTdGFydEluZGljZXMoKTtcbiAgICBjb25zdCByZW1vdmVkVGFiczogbnVtYmVyW10gPSBbXTtcblxuICAgIGxldCB2YWx1ZSA9IGVkaXRhYmxlLnZhbHVlO1xuICAgIGxpbmVzU3RhcnRJbmRpY2VzLmZvckVhY2goKHN0YXJ0SW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHRhYk1hdGNoID0gdmFsdWVcbiAgICAgICAgLnNsaWNlKHN0YXJ0SW5kZXgsIHN0YXJ0SW5kZXggKyBUQUJfU0laRSlcbiAgICAgICAgLm1hdGNoKFJFX0xFQURJTkdfVEFCKTtcblxuICAgICAgaWYgKHRhYk1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VmFsdWUgPSB2YWx1ZS5zbGljZSgwLCBzdGFydEluZGV4KTtcbiAgICAgICAgY29uc3QgZW5kVmFsdWUgPSB2YWx1ZS5zbGljZShzdGFydEluZGV4ICsgdGFiTWF0Y2hbMF0ubGVuZ3RoKTtcblxuICAgICAgICAvLyBEZWxldGUgYSB0YWIgZnJvbSB0aGUgbGluZVxuICAgICAgICB2YWx1ZSA9IGAke3N0YXJ0VmFsdWV9JHtlbmRWYWx1ZX1gO1xuICAgICAgICByZW1vdmVkVGFicy5wdXNoKHN0YXJ0SW5kZXgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZWRpdGFibGUudmFsdWUgPSB2YWx1ZTtcblxuICAgIGlmIChyZW1vdmVkVGFicy5sZW5ndGgpIHtcbiAgICAgIGlmIChzZWxlY3Rpb25TdGFydCA+IHJlbW92ZWRUYWJzW3JlbW92ZWRUYWJzLmxlbmd0aCAtIDFdKSB7XG4gICAgICAgIGVkaXRhYmxlLnNlbGVjdGlvblN0YXJ0ID0gTWF0aC5tYXgoXG4gICAgICAgICAgc2VsZWN0aW9uU3RhcnQgLSBUQUJfU0laRSxcbiAgICAgICAgICByZW1vdmVkVGFic1tyZW1vdmVkVGFicy5sZW5ndGggLSAxXSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIHRoZSBjdXJzb3IgaXMgYmVmb3JlIHRoZSBmaXJzdCB0YWIgcmVtb3ZlZCwgZXg6XG4gICAgICAgIC8vIExpbmV8ICMxXG4gICAgICAgIC8vICAgICBMaW5lICMyXG4gICAgICAgIC8vIExpbnxlICMzXG4gICAgICAgIC8vIHdlIHNob3VsZCByZXNldCB0aGUgc2VsZWN0aW9uU3RhcnQgdG8gaGlzIGluaXRpYWwgdmFsdWUuXG4gICAgICAgIGVkaXRhYmxlLnNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQ7XG4gICAgICB9XG4gICAgICBlZGl0YWJsZS5zZWxlY3Rpb25FbmQgPSBNYXRoLm1heChcbiAgICAgICAgZWRpdGFibGUuc2VsZWN0aW9uU3RhcnQsXG4gICAgICAgIHNlbGVjdGlvbkVuZCAtIFRBQl9TSVpFICogcmVtb3ZlZFRhYnMubGVuZ3RoLFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIGluZGVjZXMgb2Ygc3RhcnQgcG9zaXRpb25zIG9mIHNlbGVjdGVkIGxpbmVzLCBpbiByZXZlcnNlIG9yZGVyXG4gICAqL1xuICBjb25zdCBnZXRTZWxlY3RlZExpbmVzU3RhcnRJbmRpY2VzID0gKCkgPT4ge1xuICAgIGxldCB7IHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQsIHZhbHVlIH0gPSBlZGl0YWJsZTtcblxuICAgIC8vIGNoYXJzIGJlZm9yZSBzZWxlY3Rpb25TdGFydCBvbiB0aGUgc2FtZSBsaW5lXG4gICAgY29uc3Qgc3RhcnRPZmZzZXQgPSB2YWx1ZS5zbGljZSgwLCBzZWxlY3Rpb25TdGFydCkubWF0Y2goL1teXFxuXSokLykhWzBdXG4gICAgICAubGVuZ3RoO1xuICAgIC8vIHB1dCBjYXJldCBhdCB0aGUgc3RhcnQgb2YgdGhlIGxpbmVcbiAgICBzZWxlY3Rpb25TdGFydCA9IHNlbGVjdGlvblN0YXJ0IC0gc3RhcnRPZmZzZXQ7XG5cbiAgICBjb25zdCBzZWxlY3RlZCA9IHZhbHVlLnNsaWNlKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpO1xuXG4gICAgcmV0dXJuIHNlbGVjdGVkXG4gICAgICAuc3BsaXQoXCJcXG5cIilcbiAgICAgIC5yZWR1Y2UoXG4gICAgICAgIChzdGFydEluZGljZXMsIGxpbmUsIGlkeCwgbGluZXMpID0+XG4gICAgICAgICAgc3RhcnRJbmRpY2VzLmNvbmNhdChcbiAgICAgICAgICAgIGlkeFxuICAgICAgICAgICAgICA/IC8vIGN1cnIgbGluZSBpbmRleCBpcyBwcmV2IGxpbmUncyBzdGFydCArIHByZXYgbGluZSdzIGxlbmd0aCArIFxcblxuICAgICAgICAgICAgICAgIHN0YXJ0SW5kaWNlc1tpZHggLSAxXSArIGxpbmVzW2lkeCAtIDFdLmxlbmd0aCArIDFcbiAgICAgICAgICAgICAgOiAvLyBmaXJzdCBzZWxlY3RlZCBsaW5lXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uU3RhcnQsXG4gICAgICAgICAgKSxcbiAgICAgICAgW10gYXMgbnVtYmVyW10sXG4gICAgICApXG4gICAgICAucmV2ZXJzZSgpO1xuICB9O1xuXG4gIGNvbnN0IHN0b3BFdmVudCA9IChldmVudDogRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9O1xuXG4gIC8vIHVzaW5nIGEgc3RhdGUgdmFyaWFibGUgaW5zdGVhZCBvZiBwYXNzaW5nIGl0IHRvIHRoZSBoYW5kbGVTdWJtaXQgY2FsbGJhY2tcbiAgLy8gc28gdGhhdCB3ZSBkb24ndCBuZWVkIHRvIGNyZWF0ZSBzZXBhcmF0ZSBhIGNhbGxiYWNrIGZvciBldmVudCBoYW5kbGVyc1xuICBsZXQgc3VibWl0dGVkVmlhS2V5Ym9hcmQgPSBmYWxzZTtcbiAgY29uc3QgaGFuZGxlU3VibWl0ID0gKCkgPT4ge1xuICAgIC8vIGNsZWFudXAgbXVzdCBiZSBydW4gYmVmb3JlIG9uU3VibWl0IG90aGVyd2lzZSB3aGVuIGFwcCBibHVycyB0aGUgd3lzaXd5Z1xuICAgIC8vIGl0J2QgZ2V0IHN0dWNrIGluIGFuIGluZmluaXRlIGxvb3Agb2YgYmx1cuKGkm9uU3VibWl0IGFmdGVyIHdlIHJlLWZvY3VzIHRoZVxuICAgIC8vIHd5c2l3eWcgb24gdXBkYXRlXG4gICAgY2xlYW51cCgpO1xuICAgIGNvbnN0IHVwZGF0ZUVsZW1lbnQgPSBTY2VuZS5nZXRTY2VuZShlbGVtZW50KT8uZ2V0RWxlbWVudChlbGVtZW50LmlkKTtcbiAgICBpZiAoIXVwZGF0ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHdyYXBwZWRUZXh0ID0gXCJcIjtcbiAgICBpZiAoaXNUZXh0RWxlbWVudCh1cGRhdGVFbGVtZW50KSAmJiB1cGRhdGVFbGVtZW50Py5jb250YWluZXJJZCkge1xuICAgICAgY29uc3QgY29udGFpbmVyID0gU2NlbmUuZ2V0U2NlbmUodXBkYXRlRWxlbWVudCkhLmdldEVsZW1lbnQoXG4gICAgICAgIHVwZGF0ZUVsZW1lbnQuY29udGFpbmVySWQsXG4gICAgICApIGFzIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQ7XG5cbiAgICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgd3JhcHBlZFRleHQgPSB3cmFwVGV4dChcbiAgICAgICAgICBlZGl0YWJsZS52YWx1ZSxcbiAgICAgICAgICBnZXRGb250U3RyaW5nKHVwZGF0ZUVsZW1lbnQpLFxuICAgICAgICAgIGNvbnRhaW5lci53aWR0aCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGlzVGV4dEVsZW1lbnQodXBkYXRlRWxlbWVudCkgJiYgdXBkYXRlRWxlbWVudC5jb250YWluZXJJZCkge1xuICAgICAgICAgIGNvbnN0IGVkaXRvckhlaWdodCA9IE51bWJlcihlZGl0YWJsZS5zdHlsZS5oZWlnaHQuc2xpY2UoMCwgLTIpKTtcbiAgICAgICAgICBpZiAoZWRpdGFibGUudmFsdWUpIHtcbiAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQodXBkYXRlRWxlbWVudCwge1xuICAgICAgICAgICAgICAvLyB2ZXJ0aWNhbGx5IGNlbnRlciBhbGlnblxuICAgICAgICAgICAgICB5OiBjb250YWluZXIueSArIGNvbnRhaW5lci5oZWlnaHQgLyAyIC0gZWRpdG9ySGVpZ2h0IC8gMixcbiAgICAgICAgICAgICAgaGVpZ2h0OiBlZGl0b3JIZWlnaHQsXG4gICAgICAgICAgICAgIHdpZHRoOiBOdW1iZXIoZWRpdGFibGUuc3R5bGUud2lkdGguc2xpY2UoMCwgLTIpKSxcbiAgICAgICAgICAgICAgLy8gcHJlc2VydmUgcGFkZGluZ1xuICAgICAgICAgICAgICB4OiBjb250YWluZXIueCArIFBBRERJTkcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGJvdW5kVGV4dEVsZW1lbnRJZCA9IGdldEJvdW5kVGV4dEVsZW1lbnRJZChjb250YWluZXIpO1xuICAgICAgICAgICAgaWYgKCFib3VuZFRleHRFbGVtZW50SWQgfHwgYm91bmRUZXh0RWxlbWVudElkICE9PSBlbGVtZW50LmlkKSB7XG4gICAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7XG4gICAgICAgICAgICAgICAgYm91bmRFbGVtZW50czogKGNvbnRhaW5lci5ib3VuZEVsZW1lbnRzIHx8IFtdKS5jb25jYXQoe1xuICAgICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgICBpZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7XG4gICAgICAgICAgICAgIGJvdW5kRWxlbWVudHM6IGNvbnRhaW5lci5ib3VuZEVsZW1lbnRzPy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgKGVsZSkgPT4gZWxlLnR5cGUgIT09IFwidGV4dFwiLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHdyYXBwZWRUZXh0ID0gZWRpdGFibGUudmFsdWU7XG4gICAgfVxuXG4gICAgb25TdWJtaXQoe1xuICAgICAgdGV4dDogbm9ybWFsaXplVGV4dCh3cmFwcGVkVGV4dCksXG4gICAgICB2aWFLZXlib2FyZDogc3VibWl0dGVkVmlhS2V5Ym9hcmQsXG4gICAgICBvcmlnaW5hbFRleHQ6IGVkaXRhYmxlLnZhbHVlLFxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNsZWFudXAgPSAoKSA9PiB7XG4gICAgaWYgKGlzRGVzdHJveWVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlzRGVzdHJveWVkID0gdHJ1ZTtcbiAgICAvLyByZW1vdmUgZXZlbnRzIHRvIGVuc3VyZSB0aGV5IGRvbid0IGxhdGUtZmlyZVxuICAgIGVkaXRhYmxlLm9uYmx1ciA9IG51bGw7XG4gICAgZWRpdGFibGUub25pbnB1dCA9IG51bGw7XG4gICAgZWRpdGFibGUub25rZXlkb3duID0gbnVsbDtcblxuICAgIGlmIChvYnNlcnZlcikge1xuICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHVwZGF0ZVd5c2l3eWdTdHlsZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ3aGVlbFwiLCBzdG9wRXZlbnQsIHRydWUpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9pbnRlcmRvd25cIiwgb25Qb2ludGVyRG93bik7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVydXBcIiwgYmluZEJsdXJFdmVudCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIGhhbmRsZVN1Ym1pdCk7XG5cbiAgICB1bmJpbmRVcGRhdGUoKTtcblxuICAgIGVkaXRhYmxlLnJlbW92ZSgpO1xuICB9O1xuXG4gIGNvbnN0IGJpbmRCbHVyRXZlbnQgPSAoZXZlbnQ/OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVydXBcIiwgYmluZEJsdXJFdmVudCk7XG4gICAgLy8gRGVmZXJyZWQgc28gdGhhdCB0aGUgcG9pbnRlcmRvd24gdGhhdCBpbml0aWF0ZXMgdGhlIHd5c2l3eWcgZG9lc24ndFxuICAgIC8vIHRyaWdnZXIgdGhlIGJsdXIgb24gZW5zdWluZyBwb2ludGVydXAuXG4gICAgLy8gQWxzbyB0byBoYW5kbGUgY2FzZXMgc3VjaCBhcyBwaWNraW5nIGEgY29sb3Igd2hpY2ggd291bGQgdHJpZ2dlciBhIGJsdXJcbiAgICAvLyBpbiB0aGF0IHNhbWUgdGljay5cbiAgICBjb25zdCB0YXJnZXQgPSBldmVudD8udGFyZ2V0O1xuXG4gICAgY29uc3QgaXNUYXJnZXRDb2xvclBpY2tlciA9XG4gICAgICB0YXJnZXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmXG4gICAgICB0YXJnZXQuY2xvc2VzdChcIi5jb2xvci1waWNrZXItaW5wdXRcIikgJiZcbiAgICAgIGlzV3JpdGFibGVFbGVtZW50KHRhcmdldCk7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGVkaXRhYmxlLm9uYmx1ciA9IGhhbmRsZVN1Ym1pdDtcbiAgICAgIGlmICh0YXJnZXQgJiYgaXNUYXJnZXRDb2xvclBpY2tlcikge1xuICAgICAgICB0YXJnZXQub25ibHVyID0gKCkgPT4ge1xuICAgICAgICAgIGVkaXRhYmxlLmZvY3VzKCk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBjYXNlOiBjbGlja2luZyBvbiB0aGUgc2FtZSBwcm9wZXJ0eSDihpIgbm8gY2hhbmdlIOKGkiBubyB1cGRhdGUg4oaSIG5vIGZvY3VzXG4gICAgICBpZiAoIWlzVGFyZ2V0Q29sb3JQaWNrZXIpIHtcbiAgICAgICAgZWRpdGFibGUuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvLyBwcmV2ZW50IGJsdXIgd2hlbiBjaGFuZ2luZyBwcm9wZXJ0aWVzIGZyb20gdGhlIG1lbnVcbiAgY29uc3Qgb25Qb2ludGVyRG93biA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgIGNvbnN0IGlzVGFyZ2V0Q29sb3JQaWNrZXIgPVxuICAgICAgZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJlxuICAgICAgZXZlbnQudGFyZ2V0LmNsb3Nlc3QoXCIuY29sb3ItcGlja2VyLWlucHV0XCIpICYmXG4gICAgICBpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpO1xuICAgIGlmIChcbiAgICAgICgoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHxcbiAgICAgICAgZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgU1ZHRWxlbWVudCkgJiZcbiAgICAgICAgZXZlbnQudGFyZ2V0LmNsb3Nlc3QoYC4ke0NMQVNTRVMuU0hBUEVfQUNUSU9OU19NRU5VfWApICYmXG4gICAgICAgICFpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpKSB8fFxuICAgICAgaXNUYXJnZXRDb2xvclBpY2tlclxuICAgICkge1xuICAgICAgZWRpdGFibGUub25ibHVyID0gbnVsbDtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicG9pbnRlcnVwXCIsIGJpbmRCbHVyRXZlbnQpO1xuICAgICAgLy8gaGFuZGxlIGVkZ2UtY2FzZSB3aGVyZSBwb2ludGVydXAgZG9lc24ndCBmaXJlIGUuZy4gZHVlIHRvIHVzZXJcbiAgICAgIC8vIGFsdC10YWJiaW5nIGF3YXlcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCBoYW5kbGVTdWJtaXQpO1xuICAgIH1cbiAgfTtcblxuICAvLyBoYW5kbGUgdXBkYXRlcyBvZiB0ZXh0RWxlbWVudCBwcm9wZXJ0aWVzIG9mIGVkaXRpbmcgZWxlbWVudFxuICBjb25zdCB1bmJpbmRVcGRhdGUgPSBTY2VuZS5nZXRTY2VuZShlbGVtZW50KSEuYWRkQ2FsbGJhY2soKCkgPT4ge1xuICAgIHVwZGF0ZVd5c2l3eWdTdHlsZSgpO1xuICAgIGNvbnN0IGlzQ29sb3JQaWNrZXJBY3RpdmUgPSAhIWRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ/LmNsb3Nlc3QoXG4gICAgICBcIi5jb2xvci1waWNrZXItaW5wdXRcIixcbiAgICApO1xuICAgIGlmICghaXNDb2xvclBpY2tlckFjdGl2ZSkge1xuICAgICAgZWRpdGFibGUuZm9jdXMoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIGxldCBpc0Rlc3Ryb3llZCA9IGZhbHNlO1xuXG4gIC8vIHNlbGVjdCBvbiBpbml0IChmb2N1c2luZyBpcyBkb25lIHNlcGFyYXRlbHkgaW5zaWRlIHRoZSBiaW5kQmx1ckV2ZW50KClcbiAgLy8gYmVjYXVzZSB3ZSBuZWVkIGl0IHRvIGhhcHBlbiAqYWZ0ZXIqIHRoZSBibHVyIGV2ZW50IGZyb20gYHBvaW50ZXJkb3duYClcbiAgZWRpdGFibGUuc2VsZWN0KCk7XG4gIGJpbmRCbHVyRXZlbnQoKTtcblxuICAvLyByZXBvc2l0aW9uIHd5c2l3eWcgaW4gY2FzZSBvZiBjYW52YXMgaXMgcmVzaXplZC4gVXNpbmcgUmVzaXplT2JzZXJ2ZXJcbiAgLy8gaXMgcHJlZmVycmVkIHNvIHdlIGNhdGNoIGNoYW5nZXMgZnJvbSBob3N0LCB3aGVyZSB3aW5kb3cgbWF5IG5vdCByZXNpemUuXG4gIGxldCBvYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcbiAgaWYgKGNhbnZhcyAmJiBcIlJlc2l6ZU9ic2VydmVyXCIgaW4gd2luZG93KSB7XG4gICAgb2JzZXJ2ZXIgPSBuZXcgd2luZG93LlJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIHVwZGF0ZVd5c2l3eWdTdHlsZSgpO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoY2FudmFzKTtcbiAgfSBlbHNlIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLCB1cGRhdGVXeXNpd3lnU3R5bGUpO1xuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwb2ludGVyZG93blwiLCBvblBvaW50ZXJEb3duKTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJ3aGVlbFwiLCBzdG9wRXZlbnQsIHtcbiAgICBwYXNzaXZlOiBmYWxzZSxcbiAgICBjYXB0dXJlOiB0cnVlLFxuICB9KTtcbiAgZXhjYWxpZHJhd0NvbnRhaW5lclxuICAgID8ucXVlcnlTZWxlY3RvcihcIi5leGNhbGlkcmF3LXRleHRFZGl0b3JDb250YWluZXJcIikhXG4gICAgLmFwcGVuZENoaWxkKGVkaXRhYmxlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../element/textWysiwyg.tsx\n");
2545
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"textWysiwyg\": () => (/* binding */ textWysiwyg)\n/* harmony export */ });\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst normalizeText = (text) => {\r\n return (text\r\n // replace tabs with spaces so they render and measure correctly\r\n .replace(/\\t/g, \" \")\r\n // normalize newlines\r\n .replace(/\\r?\\n|\\r/g, \"\\n\"));\r\n};\r\nconst getTransform = (width, height, angle, appState, maxWidth, maxHeight) => {\r\n const { zoom, offsetTop, offsetLeft } = appState;\r\n const degree = (180 * angle) / Math.PI;\r\n // offsets must be multiplied by 2 to account for the division by 2 of\r\n // the whole expression afterwards\r\n let translateX = ((width - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n let translateY = ((height - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n if (width > maxWidth && zoom.value !== 1) {\r\n translateX = ((maxWidth - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n }\r\n if (height > maxHeight && zoom.value !== 1) {\r\n translateY = ((maxHeight - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n }\r\n return `translate(${translateX}px, ${translateY}px) scale(${zoom.value}) rotate(${degree}deg)`;\r\n};\r\nconst textWysiwyg = ({ id, appState, onChange, onSubmit, getViewportCoords, element, canvas, excalidrawContainer, }) => {\r\n const textPropertiesUpdated = (updatedElement, editable) => {\r\n const currentFont = editable.style.fontFamily.replaceAll('\"', \"\");\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontFamilyString)({ fontFamily: updatedElement.fontFamily }) !==\r\n currentFont) {\r\n return true;\r\n }\r\n if (`${updatedElement.fontSize}px` !== editable.style.fontSize) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n let originalContainerHeight;\r\n let approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(element)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(element))\r\n : 0;\r\n const updateWysiwygStyle = () => {\r\n var _a, _b;\r\n const updatedElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(id);\r\n if (updatedElement && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)) {\r\n let coordX = updatedElement.x;\r\n let coordY = updatedElement.y;\r\n let container = (updatedElement === null || updatedElement === void 0 ? void 0 : updatedElement.containerId)\r\n ? _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement).getElement(updatedElement.containerId)\r\n : null;\r\n let maxWidth = updatedElement.width;\r\n let maxHeight = updatedElement.height;\r\n let width = updatedElement.width;\r\n const height = editable.scrollHeight === 0\r\n ? updatedElement.height\r\n : editable.scrollHeight;\r\n if (container && updatedElement.containerId) {\r\n const propertiesUpdated = textPropertiesUpdated(updatedElement, editable);\r\n if (propertiesUpdated) {\r\n const currentContainer = (_b = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement)) === null || _b === void 0 ? void 0 : _b.getElement(updatedElement.containerId);\r\n approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement))\r\n : 0;\r\n if (updatedElement.height > currentContainer.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2) {\r\n const nextHeight = updatedElement.height + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n originalContainerHeight = nextHeight;\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: nextHeight });\r\n container = Object.assign(Object.assign({}, container), { height: nextHeight });\r\n }\r\n editable.style.height = `${updatedElement.height}px`;\r\n }\r\n if (!originalContainerHeight) {\r\n originalContainerHeight = container.height;\r\n }\r\n maxWidth = container.width - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n maxHeight = container.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n width = maxWidth;\r\n // The coordinates of text box set a distance of\r\n // 30px to preserve padding\r\n coordX = container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING;\r\n // autogrow container height if text exceeds\r\n if (editable.scrollHeight > maxHeight) {\r\n const diff = Math.min(editable.scrollHeight - maxHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height + diff });\r\n return;\r\n }\r\n else if (\r\n // autoshrink container height until original container height\r\n // is reached when text is removed\r\n container.height > originalContainerHeight &&\r\n editable.scrollHeight < maxHeight) {\r\n const diff = Math.min(maxHeight - editable.scrollHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height - diff });\r\n }\r\n // Start pushing text upward until a diff of 30px (padding)\r\n // is reached\r\n else {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n if (lines > 1 || propertiesUpdated) {\r\n // vertically center align the text\r\n coordY =\r\n container.y + container.height / 2 - editable.scrollHeight / 2;\r\n }\r\n }\r\n }\r\n const [viewportX, viewportY] = getViewportCoords(coordX, coordY);\r\n const { textAlign, angle } = updatedElement;\r\n editable.value = updatedElement.originalText || updatedElement.text;\r\n const lines = updatedElement.originalText.split(\"\\n\");\r\n const lineHeight = updatedElement.containerId\r\n ? approxLineHeight\r\n : updatedElement.height / lines.length;\r\n if (!container) {\r\n maxWidth =\r\n (appState.width + appState.offsetLeft - viewportX - 8) / appState.zoom.value -\r\n // margin-right of parent if any\r\n Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2));\r\n }\r\n // Make sure text editor height doesn't go beyond viewport\r\n const editorMaxHeight = (appState.height + appState.offsetTop - viewportY) / appState.zoom.value;\r\n console.log({\r\n maxWidth,\r\n editorMaxHeight,\r\n width,\r\n height,\r\n viewportX,\r\n viewportY,\r\n appWidth: appState.width,\r\n appHeight: appState.height,\r\n scrollX: appState.scrollX,\r\n scrollY: appState.scrollY,\r\n offsetTop: appState.offsetTop,\r\n offsetLeft: appState.offsetLeft,\r\n marginRight: Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2)),\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight)\r\n });\r\n Object.assign(editable.style, {\r\n font: (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement),\r\n // must be defined *after* font ¯\\_(ツ)_/¯\r\n lineHeight: `${lineHeight}px`,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n left: `${viewportX}px`,\r\n top: `${viewportY}px`,\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight),\r\n textAlign,\r\n color: updatedElement.strokeColor,\r\n opacity: updatedElement.opacity / 100,\r\n filter: \"var(--theme-filter)\",\r\n maxWidth: `${maxWidth}px`,\r\n maxHeight: `${editorMaxHeight}px`,\r\n });\r\n }\r\n };\r\n const editable = document.createElement(\"textarea\");\r\n editable.dir = \"auto\";\r\n editable.tabIndex = 0;\r\n editable.dataset.type = \"wysiwyg\";\r\n // prevent line wrapping on Safari\r\n editable.wrap = \"off\";\r\n editable.classList.add(\"excalidraw-wysiwyg\");\r\n let whiteSpace = \"pre\";\r\n let wordBreak = \"normal\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element)) {\r\n whiteSpace = \"pre-wrap\";\r\n wordBreak = \"break-word\";\r\n }\r\n Object.assign(editable.style, {\r\n position: \"absolute\",\r\n display: \"inline-block\",\r\n minHeight: \"1em\",\r\n backfaceVisibility: \"hidden\",\r\n margin: 0,\r\n padding: 0,\r\n border: 0,\r\n outline: 0,\r\n resize: \"none\",\r\n background: \"transparent\",\r\n overflow: \"hidden\",\r\n // must be specified because in dark mode canvas creates a stacking context\r\n zIndex: \"var(--zIndex-wysiwyg)\",\r\n wordBreak,\r\n // prevent line wrapping (`whitespace: nowrap` doesn't work on FF)\r\n whiteSpace,\r\n overflowWrap: \"break-word\",\r\n });\r\n updateWysiwygStyle();\r\n if (onChange) {\r\n editable.oninput = () => {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n // auto increase height only when lines > 1 so its\r\n // measured correctly and vertically alignes for\r\n // first line as well as setting height to \"auto\"\r\n // doubles the height as soon as user starts typing\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element) && lines > 1) {\r\n editable.style.height = \"auto\";\r\n editable.style.height = `${editable.scrollHeight}px`;\r\n }\r\n onChange(normalizeText(editable.value));\r\n };\r\n }\r\n editable.onkeydown = (event) => {\r\n event.stopPropagation();\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ESCAPE) {\r\n event.preventDefault();\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ENTER && event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD]) {\r\n event.preventDefault();\r\n if (event.isComposing || event.keyCode === 229) {\r\n return;\r\n }\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.TAB ||\r\n (event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD] &&\r\n (event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT ||\r\n event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_RIGHT))) {\r\n event.preventDefault();\r\n if (event.shiftKey || event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT) {\r\n outdent();\r\n }\r\n else {\r\n indent();\r\n }\r\n // We must send an input event to resize the element\r\n editable.dispatchEvent(new Event(\"input\"));\r\n }\r\n };\r\n const TAB_SIZE = 4;\r\n const TAB = \" \".repeat(TAB_SIZE);\r\n const RE_LEADING_TAB = new RegExp(`^ {1,${TAB_SIZE}}`);\r\n const indent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex);\r\n value = `${startValue}${TAB}${endValue}`;\r\n });\r\n editable.value = value;\r\n editable.selectionStart = selectionStart + TAB_SIZE;\r\n editable.selectionEnd = selectionEnd + TAB_SIZE * linesStartIndices.length;\r\n };\r\n const outdent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n const removedTabs = [];\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const tabMatch = value\r\n .slice(startIndex, startIndex + TAB_SIZE)\r\n .match(RE_LEADING_TAB);\r\n if (tabMatch) {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex + tabMatch[0].length);\r\n // Delete a tab from the line\r\n value = `${startValue}${endValue}`;\r\n removedTabs.push(startIndex);\r\n }\r\n });\r\n editable.value = value;\r\n if (removedTabs.length) {\r\n if (selectionStart > removedTabs[removedTabs.length - 1]) {\r\n editable.selectionStart = Math.max(selectionStart - TAB_SIZE, removedTabs[removedTabs.length - 1]);\r\n }\r\n else {\r\n // If the cursor is before the first tab removed, ex:\r\n // Line| #1\r\n // Line #2\r\n // Lin|e #3\r\n // we should reset the selectionStart to his initial value.\r\n editable.selectionStart = selectionStart;\r\n }\r\n editable.selectionEnd = Math.max(editable.selectionStart, selectionEnd - TAB_SIZE * removedTabs.length);\r\n }\r\n };\r\n /**\r\n * @returns indeces of start positions of selected lines, in reverse order\r\n */\r\n const getSelectedLinesStartIndices = () => {\r\n let { selectionStart, selectionEnd, value } = editable;\r\n // chars before selectionStart on the same line\r\n const startOffset = value.slice(0, selectionStart).match(/[^\\n]*$/)[0]\r\n .length;\r\n // put caret at the start of the line\r\n selectionStart = selectionStart - startOffset;\r\n const selected = value.slice(selectionStart, selectionEnd);\r\n return selected\r\n .split(\"\\n\")\r\n .reduce((startIndices, line, idx, lines) => startIndices.concat(idx\r\n ? // curr line index is prev line's start + prev line's length + \\n\r\n startIndices[idx - 1] + lines[idx - 1].length + 1\r\n : // first selected line\r\n selectionStart), [])\r\n .reverse();\r\n };\r\n const stopEvent = (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n };\r\n // using a state variable instead of passing it to the handleSubmit callback\r\n // so that we don't need to create separate a callback for event handlers\r\n let submittedViaKeyboard = false;\r\n const handleSubmit = () => {\r\n var _a, _b;\r\n // cleanup must be run before onSubmit otherwise when app blurs the wysiwyg\r\n // it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the\r\n // wysiwyg on update\r\n cleanup();\r\n const updateElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(element.id);\r\n if (!updateElement) {\r\n return;\r\n }\r\n let wrappedText = \"\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && (updateElement === null || updateElement === void 0 ? void 0 : updateElement.containerId)) {\r\n const container = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updateElement).getElement(updateElement.containerId);\r\n if (container) {\r\n wrappedText = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.wrapText)(editable.value, (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updateElement), container.width);\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && updateElement.containerId) {\r\n const editorHeight = Number(editable.style.height.slice(0, -2));\r\n if (editable.value) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(updateElement, {\r\n // vertically center align\r\n y: container.y + container.height / 2 - editorHeight / 2,\r\n height: editorHeight,\r\n width: Number(editable.style.width.slice(0, -2)),\r\n // preserve padding\r\n x: container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING,\r\n });\r\n const boundTextElementId = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getBoundTextElementId)(container);\r\n if (!boundTextElementId || boundTextElementId !== element.id) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (container.boundElements || []).concat({\r\n type: \"text\",\r\n id: element.id,\r\n }),\r\n });\r\n }\r\n }\r\n else {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (_b = container.boundElements) === null || _b === void 0 ? void 0 : _b.filter((ele) => ele.type !== \"text\"),\r\n });\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n wrappedText = editable.value;\r\n }\r\n onSubmit({\r\n text: normalizeText(wrappedText),\r\n viaKeyboard: submittedViaKeyboard,\r\n originalText: editable.value,\r\n });\r\n };\r\n const cleanup = () => {\r\n if (isDestroyed) {\r\n return;\r\n }\r\n isDestroyed = true;\r\n // remove events to ensure they don't late-fire\r\n editable.onblur = null;\r\n editable.oninput = null;\r\n editable.onkeydown = null;\r\n if (observer) {\r\n observer.disconnect();\r\n }\r\n window.removeEventListener(\"resize\", updateWysiwygStyle);\r\n window.removeEventListener(\"wheel\", stopEvent, true);\r\n window.removeEventListener(\"pointerdown\", onPointerDown);\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n window.removeEventListener(\"blur\", handleSubmit);\r\n unbindUpdate();\r\n editable.remove();\r\n };\r\n const bindBlurEvent = (event) => {\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n // Deferred so that the pointerdown that initiates the wysiwyg doesn't\r\n // trigger the blur on ensuing pointerup.\r\n // Also to handle cases such as picking a color which would trigger a blur\r\n // in that same tick.\r\n const target = event === null || event === void 0 ? void 0 : event.target;\r\n const isTargetColorPicker = target instanceof HTMLInputElement &&\r\n target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(target);\r\n setTimeout(() => {\r\n editable.onblur = handleSubmit;\r\n if (target && isTargetColorPicker) {\r\n target.onblur = () => {\r\n editable.focus();\r\n };\r\n }\r\n // case: clicking on the same property → no change → no update → no focus\r\n if (!isTargetColorPicker) {\r\n editable.focus();\r\n }\r\n });\r\n };\r\n // prevent blur when changing properties from the menu\r\n const onPointerDown = (event) => {\r\n const isTargetColorPicker = event.target instanceof HTMLInputElement &&\r\n event.target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target);\r\n if (((event.target instanceof HTMLElement ||\r\n event.target instanceof SVGElement) &&\r\n event.target.closest(`.${_constants__WEBPACK_IMPORTED_MODULE_4__.CLASSES.SHAPE_ACTIONS_MENU}`) &&\r\n !(0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target)) ||\r\n isTargetColorPicker) {\r\n editable.onblur = null;\r\n window.addEventListener(\"pointerup\", bindBlurEvent);\r\n // handle edge-case where pointerup doesn't fire e.g. due to user\r\n // alt-tabbing away\r\n window.addEventListener(\"blur\", handleSubmit);\r\n }\r\n };\r\n // handle updates of textElement properties of editing element\r\n const unbindUpdate = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element).addCallback(() => {\r\n var _a;\r\n updateWysiwygStyle();\r\n const isColorPickerActive = !!((_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest(\".color-picker-input\"));\r\n if (!isColorPickerActive) {\r\n editable.focus();\r\n }\r\n });\r\n // ---------------------------------------------------------------------------\r\n let isDestroyed = false;\r\n // select on init (focusing is done separately inside the bindBlurEvent()\r\n // because we need it to happen *after* the blur event from `pointerdown`)\r\n editable.select();\r\n bindBlurEvent();\r\n // reposition wysiwyg in case of canvas is resized. Using ResizeObserver\r\n // is preferred so we catch changes from host, where window may not resize.\r\n let observer = null;\r\n if (canvas && \"ResizeObserver\" in window) {\r\n observer = new window.ResizeObserver(() => {\r\n updateWysiwygStyle();\r\n });\r\n observer.observe(canvas);\r\n }\r\n else {\r\n window.addEventListener(\"resize\", updateWysiwygStyle);\r\n }\r\n window.addEventListener(\"pointerdown\", onPointerDown);\r\n window.addEventListener(\"wheel\", stopEvent, {\r\n passive: false,\r\n capture: true,\r\n });\r\n excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.querySelector(\".excalidraw-textEditorContainer\").appendChild(editable);\r\n};\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRTtRQUMxQyxPQUFPLEVBQUUsS0FBSztRQUNkLE9BQU8sRUFBRSxJQUFJO0tBQ2QsQ0FBQyxDQUFDO0lBQ0gsbUJBQW1CLGFBQW5CLG1CQUFtQix1QkFBbkIsbUJBQW1CLENBQ2YsYUFBYSxDQUFDLGlDQUFpQyxFQUNoRCxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDM0IsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL2VsZW1lbnQvdGV4dFd5c2l3eWcudHN4PzhmNGQiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09ERVMsIEtFWVMgfSBmcm9tIFwiLi4va2V5c1wiO1xuaW1wb3J0IHtcbiAgaXNXcml0YWJsZUVsZW1lbnQsXG4gIGdldEZvbnRTdHJpbmcsXG4gIGdldEZvbnRGYW1pbHlTdHJpbmcsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3Jkcyxcbn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgU2NlbmUgZnJvbSBcIi4uL3NjZW5lL1NjZW5lXCI7XG5pbXBvcnQgeyBpc0JvdW5kVG9Db250YWluZXIsIGlzVGV4dEVsZW1lbnQgfSBmcm9tIFwiLi90eXBlQ2hlY2tzXCI7XG5pbXBvcnQgeyBDTEFTU0VTLCBQQURESU5HIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IEFwcFN0YXRlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBtdXRhdGVFbGVtZW50IH0gZnJvbSBcIi4vbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgZ2V0QXBwcm94TGluZUhlaWdodCxcbiAgZ2V0Qm91bmRUZXh0RWxlbWVudElkLFxuICB3cmFwVGV4dCxcbn0gZnJvbSBcIi4vdGV4dEVsZW1lbnRcIjtcblxuY29uc3Qgbm9ybWFsaXplVGV4dCA9ICh0ZXh0OiBzdHJpbmcpID0+IHtcbiAgcmV0dXJuIChcbiAgICB0ZXh0XG4gICAgICAvLyByZXBsYWNlIHRhYnMgd2l0aCBzcGFjZXMgc28gdGhleSByZW5kZXIgYW5kIG1lYXN1cmUgY29ycmVjdGx5XG4gICAgICAucmVwbGFjZSgvXFx0L2csIFwiICAgICAgICBcIilcbiAgICAgIC8vIG5vcm1hbGl6ZSBuZXdsaW5lc1xuICAgICAgLnJlcGxhY2UoL1xccj9cXG58XFxyL2csIFwiXFxuXCIpXG4gICk7XG59O1xuXG5jb25zdCBnZXRUcmFuc2Zvcm0gPSAoXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBhbmdsZTogbnVtYmVyLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gIG1heFdpZHRoOiBudW1iZXIsXG4gIG1heEhlaWdodDogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IHsgem9vbSwgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSBhcHBTdGF0ZTtcbiAgY29uc3QgZGVncmVlID0gKDE4MCAqIGFuZ2xlKSAvIE1hdGguUEk7XG4gIC8vIG9mZnNldHMgbXVzdCBiZSBtdWx0aXBsaWVkIGJ5IDIgdG8gYWNjb3VudCBmb3IgdGhlIGRpdmlzaW9uIGJ5IDIgb2ZcbiAgLy8gdGhlIHdob2xlIGV4cHJlc3Npb24gYWZ0ZXJ3YXJkc1xuICBsZXQgdHJhbnNsYXRlWCA9ICgod2lkdGggLSBvZmZzZXRMZWZ0ICogMikgKiAoem9vbS52YWx1ZSAtIDEpKSAvIDI7XG4gIGxldCB0cmFuc2xhdGVZID0gKChoZWlnaHQgLSBvZmZzZXRUb3AgKiAyKSAqICh6b29tLnZhbHVlIC0gMSkpIC8gMjtcbiAgaWYgKHdpZHRoID4gbWF4V2lkdGggJiYgem9vbS52YWx1ZSAhPT0gMSkge1xuICAgIHRyYW5zbGF0ZVggPSAoKG1heFdpZHRoIC0gb2Zmc2V0TGVmdCAqIDIpICogKHpvb20udmFsdWUgLSAxKSkgLyAyXG4gIH1cbiAgaWYgKGhlaWdodCA+IG1heEhlaWdodCAmJiB6b29tLnZhbHVlICE9PSAxKSB7XG4gICAgdHJhbnNsYXRlWSA9ICgobWF4SGVpZ2h0IC0gb2Zmc2V0VG9wICogMikgKiAoem9vbS52YWx1ZSAtIDEpKSAvIDI7XG4gIH1cbiAgcmV0dXJuIGB0cmFuc2xhdGUoJHt0cmFuc2xhdGVYfXB4LCAke3RyYW5zbGF0ZVl9cHgpIHNjYWxlKCR7em9vbS52YWx1ZX0pIHJvdGF0ZSgke2RlZ3JlZX1kZWcpYDtcbn07XG5cbmV4cG9ydCBjb25zdCB0ZXh0V3lzaXd5ZyA9ICh7XG4gIGlkLFxuICBhcHBTdGF0ZSxcbiAgb25DaGFuZ2UsXG4gIG9uU3VibWl0LFxuICBnZXRWaWV3cG9ydENvb3JkcyxcbiAgZWxlbWVudCxcbiAgY2FudmFzLFxuICBleGNhbGlkcmF3Q29udGFpbmVyLFxufToge1xuICBpZDogRXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXTtcbiAgYXBwU3RhdGU6IEFwcFN0YXRlO1xuICBvbkNoYW5nZT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQ7XG4gIG9uU3VibWl0OiAoZGF0YToge1xuICAgIHRleHQ6IHN0cmluZztcbiAgICB2aWFLZXlib2FyZDogYm9vbGVhbjtcbiAgICBvcmlnaW5hbFRleHQ6IHN0cmluZztcbiAgfSkgPT4gdm9pZDtcbiAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gW251bWJlciwgbnVtYmVyXTtcbiAgZWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQ7XG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsO1xuICBleGNhbGlkcmF3Q29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG59KSA9PiB7XG4gIGNvbnN0IHRleHRQcm9wZXJ0aWVzVXBkYXRlZCA9IChcbiAgICB1cGRhdGVkRWxlbWVudDogRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICAgIGVkaXRhYmxlOiBIVE1MVGV4dEFyZWFFbGVtZW50LFxuICApID0+IHtcbiAgICBjb25zdCBjdXJyZW50Rm9udCA9IGVkaXRhYmxlLnN0eWxlLmZvbnRGYW1pbHkucmVwbGFjZUFsbCgnXCInLCBcIlwiKTtcbiAgICBpZiAoXG4gICAgICBnZXRGb250RmFtaWx5U3RyaW5nKHsgZm9udEZhbWlseTogdXBkYXRlZEVsZW1lbnQuZm9udEZhbWlseSB9KSAhPT1cbiAgICAgIGN1cnJlbnRGb250XG4gICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGAke3VwZGF0ZWRFbGVtZW50LmZvbnRTaXplfXB4YCAhPT0gZWRpdGFibGUuc3R5bGUuZm9udFNpemUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIGxldCBvcmlnaW5hbENvbnRhaW5lckhlaWdodDogbnVtYmVyO1xuICBsZXQgYXBwcm94TGluZUhlaWdodCA9IGlzVGV4dEVsZW1lbnQoZWxlbWVudClcbiAgICA/IGdldEFwcHJveExpbmVIZWlnaHQoZ2V0Rm9udFN0cmluZyhlbGVtZW50KSlcbiAgICA6IDA7XG5cbiAgY29uc3QgdXBkYXRlV3lzaXd5Z1N0eWxlID0gKCkgPT4ge1xuICAgIGNvbnN0IHVwZGF0ZWRFbGVtZW50ID0gU2NlbmUuZ2V0U2NlbmUoZWxlbWVudCk/LmdldEVsZW1lbnQoaWQpO1xuICAgIGlmICh1cGRhdGVkRWxlbWVudCAmJiBpc1RleHRFbGVtZW50KHVwZGF0ZWRFbGVtZW50KSkge1xuICAgICAgbGV0IGNvb3JkWCA9IHVwZGF0ZWRFbGVtZW50Lng7XG4gICAgICBsZXQgY29vcmRZID0gdXBkYXRlZEVsZW1lbnQueTtcbiAgICAgIGxldCBjb250YWluZXIgPSB1cGRhdGVkRWxlbWVudD8uY29udGFpbmVySWRcbiAgICAgICAgPyBTY2VuZS5nZXRTY2VuZSh1cGRhdGVkRWxlbWVudCkhLmdldEVsZW1lbnQodXBkYXRlZEVsZW1lbnQuY29udGFpbmVySWQpXG4gICAgICAgIDogbnVsbDtcbiAgICAgIGxldCBtYXhXaWR0aCA9IHVwZGF0ZWRFbGVtZW50LndpZHRoO1xuXG4gICAgICBsZXQgbWF4SGVpZ2h0ID0gdXBkYXRlZEVsZW1lbnQuaGVpZ2h0O1xuICAgICAgbGV0IHdpZHRoID0gdXBkYXRlZEVsZW1lbnQud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPVxuICAgICAgICBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgPT09IDBcbiAgICAgICAgICA/IHVwZGF0ZWRFbGVtZW50LmhlaWdodFxuICAgICAgICAgIDogZWRpdGFibGUuc2Nyb2xsSGVpZ2h0O1xuICAgICAgaWYgKGNvbnRhaW5lciAmJiB1cGRhdGVkRWxlbWVudC5jb250YWluZXJJZCkge1xuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzVXBkYXRlZCA9IHRleHRQcm9wZXJ0aWVzVXBkYXRlZChcbiAgICAgICAgICB1cGRhdGVkRWxlbWVudCxcbiAgICAgICAgICBlZGl0YWJsZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocHJvcGVydGllc1VwZGF0ZWQpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGFpbmVyID0gU2NlbmUuZ2V0U2NlbmUodXBkYXRlZEVsZW1lbnQpPy5nZXRFbGVtZW50KFxuICAgICAgICAgICAgdXBkYXRlZEVsZW1lbnQuY29udGFpbmVySWQsXG4gICAgICAgICAgKSBhcyBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50O1xuICAgICAgICAgIGFwcHJveExpbmVIZWlnaHQgPSBpc1RleHRFbGVtZW50KHVwZGF0ZWRFbGVtZW50KVxuICAgICAgICAgICAgPyBnZXRBcHByb3hMaW5lSGVpZ2h0KGdldEZvbnRTdHJpbmcodXBkYXRlZEVsZW1lbnQpKVxuICAgICAgICAgICAgOiAwO1xuICAgICAgICAgIGlmICh1cGRhdGVkRWxlbWVudC5oZWlnaHQgPiBjdXJyZW50Q29udGFpbmVyLmhlaWdodCAtIFBBRERJTkcgKiAyKSB7XG4gICAgICAgICAgICBjb25zdCBuZXh0SGVpZ2h0ID0gdXBkYXRlZEVsZW1lbnQuaGVpZ2h0ICsgUEFERElORyAqIDI7XG4gICAgICAgICAgICBvcmlnaW5hbENvbnRhaW5lckhlaWdodCA9IG5leHRIZWlnaHQ7XG4gICAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IG5leHRIZWlnaHQgfSk7XG4gICAgICAgICAgICBjb250YWluZXIgPSB7IC4uLmNvbnRhaW5lciwgaGVpZ2h0OiBuZXh0SGVpZ2h0IH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGVkaXRhYmxlLnN0eWxlLmhlaWdodCA9IGAke3VwZGF0ZWRFbGVtZW50LmhlaWdodH1weGA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFvcmlnaW5hbENvbnRhaW5lckhlaWdodCkge1xuICAgICAgICAgIG9yaWdpbmFsQ29udGFpbmVySGVpZ2h0ID0gY29udGFpbmVyLmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBtYXhXaWR0aCA9IGNvbnRhaW5lci53aWR0aCAtIFBBRERJTkcgKiAyO1xuICAgICAgICBtYXhIZWlnaHQgPSBjb250YWluZXIuaGVpZ2h0IC0gUEFERElORyAqIDI7XG4gICAgICAgIHdpZHRoID0gbWF4V2lkdGg7XG4gICAgICAgIC8vIFRoZSBjb29yZGluYXRlcyBvZiB0ZXh0IGJveCBzZXQgYSBkaXN0YW5jZSBvZlxuICAgICAgICAvLyAzMHB4IHRvIHByZXNlcnZlIHBhZGRpbmdcbiAgICAgICAgY29vcmRYID0gY29udGFpbmVyLnggKyBQQURESU5HO1xuXG4gICAgICAgIC8vIGF1dG9ncm93IGNvbnRhaW5lciBoZWlnaHQgaWYgdGV4dCBleGNlZWRzXG4gICAgICAgIGlmIChlZGl0YWJsZS5zY3JvbGxIZWlnaHQgPiBtYXhIZWlnaHQpIHtcbiAgICAgICAgICBjb25zdCBkaWZmID0gTWF0aC5taW4oXG4gICAgICAgICAgICBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLSBtYXhIZWlnaHQsXG4gICAgICAgICAgICBhcHByb3hMaW5lSGVpZ2h0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBjb250YWluZXIuaGVpZ2h0ICsgZGlmZiB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgLy8gYXV0b3NocmluayBjb250YWluZXIgaGVpZ2h0IHVudGlsIG9yaWdpbmFsIGNvbnRhaW5lciBoZWlnaHRcbiAgICAgICAgICAvLyBpcyByZWFjaGVkIHdoZW4gdGV4dCBpcyByZW1vdmVkXG4gICAgICAgICAgY29udGFpbmVyLmhlaWdodCA+IG9yaWdpbmFsQ29udGFpbmVySGVpZ2h0ICYmXG4gICAgICAgICAgZWRpdGFibGUuc2Nyb2xsSGVpZ2h0IDwgbWF4SGVpZ2h0XG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IGRpZmYgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIG1heEhlaWdodCAtIGVkaXRhYmxlLnNjcm9sbEhlaWdodCxcbiAgICAgICAgICAgIGFwcHJveExpbmVIZWlnaHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IGNvbnRhaW5lci5oZWlnaHQgLSBkaWZmIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFN0YXJ0IHB1c2hpbmcgdGV4dCB1cHdhcmQgdW50aWwgYSBkaWZmIG9mIDMwcHggKHBhZGRpbmcpXG4gICAgICAgIC8vIGlzIHJlYWNoZWRcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgY29uc3QgbGluZXMgPSBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLyBhcHByb3hMaW5lSGVpZ2h0O1xuXG4gICAgICAgICAgaWYgKGxpbmVzID4gMSB8fCBwcm9wZXJ0aWVzVXBkYXRlZCkge1xuICAgICAgICAgICAgLy8gdmVydGljYWxseSBjZW50ZXIgYWxpZ24gdGhlIHRleHRcbiAgICAgICAgICAgIGNvb3JkWSA9XG4gICAgICAgICAgICAgIGNvbnRhaW5lci55ICsgY29udGFpbmVyLmhlaWdodCAvIDIgLSBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLyAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgW3ZpZXdwb3J0WCwgdmlld3BvcnRZXSA9IGdldFZpZXdwb3J0Q29vcmRzKGNvb3JkWCwgY29vcmRZKTtcbiAgICAgIGNvbnN0IHsgdGV4dEFsaWduLCBhbmdsZSB9ID0gdXBkYXRlZEVsZW1lbnQ7XG5cbiAgICAgIGVkaXRhYmxlLnZhbHVlID0gdXBkYXRlZEVsZW1lbnQub3JpZ2luYWxUZXh0IHx8IHVwZGF0ZWRFbGVtZW50LnRleHQ7XG4gICAgICBjb25zdCBsaW5lcyA9IHVwZGF0ZWRFbGVtZW50Lm9yaWdpbmFsVGV4dC5zcGxpdChcIlxcblwiKTtcbiAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSB1cGRhdGVkRWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICA/IGFwcHJveExpbmVIZWlnaHRcbiAgICAgICAgOiB1cGRhdGVkRWxlbWVudC5oZWlnaHQgLyBsaW5lcy5sZW5ndGg7XG4gICAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgICBtYXhXaWR0aCA9XG4gICAgICAgICAgKCBhcHBTdGF0ZS53aWR0aCArIGFwcFN0YXRlLm9mZnNldExlZnQgLSB2aWV3cG9ydFggLSA4KSAvIGFwcFN0YXRlLnpvb20udmFsdWUgLVxuICAgICAgICAgIC8vIG1hcmdpbi1yaWdodCBvZiBwYXJlbnQgaWYgYW55XG4gICAgICAgICAgTnVtYmVyKFxuICAgICAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShcbiAgICAgICAgICAgICAgZXhjYWxpZHJhd0NvbnRhaW5lcj8ucGFyZW50Tm9kZSBhcyBFbGVtZW50LFxuICAgICAgICAgICAgKS5tYXJnaW5SaWdodC5zbGljZSgwLCAtMiksXG4gICAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gTWFrZSBzdXJlIHRleHQgZWRpdG9yIGhlaWdodCBkb2Vzbid0IGdvIGJleW9uZCB2aWV3cG9ydFxuICAgICAgY29uc3QgZWRpdG9yTWF4SGVpZ2h0ID1cbiAgICAgICAgKGFwcFN0YXRlLmhlaWdodCArIGFwcFN0YXRlLm9mZnNldFRvcCAtIHZpZXdwb3J0WSkgLyBhcHBTdGF0ZS56b29tLnZhbHVlO1xuXG4gICAgICBjb25zb2xlLmxvZyh7XG4gICAgICAgIG1heFdpZHRoLFxuICAgICAgICBlZGl0b3JNYXhIZWlnaHQsXG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIHZpZXdwb3J0WCxcbiAgICAgICAgdmlld3BvcnRZLFxuICAgICAgICBhcHBXaWR0aDphcHBTdGF0ZS53aWR0aCxcbiAgICAgICAgYXBwSGVpZ2h0OmFwcFN0YXRlLmhlaWdodCxcbiAgICAgICAgc2Nyb2xsWDogYXBwU3RhdGUuc2Nyb2xsWCxcbiAgICAgICAgc2Nyb2xsWTogYXBwU3RhdGUuc2Nyb2xsWSxcbiAgICAgICAgb2Zmc2V0VG9wOiBhcHBTdGF0ZS5vZmZzZXRUb3AsXG4gICAgICAgIG9mZnNldExlZnQ6IGFwcFN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgIG1hcmdpblJpZ2h0OiBOdW1iZXIoXG4gICAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShcbiAgICAgICAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI/LnBhcmVudE5vZGUgYXMgRWxlbWVudCxcbiAgICAgICAgICApLm1hcmdpblJpZ2h0LnNsaWNlKDAsIC0yKSxcbiAgICAgICAgKSxcbiAgICAgICAgdHJhbnNmb3JtOiBnZXRUcmFuc2Zvcm0oXG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIGFuZ2xlLFxuICAgICAgICAgIGFwcFN0YXRlLFxuICAgICAgICAgIG1heFdpZHRoLFxuICAgICAgICAgIGVkaXRvck1heEhlaWdodCxcbiAgICAgICAgKVxuICAgICAgfSk7XG4gICAgICBPYmplY3QuYXNzaWduKGVkaXRhYmxlLnN0eWxlLCB7XG4gICAgICAgIGZvbnQ6IGdldEZvbnRTdHJpbmcodXBkYXRlZEVsZW1lbnQpLFxuICAgICAgICAvLyBtdXN0IGJlIGRlZmluZWQgKmFmdGVyKiBmb250IMKvXFxfKOODhClfL8KvXG4gICAgICAgIGxpbmVIZWlnaHQ6IGAke2xpbmVIZWlnaHR9cHhgLFxuICAgICAgICB3aWR0aDogYCR7d2lkdGh9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke2hlaWdodH1weGAsXG4gICAgICAgIGxlZnQ6IGAke3ZpZXdwb3J0WH1weGAsXG4gICAgICAgIHRvcDogYCR7dmlld3BvcnRZfXB4YCxcbiAgICAgICAgdHJhbnNmb3JtOiBnZXRUcmFuc2Zvcm0oXG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIGFuZ2xlLFxuICAgICAgICAgIGFwcFN0YXRlLFxuICAgICAgICAgIG1heFdpZHRoLFxuICAgICAgICAgIGVkaXRvck1heEhlaWdodCxcbiAgICAgICAgKSxcbiAgICAgICAgdGV4dEFsaWduLFxuICAgICAgICBjb2xvcjogdXBkYXRlZEVsZW1lbnQuc3Ryb2tlQ29sb3IsXG4gICAgICAgIG9wYWNpdHk6IHVwZGF0ZWRFbGVtZW50Lm9wYWNpdHkgLyAxMDAsXG4gICAgICAgIGZpbHRlcjogXCJ2YXIoLS10aGVtZS1maWx0ZXIpXCIsXG4gICAgICAgIG1heFdpZHRoOiBgJHttYXhXaWR0aH1weGAsXG4gICAgICAgIG1heEhlaWdodDogYCR7ZWRpdG9yTWF4SGVpZ2h0fXB4YCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBlZGl0YWJsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZXh0YXJlYVwiKTtcblxuICBlZGl0YWJsZS5kaXIgPSBcImF1dG9cIjtcbiAgZWRpdGFibGUudGFiSW5kZXggPSAwO1xuICBlZGl0YWJsZS5kYXRhc2V0LnR5cGUgPSBcInd5c2l3eWdcIjtcbiAgLy8gcHJldmVudCBsaW5lIHdyYXBwaW5nIG9uIFNhZmFyaVxuICBlZGl0YWJsZS53cmFwID0gXCJvZmZcIjtcbiAgZWRpdGFibGUuY2xhc3NMaXN0LmFkZChcImV4Y2FsaWRyYXctd3lzaXd5Z1wiKTtcblxuICBsZXQgd2hpdGVTcGFjZSA9IFwicHJlXCI7XG4gIGxldCB3b3JkQnJlYWsgPSBcIm5vcm1hbFwiO1xuXG4gIGlmIChpc0JvdW5kVG9Db250YWluZXIoZWxlbWVudCkpIHtcbiAgICB3aGl0ZVNwYWNlID0gXCJwcmUtd3JhcFwiO1xuICAgIHdvcmRCcmVhayA9IFwiYnJlYWstd29yZFwiO1xuICB9XG4gIE9iamVjdC5hc3NpZ24oZWRpdGFibGUuc3R5bGUsIHtcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIGRpc3BsYXk6IFwiaW5saW5lLWJsb2NrXCIsXG4gICAgbWluSGVpZ2h0OiBcIjFlbVwiLFxuICAgIGJhY2tmYWNlVmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICBtYXJnaW46IDAsXG4gICAgcGFkZGluZzogMCxcbiAgICBib3JkZXI6IDAsXG4gICAgb3V0bGluZTogMCxcbiAgICByZXNpemU6IFwibm9uZVwiLFxuICAgIGJhY2tncm91bmQ6IFwidHJhbnNwYXJlbnRcIixcbiAgICBvdmVyZmxvdzogXCJoaWRkZW5cIixcbiAgICAvLyBtdXN0IGJlIHNwZWNpZmllZCBiZWNhdXNlIGluIGRhcmsgbW9kZSBjYW52YXMgY3JlYXRlcyBhIHN0YWNraW5nIGNvbnRleHRcbiAgICB6SW5kZXg6IFwidmFyKC0tekluZGV4LXd5c2l3eWcpXCIsXG4gICAgd29yZEJyZWFrLFxuICAgIC8vIHByZXZlbnQgbGluZSB3cmFwcGluZyAoYHdoaXRlc3BhY2U6IG5vd3JhcGAgZG9lc24ndCB3b3JrIG9uIEZGKVxuICAgIHdoaXRlU3BhY2UsXG4gICAgb3ZlcmZsb3dXcmFwOiBcImJyZWFrLXdvcmRcIixcbiAgfSk7XG4gIHVwZGF0ZVd5c2l3eWdTdHlsZSgpO1xuXG4gIGlmIChvbkNoYW5nZSkge1xuICAgIGVkaXRhYmxlLm9uaW5wdXQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBsaW5lcyA9IGVkaXRhYmxlLnNjcm9sbEhlaWdodCAvIGFwcHJveExpbmVIZWlnaHQ7XG4gICAgICAvLyBhdXRvIGluY3JlYXNlIGhlaWdodCBvbmx5IHdoZW4gbGluZXMgID4gMSBzbyBpdHNcbiAgICAgIC8vIG1lYXN1cmVkIGNvcnJlY3RseSBhbmQgdmVydGljYWxseSBhbGlnbmVzIGZvclxuICAgICAgLy8gZmlyc3QgbGluZSBhcyB3ZWxsIGFzIHNldHRpbmcgaGVpZ2h0IHRvIFwiYXV0b1wiXG4gICAgICAvLyBkb3VibGVzIHRoZSBoZWlnaHQgYXMgc29vbiBhcyB1c2VyIHN0YXJ0cyB0eXBpbmdcbiAgICAgIGlmIChpc0JvdW5kVG9Db250YWluZXIoZWxlbWVudCkgJiYgbGluZXMgPiAxKSB7XG4gICAgICAgIGVkaXRhYmxlLnN0eWxlLmhlaWdodCA9IFwiYXV0b1wiO1xuICAgICAgICBlZGl0YWJsZS5zdHlsZS5oZWlnaHQgPSBgJHtlZGl0YWJsZS5zY3JvbGxIZWlnaHR9cHhgO1xuICAgICAgfVxuICAgICAgb25DaGFuZ2Uobm9ybWFsaXplVGV4dChlZGl0YWJsZS52YWx1ZSkpO1xuICAgIH07XG4gIH1cblxuICBlZGl0YWJsZS5vbmtleWRvd24gPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVTQ0FQRSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHN1Ym1pdHRlZFZpYUtleWJvYXJkID0gdHJ1ZTtcbiAgICAgIGhhbmRsZVN1Ym1pdCgpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVOVEVSICYmIGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGV2ZW50LmlzQ29tcG9zaW5nIHx8IGV2ZW50LmtleUNvZGUgPT09IDIyOSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdWJtaXR0ZWRWaWFLZXlib2FyZCA9IHRydWU7XG4gICAgICBoYW5kbGVTdWJtaXQoKTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLlRBQiB8fFxuICAgICAgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmXG4gICAgICAgIChldmVudC5jb2RlID09PSBDT0RFUy5CUkFDS0VUX0xFRlQgfHxcbiAgICAgICAgICBldmVudC5jb2RlID09PSBDT0RFUy5CUkFDS0VUX1JJR0hUKSlcbiAgICApIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuY29kZSA9PT0gQ09ERVMuQlJBQ0tFVF9MRUZUKSB7XG4gICAgICAgIG91dGRlbnQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGVudCgpO1xuICAgICAgfVxuICAgICAgLy8gV2UgbXVzdCBzZW5kIGFuIGlucHV0IGV2ZW50IHRvIHJlc2l6ZSB0aGUgZWxlbWVudFxuICAgICAgZWRpdGFibGUuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiKSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IFRBQl9TSVpFID0gNDtcbiAgY29uc3QgVEFCID0gXCIgXCIucmVwZWF0KFRBQl9TSVpFKTtcbiAgY29uc3QgUkVfTEVBRElOR19UQUIgPSBuZXcgUmVnRXhwKGBeIHsxLCR7VEFCX1NJWkV9fWApO1xuICBjb25zdCBpbmRlbnQgPSAoKSA9PiB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kIH0gPSBlZGl0YWJsZTtcbiAgICBjb25zdCBsaW5lc1N0YXJ0SW5kaWNlcyA9IGdldFNlbGVjdGVkTGluZXNTdGFydEluZGljZXMoKTtcblxuICAgIGxldCB2YWx1ZSA9IGVkaXRhYmxlLnZhbHVlO1xuICAgIGxpbmVzU3RhcnRJbmRpY2VzLmZvckVhY2goKHN0YXJ0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnRWYWx1ZSA9IHZhbHVlLnNsaWNlKDAsIHN0YXJ0SW5kZXgpO1xuICAgICAgY29uc3QgZW5kVmFsdWUgPSB2YWx1ZS5zbGljZShzdGFydEluZGV4KTtcblxuICAgICAgdmFsdWUgPSBgJHtzdGFydFZhbHVlfSR7VEFCfSR7ZW5kVmFsdWV9YDtcbiAgICB9KTtcblxuICAgIGVkaXRhYmxlLnZhbHVlID0gdmFsdWU7XG5cbiAgICBlZGl0YWJsZS5zZWxlY3Rpb25TdGFydCA9IHNlbGVjdGlvblN0YXJ0ICsgVEFCX1NJWkU7XG4gICAgZWRpdGFibGUuc2VsZWN0aW9uRW5kID0gc2VsZWN0aW9uRW5kICsgVEFCX1NJWkUgKiBsaW5lc1N0YXJ0SW5kaWNlcy5sZW5ndGg7XG4gIH07XG5cbiAgY29uc3Qgb3V0ZGVudCA9ICgpID0+IHtcbiAgICBjb25zdCB7IHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQgfSA9IGVkaXRhYmxlO1xuICAgIGNvbnN0IGxpbmVzU3RhcnRJbmRpY2VzID0gZ2V0U2VsZWN0ZWRMaW5lc1N0YXJ0SW5kaWNlcygpO1xuICAgIGNvbnN0IHJlbW92ZWRUYWJzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgbGV0IHZhbHVlID0gZWRpdGFibGUudmFsdWU7XG4gICAgbGluZXNTdGFydEluZGljZXMuZm9yRWFjaCgoc3RhcnRJbmRleCkgPT4ge1xuICAgICAgY29uc3QgdGFiTWF0Y2ggPSB2YWx1ZVxuICAgICAgICAuc2xpY2Uoc3RhcnRJbmRleCwgc3RhcnRJbmRleCArIFRBQl9TSVpFKVxuICAgICAgICAubWF0Y2goUkVfTEVBRElOR19UQUIpO1xuXG4gICAgICBpZiAodGFiTWF0Y2gpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRWYWx1ZSA9IHZhbHVlLnNsaWNlKDAsIHN0YXJ0SW5kZXgpO1xuICAgICAgICBjb25zdCBlbmRWYWx1ZSA9IHZhbHVlLnNsaWNlKHN0YXJ0SW5kZXggKyB0YWJNYXRjaFswXS5sZW5ndGgpO1xuXG4gICAgICAgIC8vIERlbGV0ZSBhIHRhYiBmcm9tIHRoZSBsaW5lXG4gICAgICAgIHZhbHVlID0gYCR7c3RhcnRWYWx1ZX0ke2VuZFZhbHVlfWA7XG4gICAgICAgIHJlbW92ZWRUYWJzLnB1c2goc3RhcnRJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBlZGl0YWJsZS52YWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHJlbW92ZWRUYWJzLmxlbmd0aCkge1xuICAgICAgaWYgKHNlbGVjdGlvblN0YXJ0ID4gcmVtb3ZlZFRhYnNbcmVtb3ZlZFRhYnMubGVuZ3RoIC0gMV0pIHtcbiAgICAgICAgZWRpdGFibGUuc2VsZWN0aW9uU3RhcnQgPSBNYXRoLm1heChcbiAgICAgICAgICBzZWxlY3Rpb25TdGFydCAtIFRBQl9TSVpFLFxuICAgICAgICAgIHJlbW92ZWRUYWJzW3JlbW92ZWRUYWJzLmxlbmd0aCAtIDFdLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSWYgdGhlIGN1cnNvciBpcyBiZWZvcmUgdGhlIGZpcnN0IHRhYiByZW1vdmVkLCBleDpcbiAgICAgICAgLy8gTGluZXwgIzFcbiAgICAgICAgLy8gICAgIExpbmUgIzJcbiAgICAgICAgLy8gTGlufGUgIzNcbiAgICAgICAgLy8gd2Ugc2hvdWxkIHJlc2V0IHRoZSBzZWxlY3Rpb25TdGFydCB0byBoaXMgaW5pdGlhbCB2YWx1ZS5cbiAgICAgICAgZWRpdGFibGUuc2VsZWN0aW9uU3RhcnQgPSBzZWxlY3Rpb25TdGFydDtcbiAgICAgIH1cbiAgICAgIGVkaXRhYmxlLnNlbGVjdGlvbkVuZCA9IE1hdGgubWF4KFxuICAgICAgICBlZGl0YWJsZS5zZWxlY3Rpb25TdGFydCxcbiAgICAgICAgc2VsZWN0aW9uRW5kIC0gVEFCX1NJWkUgKiByZW1vdmVkVGFicy5sZW5ndGgsXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHJldHVybnMgaW5kZWNlcyBvZiBzdGFydCBwb3NpdGlvbnMgb2Ygc2VsZWN0ZWQgbGluZXMsIGluIHJldmVyc2Ugb3JkZXJcbiAgICovXG4gIGNvbnN0IGdldFNlbGVjdGVkTGluZXNTdGFydEluZGljZXMgPSAoKSA9PiB7XG4gICAgbGV0IHsgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCwgdmFsdWUgfSA9IGVkaXRhYmxlO1xuXG4gICAgLy8gY2hhcnMgYmVmb3JlIHNlbGVjdGlvblN0YXJ0IG9uIHRoZSBzYW1lIGxpbmVcbiAgICBjb25zdCBzdGFydE9mZnNldCA9IHZhbHVlLnNsaWNlKDAsIHNlbGVjdGlvblN0YXJ0KS5tYXRjaCgvW15cXG5dKiQvKSFbMF1cbiAgICAgIC5sZW5ndGg7XG4gICAgLy8gcHV0IGNhcmV0IGF0IHRoZSBzdGFydCBvZiB0aGUgbGluZVxuICAgIHNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgLSBzdGFydE9mZnNldDtcblxuICAgIGNvbnN0IHNlbGVjdGVkID0gdmFsdWUuc2xpY2Uoc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCk7XG5cbiAgICByZXR1cm4gc2VsZWN0ZWRcbiAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgLnJlZHVjZShcbiAgICAgICAgKHN0YXJ0SW5kaWNlcywgbGluZSwgaWR4LCBsaW5lcykgPT5cbiAgICAgICAgICBzdGFydEluZGljZXMuY29uY2F0KFxuICAgICAgICAgICAgaWR4XG4gICAgICAgICAgICAgID8gLy8gY3VyciBsaW5lIGluZGV4IGlzIHByZXYgbGluZSdzIHN0YXJ0ICsgcHJldiBsaW5lJ3MgbGVuZ3RoICsgXFxuXG4gICAgICAgICAgICAgICAgc3RhcnRJbmRpY2VzW2lkeCAtIDFdICsgbGluZXNbaWR4IC0gMV0ubGVuZ3RoICsgMVxuICAgICAgICAgICAgICA6IC8vIGZpcnN0IHNlbGVjdGVkIGxpbmVcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydCxcbiAgICAgICAgICApLFxuICAgICAgICBbXSBhcyBudW1iZXJbXSxcbiAgICAgIClcbiAgICAgIC5yZXZlcnNlKCk7XG4gIH07XG5cbiAgY29uc3Qgc3RvcEV2ZW50ID0gKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH07XG5cbiAgLy8gdXNpbmcgYSBzdGF0ZSB2YXJpYWJsZSBpbnN0ZWFkIG9mIHBhc3NpbmcgaXQgdG8gdGhlIGhhbmRsZVN1Ym1pdCBjYWxsYmFja1xuICAvLyBzbyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gY3JlYXRlIHNlcGFyYXRlIGEgY2FsbGJhY2sgZm9yIGV2ZW50IGhhbmRsZXJzXG4gIGxldCBzdWJtaXR0ZWRWaWFLZXlib2FyZCA9IGZhbHNlO1xuICBjb25zdCBoYW5kbGVTdWJtaXQgPSAoKSA9PiB7XG4gICAgLy8gY2xlYW51cCBtdXN0IGJlIHJ1biBiZWZvcmUgb25TdWJtaXQgb3RoZXJ3aXNlIHdoZW4gYXBwIGJsdXJzIHRoZSB3eXNpd3lnXG4gICAgLy8gaXQnZCBnZXQgc3R1Y2sgaW4gYW4gaW5maW5pdGUgbG9vcCBvZiBibHVy4oaSb25TdWJtaXQgYWZ0ZXIgd2UgcmUtZm9jdXMgdGhlXG4gICAgLy8gd3lzaXd5ZyBvbiB1cGRhdGVcbiAgICBjbGVhbnVwKCk7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudCA9IFNjZW5lLmdldFNjZW5lKGVsZW1lbnQpPy5nZXRFbGVtZW50KGVsZW1lbnQuaWQpO1xuICAgIGlmICghdXBkYXRlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgd3JhcHBlZFRleHQgPSBcIlwiO1xuICAgIGlmIChpc1RleHRFbGVtZW50KHVwZGF0ZUVsZW1lbnQpICYmIHVwZGF0ZUVsZW1lbnQ/LmNvbnRhaW5lcklkKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBTY2VuZS5nZXRTY2VuZSh1cGRhdGVFbGVtZW50KSEuZ2V0RWxlbWVudChcbiAgICAgICAgdXBkYXRlRWxlbWVudC5jb250YWluZXJJZCxcbiAgICAgICkgYXMgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudDtcblxuICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICB3cmFwcGVkVGV4dCA9IHdyYXBUZXh0KFxuICAgICAgICAgIGVkaXRhYmxlLnZhbHVlLFxuICAgICAgICAgIGdldEZvbnRTdHJpbmcodXBkYXRlRWxlbWVudCksXG4gICAgICAgICAgY29udGFpbmVyLndpZHRoLFxuICAgICAgICApO1xuICAgICAgICBpZiAoaXNUZXh0RWxlbWVudCh1cGRhdGVFbGVtZW50KSAmJiB1cGRhdGVFbGVtZW50LmNvbnRhaW5lcklkKSB7XG4gICAgICAgICAgY29uc3QgZWRpdG9ySGVpZ2h0ID0gTnVtYmVyKGVkaXRhYmxlLnN0eWxlLmhlaWdodC5zbGljZSgwLCAtMikpO1xuICAgICAgICAgIGlmIChlZGl0YWJsZS52YWx1ZSkge1xuICAgICAgICAgICAgbXV0YXRlRWxlbWVudCh1cGRhdGVFbGVtZW50LCB7XG4gICAgICAgICAgICAgIC8vIHZlcnRpY2FsbHkgY2VudGVyIGFsaWduXG4gICAgICAgICAgICAgIHk6IGNvbnRhaW5lci55ICsgY29udGFpbmVyLmhlaWdodCAvIDIgLSBlZGl0b3JIZWlnaHQgLyAyLFxuICAgICAgICAgICAgICBoZWlnaHQ6IGVkaXRvckhlaWdodCxcbiAgICAgICAgICAgICAgd2lkdGg6IE51bWJlcihlZGl0YWJsZS5zdHlsZS53aWR0aC5zbGljZSgwLCAtMikpLFxuICAgICAgICAgICAgICAvLyBwcmVzZXJ2ZSBwYWRkaW5nXG4gICAgICAgICAgICAgIHg6IGNvbnRhaW5lci54ICsgUEFERElORyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgYm91bmRUZXh0RWxlbWVudElkID0gZ2V0Qm91bmRUZXh0RWxlbWVudElkKGNvbnRhaW5lcik7XG4gICAgICAgICAgICBpZiAoIWJvdW5kVGV4dEVsZW1lbnRJZCB8fCBib3VuZFRleHRFbGVtZW50SWQgIT09IGVsZW1lbnQuaWQpIHtcbiAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHtcbiAgICAgICAgICAgICAgICBib3VuZEVsZW1lbnRzOiAoY29udGFpbmVyLmJvdW5kRWxlbWVudHMgfHwgW10pLmNvbmNhdCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHtcbiAgICAgICAgICAgICAgYm91bmRFbGVtZW50czogY29udGFpbmVyLmJvdW5kRWxlbWVudHM/LmZpbHRlcihcbiAgICAgICAgICAgICAgICAoZWxlKSA9PiBlbGUudHlwZSAhPT0gXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgd3JhcHBlZFRleHQgPSBlZGl0YWJsZS52YWx1ZTtcbiAgICB9XG5cbiAgICBvblN1Ym1pdCh7XG4gICAgICB0ZXh0OiBub3JtYWxpemVUZXh0KHdyYXBwZWRUZXh0KSxcbiAgICAgIHZpYUtleWJvYXJkOiBzdWJtaXR0ZWRWaWFLZXlib2FyZCxcbiAgICAgIG9yaWdpbmFsVGV4dDogZWRpdGFibGUudmFsdWUsXG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICBpZiAoaXNEZXN0cm95ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgIC8vIHJlbW92ZSBldmVudHMgdG8gZW5zdXJlIHRoZXkgZG9uJ3QgbGF0ZS1maXJlXG4gICAgZWRpdGFibGUub25ibHVyID0gbnVsbDtcbiAgICBlZGl0YWJsZS5vbmlucHV0ID0gbnVsbDtcbiAgICBlZGl0YWJsZS5vbmtleWRvd24gPSBudWxsO1xuXG4gICAgaWYgKG9ic2VydmVyKSB7XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgdXBkYXRlV3lzaXd5Z1N0eWxlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsIHN0b3BFdmVudCwgdHJ1ZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVyZG93blwiLCBvblBvaW50ZXJEb3duKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCBiaW5kQmx1ckV2ZW50KTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgaGFuZGxlU3VibWl0KTtcblxuICAgIHVuYmluZFVwZGF0ZSgpO1xuXG4gICAgZWRpdGFibGUucmVtb3ZlKCk7XG4gIH07XG5cbiAgY29uc3QgYmluZEJsdXJFdmVudCA9IChldmVudD86IE1vdXNlRXZlbnQpID0+IHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCBiaW5kQmx1ckV2ZW50KTtcbiAgICAvLyBEZWZlcnJlZCBzbyB0aGF0IHRoZSBwb2ludGVyZG93biB0aGF0IGluaXRpYXRlcyB0aGUgd3lzaXd5ZyBkb2Vzbid0XG4gICAgLy8gdHJpZ2dlciB0aGUgYmx1ciBvbiBlbnN1aW5nIHBvaW50ZXJ1cC5cbiAgICAvLyBBbHNvIHRvIGhhbmRsZSBjYXNlcyBzdWNoIGFzIHBpY2tpbmcgYSBjb2xvciB3aGljaCB3b3VsZCB0cmlnZ2VyIGEgYmx1clxuICAgIC8vIGluIHRoYXQgc2FtZSB0aWNrLlxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50Py50YXJnZXQ7XG5cbiAgICBjb25zdCBpc1RhcmdldENvbG9yUGlja2VyID1cbiAgICAgIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiZcbiAgICAgIHRhcmdldC5jbG9zZXN0KFwiLmNvbG9yLXBpY2tlci1pbnB1dFwiKSAmJlxuICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgZWRpdGFibGUub25ibHVyID0gaGFuZGxlU3VibWl0O1xuICAgICAgaWYgKHRhcmdldCAmJiBpc1RhcmdldENvbG9yUGlja2VyKSB7XG4gICAgICAgIHRhcmdldC5vbmJsdXIgPSAoKSA9PiB7XG4gICAgICAgICAgZWRpdGFibGUuZm9jdXMoKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIGNhc2U6IGNsaWNraW5nIG9uIHRoZSBzYW1lIHByb3BlcnR5IOKGkiBubyBjaGFuZ2Ug4oaSIG5vIHVwZGF0ZSDihpIgbm8gZm9jdXNcbiAgICAgIGlmICghaXNUYXJnZXRDb2xvclBpY2tlcikge1xuICAgICAgICBlZGl0YWJsZS5mb2N1cygpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIC8vIHByZXZlbnQgYmx1ciB3aGVuIGNoYW5naW5nIHByb3BlcnRpZXMgZnJvbSB0aGUgbWVudVxuICBjb25zdCBvblBvaW50ZXJEb3duID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNUYXJnZXRDb2xvclBpY2tlciA9XG4gICAgICBldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmXG4gICAgICBldmVudC50YXJnZXQuY2xvc2VzdChcIi5jb2xvci1waWNrZXItaW5wdXRcIikgJiZcbiAgICAgIGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCk7XG4gICAgaWYgKFxuICAgICAgKChldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fFxuICAgICAgICBldmVudC50YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSAmJlxuICAgICAgICBldmVudC50YXJnZXQuY2xvc2VzdChgLiR7Q0xBU1NFUy5TSEFQRV9BQ1RJT05TX01FTlV9YCkgJiZcbiAgICAgICAgIWlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHx8XG4gICAgICBpc1RhcmdldENvbG9yUGlja2VyXG4gICAgKSB7XG4gICAgICBlZGl0YWJsZS5vbmJsdXIgPSBudWxsO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwb2ludGVydXBcIiwgYmluZEJsdXJFdmVudCk7XG4gICAgICAvLyBoYW5kbGUgZWRnZS1jYXNlIHdoZXJlIHBvaW50ZXJ1cCBkb2Vzbid0IGZpcmUgZS5nLiBkdWUgdG8gdXNlclxuICAgICAgLy8gYWx0LXRhYmJpbmcgYXdheVxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIGhhbmRsZVN1Ym1pdCk7XG4gICAgfVxuICB9O1xuXG4gIC8vIGhhbmRsZSB1cGRhdGVzIG9mIHRleHRFbGVtZW50IHByb3BlcnRpZXMgb2YgZWRpdGluZyBlbGVtZW50XG4gIGNvbnN0IHVuYmluZFVwZGF0ZSA9IFNjZW5lLmdldFNjZW5lKGVsZW1lbnQpIS5hZGRDYWxsYmFjaygoKSA9PiB7XG4gICAgdXBkYXRlV3lzaXd5Z1N0eWxlKCk7XG4gICAgY29uc3QgaXNDb2xvclBpY2tlckFjdGl2ZSA9ICEhZG9jdW1lbnQuYWN0aXZlRWxlbWVudD8uY2xvc2VzdChcbiAgICAgIFwiLmNvbG9yLXBpY2tlci1pbnB1dFwiLFxuICAgICk7XG4gICAgaWYgKCFpc0NvbG9yUGlja2VyQWN0aXZlKSB7XG4gICAgICBlZGl0YWJsZS5mb2N1cygpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgbGV0IGlzRGVzdHJveWVkID0gZmFsc2U7XG5cbiAgLy8gc2VsZWN0IG9uIGluaXQgKGZvY3VzaW5nIGlzIGRvbmUgc2VwYXJhdGVseSBpbnNpZGUgdGhlIGJpbmRCbHVyRXZlbnQoKVxuICAvLyBiZWNhdXNlIHdlIG5lZWQgaXQgdG8gaGFwcGVuICphZnRlciogdGhlIGJsdXIgZXZlbnQgZnJvbSBgcG9pbnRlcmRvd25gKVxuICBlZGl0YWJsZS5zZWxlY3QoKTtcbiAgYmluZEJsdXJFdmVudCgpO1xuXG4gIC8vIHJlcG9zaXRpb24gd3lzaXd5ZyBpbiBjYXNlIG9mIGNhbnZhcyBpcyByZXNpemVkLiBVc2luZyBSZXNpemVPYnNlcnZlclxuICAvLyBpcyBwcmVmZXJyZWQgc28gd2UgY2F0Y2ggY2hhbmdlcyBmcm9tIGhvc3QsIHdoZXJlIHdpbmRvdyBtYXkgbm90IHJlc2l6ZS5cbiAgbGV0IG9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IG51bGwgPSBudWxsO1xuICBpZiAoY2FudmFzICYmIFwiUmVzaXplT2JzZXJ2ZXJcIiBpbiB3aW5kb3cpIHtcbiAgICBvYnNlcnZlciA9IG5ldyB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgdXBkYXRlV3lzaXd5Z1N0eWxlKCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShjYW52YXMpO1xuICB9IGVsc2Uge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHVwZGF0ZVd5c2l3eWdTdHlsZSk7XG4gIH1cblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJkb3duXCIsIG9uUG9pbnRlckRvd24pO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsIHN0b3BFdmVudCwge1xuICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgIGNhcHR1cmU6IHRydWUsXG4gIH0pO1xuICBleGNhbGlkcmF3Q29udGFpbmVyXG4gICAgPy5xdWVyeVNlbGVjdG9yKFwiLmV4Y2FsaWRyYXctdGV4dEVkaXRvckNvbnRhaW5lclwiKSFcbiAgICAuYXBwZW5kQ2hpbGQoZWRpdGFibGUpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../element/textWysiwyg.tsx\n");
2546
2546
 
2547
2547
  /***/ }),
2548
2548
 
@@ -3103,7 +3103,7 @@ module.exports = JSON.parse('{"ar-SA":86,"bg-BG":59,"bn-BD":0,"ca-ES":78,"cs-CZ"
3103
3103
  /***/ ((module) => {
3104
3104
 
3105
3105
  "use strict";
3106
- module.exports = JSON.parse('{"name":"@zsviczian/excalidraw","version":"0.10.0-textfix-7","main":"main.js","types":"types/packages/excalidraw/index.d.ts","files":["dist/*","types/*"],"publishConfig":{"access":"public"},"description":"Excalidraw as a React component","repository":"https://github.com/excalidraw/excalidraw","license":"MIT","keywords":["excalidraw","excalidraw-embed","react","npm","npm excalidraw"],"browserslist":{"production":[">0.2%","not dead","not ie <= 11","not op_mini all","not safari < 12","not kaios <= 2.5","not edge < 79","not chrome < 70","not and_uc < 13","not samsung < 10"],"development":["last 1 chrome version","last 1 firefox version","last 1 safari version"]},"peerDependencies":{"react":"^17.0.2","react-dom":"^17.0.2"},"devDependencies":{"@babel/core":"7.16.0","@babel/plugin-transform-arrow-functions":"7.16.0","@babel/plugin-transform-async-to-generator":"7.16.0","@babel/plugin-transform-runtime":"7.16.4","@babel/plugin-transform-typescript":"7.16.1","@babel/preset-env":"7.16.4","@babel/preset-react":"7.16.0","@babel/preset-typescript":"7.16.0","autoprefixer":"10.4.0","babel-loader":"8.2.3","babel-plugin-transform-class-properties":"6.24.1","cross-env":"7.0.3","css-loader":"6.5.1","mini-css-extract-plugin":"2.4.5","postcss-loader":"6.2.1","sass-loader":"12.4.0","terser-webpack-plugin":"5.2.5","ts-loader":"9.2.6","typescript":"4.5.3","webpack":"5.65.0","webpack-bundle-analyzer":"4.5.0","webpack-cli":"4.9.1"},"bugs":"https://github.com/excalidraw/excalidraw/issues","homepage":"https://github.com/excalidraw/excalidraw/tree/master/src/packages/excalidraw","scripts":{"gen:types":"tsc --project ../../../tsconfig-types.json","build:umd":"cross-env NODE_ENV=production webpack --config webpack.prod.config.js && cross-env NODE_ENV=development webpack --config webpack.dev.config.js && yarn gen:types","build:umd:withAnalyzer":"cross-env NODE_ENV=production ANALYZER=true webpack --config webpack.prod.config.js","pack":"yarn build:umd && yarn pack"},"dependencies":{"dotenv":"10.0.0"}}');
3106
+ module.exports = JSON.parse('{"name":"@zsviczian/excalidraw","version":"0.10.0-textfix-11","main":"main.js","types":"types/packages/excalidraw/index.d.ts","files":["dist/*","types/*"],"publishConfig":{"access":"public"},"description":"Excalidraw as a React component","repository":"https://github.com/excalidraw/excalidraw","license":"MIT","keywords":["excalidraw","excalidraw-embed","react","npm","npm excalidraw"],"browserslist":{"production":[">0.2%","not dead","not ie <= 11","not op_mini all","not safari < 12","not kaios <= 2.5","not edge < 79","not chrome < 70","not and_uc < 13","not samsung < 10"],"development":["last 1 chrome version","last 1 firefox version","last 1 safari version"]},"peerDependencies":{"react":"^17.0.2","react-dom":"^17.0.2"},"devDependencies":{"@babel/core":"7.16.0","@babel/plugin-transform-arrow-functions":"7.16.0","@babel/plugin-transform-async-to-generator":"7.16.0","@babel/plugin-transform-runtime":"7.16.4","@babel/plugin-transform-typescript":"7.16.1","@babel/preset-env":"7.16.4","@babel/preset-react":"7.16.0","@babel/preset-typescript":"7.16.0","autoprefixer":"10.4.0","babel-loader":"8.2.3","babel-plugin-transform-class-properties":"6.24.1","cross-env":"7.0.3","css-loader":"6.5.1","mini-css-extract-plugin":"2.4.5","postcss-loader":"6.2.1","sass-loader":"12.4.0","terser-webpack-plugin":"5.2.5","ts-loader":"9.2.6","typescript":"4.5.3","webpack":"5.65.0","webpack-bundle-analyzer":"4.5.0","webpack-cli":"4.9.1"},"bugs":"https://github.com/excalidraw/excalidraw/issues","homepage":"https://github.com/excalidraw/excalidraw/tree/master/src/packages/excalidraw","scripts":{"gen:types":"tsc --project ../../../tsconfig-types.json","build:umd":"cross-env NODE_ENV=production webpack --config webpack.prod.config.js && cross-env NODE_ENV=development webpack --config webpack.dev.config.js && yarn gen:types","build:umd:withAnalyzer":"cross-env NODE_ENV=production ANALYZER=true webpack --config webpack.prod.config.js","pack":"yarn build:umd && yarn pack"},"dependencies":{"dotenv":"10.0.0"}}');
3107
3107
 
3108
3108
  /***/ })
3109
3109