@openmrs/esm-app-shell 11.0.1-pre.5837 → 11.0.1-pre.5906

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/dist/381a84572e6513e4.js +1 -0
  3. package/dist/381a84572e6513e4.js.map +1 -0
  4. package/dist/{7e94e985736f6433.js → 4300cb8b604fb614.js} +1 -1
  5. package/dist/{7e94e985736f6433.js.map → 4300cb8b604fb614.js.map} +1 -1
  6. package/dist/844b2ca831f9e245.js +1 -0
  7. package/dist/844b2ca831f9e245.js.map +1 -0
  8. package/dist/8e42269387164197.js +1 -0
  9. package/dist/8e42269387164197.js.map +1 -0
  10. package/dist/a2e5aaf01fdf9cca.js +28 -0
  11. package/dist/a2e5aaf01fdf9cca.js.map +1 -0
  12. package/dist/bfe9ff79379676ad.js +1 -0
  13. package/dist/{b54834c7cf00760e.js.map → bfe9ff79379676ad.js.map} +1 -1
  14. package/dist/{bc45832208db8c5c.js → c61d49315a9585b1.js} +1 -1
  15. package/dist/c61d49315a9585b1.js.map +1 -0
  16. package/dist/fd4670b294d9fd74.js +1 -0
  17. package/dist/fd4670b294d9fd74.js.map +1 -0
  18. package/dist/index.html +1 -1
  19. package/dist/{openmrs.b158069b013e7685.js → openmrs.eccc976660d1ad85.js} +5 -5
  20. package/dist/{openmrs.b158069b013e7685.js.map → openmrs.eccc976660d1ad85.js.map} +1 -1
  21. package/lib/0114e2ab04d37ef3.js +8 -0
  22. package/lib/{4907fc954ee36d02.js → 45b02f9c93df63a2.js} +1 -1
  23. package/lib/{6fa8075110bb9581.js → 5534cc37564f19d5.js} +1 -11
  24. package/lib/{41733b40a9c3c3a5.js → 5b9ac61b7d510be5.js} +1 -1
  25. package/lib/6c6bdf6043cb0e08.js +8 -0
  26. package/lib/813d7bf7cf53fee8.js +16 -0
  27. package/lib/{3770bd56bfa69f3d.js → a63512181bf7b3b3.js} +55 -60
  28. package/lib/c33c18fc27e1597a.js +12 -0
  29. package/lib/{a8eb6366799b605a.js → c6d69a0ca26da571.js} +2 -2
  30. package/lib/index.html +1 -1
  31. package/lib/openmrs.js +7 -7
  32. package/package.json +3 -3
  33. package/rspack.config.js +16 -1
  34. package/tsconfig.json +1 -1
  35. package/dist/b54834c7cf00760e.js +0 -1
  36. package/dist/bc45832208db8c5c.js.map +0 -1
  37. package/dist/e8f00337999d0568.js +0 -28
  38. package/dist/e8f00337999d0568.js.map +0 -1
  39. package/lib/4afcde165187cf34.js +0 -8
@@ -1906,7 +1906,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webp
1906
1906
  },
1907
1907
  "../../../node_modules/@floating-ui/react/dist/floating-ui.react.mjs"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
1908
1908
  "use strict";
1909
- eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n Composite: () => (Composite),\n CompositeItem: () => (CompositeItem),\n FloatingArrow: () => (FloatingArrow),\n FloatingDelayGroup: () => (FloatingDelayGroup),\n FloatingFocusManager: () => (FloatingFocusManager),\n FloatingList: () => (FloatingList),\n FloatingNode: () => (FloatingNode),\n FloatingOverlay: () => (FloatingOverlay),\n FloatingPortal: () => (FloatingPortal),\n FloatingTree: () => (FloatingTree),\n NextFloatingDelayGroup: () => (NextFloatingDelayGroup),\n arrow: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.arrow),\n autoPlacement: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.autoPlacement),\n autoUpdate: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.autoUpdate),\n computePosition: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.computePosition),\n detectOverflow: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.detectOverflow),\n flip: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.flip),\n getOverflowAncestors: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_5.getOverflowAncestors),\n hide: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.hide),\n inline: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.inline),\n inner: () => (inner),\n limitShift: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.limitShift),\n offset: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.offset),\n platform: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.platform),\n safePolygon: () => (safePolygon),\n shift: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.shift),\n size: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.size),\n useClick: () => (useClick),\n useClientPoint: () => (useClientPoint),\n useDelayGroup: () => (useDelayGroup),\n useDelayGroupContext: () => (useDelayGroupContext),\n useDismiss: () => (useDismiss),\n useFloating: () => (useFloating),\n useFloatingNodeId: () => (useFloatingNodeId),\n useFloatingParentNodeId: () => (useFloatingParentNodeId),\n useFloatingPortalNode: () => (useFloatingPortalNode),\n useFloatingRootContext: () => (useFloatingRootContext),\n useFloatingTree: () => (useFloatingTree),\n useFocus: () => (useFocus),\n useHover: () => (useHover),\n useId: () => (useId),\n useInnerOffset: () => (useInnerOffset),\n useInteractions: () => (useInteractions),\n useListItem: () => (useListItem),\n useListNavigation: () => (useListNavigation),\n useMergeRefs: () => (useMergeRefs),\n useNextDelayGroup: () => (useNextDelayGroup),\n useRole: () => (useRole),\n useTransitionStatus: () => (useTransitionStatus),\n useTransitionStyles: () => (useTransitionStyles),\n useTypeahead: () => (useTypeahead)\n});\n/* import */ var react__rspack_import_0 = __webpack_require__(\"webpack/sharing/consume/default/react/react\");\n/* import */ var react__rspack_import_0_default = /*#__PURE__*/__webpack_require__.n(react__rspack_import_0);\n/* import */ var _floating_ui_react_utils__rspack_import_6 = __webpack_require__(\"../../../node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs\");\n/* import */ var react_jsx_runtime__rspack_import_1 = __webpack_require__(\"../../../node_modules/react/jsx-runtime.js\");\n/* import */ var _floating_ui_react_dom__rspack_import_5 = __webpack_require__(\"../../../node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs\");\n/* import */ var tabbable__rspack_import_7 = __webpack_require__(\"../../../node_modules/tabbable/dist/index.esm.js\");\n/* import */ var react_dom__rspack_import_2 = __webpack_require__(\"webpack/sharing/consume/default/react-dom/react-dom\");\n/* import */ var react_dom__rspack_import_2_default = /*#__PURE__*/__webpack_require__.n(react_dom__rspack_import_2);\n/* import */ var _floating_ui_react_dom__rspack_import_3 = __webpack_require__(\"../../../node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs\");\n/* import */ var _floating_ui_react_dom__rspack_import_4 = __webpack_require__(\"../../../node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs\");\n/* import */ var _floating_ui_utils__rspack_import_8 = __webpack_require__(\"../../../node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs\");\n\n\n\n\n\n\n\n\n\n\n/**\n * Merges an array of refs into a single memoized callback ref or `null`.\n * @see https://floating-ui.com/docs/react-utils#usemergerefs\n */\nfunction useMergeRefs(refs) {\n const cleanupRef = react__rspack_import_0.useRef(undefined);\n const refEffect = react__rspack_import_0.useCallback(instance => {\n const cleanups = refs.map(ref => {\n if (ref == null) {\n return;\n }\n if (typeof ref === 'function') {\n const refCallback = ref;\n const refCleanup = refCallback(instance);\n return typeof refCleanup === 'function' ? refCleanup : () => {\n refCallback(null);\n };\n }\n ref.current = instance;\n return () => {\n ref.current = null;\n };\n });\n return () => {\n cleanups.forEach(refCleanup => refCleanup == null ? void 0 : refCleanup());\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, refs);\n return react__rspack_import_0.useMemo(() => {\n if (refs.every(ref => ref == null)) {\n return null;\n }\n return value => {\n if (cleanupRef.current) {\n cleanupRef.current();\n cleanupRef.current = undefined;\n }\n if (value != null) {\n cleanupRef.current = refEffect(value);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, refs);\n}\n\nfunction sortByDocumentPosition(a, b) {\n const position = a.compareDocumentPosition(b);\n if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n return -1;\n }\n if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) {\n return 1;\n }\n return 0;\n}\nconst FloatingListContext = /*#__PURE__*/react__rspack_import_0.createContext({\n register: () => {},\n unregister: () => {},\n map: /*#__PURE__*/new Map(),\n elementsRef: {\n current: []\n }\n});\n/**\n * Provides context for a list of items within the floating element.\n * @see https://floating-ui.com/docs/FloatingList\n */\nfunction FloatingList(props) {\n const {\n children,\n elementsRef,\n labelsRef\n } = props;\n const [nodes, setNodes] = react__rspack_import_0.useState(() => new Set());\n const register = react__rspack_import_0.useCallback(node => {\n setNodes(prevSet => new Set(prevSet).add(node));\n }, []);\n const unregister = react__rspack_import_0.useCallback(node => {\n setNodes(prevSet => {\n const set = new Set(prevSet);\n set.delete(node);\n return set;\n });\n }, []);\n const map = react__rspack_import_0.useMemo(() => {\n const newMap = new Map();\n const sortedNodes = Array.from(nodes.keys()).sort(sortByDocumentPosition);\n sortedNodes.forEach((node, index) => {\n newMap.set(node, index);\n });\n return newMap;\n }, [nodes]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingListContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n register,\n unregister,\n map,\n elementsRef,\n labelsRef\n }), [register, unregister, map, elementsRef, labelsRef]),\n children: children\n });\n}\n/**\n * Used to register a list item and its index (DOM position) in the\n * `FloatingList`.\n * @see https://floating-ui.com/docs/FloatingList#uselistitem\n */\nfunction useListItem(props) {\n if (props === void 0) {\n props = {};\n }\n const {\n label\n } = props;\n const {\n register,\n unregister,\n map,\n elementsRef,\n labelsRef\n } = react__rspack_import_0.useContext(FloatingListContext);\n const [index, setIndex] = react__rspack_import_0.useState(null);\n const componentRef = react__rspack_import_0.useRef(null);\n const ref = react__rspack_import_0.useCallback(node => {\n componentRef.current = node;\n if (index !== null) {\n elementsRef.current[index] = node;\n if (labelsRef) {\n var _node$textContent;\n const isLabelDefined = label !== undefined;\n labelsRef.current[index] = isLabelDefined ? label : (_node$textContent = node == null ? void 0 : node.textContent) != null ? _node$textContent : null;\n }\n }\n }, [index, elementsRef, labelsRef, label]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n const node = componentRef.current;\n if (node) {\n register(node);\n return () => {\n unregister(node);\n };\n }\n }, [register, unregister]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n const index = componentRef.current ? map.get(componentRef.current) : null;\n if (index != null) {\n setIndex(index);\n }\n }, [map]);\n return react__rspack_import_0.useMemo(() => ({\n ref,\n index: index == null ? -1 : index\n }), [index, ref]);\n}\n\nconst FOCUSABLE_ATTRIBUTE = 'data-floating-ui-focusable';\nconst ACTIVE_KEY = 'active';\nconst SELECTED_KEY = 'selected';\nconst ARROW_LEFT = 'ArrowLeft';\nconst ARROW_RIGHT = 'ArrowRight';\nconst ARROW_UP = 'ArrowUp';\nconst ARROW_DOWN = 'ArrowDown';\n\nfunction renderJsx(render, computedProps) {\n if (typeof render === 'function') {\n return render(computedProps);\n }\n if (render) {\n return /*#__PURE__*/react__rspack_import_0.cloneElement(render, computedProps);\n }\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"div\", {\n ...computedProps\n });\n}\nconst CompositeContext = /*#__PURE__*/react__rspack_import_0.createContext({\n activeIndex: 0,\n onNavigate: () => {}\n});\nconst horizontalKeys = [ARROW_LEFT, ARROW_RIGHT];\nconst verticalKeys = [ARROW_UP, ARROW_DOWN];\nconst allKeys = [...horizontalKeys, ...verticalKeys];\n\n/**\n * Creates a single tab stop whose items are navigated by arrow keys, which\n * provides list navigation outside of floating element contexts.\n *\n * This is useful to enable navigation of a list of items that aren’t part of a\n * floating element. A menubar is an example of a composite, with each reference\n * element being an item.\n * @see https://floating-ui.com/docs/Composite\n */\nconst Composite = /*#__PURE__*/react__rspack_import_0.forwardRef(function Composite(props, forwardedRef) {\n const {\n render,\n orientation = 'both',\n loop = true,\n rtl = false,\n cols = 1,\n disabledIndices,\n activeIndex: externalActiveIndex,\n onNavigate: externalSetActiveIndex,\n itemSizes,\n dense = false,\n ...domProps\n } = props;\n const [internalActiveIndex, internalSetActiveIndex] = react__rspack_import_0.useState(0);\n const activeIndex = externalActiveIndex != null ? externalActiveIndex : internalActiveIndex;\n const onNavigate = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(externalSetActiveIndex != null ? externalSetActiveIndex : internalSetActiveIndex);\n const elementsRef = react__rspack_import_0.useRef([]);\n const renderElementProps = render && typeof render !== 'function' ? render.props : {};\n const contextValue = react__rspack_import_0.useMemo(() => ({\n activeIndex,\n onNavigate\n }), [activeIndex, onNavigate]);\n const isGrid = cols > 1;\n function handleKeyDown(event) {\n if (!allKeys.includes(event.key)) return;\n let nextIndex = activeIndex;\n const minIndex = (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(elementsRef, disabledIndices);\n const maxIndex = (0,_floating_ui_react_utils__rspack_import_6.getMaxListIndex)(elementsRef, disabledIndices);\n const horizontalEndKey = rtl ? ARROW_LEFT : ARROW_RIGHT;\n const horizontalStartKey = rtl ? ARROW_RIGHT : ARROW_LEFT;\n if (isGrid) {\n const sizes = itemSizes || Array.from({\n length: elementsRef.current.length\n }, () => ({\n width: 1,\n height: 1\n }));\n // To calculate movements on the grid, we use hypothetical cell indices\n // as if every item was 1x1, then convert back to real indices.\n const cellMap = (0,_floating_ui_react_utils__rspack_import_6.createGridCellMap)(sizes, cols, dense);\n const minGridIndex = cellMap.findIndex(index => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(elementsRef, index, disabledIndices));\n // last enabled index\n const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(elementsRef, index, disabledIndices) ? cellIndex : foundIndex, -1);\n const maybeNextIndex = cellMap[(0,_floating_ui_react_utils__rspack_import_6.getGridNavigatedIndex)({\n current: cellMap.map(itemIndex => itemIndex ? elementsRef.current[itemIndex] : null)\n }, {\n event,\n orientation,\n loop,\n rtl,\n cols,\n // treat undefined (empty grid spaces) as disabled indices so we\n // don't end up in them\n disabledIndices: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndices)([...(disabledIndices || elementsRef.current.map((_, index) => (0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(elementsRef, index) ? index : undefined)), undefined], cellMap),\n minIndex: minGridIndex,\n maxIndex: maxGridIndex,\n prevIndex: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndexOfCorner)(activeIndex > maxIndex ? minIndex : activeIndex, sizes, cellMap, cols,\n // use a corner matching the edge closest to the direction we're\n // moving in so we don't end up in the same item. Prefer\n // top/left over bottom/right.\n event.key === ARROW_DOWN ? 'bl' : event.key === horizontalEndKey ? 'tr' : 'tl')\n })];\n if (maybeNextIndex != null) {\n nextIndex = maybeNextIndex;\n }\n }\n const toEndKeys = {\n horizontal: [horizontalEndKey],\n vertical: [ARROW_DOWN],\n both: [horizontalEndKey, ARROW_DOWN]\n }[orientation];\n const toStartKeys = {\n horizontal: [horizontalStartKey],\n vertical: [ARROW_UP],\n both: [horizontalStartKey, ARROW_UP]\n }[orientation];\n const preventedKeys = isGrid ? allKeys : {\n horizontal: horizontalKeys,\n vertical: verticalKeys,\n both: allKeys\n }[orientation];\n if (nextIndex === activeIndex && [...toEndKeys, ...toStartKeys].includes(event.key)) {\n if (loop && nextIndex === maxIndex && toEndKeys.includes(event.key)) {\n nextIndex = minIndex;\n } else if (loop && nextIndex === minIndex && toStartKeys.includes(event.key)) {\n nextIndex = maxIndex;\n } else {\n nextIndex = (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(elementsRef, {\n startingIndex: nextIndex,\n decrement: toStartKeys.includes(event.key),\n disabledIndices\n });\n }\n }\n if (nextIndex !== activeIndex && !(0,_floating_ui_react_utils__rspack_import_6.isIndexOutOfListBounds)(elementsRef, nextIndex)) {\n var _elementsRef$current$;\n event.stopPropagation();\n if (preventedKeys.includes(event.key)) {\n event.preventDefault();\n }\n onNavigate(nextIndex);\n (_elementsRef$current$ = elementsRef.current[nextIndex]) == null || _elementsRef$current$.focus();\n }\n }\n const computedProps = {\n ...domProps,\n ...renderElementProps,\n ref: forwardedRef,\n 'aria-orientation': orientation === 'both' ? undefined : orientation,\n onKeyDown(e) {\n domProps.onKeyDown == null || domProps.onKeyDown(e);\n renderElementProps.onKeyDown == null || renderElementProps.onKeyDown(e);\n handleKeyDown(e);\n }\n };\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(CompositeContext.Provider, {\n value: contextValue,\n children: /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingList, {\n elementsRef: elementsRef,\n children: renderJsx(render, computedProps)\n })\n });\n});\n/**\n * @see https://floating-ui.com/docs/Composite\n */\nconst CompositeItem = /*#__PURE__*/react__rspack_import_0.forwardRef(function CompositeItem(props, forwardedRef) {\n const {\n render,\n ...domProps\n } = props;\n const renderElementProps = render && typeof render !== 'function' ? render.props : {};\n const {\n activeIndex,\n onNavigate\n } = react__rspack_import_0.useContext(CompositeContext);\n const {\n ref,\n index\n } = useListItem();\n const mergedRef = useMergeRefs([ref, forwardedRef, renderElementProps.ref]);\n const isActive = activeIndex === index;\n const computedProps = {\n ...domProps,\n ...renderElementProps,\n ref: mergedRef,\n tabIndex: isActive ? 0 : -1,\n 'data-active': isActive ? '' : undefined,\n onFocus(e) {\n domProps.onFocus == null || domProps.onFocus(e);\n renderElementProps.onFocus == null || renderElementProps.onFocus(e);\n onNavigate(index);\n }\n };\n return renderJsx(render, computedProps);\n});\n\n// https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379\nconst SafeReact = {\n ...react__rspack_import_0\n};\n\nlet serverHandoffComplete = false;\nlet count = 0;\nconst genId = () => // Ensure the id is unique with multiple independent versions of Floating UI\n// on <React 18\n\"floating-ui-\" + Math.random().toString(36).slice(2, 6) + count++;\nfunction useFloatingId() {\n const [id, setId] = react__rspack_import_0.useState(() => serverHandoffComplete ? genId() : undefined);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (id == null) {\n setId(genId());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n react__rspack_import_0.useEffect(() => {\n serverHandoffComplete = true;\n }, []);\n return id;\n}\nconst useReactId = SafeReact.useId;\n\n/**\n * Uses React 18's built-in `useId()` when available, or falls back to a\n * slightly less performant (requiring a double render) implementation for\n * earlier React versions.\n * @see https://floating-ui.com/docs/react-utils#useid\n */\nconst useId = useReactId || useFloatingId;\n\nlet devMessageSet;\nif (true) {\n devMessageSet = /*#__PURE__*/new Set();\n}\nfunction warn() {\n var _devMessageSet;\n for (var _len = arguments.length, messages = new Array(_len), _key = 0; _key < _len; _key++) {\n messages[_key] = arguments[_key];\n }\n const message = \"Floating UI: \" + messages.join(' ');\n if (!((_devMessageSet = devMessageSet) != null && _devMessageSet.has(message))) {\n var _devMessageSet2;\n (_devMessageSet2 = devMessageSet) == null || _devMessageSet2.add(message);\n console.warn(message);\n }\n}\nfunction error() {\n var _devMessageSet3;\n for (var _len2 = arguments.length, messages = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n messages[_key2] = arguments[_key2];\n }\n const message = \"Floating UI: \" + messages.join(' ');\n if (!((_devMessageSet3 = devMessageSet) != null && _devMessageSet3.has(message))) {\n var _devMessageSet4;\n (_devMessageSet4 = devMessageSet) == null || _devMessageSet4.add(message);\n console.error(message);\n }\n}\n\n/**\n * Renders a pointing arrow triangle.\n * @see https://floating-ui.com/docs/FloatingArrow\n */\nconst FloatingArrow = /*#__PURE__*/react__rspack_import_0.forwardRef(function FloatingArrow(props, ref) {\n const {\n context: {\n placement,\n elements: {\n floating\n },\n middlewareData: {\n arrow,\n shift\n }\n },\n width = 14,\n height = 7,\n tipRadius = 0,\n strokeWidth = 0,\n staticOffset,\n stroke,\n d,\n style: {\n transform,\n ...restStyle\n } = {},\n ...rest\n } = props;\n if (true) {\n if (!ref) {\n warn('The `ref` prop is required for `FloatingArrow`.');\n }\n }\n const clipPathId = useId();\n const [isRTL, setIsRTL] = react__rspack_import_0.useState(false);\n\n // https://github.com/floating-ui/floating-ui/issues/2932\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!floating) return;\n const isRTL = (0,_floating_ui_react_dom__rspack_import_5.getComputedStyle)(floating).direction === 'rtl';\n if (isRTL) {\n setIsRTL(true);\n }\n }, [floating]);\n if (!floating) {\n return null;\n }\n const [side, alignment] = placement.split('-');\n const isVerticalSide = side === 'top' || side === 'bottom';\n let computedStaticOffset = staticOffset;\n if (isVerticalSide && shift != null && shift.x || !isVerticalSide && shift != null && shift.y) {\n computedStaticOffset = null;\n }\n\n // Strokes must be double the border width, this ensures the stroke's width\n // works as you'd expect.\n const computedStrokeWidth = strokeWidth * 2;\n const halfStrokeWidth = computedStrokeWidth / 2;\n const svgX = width / 2 * (tipRadius / -8 + 1);\n const svgY = height / 2 * tipRadius / 4;\n const isCustomShape = !!d;\n const yOffsetProp = computedStaticOffset && alignment === 'end' ? 'bottom' : 'top';\n let xOffsetProp = computedStaticOffset && alignment === 'end' ? 'right' : 'left';\n if (computedStaticOffset && isRTL) {\n xOffsetProp = alignment === 'end' ? 'left' : 'right';\n }\n const arrowX = (arrow == null ? void 0 : arrow.x) != null ? computedStaticOffset || arrow.x : '';\n const arrowY = (arrow == null ? void 0 : arrow.y) != null ? computedStaticOffset || arrow.y : '';\n const dValue = d || 'M0,0' + (\" H\" + width) + (\" L\" + (width - svgX) + \",\" + (height - svgY)) + (\" Q\" + width / 2 + \",\" + height + \" \" + svgX + \",\" + (height - svgY)) + ' Z';\n const rotation = {\n top: isCustomShape ? 'rotate(180deg)' : '',\n left: isCustomShape ? 'rotate(90deg)' : 'rotate(-90deg)',\n bottom: isCustomShape ? '' : 'rotate(180deg)',\n right: isCustomShape ? 'rotate(-90deg)' : 'rotate(90deg)'\n }[side];\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsxs)(\"svg\", {\n ...rest,\n \"aria-hidden\": true,\n ref: ref,\n width: isCustomShape ? width : width + computedStrokeWidth,\n height: width,\n viewBox: \"0 0 \" + width + \" \" + (height > width ? height : width),\n style: {\n position: 'absolute',\n pointerEvents: 'none',\n [xOffsetProp]: arrowX,\n [yOffsetProp]: arrowY,\n [side]: isVerticalSide || isCustomShape ? '100%' : \"calc(100% - \" + computedStrokeWidth / 2 + \"px)\",\n transform: [rotation, transform].filter(t => !!t).join(' '),\n ...restStyle\n },\n children: [computedStrokeWidth > 0 && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"path\", {\n clipPath: \"url(#\" + clipPathId + \")\",\n fill: \"none\",\n stroke: stroke\n // Account for the stroke on the fill path rendered below.\n ,\n strokeWidth: computedStrokeWidth + (d ? 0 : 1),\n d: dValue\n }), /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"path\", {\n stroke: computedStrokeWidth && !d ? rest.fill : 'none',\n d: dValue\n }), /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"clipPath\", {\n id: clipPathId,\n children: /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"rect\", {\n x: -halfStrokeWidth,\n y: halfStrokeWidth * (isCustomShape ? -1 : 1),\n width: width + computedStrokeWidth,\n height: width\n })\n })]\n });\n});\n\nfunction createEventEmitter() {\n const map = new Map();\n return {\n emit(event, data) {\n var _map$get;\n (_map$get = map.get(event)) == null || _map$get.forEach(listener => listener(data));\n },\n on(event, listener) {\n if (!map.has(event)) {\n map.set(event, new Set());\n }\n map.get(event).add(listener);\n },\n off(event, listener) {\n var _map$get2;\n (_map$get2 = map.get(event)) == null || _map$get2.delete(listener);\n }\n };\n}\n\nconst FloatingNodeContext = /*#__PURE__*/react__rspack_import_0.createContext(null);\nconst FloatingTreeContext = /*#__PURE__*/react__rspack_import_0.createContext(null);\n\n/**\n * Returns the parent node id for nested floating elements, if available.\n * Returns `null` for top-level floating elements.\n */\nconst useFloatingParentNodeId = () => {\n var _React$useContext;\n return ((_React$useContext = react__rspack_import_0.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;\n};\n\n/**\n * Returns the nearest floating tree context, if available.\n */\nconst useFloatingTree = () => react__rspack_import_0.useContext(FloatingTreeContext);\n\n/**\n * Registers a node into the `FloatingTree`, returning its id.\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction useFloatingNodeId(customParentId) {\n const id = useId();\n const tree = useFloatingTree();\n const reactParentId = useFloatingParentNodeId();\n const parentId = customParentId || reactParentId;\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!id) return;\n const node = {\n id,\n parentId\n };\n tree == null || tree.addNode(node);\n return () => {\n tree == null || tree.removeNode(node);\n };\n }, [tree, id, parentId]);\n return id;\n}\n/**\n * Provides parent node context for nested floating elements.\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction FloatingNode(props) {\n const {\n children,\n id\n } = props;\n const parentId = useFloatingParentNodeId();\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingNodeContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n id,\n parentId\n }), [id, parentId]),\n children: children\n });\n}\n/**\n * Provides context for nested floating elements when they are not children of\n * each other on the DOM.\n * This is not necessary in all cases, except when there must be explicit communication between parent and child floating elements. It is necessary for:\n * - The `bubbles` option in the `useDismiss()` Hook\n * - Nested virtual list navigation\n * - Nested floating elements that each open on hover\n * - Custom communication between parent and child floating elements\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction FloatingTree(props) {\n const {\n children\n } = props;\n const nodesRef = react__rspack_import_0.useRef([]);\n const addNode = react__rspack_import_0.useCallback(node => {\n nodesRef.current = [...nodesRef.current, node];\n }, []);\n const removeNode = react__rspack_import_0.useCallback(node => {\n nodesRef.current = nodesRef.current.filter(n => n !== node);\n }, []);\n const [events] = react__rspack_import_0.useState(() => createEventEmitter());\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingTreeContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n nodesRef,\n addNode,\n removeNode,\n events\n }), [addNode, removeNode, events]),\n children: children\n });\n}\n\nfunction createAttribute(name) {\n return \"data-floating-ui-\" + name;\n}\n\nfunction clearTimeoutIfSet(timeoutRef) {\n if (timeoutRef.current !== -1) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = -1;\n }\n}\n\nconst safePolygonIdentifier = /*#__PURE__*/createAttribute('safe-polygon');\nfunction getDelay(value, prop, pointerType) {\n if (pointerType && !(0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType)) {\n return 0;\n }\n if (typeof value === 'number') {\n return value;\n }\n if (typeof value === 'function') {\n const result = value();\n if (typeof result === 'number') {\n return result;\n }\n return result == null ? void 0 : result[prop];\n }\n return value == null ? void 0 : value[prop];\n}\nfunction getRestMs(value) {\n if (typeof value === 'function') {\n return value();\n }\n return value;\n}\n/**\n * Opens the floating element while hovering over the reference element, like\n * CSS `:hover`.\n * @see https://floating-ui.com/docs/useHover\n */\nfunction useHover(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n dataRef,\n events,\n elements\n } = context;\n const {\n enabled = true,\n delay = 0,\n handleClose = null,\n mouseOnly = false,\n restMs = 0,\n move = true\n } = props;\n const tree = useFloatingTree();\n const parentId = useFloatingParentNodeId();\n const handleCloseRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(handleClose);\n const delayRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(delay);\n const openRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(open);\n const restMsRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(restMs);\n const pointerTypeRef = react__rspack_import_0.useRef();\n const timeoutRef = react__rspack_import_0.useRef(-1);\n const handlerRef = react__rspack_import_0.useRef();\n const restTimeoutRef = react__rspack_import_0.useRef(-1);\n const blockMouseMoveRef = react__rspack_import_0.useRef(true);\n const performedPointerEventsMutationRef = react__rspack_import_0.useRef(false);\n const unbindMouseMoveRef = react__rspack_import_0.useRef(() => {});\n const restTimeoutPendingRef = react__rspack_import_0.useRef(false);\n const isHoverOpen = react__rspack_import_0.useCallback(() => {\n var _dataRef$current$open;\n const type = (_dataRef$current$open = dataRef.current.openEvent) == null ? void 0 : _dataRef$current$open.type;\n return (type == null ? void 0 : type.includes('mouse')) && type !== 'mousedown';\n }, [dataRef]);\n\n // When closing before opening, clear the delay timeouts to cancel it\n // from showing.\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onOpenChange(_ref) {\n let {\n open\n } = _ref;\n if (!open) {\n clearTimeoutIfSet(timeoutRef);\n clearTimeoutIfSet(restTimeoutRef);\n blockMouseMoveRef.current = true;\n restTimeoutPendingRef.current = false;\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n };\n }, [enabled, events]);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n if (!handleCloseRef.current) return;\n if (!open) return;\n function onLeave(event) {\n if (isHoverOpen()) {\n onOpenChange(false, event, 'hover');\n }\n }\n const html = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).documentElement;\n html.addEventListener('mouseleave', onLeave);\n return () => {\n html.removeEventListener('mouseleave', onLeave);\n };\n }, [elements.floating, open, onOpenChange, enabled, handleCloseRef, isHoverOpen]);\n const closeWithDelay = react__rspack_import_0.useCallback(function (event, runElseBranch, reason) {\n if (runElseBranch === void 0) {\n runElseBranch = true;\n }\n if (reason === void 0) {\n reason = 'hover';\n }\n const closeDelay = getDelay(delayRef.current, 'close', pointerTypeRef.current);\n if (closeDelay && !handlerRef.current) {\n clearTimeoutIfSet(timeoutRef);\n timeoutRef.current = window.setTimeout(() => onOpenChange(false, event, reason), closeDelay);\n } else if (runElseBranch) {\n clearTimeoutIfSet(timeoutRef);\n onOpenChange(false, event, reason);\n }\n }, [delayRef, onOpenChange]);\n const cleanupMouseMoveHandler = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n unbindMouseMoveRef.current();\n handlerRef.current = undefined;\n });\n const clearPointerEvents = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n if (performedPointerEventsMutationRef.current) {\n const body = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).body;\n body.style.pointerEvents = '';\n body.removeAttribute(safePolygonIdentifier);\n performedPointerEventsMutationRef.current = false;\n }\n });\n const isClickLikeOpenEvent = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n return dataRef.current.openEvent ? ['click', 'mousedown'].includes(dataRef.current.openEvent.type) : false;\n });\n\n // Registering the mouse events on the reference directly to bypass React's\n // delegation system. If the cursor was on a disabled element and then entered\n // the reference (no gap), `mouseenter` doesn't fire in the delegation system.\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onReferenceMouseEnter(event) {\n clearTimeoutIfSet(timeoutRef);\n blockMouseMoveRef.current = false;\n if (mouseOnly && !(0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerTypeRef.current) || getRestMs(restMsRef.current) > 0 && !getDelay(delayRef.current, 'open')) {\n return;\n }\n const openDelay = getDelay(delayRef.current, 'open', pointerTypeRef.current);\n if (openDelay) {\n timeoutRef.current = window.setTimeout(() => {\n if (!openRef.current) {\n onOpenChange(true, event, 'hover');\n }\n }, openDelay);\n } else if (!open) {\n onOpenChange(true, event, 'hover');\n }\n }\n function onReferenceMouseLeave(event) {\n if (isClickLikeOpenEvent()) {\n clearPointerEvents();\n return;\n }\n unbindMouseMoveRef.current();\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating);\n clearTimeoutIfSet(restTimeoutRef);\n restTimeoutPendingRef.current = false;\n if (handleCloseRef.current && dataRef.current.floatingContext) {\n // Prevent clearing `onScrollMouseLeave` timeout.\n if (!open) {\n clearTimeoutIfSet(timeoutRef);\n }\n handlerRef.current = handleCloseRef.current({\n ...dataRef.current.floatingContext,\n tree,\n x: event.clientX,\n y: event.clientY,\n onClose() {\n clearPointerEvents();\n cleanupMouseMoveHandler();\n if (!isClickLikeOpenEvent()) {\n closeWithDelay(event, true, 'safe-polygon');\n }\n }\n });\n const handler = handlerRef.current;\n doc.addEventListener('mousemove', handler);\n unbindMouseMoveRef.current = () => {\n doc.removeEventListener('mousemove', handler);\n };\n return;\n }\n\n // Allow interactivity without `safePolygon` on touch devices. With a\n // pointer, a short close delay is an alternative, so it should work\n // consistently.\n const shouldClose = pointerTypeRef.current === 'touch' ? !(0,_floating_ui_react_utils__rspack_import_6.contains)(elements.floating, event.relatedTarget) : true;\n if (shouldClose) {\n closeWithDelay(event);\n }\n }\n\n // Ensure the floating element closes after scrolling even if the pointer\n // did not move.\n // https://github.com/floating-ui/floating-ui/discussions/1692\n function onScrollMouseLeave(event) {\n if (isClickLikeOpenEvent()) return;\n if (!dataRef.current.floatingContext) return;\n handleCloseRef.current == null || handleCloseRef.current({\n ...dataRef.current.floatingContext,\n tree,\n x: event.clientX,\n y: event.clientY,\n onClose() {\n clearPointerEvents();\n cleanupMouseMoveHandler();\n if (!isClickLikeOpenEvent()) {\n closeWithDelay(event);\n }\n }\n })(event);\n }\n function onFloatingMouseEnter() {\n clearTimeoutIfSet(timeoutRef);\n }\n function onFloatingMouseLeave(event) {\n if (!isClickLikeOpenEvent()) {\n closeWithDelay(event, false);\n }\n }\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.domReference)) {\n const reference = elements.domReference;\n const floating = elements.floating;\n if (open) {\n reference.addEventListener('mouseleave', onScrollMouseLeave);\n }\n if (move) {\n reference.addEventListener('mousemove', onReferenceMouseEnter, {\n once: true\n });\n }\n reference.addEventListener('mouseenter', onReferenceMouseEnter);\n reference.addEventListener('mouseleave', onReferenceMouseLeave);\n if (floating) {\n floating.addEventListener('mouseleave', onScrollMouseLeave);\n floating.addEventListener('mouseenter', onFloatingMouseEnter);\n floating.addEventListener('mouseleave', onFloatingMouseLeave);\n }\n return () => {\n if (open) {\n reference.removeEventListener('mouseleave', onScrollMouseLeave);\n }\n if (move) {\n reference.removeEventListener('mousemove', onReferenceMouseEnter);\n }\n reference.removeEventListener('mouseenter', onReferenceMouseEnter);\n reference.removeEventListener('mouseleave', onReferenceMouseLeave);\n if (floating) {\n floating.removeEventListener('mouseleave', onScrollMouseLeave);\n floating.removeEventListener('mouseenter', onFloatingMouseEnter);\n floating.removeEventListener('mouseleave', onFloatingMouseLeave);\n }\n };\n }\n }, [elements, enabled, context, mouseOnly, move, closeWithDelay, cleanupMouseMoveHandler, clearPointerEvents, onOpenChange, open, openRef, tree, delayRef, handleCloseRef, dataRef, isClickLikeOpenEvent, restMsRef]);\n\n // Block pointer-events of every element other than the reference and floating\n // while the floating element is open and has a `handleClose` handler. Also\n // handles nested floating elements.\n // https://github.com/floating-ui/floating-ui/issues/1722\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n var _handleCloseRef$curre;\n if (!enabled) return;\n if (open && (_handleCloseRef$curre = handleCloseRef.current) != null && _handleCloseRef$curre.__options.blockPointerEvents && isHoverOpen()) {\n performedPointerEventsMutationRef.current = true;\n const floatingEl = elements.floating;\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.domReference) && floatingEl) {\n var _tree$nodesRef$curren;\n const body = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).body;\n body.setAttribute(safePolygonIdentifier, '');\n const ref = elements.domReference;\n const parentFloating = tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null ? void 0 : _tree$nodesRef$curren.elements.floating;\n if (parentFloating) {\n parentFloating.style.pointerEvents = '';\n }\n body.style.pointerEvents = 'none';\n ref.style.pointerEvents = 'auto';\n floatingEl.style.pointerEvents = 'auto';\n return () => {\n body.style.pointerEvents = '';\n ref.style.pointerEvents = '';\n floatingEl.style.pointerEvents = '';\n };\n }\n }\n }, [enabled, open, parentId, elements, tree, handleCloseRef, isHoverOpen]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!open) {\n pointerTypeRef.current = undefined;\n restTimeoutPendingRef.current = false;\n cleanupMouseMoveHandler();\n clearPointerEvents();\n }\n }, [open, cleanupMouseMoveHandler, clearPointerEvents]);\n react__rspack_import_0.useEffect(() => {\n return () => {\n cleanupMouseMoveHandler();\n clearTimeoutIfSet(timeoutRef);\n clearTimeoutIfSet(restTimeoutRef);\n clearPointerEvents();\n };\n }, [enabled, elements.domReference, cleanupMouseMoveHandler, clearPointerEvents]);\n const reference = react__rspack_import_0.useMemo(() => {\n function setPointerRef(event) {\n pointerTypeRef.current = event.pointerType;\n }\n return {\n onPointerDown: setPointerRef,\n onPointerEnter: setPointerRef,\n onMouseMove(event) {\n const {\n nativeEvent\n } = event;\n function handleMouseMove() {\n if (!blockMouseMoveRef.current && !openRef.current) {\n onOpenChange(true, nativeEvent, 'hover');\n }\n }\n if (mouseOnly && !(0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerTypeRef.current)) {\n return;\n }\n if (open || getRestMs(restMsRef.current) === 0) {\n return;\n }\n\n // Ignore insignificant movements to account for tremors.\n if (restTimeoutPendingRef.current && event.movementX ** 2 + event.movementY ** 2 < 2) {\n return;\n }\n clearTimeoutIfSet(restTimeoutRef);\n if (pointerTypeRef.current === 'touch') {\n handleMouseMove();\n } else {\n restTimeoutPendingRef.current = true;\n restTimeoutRef.current = window.setTimeout(handleMouseMove, getRestMs(restMsRef.current));\n }\n }\n };\n }, [mouseOnly, onOpenChange, open, openRef, restMsRef]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nconst NOOP = () => {};\nconst FloatingDelayGroupContext = /*#__PURE__*/react__rspack_import_0.createContext({\n delay: 0,\n initialDelay: 0,\n timeoutMs: 0,\n currentId: null,\n setCurrentId: NOOP,\n setState: NOOP,\n isInstantPhase: false\n});\n\n/**\n * @deprecated\n * Use the return value of `useDelayGroup()` instead.\n */\nconst useDelayGroupContext = () => react__rspack_import_0.useContext(FloatingDelayGroupContext);\n/**\n * Provides context for a group of floating elements that should share a\n * `delay`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction FloatingDelayGroup(props) {\n const {\n children,\n delay,\n timeoutMs = 0\n } = props;\n const [state, setState] = react__rspack_import_0.useReducer((prev, next) => ({\n ...prev,\n ...next\n }), {\n delay,\n timeoutMs,\n initialDelay: delay,\n currentId: null,\n isInstantPhase: false\n });\n const initialCurrentIdRef = react__rspack_import_0.useRef(null);\n const setCurrentId = react__rspack_import_0.useCallback(currentId => {\n setState({\n currentId\n });\n }, []);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (state.currentId) {\n if (initialCurrentIdRef.current === null) {\n initialCurrentIdRef.current = state.currentId;\n } else if (!state.isInstantPhase) {\n setState({\n isInstantPhase: true\n });\n }\n } else {\n if (state.isInstantPhase) {\n setState({\n isInstantPhase: false\n });\n }\n initialCurrentIdRef.current = null;\n }\n }, [state.currentId, state.isInstantPhase]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingDelayGroupContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n ...state,\n setState,\n setCurrentId\n }), [state, setCurrentId]),\n children: children\n });\n}\n/**\n * Enables grouping when called inside a component that's a child of a\n * `FloatingDelayGroup`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction useDelayGroup(context, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n open,\n onOpenChange,\n floatingId\n } = context;\n const {\n id: optionId,\n enabled = true\n } = options;\n const id = optionId != null ? optionId : floatingId;\n const groupContext = useDelayGroupContext();\n const {\n currentId,\n setCurrentId,\n initialDelay,\n setState,\n timeoutMs\n } = groupContext;\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!currentId) return;\n setState({\n delay: {\n open: 1,\n close: getDelay(initialDelay, 'close')\n }\n });\n if (currentId !== id) {\n onOpenChange(false);\n }\n }, [enabled, id, onOpenChange, setState, currentId, initialDelay]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n function unset() {\n onOpenChange(false);\n setState({\n delay: initialDelay,\n currentId: null\n });\n }\n if (!enabled) return;\n if (!currentId) return;\n if (!open && currentId === id) {\n if (timeoutMs) {\n const timeout = window.setTimeout(unset, timeoutMs);\n return () => {\n clearTimeout(timeout);\n };\n }\n unset();\n }\n }, [enabled, open, setState, currentId, id, onOpenChange, initialDelay, timeoutMs]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (setCurrentId === NOOP || !open) return;\n setCurrentId(id);\n }, [enabled, open, setCurrentId, id]);\n return groupContext;\n}\n\nconst NextFloatingDelayGroupContext = /*#__PURE__*/react__rspack_import_0.createContext({\n hasProvider: false,\n timeoutMs: 0,\n delayRef: {\n current: 0\n },\n initialDelayRef: {\n current: 0\n },\n timeoutIdRef: {\n current: -1\n },\n currentIdRef: {\n current: null\n },\n currentContextRef: {\n current: null\n }\n});\n/**\n * Experimental next version of `FloatingDelayGroup` to become the default\n * in the future. This component is not yet stable.\n * Provides context for a group of floating elements that should share a\n * `delay`. Unlike `FloatingDelayGroup`, `useNextDelayGroup` with this\n * component does not cause a re-render of unrelated consumers of the\n * context when the delay changes.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction NextFloatingDelayGroup(props) {\n const {\n children,\n delay,\n timeoutMs = 0\n } = props;\n const delayRef = react__rspack_import_0.useRef(delay);\n const initialDelayRef = react__rspack_import_0.useRef(delay);\n const currentIdRef = react__rspack_import_0.useRef(null);\n const currentContextRef = react__rspack_import_0.useRef(null);\n const timeoutIdRef = react__rspack_import_0.useRef(-1);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(NextFloatingDelayGroupContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n hasProvider: true,\n delayRef,\n initialDelayRef,\n currentIdRef,\n timeoutMs,\n currentContextRef,\n timeoutIdRef\n }), [timeoutMs]),\n children: children\n });\n}\n/**\n * Enables grouping when called inside a component that's a child of a\n * `NextFloatingDelayGroup`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction useNextDelayGroup(context, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n open,\n onOpenChange,\n floatingId\n } = context;\n const {\n enabled = true\n } = options;\n const groupContext = react__rspack_import_0.useContext(NextFloatingDelayGroupContext);\n const {\n currentIdRef,\n delayRef,\n timeoutMs,\n initialDelayRef,\n currentContextRef,\n hasProvider,\n timeoutIdRef\n } = groupContext;\n const [isInstantPhase, setIsInstantPhase] = react__rspack_import_0.useState(false);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n function unset() {\n var _currentContextRef$cu;\n setIsInstantPhase(false);\n (_currentContextRef$cu = currentContextRef.current) == null || _currentContextRef$cu.setIsInstantPhase(false);\n currentIdRef.current = null;\n currentContextRef.current = null;\n delayRef.current = initialDelayRef.current;\n }\n if (!enabled) return;\n if (!currentIdRef.current) return;\n if (!open && currentIdRef.current === floatingId) {\n setIsInstantPhase(false);\n if (timeoutMs) {\n timeoutIdRef.current = window.setTimeout(unset, timeoutMs);\n return () => {\n clearTimeout(timeoutIdRef.current);\n };\n }\n unset();\n }\n }, [enabled, open, floatingId, currentIdRef, delayRef, timeoutMs, initialDelayRef, currentContextRef, timeoutIdRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!open) return;\n const prevContext = currentContextRef.current;\n const prevId = currentIdRef.current;\n currentContextRef.current = {\n onOpenChange,\n setIsInstantPhase\n };\n currentIdRef.current = floatingId;\n delayRef.current = {\n open: 0,\n close: getDelay(initialDelayRef.current, 'close')\n };\n if (prevId !== null && prevId !== floatingId) {\n clearTimeoutIfSet(timeoutIdRef);\n setIsInstantPhase(true);\n prevContext == null || prevContext.setIsInstantPhase(true);\n prevContext == null || prevContext.onOpenChange(false);\n } else {\n setIsInstantPhase(false);\n prevContext == null || prevContext.setIsInstantPhase(false);\n }\n }, [enabled, open, floatingId, onOpenChange, currentIdRef, delayRef, timeoutMs, initialDelayRef, currentContextRef, timeoutIdRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n return () => {\n currentContextRef.current = null;\n };\n }, [currentContextRef]);\n return react__rspack_import_0.useMemo(() => ({\n hasProvider,\n delayRef,\n isInstantPhase\n }), [hasProvider, delayRef, isInstantPhase]);\n}\n\nlet rafId = 0;\nfunction enqueueFocus(el, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n preventScroll = false,\n cancelPrevious = true,\n sync = false\n } = options;\n cancelPrevious && cancelAnimationFrame(rafId);\n const exec = () => el == null ? void 0 : el.focus({\n preventScroll\n });\n if (sync) {\n exec();\n } else {\n rafId = requestAnimationFrame(exec);\n }\n}\n\nfunction contains(parent, child) {\n if (!parent || !child) {\n return false;\n }\n const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();\n\n // First, attempt with faster native method\n if (parent.contains(child)) {\n return true;\n }\n\n // then fallback to custom implementation with Shadow DOM support\n if (rootNode && (0,_floating_ui_react_dom__rspack_import_5.isShadowRoot)(rootNode)) {\n let next = child;\n while (next) {\n if (parent === next) {\n return true;\n }\n // @ts-ignore\n next = next.parentNode || next.host;\n }\n }\n\n // Give up, the result is false\n return false;\n}\nfunction getTarget(event) {\n if ('composedPath' in event) {\n return event.composedPath()[0];\n }\n\n // TS thinks `event` is of type never as it assumes all browsers support\n // `composedPath()`, but browsers without shadow DOM don't.\n return event.target;\n}\nfunction getDocument(node) {\n return (node == null ? void 0 : node.ownerDocument) || document;\n}\n\n// Modified to add conditional `aria-hidden` support:\n// https://github.com/theKashey/aria-hidden/blob/9220c8f4a4fd35f63bee5510a9f41a37264382d4/src/index.ts\nlet counterMap = /*#__PURE__*/new WeakMap();\nlet uncontrolledElementsSet = /*#__PURE__*/new WeakSet();\nlet markerMap = {};\nlet lockCount$1 = 0;\nconst supportsInert = () => typeof HTMLElement !== 'undefined' && 'inert' in HTMLElement.prototype;\nconst unwrapHost = node => node && (node.host || unwrapHost(node.parentNode));\nconst correctElements = (parent, targets) => targets.map(target => {\n if (parent.contains(target)) {\n return target;\n }\n const correctedTarget = unwrapHost(target);\n if (parent.contains(correctedTarget)) {\n return correctedTarget;\n }\n return null;\n}).filter(x => x != null);\nfunction applyAttributeToOthers(uncorrectedAvoidElements, body, ariaHidden, inert) {\n const markerName = 'data-floating-ui-inert';\n const controlAttribute = inert ? 'inert' : ariaHidden ? 'aria-hidden' : null;\n const avoidElements = correctElements(body, uncorrectedAvoidElements);\n const elementsToKeep = new Set();\n const elementsToStop = new Set(avoidElements);\n const hiddenElements = [];\n if (!markerMap[markerName]) {\n markerMap[markerName] = new WeakMap();\n }\n const markerCounter = markerMap[markerName];\n avoidElements.forEach(keep);\n deep(body);\n elementsToKeep.clear();\n function keep(el) {\n if (!el || elementsToKeep.has(el)) {\n return;\n }\n elementsToKeep.add(el);\n el.parentNode && keep(el.parentNode);\n }\n function deep(parent) {\n if (!parent || elementsToStop.has(parent)) {\n return;\n }\n [].forEach.call(parent.children, node => {\n if ((0,_floating_ui_react_dom__rspack_import_5.getNodeName)(node) === 'script') return;\n if (elementsToKeep.has(node)) {\n deep(node);\n } else {\n const attr = controlAttribute ? node.getAttribute(controlAttribute) : null;\n const alreadyHidden = attr !== null && attr !== 'false';\n const currentCounterValue = counterMap.get(node) || 0;\n const counterValue = controlAttribute ? currentCounterValue + 1 : currentCounterValue;\n const markerValue = (markerCounter.get(node) || 0) + 1;\n counterMap.set(node, counterValue);\n markerCounter.set(node, markerValue);\n hiddenElements.push(node);\n if (counterValue === 1 && alreadyHidden) {\n uncontrolledElementsSet.add(node);\n }\n if (markerValue === 1) {\n node.setAttribute(markerName, '');\n }\n if (!alreadyHidden && controlAttribute) {\n node.setAttribute(controlAttribute, controlAttribute === 'inert' ? '' : 'true');\n }\n }\n });\n }\n lockCount$1++;\n return () => {\n hiddenElements.forEach(element => {\n const currentCounterValue = counterMap.get(element) || 0;\n const counterValue = controlAttribute ? currentCounterValue - 1 : currentCounterValue;\n const markerValue = (markerCounter.get(element) || 0) - 1;\n counterMap.set(element, counterValue);\n markerCounter.set(element, markerValue);\n if (!counterValue) {\n if (!uncontrolledElementsSet.has(element) && controlAttribute) {\n element.removeAttribute(controlAttribute);\n }\n uncontrolledElementsSet.delete(element);\n }\n if (!markerValue) {\n element.removeAttribute(markerName);\n }\n });\n lockCount$1--;\n if (!lockCount$1) {\n counterMap = new WeakMap();\n counterMap = new WeakMap();\n uncontrolledElementsSet = new WeakSet();\n markerMap = {};\n }\n };\n}\nfunction markOthers(avoidElements, ariaHidden, inert) {\n if (ariaHidden === void 0) {\n ariaHidden = false;\n }\n if (inert === void 0) {\n inert = false;\n }\n const body = getDocument(avoidElements[0]).body;\n return applyAttributeToOthers(avoidElements.concat(Array.from(body.querySelectorAll('[aria-live]'))), body, ariaHidden, inert);\n}\n\nconst HIDDEN_STYLES = {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'fixed',\n whiteSpace: 'nowrap',\n width: '1px',\n top: 0,\n left: 0\n};\nconst FocusGuard = /*#__PURE__*/react__rspack_import_0.forwardRef(function FocusGuard(props, ref) {\n const [role, setRole] = react__rspack_import_0.useState();\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if ((0,_floating_ui_react_utils__rspack_import_6.isSafari)()) {\n // Unlike other screen readers such as NVDA and JAWS, the virtual cursor\n // on VoiceOver does trigger the onFocus event, so we can use the focus\n // trap element. On Safari, only buttons trigger the onFocus event.\n // NB: \"group\" role in the Sandbox no longer appears to work, must be a\n // button role.\n setRole('button');\n }\n }, []);\n const restProps = {\n ref,\n tabIndex: 0,\n // Role is only for VoiceOver\n role,\n 'aria-hidden': role ? undefined : true,\n [createAttribute('focus-guard')]: '',\n style: HIDDEN_STYLES\n };\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"span\", {\n ...props,\n ...restProps\n });\n});\n\nconst PortalContext = /*#__PURE__*/react__rspack_import_0.createContext(null);\nconst attr = /*#__PURE__*/createAttribute('portal');\n/**\n * @see https://floating-ui.com/docs/FloatingPortal#usefloatingportalnode\n */\nfunction useFloatingPortalNode(props) {\n if (props === void 0) {\n props = {};\n }\n const {\n id,\n root\n } = props;\n const uniqueId = useId();\n const portalContext = usePortalContext();\n const [portalNode, setPortalNode] = react__rspack_import_0.useState(null);\n const portalNodeRef = react__rspack_import_0.useRef(null);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n return () => {\n portalNode == null || portalNode.remove();\n // Allow the subsequent layout effects to create a new node on updates.\n // The portal node will still be cleaned up on unmount.\n // https://github.com/floating-ui/floating-ui/issues/2454\n queueMicrotask(() => {\n portalNodeRef.current = null;\n });\n };\n }, [portalNode]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n // Wait for the uniqueId to be generated before creating the portal node in\n // React <18 (using `useFloatingId` instead of the native `useId`).\n // https://github.com/floating-ui/floating-ui/issues/2778\n if (!uniqueId) return;\n if (portalNodeRef.current) return;\n const existingIdRoot = id ? document.getElementById(id) : null;\n if (!existingIdRoot) return;\n const subRoot = document.createElement('div');\n subRoot.id = uniqueId;\n subRoot.setAttribute(attr, '');\n existingIdRoot.appendChild(subRoot);\n portalNodeRef.current = subRoot;\n setPortalNode(subRoot);\n }, [id, uniqueId]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n // Wait for the root to exist before creating the portal node. The root must\n // be stored in state, not a ref, for this to work reactively.\n if (root === null) return;\n if (!uniqueId) return;\n if (portalNodeRef.current) return;\n let container = root || (portalContext == null ? void 0 : portalContext.portalNode);\n if (container && !(0,_floating_ui_react_dom__rspack_import_5.isElement)(container)) container = container.current;\n container = container || document.body;\n let idWrapper = null;\n if (id) {\n idWrapper = document.createElement('div');\n idWrapper.id = id;\n container.appendChild(idWrapper);\n }\n const subRoot = document.createElement('div');\n subRoot.id = uniqueId;\n subRoot.setAttribute(attr, '');\n container = idWrapper || container;\n container.appendChild(subRoot);\n portalNodeRef.current = subRoot;\n setPortalNode(subRoot);\n }, [id, root, uniqueId, portalContext]);\n return portalNode;\n}\n/**\n * Portals the floating element into a given container element — by default,\n * outside of the app root and into the body.\n * This is necessary to ensure the floating element can appear outside any\n * potential parent containers that cause clipping (such as `overflow: hidden`),\n * while retaining its location in the React tree.\n * @see https://floating-ui.com/docs/FloatingPortal\n */\nfunction FloatingPortal(props) {\n const {\n children,\n id,\n root,\n preserveTabOrder = true\n } = props;\n const portalNode = useFloatingPortalNode({\n id,\n root\n });\n const [focusManagerState, setFocusManagerState] = react__rspack_import_0.useState(null);\n const beforeOutsideRef = react__rspack_import_0.useRef(null);\n const afterOutsideRef = react__rspack_import_0.useRef(null);\n const beforeInsideRef = react__rspack_import_0.useRef(null);\n const afterInsideRef = react__rspack_import_0.useRef(null);\n const modal = focusManagerState == null ? void 0 : focusManagerState.modal;\n const open = focusManagerState == null ? void 0 : focusManagerState.open;\n const shouldRenderGuards =\n // The FocusManager and therefore floating element are currently open/\n // rendered.\n !!focusManagerState &&\n // Guards are only for non-modal focus management.\n !focusManagerState.modal &&\n // Don't render if unmount is transitioning.\n focusManagerState.open && preserveTabOrder && !!(root || portalNode);\n\n // https://codesandbox.io/s/tabbable-portal-f4tng?file=/src/TabbablePortal.tsx\n react__rspack_import_0.useEffect(() => {\n if (!portalNode || !preserveTabOrder || modal) {\n return;\n }\n\n // Make sure elements inside the portal element are tabbable only when the\n // portal has already been focused, either by tabbing into a focus trap\n // element outside or using the mouse.\n function onFocus(event) {\n if (portalNode && (0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event)) {\n const focusing = event.type === 'focusin';\n const manageFocus = focusing ? _floating_ui_react_utils__rspack_import_6.enableFocusInside : _floating_ui_react_utils__rspack_import_6.disableFocusInside;\n manageFocus(portalNode);\n }\n }\n // Listen to the event on the capture phase so they run before the focus\n // trap elements onFocus prop is called.\n portalNode.addEventListener('focusin', onFocus, true);\n portalNode.addEventListener('focusout', onFocus, true);\n return () => {\n portalNode.removeEventListener('focusin', onFocus, true);\n portalNode.removeEventListener('focusout', onFocus, true);\n };\n }, [portalNode, preserveTabOrder, modal]);\n react__rspack_import_0.useEffect(() => {\n if (!portalNode) return;\n if (open) return;\n (0,_floating_ui_react_utils__rspack_import_6.enableFocusInside)(portalNode);\n }, [open, portalNode]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsxs)(PortalContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n preserveTabOrder,\n beforeOutsideRef,\n afterOutsideRef,\n beforeInsideRef,\n afterInsideRef,\n portalNode,\n setFocusManagerState\n }), [preserveTabOrder, portalNode]),\n children: [shouldRenderGuards && portalNode && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"outside\",\n ref: beforeOutsideRef,\n onFocus: event => {\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalNode)) {\n var _beforeInsideRef$curr;\n (_beforeInsideRef$curr = beforeInsideRef.current) == null || _beforeInsideRef$curr.focus();\n } else {\n const domReference = focusManagerState ? focusManagerState.domReference : null;\n const prevTabbable = (0,_floating_ui_react_utils__rspack_import_6.getPreviousTabbable)(domReference);\n prevTabbable == null || prevTabbable.focus();\n }\n }\n }), shouldRenderGuards && portalNode && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"span\", {\n \"aria-owns\": portalNode.id,\n style: HIDDEN_STYLES\n }), portalNode && /*#__PURE__*/react_dom__rspack_import_2.createPortal(children, portalNode), shouldRenderGuards && portalNode && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"outside\",\n ref: afterOutsideRef,\n onFocus: event => {\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalNode)) {\n var _afterInsideRef$curre;\n (_afterInsideRef$curre = afterInsideRef.current) == null || _afterInsideRef$curre.focus();\n } else {\n const domReference = focusManagerState ? focusManagerState.domReference : null;\n const nextTabbable = (0,_floating_ui_react_utils__rspack_import_6.getNextTabbable)(domReference);\n nextTabbable == null || nextTabbable.focus();\n (focusManagerState == null ? void 0 : focusManagerState.closeOnFocusOut) && (focusManagerState == null ? void 0 : focusManagerState.onOpenChange(false, event.nativeEvent, 'focus-out'));\n }\n }\n })]\n });\n}\nconst usePortalContext = () => react__rspack_import_0.useContext(PortalContext);\n\nfunction useLiteMergeRefs(refs) {\n return react__rspack_import_0.useMemo(() => {\n return value => {\n refs.forEach(ref => {\n if (ref) {\n ref.current = value;\n }\n });\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, refs);\n}\n\nconst LIST_LIMIT = 20;\nlet previouslyFocusedElements = [];\nfunction addPreviouslyFocusedElement(element) {\n previouslyFocusedElements = previouslyFocusedElements.filter(el => el.isConnected);\n if (element && (0,_floating_ui_react_dom__rspack_import_5.getNodeName)(element) !== 'body') {\n previouslyFocusedElements.push(element);\n if (previouslyFocusedElements.length > LIST_LIMIT) {\n previouslyFocusedElements = previouslyFocusedElements.slice(-20);\n }\n }\n}\nfunction getPreviouslyFocusedElement() {\n return previouslyFocusedElements.slice().reverse().find(el => el.isConnected);\n}\nfunction getFirstTabbableElement(container) {\n const tabbableOptions = (0,_floating_ui_react_utils__rspack_import_6.getTabbableOptions)();\n if ((0,tabbable__rspack_import_7.isTabbable)(container, tabbableOptions)) {\n return container;\n }\n return (0,tabbable__rspack_import_7.tabbable)(container, tabbableOptions)[0] || container;\n}\nfunction handleTabIndex(floatingFocusElement, orderRef) {\n var _floatingFocusElement;\n if (!orderRef.current.includes('floating') && !((_floatingFocusElement = floatingFocusElement.getAttribute('role')) != null && _floatingFocusElement.includes('dialog'))) {\n return;\n }\n const options = (0,_floating_ui_react_utils__rspack_import_6.getTabbableOptions)();\n const focusableElements = (0,tabbable__rspack_import_7.focusable)(floatingFocusElement, options);\n const tabbableContent = focusableElements.filter(element => {\n const dataTabIndex = element.getAttribute('data-tabindex') || '';\n return (0,tabbable__rspack_import_7.isTabbable)(element, options) || element.hasAttribute('data-tabindex') && !dataTabIndex.startsWith('-');\n });\n const tabIndex = floatingFocusElement.getAttribute('tabindex');\n if (orderRef.current.includes('floating') || tabbableContent.length === 0) {\n if (tabIndex !== '0') {\n floatingFocusElement.setAttribute('tabindex', '0');\n }\n } else if (tabIndex !== '-1' || floatingFocusElement.hasAttribute('data-tabindex') && floatingFocusElement.getAttribute('data-tabindex') !== '-1') {\n floatingFocusElement.setAttribute('tabindex', '-1');\n floatingFocusElement.setAttribute('data-tabindex', '-1');\n }\n}\nconst VisuallyHiddenDismiss = /*#__PURE__*/react__rspack_import_0.forwardRef(function VisuallyHiddenDismiss(props, ref) {\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"button\", {\n ...props,\n type: \"button\",\n ref: ref,\n tabIndex: -1,\n style: HIDDEN_STYLES\n });\n});\n/**\n * Provides focus management for the floating element.\n * @see https://floating-ui.com/docs/FloatingFocusManager\n */\nfunction FloatingFocusManager(props) {\n const {\n context,\n children,\n disabled = false,\n order = ['content'],\n guards: _guards = true,\n initialFocus = 0,\n returnFocus = true,\n restoreFocus = false,\n modal = true,\n visuallyHiddenDismiss = false,\n closeOnFocusOut = true,\n outsideElementsInert = false,\n getInsideElements: _getInsideElements = () => []\n } = props;\n const {\n open,\n onOpenChange,\n events,\n dataRef,\n elements: {\n domReference,\n floating\n }\n } = context;\n const getNodeId = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n var _dataRef$current$floa;\n return (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;\n });\n const getInsideElements = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(_getInsideElements);\n const ignoreInitialFocus = typeof initialFocus === 'number' && initialFocus < 0;\n // If the reference is a combobox and is typeable (e.g. input/textarea),\n // there are different focus semantics. The guards should not be rendered, but\n // aria-hidden should be applied to all nodes still. Further, the visually\n // hidden dismiss button should only appear at the end of the list, not the\n // start.\n const isUntrappedTypeableCombobox = (0,_floating_ui_react_utils__rspack_import_6.isTypeableCombobox)(domReference) && ignoreInitialFocus;\n\n // Force the guards to be rendered if the `inert` attribute is not supported.\n const inertSupported = supportsInert();\n const guards = inertSupported ? _guards : true;\n const useInert = !guards || inertSupported && outsideElementsInert;\n const orderRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(order);\n const initialFocusRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(initialFocus);\n const returnFocusRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(returnFocus);\n const tree = useFloatingTree();\n const portalContext = usePortalContext();\n const startDismissButtonRef = react__rspack_import_0.useRef(null);\n const endDismissButtonRef = react__rspack_import_0.useRef(null);\n const preventReturnFocusRef = react__rspack_import_0.useRef(false);\n const isPointerDownRef = react__rspack_import_0.useRef(false);\n const tabbableIndexRef = react__rspack_import_0.useRef(-1);\n const isInsidePortal = portalContext != null;\n const floatingFocusElement = (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)(floating);\n const getTabbableContent = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(function (container) {\n if (container === void 0) {\n container = floatingFocusElement;\n }\n return container ? (0,tabbable__rspack_import_7.tabbable)(container, (0,_floating_ui_react_utils__rspack_import_6.getTabbableOptions)()) : [];\n });\n const getTabbableElements = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(container => {\n const content = getTabbableContent(container);\n return orderRef.current.map(type => {\n if (domReference && type === 'reference') {\n return domReference;\n }\n if (floatingFocusElement && type === 'floating') {\n return floatingFocusElement;\n }\n return content;\n }).filter(Boolean).flat();\n });\n react__rspack_import_0.useEffect(() => {\n if (disabled) return;\n if (!modal) return;\n function onKeyDown(event) {\n if (event.key === 'Tab') {\n // The focus guards have nothing to focus, so we need to stop the event.\n if ((0,_floating_ui_react_utils__rspack_import_6.contains)(floatingFocusElement, (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement))) && getTabbableContent().length === 0 && !isUntrappedTypeableCombobox) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n }\n const els = getTabbableElements();\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n if (orderRef.current[0] === 'reference' && target === domReference) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n if (event.shiftKey) {\n enqueueFocus(els[els.length - 1]);\n } else {\n enqueueFocus(els[1]);\n }\n }\n if (orderRef.current[1] === 'floating' && target === floatingFocusElement && event.shiftKey) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n enqueueFocus(els[0]);\n }\n }\n }\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement);\n doc.addEventListener('keydown', onKeyDown);\n return () => {\n doc.removeEventListener('keydown', onKeyDown);\n };\n }, [disabled, domReference, floatingFocusElement, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);\n react__rspack_import_0.useEffect(() => {\n if (disabled) return;\n if (!floating) return;\n function handleFocusIn(event) {\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n const tabbableContent = getTabbableContent();\n const tabbableIndex = tabbableContent.indexOf(target);\n if (tabbableIndex !== -1) {\n tabbableIndexRef.current = tabbableIndex;\n }\n }\n floating.addEventListener('focusin', handleFocusIn);\n return () => {\n floating.removeEventListener('focusin', handleFocusIn);\n };\n }, [disabled, floating, getTabbableContent]);\n react__rspack_import_0.useEffect(() => {\n if (disabled) return;\n if (!closeOnFocusOut) return;\n\n // In Safari, buttons lose focus when pressing them.\n function handlePointerDown() {\n isPointerDownRef.current = true;\n setTimeout(() => {\n isPointerDownRef.current = false;\n });\n }\n function handleFocusOutside(event) {\n const relatedTarget = event.relatedTarget;\n const currentTarget = event.currentTarget;\n queueMicrotask(() => {\n const nodeId = getNodeId();\n const movedToUnrelatedNode = !((0,_floating_ui_react_utils__rspack_import_6.contains)(domReference, relatedTarget) || (0,_floating_ui_react_utils__rspack_import_6.contains)(floating, relatedTarget) || (0,_floating_ui_react_utils__rspack_import_6.contains)(relatedTarget, floating) || (0,_floating_ui_react_utils__rspack_import_6.contains)(portalContext == null ? void 0 : portalContext.portalNode, relatedTarget) || relatedTarget != null && relatedTarget.hasAttribute(createAttribute('focus-guard')) || tree && ((0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId).find(node => {\n var _node$context, _node$context2;\n return (0,_floating_ui_react_utils__rspack_import_6.contains)((_node$context = node.context) == null ? void 0 : _node$context.elements.floating, relatedTarget) || (0,_floating_ui_react_utils__rspack_import_6.contains)((_node$context2 = node.context) == null ? void 0 : _node$context2.elements.domReference, relatedTarget);\n }) || (0,_floating_ui_react_utils__rspack_import_6.getNodeAncestors)(tree.nodesRef.current, nodeId).find(node => {\n var _node$context3, _node$context4, _node$context5;\n return [(_node$context3 = node.context) == null ? void 0 : _node$context3.elements.floating, (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)((_node$context4 = node.context) == null ? void 0 : _node$context4.elements.floating)].includes(relatedTarget) || ((_node$context5 = node.context) == null ? void 0 : _node$context5.elements.domReference) === relatedTarget;\n })));\n if (currentTarget === domReference && floatingFocusElement) {\n handleTabIndex(floatingFocusElement, orderRef);\n }\n\n // Restore focus to the previous tabbable element index to prevent\n // focus from being lost outside the floating tree.\n if (restoreFocus && movedToUnrelatedNode && (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement)) === (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement).body) {\n // Let `FloatingPortal` effect knows that focus is still inside the\n // floating tree.\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(floatingFocusElement)) {\n floatingFocusElement.focus();\n }\n const prevTabbableIndex = tabbableIndexRef.current;\n const tabbableContent = getTabbableContent();\n const nodeToFocus = tabbableContent[prevTabbableIndex] || tabbableContent[tabbableContent.length - 1] || floatingFocusElement;\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(nodeToFocus)) {\n nodeToFocus.focus();\n }\n }\n\n // Focus did not move inside the floating tree, and there are no tabbable\n // portal guards to handle closing.\n if ((isUntrappedTypeableCombobox ? true : !modal) && relatedTarget && movedToUnrelatedNode && !isPointerDownRef.current &&\n // Fix React 18 Strict Mode returnFocus due to double rendering.\n relatedTarget !== getPreviouslyFocusedElement()) {\n preventReturnFocusRef.current = true;\n onOpenChange(false, event, 'focus-out');\n }\n });\n }\n if (floating && (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(domReference)) {\n domReference.addEventListener('focusout', handleFocusOutside);\n domReference.addEventListener('pointerdown', handlePointerDown);\n floating.addEventListener('focusout', handleFocusOutside);\n return () => {\n domReference.removeEventListener('focusout', handleFocusOutside);\n domReference.removeEventListener('pointerdown', handlePointerDown);\n floating.removeEventListener('focusout', handleFocusOutside);\n };\n }\n }, [disabled, domReference, floating, floatingFocusElement, modal, tree, portalContext, onOpenChange, closeOnFocusOut, restoreFocus, getTabbableContent, isUntrappedTypeableCombobox, getNodeId, orderRef]);\n const beforeGuardRef = react__rspack_import_0.useRef(null);\n const afterGuardRef = react__rspack_import_0.useRef(null);\n const mergedBeforeGuardRef = useLiteMergeRefs([beforeGuardRef, portalContext == null ? void 0 : portalContext.beforeInsideRef]);\n const mergedAfterGuardRef = useLiteMergeRefs([afterGuardRef, portalContext == null ? void 0 : portalContext.afterInsideRef]);\n react__rspack_import_0.useEffect(() => {\n var _portalContext$portal, _ancestors$find;\n if (disabled) return;\n if (!floating) return;\n\n // Don't hide portals nested within the parent portal.\n const portalNodes = Array.from((portalContext == null || (_portalContext$portal = portalContext.portalNode) == null ? void 0 : _portalContext$portal.querySelectorAll(\"[\" + createAttribute('portal') + \"]\")) || []);\n const ancestors = tree ? (0,_floating_ui_react_utils__rspack_import_6.getNodeAncestors)(tree.nodesRef.current, getNodeId()) : [];\n const ancestorFloatingNodes = tree && !modal ? ancestors.map(node => {\n var _node$context6;\n return (_node$context6 = node.context) == null ? void 0 : _node$context6.elements.floating;\n }) : [];\n const rootAncestorComboboxDomReference = (_ancestors$find = ancestors.find(node => {\n var _node$context7;\n return (0,_floating_ui_react_utils__rspack_import_6.isTypeableCombobox)(((_node$context7 = node.context) == null ? void 0 : _node$context7.elements.domReference) || null);\n })) == null || (_ancestors$find = _ancestors$find.context) == null ? void 0 : _ancestors$find.elements.domReference;\n const insideElements = [floating, rootAncestorComboboxDomReference, ...portalNodes, ...ancestorFloatingNodes, ...getInsideElements(), startDismissButtonRef.current, endDismissButtonRef.current, beforeGuardRef.current, afterGuardRef.current, portalContext == null ? void 0 : portalContext.beforeOutsideRef.current, portalContext == null ? void 0 : portalContext.afterOutsideRef.current, orderRef.current.includes('reference') || isUntrappedTypeableCombobox ? domReference : null].filter(x => x != null);\n const cleanup = modal || isUntrappedTypeableCombobox ? markOthers(insideElements, !useInert, useInert) : markOthers(insideElements);\n return () => {\n cleanup();\n };\n }, [disabled, domReference, floating, modal, orderRef, portalContext, isUntrappedTypeableCombobox, guards, useInert, tree, getNodeId, getInsideElements]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled || !(0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(floatingFocusElement)) return;\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement);\n const previouslyFocusedElement = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(doc);\n\n // Wait for any layout effect state setters to execute to set `tabIndex`.\n queueMicrotask(() => {\n const focusableElements = getTabbableElements(floatingFocusElement);\n const initialFocusValue = initialFocusRef.current;\n const elToFocus = (typeof initialFocusValue === 'number' ? focusableElements[initialFocusValue] : initialFocusValue.current) || floatingFocusElement;\n const focusAlreadyInsideFloatingEl = (0,_floating_ui_react_utils__rspack_import_6.contains)(floatingFocusElement, previouslyFocusedElement);\n if (!ignoreInitialFocus && !focusAlreadyInsideFloatingEl && open) {\n enqueueFocus(elToFocus, {\n preventScroll: elToFocus === floatingFocusElement\n });\n }\n });\n }, [disabled, open, floatingFocusElement, ignoreInitialFocus, getTabbableElements, initialFocusRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled || !floatingFocusElement) return;\n let preventReturnFocusScroll = false;\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement);\n const previouslyFocusedElement = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(doc);\n addPreviouslyFocusedElement(previouslyFocusedElement);\n\n // Dismissing via outside press should always ignore `returnFocus` to\n // prevent unwanted scrolling.\n function onOpenChange(_ref) {\n let {\n reason,\n event,\n nested\n } = _ref;\n if (['hover', 'safe-polygon'].includes(reason) && event.type === 'mouseleave') {\n preventReturnFocusRef.current = true;\n }\n if (reason !== 'outside-press') return;\n if (nested) {\n preventReturnFocusRef.current = false;\n preventReturnFocusScroll = true;\n } else if ((0,_floating_ui_react_utils__rspack_import_6.isVirtualClick)(event) || (0,_floating_ui_react_utils__rspack_import_6.isVirtualPointerEvent)(event)) {\n preventReturnFocusRef.current = false;\n } else {\n let isPreventScrollSupported = false;\n document.createElement('div').focus({\n get preventScroll() {\n isPreventScrollSupported = true;\n return false;\n }\n });\n if (isPreventScrollSupported) {\n preventReturnFocusRef.current = false;\n preventReturnFocusScroll = true;\n } else {\n preventReturnFocusRef.current = true;\n }\n }\n }\n events.on('openchange', onOpenChange);\n const fallbackEl = doc.createElement('span');\n fallbackEl.setAttribute('tabindex', '-1');\n fallbackEl.setAttribute('aria-hidden', 'true');\n Object.assign(fallbackEl.style, HIDDEN_STYLES);\n if (isInsidePortal && domReference) {\n domReference.insertAdjacentElement('afterend', fallbackEl);\n }\n function getReturnElement() {\n if (typeof returnFocusRef.current === 'boolean') {\n const el = domReference || getPreviouslyFocusedElement();\n return el && el.isConnected ? el : fallbackEl;\n }\n return returnFocusRef.current.current || fallbackEl;\n }\n return () => {\n events.off('openchange', onOpenChange);\n const activeEl = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(doc);\n const isFocusInsideFloatingTree = (0,_floating_ui_react_utils__rspack_import_6.contains)(floating, activeEl) || tree && (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, getNodeId()).some(node => {\n var _node$context8;\n return (0,_floating_ui_react_utils__rspack_import_6.contains)((_node$context8 = node.context) == null ? void 0 : _node$context8.elements.floating, activeEl);\n });\n const returnElement = getReturnElement();\n queueMicrotask(() => {\n // This is `returnElement`, if it's tabbable, or its first tabbable child.\n const tabbableReturnElement = getFirstTabbableElement(returnElement);\n if (\n // eslint-disable-next-line react-hooks/exhaustive-deps\n returnFocusRef.current && !preventReturnFocusRef.current && (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(tabbableReturnElement) && (\n // If the focus moved somewhere else after mount, avoid returning focus\n // since it likely entered a different element which should be\n // respected: https://github.com/floating-ui/floating-ui/issues/2607\n tabbableReturnElement !== activeEl && activeEl !== doc.body ? isFocusInsideFloatingTree : true)) {\n tabbableReturnElement.focus({\n preventScroll: preventReturnFocusScroll\n });\n }\n fallbackEl.remove();\n });\n };\n }, [disabled, floating, floatingFocusElement, returnFocusRef, dataRef, events, tree, isInsidePortal, domReference, getNodeId]);\n react__rspack_import_0.useEffect(() => {\n // The `returnFocus` cleanup behavior is inside a microtask; ensure we\n // wait for it to complete before resetting the flag.\n queueMicrotask(() => {\n preventReturnFocusRef.current = false;\n });\n }, [disabled]);\n\n // Synchronize the `context` & `modal` value to the FloatingPortal context.\n // It will decide whether or not it needs to render its own guards.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled) return;\n if (!portalContext) return;\n portalContext.setFocusManagerState({\n modal,\n closeOnFocusOut,\n open,\n onOpenChange,\n domReference\n });\n return () => {\n portalContext.setFocusManagerState(null);\n };\n }, [disabled, portalContext, modal, open, onOpenChange, closeOnFocusOut, domReference]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled) return;\n if (!floatingFocusElement) return;\n handleTabIndex(floatingFocusElement, orderRef);\n }, [disabled, floatingFocusElement, orderRef]);\n function renderDismissButton(location) {\n if (disabled || !visuallyHiddenDismiss || !modal) {\n return null;\n }\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(VisuallyHiddenDismiss, {\n ref: location === 'start' ? startDismissButtonRef : endDismissButtonRef,\n onClick: event => onOpenChange(false, event.nativeEvent),\n children: typeof visuallyHiddenDismiss === 'string' ? visuallyHiddenDismiss : 'Dismiss'\n });\n }\n const shouldRenderGuards = !disabled && guards && (modal ? !isUntrappedTypeableCombobox : true) && (isInsidePortal || modal);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsxs)(react_jsx_runtime__rspack_import_1.Fragment, {\n children: [shouldRenderGuards && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"inside\",\n ref: mergedBeforeGuardRef,\n onFocus: event => {\n if (modal) {\n const els = getTabbableElements();\n enqueueFocus(order[0] === 'reference' ? els[0] : els[els.length - 1]);\n } else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {\n preventReturnFocusRef.current = false;\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalContext.portalNode)) {\n const nextTabbable = (0,_floating_ui_react_utils__rspack_import_6.getNextTabbable)(domReference);\n nextTabbable == null || nextTabbable.focus();\n } else {\n var _portalContext$before;\n (_portalContext$before = portalContext.beforeOutsideRef.current) == null || _portalContext$before.focus();\n }\n }\n }\n }), !isUntrappedTypeableCombobox && renderDismissButton('start'), children, renderDismissButton('end'), shouldRenderGuards && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"inside\",\n ref: mergedAfterGuardRef,\n onFocus: event => {\n if (modal) {\n enqueueFocus(getTabbableElements()[0]);\n } else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {\n if (closeOnFocusOut) {\n preventReturnFocusRef.current = true;\n }\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalContext.portalNode)) {\n const prevTabbable = (0,_floating_ui_react_utils__rspack_import_6.getPreviousTabbable)(domReference);\n prevTabbable == null || prevTabbable.focus();\n } else {\n var _portalContext$afterO;\n (_portalContext$afterO = portalContext.afterOutsideRef.current) == null || _portalContext$afterO.focus();\n }\n }\n }\n })]\n });\n}\n\nlet lockCount = 0;\nfunction enableScrollLock() {\n const isIOS = /iP(hone|ad|od)|iOS/.test((0,_floating_ui_react_utils__rspack_import_6.getPlatform)());\n const bodyStyle = document.body.style;\n // RTL <body> scrollbar\n const scrollbarX = Math.round(document.documentElement.getBoundingClientRect().left) + document.documentElement.scrollLeft;\n const paddingProp = scrollbarX ? 'paddingLeft' : 'paddingRight';\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n const scrollX = bodyStyle.left ? parseFloat(bodyStyle.left) : window.scrollX;\n const scrollY = bodyStyle.top ? parseFloat(bodyStyle.top) : window.scrollY;\n bodyStyle.overflow = 'hidden';\n if (scrollbarWidth) {\n bodyStyle[paddingProp] = scrollbarWidth + \"px\";\n }\n\n // Only iOS doesn't respect `overflow: hidden` on document.body, and this\n // technique has fewer side effects.\n if (isIOS) {\n var _window$visualViewpor, _window$visualViewpor2;\n // iOS 12 does not support `visualViewport`.\n const offsetLeft = ((_window$visualViewpor = window.visualViewport) == null ? void 0 : _window$visualViewpor.offsetLeft) || 0;\n const offsetTop = ((_window$visualViewpor2 = window.visualViewport) == null ? void 0 : _window$visualViewpor2.offsetTop) || 0;\n Object.assign(bodyStyle, {\n position: 'fixed',\n top: -(scrollY - Math.floor(offsetTop)) + \"px\",\n left: -(scrollX - Math.floor(offsetLeft)) + \"px\",\n right: '0'\n });\n }\n return () => {\n Object.assign(bodyStyle, {\n overflow: '',\n [paddingProp]: ''\n });\n if (isIOS) {\n Object.assign(bodyStyle, {\n position: '',\n top: '',\n left: '',\n right: ''\n });\n window.scrollTo(scrollX, scrollY);\n }\n };\n}\nlet cleanup = () => {};\n\n/**\n * Provides base styling for a fixed overlay element to dim content or block\n * pointer events behind a floating element.\n * It's a regular `<div>`, so it can be styled via any CSS solution you prefer.\n * @see https://floating-ui.com/docs/FloatingOverlay\n */\nconst FloatingOverlay = /*#__PURE__*/react__rspack_import_0.forwardRef(function FloatingOverlay(props, ref) {\n const {\n lockScroll = false,\n ...rest\n } = props;\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!lockScroll) return;\n lockCount++;\n if (lockCount === 1) {\n cleanup = enableScrollLock();\n }\n return () => {\n lockCount--;\n if (lockCount === 0) {\n cleanup();\n }\n };\n }, [lockScroll]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"div\", {\n ref: ref,\n ...rest,\n style: {\n position: 'fixed',\n overflow: 'auto',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...rest.style\n }\n });\n});\n\nfunction isButtonTarget(event) {\n return (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(event.target) && event.target.tagName === 'BUTTON';\n}\nfunction isAnchorTarget(event) {\n return (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(event.target) && event.target.tagName === 'A';\n}\nfunction isSpaceIgnored(element) {\n return (0,_floating_ui_react_utils__rspack_import_6.isTypeableElement)(element);\n}\n/**\n * Opens or closes the floating element when clicking the reference element.\n * @see https://floating-ui.com/docs/useClick\n */\nfunction useClick(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n dataRef,\n elements: {\n domReference\n }\n } = context;\n const {\n enabled = true,\n event: eventOption = 'click',\n toggle = true,\n ignoreMouse = false,\n keyboardHandlers = true,\n stickIfOpen = true\n } = props;\n const pointerTypeRef = react__rspack_import_0.useRef();\n const didKeyDownRef = react__rspack_import_0.useRef(false);\n const reference = react__rspack_import_0.useMemo(() => ({\n onPointerDown(event) {\n pointerTypeRef.current = event.pointerType;\n },\n onMouseDown(event) {\n const pointerType = pointerTypeRef.current;\n\n // Ignore all buttons except for the \"main\" button.\n // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\n if (event.button !== 0) return;\n if (eventOption === 'click') return;\n if ((0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;\n if (open && toggle && (dataRef.current.openEvent && stickIfOpen ? dataRef.current.openEvent.type === 'mousedown' : true)) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n // Prevent stealing focus from the floating element\n event.preventDefault();\n onOpenChange(true, event.nativeEvent, 'click');\n }\n },\n onClick(event) {\n const pointerType = pointerTypeRef.current;\n if (eventOption === 'mousedown' && pointerTypeRef.current) {\n pointerTypeRef.current = undefined;\n return;\n }\n if ((0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;\n if (open && toggle && (dataRef.current.openEvent && stickIfOpen ? dataRef.current.openEvent.type === 'click' : true)) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n },\n onKeyDown(event) {\n pointerTypeRef.current = undefined;\n if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event)) {\n return;\n }\n if (event.key === ' ' && !isSpaceIgnored(domReference)) {\n // Prevent scrolling\n event.preventDefault();\n didKeyDownRef.current = true;\n }\n if (isAnchorTarget(event)) {\n return;\n }\n if (event.key === 'Enter') {\n if (open && toggle) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n }\n },\n onKeyUp(event) {\n if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event) || isSpaceIgnored(domReference)) {\n return;\n }\n if (event.key === ' ' && didKeyDownRef.current) {\n didKeyDownRef.current = false;\n if (open && toggle) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n }\n }\n }), [dataRef, domReference, eventOption, ignoreMouse, keyboardHandlers, onOpenChange, open, stickIfOpen, toggle]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nfunction createVirtualElement(domElement, data) {\n let offsetX = null;\n let offsetY = null;\n let isAutoUpdateEvent = false;\n return {\n contextElement: domElement || undefined,\n getBoundingClientRect() {\n var _data$dataRef$current;\n const domRect = (domElement == null ? void 0 : domElement.getBoundingClientRect()) || {\n width: 0,\n height: 0,\n x: 0,\n y: 0\n };\n const isXAxis = data.axis === 'x' || data.axis === 'both';\n const isYAxis = data.axis === 'y' || data.axis === 'both';\n const canTrackCursorOnAutoUpdate = ['mouseenter', 'mousemove'].includes(((_data$dataRef$current = data.dataRef.current.openEvent) == null ? void 0 : _data$dataRef$current.type) || '') && data.pointerType !== 'touch';\n let width = domRect.width;\n let height = domRect.height;\n let x = domRect.x;\n let y = domRect.y;\n if (offsetX == null && data.x && isXAxis) {\n offsetX = domRect.x - data.x;\n }\n if (offsetY == null && data.y && isYAxis) {\n offsetY = domRect.y - data.y;\n }\n x -= offsetX || 0;\n y -= offsetY || 0;\n width = 0;\n height = 0;\n if (!isAutoUpdateEvent || canTrackCursorOnAutoUpdate) {\n width = data.axis === 'y' ? domRect.width : 0;\n height = data.axis === 'x' ? domRect.height : 0;\n x = isXAxis && data.x != null ? data.x : x;\n y = isYAxis && data.y != null ? data.y : y;\n } else if (isAutoUpdateEvent && !canTrackCursorOnAutoUpdate) {\n height = data.axis === 'x' ? domRect.height : height;\n width = data.axis === 'y' ? domRect.width : width;\n }\n isAutoUpdateEvent = true;\n return {\n width,\n height,\n x,\n y,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x\n };\n }\n };\n}\nfunction isMouseBasedEvent(event) {\n return event != null && event.clientX != null;\n}\n/**\n * Positions the floating element relative to a client point (in the viewport),\n * such as the mouse position. By default, it follows the mouse cursor.\n * @see https://floating-ui.com/docs/useClientPoint\n */\nfunction useClientPoint(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n dataRef,\n elements: {\n floating,\n domReference\n },\n refs\n } = context;\n const {\n enabled = true,\n axis = 'both',\n x = null,\n y = null\n } = props;\n const initialRef = react__rspack_import_0.useRef(false);\n const cleanupListenerRef = react__rspack_import_0.useRef(null);\n const [pointerType, setPointerType] = react__rspack_import_0.useState();\n const [reactive, setReactive] = react__rspack_import_0.useState([]);\n const setReference = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)((x, y) => {\n if (initialRef.current) return;\n\n // Prevent setting if the open event was not a mouse-like one\n // (e.g. focus to open, then hover over the reference element).\n // Only apply if the event exists.\n if (dataRef.current.openEvent && !isMouseBasedEvent(dataRef.current.openEvent)) {\n return;\n }\n refs.setPositionReference(createVirtualElement(domReference, {\n x,\n y,\n axis,\n dataRef,\n pointerType\n }));\n });\n const handleReferenceEnterOrMove = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n if (x != null || y != null) return;\n if (!open) {\n setReference(event.clientX, event.clientY);\n } else if (!cleanupListenerRef.current) {\n // If there's no cleanup, there's no listener, but we want to ensure\n // we add the listener if the cursor landed on the floating element and\n // then back on the reference (i.e. it's interactive).\n setReactive([]);\n }\n });\n\n // If the pointer is a mouse-like pointer, we want to continue following the\n // mouse even if the floating element is transitioning out. On touch\n // devices, this is undesirable because the floating element will move to\n // the dismissal touch point.\n const openCheck = (0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType) ? floating : open;\n const addListener = react__rspack_import_0.useCallback(() => {\n // Explicitly specified `x`/`y` coordinates shouldn't add a listener.\n if (!openCheck || !enabled || x != null || y != null) return;\n const win = (0,_floating_ui_react_dom__rspack_import_5.getWindow)(floating);\n function handleMouseMove(event) {\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n if (!(0,_floating_ui_react_utils__rspack_import_6.contains)(floating, target)) {\n setReference(event.clientX, event.clientY);\n } else {\n win.removeEventListener('mousemove', handleMouseMove);\n cleanupListenerRef.current = null;\n }\n }\n if (!dataRef.current.openEvent || isMouseBasedEvent(dataRef.current.openEvent)) {\n win.addEventListener('mousemove', handleMouseMove);\n const cleanup = () => {\n win.removeEventListener('mousemove', handleMouseMove);\n cleanupListenerRef.current = null;\n };\n cleanupListenerRef.current = cleanup;\n return cleanup;\n }\n refs.setPositionReference(domReference);\n }, [openCheck, enabled, x, y, floating, dataRef, refs, domReference, setReference]);\n react__rspack_import_0.useEffect(() => {\n return addListener();\n }, [addListener, reactive]);\n react__rspack_import_0.useEffect(() => {\n if (enabled && !floating) {\n initialRef.current = false;\n }\n }, [enabled, floating]);\n react__rspack_import_0.useEffect(() => {\n if (!enabled && open) {\n initialRef.current = true;\n }\n }, [enabled, open]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (enabled && (x != null || y != null)) {\n initialRef.current = false;\n setReference(x, y);\n }\n }, [enabled, x, y, setReference]);\n const reference = react__rspack_import_0.useMemo(() => {\n function setPointerTypeRef(_ref) {\n let {\n pointerType\n } = _ref;\n setPointerType(pointerType);\n }\n return {\n onPointerDown: setPointerTypeRef,\n onPointerEnter: setPointerTypeRef,\n onMouseMove: handleReferenceEnterOrMove,\n onMouseEnter: handleReferenceEnterOrMove\n };\n }, [handleReferenceEnterOrMove]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nconst bubbleHandlerKeys = {\n pointerdown: 'onPointerDown',\n mousedown: 'onMouseDown',\n click: 'onClick'\n};\nconst captureHandlerKeys = {\n pointerdown: 'onPointerDownCapture',\n mousedown: 'onMouseDownCapture',\n click: 'onClickCapture'\n};\nconst normalizeProp = normalizable => {\n var _normalizable$escapeK, _normalizable$outside;\n return {\n escapeKey: typeof normalizable === 'boolean' ? normalizable : (_normalizable$escapeK = normalizable == null ? void 0 : normalizable.escapeKey) != null ? _normalizable$escapeK : false,\n outsidePress: typeof normalizable === 'boolean' ? normalizable : (_normalizable$outside = normalizable == null ? void 0 : normalizable.outsidePress) != null ? _normalizable$outside : true\n };\n};\n/**\n * Closes the floating element when a dismissal is requested — by default, when\n * the user presses the `escape` key or outside of the floating element.\n * @see https://floating-ui.com/docs/useDismiss\n */\nfunction useDismiss(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n elements,\n dataRef\n } = context;\n const {\n enabled = true,\n escapeKey = true,\n outsidePress: unstable_outsidePress = true,\n outsidePressEvent = 'pointerdown',\n referencePress = false,\n referencePressEvent = 'pointerdown',\n ancestorScroll = false,\n bubbles,\n capture\n } = props;\n const tree = useFloatingTree();\n const outsidePressFn = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(typeof unstable_outsidePress === 'function' ? unstable_outsidePress : () => false);\n const outsidePress = typeof unstable_outsidePress === 'function' ? outsidePressFn : unstable_outsidePress;\n const insideReactTreeRef = react__rspack_import_0.useRef(false);\n const endedOrStartedInsideRef = react__rspack_import_0.useRef(false);\n const {\n escapeKey: escapeKeyBubbles,\n outsidePress: outsidePressBubbles\n } = normalizeProp(bubbles);\n const {\n escapeKey: escapeKeyCapture,\n outsidePress: outsidePressCapture\n } = normalizeProp(capture);\n const isComposingRef = react__rspack_import_0.useRef(false);\n const closeOnEscapeKeyDown = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _dataRef$current$floa;\n if (!open || !enabled || !escapeKey || event.key !== 'Escape') {\n return;\n }\n\n // Wait until IME is settled. Pressing `Escape` while composing should\n // close the compose menu, but not the floating element.\n if (isComposingRef.current) {\n return;\n }\n const nodeId = (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;\n const children = tree ? (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId) : [];\n if (!escapeKeyBubbles) {\n event.stopPropagation();\n if (children.length > 0) {\n let shouldDismiss = true;\n children.forEach(child => {\n var _child$context;\n if ((_child$context = child.context) != null && _child$context.open && !child.context.dataRef.current.__escapeKeyBubbles) {\n shouldDismiss = false;\n return;\n }\n });\n if (!shouldDismiss) {\n return;\n }\n }\n }\n onOpenChange(false, (0,_floating_ui_react_utils__rspack_import_6.isReactEvent)(event) ? event.nativeEvent : event, 'escape-key');\n });\n const closeOnEscapeKeyDownCapture = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _getTarget2;\n const callback = () => {\n var _getTarget;\n closeOnEscapeKeyDown(event);\n (_getTarget = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget.removeEventListener('keydown', callback);\n };\n (_getTarget2 = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget2.addEventListener('keydown', callback);\n });\n const closeOnPressOutside = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _dataRef$current$floa2;\n // Given developers can stop the propagation of the synthetic event,\n // we can only be confident with a positive value.\n const insideReactTree = insideReactTreeRef.current;\n insideReactTreeRef.current = false;\n\n // When click outside is lazy (`click` event), handle dragging.\n // Don't close if:\n // - The click started inside the floating element.\n // - The click ended inside the floating element.\n const endedOrStartedInside = endedOrStartedInsideRef.current;\n endedOrStartedInsideRef.current = false;\n if (outsidePressEvent === 'click' && endedOrStartedInside) {\n return;\n }\n if (insideReactTree) {\n return;\n }\n if (typeof outsidePress === 'function' && !outsidePress(event)) {\n return;\n }\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n const inertSelector = \"[\" + createAttribute('inert') + \"]\";\n const markers = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).querySelectorAll(inertSelector);\n let targetRootAncestor = (0,_floating_ui_react_dom__rspack_import_5.isElement)(target) ? target : null;\n while (targetRootAncestor && !(0,_floating_ui_react_dom__rspack_import_5.isLastTraversableNode)(targetRootAncestor)) {\n const nextParent = (0,_floating_ui_react_dom__rspack_import_5.getParentNode)(targetRootAncestor);\n if ((0,_floating_ui_react_dom__rspack_import_5.isLastTraversableNode)(nextParent) || !(0,_floating_ui_react_dom__rspack_import_5.isElement)(nextParent)) {\n break;\n }\n targetRootAncestor = nextParent;\n }\n\n // Check if the click occurred on a third-party element injected after the\n // floating element rendered.\n if (markers.length && (0,_floating_ui_react_dom__rspack_import_5.isElement)(target) && !(0,_floating_ui_react_utils__rspack_import_6.isRootElement)(target) &&\n // Clicked on a direct ancestor (e.g. FloatingOverlay).\n !(0,_floating_ui_react_utils__rspack_import_6.contains)(target, elements.floating) &&\n // If the target root element contains none of the markers, then the\n // element was injected after the floating element rendered.\n Array.from(markers).every(marker => !(0,_floating_ui_react_utils__rspack_import_6.contains)(targetRootAncestor, marker))) {\n return;\n }\n\n // Check if the click occurred on the scrollbar\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(target) && floating) {\n const lastTraversableNode = (0,_floating_ui_react_dom__rspack_import_5.isLastTraversableNode)(target);\n const style = (0,_floating_ui_react_dom__rspack_import_5.getComputedStyle)(target);\n const scrollRe = /auto|scroll/;\n const isScrollableX = lastTraversableNode || scrollRe.test(style.overflowX);\n const isScrollableY = lastTraversableNode || scrollRe.test(style.overflowY);\n const canScrollX = isScrollableX && target.clientWidth > 0 && target.scrollWidth > target.clientWidth;\n const canScrollY = isScrollableY && target.clientHeight > 0 && target.scrollHeight > target.clientHeight;\n const isRTL = style.direction === 'rtl';\n\n // Check click position relative to scrollbar.\n // In some browsers it is possible to change the <body> (or window)\n // scrollbar to the left side, but is very rare and is difficult to\n // check for. Plus, for modal dialogs with backdrops, it is more\n // important that the backdrop is checked but not so much the window.\n const pressedVerticalScrollbar = canScrollY && (isRTL ? event.offsetX <= target.offsetWidth - target.clientWidth : event.offsetX > target.clientWidth);\n const pressedHorizontalScrollbar = canScrollX && event.offsetY > target.clientHeight;\n if (pressedVerticalScrollbar || pressedHorizontalScrollbar) {\n return;\n }\n }\n const nodeId = (_dataRef$current$floa2 = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa2.nodeId;\n const targetIsInsideChildren = tree && (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId).some(node => {\n var _node$context;\n return (0,_floating_ui_react_utils__rspack_import_6.isEventTargetWithin)(event, (_node$context = node.context) == null ? void 0 : _node$context.elements.floating);\n });\n if ((0,_floating_ui_react_utils__rspack_import_6.isEventTargetWithin)(event, elements.floating) || (0,_floating_ui_react_utils__rspack_import_6.isEventTargetWithin)(event, elements.domReference) || targetIsInsideChildren) {\n return;\n }\n const children = tree ? (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId) : [];\n if (children.length > 0) {\n let shouldDismiss = true;\n children.forEach(child => {\n var _child$context2;\n if ((_child$context2 = child.context) != null && _child$context2.open && !child.context.dataRef.current.__outsidePressBubbles) {\n shouldDismiss = false;\n return;\n }\n });\n if (!shouldDismiss) {\n return;\n }\n }\n onOpenChange(false, event, 'outside-press');\n });\n const closeOnPressOutsideCapture = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _getTarget4;\n const callback = () => {\n var _getTarget3;\n closeOnPressOutside(event);\n (_getTarget3 = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget3.removeEventListener(outsidePressEvent, callback);\n };\n (_getTarget4 = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget4.addEventListener(outsidePressEvent, callback);\n });\n react__rspack_import_0.useEffect(() => {\n if (!open || !enabled) {\n return;\n }\n dataRef.current.__escapeKeyBubbles = escapeKeyBubbles;\n dataRef.current.__outsidePressBubbles = outsidePressBubbles;\n let compositionTimeout = -1;\n function onScroll(event) {\n onOpenChange(false, event, 'ancestor-scroll');\n }\n function handleCompositionStart() {\n window.clearTimeout(compositionTimeout);\n isComposingRef.current = true;\n }\n function handleCompositionEnd() {\n // Safari fires `compositionend` before `keydown`, so we need to wait\n // until the next tick to set `isComposing` to `false`.\n // https://bugs.webkit.org/show_bug.cgi?id=165004\n compositionTimeout = window.setTimeout(() => {\n isComposingRef.current = false;\n },\n // 0ms or 1ms don't work in Safari. 5ms appears to consistently work.\n // Only apply to WebKit for the test to remain 0ms.\n (0,_floating_ui_react_dom__rspack_import_5.isWebKit)() ? 5 : 0);\n }\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating);\n if (escapeKey) {\n doc.addEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);\n doc.addEventListener('compositionstart', handleCompositionStart);\n doc.addEventListener('compositionend', handleCompositionEnd);\n }\n outsidePress && doc.addEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);\n let ancestors = [];\n if (ancestorScroll) {\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.domReference)) {\n ancestors = (0,_floating_ui_react_dom__rspack_import_5.getOverflowAncestors)(elements.domReference);\n }\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.floating)) {\n ancestors = ancestors.concat((0,_floating_ui_react_dom__rspack_import_5.getOverflowAncestors)(elements.floating));\n }\n if (!(0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.reference) && elements.reference && elements.reference.contextElement) {\n ancestors = ancestors.concat((0,_floating_ui_react_dom__rspack_import_5.getOverflowAncestors)(elements.reference.contextElement));\n }\n }\n\n // Ignore the visual viewport for scrolling dismissal (allow pinch-zoom)\n ancestors = ancestors.filter(ancestor => {\n var _doc$defaultView;\n return ancestor !== ((_doc$defaultView = doc.defaultView) == null ? void 0 : _doc$defaultView.visualViewport);\n });\n ancestors.forEach(ancestor => {\n ancestor.addEventListener('scroll', onScroll, {\n passive: true\n });\n });\n return () => {\n if (escapeKey) {\n doc.removeEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);\n doc.removeEventListener('compositionstart', handleCompositionStart);\n doc.removeEventListener('compositionend', handleCompositionEnd);\n }\n outsidePress && doc.removeEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);\n ancestors.forEach(ancestor => {\n ancestor.removeEventListener('scroll', onScroll);\n });\n window.clearTimeout(compositionTimeout);\n };\n }, [dataRef, elements, escapeKey, outsidePress, outsidePressEvent, open, onOpenChange, ancestorScroll, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, escapeKeyCapture, closeOnEscapeKeyDownCapture, closeOnPressOutside, outsidePressCapture, closeOnPressOutsideCapture]);\n react__rspack_import_0.useEffect(() => {\n insideReactTreeRef.current = false;\n }, [outsidePress, outsidePressEvent]);\n const reference = react__rspack_import_0.useMemo(() => ({\n onKeyDown: closeOnEscapeKeyDown,\n ...(referencePress && {\n [bubbleHandlerKeys[referencePressEvent]]: event => {\n onOpenChange(false, event.nativeEvent, 'reference-press');\n },\n ...(referencePressEvent !== 'click' && {\n onClick(event) {\n onOpenChange(false, event.nativeEvent, 'reference-press');\n }\n })\n })\n }), [closeOnEscapeKeyDown, onOpenChange, referencePress, referencePressEvent]);\n const floating = react__rspack_import_0.useMemo(() => ({\n onKeyDown: closeOnEscapeKeyDown,\n onMouseDown() {\n endedOrStartedInsideRef.current = true;\n },\n onMouseUp() {\n endedOrStartedInsideRef.current = true;\n },\n [captureHandlerKeys[outsidePressEvent]]: () => {\n insideReactTreeRef.current = true;\n }\n }), [closeOnEscapeKeyDown, outsidePressEvent]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nfunction useFloatingRootContext(options) {\n const {\n open = false,\n onOpenChange: onOpenChangeProp,\n elements: elementsProp\n } = options;\n const floatingId = useId();\n const dataRef = react__rspack_import_0.useRef({});\n const [events] = react__rspack_import_0.useState(() => createEventEmitter());\n const nested = useFloatingParentNodeId() != null;\n if (true) {\n const optionDomReference = elementsProp.reference;\n if (optionDomReference && !(0,_floating_ui_react_dom__rspack_import_5.isElement)(optionDomReference)) {\n error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `refs.setPositionReference()`', 'instead.');\n }\n }\n const [positionReference, setPositionReference] = react__rspack_import_0.useState(elementsProp.reference);\n const onOpenChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)((open, event, reason) => {\n dataRef.current.openEvent = open ? event : undefined;\n events.emit('openchange', {\n open,\n event,\n reason,\n nested\n });\n onOpenChangeProp == null || onOpenChangeProp(open, event, reason);\n });\n const refs = react__rspack_import_0.useMemo(() => ({\n setPositionReference\n }), []);\n const elements = react__rspack_import_0.useMemo(() => ({\n reference: positionReference || elementsProp.reference || null,\n floating: elementsProp.floating || null,\n domReference: elementsProp.reference\n }), [positionReference, elementsProp.reference, elementsProp.floating]);\n return react__rspack_import_0.useMemo(() => ({\n dataRef,\n open,\n onOpenChange,\n elements,\n events,\n floatingId,\n refs\n }), [open, onOpenChange, elements, events, floatingId, refs]);\n}\n\n/**\n * Provides data to position a floating element and context to add interactions.\n * @see https://floating-ui.com/docs/useFloating\n */\nfunction useFloating(options) {\n if (options === void 0) {\n options = {};\n }\n const {\n nodeId\n } = options;\n const internalRootContext = useFloatingRootContext({\n ...options,\n elements: {\n reference: null,\n floating: null,\n ...options.elements\n }\n });\n const rootContext = options.rootContext || internalRootContext;\n const computedElements = rootContext.elements;\n const [_domReference, setDomReference] = react__rspack_import_0.useState(null);\n const [positionReference, _setPositionReference] = react__rspack_import_0.useState(null);\n const optionDomReference = computedElements == null ? void 0 : computedElements.domReference;\n const domReference = optionDomReference || _domReference;\n const domReferenceRef = react__rspack_import_0.useRef(null);\n const tree = useFloatingTree();\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (domReference) {\n domReferenceRef.current = domReference;\n }\n }, [domReference]);\n const position = (0,_floating_ui_react_dom__rspack_import_3.useFloating)({\n ...options,\n elements: {\n ...computedElements,\n ...(positionReference && {\n reference: positionReference\n })\n }\n });\n const setPositionReference = react__rspack_import_0.useCallback(node => {\n const computedPositionReference = (0,_floating_ui_react_dom__rspack_import_5.isElement)(node) ? {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n getClientRects: () => node.getClientRects(),\n contextElement: node\n } : node;\n // Store the positionReference in state if the DOM reference is specified externally via the\n // `elements.reference` option. This ensures that it won't be overridden on future renders.\n _setPositionReference(computedPositionReference);\n position.refs.setReference(computedPositionReference);\n }, [position.refs]);\n const setReference = react__rspack_import_0.useCallback(node => {\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(node) || node === null) {\n domReferenceRef.current = node;\n setDomReference(node);\n }\n\n // Backwards-compatibility for passing a virtual element to `reference`\n // after it has set the DOM reference.\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(position.refs.reference.current) || position.refs.reference.current === null ||\n // Don't allow setting virtual elements using the old technique back to\n // `null` to support `positionReference` + an unstable `reference`\n // callback ref.\n node !== null && !(0,_floating_ui_react_dom__rspack_import_5.isElement)(node)) {\n position.refs.setReference(node);\n }\n }, [position.refs]);\n const refs = react__rspack_import_0.useMemo(() => ({\n ...position.refs,\n setReference,\n setPositionReference,\n domReference: domReferenceRef\n }), [position.refs, setReference, setPositionReference]);\n const elements = react__rspack_import_0.useMemo(() => ({\n ...position.elements,\n domReference: domReference\n }), [position.elements, domReference]);\n const context = react__rspack_import_0.useMemo(() => ({\n ...position,\n ...rootContext,\n refs,\n elements,\n nodeId\n }), [position, refs, elements, nodeId, rootContext]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n rootContext.dataRef.current.floatingContext = context;\n const node = tree == null ? void 0 : tree.nodesRef.current.find(node => node.id === nodeId);\n if (node) {\n node.context = context;\n }\n });\n return react__rspack_import_0.useMemo(() => ({\n ...position,\n context,\n refs,\n elements\n }), [position, refs, elements, context]);\n}\n\nfunction isMacSafari() {\n return (0,_floating_ui_react_utils__rspack_import_6.isMac)() && (0,_floating_ui_react_utils__rspack_import_6.isSafari)();\n}\n/**\n * Opens the floating element while the reference element has focus, like CSS\n * `:focus`.\n * @see https://floating-ui.com/docs/useFocus\n */\nfunction useFocus(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n events,\n dataRef,\n elements\n } = context;\n const {\n enabled = true,\n visibleOnly = true\n } = props;\n const blockFocusRef = react__rspack_import_0.useRef(false);\n const timeoutRef = react__rspack_import_0.useRef(-1);\n const keyboardModalityRef = react__rspack_import_0.useRef(true);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n const win = (0,_floating_ui_react_dom__rspack_import_5.getWindow)(elements.domReference);\n\n // If the reference was focused and the user left the tab/window, and the\n // floating element was not open, the focus should be blocked when they\n // return to the tab/window.\n function onBlur() {\n if (!open && (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(elements.domReference) && elements.domReference === (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.domReference))) {\n blockFocusRef.current = true;\n }\n }\n function onKeyDown() {\n keyboardModalityRef.current = true;\n }\n function onPointerDown() {\n keyboardModalityRef.current = false;\n }\n win.addEventListener('blur', onBlur);\n if (isMacSafari()) {\n win.addEventListener('keydown', onKeyDown, true);\n win.addEventListener('pointerdown', onPointerDown, true);\n }\n return () => {\n win.removeEventListener('blur', onBlur);\n if (isMacSafari()) {\n win.removeEventListener('keydown', onKeyDown, true);\n win.removeEventListener('pointerdown', onPointerDown, true);\n }\n };\n }, [elements.domReference, open, enabled]);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onOpenChange(_ref) {\n let {\n reason\n } = _ref;\n if (reason === 'reference-press' || reason === 'escape-key') {\n blockFocusRef.current = true;\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n };\n }, [events, enabled]);\n react__rspack_import_0.useEffect(() => {\n return () => {\n clearTimeoutIfSet(timeoutRef);\n };\n }, []);\n const reference = react__rspack_import_0.useMemo(() => ({\n onMouseLeave() {\n blockFocusRef.current = false;\n },\n onFocus(event) {\n if (blockFocusRef.current) return;\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event.nativeEvent);\n if (visibleOnly && (0,_floating_ui_react_dom__rspack_import_5.isElement)(target)) {\n // Safari fails to match `:focus-visible` if focus was initially\n // outside the document.\n if (isMacSafari() && !event.relatedTarget) {\n if (!keyboardModalityRef.current && !(0,_floating_ui_react_utils__rspack_import_6.isTypeableElement)(target)) {\n return;\n }\n } else if (!(0,_floating_ui_react_utils__rspack_import_6.matchesFocusVisible)(target)) {\n return;\n }\n }\n onOpenChange(true, event.nativeEvent, 'focus');\n },\n onBlur(event) {\n blockFocusRef.current = false;\n const relatedTarget = event.relatedTarget;\n const nativeEvent = event.nativeEvent;\n\n // Hit the non-modal focus management portal guard. Focus will be\n // moved into the floating element immediately after.\n const movedToFocusGuard = (0,_floating_ui_react_dom__rspack_import_5.isElement)(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';\n\n // Wait for the window blur listener to fire.\n timeoutRef.current = window.setTimeout(() => {\n var _dataRef$current$floa;\n const activeEl = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(elements.domReference ? elements.domReference.ownerDocument : document);\n\n // Focus left the page, keep it open.\n if (!relatedTarget && activeEl === elements.domReference) return;\n\n // When focusing the reference element (e.g. regular click), then\n // clicking into the floating element, prevent it from hiding.\n // Note: it must be focusable, e.g. `tabindex=\"-1\"`.\n // We can not rely on relatedTarget to point to the correct element\n // as it will only point to the shadow host of the newly focused element\n // and not the element that actually has received focus if it is located\n // inside a shadow root.\n if ((0,_floating_ui_react_utils__rspack_import_6.contains)((_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.refs.floating.current, activeEl) || (0,_floating_ui_react_utils__rspack_import_6.contains)(elements.domReference, activeEl) || movedToFocusGuard) {\n return;\n }\n onOpenChange(false, nativeEvent, 'focus');\n });\n }\n }), [dataRef, elements.domReference, onOpenChange, visibleOnly]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nfunction mergeProps(userProps, propsList, elementKey) {\n const map = new Map();\n const isItem = elementKey === 'item';\n let domUserProps = userProps;\n if (isItem && userProps) {\n const {\n [ACTIVE_KEY]: _,\n [SELECTED_KEY]: __,\n ...validProps\n } = userProps;\n domUserProps = validProps;\n }\n return {\n ...(elementKey === 'floating' && {\n tabIndex: -1,\n [FOCUSABLE_ATTRIBUTE]: ''\n }),\n ...domUserProps,\n ...propsList.map(value => {\n const propsOrGetProps = value ? value[elementKey] : null;\n if (typeof propsOrGetProps === 'function') {\n return userProps ? propsOrGetProps(userProps) : null;\n }\n return propsOrGetProps;\n }).concat(userProps).reduce((acc, props) => {\n if (!props) {\n return acc;\n }\n Object.entries(props).forEach(_ref => {\n let [key, value] = _ref;\n if (isItem && [ACTIVE_KEY, SELECTED_KEY].includes(key)) {\n return;\n }\n if (key.indexOf('on') === 0) {\n if (!map.has(key)) {\n map.set(key, []);\n }\n if (typeof value === 'function') {\n var _map$get;\n (_map$get = map.get(key)) == null || _map$get.push(value);\n acc[key] = function () {\n var _map$get2;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n return (_map$get2 = map.get(key)) == null ? void 0 : _map$get2.map(fn => fn(...args)).find(val => val !== undefined);\n };\n }\n } else {\n acc[key] = value;\n }\n });\n return acc;\n }, {})\n };\n}\n/**\n * Merges an array of interaction hooks' props into prop getters, allowing\n * event handler functions to be composed together without overwriting one\n * another.\n * @see https://floating-ui.com/docs/useInteractions\n */\nfunction useInteractions(propsList) {\n if (propsList === void 0) {\n propsList = [];\n }\n const referenceDeps = propsList.map(key => key == null ? void 0 : key.reference);\n const floatingDeps = propsList.map(key => key == null ? void 0 : key.floating);\n const itemDeps = propsList.map(key => key == null ? void 0 : key.item);\n const getReferenceProps = react__rspack_import_0.useCallback(userProps => mergeProps(userProps, propsList, 'reference'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n referenceDeps);\n const getFloatingProps = react__rspack_import_0.useCallback(userProps => mergeProps(userProps, propsList, 'floating'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n floatingDeps);\n const getItemProps = react__rspack_import_0.useCallback(userProps => mergeProps(userProps, propsList, 'item'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n itemDeps);\n return react__rspack_import_0.useMemo(() => ({\n getReferenceProps,\n getFloatingProps,\n getItemProps\n }), [getReferenceProps, getFloatingProps, getItemProps]);\n}\n\nconst ESCAPE = 'Escape';\nfunction doSwitch(orientation, vertical, horizontal) {\n switch (orientation) {\n case 'vertical':\n return vertical;\n case 'horizontal':\n return horizontal;\n default:\n return vertical || horizontal;\n }\n}\nfunction isMainOrientationKey(key, orientation) {\n const vertical = key === ARROW_UP || key === ARROW_DOWN;\n const horizontal = key === ARROW_LEFT || key === ARROW_RIGHT;\n return doSwitch(orientation, vertical, horizontal);\n}\nfunction isMainOrientationToEndKey(key, orientation, rtl) {\n const vertical = key === ARROW_DOWN;\n const horizontal = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;\n return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key === ' ' || key === '';\n}\nfunction isCrossOrientationOpenKey(key, orientation, rtl) {\n const vertical = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;\n const horizontal = key === ARROW_DOWN;\n return doSwitch(orientation, vertical, horizontal);\n}\nfunction isCrossOrientationCloseKey(key, orientation, rtl, cols) {\n const vertical = rtl ? key === ARROW_RIGHT : key === ARROW_LEFT;\n const horizontal = key === ARROW_UP;\n if (orientation === 'both' || orientation === 'horizontal' && cols && cols > 1) {\n return key === ESCAPE;\n }\n return doSwitch(orientation, vertical, horizontal);\n}\n/**\n * Adds arrow key-based navigation of a list of items, either using real DOM\n * focus or virtual focus.\n * @see https://floating-ui.com/docs/useListNavigation\n */\nfunction useListNavigation(context, props) {\n const {\n open,\n onOpenChange,\n elements,\n floatingId\n } = context;\n const {\n listRef,\n activeIndex,\n onNavigate: unstable_onNavigate = () => {},\n enabled = true,\n selectedIndex = null,\n allowEscape = false,\n loop = false,\n nested = false,\n rtl = false,\n virtual = false,\n focusItemOnOpen = 'auto',\n focusItemOnHover = true,\n openOnArrowKeyDown = true,\n disabledIndices = undefined,\n orientation = 'vertical',\n parentOrientation,\n cols = 1,\n scrollItemIntoView = true,\n virtualItemRef,\n itemSizes,\n dense = false\n } = props;\n if (true) {\n if (allowEscape) {\n if (!loop) {\n warn('`useListNavigation` looping must be enabled to allow escaping.');\n }\n if (!virtual) {\n warn('`useListNavigation` must be virtual to allow escaping.');\n }\n }\n if (orientation === 'vertical' && cols > 1) {\n warn('In grid list navigation mode (`cols` > 1), the `orientation` should', 'be either \"horizontal\" or \"both\".');\n }\n }\n const floatingFocusElement = (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)(elements.floating);\n const floatingFocusElementRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(floatingFocusElement);\n const parentId = useFloatingParentNodeId();\n const tree = useFloatingTree();\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n context.dataRef.current.orientation = orientation;\n }, [context, orientation]);\n const onNavigate = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n unstable_onNavigate(indexRef.current === -1 ? null : indexRef.current);\n });\n const typeableComboboxReference = (0,_floating_ui_react_utils__rspack_import_6.isTypeableCombobox)(elements.domReference);\n const focusItemOnOpenRef = react__rspack_import_0.useRef(focusItemOnOpen);\n const indexRef = react__rspack_import_0.useRef(selectedIndex != null ? selectedIndex : -1);\n const keyRef = react__rspack_import_0.useRef(null);\n const isPointerModalityRef = react__rspack_import_0.useRef(true);\n const previousOnNavigateRef = react__rspack_import_0.useRef(onNavigate);\n const previousMountedRef = react__rspack_import_0.useRef(!!elements.floating);\n const previousOpenRef = react__rspack_import_0.useRef(open);\n const forceSyncFocusRef = react__rspack_import_0.useRef(false);\n const forceScrollIntoViewRef = react__rspack_import_0.useRef(false);\n const disabledIndicesRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(disabledIndices);\n const latestOpenRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(open);\n const scrollItemIntoViewRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(scrollItemIntoView);\n const selectedIndexRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(selectedIndex);\n const [activeId, setActiveId] = react__rspack_import_0.useState();\n const [virtualId, setVirtualId] = react__rspack_import_0.useState();\n const focusItem = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n function runFocus(item) {\n if (virtual) {\n var _item$id;\n if ((_item$id = item.id) != null && _item$id.endsWith('-fui-option')) {\n item.id = floatingId + \"-\" + Math.random().toString(16).slice(2, 10);\n }\n setActiveId(item.id);\n tree == null || tree.events.emit('virtualfocus', item);\n if (virtualItemRef) {\n virtualItemRef.current = item;\n }\n } else {\n enqueueFocus(item, {\n sync: forceSyncFocusRef.current,\n preventScroll: true\n });\n }\n }\n const initialItem = listRef.current[indexRef.current];\n const forceScrollIntoView = forceScrollIntoViewRef.current;\n if (initialItem) {\n runFocus(initialItem);\n }\n const scheduler = forceSyncFocusRef.current ? v => v() : requestAnimationFrame;\n scheduler(() => {\n const waitedItem = listRef.current[indexRef.current] || initialItem;\n if (!waitedItem) return;\n if (!initialItem) {\n runFocus(waitedItem);\n }\n const scrollIntoViewOptions = scrollItemIntoViewRef.current;\n const shouldScrollIntoView = scrollIntoViewOptions && item && (forceScrollIntoView || !isPointerModalityRef.current);\n if (shouldScrollIntoView) {\n // JSDOM doesn't support `.scrollIntoView()` but it's widely supported\n // by all browsers.\n waitedItem.scrollIntoView == null || waitedItem.scrollIntoView(typeof scrollIntoViewOptions === 'boolean' ? {\n block: 'nearest',\n inline: 'nearest'\n } : scrollIntoViewOptions);\n }\n });\n });\n\n // Sync `selectedIndex` to be the `activeIndex` upon opening the floating\n // element. Also, reset `activeIndex` upon closing the floating element.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (open && elements.floating) {\n if (focusItemOnOpenRef.current && selectedIndex != null) {\n // Regardless of the pointer modality, we want to ensure the selected\n // item comes into view when the floating element is opened.\n forceScrollIntoViewRef.current = true;\n indexRef.current = selectedIndex;\n onNavigate();\n }\n } else if (previousMountedRef.current) {\n // Since the user can specify `onNavigate` conditionally\n // (onNavigate: open ? setActiveIndex : setSelectedIndex),\n // we store and call the previous function.\n indexRef.current = -1;\n previousOnNavigateRef.current();\n }\n }, [enabled, open, elements.floating, selectedIndex, onNavigate]);\n\n // Sync `activeIndex` to be the focused item while the floating element is\n // open.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!open) return;\n if (!elements.floating) return;\n if (activeIndex == null) {\n forceSyncFocusRef.current = false;\n if (selectedIndexRef.current != null) {\n return;\n }\n\n // Reset while the floating element was open (e.g. the list changed).\n if (previousMountedRef.current) {\n indexRef.current = -1;\n focusItem();\n }\n\n // Initial sync.\n if ((!previousOpenRef.current || !previousMountedRef.current) && focusItemOnOpenRef.current && (keyRef.current != null || focusItemOnOpenRef.current === true && keyRef.current == null)) {\n let runs = 0;\n const waitForListPopulated = () => {\n if (listRef.current[0] == null) {\n // Avoid letting the browser paint if possible on the first try,\n // otherwise use rAF. Don't try more than twice, since something\n // is wrong otherwise.\n if (runs < 2) {\n const scheduler = runs ? requestAnimationFrame : queueMicrotask;\n scheduler(waitForListPopulated);\n }\n runs++;\n } else {\n indexRef.current = keyRef.current == null || isMainOrientationToEndKey(keyRef.current, orientation, rtl) || nested ? (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(listRef, disabledIndicesRef.current) : (0,_floating_ui_react_utils__rspack_import_6.getMaxListIndex)(listRef, disabledIndicesRef.current);\n keyRef.current = null;\n onNavigate();\n }\n };\n waitForListPopulated();\n }\n } else if (!(0,_floating_ui_react_utils__rspack_import_6.isIndexOutOfListBounds)(listRef, activeIndex)) {\n indexRef.current = activeIndex;\n focusItem();\n forceScrollIntoViewRef.current = false;\n }\n }, [enabled, open, elements.floating, activeIndex, selectedIndexRef, nested, listRef, orientation, rtl, onNavigate, focusItem, disabledIndicesRef]);\n\n // Ensure the parent floating element has focus when a nested child closes\n // to allow arrow key navigation to work after the pointer leaves the child.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n var _nodes$find;\n if (!enabled || elements.floating || !tree || virtual || !previousMountedRef.current) {\n return;\n }\n const nodes = tree.nodesRef.current;\n const parent = (_nodes$find = nodes.find(node => node.id === parentId)) == null || (_nodes$find = _nodes$find.context) == null ? void 0 : _nodes$find.elements.floating;\n const activeEl = (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating));\n const treeContainsActiveEl = nodes.some(node => node.context && (0,_floating_ui_react_utils__rspack_import_6.contains)(node.context.elements.floating, activeEl));\n if (parent && !treeContainsActiveEl && isPointerModalityRef.current) {\n parent.focus({\n preventScroll: true\n });\n }\n }, [enabled, elements.floating, tree, parentId, virtual]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!tree) return;\n if (!virtual) return;\n if (parentId) return;\n function handleVirtualFocus(item) {\n setVirtualId(item.id);\n if (virtualItemRef) {\n virtualItemRef.current = item;\n }\n }\n tree.events.on('virtualfocus', handleVirtualFocus);\n return () => {\n tree.events.off('virtualfocus', handleVirtualFocus);\n };\n }, [enabled, tree, virtual, parentId, virtualItemRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n previousOnNavigateRef.current = onNavigate;\n previousOpenRef.current = open;\n previousMountedRef.current = !!elements.floating;\n });\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!open) {\n keyRef.current = null;\n }\n }, [open]);\n const hasActiveIndex = activeIndex != null;\n const item = react__rspack_import_0.useMemo(() => {\n function syncCurrentTarget(currentTarget) {\n if (!open) return;\n const index = listRef.current.indexOf(currentTarget);\n if (index !== -1 && indexRef.current !== index) {\n indexRef.current = index;\n onNavigate();\n }\n }\n const props = {\n onFocus(_ref) {\n let {\n currentTarget\n } = _ref;\n forceSyncFocusRef.current = true;\n syncCurrentTarget(currentTarget);\n },\n onClick: _ref2 => {\n let {\n currentTarget\n } = _ref2;\n return currentTarget.focus({\n preventScroll: true\n });\n },\n // Safari\n ...(focusItemOnHover && {\n onMouseMove(_ref3) {\n let {\n currentTarget\n } = _ref3;\n forceSyncFocusRef.current = true;\n forceScrollIntoViewRef.current = false;\n syncCurrentTarget(currentTarget);\n },\n onPointerLeave(_ref4) {\n let {\n pointerType\n } = _ref4;\n if (!isPointerModalityRef.current || pointerType === 'touch') {\n return;\n }\n forceSyncFocusRef.current = true;\n indexRef.current = -1;\n onNavigate();\n if (!virtual) {\n var _floatingFocusElement;\n (_floatingFocusElement = floatingFocusElementRef.current) == null || _floatingFocusElement.focus({\n preventScroll: true\n });\n }\n }\n })\n };\n return props;\n }, [open, floatingFocusElementRef, focusItemOnHover, listRef, onNavigate, virtual]);\n const getParentOrientation = react__rspack_import_0.useCallback(() => {\n var _tree$nodesRef$curren;\n return parentOrientation != null ? parentOrientation : tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.dataRef) == null ? void 0 : _tree$nodesRef$curren.current.orientation;\n }, [parentId, tree, parentOrientation]);\n const commonOnKeyDown = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n isPointerModalityRef.current = false;\n forceSyncFocusRef.current = true;\n\n // When composing a character, Chrome fires ArrowDown twice. Firefox/Safari\n // don't appear to suffer from this. `event.isComposing` is avoided due to\n // Safari not supporting it properly (although it's not needed in the first\n // place for Safari, just avoiding any possible issues).\n if (event.which === 229) {\n return;\n }\n\n // If the floating element is animating out, ignore navigation. Otherwise,\n // the `activeIndex` gets set to 0 despite not being open so the next time\n // the user ArrowDowns, the first item won't be focused.\n if (!latestOpenRef.current && event.currentTarget === floatingFocusElementRef.current) {\n return;\n }\n if (nested && isCrossOrientationCloseKey(event.key, orientation, rtl, cols)) {\n // If the nested list's close key is also the parent navigation key,\n // let the parent navigate. Otherwise, stop propagating the event.\n if (!isMainOrientationKey(event.key, getParentOrientation())) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n }\n onOpenChange(false, event.nativeEvent, 'list-navigation');\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(elements.domReference)) {\n if (virtual) {\n tree == null || tree.events.emit('virtualfocus', elements.domReference);\n } else {\n elements.domReference.focus();\n }\n }\n return;\n }\n const currentIndex = indexRef.current;\n const minIndex = (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(listRef, disabledIndices);\n const maxIndex = (0,_floating_ui_react_utils__rspack_import_6.getMaxListIndex)(listRef, disabledIndices);\n if (!typeableComboboxReference) {\n if (event.key === 'Home') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n indexRef.current = minIndex;\n onNavigate();\n }\n if (event.key === 'End') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n indexRef.current = maxIndex;\n onNavigate();\n }\n }\n\n // Grid navigation.\n if (cols > 1) {\n const sizes = itemSizes || Array.from({\n length: listRef.current.length\n }, () => ({\n width: 1,\n height: 1\n }));\n // To calculate movements on the grid, we use hypothetical cell indices\n // as if every item was 1x1, then convert back to real indices.\n const cellMap = (0,_floating_ui_react_utils__rspack_import_6.createGridCellMap)(sizes, cols, dense);\n const minGridIndex = cellMap.findIndex(index => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(listRef, index, disabledIndices));\n // last enabled index\n const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(listRef, index, disabledIndices) ? cellIndex : foundIndex, -1);\n const index = cellMap[(0,_floating_ui_react_utils__rspack_import_6.getGridNavigatedIndex)({\n current: cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null)\n }, {\n event,\n orientation,\n loop,\n rtl,\n cols,\n // treat undefined (empty grid spaces) as disabled indices so we\n // don't end up in them\n disabledIndices: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndices)([...(disabledIndices || listRef.current.map((_, index) => (0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(listRef, index) ? index : undefined)), undefined], cellMap),\n minIndex: minGridIndex,\n maxIndex: maxGridIndex,\n prevIndex: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndexOfCorner)(indexRef.current > maxIndex ? minIndex : indexRef.current, sizes, cellMap, cols,\n // use a corner matching the edge closest to the direction\n // we're moving in so we don't end up in the same item. Prefer\n // top/left over bottom/right.\n event.key === ARROW_DOWN ? 'bl' : event.key === (rtl ? ARROW_LEFT : ARROW_RIGHT) ? 'tr' : 'tl'),\n stopEvent: true\n })];\n if (index != null) {\n indexRef.current = index;\n onNavigate();\n }\n if (orientation === 'both') {\n return;\n }\n }\n if (isMainOrientationKey(event.key, orientation)) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n\n // Reset the index if no item is focused.\n if (open && !virtual && (0,_floating_ui_react_utils__rspack_import_6.activeElement)(event.currentTarget.ownerDocument) === event.currentTarget) {\n indexRef.current = isMainOrientationToEndKey(event.key, orientation, rtl) ? minIndex : maxIndex;\n onNavigate();\n return;\n }\n if (isMainOrientationToEndKey(event.key, orientation, rtl)) {\n if (loop) {\n indexRef.current = currentIndex >= maxIndex ? allowEscape && currentIndex !== listRef.current.length ? -1 : minIndex : (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n disabledIndices\n });\n } else {\n indexRef.current = Math.min(maxIndex, (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n disabledIndices\n }));\n }\n } else {\n if (loop) {\n indexRef.current = currentIndex <= minIndex ? allowEscape && currentIndex !== -1 ? listRef.current.length : maxIndex : (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n decrement: true,\n disabledIndices\n });\n } else {\n indexRef.current = Math.max(minIndex, (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n decrement: true,\n disabledIndices\n }));\n }\n }\n if ((0,_floating_ui_react_utils__rspack_import_6.isIndexOutOfListBounds)(listRef, indexRef.current)) {\n indexRef.current = -1;\n }\n onNavigate();\n }\n });\n const ariaActiveDescendantProp = react__rspack_import_0.useMemo(() => {\n return virtual && open && hasActiveIndex && {\n 'aria-activedescendant': virtualId || activeId\n };\n }, [virtual, open, hasActiveIndex, virtualId, activeId]);\n const floating = react__rspack_import_0.useMemo(() => {\n return {\n 'aria-orientation': orientation === 'both' ? undefined : orientation,\n ...(!typeableComboboxReference ? ariaActiveDescendantProp : {}),\n onKeyDown: commonOnKeyDown,\n onPointerMove() {\n isPointerModalityRef.current = true;\n }\n };\n }, [ariaActiveDescendantProp, commonOnKeyDown, orientation, typeableComboboxReference]);\n const reference = react__rspack_import_0.useMemo(() => {\n function checkVirtualMouse(event) {\n if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__rspack_import_6.isVirtualClick)(event.nativeEvent)) {\n focusItemOnOpenRef.current = true;\n }\n }\n function checkVirtualPointer(event) {\n // `pointerdown` fires first, reset the state then perform the checks.\n focusItemOnOpenRef.current = focusItemOnOpen;\n if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__rspack_import_6.isVirtualPointerEvent)(event.nativeEvent)) {\n focusItemOnOpenRef.current = true;\n }\n }\n return {\n ...ariaActiveDescendantProp,\n onKeyDown(event) {\n isPointerModalityRef.current = false;\n const isArrowKey = event.key.startsWith('Arrow');\n const isHomeOrEndKey = ['Home', 'End'].includes(event.key);\n const isMoveKey = isArrowKey || isHomeOrEndKey;\n const isCrossOpenKey = isCrossOrientationOpenKey(event.key, orientation, rtl);\n const isCrossCloseKey = isCrossOrientationCloseKey(event.key, orientation, rtl, cols);\n const isParentCrossOpenKey = isCrossOrientationOpenKey(event.key, getParentOrientation(), rtl);\n const isMainKey = isMainOrientationKey(event.key, orientation);\n const isNavigationKey = (nested ? isParentCrossOpenKey : isMainKey) || event.key === 'Enter' || event.key.trim() === '';\n if (virtual && open) {\n const rootNode = tree == null ? void 0 : tree.nodesRef.current.find(node => node.parentId == null);\n const deepestNode = tree && rootNode ? (0,_floating_ui_react_utils__rspack_import_6.getDeepestNode)(tree.nodesRef.current, rootNode.id) : null;\n if (isMoveKey && deepestNode && virtualItemRef) {\n const eventObject = new KeyboardEvent('keydown', {\n key: event.key,\n bubbles: true\n });\n if (isCrossOpenKey || isCrossCloseKey) {\n var _deepestNode$context, _deepestNode$context2;\n const isCurrentTarget = ((_deepestNode$context = deepestNode.context) == null ? void 0 : _deepestNode$context.elements.domReference) === event.currentTarget;\n const dispatchItem = isCrossCloseKey && !isCurrentTarget ? (_deepestNode$context2 = deepestNode.context) == null ? void 0 : _deepestNode$context2.elements.domReference : isCrossOpenKey ? listRef.current.find(item => (item == null ? void 0 : item.id) === activeId) : null;\n if (dispatchItem) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n dispatchItem.dispatchEvent(eventObject);\n setVirtualId(undefined);\n }\n }\n if ((isMainKey || isHomeOrEndKey) && deepestNode.context) {\n if (deepestNode.context.open && deepestNode.parentId && event.currentTarget !== deepestNode.context.elements.domReference) {\n var _deepestNode$context$;\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n (_deepestNode$context$ = deepestNode.context.elements.domReference) == null || _deepestNode$context$.dispatchEvent(eventObject);\n return;\n }\n }\n }\n return commonOnKeyDown(event);\n }\n // If a floating element should not open on arrow key down, avoid\n // setting `activeIndex` while it's closed.\n if (!open && !openOnArrowKeyDown && isArrowKey) {\n return;\n }\n if (isNavigationKey) {\n const isParentMainKey = isMainOrientationKey(event.key, getParentOrientation());\n keyRef.current = nested && isParentMainKey ? null : event.key;\n }\n if (nested) {\n if (isParentCrossOpenKey) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n if (open) {\n indexRef.current = (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(listRef, disabledIndicesRef.current);\n onNavigate();\n } else {\n onOpenChange(true, event.nativeEvent, 'list-navigation');\n }\n }\n return;\n }\n if (isMainKey) {\n if (selectedIndex != null) {\n indexRef.current = selectedIndex;\n }\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n if (!open && openOnArrowKeyDown) {\n onOpenChange(true, event.nativeEvent, 'list-navigation');\n } else {\n commonOnKeyDown(event);\n }\n if (open) {\n onNavigate();\n }\n }\n },\n onFocus() {\n if (open && !virtual) {\n indexRef.current = -1;\n onNavigate();\n }\n },\n onPointerDown: checkVirtualPointer,\n onPointerEnter: checkVirtualPointer,\n onMouseDown: checkVirtualMouse,\n onClick: checkVirtualMouse\n };\n }, [activeId, ariaActiveDescendantProp, cols, commonOnKeyDown, disabledIndicesRef, focusItemOnOpen, listRef, nested, onNavigate, onOpenChange, open, openOnArrowKeyDown, orientation, getParentOrientation, rtl, selectedIndex, tree, virtual, virtualItemRef]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating,\n item\n } : {}, [enabled, reference, floating, item]);\n}\n\nconst componentRoleToAriaRoleMap = /*#__PURE__*/new Map([['select', 'listbox'], ['combobox', 'listbox'], ['label', false]]);\n\n/**\n * Adds base screen reader props to the reference and floating elements for a\n * given floating element `role`.\n * @see https://floating-ui.com/docs/useRole\n */\nfunction useRole(context, props) {\n var _elements$domReferenc, _componentRoleToAriaR;\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n elements,\n floatingId: defaultFloatingId\n } = context;\n const {\n enabled = true,\n role = 'dialog'\n } = props;\n const defaultReferenceId = useId();\n const referenceId = ((_elements$domReferenc = elements.domReference) == null ? void 0 : _elements$domReferenc.id) || defaultReferenceId;\n const floatingId = react__rspack_import_0.useMemo(() => {\n var _getFloatingFocusElem;\n return ((_getFloatingFocusElem = (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)(elements.floating)) == null ? void 0 : _getFloatingFocusElem.id) || defaultFloatingId;\n }, [elements.floating, defaultFloatingId]);\n const ariaRole = (_componentRoleToAriaR = componentRoleToAriaRoleMap.get(role)) != null ? _componentRoleToAriaR : role;\n const parentId = useFloatingParentNodeId();\n const isNested = parentId != null;\n const reference = react__rspack_import_0.useMemo(() => {\n if (ariaRole === 'tooltip' || role === 'label') {\n return {\n [\"aria-\" + (role === 'label' ? 'labelledby' : 'describedby')]: open ? floatingId : undefined\n };\n }\n return {\n 'aria-expanded': open ? 'true' : 'false',\n 'aria-haspopup': ariaRole === 'alertdialog' ? 'dialog' : ariaRole,\n 'aria-controls': open ? floatingId : undefined,\n ...(ariaRole === 'listbox' && {\n role: 'combobox'\n }),\n ...(ariaRole === 'menu' && {\n id: referenceId\n }),\n ...(ariaRole === 'menu' && isNested && {\n role: 'menuitem'\n }),\n ...(role === 'select' && {\n 'aria-autocomplete': 'none'\n }),\n ...(role === 'combobox' && {\n 'aria-autocomplete': 'list'\n })\n };\n }, [ariaRole, floatingId, isNested, open, referenceId, role]);\n const floating = react__rspack_import_0.useMemo(() => {\n const floatingProps = {\n id: floatingId,\n ...(ariaRole && {\n role: ariaRole\n })\n };\n if (ariaRole === 'tooltip' || role === 'label') {\n return floatingProps;\n }\n return {\n ...floatingProps,\n ...(ariaRole === 'menu' && {\n 'aria-labelledby': referenceId\n })\n };\n }, [ariaRole, floatingId, referenceId, role]);\n const item = react__rspack_import_0.useCallback(_ref => {\n let {\n active,\n selected\n } = _ref;\n const commonProps = {\n role: 'option',\n ...(active && {\n id: floatingId + \"-fui-option\"\n })\n };\n\n // For `menu`, we are unable to tell if the item is a `menuitemradio`\n // or `menuitemcheckbox`. For backwards-compatibility reasons, also\n // avoid defaulting to `menuitem` as it may overwrite custom role props.\n switch (role) {\n case 'select':\n return {\n ...commonProps,\n 'aria-selected': active && selected\n };\n case 'combobox':\n {\n return {\n ...commonProps,\n 'aria-selected': selected\n };\n }\n }\n return {};\n }, [floatingId, role]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating,\n item\n } : {}, [enabled, reference, floating, item]);\n}\n\n// Converts a JS style key like `backgroundColor` to a CSS transition-property\n// like `background-color`.\nconst camelCaseToKebabCase = str => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());\nfunction execWithArgsOrReturn(valueOrFn, args) {\n return typeof valueOrFn === 'function' ? valueOrFn(args) : valueOrFn;\n}\nfunction useDelayUnmount(open, durationMs) {\n const [isMounted, setIsMounted] = react__rspack_import_0.useState(open);\n if (open && !isMounted) {\n setIsMounted(true);\n }\n react__rspack_import_0.useEffect(() => {\n if (!open && isMounted) {\n const timeout = setTimeout(() => setIsMounted(false), durationMs);\n return () => clearTimeout(timeout);\n }\n }, [open, isMounted, durationMs]);\n return isMounted;\n}\n/**\n * Provides a status string to apply CSS transitions to a floating element,\n * correctly handling placement-aware transitions.\n * @see https://floating-ui.com/docs/useTransition#usetransitionstatus\n */\nfunction useTransitionStatus(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n elements: {\n floating\n }\n } = context;\n const {\n duration = 250\n } = props;\n const isNumberDuration = typeof duration === 'number';\n const closeDuration = (isNumberDuration ? duration : duration.close) || 0;\n const [status, setStatus] = react__rspack_import_0.useState('unmounted');\n const isMounted = useDelayUnmount(open, closeDuration);\n if (!isMounted && status === 'close') {\n setStatus('unmounted');\n }\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!floating) return;\n if (open) {\n setStatus('initial');\n const frame = requestAnimationFrame(() => {\n // Ensure it opens before paint. With `FloatingDelayGroup`,\n // this avoids a flicker when moving between floating elements\n // to ensure one is always open with no missing frames.\n react_dom__rspack_import_2.flushSync(() => {\n setStatus('open');\n });\n });\n return () => {\n cancelAnimationFrame(frame);\n };\n }\n setStatus('close');\n }, [open, floating]);\n return {\n isMounted,\n status\n };\n}\n/**\n * Provides styles to apply CSS transitions to a floating element, correctly\n * handling placement-aware transitions. Wrapper around `useTransitionStatus`.\n * @see https://floating-ui.com/docs/useTransition#usetransitionstyles\n */\nfunction useTransitionStyles(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n initial: unstable_initial = {\n opacity: 0\n },\n open: unstable_open,\n close: unstable_close,\n common: unstable_common,\n duration = 250\n } = props;\n const placement = context.placement;\n const side = placement.split('-')[0];\n const fnArgs = react__rspack_import_0.useMemo(() => ({\n side,\n placement\n }), [side, placement]);\n const isNumberDuration = typeof duration === 'number';\n const openDuration = (isNumberDuration ? duration : duration.open) || 0;\n const closeDuration = (isNumberDuration ? duration : duration.close) || 0;\n const [styles, setStyles] = react__rspack_import_0.useState(() => ({\n ...execWithArgsOrReturn(unstable_common, fnArgs),\n ...execWithArgsOrReturn(unstable_initial, fnArgs)\n }));\n const {\n isMounted,\n status\n } = useTransitionStatus(context, {\n duration\n });\n const initialRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_initial);\n const openRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_open);\n const closeRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_close);\n const commonRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_common);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n const initialStyles = execWithArgsOrReturn(initialRef.current, fnArgs);\n const closeStyles = execWithArgsOrReturn(closeRef.current, fnArgs);\n const commonStyles = execWithArgsOrReturn(commonRef.current, fnArgs);\n const openStyles = execWithArgsOrReturn(openRef.current, fnArgs) || Object.keys(initialStyles).reduce((acc, key) => {\n acc[key] = '';\n return acc;\n }, {});\n if (status === 'initial') {\n setStyles(styles => ({\n transitionProperty: styles.transitionProperty,\n ...commonStyles,\n ...initialStyles\n }));\n }\n if (status === 'open') {\n setStyles({\n transitionProperty: Object.keys(openStyles).map(camelCaseToKebabCase).join(','),\n transitionDuration: openDuration + \"ms\",\n ...commonStyles,\n ...openStyles\n });\n }\n if (status === 'close') {\n const styles = closeStyles || initialStyles;\n setStyles({\n transitionProperty: Object.keys(styles).map(camelCaseToKebabCase).join(','),\n transitionDuration: closeDuration + \"ms\",\n ...commonStyles,\n ...styles\n });\n }\n }, [closeDuration, closeRef, initialRef, openRef, commonRef, openDuration, status, fnArgs]);\n return {\n isMounted,\n styles\n };\n}\n\n/**\n * Provides a matching callback that can be used to focus an item as the user\n * types, often used in tandem with `useListNavigation()`.\n * @see https://floating-ui.com/docs/useTypeahead\n */\nfunction useTypeahead(context, props) {\n var _ref;\n const {\n open,\n dataRef\n } = context;\n const {\n listRef,\n activeIndex,\n onMatch: unstable_onMatch,\n onTypingChange: unstable_onTypingChange,\n enabled = true,\n findMatch = null,\n resetMs = 750,\n ignoreKeys = [],\n selectedIndex = null\n } = props;\n const timeoutIdRef = react__rspack_import_0.useRef(-1);\n const stringRef = react__rspack_import_0.useRef('');\n const prevIndexRef = react__rspack_import_0.useRef((_ref = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref : -1);\n const matchIndexRef = react__rspack_import_0.useRef(null);\n const onMatch = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(unstable_onMatch);\n const onTypingChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(unstable_onTypingChange);\n const findMatchRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(findMatch);\n const ignoreKeysRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(ignoreKeys);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (open) {\n clearTimeoutIfSet(timeoutIdRef);\n matchIndexRef.current = null;\n stringRef.current = '';\n }\n }, [open]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n // Sync arrow key navigation but not typeahead navigation.\n if (open && stringRef.current === '') {\n var _ref2;\n prevIndexRef.current = (_ref2 = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref2 : -1;\n }\n }, [open, selectedIndex, activeIndex]);\n const setTypingChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(value => {\n if (value) {\n if (!dataRef.current.typing) {\n dataRef.current.typing = value;\n onTypingChange(value);\n }\n } else {\n if (dataRef.current.typing) {\n dataRef.current.typing = value;\n onTypingChange(value);\n }\n }\n });\n const onKeyDown = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n function getMatchingIndex(list, orderedList, string) {\n const str = findMatchRef.current ? findMatchRef.current(orderedList, string) : orderedList.find(text => (text == null ? void 0 : text.toLocaleLowerCase().indexOf(string.toLocaleLowerCase())) === 0);\n return str ? list.indexOf(str) : -1;\n }\n const listContent = listRef.current;\n if (stringRef.current.length > 0 && stringRef.current[0] !== ' ') {\n if (getMatchingIndex(listContent, listContent, stringRef.current) === -1) {\n setTypingChange(false);\n } else if (event.key === ' ') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n }\n }\n if (listContent == null || ignoreKeysRef.current.includes(event.key) ||\n // Character key.\n event.key.length !== 1 ||\n // Modifier key.\n event.ctrlKey || event.metaKey || event.altKey) {\n return;\n }\n if (open && event.key !== ' ') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n setTypingChange(true);\n }\n\n // Bail out if the list contains a word like \"llama\" or \"aaron\". TODO:\n // allow it in this case, too.\n const allowRapidSuccessionOfFirstLetter = listContent.every(text => {\n var _text$, _text$2;\n return text ? ((_text$ = text[0]) == null ? void 0 : _text$.toLocaleLowerCase()) !== ((_text$2 = text[1]) == null ? void 0 : _text$2.toLocaleLowerCase()) : true;\n });\n\n // Allows the user to cycle through items that start with the same letter\n // in rapid succession.\n if (allowRapidSuccessionOfFirstLetter && stringRef.current === event.key) {\n stringRef.current = '';\n prevIndexRef.current = matchIndexRef.current;\n }\n stringRef.current += event.key;\n clearTimeoutIfSet(timeoutIdRef);\n timeoutIdRef.current = window.setTimeout(() => {\n stringRef.current = '';\n prevIndexRef.current = matchIndexRef.current;\n setTypingChange(false);\n }, resetMs);\n const prevIndex = prevIndexRef.current;\n const index = getMatchingIndex(listContent, [...listContent.slice((prevIndex || 0) + 1), ...listContent.slice(0, (prevIndex || 0) + 1)], stringRef.current);\n if (index !== -1) {\n onMatch(index);\n matchIndexRef.current = index;\n } else if (event.key !== ' ') {\n stringRef.current = '';\n setTypingChange(false);\n }\n });\n const reference = react__rspack_import_0.useMemo(() => ({\n onKeyDown\n }), [onKeyDown]);\n const floating = react__rspack_import_0.useMemo(() => {\n return {\n onKeyDown,\n onKeyUp(event) {\n if (event.key === ' ') {\n setTypingChange(false);\n }\n }\n };\n }, [onKeyDown, setTypingChange]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nfunction getArgsWithCustomFloatingHeight(state, height) {\n return {\n ...state,\n rects: {\n ...state.rects,\n floating: {\n ...state.rects.floating,\n height\n }\n }\n };\n}\n/**\n * Positions the floating element such that an inner element inside of it is\n * anchored to the reference element.\n * @see https://floating-ui.com/docs/inner\n * @deprecated\n */\nconst inner = props => ({\n name: 'inner',\n options: props,\n async fn(state) {\n const {\n listRef,\n overflowRef,\n onFallbackChange,\n offset: innerOffset = 0,\n index = 0,\n minItemsVisible = 4,\n referenceOverflowThreshold = 0,\n scrollRef,\n ...detectOverflowOptions\n } = (0,_floating_ui_utils__rspack_import_8.evaluate)(props, state);\n const {\n rects,\n elements: {\n floating\n }\n } = state;\n const item = listRef.current[index];\n const scrollEl = (scrollRef == null ? void 0 : scrollRef.current) || floating;\n\n // Valid combinations:\n // 1. Floating element is the scrollRef and has a border (default)\n // 2. Floating element is not the scrollRef, floating element has a border\n // 3. Floating element is not the scrollRef, scrollRef has a border\n // Floating > {...getFloatingProps()} wrapper > scrollRef > items is not\n // allowed as VoiceOver doesn't work.\n const clientTop = floating.clientTop || scrollEl.clientTop;\n const floatingIsBordered = floating.clientTop !== 0;\n const scrollElIsBordered = scrollEl.clientTop !== 0;\n const floatingIsScrollEl = floating === scrollEl;\n if (true) {\n if (!state.placement.startsWith('bottom')) {\n warn('`placement` side must be \"bottom\" when using the `inner`', 'middleware.');\n }\n }\n if (!item) {\n return {};\n }\n const nextArgs = {\n ...state,\n ...(await (0,_floating_ui_react_dom__rspack_import_3.offset)(-item.offsetTop - floating.clientTop - rects.reference.height / 2 - item.offsetHeight / 2 - innerOffset).fn(state))\n };\n const overflow = await (0,_floating_ui_react_dom__rspack_import_4.detectOverflow)(getArgsWithCustomFloatingHeight(nextArgs, scrollEl.scrollHeight + clientTop + floating.clientTop), detectOverflowOptions);\n const refOverflow = await (0,_floating_ui_react_dom__rspack_import_4.detectOverflow)(nextArgs, {\n ...detectOverflowOptions,\n elementContext: 'reference'\n });\n const diffY = (0,_floating_ui_utils__rspack_import_8.max)(0, overflow.top);\n const nextY = nextArgs.y + diffY;\n const isScrollable = scrollEl.scrollHeight > scrollEl.clientHeight;\n const rounder = isScrollable ? v => v : _floating_ui_utils__rspack_import_8.round;\n const maxHeight = rounder((0,_floating_ui_utils__rspack_import_8.max)(0, scrollEl.scrollHeight + (floatingIsBordered && floatingIsScrollEl || scrollElIsBordered ? clientTop * 2 : 0) - diffY - (0,_floating_ui_utils__rspack_import_8.max)(0, overflow.bottom)));\n scrollEl.style.maxHeight = maxHeight + \"px\";\n scrollEl.scrollTop = diffY;\n\n // There is not enough space, fallback to standard anchored positioning\n if (onFallbackChange) {\n const shouldFallback = scrollEl.offsetHeight < item.offsetHeight * (0,_floating_ui_utils__rspack_import_8.min)(minItemsVisible, listRef.current.length) - 1 || refOverflow.top >= -referenceOverflowThreshold || refOverflow.bottom >= -referenceOverflowThreshold;\n react_dom__rspack_import_2.flushSync(() => onFallbackChange(shouldFallback));\n }\n if (overflowRef) {\n overflowRef.current = await (0,_floating_ui_react_dom__rspack_import_4.detectOverflow)(getArgsWithCustomFloatingHeight({\n ...nextArgs,\n y: nextY\n }, scrollEl.offsetHeight + clientTop + floating.clientTop), detectOverflowOptions);\n }\n return {\n y: nextY\n };\n }\n});\n/**\n * Changes the `inner` middleware's `offset` upon a `wheel` event to\n * expand the floating element's height, revealing more list items.\n * @see https://floating-ui.com/docs/inner\n * @deprecated\n */\nfunction useInnerOffset(context, props) {\n const {\n open,\n elements\n } = context;\n const {\n enabled = true,\n overflowRef,\n scrollRef,\n onChange: unstable_onChange\n } = props;\n const onChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(unstable_onChange);\n const controlledScrollingRef = react__rspack_import_0.useRef(false);\n const prevScrollTopRef = react__rspack_import_0.useRef(null);\n const initialOverflowRef = react__rspack_import_0.useRef(null);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onWheel(e) {\n if (e.ctrlKey || !el || overflowRef.current == null) {\n return;\n }\n const dY = e.deltaY;\n const isAtTop = overflowRef.current.top >= -0.5;\n const isAtBottom = overflowRef.current.bottom >= -0.5;\n const remainingScroll = el.scrollHeight - el.clientHeight;\n const sign = dY < 0 ? -1 : 1;\n const method = dY < 0 ? 'max' : 'min';\n if (el.scrollHeight <= el.clientHeight) {\n return;\n }\n if (!isAtTop && dY > 0 || !isAtBottom && dY < 0) {\n e.preventDefault();\n react_dom__rspack_import_2.flushSync(() => {\n onChange(d => d + Math[method](dY, remainingScroll * sign));\n });\n } else if (/firefox/i.test((0,_floating_ui_react_utils__rspack_import_6.getUserAgent)())) {\n // Needed to propagate scrolling during momentum scrolling phase once\n // it gets limited by the boundary. UX improvement, not critical.\n el.scrollTop += dY;\n }\n }\n const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;\n if (open && el) {\n el.addEventListener('wheel', onWheel);\n\n // Wait for the position to be ready.\n requestAnimationFrame(() => {\n prevScrollTopRef.current = el.scrollTop;\n if (overflowRef.current != null) {\n initialOverflowRef.current = {\n ...overflowRef.current\n };\n }\n });\n return () => {\n prevScrollTopRef.current = null;\n initialOverflowRef.current = null;\n el.removeEventListener('wheel', onWheel);\n };\n }\n }, [enabled, open, elements.floating, overflowRef, scrollRef, onChange]);\n const floating = react__rspack_import_0.useMemo(() => ({\n onKeyDown() {\n controlledScrollingRef.current = true;\n },\n onWheel() {\n controlledScrollingRef.current = false;\n },\n onPointerMove() {\n controlledScrollingRef.current = false;\n },\n onScroll() {\n const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;\n if (!overflowRef.current || !el || !controlledScrollingRef.current) {\n return;\n }\n if (prevScrollTopRef.current !== null) {\n const scrollDiff = el.scrollTop - prevScrollTopRef.current;\n if (overflowRef.current.bottom < -0.5 && scrollDiff < -1 || overflowRef.current.top < -0.5 && scrollDiff > 1) {\n react_dom__rspack_import_2.flushSync(() => onChange(d => d + scrollDiff));\n }\n }\n\n // [Firefox] Wait for the height change to have been applied.\n requestAnimationFrame(() => {\n prevScrollTopRef.current = el.scrollTop;\n });\n }\n }), [elements.floating, onChange, overflowRef, scrollRef]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n floating\n } : {}, [enabled, floating]);\n}\n\nfunction getNodeChildren(nodes, id, onlyOpenChildren) {\n if (onlyOpenChildren === void 0) {\n onlyOpenChildren = true;\n }\n let allChildren = nodes.filter(node => {\n var _node$context;\n return node.parentId === id && ((_node$context = node.context) == null ? void 0 : _node$context.open);\n });\n let currentChildren = allChildren;\n while (currentChildren.length) {\n currentChildren = onlyOpenChildren ? nodes.filter(node => {\n var _currentChildren;\n return (_currentChildren = currentChildren) == null ? void 0 : _currentChildren.some(n => {\n var _node$context2;\n return node.parentId === n.id && ((_node$context2 = node.context) == null ? void 0 : _node$context2.open);\n });\n }) : nodes;\n allChildren = allChildren.concat(currentChildren);\n }\n return allChildren;\n}\n\nfunction isPointInPolygon(point, polygon) {\n const [x, y] = point;\n let isInside = false;\n const length = polygon.length;\n for (let i = 0, j = length - 1; i < length; j = i++) {\n const [xi, yi] = polygon[i] || [0, 0];\n const [xj, yj] = polygon[j] || [0, 0];\n const intersect = yi >= y !== yj >= y && x <= (xj - xi) * (y - yi) / (yj - yi) + xi;\n if (intersect) {\n isInside = !isInside;\n }\n }\n return isInside;\n}\nfunction isInside(point, rect) {\n return point[0] >= rect.x && point[0] <= rect.x + rect.width && point[1] >= rect.y && point[1] <= rect.y + rect.height;\n}\n/**\n * Generates a safe polygon area that the user can traverse without closing the\n * floating element once leaving the reference element.\n * @see https://floating-ui.com/docs/useHover#safepolygon\n */\nfunction safePolygon(options) {\n if (options === void 0) {\n options = {};\n }\n const {\n buffer = 0.5,\n blockPointerEvents = false,\n requireIntent = true\n } = options;\n let timeoutId;\n let hasLanded = false;\n let lastX = null;\n let lastY = null;\n let lastCursorTime = performance.now();\n function getCursorSpeed(x, y) {\n const currentTime = performance.now();\n const elapsedTime = currentTime - lastCursorTime;\n if (lastX === null || lastY === null || elapsedTime === 0) {\n lastX = x;\n lastY = y;\n lastCursorTime = currentTime;\n return null;\n }\n const deltaX = x - lastX;\n const deltaY = y - lastY;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n const speed = distance / elapsedTime; // px / ms\n\n lastX = x;\n lastY = y;\n lastCursorTime = currentTime;\n return speed;\n }\n const fn = _ref => {\n let {\n x,\n y,\n placement,\n elements,\n onClose,\n nodeId,\n tree\n } = _ref;\n return function onMouseMove(event) {\n function close() {\n clearTimeout(timeoutId);\n onClose();\n }\n clearTimeout(timeoutId);\n if (!elements.domReference || !elements.floating || placement == null || x == null || y == null) {\n return;\n }\n const {\n clientX,\n clientY\n } = event;\n const clientPoint = [clientX, clientY];\n const target = getTarget(event);\n const isLeave = event.type === 'mouseleave';\n const isOverFloatingEl = contains(elements.floating, target);\n const isOverReferenceEl = contains(elements.domReference, target);\n const refRect = elements.domReference.getBoundingClientRect();\n const rect = elements.floating.getBoundingClientRect();\n const side = placement.split('-')[0];\n const cursorLeaveFromRight = x > rect.right - rect.width / 2;\n const cursorLeaveFromBottom = y > rect.bottom - rect.height / 2;\n const isOverReferenceRect = isInside(clientPoint, refRect);\n const isFloatingWider = rect.width > refRect.width;\n const isFloatingTaller = rect.height > refRect.height;\n const left = (isFloatingWider ? refRect : rect).left;\n const right = (isFloatingWider ? refRect : rect).right;\n const top = (isFloatingTaller ? refRect : rect).top;\n const bottom = (isFloatingTaller ? refRect : rect).bottom;\n if (isOverFloatingEl) {\n hasLanded = true;\n if (!isLeave) {\n return;\n }\n }\n if (isOverReferenceEl) {\n hasLanded = false;\n }\n if (isOverReferenceEl && !isLeave) {\n hasLanded = true;\n return;\n }\n\n // Prevent overlapping floating element from being stuck in an open-close\n // loop: https://github.com/floating-ui/floating-ui/issues/1910\n if (isLeave && (0,_floating_ui_react_dom__rspack_import_5.isElement)(event.relatedTarget) && contains(elements.floating, event.relatedTarget)) {\n return;\n }\n\n // If any nested child is open, abort.\n if (tree && getNodeChildren(tree.nodesRef.current, nodeId).some(_ref2 => {\n let {\n context\n } = _ref2;\n return context == null ? void 0 : context.open;\n })) {\n return;\n }\n\n // If the pointer is leaving from the opposite side, the \"buffer\" logic\n // creates a point where the floating element remains open, but should be\n // ignored.\n // A constant of 1 handles floating point rounding errors.\n if (side === 'top' && y >= refRect.bottom - 1 || side === 'bottom' && y <= refRect.top + 1 || side === 'left' && x >= refRect.right - 1 || side === 'right' && x <= refRect.left + 1) {\n return close();\n }\n\n // Ignore when the cursor is within the rectangular trough between the\n // two elements. Since the triangle is created from the cursor point,\n // which can start beyond the ref element's edge, traversing back and\n // forth from the ref to the floating element can cause it to close. This\n // ensures it always remains open in that case.\n let rectPoly = [];\n switch (side) {\n case 'top':\n rectPoly = [[left, refRect.top + 1], [left, rect.bottom - 1], [right, rect.bottom - 1], [right, refRect.top + 1]];\n break;\n case 'bottom':\n rectPoly = [[left, rect.top + 1], [left, refRect.bottom - 1], [right, refRect.bottom - 1], [right, rect.top + 1]];\n break;\n case 'left':\n rectPoly = [[rect.right - 1, bottom], [rect.right - 1, top], [refRect.left + 1, top], [refRect.left + 1, bottom]];\n break;\n case 'right':\n rectPoly = [[refRect.right - 1, bottom], [refRect.right - 1, top], [rect.left + 1, top], [rect.left + 1, bottom]];\n break;\n }\n function getPolygon(_ref3) {\n let [x, y] = _ref3;\n switch (side) {\n case 'top':\n {\n const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];\n const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];\n const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.bottom - buffer : isFloatingWider ? rect.bottom - buffer : rect.top], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.bottom - buffer : rect.top : rect.bottom - buffer]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n case 'bottom':\n {\n const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];\n const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];\n const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.top + buffer : isFloatingWider ? rect.top + buffer : rect.bottom], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.top + buffer : rect.bottom : rect.top + buffer]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n case 'left':\n {\n const cursorPointOne = [x + buffer + 1, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const cursorPointTwo = [x + buffer + 1, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const commonPoints = [[cursorLeaveFromBottom ? rect.right - buffer : isFloatingTaller ? rect.right - buffer : rect.left, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.right - buffer : rect.left : rect.right - buffer, rect.bottom]];\n return [...commonPoints, cursorPointOne, cursorPointTwo];\n }\n case 'right':\n {\n const cursorPointOne = [x - buffer, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const cursorPointTwo = [x - buffer, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const commonPoints = [[cursorLeaveFromBottom ? rect.left + buffer : isFloatingTaller ? rect.left + buffer : rect.right, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.left + buffer : rect.right : rect.left + buffer, rect.bottom]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n }\n }\n if (isPointInPolygon([clientX, clientY], rectPoly)) {\n return;\n }\n if (hasLanded && !isOverReferenceRect) {\n return close();\n }\n if (!isLeave && requireIntent) {\n const cursorSpeed = getCursorSpeed(event.clientX, event.clientY);\n const cursorSpeedThreshold = 0.1;\n if (cursorSpeed !== null && cursorSpeed < cursorSpeedThreshold) {\n return close();\n }\n }\n if (!isPointInPolygon([clientX, clientY], getPolygon([x, y]))) {\n close();\n } else if (!hasLanded && requireIntent) {\n timeoutId = window.setTimeout(close, 40);\n }\n };\n };\n fn.__options = {\n blockPointerEvents\n };\n return fn;\n}\n\n\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218L2hvbWUvcnVubmVyL3dvcmsvb3Blbm1ycy1lc20tY29yZS9vcGVubXJzLWVzbS1jb3JlL25vZGVfbW9kdWxlcy9AZmxvYXRpbmctdWkvcmVhY3QvZGlzdC9mbG9hdGluZy11aS5yZWFjdC5tanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9AZmxvYXRpbmctdWkvcmVhY3QvZGlzdC9mbG9hdGluZy11aS5yZWFjdC5tanM/MTA3ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QsIHVzZUVmZmVjdEV2ZW50LCBnZXRNaW5MaXN0SW5kZXgsIGdldE1heExpc3RJbmRleCwgY3JlYXRlR3JpZENlbGxNYXAsIGlzTGlzdEluZGV4RGlzYWJsZWQsIGdldEdyaWROYXZpZ2F0ZWRJbmRleCwgZ2V0R3JpZENlbGxJbmRleE9mQ29ybmVyLCBnZXRHcmlkQ2VsbEluZGljZXMsIGZpbmROb25EaXNhYmxlZExpc3RJbmRleCwgaXNJbmRleE91dE9mTGlzdEJvdW5kcywgdXNlTGF0ZXN0UmVmLCBnZXREb2N1bWVudCBhcyBnZXREb2N1bWVudCQxLCBpc01vdXNlTGlrZVBvaW50ZXJUeXBlLCBjb250YWlucyBhcyBjb250YWlucyQxLCBpc1NhZmFyaSwgZW5hYmxlRm9jdXNJbnNpZGUsIGlzT3V0c2lkZUV2ZW50LCBnZXRQcmV2aW91c1RhYmJhYmxlLCBnZXROZXh0VGFiYmFibGUsIGRpc2FibGVGb2N1c0luc2lkZSwgaXNUeXBlYWJsZUNvbWJvYm94LCBnZXRGbG9hdGluZ0ZvY3VzRWxlbWVudCwgZ2V0VGFiYmFibGVPcHRpb25zLCBnZXROb2RlQW5jZXN0b3JzLCBhY3RpdmVFbGVtZW50LCBnZXROb2RlQ2hpbGRyZW4gYXMgZ2V0Tm9kZUNoaWxkcmVuJDEsIHN0b3BFdmVudCwgZ2V0VGFyZ2V0IGFzIGdldFRhcmdldCQxLCBpc1ZpcnR1YWxDbGljaywgaXNWaXJ0dWFsUG9pbnRlckV2ZW50LCBnZXRQbGF0Zm9ybSwgaXNUeXBlYWJsZUVsZW1lbnQsIGlzUmVhY3RFdmVudCwgaXNSb290RWxlbWVudCwgaXNFdmVudFRhcmdldFdpdGhpbiwgbWF0Y2hlc0ZvY3VzVmlzaWJsZSwgaXNNYWMsIGdldERlZXBlc3ROb2RlLCBnZXRVc2VyQWdlbnQgfSBmcm9tICdAZmxvYXRpbmctdWkvcmVhY3QvdXRpbHMnO1xuaW1wb3J0IHsganN4LCBqc3hzLCBGcmFnbWVudCB9IGZyb20gJ3JlYWN0L2pzeC1ydW50aW1lJztcbmltcG9ydCB7IGdldENvbXB1dGVkU3R5bGUsIGlzRWxlbWVudCwgaXNTaGFkb3dSb290LCBnZXROb2RlTmFtZSwgaXNIVE1MRWxlbWVudCwgZ2V0V2luZG93LCBpc0xhc3RUcmF2ZXJzYWJsZU5vZGUsIGdldFBhcmVudE5vZGUsIGlzV2ViS2l0IH0gZnJvbSAnQGZsb2F0aW5nLXVpL3V0aWxzL2RvbSc7XG5pbXBvcnQgeyB0YWJiYWJsZSwgaXNUYWJiYWJsZSwgZm9jdXNhYmxlIH0gZnJvbSAndGFiYmFibGUnO1xuaW1wb3J0ICogYXMgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcbmltcG9ydCB7IGdldE92ZXJmbG93QW5jZXN0b3JzLCB1c2VGbG9hdGluZyBhcyB1c2VGbG9hdGluZyQxLCBvZmZzZXQsIGRldGVjdE92ZXJmbG93IH0gZnJvbSAnQGZsb2F0aW5nLXVpL3JlYWN0LWRvbSc7XG5leHBvcnQgeyBhcnJvdywgYXV0b1BsYWNlbWVudCwgYXV0b1VwZGF0ZSwgY29tcHV0ZVBvc2l0aW9uLCBkZXRlY3RPdmVyZmxvdywgZmxpcCwgZ2V0T3ZlcmZsb3dBbmNlc3RvcnMsIGhpZGUsIGlubGluZSwgbGltaXRTaGlmdCwgb2Zmc2V0LCBwbGF0Zm9ybSwgc2hpZnQsIHNpemUgfSBmcm9tICdAZmxvYXRpbmctdWkvcmVhY3QtZG9tJztcbmltcG9ydCB7IGV2YWx1YXRlLCBtYXgsIHJvdW5kLCBtaW4gfSBmcm9tICdAZmxvYXRpbmctdWkvdXRpbHMnO1xuXG4vKipcbiAqIE1lcmdlcyBhbiBhcnJheSBvZiByZWZzIGludG8gYSBzaW5nbGUgbWVtb2l6ZWQgY2FsbGJhY2sgcmVmIG9yIGBudWxsYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9yZWFjdC11dGlscyN1c2VtZXJnZXJlZnNcbiAqL1xuZnVuY3Rpb24gdXNlTWVyZ2VSZWZzKHJlZnMpIHtcbiAgY29uc3QgY2xlYW51cFJlZiA9IFJlYWN0LnVzZVJlZih1bmRlZmluZWQpO1xuICBjb25zdCByZWZFZmZlY3QgPSBSZWFjdC51c2VDYWxsYmFjayhpbnN0YW5jZSA9PiB7XG4gICAgY29uc3QgY2xlYW51cHMgPSByZWZzLm1hcChyZWYgPT4ge1xuICAgICAgaWYgKHJlZiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IHJlZkNhbGxiYWNrID0gcmVmO1xuICAgICAgICBjb25zdCByZWZDbGVhbnVwID0gcmVmQ2FsbGJhY2soaW5zdGFuY2UpO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHJlZkNsZWFudXAgPT09ICdmdW5jdGlvbicgPyByZWZDbGVhbnVwIDogKCkgPT4ge1xuICAgICAgICAgIHJlZkNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmVmLmN1cnJlbnQgPSBpbnN0YW5jZTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH07XG4gICAgfSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNsZWFudXBzLmZvckVhY2gocmVmQ2xlYW51cCA9PiByZWZDbGVhbnVwID09IG51bGwgPyB2b2lkIDAgOiByZWZDbGVhbnVwKCkpO1xuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCByZWZzKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChyZWZzLmV2ZXJ5KHJlZiA9PiByZWYgPT0gbnVsbCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUgPT4ge1xuICAgICAgaWYgKGNsZWFudXBSZWYuY3VycmVudCkge1xuICAgICAgICBjbGVhbnVwUmVmLmN1cnJlbnQoKTtcbiAgICAgICAgY2xlYW51cFJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgY2xlYW51cFJlZi5jdXJyZW50ID0gcmVmRWZmZWN0KHZhbHVlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgcmVmcyk7XG59XG5cbmZ1bmN0aW9uIHNvcnRCeURvY3VtZW50UG9zaXRpb24oYSwgYikge1xuICBjb25zdCBwb3NpdGlvbiA9IGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYik7XG4gIGlmIChwb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HIHx8IHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9DT05UQUlORURfQlkpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcgfHwgcG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5TKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5jb25zdCBGbG9hdGluZ0xpc3RDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQoe1xuICByZWdpc3RlcjogKCkgPT4ge30sXG4gIHVucmVnaXN0ZXI6ICgpID0+IHt9LFxuICBtYXA6IC8qI19fUFVSRV9fKi9uZXcgTWFwKCksXG4gIGVsZW1lbnRzUmVmOiB7XG4gICAgY3VycmVudDogW11cbiAgfVxufSk7XG4vKipcbiAqIFByb3ZpZGVzIGNvbnRleHQgZm9yIGEgbGlzdCBvZiBpdGVtcyB3aXRoaW4gdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdMaXN0XG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nTGlzdChwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgZWxlbWVudHNSZWYsXG4gICAgbGFiZWxzUmVmXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgW25vZGVzLCBzZXROb2Rlc10gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBuZXcgU2V0KCkpO1xuICBjb25zdCByZWdpc3RlciA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIHNldE5vZGVzKHByZXZTZXQgPT4gbmV3IFNldChwcmV2U2V0KS5hZGQobm9kZSkpO1xuICB9LCBbXSk7XG4gIGNvbnN0IHVucmVnaXN0ZXIgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBzZXROb2RlcyhwcmV2U2V0ID0+IHtcbiAgICAgIGNvbnN0IHNldCA9IG5ldyBTZXQocHJldlNldCk7XG4gICAgICBzZXQuZGVsZXRlKG5vZGUpO1xuICAgICAgcmV0dXJuIHNldDtcbiAgICB9KTtcbiAgfSwgW10pO1xuICBjb25zdCBtYXAgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBuZXdNYXAgPSBuZXcgTWFwKCk7XG4gICAgY29uc3Qgc29ydGVkTm9kZXMgPSBBcnJheS5mcm9tKG5vZGVzLmtleXMoKSkuc29ydChzb3J0QnlEb2N1bWVudFBvc2l0aW9uKTtcbiAgICBzb3J0ZWROb2Rlcy5mb3JFYWNoKChub2RlLCBpbmRleCkgPT4ge1xuICAgICAgbmV3TWFwLnNldChub2RlLCBpbmRleCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld01hcDtcbiAgfSwgW25vZGVzXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KEZsb2F0aW5nTGlzdENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgcmVnaXN0ZXIsXG4gICAgICB1bnJlZ2lzdGVyLFxuICAgICAgbWFwLFxuICAgICAgZWxlbWVudHNSZWYsXG4gICAgICBsYWJlbHNSZWZcbiAgICB9KSwgW3JlZ2lzdGVyLCB1bnJlZ2lzdGVyLCBtYXAsIGVsZW1lbnRzUmVmLCBsYWJlbHNSZWZdKSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5cbiAgfSk7XG59XG4vKipcbiAqIFVzZWQgdG8gcmVnaXN0ZXIgYSBsaXN0IGl0ZW0gYW5kIGl0cyBpbmRleCAoRE9NIHBvc2l0aW9uKSBpbiB0aGVcbiAqIGBGbG9hdGluZ0xpc3RgLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nTGlzdCN1c2VsaXN0aXRlbVxuICovXG5mdW5jdGlvbiB1c2VMaXN0SXRlbShwcm9wcykge1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIGxhYmVsXG4gIH0gPSBwcm9wcztcbiAgY29uc3Qge1xuICAgIHJlZ2lzdGVyLFxuICAgIHVucmVnaXN0ZXIsXG4gICAgbWFwLFxuICAgIGVsZW1lbnRzUmVmLFxuICAgIGxhYmVsc1JlZlxuICB9ID0gUmVhY3QudXNlQ29udGV4dChGbG9hdGluZ0xpc3RDb250ZXh0KTtcbiAgY29uc3QgW2luZGV4LCBzZXRJbmRleF0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3QgY29tcG9uZW50UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCByZWYgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBjb21wb25lbnRSZWYuY3VycmVudCA9IG5vZGU7XG4gICAgaWYgKGluZGV4ICE9PSBudWxsKSB7XG4gICAgICBlbGVtZW50c1JlZi5jdXJyZW50W2luZGV4XSA9IG5vZGU7XG4gICAgICBpZiAobGFiZWxzUmVmKSB7XG4gICAgICAgIHZhciBfbm9kZSR0ZXh0Q29udGVudDtcbiAgICAgICAgY29uc3QgaXNMYWJlbERlZmluZWQgPSBsYWJlbCAhPT0gdW5kZWZpbmVkO1xuICAgICAgICBsYWJlbHNSZWYuY3VycmVudFtpbmRleF0gPSBpc0xhYmVsRGVmaW5lZCA/IGxhYmVsIDogKF9ub2RlJHRleHRDb250ZW50ID0gbm9kZSA9PSBudWxsID8gdm9pZCAwIDogbm9kZS50ZXh0Q29udGVudCkgIT0gbnVsbCA/IF9ub2RlJHRleHRDb250ZW50IDogbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtpbmRleCwgZWxlbWVudHNSZWYsIGxhYmVsc1JlZiwgbGFiZWxdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBub2RlID0gY29tcG9uZW50UmVmLmN1cnJlbnQ7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHJlZ2lzdGVyKG5vZGUpO1xuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgdW5yZWdpc3Rlcihub2RlKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbcmVnaXN0ZXIsIHVucmVnaXN0ZXJdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBpbmRleCA9IGNvbXBvbmVudFJlZi5jdXJyZW50ID8gbWFwLmdldChjb21wb25lbnRSZWYuY3VycmVudCkgOiBudWxsO1xuICAgIGlmIChpbmRleCAhPSBudWxsKSB7XG4gICAgICBzZXRJbmRleChpbmRleCk7XG4gICAgfVxuICB9LCBbbWFwXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgcmVmLFxuICAgIGluZGV4OiBpbmRleCA9PSBudWxsID8gLTEgOiBpbmRleFxuICB9KSwgW2luZGV4LCByZWZdKTtcbn1cblxuY29uc3QgRk9DVVNBQkxFX0FUVFJJQlVURSA9ICdkYXRhLWZsb2F0aW5nLXVpLWZvY3VzYWJsZSc7XG5jb25zdCBBQ1RJVkVfS0VZID0gJ2FjdGl2ZSc7XG5jb25zdCBTRUxFQ1RFRF9LRVkgPSAnc2VsZWN0ZWQnO1xuY29uc3QgQVJST1dfTEVGVCA9ICdBcnJvd0xlZnQnO1xuY29uc3QgQVJST1dfUklHSFQgPSAnQXJyb3dSaWdodCc7XG5jb25zdCBBUlJPV19VUCA9ICdBcnJvd1VwJztcbmNvbnN0IEFSUk9XX0RPV04gPSAnQXJyb3dEb3duJztcblxuZnVuY3Rpb24gcmVuZGVySnN4KHJlbmRlciwgY29tcHV0ZWRQcm9wcykge1xuICBpZiAodHlwZW9mIHJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiByZW5kZXIoY29tcHV0ZWRQcm9wcyk7XG4gIH1cbiAgaWYgKHJlbmRlcikge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KHJlbmRlciwgY29tcHV0ZWRQcm9wcyk7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goXCJkaXZcIiwge1xuICAgIC4uLmNvbXB1dGVkUHJvcHNcbiAgfSk7XG59XG5jb25zdCBDb21wb3NpdGVDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQoe1xuICBhY3RpdmVJbmRleDogMCxcbiAgb25OYXZpZ2F0ZTogKCkgPT4ge31cbn0pO1xuY29uc3QgaG9yaXpvbnRhbEtleXMgPSBbQVJST1dfTEVGVCwgQVJST1dfUklHSFRdO1xuY29uc3QgdmVydGljYWxLZXlzID0gW0FSUk9XX1VQLCBBUlJPV19ET1dOXTtcbmNvbnN0IGFsbEtleXMgPSBbLi4uaG9yaXpvbnRhbEtleXMsIC4uLnZlcnRpY2FsS2V5c107XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNpbmdsZSB0YWIgc3RvcCB3aG9zZSBpdGVtcyBhcmUgbmF2aWdhdGVkIGJ5IGFycm93IGtleXMsIHdoaWNoXG4gKiBwcm92aWRlcyBsaXN0IG5hdmlnYXRpb24gb3V0c2lkZSBvZiBmbG9hdGluZyBlbGVtZW50IGNvbnRleHRzLlxuICpcbiAqIFRoaXMgaXMgdXNlZnVsIHRvIGVuYWJsZSBuYXZpZ2F0aW9uIG9mIGEgbGlzdCBvZiBpdGVtcyB0aGF0IGFyZW7igJl0IHBhcnQgb2YgYVxuICogZmxvYXRpbmcgZWxlbWVudC4gQSBtZW51YmFyIGlzIGFuIGV4YW1wbGUgb2YgYSBjb21wb3NpdGUsIHdpdGggZWFjaCByZWZlcmVuY2VcbiAqIGVsZW1lbnQgYmVpbmcgYW4gaXRlbS5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9Db21wb3NpdGVcbiAqL1xuY29uc3QgQ29tcG9zaXRlID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gQ29tcG9zaXRlKHByb3BzLCBmb3J3YXJkZWRSZWYpIHtcbiAgY29uc3Qge1xuICAgIHJlbmRlcixcbiAgICBvcmllbnRhdGlvbiA9ICdib3RoJyxcbiAgICBsb29wID0gdHJ1ZSxcbiAgICBydGwgPSBmYWxzZSxcbiAgICBjb2xzID0gMSxcbiAgICBkaXNhYmxlZEluZGljZXMsXG4gICAgYWN0aXZlSW5kZXg6IGV4dGVybmFsQWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZTogZXh0ZXJuYWxTZXRBY3RpdmVJbmRleCxcbiAgICBpdGVtU2l6ZXMsXG4gICAgZGVuc2UgPSBmYWxzZSxcbiAgICAuLi5kb21Qcm9wc1xuICB9ID0gcHJvcHM7XG4gIGNvbnN0IFtpbnRlcm5hbEFjdGl2ZUluZGV4LCBpbnRlcm5hbFNldEFjdGl2ZUluZGV4XSA9IFJlYWN0LnVzZVN0YXRlKDApO1xuICBjb25zdCBhY3RpdmVJbmRleCA9IGV4dGVybmFsQWN0aXZlSW5kZXggIT0gbnVsbCA/IGV4dGVybmFsQWN0aXZlSW5kZXggOiBpbnRlcm5hbEFjdGl2ZUluZGV4O1xuICBjb25zdCBvbk5hdmlnYXRlID0gdXNlRWZmZWN0RXZlbnQoZXh0ZXJuYWxTZXRBY3RpdmVJbmRleCAhPSBudWxsID8gZXh0ZXJuYWxTZXRBY3RpdmVJbmRleCA6IGludGVybmFsU2V0QWN0aXZlSW5kZXgpO1xuICBjb25zdCBlbGVtZW50c1JlZiA9IFJlYWN0LnVzZVJlZihbXSk7XG4gIGNvbnN0IHJlbmRlckVsZW1lbnRQcm9wcyA9IHJlbmRlciAmJiB0eXBlb2YgcmVuZGVyICE9PSAnZnVuY3Rpb24nID8gcmVuZGVyLnByb3BzIDoge307XG4gIGNvbnN0IGNvbnRleHRWYWx1ZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBhY3RpdmVJbmRleCxcbiAgICBvbk5hdmlnYXRlXG4gIH0pLCBbYWN0aXZlSW5kZXgsIG9uTmF2aWdhdGVdKTtcbiAgY29uc3QgaXNHcmlkID0gY29scyA+IDE7XG4gIGZ1bmN0aW9uIGhhbmRsZUtleURvd24oZXZlbnQpIHtcbiAgICBpZiAoIWFsbEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkgcmV0dXJuO1xuICAgIGxldCBuZXh0SW5kZXggPSBhY3RpdmVJbmRleDtcbiAgICBjb25zdCBtaW5JbmRleCA9IGdldE1pbkxpc3RJbmRleChlbGVtZW50c1JlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBtYXhJbmRleCA9IGdldE1heExpc3RJbmRleChlbGVtZW50c1JlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBob3Jpem9udGFsRW5kS2V5ID0gcnRsID8gQVJST1dfTEVGVCA6IEFSUk9XX1JJR0hUO1xuICAgIGNvbnN0IGhvcml6b250YWxTdGFydEtleSA9IHJ0bCA/IEFSUk9XX1JJR0hUIDogQVJST1dfTEVGVDtcbiAgICBpZiAoaXNHcmlkKSB7XG4gICAgICBjb25zdCBzaXplcyA9IGl0ZW1TaXplcyB8fCBBcnJheS5mcm9tKHtcbiAgICAgICAgbGVuZ3RoOiBlbGVtZW50c1JlZi5jdXJyZW50Lmxlbmd0aFxuICAgICAgfSwgKCkgPT4gKHtcbiAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgIGhlaWdodDogMVxuICAgICAgfSkpO1xuICAgICAgLy8gVG8gY2FsY3VsYXRlIG1vdmVtZW50cyBvbiB0aGUgZ3JpZCwgd2UgdXNlIGh5cG90aGV0aWNhbCBjZWxsIGluZGljZXNcbiAgICAgIC8vIGFzIGlmIGV2ZXJ5IGl0ZW0gd2FzIDF4MSwgdGhlbiBjb252ZXJ0IGJhY2sgdG8gcmVhbCBpbmRpY2VzLlxuICAgICAgY29uc3QgY2VsbE1hcCA9IGNyZWF0ZUdyaWRDZWxsTWFwKHNpemVzLCBjb2xzLCBkZW5zZSk7XG4gICAgICBjb25zdCBtaW5HcmlkSW5kZXggPSBjZWxsTWFwLmZpbmRJbmRleChpbmRleCA9PiBpbmRleCAhPSBudWxsICYmICFpc0xpc3RJbmRleERpc2FibGVkKGVsZW1lbnRzUmVmLCBpbmRleCwgZGlzYWJsZWRJbmRpY2VzKSk7XG4gICAgICAvLyBsYXN0IGVuYWJsZWQgaW5kZXhcbiAgICAgIGNvbnN0IG1heEdyaWRJbmRleCA9IGNlbGxNYXAucmVkdWNlKChmb3VuZEluZGV4LCBpbmRleCwgY2VsbEluZGV4KSA9PiBpbmRleCAhPSBudWxsICYmICFpc0xpc3RJbmRleERpc2FibGVkKGVsZW1lbnRzUmVmLCBpbmRleCwgZGlzYWJsZWRJbmRpY2VzKSA/IGNlbGxJbmRleCA6IGZvdW5kSW5kZXgsIC0xKTtcbiAgICAgIGNvbnN0IG1heWJlTmV4dEluZGV4ID0gY2VsbE1hcFtnZXRHcmlkTmF2aWdhdGVkSW5kZXgoe1xuICAgICAgICBjdXJyZW50OiBjZWxsTWFwLm1hcChpdGVtSW5kZXggPT4gaXRlbUluZGV4ID8gZWxlbWVudHNSZWYuY3VycmVudFtpdGVtSW5kZXhdIDogbnVsbClcbiAgICAgIH0sIHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIG9yaWVudGF0aW9uLFxuICAgICAgICBsb29wLFxuICAgICAgICBydGwsXG4gICAgICAgIGNvbHMsXG4gICAgICAgIC8vIHRyZWF0IHVuZGVmaW5lZCAoZW1wdHkgZ3JpZCBzcGFjZXMpIGFzIGRpc2FibGVkIGluZGljZXMgc28gd2VcbiAgICAgICAgLy8gZG9uJ3QgZW5kIHVwIGluIHRoZW1cbiAgICAgICAgZGlzYWJsZWRJbmRpY2VzOiBnZXRHcmlkQ2VsbEluZGljZXMoWy4uLihkaXNhYmxlZEluZGljZXMgfHwgZWxlbWVudHNSZWYuY3VycmVudC5tYXAoKF8sIGluZGV4KSA9PiBpc0xpc3RJbmRleERpc2FibGVkKGVsZW1lbnRzUmVmLCBpbmRleCkgPyBpbmRleCA6IHVuZGVmaW5lZCkpLCB1bmRlZmluZWRdLCBjZWxsTWFwKSxcbiAgICAgICAgbWluSW5kZXg6IG1pbkdyaWRJbmRleCxcbiAgICAgICAgbWF4SW5kZXg6IG1heEdyaWRJbmRleCxcbiAgICAgICAgcHJldkluZGV4OiBnZXRHcmlkQ2VsbEluZGV4T2ZDb3JuZXIoYWN0aXZlSW5kZXggPiBtYXhJbmRleCA/IG1pbkluZGV4IDogYWN0aXZlSW5kZXgsIHNpemVzLCBjZWxsTWFwLCBjb2xzLFxuICAgICAgICAvLyB1c2UgYSBjb3JuZXIgbWF0Y2hpbmcgdGhlIGVkZ2UgY2xvc2VzdCB0byB0aGUgZGlyZWN0aW9uIHdlJ3JlXG4gICAgICAgIC8vIG1vdmluZyBpbiBzbyB3ZSBkb24ndCBlbmQgdXAgaW4gdGhlIHNhbWUgaXRlbS4gUHJlZmVyXG4gICAgICAgIC8vIHRvcC9sZWZ0IG92ZXIgYm90dG9tL3JpZ2h0LlxuICAgICAgICBldmVudC5rZXkgPT09IEFSUk9XX0RPV04gPyAnYmwnIDogZXZlbnQua2V5ID09PSBob3Jpem9udGFsRW5kS2V5ID8gJ3RyJyA6ICd0bCcpXG4gICAgICB9KV07XG4gICAgICBpZiAobWF5YmVOZXh0SW5kZXggIT0gbnVsbCkge1xuICAgICAgICBuZXh0SW5kZXggPSBtYXliZU5leHRJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdG9FbmRLZXlzID0ge1xuICAgICAgaG9yaXpvbnRhbDogW2hvcml6b250YWxFbmRLZXldLFxuICAgICAgdmVydGljYWw6IFtBUlJPV19ET1dOXSxcbiAgICAgIGJvdGg6IFtob3Jpem9udGFsRW5kS2V5LCBBUlJPV19ET1dOXVxuICAgIH1bb3JpZW50YXRpb25dO1xuICAgIGNvbnN0IHRvU3RhcnRLZXlzID0ge1xuICAgICAgaG9yaXpvbnRhbDogW2hvcml6b250YWxTdGFydEtleV0sXG4gICAgICB2ZXJ0aWNhbDogW0FSUk9XX1VQXSxcbiAgICAgIGJvdGg6IFtob3Jpem9udGFsU3RhcnRLZXksIEFSUk9XX1VQXVxuICAgIH1bb3JpZW50YXRpb25dO1xuICAgIGNvbnN0IHByZXZlbnRlZEtleXMgPSBpc0dyaWQgPyBhbGxLZXlzIDoge1xuICAgICAgaG9yaXpvbnRhbDogaG9yaXpvbnRhbEtleXMsXG4gICAgICB2ZXJ0aWNhbDogdmVydGljYWxLZXlzLFxuICAgICAgYm90aDogYWxsS2V5c1xuICAgIH1bb3JpZW50YXRpb25dO1xuICAgIGlmIChuZXh0SW5kZXggPT09IGFjdGl2ZUluZGV4ICYmIFsuLi50b0VuZEtleXMsIC4uLnRvU3RhcnRLZXlzXS5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICBpZiAobG9vcCAmJiBuZXh0SW5kZXggPT09IG1heEluZGV4ICYmIHRvRW5kS2V5cy5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICAgIG5leHRJbmRleCA9IG1pbkluZGV4O1xuICAgICAgfSBlbHNlIGlmIChsb29wICYmIG5leHRJbmRleCA9PT0gbWluSW5kZXggJiYgdG9TdGFydEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgICBuZXh0SW5kZXggPSBtYXhJbmRleDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRJbmRleCA9IGZpbmROb25EaXNhYmxlZExpc3RJbmRleChlbGVtZW50c1JlZiwge1xuICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IG5leHRJbmRleCxcbiAgICAgICAgICBkZWNyZW1lbnQ6IHRvU3RhcnRLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSksXG4gICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobmV4dEluZGV4ICE9PSBhY3RpdmVJbmRleCAmJiAhaXNJbmRleE91dE9mTGlzdEJvdW5kcyhlbGVtZW50c1JlZiwgbmV4dEluZGV4KSkge1xuICAgICAgdmFyIF9lbGVtZW50c1JlZiRjdXJyZW50JDtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgaWYgKHByZXZlbnRlZEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgICAgb25OYXZpZ2F0ZShuZXh0SW5kZXgpO1xuICAgICAgKF9lbGVtZW50c1JlZiRjdXJyZW50JCA9IGVsZW1lbnRzUmVmLmN1cnJlbnRbbmV4dEluZGV4XSkgPT0gbnVsbCB8fCBfZWxlbWVudHNSZWYkY3VycmVudCQuZm9jdXMoKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgY29tcHV0ZWRQcm9wcyA9IHtcbiAgICAuLi5kb21Qcm9wcyxcbiAgICAuLi5yZW5kZXJFbGVtZW50UHJvcHMsXG4gICAgcmVmOiBmb3J3YXJkZWRSZWYsXG4gICAgJ2FyaWEtb3JpZW50YXRpb24nOiBvcmllbnRhdGlvbiA9PT0gJ2JvdGgnID8gdW5kZWZpbmVkIDogb3JpZW50YXRpb24sXG4gICAgb25LZXlEb3duKGUpIHtcbiAgICAgIGRvbVByb3BzLm9uS2V5RG93biA9PSBudWxsIHx8IGRvbVByb3BzLm9uS2V5RG93bihlKTtcbiAgICAgIHJlbmRlckVsZW1lbnRQcm9wcy5vbktleURvd24gPT0gbnVsbCB8fCByZW5kZXJFbGVtZW50UHJvcHMub25LZXlEb3duKGUpO1xuICAgICAgaGFuZGxlS2V5RG93bihlKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KENvbXBvc2l0ZUNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogY29udGV4dFZhbHVlLFxuICAgIGNoaWxkcmVuOiAvKiNfX1BVUkVfXyovanN4KEZsb2F0aW5nTGlzdCwge1xuICAgICAgZWxlbWVudHNSZWY6IGVsZW1lbnRzUmVmLFxuICAgICAgY2hpbGRyZW46IHJlbmRlckpzeChyZW5kZXIsIGNvbXB1dGVkUHJvcHMpXG4gICAgfSlcbiAgfSk7XG59KTtcbi8qKlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0NvbXBvc2l0ZVxuICovXG5jb25zdCBDb21wb3NpdGVJdGVtID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gQ29tcG9zaXRlSXRlbShwcm9wcywgZm9yd2FyZGVkUmVmKSB7XG4gIGNvbnN0IHtcbiAgICByZW5kZXIsXG4gICAgLi4uZG9tUHJvcHNcbiAgfSA9IHByb3BzO1xuICBjb25zdCByZW5kZXJFbGVtZW50UHJvcHMgPSByZW5kZXIgJiYgdHlwZW9mIHJlbmRlciAhPT0gJ2Z1bmN0aW9uJyA/IHJlbmRlci5wcm9wcyA6IHt9O1xuICBjb25zdCB7XG4gICAgYWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZVxuICB9ID0gUmVhY3QudXNlQ29udGV4dChDb21wb3NpdGVDb250ZXh0KTtcbiAgY29uc3Qge1xuICAgIHJlZixcbiAgICBpbmRleFxuICB9ID0gdXNlTGlzdEl0ZW0oKTtcbiAgY29uc3QgbWVyZ2VkUmVmID0gdXNlTWVyZ2VSZWZzKFtyZWYsIGZvcndhcmRlZFJlZiwgcmVuZGVyRWxlbWVudFByb3BzLnJlZl0pO1xuICBjb25zdCBpc0FjdGl2ZSA9IGFjdGl2ZUluZGV4ID09PSBpbmRleDtcbiAgY29uc3QgY29tcHV0ZWRQcm9wcyA9IHtcbiAgICAuLi5kb21Qcm9wcyxcbiAgICAuLi5yZW5kZXJFbGVtZW50UHJvcHMsXG4gICAgcmVmOiBtZXJnZWRSZWYsXG4gICAgdGFiSW5kZXg6IGlzQWN0aXZlID8gMCA6IC0xLFxuICAgICdkYXRhLWFjdGl2ZSc6IGlzQWN0aXZlID8gJycgOiB1bmRlZmluZWQsXG4gICAgb25Gb2N1cyhlKSB7XG4gICAgICBkb21Qcm9wcy5vbkZvY3VzID09IG51bGwgfHwgZG9tUHJvcHMub25Gb2N1cyhlKTtcbiAgICAgIHJlbmRlckVsZW1lbnRQcm9wcy5vbkZvY3VzID09IG51bGwgfHwgcmVuZGVyRWxlbWVudFByb3BzLm9uRm9jdXMoZSk7XG4gICAgICBvbk5hdmlnYXRlKGluZGV4KTtcbiAgICB9XG4gIH07XG4gIHJldHVybiByZW5kZXJKc3gocmVuZGVyLCBjb21wdXRlZFByb3BzKTtcbn0pO1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vbXVpL21hdGVyaWFsLXVpL2lzc3Vlcy80MTE5MCNpc3N1ZWNvbW1lbnQtMjA0MDg3MzM3OVxuY29uc3QgU2FmZVJlYWN0ID0ge1xuICAuLi5SZWFjdFxufTtcblxubGV0IHNlcnZlckhhbmRvZmZDb21wbGV0ZSA9IGZhbHNlO1xubGV0IGNvdW50ID0gMDtcbmNvbnN0IGdlbklkID0gKCkgPT4gLy8gRW5zdXJlIHRoZSBpZCBpcyB1bmlxdWUgd2l0aCBtdWx0aXBsZSBpbmRlcGVuZGVudCB2ZXJzaW9ucyBvZiBGbG9hdGluZyBVSVxuLy8gb24gPFJlYWN0IDE4XG5cImZsb2F0aW5nLXVpLVwiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgNikgKyBjb3VudCsrO1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdJZCgpIHtcbiAgY29uc3QgW2lkLCBzZXRJZF0gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBzZXJ2ZXJIYW5kb2ZmQ29tcGxldGUgPyBnZW5JZCgpIDogdW5kZWZpbmVkKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaWQgPT0gbnVsbCkge1xuICAgICAgc2V0SWQoZ2VuSWQoKSk7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgW10pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHNlcnZlckhhbmRvZmZDb21wbGV0ZSA9IHRydWU7XG4gIH0sIFtdKTtcbiAgcmV0dXJuIGlkO1xufVxuY29uc3QgdXNlUmVhY3RJZCA9IFNhZmVSZWFjdC51c2VJZDtcblxuLyoqXG4gKiBVc2VzIFJlYWN0IDE4J3MgYnVpbHQtaW4gYHVzZUlkKClgIHdoZW4gYXZhaWxhYmxlLCBvciBmYWxscyBiYWNrIHRvIGFcbiAqIHNsaWdodGx5IGxlc3MgcGVyZm9ybWFudCAocmVxdWlyaW5nIGEgZG91YmxlIHJlbmRlcikgaW1wbGVtZW50YXRpb24gZm9yXG4gKiBlYXJsaWVyIFJlYWN0IHZlcnNpb25zLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3JlYWN0LXV0aWxzI3VzZWlkXG4gKi9cbmNvbnN0IHVzZUlkID0gdXNlUmVhY3RJZCB8fCB1c2VGbG9hdGluZ0lkO1xuXG5sZXQgZGV2TWVzc2FnZVNldDtcbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgZGV2TWVzc2FnZVNldCA9IC8qI19fUFVSRV9fKi9uZXcgU2V0KCk7XG59XG5mdW5jdGlvbiB3YXJuKCkge1xuICB2YXIgX2Rldk1lc3NhZ2VTZXQ7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBtZXNzYWdlcyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBtZXNzYWdlc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuICBjb25zdCBtZXNzYWdlID0gXCJGbG9hdGluZyBVSTogXCIgKyBtZXNzYWdlcy5qb2luKCcgJyk7XG4gIGlmICghKChfZGV2TWVzc2FnZVNldCA9IGRldk1lc3NhZ2VTZXQpICE9IG51bGwgJiYgX2Rldk1lc3NhZ2VTZXQuaGFzKG1lc3NhZ2UpKSkge1xuICAgIHZhciBfZGV2TWVzc2FnZVNldDI7XG4gICAgKF9kZXZNZXNzYWdlU2V0MiA9IGRldk1lc3NhZ2VTZXQpID09IG51bGwgfHwgX2Rldk1lc3NhZ2VTZXQyLmFkZChtZXNzYWdlKTtcbiAgICBjb25zb2xlLndhcm4obWVzc2FnZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVycm9yKCkge1xuICB2YXIgX2Rldk1lc3NhZ2VTZXQzO1xuICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIG1lc3NhZ2VzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgbWVzc2FnZXNbX2tleTJdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgfVxuICBjb25zdCBtZXNzYWdlID0gXCJGbG9hdGluZyBVSTogXCIgKyBtZXNzYWdlcy5qb2luKCcgJyk7XG4gIGlmICghKChfZGV2TWVzc2FnZVNldDMgPSBkZXZNZXNzYWdlU2V0KSAhPSBudWxsICYmIF9kZXZNZXNzYWdlU2V0My5oYXMobWVzc2FnZSkpKSB7XG4gICAgdmFyIF9kZXZNZXNzYWdlU2V0NDtcbiAgICAoX2Rldk1lc3NhZ2VTZXQ0ID0gZGV2TWVzc2FnZVNldCkgPT0gbnVsbCB8fCBfZGV2TWVzc2FnZVNldDQuYWRkKG1lc3NhZ2UpO1xuICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgcG9pbnRpbmcgYXJyb3cgdHJpYW5nbGUuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdBcnJvd1xuICovXG5jb25zdCBGbG9hdGluZ0Fycm93ID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRmxvYXRpbmdBcnJvdyhwcm9wcywgcmVmKSB7XG4gIGNvbnN0IHtcbiAgICBjb250ZXh0OiB7XG4gICAgICBwbGFjZW1lbnQsXG4gICAgICBlbGVtZW50czoge1xuICAgICAgICBmbG9hdGluZ1xuICAgICAgfSxcbiAgICAgIG1pZGRsZXdhcmVEYXRhOiB7XG4gICAgICAgIGFycm93LFxuICAgICAgICBzaGlmdFxuICAgICAgfVxuICAgIH0sXG4gICAgd2lkdGggPSAxNCxcbiAgICBoZWlnaHQgPSA3LFxuICAgIHRpcFJhZGl1cyA9IDAsXG4gICAgc3Ryb2tlV2lkdGggPSAwLFxuICAgIHN0YXRpY09mZnNldCxcbiAgICBzdHJva2UsXG4gICAgZCxcbiAgICBzdHlsZToge1xuICAgICAgdHJhbnNmb3JtLFxuICAgICAgLi4ucmVzdFN0eWxlXG4gICAgfSA9IHt9LFxuICAgIC4uLnJlc3RcbiAgfSA9IHByb3BzO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgaWYgKCFyZWYpIHtcbiAgICAgIHdhcm4oJ1RoZSBgcmVmYCBwcm9wIGlzIHJlcXVpcmVkIGZvciBgRmxvYXRpbmdBcnJvd2AuJyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IGNsaXBQYXRoSWQgPSB1c2VJZCgpO1xuICBjb25zdCBbaXNSVEwsIHNldElzUlRMXSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKTtcblxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmxvYXRpbmctdWkvZmxvYXRpbmctdWkvaXNzdWVzLzI5MzJcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWZsb2F0aW5nKSByZXR1cm47XG4gICAgY29uc3QgaXNSVEwgPSBnZXRDb21wdXRlZFN0eWxlKGZsb2F0aW5nKS5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgIGlmIChpc1JUTCkge1xuICAgICAgc2V0SXNSVEwodHJ1ZSk7XG4gICAgfVxuICB9LCBbZmxvYXRpbmddKTtcbiAgaWYgKCFmbG9hdGluZykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IFtzaWRlLCBhbGlnbm1lbnRdID0gcGxhY2VtZW50LnNwbGl0KCctJyk7XG4gIGNvbnN0IGlzVmVydGljYWxTaWRlID0gc2lkZSA9PT0gJ3RvcCcgfHwgc2lkZSA9PT0gJ2JvdHRvbSc7XG4gIGxldCBjb21wdXRlZFN0YXRpY09mZnNldCA9IHN0YXRpY09mZnNldDtcbiAgaWYgKGlzVmVydGljYWxTaWRlICYmIHNoaWZ0ICE9IG51bGwgJiYgc2hpZnQueCB8fCAhaXNWZXJ0aWNhbFNpZGUgJiYgc2hpZnQgIT0gbnVsbCAmJiBzaGlmdC55KSB7XG4gICAgY29tcHV0ZWRTdGF0aWNPZmZzZXQgPSBudWxsO1xuICB9XG5cbiAgLy8gU3Ryb2tlcyBtdXN0IGJlIGRvdWJsZSB0aGUgYm9yZGVyIHdpZHRoLCB0aGlzIGVuc3VyZXMgdGhlIHN0cm9rZSdzIHdpZHRoXG4gIC8vIHdvcmtzIGFzIHlvdSdkIGV4cGVjdC5cbiAgY29uc3QgY29tcHV0ZWRTdHJva2VXaWR0aCA9IHN0cm9rZVdpZHRoICogMjtcbiAgY29uc3QgaGFsZlN0cm9rZVdpZHRoID0gY29tcHV0ZWRTdHJva2VXaWR0aCAvIDI7XG4gIGNvbnN0IHN2Z1ggPSB3aWR0aCAvIDIgKiAodGlwUmFkaXVzIC8gLTggKyAxKTtcbiAgY29uc3Qgc3ZnWSA9IGhlaWdodCAvIDIgKiB0aXBSYWRpdXMgLyA0O1xuICBjb25zdCBpc0N1c3RvbVNoYXBlID0gISFkO1xuICBjb25zdCB5T2Zmc2V0UHJvcCA9IGNvbXB1dGVkU3RhdGljT2Zmc2V0ICYmIGFsaWdubWVudCA9PT0gJ2VuZCcgPyAnYm90dG9tJyA6ICd0b3AnO1xuICBsZXQgeE9mZnNldFByb3AgPSBjb21wdXRlZFN0YXRpY09mZnNldCAmJiBhbGlnbm1lbnQgPT09ICdlbmQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgaWYgKGNvbXB1dGVkU3RhdGljT2Zmc2V0ICYmIGlzUlRMKSB7XG4gICAgeE9mZnNldFByb3AgPSBhbGlnbm1lbnQgPT09ICdlbmQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgfVxuICBjb25zdCBhcnJvd1ggPSAoYXJyb3cgPT0gbnVsbCA/IHZvaWQgMCA6IGFycm93LngpICE9IG51bGwgPyBjb21wdXRlZFN0YXRpY09mZnNldCB8fCBhcnJvdy54IDogJyc7XG4gIGNvbnN0IGFycm93WSA9IChhcnJvdyA9PSBudWxsID8gdm9pZCAwIDogYXJyb3cueSkgIT0gbnVsbCA/IGNvbXB1dGVkU3RhdGljT2Zmc2V0IHx8IGFycm93LnkgOiAnJztcbiAgY29uc3QgZFZhbHVlID0gZCB8fCAnTTAsMCcgKyAoXCIgSFwiICsgd2lkdGgpICsgKFwiIExcIiArICh3aWR0aCAtIHN2Z1gpICsgXCIsXCIgKyAoaGVpZ2h0IC0gc3ZnWSkpICsgKFwiIFFcIiArIHdpZHRoIC8gMiArIFwiLFwiICsgaGVpZ2h0ICsgXCIgXCIgKyBzdmdYICsgXCIsXCIgKyAoaGVpZ2h0IC0gc3ZnWSkpICsgJyBaJztcbiAgY29uc3Qgcm90YXRpb24gPSB7XG4gICAgdG9wOiBpc0N1c3RvbVNoYXBlID8gJ3JvdGF0ZSgxODBkZWcpJyA6ICcnLFxuICAgIGxlZnQ6IGlzQ3VzdG9tU2hhcGUgPyAncm90YXRlKDkwZGVnKScgOiAncm90YXRlKC05MGRlZyknLFxuICAgIGJvdHRvbTogaXNDdXN0b21TaGFwZSA/ICcnIDogJ3JvdGF0ZSgxODBkZWcpJyxcbiAgICByaWdodDogaXNDdXN0b21TaGFwZSA/ICdyb3RhdGUoLTkwZGVnKScgOiAncm90YXRlKDkwZGVnKSdcbiAgfVtzaWRlXTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3hzKFwic3ZnXCIsIHtcbiAgICAuLi5yZXN0LFxuICAgIFwiYXJpYS1oaWRkZW5cIjogdHJ1ZSxcbiAgICByZWY6IHJlZixcbiAgICB3aWR0aDogaXNDdXN0b21TaGFwZSA/IHdpZHRoIDogd2lkdGggKyBjb21wdXRlZFN0cm9rZVdpZHRoLFxuICAgIGhlaWdodDogd2lkdGgsXG4gICAgdmlld0JveDogXCIwIDAgXCIgKyB3aWR0aCArIFwiIFwiICsgKGhlaWdodCA+IHdpZHRoID8gaGVpZ2h0IDogd2lkdGgpLFxuICAgIHN0eWxlOiB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgIFt4T2Zmc2V0UHJvcF06IGFycm93WCxcbiAgICAgIFt5T2Zmc2V0UHJvcF06IGFycm93WSxcbiAgICAgIFtzaWRlXTogaXNWZXJ0aWNhbFNpZGUgfHwgaXNDdXN0b21TaGFwZSA/ICcxMDAlJyA6IFwiY2FsYygxMDAlIC0gXCIgKyBjb21wdXRlZFN0cm9rZVdpZHRoIC8gMiArIFwicHgpXCIsXG4gICAgICB0cmFuc2Zvcm06IFtyb3RhdGlvbiwgdHJhbnNmb3JtXS5maWx0ZXIodCA9PiAhIXQpLmpvaW4oJyAnKSxcbiAgICAgIC4uLnJlc3RTdHlsZVxuICAgIH0sXG4gICAgY2hpbGRyZW46IFtjb21wdXRlZFN0cm9rZVdpZHRoID4gMCAmJiAvKiNfX1BVUkVfXyovanN4KFwicGF0aFwiLCB7XG4gICAgICBjbGlwUGF0aDogXCJ1cmwoI1wiICsgY2xpcFBhdGhJZCArIFwiKVwiLFxuICAgICAgZmlsbDogXCJub25lXCIsXG4gICAgICBzdHJva2U6IHN0cm9rZVxuICAgICAgLy8gQWNjb3VudCBmb3IgdGhlIHN0cm9rZSBvbiB0aGUgZmlsbCBwYXRoIHJlbmRlcmVkIGJlbG93LlxuICAgICAgLFxuICAgICAgc3Ryb2tlV2lkdGg6IGNvbXB1dGVkU3Ryb2tlV2lkdGggKyAoZCA/IDAgOiAxKSxcbiAgICAgIGQ6IGRWYWx1ZVxuICAgIH0pLCAvKiNfX1BVUkVfXyovanN4KFwicGF0aFwiLCB7XG4gICAgICBzdHJva2U6IGNvbXB1dGVkU3Ryb2tlV2lkdGggJiYgIWQgPyByZXN0LmZpbGwgOiAnbm9uZScsXG4gICAgICBkOiBkVmFsdWVcbiAgICB9KSwgLyojX19QVVJFX18qL2pzeChcImNsaXBQYXRoXCIsIHtcbiAgICAgIGlkOiBjbGlwUGF0aElkLFxuICAgICAgY2hpbGRyZW46IC8qI19fUFVSRV9fKi9qc3goXCJyZWN0XCIsIHtcbiAgICAgICAgeDogLWhhbGZTdHJva2VXaWR0aCxcbiAgICAgICAgeTogaGFsZlN0cm9rZVdpZHRoICogKGlzQ3VzdG9tU2hhcGUgPyAtMSA6IDEpLFxuICAgICAgICB3aWR0aDogd2lkdGggKyBjb21wdXRlZFN0cm9rZVdpZHRoLFxuICAgICAgICBoZWlnaHQ6IHdpZHRoXG4gICAgICB9KVxuICAgIH0pXVxuICB9KTtcbn0pO1xuXG5mdW5jdGlvbiBjcmVhdGVFdmVudEVtaXR0ZXIoKSB7XG4gIGNvbnN0IG1hcCA9IG5ldyBNYXAoKTtcbiAgcmV0dXJuIHtcbiAgICBlbWl0KGV2ZW50LCBkYXRhKSB7XG4gICAgICB2YXIgX21hcCRnZXQ7XG4gICAgICAoX21hcCRnZXQgPSBtYXAuZ2V0KGV2ZW50KSkgPT0gbnVsbCB8fCBfbWFwJGdldC5mb3JFYWNoKGxpc3RlbmVyID0+IGxpc3RlbmVyKGRhdGEpKTtcbiAgICB9LFxuICAgIG9uKGV2ZW50LCBsaXN0ZW5lcikge1xuICAgICAgaWYgKCFtYXAuaGFzKGV2ZW50KSkge1xuICAgICAgICBtYXAuc2V0KGV2ZW50LCBuZXcgU2V0KCkpO1xuICAgICAgfVxuICAgICAgbWFwLmdldChldmVudCkuYWRkKGxpc3RlbmVyKTtcbiAgICB9LFxuICAgIG9mZihldmVudCwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBfbWFwJGdldDI7XG4gICAgICAoX21hcCRnZXQyID0gbWFwLmdldChldmVudCkpID09IG51bGwgfHwgX21hcCRnZXQyLmRlbGV0ZShsaXN0ZW5lcik7XG4gICAgfVxuICB9O1xufVxuXG5jb25zdCBGbG9hdGluZ05vZGVDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5jb25zdCBGbG9hdGluZ1RyZWVDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGFyZW50IG5vZGUgaWQgZm9yIG5lc3RlZCBmbG9hdGluZyBlbGVtZW50cywgaWYgYXZhaWxhYmxlLlxuICogUmV0dXJucyBgbnVsbGAgZm9yIHRvcC1sZXZlbCBmbG9hdGluZyBlbGVtZW50cy5cbiAqL1xuY29uc3QgdXNlRmxvYXRpbmdQYXJlbnROb2RlSWQgPSAoKSA9PiB7XG4gIHZhciBfUmVhY3QkdXNlQ29udGV4dDtcbiAgcmV0dXJuICgoX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KEZsb2F0aW5nTm9kZUNvbnRleHQpKSA9PSBudWxsID8gdm9pZCAwIDogX1JlYWN0JHVzZUNvbnRleHQuaWQpIHx8IG51bGw7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG5lYXJlc3QgZmxvYXRpbmcgdHJlZSBjb250ZXh0LCBpZiBhdmFpbGFibGUuXG4gKi9cbmNvbnN0IHVzZUZsb2F0aW5nVHJlZSA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdUcmVlQ29udGV4dCk7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgbm9kZSBpbnRvIHRoZSBgRmxvYXRpbmdUcmVlYCwgcmV0dXJuaW5nIGl0cyBpZC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ1RyZWVcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdOb2RlSWQoY3VzdG9tUGFyZW50SWQpIHtcbiAgY29uc3QgaWQgPSB1c2VJZCgpO1xuICBjb25zdCB0cmVlID0gdXNlRmxvYXRpbmdUcmVlKCk7XG4gIGNvbnN0IHJlYWN0UGFyZW50SWQgPSB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCgpO1xuICBjb25zdCBwYXJlbnRJZCA9IGN1c3RvbVBhcmVudElkIHx8IHJlYWN0UGFyZW50SWQ7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFpZCkgcmV0dXJuO1xuICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICBpZCxcbiAgICAgIHBhcmVudElkXG4gICAgfTtcbiAgICB0cmVlID09IG51bGwgfHwgdHJlZS5hZGROb2RlKG5vZGUpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0cmVlID09IG51bGwgfHwgdHJlZS5yZW1vdmVOb2RlKG5vZGUpO1xuICAgIH07XG4gIH0sIFt0cmVlLCBpZCwgcGFyZW50SWRdKTtcbiAgcmV0dXJuIGlkO1xufVxuLyoqXG4gKiBQcm92aWRlcyBwYXJlbnQgbm9kZSBjb250ZXh0IGZvciBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdUcmVlXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nTm9kZShwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgaWRcbiAgfSA9IHByb3BzO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KEZsb2F0aW5nTm9kZUNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgaWQsXG4gICAgICBwYXJlbnRJZFxuICAgIH0pLCBbaWQsIHBhcmVudElkXSksXG4gICAgY2hpbGRyZW46IGNoaWxkcmVuXG4gIH0pO1xufVxuLyoqXG4gKiBQcm92aWRlcyBjb250ZXh0IGZvciBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMgd2hlbiB0aGV5IGFyZSBub3QgY2hpbGRyZW4gb2ZcbiAqIGVhY2ggb3RoZXIgb24gdGhlIERPTS5cbiAqIFRoaXMgaXMgbm90IG5lY2Vzc2FyeSBpbiBhbGwgY2FzZXMsIGV4Y2VwdCB3aGVuIHRoZXJlIG11c3QgYmUgZXhwbGljaXQgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIHBhcmVudCBhbmQgY2hpbGQgZmxvYXRpbmcgZWxlbWVudHMuIEl0IGlzIG5lY2Vzc2FyeSBmb3I6XG4gKiAtIFRoZSBgYnViYmxlc2Agb3B0aW9uIGluIHRoZSBgdXNlRGlzbWlzcygpYCBIb29rXG4gKiAtIE5lc3RlZCB2aXJ0dWFsIGxpc3QgbmF2aWdhdGlvblxuICogLSBOZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMgdGhhdCBlYWNoIG9wZW4gb24gaG92ZXJcbiAqIC0gQ3VzdG9tIGNvbW11bmljYXRpb24gYmV0d2VlbiBwYXJlbnQgYW5kIGNoaWxkIGZsb2F0aW5nIGVsZW1lbnRzXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdUcmVlXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nVHJlZShwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW5cbiAgfSA9IHByb3BzO1xuICBjb25zdCBub2Rlc1JlZiA9IFJlYWN0LnVzZVJlZihbXSk7XG4gIGNvbnN0IGFkZE5vZGUgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBub2Rlc1JlZi5jdXJyZW50ID0gWy4uLm5vZGVzUmVmLmN1cnJlbnQsIG5vZGVdO1xuICB9LCBbXSk7XG4gIGNvbnN0IHJlbW92ZU5vZGUgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBub2Rlc1JlZi5jdXJyZW50ID0gbm9kZXNSZWYuY3VycmVudC5maWx0ZXIobiA9PiBuICE9PSBub2RlKTtcbiAgfSwgW10pO1xuICBjb25zdCBbZXZlbnRzXSA9IFJlYWN0LnVzZVN0YXRlKCgpID0+IGNyZWF0ZUV2ZW50RW1pdHRlcigpKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goRmxvYXRpbmdUcmVlQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgICBub2Rlc1JlZixcbiAgICAgIGFkZE5vZGUsXG4gICAgICByZW1vdmVOb2RlLFxuICAgICAgZXZlbnRzXG4gICAgfSksIFthZGROb2RlLCByZW1vdmVOb2RlLCBldmVudHNdKSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUF0dHJpYnV0ZShuYW1lKSB7XG4gIHJldHVybiBcImRhdGEtZmxvYXRpbmctdWktXCIgKyBuYW1lO1xufVxuXG5mdW5jdGlvbiBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0UmVmKSB7XG4gIGlmICh0aW1lb3V0UmVmLmN1cnJlbnQgIT09IC0xKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgdGltZW91dFJlZi5jdXJyZW50ID0gLTE7XG4gIH1cbn1cblxuY29uc3Qgc2FmZVBvbHlnb25JZGVudGlmaWVyID0gLyojX19QVVJFX18qL2NyZWF0ZUF0dHJpYnV0ZSgnc2FmZS1wb2x5Z29uJyk7XG5mdW5jdGlvbiBnZXREZWxheSh2YWx1ZSwgcHJvcCwgcG9pbnRlclR5cGUpIHtcbiAgaWYgKHBvaW50ZXJUeXBlICYmICFpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlKSkge1xuICAgIHJldHVybiAwO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCByZXN1bHQgPSB2YWx1ZSgpO1xuICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gdm9pZCAwIDogcmVzdWx0W3Byb3BdO1xuICB9XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gdm9pZCAwIDogdmFsdWVbcHJvcF07XG59XG5mdW5jdGlvbiBnZXRSZXN0TXModmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB2YWx1ZSgpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cbi8qKlxuICogT3BlbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2hpbGUgaG92ZXJpbmcgb3ZlciB0aGUgcmVmZXJlbmNlIGVsZW1lbnQsIGxpa2VcbiAqIENTUyBgOmhvdmVyYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VIb3ZlclxuICovXG5mdW5jdGlvbiB1c2VIb3Zlcihjb250ZXh0LCBwcm9wcykge1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGRhdGFSZWYsXG4gICAgZXZlbnRzLFxuICAgIGVsZW1lbnRzXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgZGVsYXkgPSAwLFxuICAgIGhhbmRsZUNsb3NlID0gbnVsbCxcbiAgICBtb3VzZU9ubHkgPSBmYWxzZSxcbiAgICByZXN0TXMgPSAwLFxuICAgIG1vdmUgPSB0cnVlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIGNvbnN0IGhhbmRsZUNsb3NlUmVmID0gdXNlTGF0ZXN0UmVmKGhhbmRsZUNsb3NlKTtcbiAgY29uc3QgZGVsYXlSZWYgPSB1c2VMYXRlc3RSZWYoZGVsYXkpO1xuICBjb25zdCBvcGVuUmVmID0gdXNlTGF0ZXN0UmVmKG9wZW4pO1xuICBjb25zdCByZXN0TXNSZWYgPSB1c2VMYXRlc3RSZWYocmVzdE1zKTtcbiAgY29uc3QgcG9pbnRlclR5cGVSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgY29uc3QgdGltZW91dFJlZiA9IFJlYWN0LnVzZVJlZigtMSk7XG4gIGNvbnN0IGhhbmRsZXJSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgY29uc3QgcmVzdFRpbWVvdXRSZWYgPSBSZWFjdC51c2VSZWYoLTEpO1xuICBjb25zdCBibG9ja01vdXNlTW92ZVJlZiA9IFJlYWN0LnVzZVJlZih0cnVlKTtcbiAgY29uc3QgcGVyZm9ybWVkUG9pbnRlckV2ZW50c011dGF0aW9uUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgdW5iaW5kTW91c2VNb3ZlUmVmID0gUmVhY3QudXNlUmVmKCgpID0+IHt9KTtcbiAgY29uc3QgcmVzdFRpbWVvdXRQZW5kaW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgaXNIb3Zlck9wZW4gPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkb3BlbjtcbiAgICBjb25zdCB0eXBlID0gKF9kYXRhUmVmJGN1cnJlbnQkb3BlbiA9IGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JG9wZW4udHlwZTtcbiAgICByZXR1cm4gKHR5cGUgPT0gbnVsbCA/IHZvaWQgMCA6IHR5cGUuaW5jbHVkZXMoJ21vdXNlJykpICYmIHR5cGUgIT09ICdtb3VzZWRvd24nO1xuICB9LCBbZGF0YVJlZl0pO1xuXG4gIC8vIFdoZW4gY2xvc2luZyBiZWZvcmUgb3BlbmluZywgY2xlYXIgdGhlIGRlbGF5IHRpbWVvdXRzIHRvIGNhbmNlbCBpdFxuICAvLyBmcm9tIHNob3dpbmcuXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgZnVuY3Rpb24gb25PcGVuQ2hhbmdlKF9yZWYpIHtcbiAgICAgIGxldCB7XG4gICAgICAgIG9wZW5cbiAgICAgIH0gPSBfcmVmO1xuICAgICAgaWYgKCFvcGVuKSB7XG4gICAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICAgIGJsb2NrTW91c2VNb3ZlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICByZXN0VGltZW91dFBlbmRpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBldmVudHMub24oJ29wZW5jaGFuZ2UnLCBvbk9wZW5DaGFuZ2UpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBldmVudHMub2ZmKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICB9O1xuICB9LCBbZW5hYmxlZCwgZXZlbnRzXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKCFoYW5kbGVDbG9zZVJlZi5jdXJyZW50KSByZXR1cm47XG4gICAgaWYgKCFvcGVuKSByZXR1cm47XG4gICAgZnVuY3Rpb24gb25MZWF2ZShldmVudCkge1xuICAgICAgaWYgKGlzSG92ZXJPcGVuKCkpIHtcbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudCwgJ2hvdmVyJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGh0bWwgPSBnZXREb2N1bWVudCQxKGVsZW1lbnRzLmZsb2F0aW5nKS5kb2N1bWVudEVsZW1lbnQ7XG4gICAgaHRtbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25MZWF2ZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGh0bWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uTGVhdmUpO1xuICAgIH07XG4gIH0sIFtlbGVtZW50cy5mbG9hdGluZywgb3Blbiwgb25PcGVuQ2hhbmdlLCBlbmFibGVkLCBoYW5kbGVDbG9zZVJlZiwgaXNIb3Zlck9wZW5dKTtcbiAgY29uc3QgY2xvc2VXaXRoRGVsYXkgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAoZXZlbnQsIHJ1bkVsc2VCcmFuY2gsIHJlYXNvbikge1xuICAgIGlmIChydW5FbHNlQnJhbmNoID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkVsc2VCcmFuY2ggPSB0cnVlO1xuICAgIH1cbiAgICBpZiAocmVhc29uID09PSB2b2lkIDApIHtcbiAgICAgIHJlYXNvbiA9ICdob3Zlcic7XG4gICAgfVxuICAgIGNvbnN0IGNsb3NlRGVsYXkgPSBnZXREZWxheShkZWxheVJlZi5jdXJyZW50LCAnY2xvc2UnLCBwb2ludGVyVHlwZVJlZi5jdXJyZW50KTtcbiAgICBpZiAoY2xvc2VEZWxheSAmJiAhaGFuZGxlclJlZi5jdXJyZW50KSB7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0UmVmKTtcbiAgICAgIHRpbWVvdXRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsIHJlYXNvbiksIGNsb3NlRGVsYXkpO1xuICAgIH0gZWxzZSBpZiAocnVuRWxzZUJyYW5jaCkge1xuICAgICAgY2xlYXJUaW1lb3V0SWZTZXQodGltZW91dFJlZik7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCByZWFzb24pO1xuICAgIH1cbiAgfSwgW2RlbGF5UmVmLCBvbk9wZW5DaGFuZ2VdKTtcbiAgY29uc3QgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdW5iaW5kTW91c2VNb3ZlUmVmLmN1cnJlbnQoKTtcbiAgICBoYW5kbGVyUmVmLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gIH0pO1xuICBjb25zdCBjbGVhclBvaW50ZXJFdmVudHMgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgaWYgKHBlcmZvcm1lZFBvaW50ZXJFdmVudHNNdXRhdGlvblJlZi5jdXJyZW50KSB7XG4gICAgICBjb25zdCBib2R5ID0gZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZykuYm9keTtcbiAgICAgIGJvZHkuc3R5bGUucG9pbnRlckV2ZW50cyA9ICcnO1xuICAgICAgYm9keS5yZW1vdmVBdHRyaWJ1dGUoc2FmZVBvbHlnb25JZGVudGlmaWVyKTtcbiAgICAgIHBlcmZvcm1lZFBvaW50ZXJFdmVudHNNdXRhdGlvblJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgY29uc3QgaXNDbGlja0xpa2VPcGVuRXZlbnQgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgcmV0dXJuIGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgPyBbJ2NsaWNrJywgJ21vdXNlZG93biddLmluY2x1ZGVzKGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQudHlwZSkgOiBmYWxzZTtcbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXJpbmcgdGhlIG1vdXNlIGV2ZW50cyBvbiB0aGUgcmVmZXJlbmNlIGRpcmVjdGx5IHRvIGJ5cGFzcyBSZWFjdCdzXG4gIC8vIGRlbGVnYXRpb24gc3lzdGVtLiBJZiB0aGUgY3Vyc29yIHdhcyBvbiBhIGRpc2FibGVkIGVsZW1lbnQgYW5kIHRoZW4gZW50ZXJlZFxuICAvLyB0aGUgcmVmZXJlbmNlIChubyBnYXApLCBgbW91c2VlbnRlcmAgZG9lc24ndCBmaXJlIGluIHRoZSBkZWxlZ2F0aW9uIHN5c3RlbS5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBvblJlZmVyZW5jZU1vdXNlRW50ZXIoZXZlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgICAgYmxvY2tNb3VzZU1vdmVSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgaWYgKG1vdXNlT25seSAmJiAhaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZVJlZi5jdXJyZW50KSB8fCBnZXRSZXN0TXMocmVzdE1zUmVmLmN1cnJlbnQpID4gMCAmJiAhZ2V0RGVsYXkoZGVsYXlSZWYuY3VycmVudCwgJ29wZW4nKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBvcGVuRGVsYXkgPSBnZXREZWxheShkZWxheVJlZi5jdXJyZW50LCAnb3BlbicsIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQpO1xuICAgICAgaWYgKG9wZW5EZWxheSkge1xuICAgICAgICB0aW1lb3V0UmVmLmN1cnJlbnQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaWYgKCFvcGVuUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudCwgJ2hvdmVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBvcGVuRGVsYXkpO1xuICAgICAgfSBlbHNlIGlmICghb3Blbikge1xuICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQsICdob3ZlcicpO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBvblJlZmVyZW5jZU1vdXNlTGVhdmUoZXZlbnQpIHtcbiAgICAgIGlmIChpc0NsaWNrTGlrZU9wZW5FdmVudCgpKSB7XG4gICAgICAgIGNsZWFyUG9pbnRlckV2ZW50cygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB1bmJpbmRNb3VzZU1vdmVSZWYuY3VycmVudCgpO1xuICAgICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZyk7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICByZXN0VGltZW91dFBlbmRpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgaWYgKGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQgJiYgZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCkge1xuICAgICAgICAvLyBQcmV2ZW50IGNsZWFyaW5nIGBvblNjcm9sbE1vdXNlTGVhdmVgIHRpbWVvdXQuXG4gICAgICAgIGlmICghb3Blbikge1xuICAgICAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgICAgICB9XG4gICAgICAgIGhhbmRsZXJSZWYuY3VycmVudCA9IGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQoe1xuICAgICAgICAgIC4uLmRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQsXG4gICAgICAgICAgdHJlZSxcbiAgICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgICAgICAgb25DbG9zZSgpIHtcbiAgICAgICAgICAgIGNsZWFyUG9pbnRlckV2ZW50cygpO1xuICAgICAgICAgICAgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmICghaXNDbGlja0xpa2VPcGVuRXZlbnQoKSkge1xuICAgICAgICAgICAgICBjbG9zZVdpdGhEZWxheShldmVudCwgdHJ1ZSwgJ3NhZmUtcG9seWdvbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBoYW5kbGVyUmVmLmN1cnJlbnQ7XG4gICAgICAgIGRvYy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBoYW5kbGVyKTtcbiAgICAgICAgdW5iaW5kTW91c2VNb3ZlUmVmLmN1cnJlbnQgPSAoKSA9PiB7XG4gICAgICAgICAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGhhbmRsZXIpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEFsbG93IGludGVyYWN0aXZpdHkgd2l0aG91dCBgc2FmZVBvbHlnb25gIG9uIHRvdWNoIGRldmljZXMuIFdpdGggYVxuICAgICAgLy8gcG9pbnRlciwgYSBzaG9ydCBjbG9zZSBkZWxheSBpcyBhbiBhbHRlcm5hdGl2ZSwgc28gaXQgc2hvdWxkIHdvcmtcbiAgICAgIC8vIGNvbnNpc3RlbnRseS5cbiAgICAgIGNvbnN0IHNob3VsZENsb3NlID0gcG9pbnRlclR5cGVSZWYuY3VycmVudCA9PT0gJ3RvdWNoJyA/ICFjb250YWlucyQxKGVsZW1lbnRzLmZsb2F0aW5nLCBldmVudC5yZWxhdGVkVGFyZ2V0KSA6IHRydWU7XG4gICAgICBpZiAoc2hvdWxkQ2xvc2UpIHtcbiAgICAgICAgY2xvc2VXaXRoRGVsYXkoZXZlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVuc3VyZSB0aGUgZmxvYXRpbmcgZWxlbWVudCBjbG9zZXMgYWZ0ZXIgc2Nyb2xsaW5nIGV2ZW4gaWYgdGhlIHBvaW50ZXJcbiAgICAvLyBkaWQgbm90IG1vdmUuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2Rpc2N1c3Npb25zLzE2OTJcbiAgICBmdW5jdGlvbiBvblNjcm9sbE1vdXNlTGVhdmUoZXZlbnQpIHtcbiAgICAgIGlmIChpc0NsaWNrTGlrZU9wZW5FdmVudCgpKSByZXR1cm47XG4gICAgICBpZiAoIWRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpIHJldHVybjtcbiAgICAgIGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQgPT0gbnVsbCB8fCBoYW5kbGVDbG9zZVJlZi5jdXJyZW50KHtcbiAgICAgICAgLi4uZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCxcbiAgICAgICAgdHJlZSxcbiAgICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgICAgb25DbG9zZSgpIHtcbiAgICAgICAgICBjbGVhclBvaW50ZXJFdmVudHMoKTtcbiAgICAgICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgICAgIGlmICghaXNDbGlja0xpa2VPcGVuRXZlbnQoKSkge1xuICAgICAgICAgICAgY2xvc2VXaXRoRGVsYXkoZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSkoZXZlbnQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvbkZsb2F0aW5nTW91c2VFbnRlcigpIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvbkZsb2F0aW5nTW91c2VMZWF2ZShldmVudCkge1xuICAgICAgaWYgKCFpc0NsaWNrTGlrZU9wZW5FdmVudCgpKSB7XG4gICAgICAgIGNsb3NlV2l0aERlbGF5KGV2ZW50LCBmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgY29uc3QgcmVmZXJlbmNlID0gZWxlbWVudHMuZG9tUmVmZXJlbmNlO1xuICAgICAgY29uc3QgZmxvYXRpbmcgPSBlbGVtZW50cy5mbG9hdGluZztcbiAgICAgIGlmIChvcGVuKSB7XG4gICAgICAgIHJlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25TY3JvbGxNb3VzZUxlYXZlKTtcbiAgICAgIH1cbiAgICAgIGlmIChtb3ZlKSB7XG4gICAgICAgIHJlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvblJlZmVyZW5jZU1vdXNlRW50ZXIsIHtcbiAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBvblJlZmVyZW5jZU1vdXNlRW50ZXIpO1xuICAgICAgcmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBvblJlZmVyZW5jZU1vdXNlTGVhdmUpO1xuICAgICAgaWYgKGZsb2F0aW5nKSB7XG4gICAgICAgIGZsb2F0aW5nLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBvblNjcm9sbE1vdXNlTGVhdmUpO1xuICAgICAgICBmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgb25GbG9hdGluZ01vdXNlRW50ZXIpO1xuICAgICAgICBmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25GbG9hdGluZ01vdXNlTGVhdmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKG9wZW4pIHtcbiAgICAgICAgICByZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uU2Nyb2xsTW91c2VMZWF2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vdmUpIHtcbiAgICAgICAgICByZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25SZWZlcmVuY2VNb3VzZUVudGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIG9uUmVmZXJlbmNlTW91c2VFbnRlcik7XG4gICAgICAgIHJlZmVyZW5jZS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25SZWZlcmVuY2VNb3VzZUxlYXZlKTtcbiAgICAgICAgaWYgKGZsb2F0aW5nKSB7XG4gICAgICAgICAgZmxvYXRpbmcucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uU2Nyb2xsTW91c2VMZWF2ZSk7XG4gICAgICAgICAgZmxvYXRpbmcucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIG9uRmxvYXRpbmdNb3VzZUVudGVyKTtcbiAgICAgICAgICBmbG9hdGluZy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25GbG9hdGluZ01vdXNlTGVhdmUpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgfSwgW2VsZW1lbnRzLCBlbmFibGVkLCBjb250ZXh0LCBtb3VzZU9ubHksIG1vdmUsIGNsb3NlV2l0aERlbGF5LCBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlciwgY2xlYXJQb2ludGVyRXZlbnRzLCBvbk9wZW5DaGFuZ2UsIG9wZW4sIG9wZW5SZWYsIHRyZWUsIGRlbGF5UmVmLCBoYW5kbGVDbG9zZVJlZiwgZGF0YVJlZiwgaXNDbGlja0xpa2VPcGVuRXZlbnQsIHJlc3RNc1JlZl0pO1xuXG4gIC8vIEJsb2NrIHBvaW50ZXItZXZlbnRzIG9mIGV2ZXJ5IGVsZW1lbnQgb3RoZXIgdGhhbiB0aGUgcmVmZXJlbmNlIGFuZCBmbG9hdGluZ1xuICAvLyB3aGlsZSB0aGUgZmxvYXRpbmcgZWxlbWVudCBpcyBvcGVuIGFuZCBoYXMgYSBgaGFuZGxlQ2xvc2VgIGhhbmRsZXIuIEFsc29cbiAgLy8gaGFuZGxlcyBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMTcyMlxuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIHZhciBfaGFuZGxlQ2xvc2VSZWYkY3VycmU7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKG9wZW4gJiYgKF9oYW5kbGVDbG9zZVJlZiRjdXJyZSA9IGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQpICE9IG51bGwgJiYgX2hhbmRsZUNsb3NlUmVmJGN1cnJlLl9fb3B0aW9ucy5ibG9ja1BvaW50ZXJFdmVudHMgJiYgaXNIb3Zlck9wZW4oKSkge1xuICAgICAgcGVyZm9ybWVkUG9pbnRlckV2ZW50c011dGF0aW9uUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgY29uc3QgZmxvYXRpbmdFbCA9IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgICAgaWYgKGlzRWxlbWVudChlbGVtZW50cy5kb21SZWZlcmVuY2UpICYmIGZsb2F0aW5nRWwpIHtcbiAgICAgICAgdmFyIF90cmVlJG5vZGVzUmVmJGN1cnJlbjtcbiAgICAgICAgY29uc3QgYm9keSA9IGdldERvY3VtZW50JDEoZWxlbWVudHMuZmxvYXRpbmcpLmJvZHk7XG4gICAgICAgIGJvZHkuc2V0QXR0cmlidXRlKHNhZmVQb2x5Z29uSWRlbnRpZmllciwgJycpO1xuICAgICAgICBjb25zdCByZWYgPSBlbGVtZW50cy5kb21SZWZlcmVuY2U7XG4gICAgICAgIGNvbnN0IHBhcmVudEZsb2F0aW5nID0gdHJlZSA9PSBudWxsIHx8IChfdHJlZSRub2Rlc1JlZiRjdXJyZW4gPSB0cmVlLm5vZGVzUmVmLmN1cnJlbnQuZmluZChub2RlID0+IG5vZGUuaWQgPT09IHBhcmVudElkKSkgPT0gbnVsbCB8fCAoX3RyZWUkbm9kZXNSZWYkY3VycmVuID0gX3RyZWUkbm9kZXNSZWYkY3VycmVuLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfdHJlZSRub2Rlc1JlZiRjdXJyZW4uZWxlbWVudHMuZmxvYXRpbmc7XG4gICAgICAgIGlmIChwYXJlbnRGbG9hdGluZykge1xuICAgICAgICAgIHBhcmVudEZsb2F0aW5nLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgICAgfVxuICAgICAgICBib2R5LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgICAgIHJlZi5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgICAgICBmbG9hdGluZ0VsLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgYm9keS5zdHlsZS5wb2ludGVyRXZlbnRzID0gJyc7XG4gICAgICAgICAgcmVmLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgICAgICBmbG9hdGluZ0VsLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuLCBwYXJlbnRJZCwgZWxlbWVudHMsIHRyZWUsIGhhbmRsZUNsb3NlUmVmLCBpc0hvdmVyT3Blbl0pO1xuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3Blbikge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgIHJlc3RUaW1lb3V0UGVuZGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgY2xlYXJQb2ludGVyRXZlbnRzKCk7XG4gICAgfVxuICB9LCBbb3BlbiwgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIsIGNsZWFyUG9pbnRlckV2ZW50c10pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgY2xlYXJUaW1lb3V0SWZTZXQodGltZW91dFJlZik7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICBjbGVhclBvaW50ZXJFdmVudHMoKTtcbiAgICB9O1xuICB9LCBbZW5hYmxlZCwgZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlciwgY2xlYXJQb2ludGVyRXZlbnRzXSk7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHNldFBvaW50ZXJSZWYoZXZlbnQpIHtcbiAgICAgIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQgPSBldmVudC5wb2ludGVyVHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG9uUG9pbnRlckRvd246IHNldFBvaW50ZXJSZWYsXG4gICAgICBvblBvaW50ZXJFbnRlcjogc2V0UG9pbnRlclJlZixcbiAgICAgIG9uTW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBuYXRpdmVFdmVudFxuICAgICAgICB9ID0gZXZlbnQ7XG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZU1vdXNlTW92ZSgpIHtcbiAgICAgICAgICBpZiAoIWJsb2NrTW91c2VNb3ZlUmVmLmN1cnJlbnQgJiYgIW9wZW5SZWYuY3VycmVudCkge1xuICAgICAgICAgICAgb25PcGVuQ2hhbmdlKHRydWUsIG5hdGl2ZUV2ZW50LCAnaG92ZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vdXNlT25seSAmJiAhaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZVJlZi5jdXJyZW50KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3BlbiB8fCBnZXRSZXN0TXMocmVzdE1zUmVmLmN1cnJlbnQpID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWdub3JlIGluc2lnbmlmaWNhbnQgbW92ZW1lbnRzIHRvIGFjY291bnQgZm9yIHRyZW1vcnMuXG4gICAgICAgIGlmIChyZXN0VGltZW91dFBlbmRpbmdSZWYuY3VycmVudCAmJiBldmVudC5tb3ZlbWVudFggKiogMiArIGV2ZW50Lm1vdmVtZW50WSAqKiAyIDwgMikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICAgIGlmIChwb2ludGVyVHlwZVJlZi5jdXJyZW50ID09PSAndG91Y2gnKSB7XG4gICAgICAgICAgaGFuZGxlTW91c2VNb3ZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdFRpbWVvdXRQZW5kaW5nUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgIHJlc3RUaW1lb3V0UmVmLmN1cnJlbnQgPSB3aW5kb3cuc2V0VGltZW91dChoYW5kbGVNb3VzZU1vdmUsIGdldFJlc3RNcyhyZXN0TXNSZWYuY3VycmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW21vdXNlT25seSwgb25PcGVuQ2hhbmdlLCBvcGVuLCBvcGVuUmVmLCByZXN0TXNSZWZdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2VcbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlXSk7XG59XG5cbmNvbnN0IE5PT1AgPSAoKSA9PiB7fTtcbmNvbnN0IEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7XG4gIGRlbGF5OiAwLFxuICBpbml0aWFsRGVsYXk6IDAsXG4gIHRpbWVvdXRNczogMCxcbiAgY3VycmVudElkOiBudWxsLFxuICBzZXRDdXJyZW50SWQ6IE5PT1AsXG4gIHNldFN0YXRlOiBOT09QLFxuICBpc0luc3RhbnRQaGFzZTogZmFsc2Vcbn0pO1xuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKiBVc2UgdGhlIHJldHVybiB2YWx1ZSBvZiBgdXNlRGVsYXlHcm91cCgpYCBpbnN0ZWFkLlxuICovXG5jb25zdCB1c2VEZWxheUdyb3VwQ29udGV4dCA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdEZWxheUdyb3VwQ29udGV4dCk7XG4vKipcbiAqIFByb3ZpZGVzIGNvbnRleHQgZm9yIGEgZ3JvdXAgb2YgZmxvYXRpbmcgZWxlbWVudHMgdGhhdCBzaG91bGQgc2hhcmUgYVxuICogYGRlbGF5YC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gRmxvYXRpbmdEZWxheUdyb3VwKHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBjaGlsZHJlbixcbiAgICBkZWxheSxcbiAgICB0aW1lb3V0TXMgPSAwXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgW3N0YXRlLCBzZXRTdGF0ZV0gPSBSZWFjdC51c2VSZWR1Y2VyKChwcmV2LCBuZXh0KSA9PiAoe1xuICAgIC4uLnByZXYsXG4gICAgLi4ubmV4dFxuICB9KSwge1xuICAgIGRlbGF5LFxuICAgIHRpbWVvdXRNcyxcbiAgICBpbml0aWFsRGVsYXk6IGRlbGF5LFxuICAgIGN1cnJlbnRJZDogbnVsbCxcbiAgICBpc0luc3RhbnRQaGFzZTogZmFsc2VcbiAgfSk7XG4gIGNvbnN0IGluaXRpYWxDdXJyZW50SWRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHNldEN1cnJlbnRJZCA9IFJlYWN0LnVzZUNhbGxiYWNrKGN1cnJlbnRJZCA9PiB7XG4gICAgc2V0U3RhdGUoe1xuICAgICAgY3VycmVudElkXG4gICAgfSk7XG4gIH0sIFtdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoc3RhdGUuY3VycmVudElkKSB7XG4gICAgICBpZiAoaW5pdGlhbEN1cnJlbnRJZFJlZi5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAgIGluaXRpYWxDdXJyZW50SWRSZWYuY3VycmVudCA9IHN0YXRlLmN1cnJlbnRJZDtcbiAgICAgIH0gZWxzZSBpZiAoIXN0YXRlLmlzSW5zdGFudFBoYXNlKSB7XG4gICAgICAgIHNldFN0YXRlKHtcbiAgICAgICAgICBpc0luc3RhbnRQaGFzZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLmlzSW5zdGFudFBoYXNlKSB7XG4gICAgICAgIHNldFN0YXRlKHtcbiAgICAgICAgICBpc0luc3RhbnRQaGFzZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpbml0aWFsQ3VycmVudElkUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIH1cbiAgfSwgW3N0YXRlLmN1cnJlbnRJZCwgc3RhdGUuaXNJbnN0YW50UGhhc2VdKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goRmxvYXRpbmdEZWxheUdyb3VwQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIHNldFN0YXRlLFxuICAgICAgc2V0Q3VycmVudElkXG4gICAgfSksIFtzdGF0ZSwgc2V0Q3VycmVudElkXSksXG4gICAgY2hpbGRyZW46IGNoaWxkcmVuXG4gIH0pO1xufVxuLyoqXG4gKiBFbmFibGVzIGdyb3VwaW5nIHdoZW4gY2FsbGVkIGluc2lkZSBhIGNvbXBvbmVudCB0aGF0J3MgYSBjaGlsZCBvZiBhXG4gKiBgRmxvYXRpbmdEZWxheUdyb3VwYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gdXNlRGVsYXlHcm91cChjb250ZXh0LCBvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zID09PSB2b2lkIDApIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGZsb2F0aW5nSWRcbiAgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtcbiAgICBpZDogb3B0aW9uSWQsXG4gICAgZW5hYmxlZCA9IHRydWVcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGlkID0gb3B0aW9uSWQgIT0gbnVsbCA/IG9wdGlvbklkIDogZmxvYXRpbmdJZDtcbiAgY29uc3QgZ3JvdXBDb250ZXh0ID0gdXNlRGVsYXlHcm91cENvbnRleHQoKTtcbiAgY29uc3Qge1xuICAgIGN1cnJlbnRJZCxcbiAgICBzZXRDdXJyZW50SWQsXG4gICAgaW5pdGlhbERlbGF5LFxuICAgIHNldFN0YXRlLFxuICAgIHRpbWVvdXRNc1xuICB9ID0gZ3JvdXBDb250ZXh0O1xuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmICghY3VycmVudElkKSByZXR1cm47XG4gICAgc2V0U3RhdGUoe1xuICAgICAgZGVsYXk6IHtcbiAgICAgICAgb3BlbjogMSxcbiAgICAgICAgY2xvc2U6IGdldERlbGF5KGluaXRpYWxEZWxheSwgJ2Nsb3NlJylcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoY3VycmVudElkICE9PSBpZCkge1xuICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlKTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBpZCwgb25PcGVuQ2hhbmdlLCBzZXRTdGF0ZSwgY3VycmVudElkLCBpbml0aWFsRGVsYXldKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBmdW5jdGlvbiB1bnNldCgpIHtcbiAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSk7XG4gICAgICBzZXRTdGF0ZSh7XG4gICAgICAgIGRlbGF5OiBpbml0aWFsRGVsYXksXG4gICAgICAgIGN1cnJlbnRJZDogbnVsbFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmICghY3VycmVudElkKSByZXR1cm47XG4gICAgaWYgKCFvcGVuICYmIGN1cnJlbnRJZCA9PT0gaWQpIHtcbiAgICAgIGlmICh0aW1lb3V0TXMpIHtcbiAgICAgICAgY29uc3QgdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KHVuc2V0LCB0aW1lb3V0TXMpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHVuc2V0KCk7XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgb3Blbiwgc2V0U3RhdGUsIGN1cnJlbnRJZCwgaWQsIG9uT3BlbkNoYW5nZSwgaW5pdGlhbERlbGF5LCB0aW1lb3V0TXNdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoc2V0Q3VycmVudElkID09PSBOT09QIHx8ICFvcGVuKSByZXR1cm47XG4gICAgc2V0Q3VycmVudElkKGlkKTtcbiAgfSwgW2VuYWJsZWQsIG9wZW4sIHNldEN1cnJlbnRJZCwgaWRdKTtcbiAgcmV0dXJuIGdyb3VwQ29udGV4dDtcbn1cblxuY29uc3QgTmV4dEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7XG4gIGhhc1Byb3ZpZGVyOiBmYWxzZSxcbiAgdGltZW91dE1zOiAwLFxuICBkZWxheVJlZjoge1xuICAgIGN1cnJlbnQ6IDBcbiAgfSxcbiAgaW5pdGlhbERlbGF5UmVmOiB7XG4gICAgY3VycmVudDogMFxuICB9LFxuICB0aW1lb3V0SWRSZWY6IHtcbiAgICBjdXJyZW50OiAtMVxuICB9LFxuICBjdXJyZW50SWRSZWY6IHtcbiAgICBjdXJyZW50OiBudWxsXG4gIH0sXG4gIGN1cnJlbnRDb250ZXh0UmVmOiB7XG4gICAgY3VycmVudDogbnVsbFxuICB9XG59KTtcbi8qKlxuICogRXhwZXJpbWVudGFsIG5leHQgdmVyc2lvbiBvZiBgRmxvYXRpbmdEZWxheUdyb3VwYCB0byBiZWNvbWUgdGhlIGRlZmF1bHRcbiAqIGluIHRoZSBmdXR1cmUuIFRoaXMgY29tcG9uZW50IGlzIG5vdCB5ZXQgc3RhYmxlLlxuICogUHJvdmlkZXMgY29udGV4dCBmb3IgYSBncm91cCBvZiBmbG9hdGluZyBlbGVtZW50cyB0aGF0IHNob3VsZCBzaGFyZSBhXG4gKiBgZGVsYXlgLiBVbmxpa2UgYEZsb2F0aW5nRGVsYXlHcm91cGAsIGB1c2VOZXh0RGVsYXlHcm91cGAgd2l0aCB0aGlzXG4gKiBjb21wb25lbnQgZG9lcyBub3QgY2F1c2UgYSByZS1yZW5kZXIgb2YgdW5yZWxhdGVkIGNvbnN1bWVycyBvZiB0aGVcbiAqIGNvbnRleHQgd2hlbiB0aGUgZGVsYXkgY2hhbmdlcy5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gTmV4dEZsb2F0aW5nRGVsYXlHcm91cChwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgZGVsYXksXG4gICAgdGltZW91dE1zID0gMFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGRlbGF5UmVmID0gUmVhY3QudXNlUmVmKGRlbGF5KTtcbiAgY29uc3QgaW5pdGlhbERlbGF5UmVmID0gUmVhY3QudXNlUmVmKGRlbGF5KTtcbiAgY29uc3QgY3VycmVudElkUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBjdXJyZW50Q29udGV4dFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgdGltZW91dElkUmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goTmV4dEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgaGFzUHJvdmlkZXI6IHRydWUsXG4gICAgICBkZWxheVJlZixcbiAgICAgIGluaXRpYWxEZWxheVJlZixcbiAgICAgIGN1cnJlbnRJZFJlZixcbiAgICAgIHRpbWVvdXRNcyxcbiAgICAgIGN1cnJlbnRDb250ZXh0UmVmLFxuICAgICAgdGltZW91dElkUmVmXG4gICAgfSksIFt0aW1lb3V0TXNdKSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5cbiAgfSk7XG59XG4vKipcbiAqIEVuYWJsZXMgZ3JvdXBpbmcgd2hlbiBjYWxsZWQgaW5zaWRlIGEgY29tcG9uZW50IHRoYXQncyBhIGNoaWxkIG9mIGFcbiAqIGBOZXh0RmxvYXRpbmdEZWxheUdyb3VwYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gdXNlTmV4dERlbGF5R3JvdXAoY29udGV4dCwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBmbG9hdGluZ0lkXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWVcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGdyb3VwQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoTmV4dEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQpO1xuICBjb25zdCB7XG4gICAgY3VycmVudElkUmVmLFxuICAgIGRlbGF5UmVmLFxuICAgIHRpbWVvdXRNcyxcbiAgICBpbml0aWFsRGVsYXlSZWYsXG4gICAgY3VycmVudENvbnRleHRSZWYsXG4gICAgaGFzUHJvdmlkZXIsXG4gICAgdGltZW91dElkUmVmXG4gIH0gPSBncm91cENvbnRleHQ7XG4gIGNvbnN0IFtpc0luc3RhbnRQaGFzZSwgc2V0SXNJbnN0YW50UGhhc2VdID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpO1xuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHVuc2V0KCkge1xuICAgICAgdmFyIF9jdXJyZW50Q29udGV4dFJlZiRjdTtcbiAgICAgIHNldElzSW5zdGFudFBoYXNlKGZhbHNlKTtcbiAgICAgIChfY3VycmVudENvbnRleHRSZWYkY3UgPSBjdXJyZW50Q29udGV4dFJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9jdXJyZW50Q29udGV4dFJlZiRjdS5zZXRJc0luc3RhbnRQaGFzZShmYWxzZSk7XG4gICAgICBjdXJyZW50SWRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBjdXJyZW50Q29udGV4dFJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIGRlbGF5UmVmLmN1cnJlbnQgPSBpbml0aWFsRGVsYXlSZWYuY3VycmVudDtcbiAgICB9XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKCFjdXJyZW50SWRSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgIGlmICghb3BlbiAmJiBjdXJyZW50SWRSZWYuY3VycmVudCA9PT0gZmxvYXRpbmdJZCkge1xuICAgICAgc2V0SXNJbnN0YW50UGhhc2UoZmFsc2UpO1xuICAgICAgaWYgKHRpbWVvdXRNcykge1xuICAgICAgICB0aW1lb3V0SWRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KHVuc2V0LCB0aW1lb3V0TXMpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWRSZWYuY3VycmVudCk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB1bnNldCgpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGZsb2F0aW5nSWQsIGN1cnJlbnRJZFJlZiwgZGVsYXlSZWYsIHRpbWVvdXRNcywgaW5pdGlhbERlbGF5UmVmLCBjdXJyZW50Q29udGV4dFJlZiwgdGltZW91dElkUmVmXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKCFvcGVuKSByZXR1cm47XG4gICAgY29uc3QgcHJldkNvbnRleHQgPSBjdXJyZW50Q29udGV4dFJlZi5jdXJyZW50O1xuICAgIGNvbnN0IHByZXZJZCA9IGN1cnJlbnRJZFJlZi5jdXJyZW50O1xuICAgIGN1cnJlbnRDb250ZXh0UmVmLmN1cnJlbnQgPSB7XG4gICAgICBvbk9wZW5DaGFuZ2UsXG4gICAgICBzZXRJc0luc3RhbnRQaGFzZVxuICAgIH07XG4gICAgY3VycmVudElkUmVmLmN1cnJlbnQgPSBmbG9hdGluZ0lkO1xuICAgIGRlbGF5UmVmLmN1cnJlbnQgPSB7XG4gICAgICBvcGVuOiAwLFxuICAgICAgY2xvc2U6IGdldERlbGF5KGluaXRpYWxEZWxheVJlZi5jdXJyZW50LCAnY2xvc2UnKVxuICAgIH07XG4gICAgaWYgKHByZXZJZCAhPT0gbnVsbCAmJiBwcmV2SWQgIT09IGZsb2F0aW5nSWQpIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRJZFJlZik7XG4gICAgICBzZXRJc0luc3RhbnRQaGFzZSh0cnVlKTtcbiAgICAgIHByZXZDb250ZXh0ID09IG51bGwgfHwgcHJldkNvbnRleHQuc2V0SXNJbnN0YW50UGhhc2UodHJ1ZSk7XG4gICAgICBwcmV2Q29udGV4dCA9PSBudWxsIHx8IHByZXZDb250ZXh0Lm9uT3BlbkNoYW5nZShmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldElzSW5zdGFudFBoYXNlKGZhbHNlKTtcbiAgICAgIHByZXZDb250ZXh0ID09IG51bGwgfHwgcHJldkNvbnRleHQuc2V0SXNJbnN0YW50UGhhc2UoZmFsc2UpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGZsb2F0aW5nSWQsIG9uT3BlbkNoYW5nZSwgY3VycmVudElkUmVmLCBkZWxheVJlZiwgdGltZW91dE1zLCBpbml0aWFsRGVsYXlSZWYsIGN1cnJlbnRDb250ZXh0UmVmLCB0aW1lb3V0SWRSZWZdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY3VycmVudENvbnRleHRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfTtcbiAgfSwgW2N1cnJlbnRDb250ZXh0UmVmXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgaGFzUHJvdmlkZXIsXG4gICAgZGVsYXlSZWYsXG4gICAgaXNJbnN0YW50UGhhc2VcbiAgfSksIFtoYXNQcm92aWRlciwgZGVsYXlSZWYsIGlzSW5zdGFudFBoYXNlXSk7XG59XG5cbmxldCByYWZJZCA9IDA7XG5mdW5jdGlvbiBlbnF1ZXVlRm9jdXMoZWwsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgcHJldmVudFNjcm9sbCA9IGZhbHNlLFxuICAgIGNhbmNlbFByZXZpb3VzID0gdHJ1ZSxcbiAgICBzeW5jID0gZmFsc2VcbiAgfSA9IG9wdGlvbnM7XG4gIGNhbmNlbFByZXZpb3VzICYmIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZklkKTtcbiAgY29uc3QgZXhlYyA9ICgpID0+IGVsID09IG51bGwgPyB2b2lkIDAgOiBlbC5mb2N1cyh7XG4gICAgcHJldmVudFNjcm9sbFxuICB9KTtcbiAgaWYgKHN5bmMpIHtcbiAgICBleGVjKCk7XG4gIH0gZWxzZSB7XG4gICAgcmFmSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZXhlYyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udGFpbnMocGFyZW50LCBjaGlsZCkge1xuICBpZiAoIXBhcmVudCB8fCAhY2hpbGQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgcm9vdE5vZGUgPSBjaGlsZC5nZXRSb290Tm9kZSA9PSBudWxsID8gdm9pZCAwIDogY2hpbGQuZ2V0Um9vdE5vZGUoKTtcblxuICAvLyBGaXJzdCwgYXR0ZW1wdCB3aXRoIGZhc3RlciBuYXRpdmUgbWV0aG9kXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyB0aGVuIGZhbGxiYWNrIHRvIGN1c3RvbSBpbXBsZW1lbnRhdGlvbiB3aXRoIFNoYWRvdyBET00gc3VwcG9ydFxuICBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgIGxldCBuZXh0ID0gY2hpbGQ7XG4gICAgd2hpbGUgKG5leHQpIHtcbiAgICAgIGlmIChwYXJlbnQgPT09IG5leHQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBuZXh0ID0gbmV4dC5wYXJlbnROb2RlIHx8IG5leHQuaG9zdDtcbiAgICB9XG4gIH1cblxuICAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG4gIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGdldFRhcmdldChldmVudCkge1xuICBpZiAoJ2NvbXBvc2VkUGF0aCcgaW4gZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQuY29tcG9zZWRQYXRoKClbMF07XG4gIH1cblxuICAvLyBUUyB0aGlua3MgYGV2ZW50YCBpcyBvZiB0eXBlIG5ldmVyIGFzIGl0IGFzc3VtZXMgYWxsIGJyb3dzZXJzIHN1cHBvcnRcbiAgLy8gYGNvbXBvc2VkUGF0aCgpYCwgYnV0IGJyb3dzZXJzIHdpdGhvdXQgc2hhZG93IERPTSBkb24ndC5cbiAgcmV0dXJuIGV2ZW50LnRhcmdldDtcbn1cbmZ1bmN0aW9uIGdldERvY3VtZW50KG5vZGUpIHtcbiAgcmV0dXJuIChub2RlID09IG51bGwgPyB2b2lkIDAgOiBub2RlLm93bmVyRG9jdW1lbnQpIHx8IGRvY3VtZW50O1xufVxuXG4vLyBNb2RpZmllZCB0byBhZGQgY29uZGl0aW9uYWwgYGFyaWEtaGlkZGVuYCBzdXBwb3J0OlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RoZUthc2hleS9hcmlhLWhpZGRlbi9ibG9iLzkyMjBjOGY0YTRmZDM1ZjYzYmVlNTUxMGE5ZjQxYTM3MjY0MzgyZDQvc3JjL2luZGV4LnRzXG5sZXQgY291bnRlck1hcCA9IC8qI19fUFVSRV9fKi9uZXcgV2Vha01hcCgpO1xubGV0IHVuY29udHJvbGxlZEVsZW1lbnRzU2V0ID0gLyojX19QVVJFX18qL25ldyBXZWFrU2V0KCk7XG5sZXQgbWFya2VyTWFwID0ge307XG5sZXQgbG9ja0NvdW50JDEgPSAwO1xuY29uc3Qgc3VwcG9ydHNJbmVydCA9ICgpID0+IHR5cGVvZiBIVE1MRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2luZXJ0JyBpbiBIVE1MRWxlbWVudC5wcm90b3R5cGU7XG5jb25zdCB1bndyYXBIb3N0ID0gbm9kZSA9PiBub2RlICYmIChub2RlLmhvc3QgfHwgdW53cmFwSG9zdChub2RlLnBhcmVudE5vZGUpKTtcbmNvbnN0IGNvcnJlY3RFbGVtZW50cyA9IChwYXJlbnQsIHRhcmdldHMpID0+IHRhcmdldHMubWFwKHRhcmdldCA9PiB7XG4gIGlmIChwYXJlbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbiAgY29uc3QgY29ycmVjdGVkVGFyZ2V0ID0gdW53cmFwSG9zdCh0YXJnZXQpO1xuICBpZiAocGFyZW50LmNvbnRhaW5zKGNvcnJlY3RlZFRhcmdldCkpIHtcbiAgICByZXR1cm4gY29ycmVjdGVkVGFyZ2V0O1xuICB9XG4gIHJldHVybiBudWxsO1xufSkuZmlsdGVyKHggPT4geCAhPSBudWxsKTtcbmZ1bmN0aW9uIGFwcGx5QXR0cmlidXRlVG9PdGhlcnModW5jb3JyZWN0ZWRBdm9pZEVsZW1lbnRzLCBib2R5LCBhcmlhSGlkZGVuLCBpbmVydCkge1xuICBjb25zdCBtYXJrZXJOYW1lID0gJ2RhdGEtZmxvYXRpbmctdWktaW5lcnQnO1xuICBjb25zdCBjb250cm9sQXR0cmlidXRlID0gaW5lcnQgPyAnaW5lcnQnIDogYXJpYUhpZGRlbiA/ICdhcmlhLWhpZGRlbicgOiBudWxsO1xuICBjb25zdCBhdm9pZEVsZW1lbnRzID0gY29ycmVjdEVsZW1lbnRzKGJvZHksIHVuY29ycmVjdGVkQXZvaWRFbGVtZW50cyk7XG4gIGNvbnN0IGVsZW1lbnRzVG9LZWVwID0gbmV3IFNldCgpO1xuICBjb25zdCBlbGVtZW50c1RvU3RvcCA9IG5ldyBTZXQoYXZvaWRFbGVtZW50cyk7XG4gIGNvbnN0IGhpZGRlbkVsZW1lbnRzID0gW107XG4gIGlmICghbWFya2VyTWFwW21hcmtlck5hbWVdKSB7XG4gICAgbWFya2VyTWFwW21hcmtlck5hbWVdID0gbmV3IFdlYWtNYXAoKTtcbiAgfVxuICBjb25zdCBtYXJrZXJDb3VudGVyID0gbWFya2VyTWFwW21hcmtlck5hbWVdO1xuICBhdm9pZEVsZW1lbnRzLmZvckVhY2goa2VlcCk7XG4gIGRlZXAoYm9keSk7XG4gIGVsZW1lbnRzVG9LZWVwLmNsZWFyKCk7XG4gIGZ1bmN0aW9uIGtlZXAoZWwpIHtcbiAgICBpZiAoIWVsIHx8IGVsZW1lbnRzVG9LZWVwLmhhcyhlbCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZWxlbWVudHNUb0tlZXAuYWRkKGVsKTtcbiAgICBlbC5wYXJlbnROb2RlICYmIGtlZXAoZWwucGFyZW50Tm9kZSk7XG4gIH1cbiAgZnVuY3Rpb24gZGVlcChwYXJlbnQpIHtcbiAgICBpZiAoIXBhcmVudCB8fCBlbGVtZW50c1RvU3RvcC5oYXMocGFyZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBbXS5mb3JFYWNoLmNhbGwocGFyZW50LmNoaWxkcmVuLCBub2RlID0+IHtcbiAgICAgIGlmIChnZXROb2RlTmFtZShub2RlKSA9PT0gJ3NjcmlwdCcpIHJldHVybjtcbiAgICAgIGlmIChlbGVtZW50c1RvS2VlcC5oYXMobm9kZSkpIHtcbiAgICAgICAgZGVlcChub2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGF0dHIgPSBjb250cm9sQXR0cmlidXRlID8gbm9kZS5nZXRBdHRyaWJ1dGUoY29udHJvbEF0dHJpYnV0ZSkgOiBudWxsO1xuICAgICAgICBjb25zdCBhbHJlYWR5SGlkZGVuID0gYXR0ciAhPT0gbnVsbCAmJiBhdHRyICE9PSAnZmFsc2UnO1xuICAgICAgICBjb25zdCBjdXJyZW50Q291bnRlclZhbHVlID0gY291bnRlck1hcC5nZXQobm9kZSkgfHwgMDtcbiAgICAgICAgY29uc3QgY291bnRlclZhbHVlID0gY29udHJvbEF0dHJpYnV0ZSA/IGN1cnJlbnRDb3VudGVyVmFsdWUgKyAxIDogY3VycmVudENvdW50ZXJWYWx1ZTtcbiAgICAgICAgY29uc3QgbWFya2VyVmFsdWUgPSAobWFya2VyQ291bnRlci5nZXQobm9kZSkgfHwgMCkgKyAxO1xuICAgICAgICBjb3VudGVyTWFwLnNldChub2RlLCBjb3VudGVyVmFsdWUpO1xuICAgICAgICBtYXJrZXJDb3VudGVyLnNldChub2RlLCBtYXJrZXJWYWx1ZSk7XG4gICAgICAgIGhpZGRlbkVsZW1lbnRzLnB1c2gobm9kZSk7XG4gICAgICAgIGlmIChjb3VudGVyVmFsdWUgPT09IDEgJiYgYWxyZWFkeUhpZGRlbikge1xuICAgICAgICAgIHVuY29udHJvbGxlZEVsZW1lbnRzU2V0LmFkZChub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWFya2VyVmFsdWUgPT09IDEpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShtYXJrZXJOYW1lLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbHJlYWR5SGlkZGVuICYmIGNvbnRyb2xBdHRyaWJ1dGUpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShjb250cm9sQXR0cmlidXRlLCBjb250cm9sQXR0cmlidXRlID09PSAnaW5lcnQnID8gJycgOiAndHJ1ZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgbG9ja0NvdW50JDErKztcbiAgcmV0dXJuICgpID0+IHtcbiAgICBoaWRkZW5FbGVtZW50cy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgY29uc3QgY3VycmVudENvdW50ZXJWYWx1ZSA9IGNvdW50ZXJNYXAuZ2V0KGVsZW1lbnQpIHx8IDA7XG4gICAgICBjb25zdCBjb3VudGVyVmFsdWUgPSBjb250cm9sQXR0cmlidXRlID8gY3VycmVudENvdW50ZXJWYWx1ZSAtIDEgOiBjdXJyZW50Q291bnRlclZhbHVlO1xuICAgICAgY29uc3QgbWFya2VyVmFsdWUgPSAobWFya2VyQ291bnRlci5nZXQoZWxlbWVudCkgfHwgMCkgLSAxO1xuICAgICAgY291bnRlck1hcC5zZXQoZWxlbWVudCwgY291bnRlclZhbHVlKTtcbiAgICAgIG1hcmtlckNvdW50ZXIuc2V0KGVsZW1lbnQsIG1hcmtlclZhbHVlKTtcbiAgICAgIGlmICghY291bnRlclZhbHVlKSB7XG4gICAgICAgIGlmICghdW5jb250cm9sbGVkRWxlbWVudHNTZXQuaGFzKGVsZW1lbnQpICYmIGNvbnRyb2xBdHRyaWJ1dGUpIHtcbiAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShjb250cm9sQXR0cmlidXRlKTtcbiAgICAgICAgfVxuICAgICAgICB1bmNvbnRyb2xsZWRFbGVtZW50c1NldC5kZWxldGUoZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBpZiAoIW1hcmtlclZhbHVlKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG1hcmtlck5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGxvY2tDb3VudCQxLS07XG4gICAgaWYgKCFsb2NrQ291bnQkMSkge1xuICAgICAgY291bnRlck1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICBjb3VudGVyTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgIHVuY29udHJvbGxlZEVsZW1lbnRzU2V0ID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgIG1hcmtlck1hcCA9IHt9O1xuICAgIH1cbiAgfTtcbn1cbmZ1bmN0aW9uIG1hcmtPdGhlcnMoYXZvaWRFbGVtZW50cywgYXJpYUhpZGRlbiwgaW5lcnQpIHtcbiAgaWYgKGFyaWFIaWRkZW4gPT09IHZvaWQgMCkge1xuICAgIGFyaWFIaWRkZW4gPSBmYWxzZTtcbiAgfVxuICBpZiAoaW5lcnQgPT09IHZvaWQgMCkge1xuICAgIGluZXJ0ID0gZmFsc2U7XG4gIH1cbiAgY29uc3QgYm9keSA9IGdldERvY3VtZW50KGF2b2lkRWxlbWVudHNbMF0pLmJvZHk7XG4gIHJldHVybiBhcHBseUF0dHJpYnV0ZVRvT3RoZXJzKGF2b2lkRWxlbWVudHMuY29uY2F0KEFycmF5LmZyb20oYm9keS5xdWVyeVNlbGVjdG9yQWxsKCdbYXJpYS1saXZlXScpKSksIGJvZHksIGFyaWFIaWRkZW4sIGluZXJ0KTtcbn1cblxuY29uc3QgSElEREVOX1NUWUxFUyA9IHtcbiAgYm9yZGVyOiAwLFxuICBjbGlwOiAncmVjdCgwIDAgMCAwKScsXG4gIGhlaWdodDogJzFweCcsXG4gIG1hcmdpbjogJy0xcHgnLFxuICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gIHBhZGRpbmc6IDAsXG4gIHBvc2l0aW9uOiAnZml4ZWQnLFxuICB3aGl0ZVNwYWNlOiAnbm93cmFwJyxcbiAgd2lkdGg6ICcxcHgnLFxuICB0b3A6IDAsXG4gIGxlZnQ6IDBcbn07XG5jb25zdCBGb2N1c0d1YXJkID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRm9jdXNHdWFyZChwcm9wcywgcmVmKSB7XG4gIGNvbnN0IFtyb2xlLCBzZXRSb2xlXSA9IFJlYWN0LnVzZVN0YXRlKCk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGlzU2FmYXJpKCkpIHtcbiAgICAgIC8vIFVubGlrZSBvdGhlciBzY3JlZW4gcmVhZGVycyBzdWNoIGFzIE5WREEgYW5kIEpBV1MsIHRoZSB2aXJ0dWFsIGN1cnNvclxuICAgICAgLy8gb24gVm9pY2VPdmVyIGRvZXMgdHJpZ2dlciB0aGUgb25Gb2N1cyBldmVudCwgc28gd2UgY2FuIHVzZSB0aGUgZm9jdXNcbiAgICAgIC8vIHRyYXAgZWxlbWVudC4gT24gU2FmYXJpLCBvbmx5IGJ1dHRvbnMgdHJpZ2dlciB0aGUgb25Gb2N1cyBldmVudC5cbiAgICAgIC8vIE5COiBcImdyb3VwXCIgcm9sZSBpbiB0aGUgU2FuZGJveCBubyBsb25nZXIgYXBwZWFycyB0byB3b3JrLCBtdXN0IGJlIGFcbiAgICAgIC8vIGJ1dHRvbiByb2xlLlxuICAgICAgc2V0Um9sZSgnYnV0dG9uJyk7XG4gICAgfVxuICB9LCBbXSk7XG4gIGNvbnN0IHJlc3RQcm9wcyA9IHtcbiAgICByZWYsXG4gICAgdGFiSW5kZXg6IDAsXG4gICAgLy8gUm9sZSBpcyBvbmx5IGZvciBWb2ljZU92ZXJcbiAgICByb2xlLFxuICAgICdhcmlhLWhpZGRlbic6IHJvbGUgPyB1bmRlZmluZWQgOiB0cnVlLFxuICAgIFtjcmVhdGVBdHRyaWJ1dGUoJ2ZvY3VzLWd1YXJkJyldOiAnJyxcbiAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICB9O1xuICByZXR1cm4gLyojX19QVVJFX18qL2pzeChcInNwYW5cIiwge1xuICAgIC4uLnByb3BzLFxuICAgIC4uLnJlc3RQcm9wc1xuICB9KTtcbn0pO1xuXG5jb25zdCBQb3J0YWxDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5jb25zdCBhdHRyID0gLyojX19QVVJFX18qL2NyZWF0ZUF0dHJpYnV0ZSgncG9ydGFsJyk7XG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ1BvcnRhbCN1c2VmbG9hdGluZ3BvcnRhbG5vZGVcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdQb3J0YWxOb2RlKHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgaWQsXG4gICAgcm9vdFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHVuaXF1ZUlkID0gdXNlSWQoKTtcbiAgY29uc3QgcG9ydGFsQ29udGV4dCA9IHVzZVBvcnRhbENvbnRleHQoKTtcbiAgY29uc3QgW3BvcnRhbE5vZGUsIHNldFBvcnRhbE5vZGVdID0gUmVhY3QudXNlU3RhdGUobnVsbCk7XG4gIGNvbnN0IHBvcnRhbE5vZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHBvcnRhbE5vZGUgPT0gbnVsbCB8fCBwb3J0YWxOb2RlLnJlbW92ZSgpO1xuICAgICAgLy8gQWxsb3cgdGhlIHN1YnNlcXVlbnQgbGF5b3V0IGVmZmVjdHMgdG8gY3JlYXRlIGEgbmV3IG5vZGUgb24gdXBkYXRlcy5cbiAgICAgIC8vIFRoZSBwb3J0YWwgbm9kZSB3aWxsIHN0aWxsIGJlIGNsZWFuZWQgdXAgb24gdW5tb3VudC5cbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMjQ1NFxuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICBwb3J0YWxOb2RlUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSwgW3BvcnRhbE5vZGVdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICAvLyBXYWl0IGZvciB0aGUgdW5pcXVlSWQgdG8gYmUgZ2VuZXJhdGVkIGJlZm9yZSBjcmVhdGluZyB0aGUgcG9ydGFsIG5vZGUgaW5cbiAgICAvLyBSZWFjdCA8MTggKHVzaW5nIGB1c2VGbG9hdGluZ0lkYCBpbnN0ZWFkIG9mIHRoZSBuYXRpdmUgYHVzZUlkYCkuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2lzc3Vlcy8yNzc4XG4gICAgaWYgKCF1bmlxdWVJZCkgcmV0dXJuO1xuICAgIGlmIChwb3J0YWxOb2RlUmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBjb25zdCBleGlzdGluZ0lkUm9vdCA9IGlkID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpIDogbnVsbDtcbiAgICBpZiAoIWV4aXN0aW5nSWRSb290KSByZXR1cm47XG4gICAgY29uc3Qgc3ViUm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHN1YlJvb3QuaWQgPSB1bmlxdWVJZDtcbiAgICBzdWJSb290LnNldEF0dHJpYnV0ZShhdHRyLCAnJyk7XG4gICAgZXhpc3RpbmdJZFJvb3QuYXBwZW5kQ2hpbGQoc3ViUm9vdCk7XG4gICAgcG9ydGFsTm9kZVJlZi5jdXJyZW50ID0gc3ViUm9vdDtcbiAgICBzZXRQb3J0YWxOb2RlKHN1YlJvb3QpO1xuICB9LCBbaWQsIHVuaXF1ZUlkXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgLy8gV2FpdCBmb3IgdGhlIHJvb3QgdG8gZXhpc3QgYmVmb3JlIGNyZWF0aW5nIHRoZSBwb3J0YWwgbm9kZS4gVGhlIHJvb3QgbXVzdFxuICAgIC8vIGJlIHN0b3JlZCBpbiBzdGF0ZSwgbm90IGEgcmVmLCBmb3IgdGhpcyB0byB3b3JrIHJlYWN0aXZlbHkuXG4gICAgaWYgKHJvb3QgPT09IG51bGwpIHJldHVybjtcbiAgICBpZiAoIXVuaXF1ZUlkKSByZXR1cm47XG4gICAgaWYgKHBvcnRhbE5vZGVSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgIGxldCBjb250YWluZXIgPSByb290IHx8IChwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpO1xuICAgIGlmIChjb250YWluZXIgJiYgIWlzRWxlbWVudChjb250YWluZXIpKSBjb250YWluZXIgPSBjb250YWluZXIuY3VycmVudDtcbiAgICBjb250YWluZXIgPSBjb250YWluZXIgfHwgZG9jdW1lbnQuYm9keTtcbiAgICBsZXQgaWRXcmFwcGVyID0gbnVsbDtcbiAgICBpZiAoaWQpIHtcbiAgICAgIGlkV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgaWRXcmFwcGVyLmlkID0gaWQ7XG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoaWRXcmFwcGVyKTtcbiAgICB9XG4gICAgY29uc3Qgc3ViUm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHN1YlJvb3QuaWQgPSB1bmlxdWVJZDtcbiAgICBzdWJSb290LnNldEF0dHJpYnV0ZShhdHRyLCAnJyk7XG4gICAgY29udGFpbmVyID0gaWRXcmFwcGVyIHx8IGNvbnRhaW5lcjtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoc3ViUm9vdCk7XG4gICAgcG9ydGFsTm9kZVJlZi5jdXJyZW50ID0gc3ViUm9vdDtcbiAgICBzZXRQb3J0YWxOb2RlKHN1YlJvb3QpO1xuICB9LCBbaWQsIHJvb3QsIHVuaXF1ZUlkLCBwb3J0YWxDb250ZXh0XSk7XG4gIHJldHVybiBwb3J0YWxOb2RlO1xufVxuLyoqXG4gKiBQb3J0YWxzIHRoZSBmbG9hdGluZyBlbGVtZW50IGludG8gYSBnaXZlbiBjb250YWluZXIgZWxlbWVudCDigJQgYnkgZGVmYXVsdCxcbiAqIG91dHNpZGUgb2YgdGhlIGFwcCByb290IGFuZCBpbnRvIHRoZSBib2R5LlxuICogVGhpcyBpcyBuZWNlc3NhcnkgdG8gZW5zdXJlIHRoZSBmbG9hdGluZyBlbGVtZW50IGNhbiBhcHBlYXIgb3V0c2lkZSBhbnlcbiAqIHBvdGVudGlhbCBwYXJlbnQgY29udGFpbmVycyB0aGF0IGNhdXNlIGNsaXBwaW5nIChzdWNoIGFzIGBvdmVyZmxvdzogaGlkZGVuYCksXG4gKiB3aGlsZSByZXRhaW5pbmcgaXRzIGxvY2F0aW9uIGluIHRoZSBSZWFjdCB0cmVlLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nUG9ydGFsXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nUG9ydGFsKHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBjaGlsZHJlbixcbiAgICBpZCxcbiAgICByb290LFxuICAgIHByZXNlcnZlVGFiT3JkZXIgPSB0cnVlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgcG9ydGFsTm9kZSA9IHVzZUZsb2F0aW5nUG9ydGFsTm9kZSh7XG4gICAgaWQsXG4gICAgcm9vdFxuICB9KTtcbiAgY29uc3QgW2ZvY3VzTWFuYWdlclN0YXRlLCBzZXRGb2N1c01hbmFnZXJTdGF0ZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3QgYmVmb3JlT3V0c2lkZVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgYWZ0ZXJPdXRzaWRlUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBiZWZvcmVJbnNpZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGFmdGVySW5zaWRlUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBtb2RhbCA9IGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5tb2RhbDtcbiAgY29uc3Qgb3BlbiA9IGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5vcGVuO1xuICBjb25zdCBzaG91bGRSZW5kZXJHdWFyZHMgPVxuICAvLyBUaGUgRm9jdXNNYW5hZ2VyIGFuZCB0aGVyZWZvcmUgZmxvYXRpbmcgZWxlbWVudCBhcmUgY3VycmVudGx5IG9wZW4vXG4gIC8vIHJlbmRlcmVkLlxuICAhIWZvY3VzTWFuYWdlclN0YXRlICYmXG4gIC8vIEd1YXJkcyBhcmUgb25seSBmb3Igbm9uLW1vZGFsIGZvY3VzIG1hbmFnZW1lbnQuXG4gICFmb2N1c01hbmFnZXJTdGF0ZS5tb2RhbCAmJlxuICAvLyBEb24ndCByZW5kZXIgaWYgdW5tb3VudCBpcyB0cmFuc2l0aW9uaW5nLlxuICBmb2N1c01hbmFnZXJTdGF0ZS5vcGVuICYmIHByZXNlcnZlVGFiT3JkZXIgJiYgISEocm9vdCB8fCBwb3J0YWxOb2RlKTtcblxuICAvLyBodHRwczovL2NvZGVzYW5kYm94LmlvL3MvdGFiYmFibGUtcG9ydGFsLWY0dG5nP2ZpbGU9L3NyYy9UYWJiYWJsZVBvcnRhbC50c3hcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXBvcnRhbE5vZGUgfHwgIXByZXNlcnZlVGFiT3JkZXIgfHwgbW9kYWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgZWxlbWVudHMgaW5zaWRlIHRoZSBwb3J0YWwgZWxlbWVudCBhcmUgdGFiYmFibGUgb25seSB3aGVuIHRoZVxuICAgIC8vIHBvcnRhbCBoYXMgYWxyZWFkeSBiZWVuIGZvY3VzZWQsIGVpdGhlciBieSB0YWJiaW5nIGludG8gYSBmb2N1cyB0cmFwXG4gICAgLy8gZWxlbWVudCBvdXRzaWRlIG9yIHVzaW5nIHRoZSBtb3VzZS5cbiAgICBmdW5jdGlvbiBvbkZvY3VzKGV2ZW50KSB7XG4gICAgICBpZiAocG9ydGFsTm9kZSAmJiBpc091dHNpZGVFdmVudChldmVudCkpIHtcbiAgICAgICAgY29uc3QgZm9jdXNpbmcgPSBldmVudC50eXBlID09PSAnZm9jdXNpbic7XG4gICAgICAgIGNvbnN0IG1hbmFnZUZvY3VzID0gZm9jdXNpbmcgPyBlbmFibGVGb2N1c0luc2lkZSA6IGRpc2FibGVGb2N1c0luc2lkZTtcbiAgICAgICAgbWFuYWdlRm9jdXMocG9ydGFsTm9kZSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIExpc3RlbiB0byB0aGUgZXZlbnQgb24gdGhlIGNhcHR1cmUgcGhhc2Ugc28gdGhleSBydW4gYmVmb3JlIHRoZSBmb2N1c1xuICAgIC8vIHRyYXAgZWxlbWVudHMgb25Gb2N1cyBwcm9wIGlzIGNhbGxlZC5cbiAgICBwb3J0YWxOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLCBvbkZvY3VzLCB0cnVlKTtcbiAgICBwb3J0YWxOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0Jywgb25Gb2N1cywgdHJ1ZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHBvcnRhbE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIG9uRm9jdXMsIHRydWUpO1xuICAgICAgcG9ydGFsTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIG9uRm9jdXMsIHRydWUpO1xuICAgIH07XG4gIH0sIFtwb3J0YWxOb2RlLCBwcmVzZXJ2ZVRhYk9yZGVyLCBtb2RhbF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghcG9ydGFsTm9kZSkgcmV0dXJuO1xuICAgIGlmIChvcGVuKSByZXR1cm47XG4gICAgZW5hYmxlRm9jdXNJbnNpZGUocG9ydGFsTm9kZSk7XG4gIH0sIFtvcGVuLCBwb3J0YWxOb2RlXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4cyhQb3J0YWxDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgdmFsdWU6IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICAgIHByZXNlcnZlVGFiT3JkZXIsXG4gICAgICBiZWZvcmVPdXRzaWRlUmVmLFxuICAgICAgYWZ0ZXJPdXRzaWRlUmVmLFxuICAgICAgYmVmb3JlSW5zaWRlUmVmLFxuICAgICAgYWZ0ZXJJbnNpZGVSZWYsXG4gICAgICBwb3J0YWxOb2RlLFxuICAgICAgc2V0Rm9jdXNNYW5hZ2VyU3RhdGVcbiAgICB9KSwgW3ByZXNlcnZlVGFiT3JkZXIsIHBvcnRhbE5vZGVdKSxcbiAgICBjaGlsZHJlbjogW3Nob3VsZFJlbmRlckd1YXJkcyAmJiBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9qc3goRm9jdXNHdWFyZCwge1xuICAgICAgXCJkYXRhLXR5cGVcIjogXCJvdXRzaWRlXCIsXG4gICAgICByZWY6IGJlZm9yZU91dHNpZGVSZWYsXG4gICAgICBvbkZvY3VzOiBldmVudCA9PiB7XG4gICAgICAgIGlmIChpc091dHNpZGVFdmVudChldmVudCwgcG9ydGFsTm9kZSkpIHtcbiAgICAgICAgICB2YXIgX2JlZm9yZUluc2lkZVJlZiRjdXJyO1xuICAgICAgICAgIChfYmVmb3JlSW5zaWRlUmVmJGN1cnIgPSBiZWZvcmVJbnNpZGVSZWYuY3VycmVudCkgPT0gbnVsbCB8fCBfYmVmb3JlSW5zaWRlUmVmJGN1cnIuZm9jdXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBkb21SZWZlcmVuY2UgPSBmb2N1c01hbmFnZXJTdGF0ZSA/IGZvY3VzTWFuYWdlclN0YXRlLmRvbVJlZmVyZW5jZSA6IG51bGw7XG4gICAgICAgICAgY29uc3QgcHJldlRhYmJhYmxlID0gZ2V0UHJldmlvdXNUYWJiYWJsZShkb21SZWZlcmVuY2UpO1xuICAgICAgICAgIHByZXZUYWJiYWJsZSA9PSBudWxsIHx8IHByZXZUYWJiYWJsZS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksIHNob3VsZFJlbmRlckd1YXJkcyAmJiBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9qc3goXCJzcGFuXCIsIHtcbiAgICAgIFwiYXJpYS1vd25zXCI6IHBvcnRhbE5vZGUuaWQsXG4gICAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICAgIH0pLCBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9SZWFjdERPTS5jcmVhdGVQb3J0YWwoY2hpbGRyZW4sIHBvcnRhbE5vZGUpLCBzaG91bGRSZW5kZXJHdWFyZHMgJiYgcG9ydGFsTm9kZSAmJiAvKiNfX1BVUkVfXyovanN4KEZvY3VzR3VhcmQsIHtcbiAgICAgIFwiZGF0YS10eXBlXCI6IFwib3V0c2lkZVwiLFxuICAgICAgcmVmOiBhZnRlck91dHNpZGVSZWYsXG4gICAgICBvbkZvY3VzOiBldmVudCA9PiB7XG4gICAgICAgIGlmIChpc091dHNpZGVFdmVudChldmVudCwgcG9ydGFsTm9kZSkpIHtcbiAgICAgICAgICB2YXIgX2FmdGVySW5zaWRlUmVmJGN1cnJlO1xuICAgICAgICAgIChfYWZ0ZXJJbnNpZGVSZWYkY3VycmUgPSBhZnRlckluc2lkZVJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9hZnRlckluc2lkZVJlZiRjdXJyZS5mb2N1cygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGRvbVJlZmVyZW5jZSA9IGZvY3VzTWFuYWdlclN0YXRlID8gZm9jdXNNYW5hZ2VyU3RhdGUuZG9tUmVmZXJlbmNlIDogbnVsbDtcbiAgICAgICAgICBjb25zdCBuZXh0VGFiYmFibGUgPSBnZXROZXh0VGFiYmFibGUoZG9tUmVmZXJlbmNlKTtcbiAgICAgICAgICBuZXh0VGFiYmFibGUgPT0gbnVsbCB8fCBuZXh0VGFiYmFibGUuZm9jdXMoKTtcbiAgICAgICAgICAoZm9jdXNNYW5hZ2VyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IGZvY3VzTWFuYWdlclN0YXRlLmNsb3NlT25Gb2N1c091dCkgJiYgKGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5vbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnZm9jdXMtb3V0JykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSldXG4gIH0pO1xufVxuY29uc3QgdXNlUG9ydGFsQ29udGV4dCA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoUG9ydGFsQ29udGV4dCk7XG5cbmZ1bmN0aW9uIHVzZUxpdGVNZXJnZVJlZnMocmVmcykge1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIHZhbHVlID0+IHtcbiAgICAgIHJlZnMuZm9yRWFjaChyZWYgPT4ge1xuICAgICAgICBpZiAocmVmKSB7XG4gICAgICAgICAgcmVmLmN1cnJlbnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIHJlZnMpO1xufVxuXG5jb25zdCBMSVNUX0xJTUlUID0gMjA7XG5sZXQgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cyA9IFtdO1xuZnVuY3Rpb24gYWRkUHJldmlvdXNseUZvY3VzZWRFbGVtZW50KGVsZW1lbnQpIHtcbiAgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cyA9IHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMuZmlsdGVyKGVsID0+IGVsLmlzQ29ubmVjdGVkKTtcbiAgaWYgKGVsZW1lbnQgJiYgZ2V0Tm9kZU5hbWUoZWxlbWVudCkgIT09ICdib2R5Jykge1xuICAgIHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICBpZiAocHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5sZW5ndGggPiBMSVNUX0xJTUlUKSB7XG4gICAgICBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnRzID0gcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5zbGljZSgtMjApO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZ2V0UHJldmlvdXNseUZvY3VzZWRFbGVtZW50KCkge1xuICByZXR1cm4gcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5zbGljZSgpLnJldmVyc2UoKS5maW5kKGVsID0+IGVsLmlzQ29ubmVjdGVkKTtcbn1cbmZ1bmN0aW9uIGdldEZpcnN0VGFiYmFibGVFbGVtZW50KGNvbnRhaW5lcikge1xuICBjb25zdCB0YWJiYWJsZU9wdGlvbnMgPSBnZXRUYWJiYWJsZU9wdGlvbnMoKTtcbiAgaWYgKGlzVGFiYmFibGUoY29udGFpbmVyLCB0YWJiYWJsZU9wdGlvbnMpKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgfVxuICByZXR1cm4gdGFiYmFibGUoY29udGFpbmVyLCB0YWJiYWJsZU9wdGlvbnMpWzBdIHx8IGNvbnRhaW5lcjtcbn1cbmZ1bmN0aW9uIGhhbmRsZVRhYkluZGV4KGZsb2F0aW5nRm9jdXNFbGVtZW50LCBvcmRlclJlZikge1xuICB2YXIgX2Zsb2F0aW5nRm9jdXNFbGVtZW50O1xuICBpZiAoIW9yZGVyUmVmLmN1cnJlbnQuaW5jbHVkZXMoJ2Zsb2F0aW5nJykgJiYgISgoX2Zsb2F0aW5nRm9jdXNFbGVtZW50ID0gZmxvYXRpbmdGb2N1c0VsZW1lbnQuZ2V0QXR0cmlidXRlKCdyb2xlJykpICE9IG51bGwgJiYgX2Zsb2F0aW5nRm9jdXNFbGVtZW50LmluY2x1ZGVzKCdkaWFsb2cnKSkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3Qgb3B0aW9ucyA9IGdldFRhYmJhYmxlT3B0aW9ucygpO1xuICBjb25zdCBmb2N1c2FibGVFbGVtZW50cyA9IGZvY3VzYWJsZShmbG9hdGluZ0ZvY3VzRWxlbWVudCwgb3B0aW9ucyk7XG4gIGNvbnN0IHRhYmJhYmxlQ29udGVudCA9IGZvY3VzYWJsZUVsZW1lbnRzLmZpbHRlcihlbGVtZW50ID0+IHtcbiAgICBjb25zdCBkYXRhVGFiSW5kZXggPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS10YWJpbmRleCcpIHx8ICcnO1xuICAgIHJldHVybiBpc1RhYmJhYmxlKGVsZW1lbnQsIG9wdGlvbnMpIHx8IGVsZW1lbnQuaGFzQXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JykgJiYgIWRhdGFUYWJJbmRleC5zdGFydHNXaXRoKCctJyk7XG4gIH0pO1xuICBjb25zdCB0YWJJbmRleCA9IGZsb2F0aW5nRm9jdXNFbGVtZW50LmdldEF0dHJpYnV0ZSgndGFiaW5kZXgnKTtcbiAgaWYgKG9yZGVyUmVmLmN1cnJlbnQuaW5jbHVkZXMoJ2Zsb2F0aW5nJykgfHwgdGFiYmFibGVDb250ZW50Lmxlbmd0aCA9PT0gMCkge1xuICAgIGlmICh0YWJJbmRleCAhPT0gJzAnKSB7XG4gICAgICBmbG9hdGluZ0ZvY3VzRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJzAnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGFiSW5kZXggIT09ICctMScgfHwgZmxvYXRpbmdGb2N1c0VsZW1lbnQuaGFzQXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JykgJiYgZmxvYXRpbmdGb2N1c0VsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JykgIT09ICctMScpIHtcbiAgICBmbG9hdGluZ0ZvY3VzRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJy0xJyk7XG4gICAgZmxvYXRpbmdGb2N1c0VsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JywgJy0xJyk7XG4gIH1cbn1cbmNvbnN0IFZpc3VhbGx5SGlkZGVuRGlzbWlzcyA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIFZpc3VhbGx5SGlkZGVuRGlzbWlzcyhwcm9wcywgcmVmKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KFwiYnV0dG9uXCIsIHtcbiAgICAuLi5wcm9wcyxcbiAgICB0eXBlOiBcImJ1dHRvblwiLFxuICAgIHJlZjogcmVmLFxuICAgIHRhYkluZGV4OiAtMSxcbiAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICB9KTtcbn0pO1xuLyoqXG4gKiBQcm92aWRlcyBmb2N1cyBtYW5hZ2VtZW50IGZvciB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0ZvY3VzTWFuYWdlclxuICovXG5mdW5jdGlvbiBGbG9hdGluZ0ZvY3VzTWFuYWdlcihwcm9wcykge1xuICBjb25zdCB7XG4gICAgY29udGV4dCxcbiAgICBjaGlsZHJlbixcbiAgICBkaXNhYmxlZCA9IGZhbHNlLFxuICAgIG9yZGVyID0gWydjb250ZW50J10sXG4gICAgZ3VhcmRzOiBfZ3VhcmRzID0gdHJ1ZSxcbiAgICBpbml0aWFsRm9jdXMgPSAwLFxuICAgIHJldHVybkZvY3VzID0gdHJ1ZSxcbiAgICByZXN0b3JlRm9jdXMgPSBmYWxzZSxcbiAgICBtb2RhbCA9IHRydWUsXG4gICAgdmlzdWFsbHlIaWRkZW5EaXNtaXNzID0gZmFsc2UsXG4gICAgY2xvc2VPbkZvY3VzT3V0ID0gdHJ1ZSxcbiAgICBvdXRzaWRlRWxlbWVudHNJbmVydCA9IGZhbHNlLFxuICAgIGdldEluc2lkZUVsZW1lbnRzOiBfZ2V0SW5zaWRlRWxlbWVudHMgPSAoKSA9PiBbXVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBldmVudHMsXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50czoge1xuICAgICAgZG9tUmVmZXJlbmNlLFxuICAgICAgZmxvYXRpbmdcbiAgICB9XG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCBnZXROb2RlSWQgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkZmxvYTtcbiAgICByZXR1cm4gKF9kYXRhUmVmJGN1cnJlbnQkZmxvYSA9IGRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JGZsb2Eubm9kZUlkO1xuICB9KTtcbiAgY29uc3QgZ2V0SW5zaWRlRWxlbWVudHMgPSB1c2VFZmZlY3RFdmVudChfZ2V0SW5zaWRlRWxlbWVudHMpO1xuICBjb25zdCBpZ25vcmVJbml0aWFsRm9jdXMgPSB0eXBlb2YgaW5pdGlhbEZvY3VzID09PSAnbnVtYmVyJyAmJiBpbml0aWFsRm9jdXMgPCAwO1xuICAvLyBJZiB0aGUgcmVmZXJlbmNlIGlzIGEgY29tYm9ib3ggYW5kIGlzIHR5cGVhYmxlIChlLmcuIGlucHV0L3RleHRhcmVhKSxcbiAgLy8gdGhlcmUgYXJlIGRpZmZlcmVudCBmb2N1cyBzZW1hbnRpY3MuIFRoZSBndWFyZHMgc2hvdWxkIG5vdCBiZSByZW5kZXJlZCwgYnV0XG4gIC8vIGFyaWEtaGlkZGVuIHNob3VsZCBiZSBhcHBsaWVkIHRvIGFsbCBub2RlcyBzdGlsbC4gRnVydGhlciwgdGhlIHZpc3VhbGx5XG4gIC8vIGhpZGRlbiBkaXNtaXNzIGJ1dHRvbiBzaG91bGQgb25seSBhcHBlYXIgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCwgbm90IHRoZVxuICAvLyBzdGFydC5cbiAgY29uc3QgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID0gaXNUeXBlYWJsZUNvbWJvYm94KGRvbVJlZmVyZW5jZSkgJiYgaWdub3JlSW5pdGlhbEZvY3VzO1xuXG4gIC8vIEZvcmNlIHRoZSBndWFyZHMgdG8gYmUgcmVuZGVyZWQgaWYgdGhlIGBpbmVydGAgYXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gIGNvbnN0IGluZXJ0U3VwcG9ydGVkID0gc3VwcG9ydHNJbmVydCgpO1xuICBjb25zdCBndWFyZHMgPSBpbmVydFN1cHBvcnRlZCA/IF9ndWFyZHMgOiB0cnVlO1xuICBjb25zdCB1c2VJbmVydCA9ICFndWFyZHMgfHwgaW5lcnRTdXBwb3J0ZWQgJiYgb3V0c2lkZUVsZW1lbnRzSW5lcnQ7XG4gIGNvbnN0IG9yZGVyUmVmID0gdXNlTGF0ZXN0UmVmKG9yZGVyKTtcbiAgY29uc3QgaW5pdGlhbEZvY3VzUmVmID0gdXNlTGF0ZXN0UmVmKGluaXRpYWxGb2N1cyk7XG4gIGNvbnN0IHJldHVybkZvY3VzUmVmID0gdXNlTGF0ZXN0UmVmKHJldHVybkZvY3VzKTtcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBwb3J0YWxDb250ZXh0ID0gdXNlUG9ydGFsQ29udGV4dCgpO1xuICBjb25zdCBzdGFydERpc21pc3NCdXR0b25SZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGVuZERpc21pc3NCdXR0b25SZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHByZXZlbnRSZXR1cm5Gb2N1c1JlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGlzUG9pbnRlckRvd25SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB0YWJiYWJsZUluZGV4UmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3QgaXNJbnNpZGVQb3J0YWwgPSBwb3J0YWxDb250ZXh0ICE9IG51bGw7XG4gIGNvbnN0IGZsb2F0aW5nRm9jdXNFbGVtZW50ID0gZ2V0RmxvYXRpbmdGb2N1c0VsZW1lbnQoZmxvYXRpbmcpO1xuICBjb25zdCBnZXRUYWJiYWJsZUNvbnRlbnQgPSB1c2VFZmZlY3RFdmVudChmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgaWYgKGNvbnRhaW5lciA9PT0gdm9pZCAwKSB7XG4gICAgICBjb250YWluZXIgPSBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRhaW5lciA/IHRhYmJhYmxlKGNvbnRhaW5lciwgZ2V0VGFiYmFibGVPcHRpb25zKCkpIDogW107XG4gIH0pO1xuICBjb25zdCBnZXRUYWJiYWJsZUVsZW1lbnRzID0gdXNlRWZmZWN0RXZlbnQoY29udGFpbmVyID0+IHtcbiAgICBjb25zdCBjb250ZW50ID0gZ2V0VGFiYmFibGVDb250ZW50KGNvbnRhaW5lcik7XG4gICAgcmV0dXJuIG9yZGVyUmVmLmN1cnJlbnQubWFwKHR5cGUgPT4ge1xuICAgICAgaWYgKGRvbVJlZmVyZW5jZSAmJiB0eXBlID09PSAncmVmZXJlbmNlJykge1xuICAgICAgICByZXR1cm4gZG9tUmVmZXJlbmNlO1xuICAgICAgfVxuICAgICAgaWYgKGZsb2F0aW5nRm9jdXNFbGVtZW50ICYmIHR5cGUgPT09ICdmbG9hdGluZycpIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0aW5nRm9jdXNFbGVtZW50O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfSkuZmlsdGVyKEJvb2xlYW4pLmZsYXQoKTtcbiAgfSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFtb2RhbCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIG9uS2V5RG93bihldmVudCkge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicpIHtcbiAgICAgICAgLy8gVGhlIGZvY3VzIGd1YXJkcyBoYXZlIG5vdGhpbmcgdG8gZm9jdXMsIHNvIHdlIG5lZWQgdG8gc3RvcCB0aGUgZXZlbnQuXG4gICAgICAgIGlmIChjb250YWlucyQxKGZsb2F0aW5nRm9jdXNFbGVtZW50LCBhY3RpdmVFbGVtZW50KGdldERvY3VtZW50JDEoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSkgJiYgZ2V0VGFiYmFibGVDb250ZW50KCkubGVuZ3RoID09PSAwICYmICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gpIHtcbiAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVscyA9IGdldFRhYmJhYmxlRWxlbWVudHMoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0VGFyZ2V0JDEoZXZlbnQpO1xuICAgICAgICBpZiAob3JkZXJSZWYuY3VycmVudFswXSA9PT0gJ3JlZmVyZW5jZScgJiYgdGFyZ2V0ID09PSBkb21SZWZlcmVuY2UpIHtcbiAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgIGlmIChldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgZW5xdWV1ZUZvY3VzKGVsc1tlbHMubGVuZ3RoIC0gMV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbnF1ZXVlRm9jdXMoZWxzWzFdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yZGVyUmVmLmN1cnJlbnRbMV0gPT09ICdmbG9hdGluZycgJiYgdGFyZ2V0ID09PSBmbG9hdGluZ0ZvY3VzRWxlbWVudCAmJiBldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgICAgZW5xdWV1ZUZvY3VzKGVsc1swXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQkMShmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleURvd24pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93bik7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBkb21SZWZlcmVuY2UsIGZsb2F0aW5nRm9jdXNFbGVtZW50LCBtb2RhbCwgb3JkZXJSZWYsIGlzVW50cmFwcGVkVHlwZWFibGVDb21ib2JveCwgZ2V0VGFiYmFibGVDb250ZW50LCBnZXRUYWJiYWJsZUVsZW1lbnRzXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFmbG9hdGluZykgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIGhhbmRsZUZvY3VzSW4oZXZlbnQpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50KTtcbiAgICAgIGNvbnN0IHRhYmJhYmxlQ29udGVudCA9IGdldFRhYmJhYmxlQ29udGVudCgpO1xuICAgICAgY29uc3QgdGFiYmFibGVJbmRleCA9IHRhYmJhYmxlQ29udGVudC5pbmRleE9mKHRhcmdldCk7XG4gICAgICBpZiAodGFiYmFibGVJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgdGFiYmFibGVJbmRleFJlZi5jdXJyZW50ID0gdGFiYmFibGVJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgZmxvYXRpbmcuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIGhhbmRsZUZvY3VzSW4pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBmbG9hdGluZy5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c2luJywgaGFuZGxlRm9jdXNJbik7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBmbG9hdGluZywgZ2V0VGFiYmFibGVDb250ZW50XSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFjbG9zZU9uRm9jdXNPdXQpIHJldHVybjtcblxuICAgIC8vIEluIFNhZmFyaSwgYnV0dG9ucyBsb3NlIGZvY3VzIHdoZW4gcHJlc3NpbmcgdGhlbS5cbiAgICBmdW5jdGlvbiBoYW5kbGVQb2ludGVyRG93bigpIHtcbiAgICAgIGlzUG9pbnRlckRvd25SZWYuY3VycmVudCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaXNQb2ludGVyRG93blJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaGFuZGxlRm9jdXNPdXRzaWRlKGV2ZW50KSB7XG4gICAgICBjb25zdCByZWxhdGVkVGFyZ2V0ID0gZXZlbnQucmVsYXRlZFRhcmdldDtcbiAgICAgIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBldmVudC5jdXJyZW50VGFyZ2V0O1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICBjb25zdCBub2RlSWQgPSBnZXROb2RlSWQoKTtcbiAgICAgICAgY29uc3QgbW92ZWRUb1VucmVsYXRlZE5vZGUgPSAhKGNvbnRhaW5zJDEoZG9tUmVmZXJlbmNlLCByZWxhdGVkVGFyZ2V0KSB8fCBjb250YWlucyQxKGZsb2F0aW5nLCByZWxhdGVkVGFyZ2V0KSB8fCBjb250YWlucyQxKHJlbGF0ZWRUYXJnZXQsIGZsb2F0aW5nKSB8fCBjb250YWlucyQxKHBvcnRhbENvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSwgcmVsYXRlZFRhcmdldCkgfHwgcmVsYXRlZFRhcmdldCAhPSBudWxsICYmIHJlbGF0ZWRUYXJnZXQuaGFzQXR0cmlidXRlKGNyZWF0ZUF0dHJpYnV0ZSgnZm9jdXMtZ3VhcmQnKSkgfHwgdHJlZSAmJiAoZ2V0Tm9kZUNoaWxkcmVuJDEodHJlZS5ub2Rlc1JlZi5jdXJyZW50LCBub2RlSWQpLmZpbmQobm9kZSA9PiB7XG4gICAgICAgICAgdmFyIF9ub2RlJGNvbnRleHQsIF9ub2RlJGNvbnRleHQyO1xuICAgICAgICAgIHJldHVybiBjb250YWlucyQxKChfbm9kZSRjb250ZXh0ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dC5lbGVtZW50cy5mbG9hdGluZywgcmVsYXRlZFRhcmdldCkgfHwgY29udGFpbnMkMSgoX25vZGUkY29udGV4dDIgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Mi5lbGVtZW50cy5kb21SZWZlcmVuY2UsIHJlbGF0ZWRUYXJnZXQpO1xuICAgICAgICB9KSB8fCBnZXROb2RlQW5jZXN0b3JzKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKS5maW5kKG5vZGUgPT4ge1xuICAgICAgICAgIHZhciBfbm9kZSRjb250ZXh0MywgX25vZGUkY29udGV4dDQsIF9ub2RlJGNvbnRleHQ1O1xuICAgICAgICAgIHJldHVybiBbKF9ub2RlJGNvbnRleHQzID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDMuZWxlbWVudHMuZmxvYXRpbmcsIGdldEZsb2F0aW5nRm9jdXNFbGVtZW50KChfbm9kZSRjb250ZXh0NCA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQ0LmVsZW1lbnRzLmZsb2F0aW5nKV0uaW5jbHVkZXMocmVsYXRlZFRhcmdldCkgfHwgKChfbm9kZSRjb250ZXh0NSA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQ1LmVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgPT09IHJlbGF0ZWRUYXJnZXQ7XG4gICAgICAgIH0pKSk7XG4gICAgICAgIGlmIChjdXJyZW50VGFyZ2V0ID09PSBkb21SZWZlcmVuY2UgJiYgZmxvYXRpbmdGb2N1c0VsZW1lbnQpIHtcbiAgICAgICAgICBoYW5kbGVUYWJJbmRleChmbG9hdGluZ0ZvY3VzRWxlbWVudCwgb3JkZXJSZWYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzdG9yZSBmb2N1cyB0byB0aGUgcHJldmlvdXMgdGFiYmFibGUgZWxlbWVudCBpbmRleCB0byBwcmV2ZW50XG4gICAgICAgIC8vIGZvY3VzIGZyb20gYmVpbmcgbG9zdCBvdXRzaWRlIHRoZSBmbG9hdGluZyB0cmVlLlxuICAgICAgICBpZiAocmVzdG9yZUZvY3VzICYmIG1vdmVkVG9VbnJlbGF0ZWROb2RlICYmIGFjdGl2ZUVsZW1lbnQoZ2V0RG9jdW1lbnQkMShmbG9hdGluZ0ZvY3VzRWxlbWVudCkpID09PSBnZXREb2N1bWVudCQxKGZsb2F0aW5nRm9jdXNFbGVtZW50KS5ib2R5KSB7XG4gICAgICAgICAgLy8gTGV0IGBGbG9hdGluZ1BvcnRhbGAgZWZmZWN0IGtub3dzIHRoYXQgZm9jdXMgaXMgc3RpbGwgaW5zaWRlIHRoZVxuICAgICAgICAgIC8vIGZsb2F0aW5nIHRyZWUuXG4gICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSB7XG4gICAgICAgICAgICBmbG9hdGluZ0ZvY3VzRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBwcmV2VGFiYmFibGVJbmRleCA9IHRhYmJhYmxlSW5kZXhSZWYuY3VycmVudDtcbiAgICAgICAgICBjb25zdCB0YWJiYWJsZUNvbnRlbnQgPSBnZXRUYWJiYWJsZUNvbnRlbnQoKTtcbiAgICAgICAgICBjb25zdCBub2RlVG9Gb2N1cyA9IHRhYmJhYmxlQ29udGVudFtwcmV2VGFiYmFibGVJbmRleF0gfHwgdGFiYmFibGVDb250ZW50W3RhYmJhYmxlQ29udGVudC5sZW5ndGggLSAxXSB8fCBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICAgICAgICBpZiAoaXNIVE1MRWxlbWVudChub2RlVG9Gb2N1cykpIHtcbiAgICAgICAgICAgIG5vZGVUb0ZvY3VzLmZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9jdXMgZGlkIG5vdCBtb3ZlIGluc2lkZSB0aGUgZmxvYXRpbmcgdHJlZSwgYW5kIHRoZXJlIGFyZSBubyB0YWJiYWJsZVxuICAgICAgICAvLyBwb3J0YWwgZ3VhcmRzIHRvIGhhbmRsZSBjbG9zaW5nLlxuICAgICAgICBpZiAoKGlzVW50cmFwcGVkVHlwZWFibGVDb21ib2JveCA/IHRydWUgOiAhbW9kYWwpICYmIHJlbGF0ZWRUYXJnZXQgJiYgbW92ZWRUb1VucmVsYXRlZE5vZGUgJiYgIWlzUG9pbnRlckRvd25SZWYuY3VycmVudCAmJlxuICAgICAgICAvLyBGaXggUmVhY3QgMTggU3RyaWN0IE1vZGUgcmV0dXJuRm9jdXMgZHVlIHRvIGRvdWJsZSByZW5kZXJpbmcuXG4gICAgICAgIHJlbGF0ZWRUYXJnZXQgIT09IGdldFByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCgpKSB7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsICdmb2N1cy1vdXQnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChmbG9hdGluZyAmJiBpc0hUTUxFbGVtZW50KGRvbVJlZmVyZW5jZSkpIHtcbiAgICAgIGRvbVJlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIGhhbmRsZUZvY3VzT3V0c2lkZSk7XG4gICAgICBkb21SZWZlcmVuY2UuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBoYW5kbGVQb2ludGVyRG93bik7XG4gICAgICBmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIGhhbmRsZUZvY3VzT3V0c2lkZSk7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBkb21SZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignZm9jdXNvdXQnLCBoYW5kbGVGb2N1c091dHNpZGUpO1xuICAgICAgICBkb21SZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBoYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGZsb2F0aW5nLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0JywgaGFuZGxlRm9jdXNPdXRzaWRlKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbZGlzYWJsZWQsIGRvbVJlZmVyZW5jZSwgZmxvYXRpbmcsIGZsb2F0aW5nRm9jdXNFbGVtZW50LCBtb2RhbCwgdHJlZSwgcG9ydGFsQ29udGV4dCwgb25PcGVuQ2hhbmdlLCBjbG9zZU9uRm9jdXNPdXQsIHJlc3RvcmVGb2N1cywgZ2V0VGFiYmFibGVDb250ZW50LCBpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gsIGdldE5vZGVJZCwgb3JkZXJSZWZdKTtcbiAgY29uc3QgYmVmb3JlR3VhcmRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGFmdGVyR3VhcmRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IG1lcmdlZEJlZm9yZUd1YXJkUmVmID0gdXNlTGl0ZU1lcmdlUmVmcyhbYmVmb3JlR3VhcmRSZWYsIHBvcnRhbENvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IHBvcnRhbENvbnRleHQuYmVmb3JlSW5zaWRlUmVmXSk7XG4gIGNvbnN0IG1lcmdlZEFmdGVyR3VhcmRSZWYgPSB1c2VMaXRlTWVyZ2VSZWZzKFthZnRlckd1YXJkUmVmLCBwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LmFmdGVySW5zaWRlUmVmXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgdmFyIF9wb3J0YWxDb250ZXh0JHBvcnRhbCwgX2FuY2VzdG9ycyRmaW5kO1xuICAgIGlmIChkaXNhYmxlZCkgcmV0dXJuO1xuICAgIGlmICghZmxvYXRpbmcpIHJldHVybjtcblxuICAgIC8vIERvbid0IGhpZGUgcG9ydGFscyBuZXN0ZWQgd2l0aGluIHRoZSBwYXJlbnQgcG9ydGFsLlxuICAgIGNvbnN0IHBvcnRhbE5vZGVzID0gQXJyYXkuZnJvbSgocG9ydGFsQ29udGV4dCA9PSBudWxsIHx8IChfcG9ydGFsQ29udGV4dCRwb3J0YWwgPSBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpID09IG51bGwgPyB2b2lkIDAgOiBfcG9ydGFsQ29udGV4dCRwb3J0YWwucXVlcnlTZWxlY3RvckFsbChcIltcIiArIGNyZWF0ZUF0dHJpYnV0ZSgncG9ydGFsJykgKyBcIl1cIikpIHx8IFtdKTtcbiAgICBjb25zdCBhbmNlc3RvcnMgPSB0cmVlID8gZ2V0Tm9kZUFuY2VzdG9ycyh0cmVlLm5vZGVzUmVmLmN1cnJlbnQsIGdldE5vZGVJZCgpKSA6IFtdO1xuICAgIGNvbnN0IGFuY2VzdG9yRmxvYXRpbmdOb2RlcyA9IHRyZWUgJiYgIW1vZGFsID8gYW5jZXN0b3JzLm1hcChub2RlID0+IHtcbiAgICAgIHZhciBfbm9kZSRjb250ZXh0NjtcbiAgICAgIHJldHVybiAoX25vZGUkY29udGV4dDYgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Ni5lbGVtZW50cy5mbG9hdGluZztcbiAgICB9KSA6IFtdO1xuICAgIGNvbnN0IHJvb3RBbmNlc3RvckNvbWJvYm94RG9tUmVmZXJlbmNlID0gKF9hbmNlc3RvcnMkZmluZCA9IGFuY2VzdG9ycy5maW5kKG5vZGUgPT4ge1xuICAgICAgdmFyIF9ub2RlJGNvbnRleHQ3O1xuICAgICAgcmV0dXJuIGlzVHlwZWFibGVDb21ib2JveCgoKF9ub2RlJGNvbnRleHQ3ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDcuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSB8fCBudWxsKTtcbiAgICB9KSkgPT0gbnVsbCB8fCAoX2FuY2VzdG9ycyRmaW5kID0gX2FuY2VzdG9ycyRmaW5kLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfYW5jZXN0b3JzJGZpbmQuZWxlbWVudHMuZG9tUmVmZXJlbmNlO1xuICAgIGNvbnN0IGluc2lkZUVsZW1lbnRzID0gW2Zsb2F0aW5nLCByb290QW5jZXN0b3JDb21ib2JveERvbVJlZmVyZW5jZSwgLi4ucG9ydGFsTm9kZXMsIC4uLmFuY2VzdG9yRmxvYXRpbmdOb2RlcywgLi4uZ2V0SW5zaWRlRWxlbWVudHMoKSwgc3RhcnREaXNtaXNzQnV0dG9uUmVmLmN1cnJlbnQsIGVuZERpc21pc3NCdXR0b25SZWYuY3VycmVudCwgYmVmb3JlR3VhcmRSZWYuY3VycmVudCwgYWZ0ZXJHdWFyZFJlZi5jdXJyZW50LCBwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LmJlZm9yZU91dHNpZGVSZWYuY3VycmVudCwgcG9ydGFsQ29udGV4dCA9PSBudWxsID8gdm9pZCAwIDogcG9ydGFsQ29udGV4dC5hZnRlck91dHNpZGVSZWYuY3VycmVudCwgb3JkZXJSZWYuY3VycmVudC5pbmNsdWRlcygncmVmZXJlbmNlJykgfHwgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID8gZG9tUmVmZXJlbmNlIDogbnVsbF0uZmlsdGVyKHggPT4geCAhPSBudWxsKTtcbiAgICBjb25zdCBjbGVhbnVwID0gbW9kYWwgfHwgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID8gbWFya090aGVycyhpbnNpZGVFbGVtZW50cywgIXVzZUluZXJ0LCB1c2VJbmVydCkgOiBtYXJrT3RoZXJzKGluc2lkZUVsZW1lbnRzKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH07XG4gIH0sIFtkaXNhYmxlZCwgZG9tUmVmZXJlbmNlLCBmbG9hdGluZywgbW9kYWwsIG9yZGVyUmVmLCBwb3J0YWxDb250ZXh0LCBpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gsIGd1YXJkcywgdXNlSW5lcnQsIHRyZWUsIGdldE5vZGVJZCwgZ2V0SW5zaWRlRWxlbWVudHNdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIWlzSFRNTEVsZW1lbnQoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSByZXR1cm47XG4gICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQkMShmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgY29uc3QgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50ID0gYWN0aXZlRWxlbWVudChkb2MpO1xuXG4gICAgLy8gV2FpdCBmb3IgYW55IGxheW91dCBlZmZlY3Qgc3RhdGUgc2V0dGVycyB0byBleGVjdXRlIHRvIHNldCBgdGFiSW5kZXhgLlxuICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgIGNvbnN0IGZvY3VzYWJsZUVsZW1lbnRzID0gZ2V0VGFiYmFibGVFbGVtZW50cyhmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgICBjb25zdCBpbml0aWFsRm9jdXNWYWx1ZSA9IGluaXRpYWxGb2N1c1JlZi5jdXJyZW50O1xuICAgICAgY29uc3QgZWxUb0ZvY3VzID0gKHR5cGVvZiBpbml0aWFsRm9jdXNWYWx1ZSA9PT0gJ251bWJlcicgPyBmb2N1c2FibGVFbGVtZW50c1tpbml0aWFsRm9jdXNWYWx1ZV0gOiBpbml0aWFsRm9jdXNWYWx1ZS5jdXJyZW50KSB8fCBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICAgIGNvbnN0IGZvY3VzQWxyZWFkeUluc2lkZUZsb2F0aW5nRWwgPSBjb250YWlucyQxKGZsb2F0aW5nRm9jdXNFbGVtZW50LCBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQpO1xuICAgICAgaWYgKCFpZ25vcmVJbml0aWFsRm9jdXMgJiYgIWZvY3VzQWxyZWFkeUluc2lkZUZsb2F0aW5nRWwgJiYgb3Blbikge1xuICAgICAgICBlbnF1ZXVlRm9jdXMoZWxUb0ZvY3VzLCB7XG4gICAgICAgICAgcHJldmVudFNjcm9sbDogZWxUb0ZvY3VzID09PSBmbG9hdGluZ0ZvY3VzRWxlbWVudFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSwgW2Rpc2FibGVkLCBvcGVuLCBmbG9hdGluZ0ZvY3VzRWxlbWVudCwgaWdub3JlSW5pdGlhbEZvY3VzLCBnZXRUYWJiYWJsZUVsZW1lbnRzLCBpbml0aWFsRm9jdXNSZWZdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIWZsb2F0aW5nRm9jdXNFbGVtZW50KSByZXR1cm47XG4gICAgbGV0IHByZXZlbnRSZXR1cm5Gb2N1c1Njcm9sbCA9IGZhbHNlO1xuICAgIGNvbnN0IGRvYyA9IGdldERvY3VtZW50JDEoZmxvYXRpbmdGb2N1c0VsZW1lbnQpO1xuICAgIGNvbnN0IHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCA9IGFjdGl2ZUVsZW1lbnQoZG9jKTtcbiAgICBhZGRQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQocHJldmlvdXNseUZvY3VzZWRFbGVtZW50KTtcblxuICAgIC8vIERpc21pc3NpbmcgdmlhIG91dHNpZGUgcHJlc3Mgc2hvdWxkIGFsd2F5cyBpZ25vcmUgYHJldHVybkZvY3VzYCB0b1xuICAgIC8vIHByZXZlbnQgdW53YW50ZWQgc2Nyb2xsaW5nLlxuICAgIGZ1bmN0aW9uIG9uT3BlbkNoYW5nZShfcmVmKSB7XG4gICAgICBsZXQge1xuICAgICAgICByZWFzb24sXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBuZXN0ZWRcbiAgICAgIH0gPSBfcmVmO1xuICAgICAgaWYgKFsnaG92ZXInLCAnc2FmZS1wb2x5Z29uJ10uaW5jbHVkZXMocmVhc29uKSAmJiBldmVudC50eXBlID09PSAnbW91c2VsZWF2ZScpIHtcbiAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlYXNvbiAhPT0gJ291dHNpZGUtcHJlc3MnKSByZXR1cm47XG4gICAgICBpZiAobmVzdGVkKSB7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1Njcm9sbCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGlzVmlydHVhbENsaWNrKGV2ZW50KSB8fCBpc1ZpcnR1YWxQb2ludGVyRXZlbnQoZXZlbnQpKSB7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgaXNQcmV2ZW50U2Nyb2xsU3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLmZvY3VzKHtcbiAgICAgICAgICBnZXQgcHJldmVudFNjcm9sbCgpIHtcbiAgICAgICAgICAgIGlzUHJldmVudFNjcm9sbFN1cHBvcnRlZCA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlzUHJldmVudFNjcm9sbFN1cHBvcnRlZCkge1xuICAgICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzU2Nyb2xsID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2ZW50UmV0dXJuRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZXZlbnRzLm9uKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICBjb25zdCBmYWxsYmFja0VsID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBmYWxsYmFja0VsLnNldEF0dHJpYnV0ZSgndGFiaW5kZXgnLCAnLTEnKTtcbiAgICBmYWxsYmFja0VsLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgIE9iamVjdC5hc3NpZ24oZmFsbGJhY2tFbC5zdHlsZSwgSElEREVOX1NUWUxFUyk7XG4gICAgaWYgKGlzSW5zaWRlUG9ydGFsICYmIGRvbVJlZmVyZW5jZSkge1xuICAgICAgZG9tUmVmZXJlbmNlLmluc2VydEFkamFjZW50RWxlbWVudCgnYWZ0ZXJlbmQnLCBmYWxsYmFja0VsKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0UmV0dXJuRWxlbWVudCgpIHtcbiAgICAgIGlmICh0eXBlb2YgcmV0dXJuRm9jdXNSZWYuY3VycmVudCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIGNvbnN0IGVsID0gZG9tUmVmZXJlbmNlIHx8IGdldFByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCgpO1xuICAgICAgICByZXR1cm4gZWwgJiYgZWwuaXNDb25uZWN0ZWQgPyBlbCA6IGZhbGxiYWNrRWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0dXJuRm9jdXNSZWYuY3VycmVudC5jdXJyZW50IHx8IGZhbGxiYWNrRWw7XG4gICAgfVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBldmVudHMub2ZmKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICAgIGNvbnN0IGFjdGl2ZUVsID0gYWN0aXZlRWxlbWVudChkb2MpO1xuICAgICAgY29uc3QgaXNGb2N1c0luc2lkZUZsb2F0aW5nVHJlZSA9IGNvbnRhaW5zJDEoZmxvYXRpbmcsIGFjdGl2ZUVsKSB8fCB0cmVlICYmIGdldE5vZGVDaGlsZHJlbiQxKHRyZWUubm9kZXNSZWYuY3VycmVudCwgZ2V0Tm9kZUlkKCkpLnNvbWUobm9kZSA9PiB7XG4gICAgICAgIHZhciBfbm9kZSRjb250ZXh0ODtcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5zJDEoKF9ub2RlJGNvbnRleHQ4ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDguZWxlbWVudHMuZmxvYXRpbmcsIGFjdGl2ZUVsKTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcmV0dXJuRWxlbWVudCA9IGdldFJldHVybkVsZW1lbnQoKTtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgLy8gVGhpcyBpcyBgcmV0dXJuRWxlbWVudGAsIGlmIGl0J3MgdGFiYmFibGUsIG9yIGl0cyBmaXJzdCB0YWJiYWJsZSBjaGlsZC5cbiAgICAgICAgY29uc3QgdGFiYmFibGVSZXR1cm5FbGVtZW50ID0gZ2V0Rmlyc3RUYWJiYWJsZUVsZW1lbnQocmV0dXJuRWxlbWVudCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICAgICAgICByZXR1cm5Gb2N1c1JlZi5jdXJyZW50ICYmICFwcmV2ZW50UmV0dXJuRm9jdXNSZWYuY3VycmVudCAmJiBpc0hUTUxFbGVtZW50KHRhYmJhYmxlUmV0dXJuRWxlbWVudCkgJiYgKFxuICAgICAgICAvLyBJZiB0aGUgZm9jdXMgbW92ZWQgc29tZXdoZXJlIGVsc2UgYWZ0ZXIgbW91bnQsIGF2b2lkIHJldHVybmluZyBmb2N1c1xuICAgICAgICAvLyBzaW5jZSBpdCBsaWtlbHkgZW50ZXJlZCBhIGRpZmZlcmVudCBlbGVtZW50IHdoaWNoIHNob3VsZCBiZVxuICAgICAgICAvLyByZXNwZWN0ZWQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMjYwN1xuICAgICAgICB0YWJiYWJsZVJldHVybkVsZW1lbnQgIT09IGFjdGl2ZUVsICYmIGFjdGl2ZUVsICE9PSBkb2MuYm9keSA/IGlzRm9jdXNJbnNpZGVGbG9hdGluZ1RyZWUgOiB0cnVlKSkge1xuICAgICAgICAgIHRhYmJhYmxlUmV0dXJuRWxlbWVudC5mb2N1cyh7XG4gICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiBwcmV2ZW50UmV0dXJuRm9jdXNTY3JvbGxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmYWxsYmFja0VsLnJlbW92ZSgpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBmbG9hdGluZywgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIHJldHVybkZvY3VzUmVmLCBkYXRhUmVmLCBldmVudHMsIHRyZWUsIGlzSW5zaWRlUG9ydGFsLCBkb21SZWZlcmVuY2UsIGdldE5vZGVJZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIC8vIFRoZSBgcmV0dXJuRm9jdXNgIGNsZWFudXAgYmVoYXZpb3IgaXMgaW5zaWRlIGEgbWljcm90YXNrOyBlbnN1cmUgd2VcbiAgICAvLyB3YWl0IGZvciBpdCB0byBjb21wbGV0ZSBiZWZvcmUgcmVzZXR0aW5nIHRoZSBmbGFnLlxuICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSk7XG4gIH0sIFtkaXNhYmxlZF0pO1xuXG4gIC8vIFN5bmNocm9uaXplIHRoZSBgY29udGV4dGAgJiBgbW9kYWxgIHZhbHVlIHRvIHRoZSBGbG9hdGluZ1BvcnRhbCBjb250ZXh0LlxuICAvLyBJdCB3aWxsIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCBpdCBuZWVkcyB0byByZW5kZXIgaXRzIG93biBndWFyZHMuXG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFwb3J0YWxDb250ZXh0KSByZXR1cm47XG4gICAgcG9ydGFsQ29udGV4dC5zZXRGb2N1c01hbmFnZXJTdGF0ZSh7XG4gICAgICBtb2RhbCxcbiAgICAgIGNsb3NlT25Gb2N1c091dCxcbiAgICAgIG9wZW4sXG4gICAgICBvbk9wZW5DaGFuZ2UsXG4gICAgICBkb21SZWZlcmVuY2VcbiAgICB9KTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgcG9ydGFsQ29udGV4dC5zZXRGb2N1c01hbmFnZXJTdGF0ZShudWxsKTtcbiAgICB9O1xuICB9LCBbZGlzYWJsZWQsIHBvcnRhbENvbnRleHQsIG1vZGFsLCBvcGVuLCBvbk9wZW5DaGFuZ2UsIGNsb3NlT25Gb2N1c091dCwgZG9tUmVmZXJlbmNlXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFmbG9hdGluZ0ZvY3VzRWxlbWVudCkgcmV0dXJuO1xuICAgIGhhbmRsZVRhYkluZGV4KGZsb2F0aW5nRm9jdXNFbGVtZW50LCBvcmRlclJlZik7XG4gIH0sIFtkaXNhYmxlZCwgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIG9yZGVyUmVmXSk7XG4gIGZ1bmN0aW9uIHJlbmRlckRpc21pc3NCdXR0b24obG9jYXRpb24pIHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIXZpc3VhbGx5SGlkZGVuRGlzbWlzcyB8fCAhbW9kYWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gLyojX19QVVJFX18qL2pzeChWaXN1YWxseUhpZGRlbkRpc21pc3MsIHtcbiAgICAgIHJlZjogbG9jYXRpb24gPT09ICdzdGFydCcgPyBzdGFydERpc21pc3NCdXR0b25SZWYgOiBlbmREaXNtaXNzQnV0dG9uUmVmLFxuICAgICAgb25DbGljazogZXZlbnQgPT4gb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCksXG4gICAgICBjaGlsZHJlbjogdHlwZW9mIHZpc3VhbGx5SGlkZGVuRGlzbWlzcyA9PT0gJ3N0cmluZycgPyB2aXN1YWxseUhpZGRlbkRpc21pc3MgOiAnRGlzbWlzcydcbiAgICB9KTtcbiAgfVxuICBjb25zdCBzaG91bGRSZW5kZXJHdWFyZHMgPSAhZGlzYWJsZWQgJiYgZ3VhcmRzICYmIChtb2RhbCA/ICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggOiB0cnVlKSAmJiAoaXNJbnNpZGVQb3J0YWwgfHwgbW9kYWwpO1xuICByZXR1cm4gLyojX19QVVJFX18qL2pzeHMoRnJhZ21lbnQsIHtcbiAgICBjaGlsZHJlbjogW3Nob3VsZFJlbmRlckd1YXJkcyAmJiAvKiNfX1BVUkVfXyovanN4KEZvY3VzR3VhcmQsIHtcbiAgICAgIFwiZGF0YS10eXBlXCI6IFwiaW5zaWRlXCIsXG4gICAgICByZWY6IG1lcmdlZEJlZm9yZUd1YXJkUmVmLFxuICAgICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgICBpZiAobW9kYWwpIHtcbiAgICAgICAgICBjb25zdCBlbHMgPSBnZXRUYWJiYWJsZUVsZW1lbnRzKCk7XG4gICAgICAgICAgZW5xdWV1ZUZvY3VzKG9yZGVyWzBdID09PSAncmVmZXJlbmNlJyA/IGVsc1swXSA6IGVsc1tlbHMubGVuZ3RoIC0gMV0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBvcnRhbENvbnRleHQgIT0gbnVsbCAmJiBwb3J0YWxDb250ZXh0LnByZXNlcnZlVGFiT3JkZXIgJiYgcG9ydGFsQ29udGV4dC5wb3J0YWxOb2RlKSB7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgICBpZiAoaXNPdXRzaWRlRXZlbnQoZXZlbnQsIHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IG5leHRUYWJiYWJsZSA9IGdldE5leHRUYWJiYWJsZShkb21SZWZlcmVuY2UpO1xuICAgICAgICAgICAgbmV4dFRhYmJhYmxlID09IG51bGwgfHwgbmV4dFRhYmJhYmxlLmZvY3VzKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBfcG9ydGFsQ29udGV4dCRiZWZvcmU7XG4gICAgICAgICAgICAoX3BvcnRhbENvbnRleHQkYmVmb3JlID0gcG9ydGFsQ29udGV4dC5iZWZvcmVPdXRzaWRlUmVmLmN1cnJlbnQpID09IG51bGwgfHwgX3BvcnRhbENvbnRleHQkYmVmb3JlLmZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggJiYgcmVuZGVyRGlzbWlzc0J1dHRvbignc3RhcnQnKSwgY2hpbGRyZW4sIHJlbmRlckRpc21pc3NCdXR0b24oJ2VuZCcpLCBzaG91bGRSZW5kZXJHdWFyZHMgJiYgLyojX19QVVJFX18qL2pzeChGb2N1c0d1YXJkLCB7XG4gICAgICBcImRhdGEtdHlwZVwiOiBcImluc2lkZVwiLFxuICAgICAgcmVmOiBtZXJnZWRBZnRlckd1YXJkUmVmLFxuICAgICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgICBpZiAobW9kYWwpIHtcbiAgICAgICAgICBlbnF1ZXVlRm9jdXMoZ2V0VGFiYmFibGVFbGVtZW50cygpWzBdKTtcbiAgICAgICAgfSBlbHNlIGlmIChwb3J0YWxDb250ZXh0ICE9IG51bGwgJiYgcG9ydGFsQ29udGV4dC5wcmVzZXJ2ZVRhYk9yZGVyICYmIHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSkge1xuICAgICAgICAgIGlmIChjbG9zZU9uRm9jdXNPdXQpIHtcbiAgICAgICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzT3V0c2lkZUV2ZW50KGV2ZW50LCBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2VGFiYmFibGUgPSBnZXRQcmV2aW91c1RhYmJhYmxlKGRvbVJlZmVyZW5jZSk7XG4gICAgICAgICAgICBwcmV2VGFiYmFibGUgPT0gbnVsbCB8fCBwcmV2VGFiYmFibGUuZm9jdXMoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIF9wb3J0YWxDb250ZXh0JGFmdGVyTztcbiAgICAgICAgICAgIChfcG9ydGFsQ29udGV4dCRhZnRlck8gPSBwb3J0YWxDb250ZXh0LmFmdGVyT3V0c2lkZVJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9wb3J0YWxDb250ZXh0JGFmdGVyTy5mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXVxuICB9KTtcbn1cblxubGV0IGxvY2tDb3VudCA9IDA7XG5mdW5jdGlvbiBlbmFibGVTY3JvbGxMb2NrKCkge1xuICBjb25zdCBpc0lPUyA9IC9pUChob25lfGFkfG9kKXxpT1MvLnRlc3QoZ2V0UGxhdGZvcm0oKSk7XG4gIGNvbnN0IGJvZHlTdHlsZSA9IGRvY3VtZW50LmJvZHkuc3R5bGU7XG4gIC8vIFJUTCA8Ym9keT4gc2Nyb2xsYmFyXG4gIGNvbnN0IHNjcm9sbGJhclggPSBNYXRoLnJvdW5kKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0KSArIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xuICBjb25zdCBwYWRkaW5nUHJvcCA9IHNjcm9sbGJhclggPyAncGFkZGluZ0xlZnQnIDogJ3BhZGRpbmdSaWdodCc7XG4gIGNvbnN0IHNjcm9sbGJhcldpZHRoID0gd2luZG93LmlubmVyV2lkdGggLSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gIGNvbnN0IHNjcm9sbFggPSBib2R5U3R5bGUubGVmdCA/IHBhcnNlRmxvYXQoYm9keVN0eWxlLmxlZnQpIDogd2luZG93LnNjcm9sbFg7XG4gIGNvbnN0IHNjcm9sbFkgPSBib2R5U3R5bGUudG9wID8gcGFyc2VGbG9hdChib2R5U3R5bGUudG9wKSA6IHdpbmRvdy5zY3JvbGxZO1xuICBib2R5U3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgaWYgKHNjcm9sbGJhcldpZHRoKSB7XG4gICAgYm9keVN0eWxlW3BhZGRpbmdQcm9wXSA9IHNjcm9sbGJhcldpZHRoICsgXCJweFwiO1xuICB9XG5cbiAgLy8gT25seSBpT1MgZG9lc24ndCByZXNwZWN0IGBvdmVyZmxvdzogaGlkZGVuYCBvbiBkb2N1bWVudC5ib2R5LCBhbmQgdGhpc1xuICAvLyB0ZWNobmlxdWUgaGFzIGZld2VyIHNpZGUgZWZmZWN0cy5cbiAgaWYgKGlzSU9TKSB7XG4gICAgdmFyIF93aW5kb3ckdmlzdWFsVmlld3BvciwgX3dpbmRvdyR2aXN1YWxWaWV3cG9yMjtcbiAgICAvLyBpT1MgMTIgZG9lcyBub3Qgc3VwcG9ydCBgdmlzdWFsVmlld3BvcnRgLlxuICAgIGNvbnN0IG9mZnNldExlZnQgPSAoKF93aW5kb3ckdmlzdWFsVmlld3BvciA9IHdpbmRvdy52aXN1YWxWaWV3cG9ydCkgPT0gbnVsbCA/IHZvaWQgMCA6IF93aW5kb3ckdmlzdWFsVmlld3Bvci5vZmZzZXRMZWZ0KSB8fCAwO1xuICAgIGNvbnN0IG9mZnNldFRvcCA9ICgoX3dpbmRvdyR2aXN1YWxWaWV3cG9yMiA9IHdpbmRvdy52aXN1YWxWaWV3cG9ydCkgPT0gbnVsbCA/IHZvaWQgMCA6IF93aW5kb3ckdmlzdWFsVmlld3BvcjIub2Zmc2V0VG9wKSB8fCAwO1xuICAgIE9iamVjdC5hc3NpZ24oYm9keVN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcbiAgICAgIHRvcDogLShzY3JvbGxZIC0gTWF0aC5mbG9vcihvZmZzZXRUb3ApKSArIFwicHhcIixcbiAgICAgIGxlZnQ6IC0oc2Nyb2xsWCAtIE1hdGguZmxvb3Iob2Zmc2V0TGVmdCkpICsgXCJweFwiLFxuICAgICAgcmlnaHQ6ICcwJ1xuICAgIH0pO1xuICB9XG4gIHJldHVybiAoKSA9PiB7XG4gICAgT2JqZWN0LmFzc2lnbihib2R5U3R5bGUsIHtcbiAgICAgIG92ZXJmbG93OiAnJyxcbiAgICAgIFtwYWRkaW5nUHJvcF06ICcnXG4gICAgfSk7XG4gICAgaWYgKGlzSU9TKSB7XG4gICAgICBPYmplY3QuYXNzaWduKGJvZHlTdHlsZSwge1xuICAgICAgICBwb3NpdGlvbjogJycsXG4gICAgICAgIHRvcDogJycsXG4gICAgICAgIGxlZnQ6ICcnLFxuICAgICAgICByaWdodDogJydcbiAgICAgIH0pO1xuICAgICAgd2luZG93LnNjcm9sbFRvKHNjcm9sbFgsIHNjcm9sbFkpO1xuICAgIH1cbiAgfTtcbn1cbmxldCBjbGVhbnVwID0gKCkgPT4ge307XG5cbi8qKlxuICogUHJvdmlkZXMgYmFzZSBzdHlsaW5nIGZvciBhIGZpeGVkIG92ZXJsYXkgZWxlbWVudCB0byBkaW0gY29udGVudCBvciBibG9ja1xuICogcG9pbnRlciBldmVudHMgYmVoaW5kIGEgZmxvYXRpbmcgZWxlbWVudC5cbiAqIEl0J3MgYSByZWd1bGFyIGA8ZGl2PmAsIHNvIGl0IGNhbiBiZSBzdHlsZWQgdmlhIGFueSBDU1Mgc29sdXRpb24geW91IHByZWZlci5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ092ZXJsYXlcbiAqL1xuY29uc3QgRmxvYXRpbmdPdmVybGF5ID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRmxvYXRpbmdPdmVybGF5KHByb3BzLCByZWYpIHtcbiAgY29uc3Qge1xuICAgIGxvY2tTY3JvbGwgPSBmYWxzZSxcbiAgICAuLi5yZXN0XG4gIH0gPSBwcm9wcztcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWxvY2tTY3JvbGwpIHJldHVybjtcbiAgICBsb2NrQ291bnQrKztcbiAgICBpZiAobG9ja0NvdW50ID09PSAxKSB7XG4gICAgICBjbGVhbnVwID0gZW5hYmxlU2Nyb2xsTG9jaygpO1xuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgbG9ja0NvdW50LS07XG4gICAgICBpZiAobG9ja0NvdW50ID09PSAwKSB7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbbG9ja1Njcm9sbF0pO1xuICByZXR1cm4gLyojX19QVVJFX18qL2pzeChcImRpdlwiLCB7XG4gICAgcmVmOiByZWYsXG4gICAgLi4ucmVzdCxcbiAgICBzdHlsZToge1xuICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICBvdmVyZmxvdzogJ2F1dG8nLFxuICAgICAgdG9wOiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgLi4ucmVzdC5zdHlsZVxuICAgIH1cbiAgfSk7XG59KTtcblxuZnVuY3Rpb24gaXNCdXR0b25UYXJnZXQoZXZlbnQpIHtcbiAgcmV0dXJuIGlzSFRNTEVsZW1lbnQoZXZlbnQudGFyZ2V0KSAmJiBldmVudC50YXJnZXQudGFnTmFtZSA9PT0gJ0JVVFRPTic7XG59XG5mdW5jdGlvbiBpc0FuY2hvclRhcmdldChldmVudCkge1xuICByZXR1cm4gaXNIVE1MRWxlbWVudChldmVudC50YXJnZXQpICYmIGV2ZW50LnRhcmdldC50YWdOYW1lID09PSAnQSc7XG59XG5mdW5jdGlvbiBpc1NwYWNlSWdub3JlZChlbGVtZW50KSB7XG4gIHJldHVybiBpc1R5cGVhYmxlRWxlbWVudChlbGVtZW50KTtcbn1cbi8qKlxuICogT3BlbnMgb3IgY2xvc2VzIHRoZSBmbG9hdGluZyBlbGVtZW50IHdoZW4gY2xpY2tpbmcgdGhlIHJlZmVyZW5jZSBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUNsaWNrXG4gKi9cbmZ1bmN0aW9uIHVzZUNsaWNrKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50czoge1xuICAgICAgZG9tUmVmZXJlbmNlXG4gICAgfVxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIGV2ZW50OiBldmVudE9wdGlvbiA9ICdjbGljaycsXG4gICAgdG9nZ2xlID0gdHJ1ZSxcbiAgICBpZ25vcmVNb3VzZSA9IGZhbHNlLFxuICAgIGtleWJvYXJkSGFuZGxlcnMgPSB0cnVlLFxuICAgIHN0aWNrSWZPcGVuID0gdHJ1ZVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHBvaW50ZXJUeXBlUmVmID0gUmVhY3QudXNlUmVmKCk7XG4gIGNvbnN0IGRpZEtleURvd25SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25Qb2ludGVyRG93bihldmVudCkge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IGV2ZW50LnBvaW50ZXJUeXBlO1xuICAgIH0sXG4gICAgb25Nb3VzZURvd24oZXZlbnQpIHtcbiAgICAgIGNvbnN0IHBvaW50ZXJUeXBlID0gcG9pbnRlclR5cGVSZWYuY3VycmVudDtcblxuICAgICAgLy8gSWdub3JlIGFsbCBidXR0b25zIGV4Y2VwdCBmb3IgdGhlIFwibWFpblwiIGJ1dHRvbi5cbiAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Nb3VzZUV2ZW50L2J1dHRvblxuICAgICAgaWYgKGV2ZW50LmJ1dHRvbiAhPT0gMCkgcmV0dXJuO1xuICAgICAgaWYgKGV2ZW50T3B0aW9uID09PSAnY2xpY2snKSByZXR1cm47XG4gICAgICBpZiAoaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZSwgdHJ1ZSkgJiYgaWdub3JlTW91c2UpIHJldHVybjtcbiAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSAmJiAoZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCAmJiBzdGlja0lmT3BlbiA/IGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgOiB0cnVlKSkge1xuICAgICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnY2xpY2snKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFByZXZlbnQgc3RlYWxpbmcgZm9jdXMgZnJvbSB0aGUgZmxvYXRpbmcgZWxlbWVudFxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgfVxuICAgIH0sXG4gICAgb25DbGljayhldmVudCkge1xuICAgICAgY29uc3QgcG9pbnRlclR5cGUgPSBwb2ludGVyVHlwZVJlZi5jdXJyZW50O1xuICAgICAgaWYgKGV2ZW50T3B0aW9uID09PSAnbW91c2Vkb3duJyAmJiBwb2ludGVyVHlwZVJlZi5jdXJyZW50KSB7XG4gICAgICAgIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlLCB0cnVlKSAmJiBpZ25vcmVNb3VzZSkgcmV0dXJuO1xuICAgICAgaWYgKG9wZW4gJiYgdG9nZ2xlICYmIChkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50ICYmIHN0aWNrSWZPcGVuID8gZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudC50eXBlID09PSAnY2xpY2snIDogdHJ1ZSkpIHtcbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgfVxuICAgIH0sXG4gICAgb25LZXlEb3duKGV2ZW50KSB7XG4gICAgICBwb2ludGVyVHlwZVJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHwgIWtleWJvYXJkSGFuZGxlcnMgfHwgaXNCdXR0b25UYXJnZXQoZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICcgJyAmJiAhaXNTcGFjZUlnbm9yZWQoZG9tUmVmZXJlbmNlKSkge1xuICAgICAgICAvLyBQcmV2ZW50IHNjcm9sbGluZ1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBkaWRLZXlEb3duUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKGlzQW5jaG9yVGFyZ2V0KGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSkge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIG9uS2V5VXAoZXZlbnQpIHtcbiAgICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkIHx8ICFrZXlib2FyZEhhbmRsZXJzIHx8IGlzQnV0dG9uVGFyZ2V0KGV2ZW50KSB8fCBpc1NwYWNlSWdub3JlZChkb21SZWZlcmVuY2UpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICcgJyAmJiBkaWRLZXlEb3duUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgZGlkS2V5RG93blJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSkge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pLCBbZGF0YVJlZiwgZG9tUmVmZXJlbmNlLCBldmVudE9wdGlvbiwgaWdub3JlTW91c2UsIGtleWJvYXJkSGFuZGxlcnMsIG9uT3BlbkNoYW5nZSwgb3Blbiwgc3RpY2tJZk9wZW4sIHRvZ2dsZV0pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiBlbmFibGVkID8ge1xuICAgIHJlZmVyZW5jZVxuICB9IDoge30sIFtlbmFibGVkLCByZWZlcmVuY2VdKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlydHVhbEVsZW1lbnQoZG9tRWxlbWVudCwgZGF0YSkge1xuICBsZXQgb2Zmc2V0WCA9IG51bGw7XG4gIGxldCBvZmZzZXRZID0gbnVsbDtcbiAgbGV0IGlzQXV0b1VwZGF0ZUV2ZW50ID0gZmFsc2U7XG4gIHJldHVybiB7XG4gICAgY29udGV4dEVsZW1lbnQ6IGRvbUVsZW1lbnQgfHwgdW5kZWZpbmVkLFxuICAgIGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIHtcbiAgICAgIHZhciBfZGF0YSRkYXRhUmVmJGN1cnJlbnQ7XG4gICAgICBjb25zdCBkb21SZWN0ID0gKGRvbUVsZW1lbnQgPT0gbnVsbCA/IHZvaWQgMCA6IGRvbUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpIHx8IHtcbiAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgIGhlaWdodDogMCxcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogMFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGlzWEF4aXMgPSBkYXRhLmF4aXMgPT09ICd4JyB8fCBkYXRhLmF4aXMgPT09ICdib3RoJztcbiAgICAgIGNvbnN0IGlzWUF4aXMgPSBkYXRhLmF4aXMgPT09ICd5JyB8fCBkYXRhLmF4aXMgPT09ICdib3RoJztcbiAgICAgIGNvbnN0IGNhblRyYWNrQ3Vyc29yT25BdXRvVXBkYXRlID0gWydtb3VzZWVudGVyJywgJ21vdXNlbW92ZSddLmluY2x1ZGVzKCgoX2RhdGEkZGF0YVJlZiRjdXJyZW50ID0gZGF0YS5kYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGEkZGF0YVJlZiRjdXJyZW50LnR5cGUpIHx8ICcnKSAmJiBkYXRhLnBvaW50ZXJUeXBlICE9PSAndG91Y2gnO1xuICAgICAgbGV0IHdpZHRoID0gZG9tUmVjdC53aWR0aDtcbiAgICAgIGxldCBoZWlnaHQgPSBkb21SZWN0LmhlaWdodDtcbiAgICAgIGxldCB4ID0gZG9tUmVjdC54O1xuICAgICAgbGV0IHkgPSBkb21SZWN0Lnk7XG4gICAgICBpZiAob2Zmc2V0WCA9PSBudWxsICYmIGRhdGEueCAmJiBpc1hBeGlzKSB7XG4gICAgICAgIG9mZnNldFggPSBkb21SZWN0LnggLSBkYXRhLng7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0WSA9PSBudWxsICYmIGRhdGEueSAmJiBpc1lBeGlzKSB7XG4gICAgICAgIG9mZnNldFkgPSBkb21SZWN0LnkgLSBkYXRhLnk7XG4gICAgICB9XG4gICAgICB4IC09IG9mZnNldFggfHwgMDtcbiAgICAgIHkgLT0gb2Zmc2V0WSB8fCAwO1xuICAgICAgd2lkdGggPSAwO1xuICAgICAgaGVpZ2h0ID0gMDtcbiAgICAgIGlmICghaXNBdXRvVXBkYXRlRXZlbnQgfHwgY2FuVHJhY2tDdXJzb3JPbkF1dG9VcGRhdGUpIHtcbiAgICAgICAgd2lkdGggPSBkYXRhLmF4aXMgPT09ICd5JyA/IGRvbVJlY3Qud2lkdGggOiAwO1xuICAgICAgICBoZWlnaHQgPSBkYXRhLmF4aXMgPT09ICd4JyA/IGRvbVJlY3QuaGVpZ2h0IDogMDtcbiAgICAgICAgeCA9IGlzWEF4aXMgJiYgZGF0YS54ICE9IG51bGwgPyBkYXRhLnggOiB4O1xuICAgICAgICB5ID0gaXNZQXhpcyAmJiBkYXRhLnkgIT0gbnVsbCA/IGRhdGEueSA6IHk7XG4gICAgICB9IGVsc2UgaWYgKGlzQXV0b1VwZGF0ZUV2ZW50ICYmICFjYW5UcmFja0N1cnNvck9uQXV0b1VwZGF0ZSkge1xuICAgICAgICBoZWlnaHQgPSBkYXRhLmF4aXMgPT09ICd4JyA/IGRvbVJlY3QuaGVpZ2h0IDogaGVpZ2h0O1xuICAgICAgICB3aWR0aCA9IGRhdGEuYXhpcyA9PT0gJ3knID8gZG9tUmVjdC53aWR0aCA6IHdpZHRoO1xuICAgICAgfVxuICAgICAgaXNBdXRvVXBkYXRlRXZlbnQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodCxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgICAgdG9wOiB5LFxuICAgICAgICByaWdodDogeCArIHdpZHRoLFxuICAgICAgICBib3R0b206IHkgKyBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IHhcbiAgICAgIH07XG4gICAgfVxuICB9O1xufVxuZnVuY3Rpb24gaXNNb3VzZUJhc2VkRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIGV2ZW50ICE9IG51bGwgJiYgZXZlbnQuY2xpZW50WCAhPSBudWxsO1xufVxuLyoqXG4gKiBQb3NpdGlvbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgcmVsYXRpdmUgdG8gYSBjbGllbnQgcG9pbnQgKGluIHRoZSB2aWV3cG9ydCksXG4gKiBzdWNoIGFzIHRoZSBtb3VzZSBwb3NpdGlvbi4gQnkgZGVmYXVsdCwgaXQgZm9sbG93cyB0aGUgbW91c2UgY3Vyc29yLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUNsaWVudFBvaW50XG4gKi9cbmZ1bmN0aW9uIHVzZUNsaWVudFBvaW50KGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBkYXRhUmVmLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICBmbG9hdGluZyxcbiAgICAgIGRvbVJlZmVyZW5jZVxuICAgIH0sXG4gICAgcmVmc1xuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIGF4aXMgPSAnYm90aCcsXG4gICAgeCA9IG51bGwsXG4gICAgeSA9IG51bGxcbiAgfSA9IHByb3BzO1xuICBjb25zdCBpbml0aWFsUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgY2xlYW51cExpc3RlbmVyUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBbcG9pbnRlclR5cGUsIHNldFBvaW50ZXJUeXBlXSA9IFJlYWN0LnVzZVN0YXRlKCk7XG4gIGNvbnN0IFtyZWFjdGl2ZSwgc2V0UmVhY3RpdmVdID0gUmVhY3QudXNlU3RhdGUoW10pO1xuICBjb25zdCBzZXRSZWZlcmVuY2UgPSB1c2VFZmZlY3RFdmVudCgoeCwgeSkgPT4ge1xuICAgIGlmIChpbml0aWFsUmVmLmN1cnJlbnQpIHJldHVybjtcblxuICAgIC8vIFByZXZlbnQgc2V0dGluZyBpZiB0aGUgb3BlbiBldmVudCB3YXMgbm90IGEgbW91c2UtbGlrZSBvbmVcbiAgICAvLyAoZS5nLiBmb2N1cyB0byBvcGVuLCB0aGVuIGhvdmVyIG92ZXIgdGhlIHJlZmVyZW5jZSBlbGVtZW50KS5cbiAgICAvLyBPbmx5IGFwcGx5IGlmIHRoZSBldmVudCBleGlzdHMuXG4gICAgaWYgKGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgJiYgIWlzTW91c2VCYXNlZEV2ZW50KGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlZnMuc2V0UG9zaXRpb25SZWZlcmVuY2UoY3JlYXRlVmlydHVhbEVsZW1lbnQoZG9tUmVmZXJlbmNlLCB7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIGF4aXMsXG4gICAgICBkYXRhUmVmLFxuICAgICAgcG9pbnRlclR5cGVcbiAgICB9KSk7XG4gIH0pO1xuICBjb25zdCBoYW5kbGVSZWZlcmVuY2VFbnRlck9yTW92ZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICBpZiAoeCAhPSBudWxsIHx8IHkgIT0gbnVsbCkgcmV0dXJuO1xuICAgIGlmICghb3Blbikge1xuICAgICAgc2V0UmVmZXJlbmNlKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xuICAgIH0gZWxzZSBpZiAoIWNsZWFudXBMaXN0ZW5lclJlZi5jdXJyZW50KSB7XG4gICAgICAvLyBJZiB0aGVyZSdzIG5vIGNsZWFudXAsIHRoZXJlJ3Mgbm8gbGlzdGVuZXIsIGJ1dCB3ZSB3YW50IHRvIGVuc3VyZVxuICAgICAgLy8gd2UgYWRkIHRoZSBsaXN0ZW5lciBpZiB0aGUgY3Vyc29yIGxhbmRlZCBvbiB0aGUgZmxvYXRpbmcgZWxlbWVudCBhbmRcbiAgICAgIC8vIHRoZW4gYmFjayBvbiB0aGUgcmVmZXJlbmNlIChpLmUuIGl0J3MgaW50ZXJhY3RpdmUpLlxuICAgICAgc2V0UmVhY3RpdmUoW10pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gSWYgdGhlIHBvaW50ZXIgaXMgYSBtb3VzZS1saWtlIHBvaW50ZXIsIHdlIHdhbnQgdG8gY29udGludWUgZm9sbG93aW5nIHRoZVxuICAvLyBtb3VzZSBldmVuIGlmIHRoZSBmbG9hdGluZyBlbGVtZW50IGlzIHRyYW5zaXRpb25pbmcgb3V0LiBPbiB0b3VjaFxuICAvLyBkZXZpY2VzLCB0aGlzIGlzIHVuZGVzaXJhYmxlIGJlY2F1c2UgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2lsbCBtb3ZlIHRvXG4gIC8vIHRoZSBkaXNtaXNzYWwgdG91Y2ggcG9pbnQuXG4gIGNvbnN0IG9wZW5DaGVjayA9IGlzTW91c2VMaWtlUG9pbnRlclR5cGUocG9pbnRlclR5cGUpID8gZmxvYXRpbmcgOiBvcGVuO1xuICBjb25zdCBhZGRMaXN0ZW5lciA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAvLyBFeHBsaWNpdGx5IHNwZWNpZmllZCBgeGAvYHlgIGNvb3JkaW5hdGVzIHNob3VsZG4ndCBhZGQgYSBsaXN0ZW5lci5cbiAgICBpZiAoIW9wZW5DaGVjayB8fCAhZW5hYmxlZCB8fCB4ICE9IG51bGwgfHwgeSAhPSBudWxsKSByZXR1cm47XG4gICAgY29uc3Qgd2luID0gZ2V0V2luZG93KGZsb2F0aW5nKTtcbiAgICBmdW5jdGlvbiBoYW5kbGVNb3VzZU1vdmUoZXZlbnQpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50KTtcbiAgICAgIGlmICghY29udGFpbnMkMShmbG9hdGluZywgdGFyZ2V0KSkge1xuICAgICAgICBzZXRSZWZlcmVuY2UoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgaGFuZGxlTW91c2VNb3ZlKTtcbiAgICAgICAgY2xlYW51cExpc3RlbmVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgfHwgaXNNb3VzZUJhc2VkRXZlbnQoZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCkpIHtcbiAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBoYW5kbGVNb3VzZU1vdmUpO1xuICAgICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGhhbmRsZU1vdXNlTW92ZSk7XG4gICAgICAgIGNsZWFudXBMaXN0ZW5lclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH07XG4gICAgICBjbGVhbnVwTGlzdGVuZXJSZWYuY3VycmVudCA9IGNsZWFudXA7XG4gICAgICByZXR1cm4gY2xlYW51cDtcbiAgICB9XG4gICAgcmVmcy5zZXRQb3NpdGlvblJlZmVyZW5jZShkb21SZWZlcmVuY2UpO1xuICB9LCBbb3BlbkNoZWNrLCBlbmFibGVkLCB4LCB5LCBmbG9hdGluZywgZGF0YVJlZiwgcmVmcywgZG9tUmVmZXJlbmNlLCBzZXRSZWZlcmVuY2VdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gYWRkTGlzdGVuZXIoKTtcbiAgfSwgW2FkZExpc3RlbmVyLCByZWFjdGl2ZV0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChlbmFibGVkICYmICFmbG9hdGluZykge1xuICAgICAgaW5pdGlhbFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgZmxvYXRpbmddKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQgJiYgb3Blbikge1xuICAgICAgaW5pdGlhbFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGVuYWJsZWQgJiYgKHggIT0gbnVsbCB8fCB5ICE9IG51bGwpKSB7XG4gICAgICBpbml0aWFsUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIHNldFJlZmVyZW5jZSh4LCB5KTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCB4LCB5LCBzZXRSZWZlcmVuY2VdKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgZnVuY3Rpb24gc2V0UG9pbnRlclR5cGVSZWYoX3JlZikge1xuICAgICAgbGV0IHtcbiAgICAgICAgcG9pbnRlclR5cGVcbiAgICAgIH0gPSBfcmVmO1xuICAgICAgc2V0UG9pbnRlclR5cGUocG9pbnRlclR5cGUpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb25Qb2ludGVyRG93bjogc2V0UG9pbnRlclR5cGVSZWYsXG4gICAgICBvblBvaW50ZXJFbnRlcjogc2V0UG9pbnRlclR5cGVSZWYsXG4gICAgICBvbk1vdXNlTW92ZTogaGFuZGxlUmVmZXJlbmNlRW50ZXJPck1vdmUsXG4gICAgICBvbk1vdXNlRW50ZXI6IGhhbmRsZVJlZmVyZW5jZUVudGVyT3JNb3ZlXG4gICAgfTtcbiAgfSwgW2hhbmRsZVJlZmVyZW5jZUVudGVyT3JNb3ZlXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZV0pO1xufVxuXG5jb25zdCBidWJibGVIYW5kbGVyS2V5cyA9IHtcbiAgcG9pbnRlcmRvd246ICdvblBvaW50ZXJEb3duJyxcbiAgbW91c2Vkb3duOiAnb25Nb3VzZURvd24nLFxuICBjbGljazogJ29uQ2xpY2snXG59O1xuY29uc3QgY2FwdHVyZUhhbmRsZXJLZXlzID0ge1xuICBwb2ludGVyZG93bjogJ29uUG9pbnRlckRvd25DYXB0dXJlJyxcbiAgbW91c2Vkb3duOiAnb25Nb3VzZURvd25DYXB0dXJlJyxcbiAgY2xpY2s6ICdvbkNsaWNrQ2FwdHVyZSdcbn07XG5jb25zdCBub3JtYWxpemVQcm9wID0gbm9ybWFsaXphYmxlID0+IHtcbiAgdmFyIF9ub3JtYWxpemFibGUkZXNjYXBlSywgX25vcm1hbGl6YWJsZSRvdXRzaWRlO1xuICByZXR1cm4ge1xuICAgIGVzY2FwZUtleTogdHlwZW9mIG5vcm1hbGl6YWJsZSA9PT0gJ2Jvb2xlYW4nID8gbm9ybWFsaXphYmxlIDogKF9ub3JtYWxpemFibGUkZXNjYXBlSyA9IG5vcm1hbGl6YWJsZSA9PSBudWxsID8gdm9pZCAwIDogbm9ybWFsaXphYmxlLmVzY2FwZUtleSkgIT0gbnVsbCA/IF9ub3JtYWxpemFibGUkZXNjYXBlSyA6IGZhbHNlLFxuICAgIG91dHNpZGVQcmVzczogdHlwZW9mIG5vcm1hbGl6YWJsZSA9PT0gJ2Jvb2xlYW4nID8gbm9ybWFsaXphYmxlIDogKF9ub3JtYWxpemFibGUkb3V0c2lkZSA9IG5vcm1hbGl6YWJsZSA9PSBudWxsID8gdm9pZCAwIDogbm9ybWFsaXphYmxlLm91dHNpZGVQcmVzcykgIT0gbnVsbCA/IF9ub3JtYWxpemFibGUkb3V0c2lkZSA6IHRydWVcbiAgfTtcbn07XG4vKipcbiAqIENsb3NlcyB0aGUgZmxvYXRpbmcgZWxlbWVudCB3aGVuIGEgZGlzbWlzc2FsIGlzIHJlcXVlc3RlZCDigJQgYnkgZGVmYXVsdCwgd2hlblxuICogdGhlIHVzZXIgcHJlc3NlcyB0aGUgYGVzY2FwZWAga2V5IG9yIG91dHNpZGUgb2YgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRGlzbWlzc1xuICovXG5mdW5jdGlvbiB1c2VEaXNtaXNzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZGF0YVJlZlxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIGVzY2FwZUtleSA9IHRydWUsXG4gICAgb3V0c2lkZVByZXNzOiB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgPSB0cnVlLFxuICAgIG91dHNpZGVQcmVzc0V2ZW50ID0gJ3BvaW50ZXJkb3duJyxcbiAgICByZWZlcmVuY2VQcmVzcyA9IGZhbHNlLFxuICAgIHJlZmVyZW5jZVByZXNzRXZlbnQgPSAncG9pbnRlcmRvd24nLFxuICAgIGFuY2VzdG9yU2Nyb2xsID0gZmFsc2UsXG4gICAgYnViYmxlcyxcbiAgICBjYXB0dXJlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBvdXRzaWRlUHJlc3NGbiA9IHVzZUVmZmVjdEV2ZW50KHR5cGVvZiB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgPT09ICdmdW5jdGlvbicgPyB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgOiAoKSA9PiBmYWxzZSk7XG4gIGNvbnN0IG91dHNpZGVQcmVzcyA9IHR5cGVvZiB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgPT09ICdmdW5jdGlvbicgPyBvdXRzaWRlUHJlc3NGbiA6IHVuc3RhYmxlX291dHNpZGVQcmVzcztcbiAgY29uc3QgaW5zaWRlUmVhY3RUcmVlUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB7XG4gICAgZXNjYXBlS2V5OiBlc2NhcGVLZXlCdWJibGVzLFxuICAgIG91dHNpZGVQcmVzczogb3V0c2lkZVByZXNzQnViYmxlc1xuICB9ID0gbm9ybWFsaXplUHJvcChidWJibGVzKTtcbiAgY29uc3Qge1xuICAgIGVzY2FwZUtleTogZXNjYXBlS2V5Q2FwdHVyZSxcbiAgICBvdXRzaWRlUHJlc3M6IG91dHNpZGVQcmVzc0NhcHR1cmVcbiAgfSA9IG5vcm1hbGl6ZVByb3AoY2FwdHVyZSk7XG4gIGNvbnN0IGlzQ29tcG9zaW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgY2xvc2VPbkVzY2FwZUtleURvd24gPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkZmxvYTtcbiAgICBpZiAoIW9wZW4gfHwgIWVuYWJsZWQgfHwgIWVzY2FwZUtleSB8fCBldmVudC5rZXkgIT09ICdFc2NhcGUnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gV2FpdCB1bnRpbCBJTUUgaXMgc2V0dGxlZC4gUHJlc3NpbmcgYEVzY2FwZWAgd2hpbGUgY29tcG9zaW5nIHNob3VsZFxuICAgIC8vIGNsb3NlIHRoZSBjb21wb3NlIG1lbnUsIGJ1dCBub3QgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gICAgaWYgKGlzQ29tcG9zaW5nUmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9kZUlkID0gKF9kYXRhUmVmJGN1cnJlbnQkZmxvYSA9IGRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JGZsb2Eubm9kZUlkO1xuICAgIGNvbnN0IGNoaWxkcmVuID0gdHJlZSA/IGdldE5vZGVDaGlsZHJlbiQxKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKSA6IFtdO1xuICAgIGlmICghZXNjYXBlS2V5QnViYmxlcykge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICBsZXQgc2hvdWxkRGlzbWlzcyA9IHRydWU7XG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgIHZhciBfY2hpbGQkY29udGV4dDtcbiAgICAgICAgICBpZiAoKF9jaGlsZCRjb250ZXh0ID0gY2hpbGQuY29udGV4dCkgIT0gbnVsbCAmJiBfY2hpbGQkY29udGV4dC5vcGVuICYmICFjaGlsZC5jb250ZXh0LmRhdGFSZWYuY3VycmVudC5fX2VzY2FwZUtleUJ1YmJsZXMpIHtcbiAgICAgICAgICAgIHNob3VsZERpc21pc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXNob3VsZERpc21pc3MpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBpc1JlYWN0RXZlbnQoZXZlbnQpID8gZXZlbnQubmF0aXZlRXZlbnQgOiBldmVudCwgJ2VzY2FwZS1rZXknKTtcbiAgfSk7XG4gIGNvbnN0IGNsb3NlT25Fc2NhcGVLZXlEb3duQ2FwdHVyZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2dldFRhcmdldDI7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICB2YXIgX2dldFRhcmdldDtcbiAgICAgIGNsb3NlT25Fc2NhcGVLZXlEb3duKGV2ZW50KTtcbiAgICAgIChfZ2V0VGFyZ2V0ID0gZ2V0VGFyZ2V0JDEoZXZlbnQpKSA9PSBudWxsIHx8IF9nZXRUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGNhbGxiYWNrKTtcbiAgICB9O1xuICAgIChfZ2V0VGFyZ2V0MiA9IGdldFRhcmdldCQxKGV2ZW50KSkgPT0gbnVsbCB8fCBfZ2V0VGFyZ2V0Mi5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgY2FsbGJhY2spO1xuICB9KTtcbiAgY29uc3QgY2xvc2VPblByZXNzT3V0c2lkZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2RhdGFSZWYkY3VycmVudCRmbG9hMjtcbiAgICAvLyBHaXZlbiBkZXZlbG9wZXJzIGNhbiBzdG9wIHRoZSBwcm9wYWdhdGlvbiBvZiB0aGUgc3ludGhldGljIGV2ZW50LFxuICAgIC8vIHdlIGNhbiBvbmx5IGJlIGNvbmZpZGVudCB3aXRoIGEgcG9zaXRpdmUgdmFsdWUuXG4gICAgY29uc3QgaW5zaWRlUmVhY3RUcmVlID0gaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQ7XG4gICAgaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQgPSBmYWxzZTtcblxuICAgIC8vIFdoZW4gY2xpY2sgb3V0c2lkZSBpcyBsYXp5IChgY2xpY2tgIGV2ZW50KSwgaGFuZGxlIGRyYWdnaW5nLlxuICAgIC8vIERvbid0IGNsb3NlIGlmOlxuICAgIC8vIC0gVGhlIGNsaWNrIHN0YXJ0ZWQgaW5zaWRlIHRoZSBmbG9hdGluZyBlbGVtZW50LlxuICAgIC8vIC0gVGhlIGNsaWNrIGVuZGVkIGluc2lkZSB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAgICBjb25zdCBlbmRlZE9yU3RhcnRlZEluc2lkZSA9IGVuZGVkT3JTdGFydGVkSW5zaWRlUmVmLmN1cnJlbnQ7XG4gICAgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIGlmIChvdXRzaWRlUHJlc3NFdmVudCA9PT0gJ2NsaWNrJyAmJiBlbmRlZE9yU3RhcnRlZEluc2lkZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaW5zaWRlUmVhY3RUcmVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb3V0c2lkZVByZXNzID09PSAnZnVuY3Rpb24nICYmICFvdXRzaWRlUHJlc3MoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50KTtcbiAgICBjb25zdCBpbmVydFNlbGVjdG9yID0gXCJbXCIgKyBjcmVhdGVBdHRyaWJ1dGUoJ2luZXJ0JykgKyBcIl1cIjtcbiAgICBjb25zdCBtYXJrZXJzID0gZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZykucXVlcnlTZWxlY3RvckFsbChpbmVydFNlbGVjdG9yKTtcbiAgICBsZXQgdGFyZ2V0Um9vdEFuY2VzdG9yID0gaXNFbGVtZW50KHRhcmdldCkgPyB0YXJnZXQgOiBudWxsO1xuICAgIHdoaWxlICh0YXJnZXRSb290QW5jZXN0b3IgJiYgIWlzTGFzdFRyYXZlcnNhYmxlTm9kZSh0YXJnZXRSb290QW5jZXN0b3IpKSB7XG4gICAgICBjb25zdCBuZXh0UGFyZW50ID0gZ2V0UGFyZW50Tm9kZSh0YXJnZXRSb290QW5jZXN0b3IpO1xuICAgICAgaWYgKGlzTGFzdFRyYXZlcnNhYmxlTm9kZShuZXh0UGFyZW50KSB8fCAhaXNFbGVtZW50KG5leHRQYXJlbnQpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdGFyZ2V0Um9vdEFuY2VzdG9yID0gbmV4dFBhcmVudDtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgY2xpY2sgb2NjdXJyZWQgb24gYSB0aGlyZC1wYXJ0eSBlbGVtZW50IGluamVjdGVkIGFmdGVyIHRoZVxuICAgIC8vIGZsb2F0aW5nIGVsZW1lbnQgcmVuZGVyZWQuXG4gICAgaWYgKG1hcmtlcnMubGVuZ3RoICYmIGlzRWxlbWVudCh0YXJnZXQpICYmICFpc1Jvb3RFbGVtZW50KHRhcmdldCkgJiZcbiAgICAvLyBDbGlja2VkIG9uIGEgZGlyZWN0IGFuY2VzdG9yIChlLmcuIEZsb2F0aW5nT3ZlcmxheSkuXG4gICAgIWNvbnRhaW5zJDEodGFyZ2V0LCBlbGVtZW50cy5mbG9hdGluZykgJiZcbiAgICAvLyBJZiB0aGUgdGFyZ2V0IHJvb3QgZWxlbWVudCBjb250YWlucyBub25lIG9mIHRoZSBtYXJrZXJzLCB0aGVuIHRoZVxuICAgIC8vIGVsZW1lbnQgd2FzIGluamVjdGVkIGFmdGVyIHRoZSBmbG9hdGluZyBlbGVtZW50IHJlbmRlcmVkLlxuICAgIEFycmF5LmZyb20obWFya2VycykuZXZlcnkobWFya2VyID0+ICFjb250YWlucyQxKHRhcmdldFJvb3RBbmNlc3RvciwgbWFya2VyKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgY2xpY2sgb2NjdXJyZWQgb24gdGhlIHNjcm9sbGJhclxuICAgIGlmIChpc0hUTUxFbGVtZW50KHRhcmdldCkgJiYgZmxvYXRpbmcpIHtcbiAgICAgIGNvbnN0IGxhc3RUcmF2ZXJzYWJsZU5vZGUgPSBpc0xhc3RUcmF2ZXJzYWJsZU5vZGUodGFyZ2V0KTtcbiAgICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpO1xuICAgICAgY29uc3Qgc2Nyb2xsUmUgPSAvYXV0b3xzY3JvbGwvO1xuICAgICAgY29uc3QgaXNTY3JvbGxhYmxlWCA9IGxhc3RUcmF2ZXJzYWJsZU5vZGUgfHwgc2Nyb2xsUmUudGVzdChzdHlsZS5vdmVyZmxvd1gpO1xuICAgICAgY29uc3QgaXNTY3JvbGxhYmxlWSA9IGxhc3RUcmF2ZXJzYWJsZU5vZGUgfHwgc2Nyb2xsUmUudGVzdChzdHlsZS5vdmVyZmxvd1kpO1xuICAgICAgY29uc3QgY2FuU2Nyb2xsWCA9IGlzU2Nyb2xsYWJsZVggJiYgdGFyZ2V0LmNsaWVudFdpZHRoID4gMCAmJiB0YXJnZXQuc2Nyb2xsV2lkdGggPiB0YXJnZXQuY2xpZW50V2lkdGg7XG4gICAgICBjb25zdCBjYW5TY3JvbGxZID0gaXNTY3JvbGxhYmxlWSAmJiB0YXJnZXQuY2xpZW50SGVpZ2h0ID4gMCAmJiB0YXJnZXQuc2Nyb2xsSGVpZ2h0ID4gdGFyZ2V0LmNsaWVudEhlaWdodDtcbiAgICAgIGNvbnN0IGlzUlRMID0gc3R5bGUuZGlyZWN0aW9uID09PSAncnRsJztcblxuICAgICAgLy8gQ2hlY2sgY2xpY2sgcG9zaXRpb24gcmVsYXRpdmUgdG8gc2Nyb2xsYmFyLlxuICAgICAgLy8gSW4gc29tZSBicm93c2VycyBpdCBpcyBwb3NzaWJsZSB0byBjaGFuZ2UgdGhlIDxib2R5PiAob3Igd2luZG93KVxuICAgICAgLy8gc2Nyb2xsYmFyIHRvIHRoZSBsZWZ0IHNpZGUsIGJ1dCBpcyB2ZXJ5IHJhcmUgYW5kIGlzIGRpZmZpY3VsdCB0b1xuICAgICAgLy8gY2hlY2sgZm9yLiBQbHVzLCBmb3IgbW9kYWwgZGlhbG9ncyB3aXRoIGJhY2tkcm9wcywgaXQgaXMgbW9yZVxuICAgICAgLy8gaW1wb3J0YW50IHRoYXQgdGhlIGJhY2tkcm9wIGlzIGNoZWNrZWQgYnV0IG5vdCBzbyBtdWNoIHRoZSB3aW5kb3cuXG4gICAgICBjb25zdCBwcmVzc2VkVmVydGljYWxTY3JvbGxiYXIgPSBjYW5TY3JvbGxZICYmIChpc1JUTCA/IGV2ZW50Lm9mZnNldFggPD0gdGFyZ2V0Lm9mZnNldFdpZHRoIC0gdGFyZ2V0LmNsaWVudFdpZHRoIDogZXZlbnQub2Zmc2V0WCA+IHRhcmdldC5jbGllbnRXaWR0aCk7XG4gICAgICBjb25zdCBwcmVzc2VkSG9yaXpvbnRhbFNjcm9sbGJhciA9IGNhblNjcm9sbFggJiYgZXZlbnQub2Zmc2V0WSA+IHRhcmdldC5jbGllbnRIZWlnaHQ7XG4gICAgICBpZiAocHJlc3NlZFZlcnRpY2FsU2Nyb2xsYmFyIHx8IHByZXNzZWRIb3Jpem9udGFsU2Nyb2xsYmFyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3Qgbm9kZUlkID0gKF9kYXRhUmVmJGN1cnJlbnQkZmxvYTIgPSBkYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGFSZWYkY3VycmVudCRmbG9hMi5ub2RlSWQ7XG4gICAgY29uc3QgdGFyZ2V0SXNJbnNpZGVDaGlsZHJlbiA9IHRyZWUgJiYgZ2V0Tm9kZUNoaWxkcmVuJDEodHJlZS5ub2Rlc1JlZi5jdXJyZW50LCBub2RlSWQpLnNvbWUobm9kZSA9PiB7XG4gICAgICB2YXIgX25vZGUkY29udGV4dDtcbiAgICAgIHJldHVybiBpc0V2ZW50VGFyZ2V0V2l0aGluKGV2ZW50LCAoX25vZGUkY29udGV4dCA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQuZWxlbWVudHMuZmxvYXRpbmcpO1xuICAgIH0pO1xuICAgIGlmIChpc0V2ZW50VGFyZ2V0V2l0aGluKGV2ZW50LCBlbGVtZW50cy5mbG9hdGluZykgfHwgaXNFdmVudFRhcmdldFdpdGhpbihldmVudCwgZWxlbWVudHMuZG9tUmVmZXJlbmNlKSB8fCB0YXJnZXRJc0luc2lkZUNoaWxkcmVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNoaWxkcmVuID0gdHJlZSA/IGdldE5vZGVDaGlsZHJlbiQxKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKSA6IFtdO1xuICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICBsZXQgc2hvdWxkRGlzbWlzcyA9IHRydWU7XG4gICAgICBjaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAgICAgdmFyIF9jaGlsZCRjb250ZXh0MjtcbiAgICAgICAgaWYgKChfY2hpbGQkY29udGV4dDIgPSBjaGlsZC5jb250ZXh0KSAhPSBudWxsICYmIF9jaGlsZCRjb250ZXh0Mi5vcGVuICYmICFjaGlsZC5jb250ZXh0LmRhdGFSZWYuY3VycmVudC5fX291dHNpZGVQcmVzc0J1YmJsZXMpIHtcbiAgICAgICAgICBzaG91bGREaXNtaXNzID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmICghc2hvdWxkRGlzbWlzcykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsICdvdXRzaWRlLXByZXNzJyk7XG4gIH0pO1xuICBjb25zdCBjbG9zZU9uUHJlc3NPdXRzaWRlQ2FwdHVyZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2dldFRhcmdldDQ7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICB2YXIgX2dldFRhcmdldDM7XG4gICAgICBjbG9zZU9uUHJlc3NPdXRzaWRlKGV2ZW50KTtcbiAgICAgIChfZ2V0VGFyZ2V0MyA9IGdldFRhcmdldCQxKGV2ZW50KSkgPT0gbnVsbCB8fCBfZ2V0VGFyZ2V0My5yZW1vdmVFdmVudExpc3RlbmVyKG91dHNpZGVQcmVzc0V2ZW50LCBjYWxsYmFjayk7XG4gICAgfTtcbiAgICAoX2dldFRhcmdldDQgPSBnZXRUYXJnZXQkMShldmVudCkpID09IG51bGwgfHwgX2dldFRhcmdldDQuYWRkRXZlbnRMaXN0ZW5lcihvdXRzaWRlUHJlc3NFdmVudCwgY2FsbGJhY2spO1xuICB9KTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIW9wZW4gfHwgIWVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGF0YVJlZi5jdXJyZW50Ll9fZXNjYXBlS2V5QnViYmxlcyA9IGVzY2FwZUtleUJ1YmJsZXM7XG4gICAgZGF0YVJlZi5jdXJyZW50Ll9fb3V0c2lkZVByZXNzQnViYmxlcyA9IG91dHNpZGVQcmVzc0J1YmJsZXM7XG4gICAgbGV0IGNvbXBvc2l0aW9uVGltZW91dCA9IC0xO1xuICAgIGZ1bmN0aW9uIG9uU2Nyb2xsKGV2ZW50KSB7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCAnYW5jZXN0b3Itc2Nyb2xsJyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGhhbmRsZUNvbXBvc2l0aW9uU3RhcnQoKSB7XG4gICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KGNvbXBvc2l0aW9uVGltZW91dCk7XG4gICAgICBpc0NvbXBvc2luZ1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaGFuZGxlQ29tcG9zaXRpb25FbmQoKSB7XG4gICAgICAvLyBTYWZhcmkgZmlyZXMgYGNvbXBvc2l0aW9uZW5kYCBiZWZvcmUgYGtleWRvd25gLCBzbyB3ZSBuZWVkIHRvIHdhaXRcbiAgICAgIC8vIHVudGlsIHRoZSBuZXh0IHRpY2sgdG8gc2V0IGBpc0NvbXBvc2luZ2AgdG8gYGZhbHNlYC5cbiAgICAgIC8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNjUwMDRcbiAgICAgIGNvbXBvc2l0aW9uVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaXNDb21wb3NpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIC8vIDBtcyBvciAxbXMgZG9uJ3Qgd29yayBpbiBTYWZhcmkuIDVtcyBhcHBlYXJzIHRvIGNvbnNpc3RlbnRseSB3b3JrLlxuICAgICAgLy8gT25seSBhcHBseSB0byBXZWJLaXQgZm9yIHRoZSB0ZXN0IHRvIHJlbWFpbiAwbXMuXG4gICAgICBpc1dlYktpdCgpID8gNSA6IDApO1xuICAgIH1cbiAgICBjb25zdCBkb2MgPSBnZXREb2N1bWVudCQxKGVsZW1lbnRzLmZsb2F0aW5nKTtcbiAgICBpZiAoZXNjYXBlS2V5KSB7XG4gICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGVzY2FwZUtleUNhcHR1cmUgPyBjbG9zZU9uRXNjYXBlS2V5RG93bkNhcHR1cmUgOiBjbG9zZU9uRXNjYXBlS2V5RG93biwgZXNjYXBlS2V5Q2FwdHVyZSk7XG4gICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25zdGFydCcsIGhhbmRsZUNvbXBvc2l0aW9uU3RhcnQpO1xuICAgICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbXBvc2l0aW9uZW5kJywgaGFuZGxlQ29tcG9zaXRpb25FbmQpO1xuICAgIH1cbiAgICBvdXRzaWRlUHJlc3MgJiYgZG9jLmFkZEV2ZW50TGlzdGVuZXIob3V0c2lkZVByZXNzRXZlbnQsIG91dHNpZGVQcmVzc0NhcHR1cmUgPyBjbG9zZU9uUHJlc3NPdXRzaWRlQ2FwdHVyZSA6IGNsb3NlT25QcmVzc091dHNpZGUsIG91dHNpZGVQcmVzc0NhcHR1cmUpO1xuICAgIGxldCBhbmNlc3RvcnMgPSBbXTtcbiAgICBpZiAoYW5jZXN0b3JTY3JvbGwpIHtcbiAgICAgIGlmIChpc0VsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgICBhbmNlc3RvcnMgPSBnZXRPdmVyZmxvd0FuY2VzdG9ycyhlbGVtZW50cy5kb21SZWZlcmVuY2UpO1xuICAgICAgfVxuICAgICAgaWYgKGlzRWxlbWVudChlbGVtZW50cy5mbG9hdGluZykpIHtcbiAgICAgICAgYW5jZXN0b3JzID0gYW5jZXN0b3JzLmNvbmNhdChnZXRPdmVyZmxvd0FuY2VzdG9ycyhlbGVtZW50cy5mbG9hdGluZykpO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0VsZW1lbnQoZWxlbWVudHMucmVmZXJlbmNlKSAmJiBlbGVtZW50cy5yZWZlcmVuY2UgJiYgZWxlbWVudHMucmVmZXJlbmNlLmNvbnRleHRFbGVtZW50KSB7XG4gICAgICAgIGFuY2VzdG9ycyA9IGFuY2VzdG9ycy5jb25jYXQoZ2V0T3ZlcmZsb3dBbmNlc3RvcnMoZWxlbWVudHMucmVmZXJlbmNlLmNvbnRleHRFbGVtZW50KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWdub3JlIHRoZSB2aXN1YWwgdmlld3BvcnQgZm9yIHNjcm9sbGluZyBkaXNtaXNzYWwgKGFsbG93IHBpbmNoLXpvb20pXG4gICAgYW5jZXN0b3JzID0gYW5jZXN0b3JzLmZpbHRlcihhbmNlc3RvciA9PiB7XG4gICAgICB2YXIgX2RvYyRkZWZhdWx0VmlldztcbiAgICAgIHJldHVybiBhbmNlc3RvciAhPT0gKChfZG9jJGRlZmF1bHRWaWV3ID0gZG9jLmRlZmF1bHRWaWV3KSA9PSBudWxsID8gdm9pZCAwIDogX2RvYyRkZWZhdWx0Vmlldy52aXN1YWxWaWV3cG9ydCk7XG4gICAgfSk7XG4gICAgYW5jZXN0b3JzLmZvckVhY2goYW5jZXN0b3IgPT4ge1xuICAgICAgYW5jZXN0b3IuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgb25TY3JvbGwsIHtcbiAgICAgICAgcGFzc2l2ZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmIChlc2NhcGVLZXkpIHtcbiAgICAgICAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBlc2NhcGVLZXlDYXB0dXJlID8gY2xvc2VPbkVzY2FwZUtleURvd25DYXB0dXJlIDogY2xvc2VPbkVzY2FwZUtleURvd24sIGVzY2FwZUtleUNhcHR1cmUpO1xuICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25zdGFydCcsIGhhbmRsZUNvbXBvc2l0aW9uU3RhcnQpO1xuICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25lbmQnLCBoYW5kbGVDb21wb3NpdGlvbkVuZCk7XG4gICAgICB9XG4gICAgICBvdXRzaWRlUHJlc3MgJiYgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIob3V0c2lkZVByZXNzRXZlbnQsIG91dHNpZGVQcmVzc0NhcHR1cmUgPyBjbG9zZU9uUHJlc3NPdXRzaWRlQ2FwdHVyZSA6IGNsb3NlT25QcmVzc091dHNpZGUsIG91dHNpZGVQcmVzc0NhcHR1cmUpO1xuICAgICAgYW5jZXN0b3JzLmZvckVhY2goYW5jZXN0b3IgPT4ge1xuICAgICAgICBhbmNlc3Rvci5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCk7XG4gICAgICB9KTtcbiAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQoY29tcG9zaXRpb25UaW1lb3V0KTtcbiAgICB9O1xuICB9LCBbZGF0YVJlZiwgZWxlbWVudHMsIGVzY2FwZUtleSwgb3V0c2lkZVByZXNzLCBvdXRzaWRlUHJlc3NFdmVudCwgb3Blbiwgb25PcGVuQ2hhbmdlLCBhbmNlc3RvclNjcm9sbCwgZW5hYmxlZCwgZXNjYXBlS2V5QnViYmxlcywgb3V0c2lkZVByZXNzQnViYmxlcywgY2xvc2VPbkVzY2FwZUtleURvd24sIGVzY2FwZUtleUNhcHR1cmUsIGNsb3NlT25Fc2NhcGVLZXlEb3duQ2FwdHVyZSwgY2xvc2VPblByZXNzT3V0c2lkZSwgb3V0c2lkZVByZXNzQ2FwdHVyZSwgY2xvc2VPblByZXNzT3V0c2lkZUNhcHR1cmVdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpbnNpZGVSZWFjdFRyZWVSZWYuY3VycmVudCA9IGZhbHNlO1xuICB9LCBbb3V0c2lkZVByZXNzLCBvdXRzaWRlUHJlc3NFdmVudF0pO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25LZXlEb3duOiBjbG9zZU9uRXNjYXBlS2V5RG93bixcbiAgICAuLi4ocmVmZXJlbmNlUHJlc3MgJiYge1xuICAgICAgW2J1YmJsZUhhbmRsZXJLZXlzW3JlZmVyZW5jZVByZXNzRXZlbnRdXTogZXZlbnQgPT4ge1xuICAgICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAncmVmZXJlbmNlLXByZXNzJyk7XG4gICAgICB9LFxuICAgICAgLi4uKHJlZmVyZW5jZVByZXNzRXZlbnQgIT09ICdjbGljaycgJiYge1xuICAgICAgICBvbkNsaWNrKGV2ZW50KSB7XG4gICAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ3JlZmVyZW5jZS1wcmVzcycpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH0pLCBbY2xvc2VPbkVzY2FwZUtleURvd24sIG9uT3BlbkNoYW5nZSwgcmVmZXJlbmNlUHJlc3MsIHJlZmVyZW5jZVByZXNzRXZlbnRdKTtcbiAgY29uc3QgZmxvYXRpbmcgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25LZXlEb3duOiBjbG9zZU9uRXNjYXBlS2V5RG93bixcbiAgICBvbk1vdXNlRG93bigpIHtcbiAgICAgIGVuZGVkT3JTdGFydGVkSW5zaWRlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH0sXG4gICAgb25Nb3VzZVVwKCkge1xuICAgICAgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSxcbiAgICBbY2FwdHVyZUhhbmRsZXJLZXlzW291dHNpZGVQcmVzc0V2ZW50XV06ICgpID0+IHtcbiAgICAgIGluc2lkZVJlYWN0VHJlZVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0pLCBbY2xvc2VPbkVzY2FwZUtleURvd24sIG91dHNpZGVQcmVzc0V2ZW50XSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZSwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gdXNlRmxvYXRpbmdSb290Q29udGV4dChvcHRpb25zKSB7XG4gIGNvbnN0IHtcbiAgICBvcGVuID0gZmFsc2UsXG4gICAgb25PcGVuQ2hhbmdlOiBvbk9wZW5DaGFuZ2VQcm9wLFxuICAgIGVsZW1lbnRzOiBlbGVtZW50c1Byb3BcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGZsb2F0aW5nSWQgPSB1c2VJZCgpO1xuICBjb25zdCBkYXRhUmVmID0gUmVhY3QudXNlUmVmKHt9KTtcbiAgY29uc3QgW2V2ZW50c10gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBjcmVhdGVFdmVudEVtaXR0ZXIoKSk7XG4gIGNvbnN0IG5lc3RlZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCkgIT0gbnVsbDtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgIGNvbnN0IG9wdGlvbkRvbVJlZmVyZW5jZSA9IGVsZW1lbnRzUHJvcC5yZWZlcmVuY2U7XG4gICAgaWYgKG9wdGlvbkRvbVJlZmVyZW5jZSAmJiAhaXNFbGVtZW50KG9wdGlvbkRvbVJlZmVyZW5jZSkpIHtcbiAgICAgIGVycm9yKCdDYW5ub3QgcGFzcyBhIHZpcnR1YWwgZWxlbWVudCB0byB0aGUgYGVsZW1lbnRzLnJlZmVyZW5jZWAgb3B0aW9uLCcsICdhcyBpdCBtdXN0IGJlIGEgcmVhbCBET00gZWxlbWVudC4gVXNlIGByZWZzLnNldFBvc2l0aW9uUmVmZXJlbmNlKClgJywgJ2luc3RlYWQuJyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IFtwb3NpdGlvblJlZmVyZW5jZSwgc2V0UG9zaXRpb25SZWZlcmVuY2VdID0gUmVhY3QudXNlU3RhdGUoZWxlbWVudHNQcm9wLnJlZmVyZW5jZSk7XG4gIGNvbnN0IG9uT3BlbkNoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KChvcGVuLCBldmVudCwgcmVhc29uKSA9PiB7XG4gICAgZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCA9IG9wZW4gPyBldmVudCA6IHVuZGVmaW5lZDtcbiAgICBldmVudHMuZW1pdCgnb3BlbmNoYW5nZScsIHtcbiAgICAgIG9wZW4sXG4gICAgICBldmVudCxcbiAgICAgIHJlYXNvbixcbiAgICAgIG5lc3RlZFxuICAgIH0pO1xuICAgIG9uT3BlbkNoYW5nZVByb3AgPT0gbnVsbCB8fCBvbk9wZW5DaGFuZ2VQcm9wKG9wZW4sIGV2ZW50LCByZWFzb24pO1xuICB9KTtcbiAgY29uc3QgcmVmcyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBzZXRQb3NpdGlvblJlZmVyZW5jZVxuICB9KSwgW10pO1xuICBjb25zdCBlbGVtZW50cyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICByZWZlcmVuY2U6IHBvc2l0aW9uUmVmZXJlbmNlIHx8IGVsZW1lbnRzUHJvcC5yZWZlcmVuY2UgfHwgbnVsbCxcbiAgICBmbG9hdGluZzogZWxlbWVudHNQcm9wLmZsb2F0aW5nIHx8IG51bGwsXG4gICAgZG9tUmVmZXJlbmNlOiBlbGVtZW50c1Byb3AucmVmZXJlbmNlXG4gIH0pLCBbcG9zaXRpb25SZWZlcmVuY2UsIGVsZW1lbnRzUHJvcC5yZWZlcmVuY2UsIGVsZW1lbnRzUHJvcC5mbG9hdGluZ10pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIGRhdGFSZWYsXG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZXZlbnRzLFxuICAgIGZsb2F0aW5nSWQsXG4gICAgcmVmc1xuICB9KSwgW29wZW4sIG9uT3BlbkNoYW5nZSwgZWxlbWVudHMsIGV2ZW50cywgZmxvYXRpbmdJZCwgcmVmc10pO1xufVxuXG4vKipcbiAqIFByb3ZpZGVzIGRhdGEgdG8gcG9zaXRpb24gYSBmbG9hdGluZyBlbGVtZW50IGFuZCBjb250ZXh0IHRvIGFkZCBpbnRlcmFjdGlvbnMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRmxvYXRpbmdcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmcob3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBub2RlSWRcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGludGVybmFsUm9vdENvbnRleHQgPSB1c2VGbG9hdGluZ1Jvb3RDb250ZXh0KHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICByZWZlcmVuY2U6IG51bGwsXG4gICAgICBmbG9hdGluZzogbnVsbCxcbiAgICAgIC4uLm9wdGlvbnMuZWxlbWVudHNcbiAgICB9XG4gIH0pO1xuICBjb25zdCByb290Q29udGV4dCA9IG9wdGlvbnMucm9vdENvbnRleHQgfHwgaW50ZXJuYWxSb290Q29udGV4dDtcbiAgY29uc3QgY29tcHV0ZWRFbGVtZW50cyA9IHJvb3RDb250ZXh0LmVsZW1lbnRzO1xuICBjb25zdCBbX2RvbVJlZmVyZW5jZSwgc2V0RG9tUmVmZXJlbmNlXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpO1xuICBjb25zdCBbcG9zaXRpb25SZWZlcmVuY2UsIF9zZXRQb3NpdGlvblJlZmVyZW5jZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3Qgb3B0aW9uRG9tUmVmZXJlbmNlID0gY29tcHV0ZWRFbGVtZW50cyA9PSBudWxsID8gdm9pZCAwIDogY29tcHV0ZWRFbGVtZW50cy5kb21SZWZlcmVuY2U7XG4gIGNvbnN0IGRvbVJlZmVyZW5jZSA9IG9wdGlvbkRvbVJlZmVyZW5jZSB8fCBfZG9tUmVmZXJlbmNlO1xuICBjb25zdCBkb21SZWZlcmVuY2VSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZG9tUmVmZXJlbmNlKSB7XG4gICAgICBkb21SZWZlcmVuY2VSZWYuY3VycmVudCA9IGRvbVJlZmVyZW5jZTtcbiAgICB9XG4gIH0sIFtkb21SZWZlcmVuY2VdKTtcbiAgY29uc3QgcG9zaXRpb24gPSB1c2VGbG9hdGluZyQxKHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICAuLi5jb21wdXRlZEVsZW1lbnRzLFxuICAgICAgLi4uKHBvc2l0aW9uUmVmZXJlbmNlICYmIHtcbiAgICAgICAgcmVmZXJlbmNlOiBwb3NpdGlvblJlZmVyZW5jZVxuICAgICAgfSlcbiAgICB9XG4gIH0pO1xuICBjb25zdCBzZXRQb3NpdGlvblJlZmVyZW5jZSA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIGNvbnN0IGNvbXB1dGVkUG9zaXRpb25SZWZlcmVuY2UgPSBpc0VsZW1lbnQobm9kZSkgPyB7XG4gICAgICBnZXRCb3VuZGluZ0NsaWVudFJlY3Q6ICgpID0+IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICBnZXRDbGllbnRSZWN0czogKCkgPT4gbm9kZS5nZXRDbGllbnRSZWN0cygpLFxuICAgICAgY29udGV4dEVsZW1lbnQ6IG5vZGVcbiAgICB9IDogbm9kZTtcbiAgICAvLyBTdG9yZSB0aGUgcG9zaXRpb25SZWZlcmVuY2UgaW4gc3RhdGUgaWYgdGhlIERPTSByZWZlcmVuY2UgaXMgc3BlY2lmaWVkIGV4dGVybmFsbHkgdmlhIHRoZVxuICAgIC8vIGBlbGVtZW50cy5yZWZlcmVuY2VgIG9wdGlvbi4gVGhpcyBlbnN1cmVzIHRoYXQgaXQgd29uJ3QgYmUgb3ZlcnJpZGRlbiBvbiBmdXR1cmUgcmVuZGVycy5cbiAgICBfc2V0UG9zaXRpb25SZWZlcmVuY2UoY29tcHV0ZWRQb3NpdGlvblJlZmVyZW5jZSk7XG4gICAgcG9zaXRpb24ucmVmcy5zZXRSZWZlcmVuY2UoY29tcHV0ZWRQb3NpdGlvblJlZmVyZW5jZSk7XG4gIH0sIFtwb3NpdGlvbi5yZWZzXSk7XG4gIGNvbnN0IHNldFJlZmVyZW5jZSA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIGlmIChpc0VsZW1lbnQobm9kZSkgfHwgbm9kZSA9PT0gbnVsbCkge1xuICAgICAgZG9tUmVmZXJlbmNlUmVmLmN1cnJlbnQgPSBub2RlO1xuICAgICAgc2V0RG9tUmVmZXJlbmNlKG5vZGUpO1xuICAgIH1cblxuICAgIC8vIEJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IGZvciBwYXNzaW5nIGEgdmlydHVhbCBlbGVtZW50IHRvIGByZWZlcmVuY2VgXG4gICAgLy8gYWZ0ZXIgaXQgaGFzIHNldCB0aGUgRE9NIHJlZmVyZW5jZS5cbiAgICBpZiAoaXNFbGVtZW50KHBvc2l0aW9uLnJlZnMucmVmZXJlbmNlLmN1cnJlbnQpIHx8IHBvc2l0aW9uLnJlZnMucmVmZXJlbmNlLmN1cnJlbnQgPT09IG51bGwgfHxcbiAgICAvLyBEb24ndCBhbGxvdyBzZXR0aW5nIHZpcnR1YWwgZWxlbWVudHMgdXNpbmcgdGhlIG9sZCB0ZWNobmlxdWUgYmFjayB0b1xuICAgIC8vIGBudWxsYCB0byBzdXBwb3J0IGBwb3NpdGlvblJlZmVyZW5jZWAgKyBhbiB1bnN0YWJsZSBgcmVmZXJlbmNlYFxuICAgIC8vIGNhbGxiYWNrIHJlZi5cbiAgICBub2RlICE9PSBudWxsICYmICFpc0VsZW1lbnQobm9kZSkpIHtcbiAgICAgIHBvc2l0aW9uLnJlZnMuc2V0UmVmZXJlbmNlKG5vZGUpO1xuICAgIH1cbiAgfSwgW3Bvc2l0aW9uLnJlZnNdKTtcbiAgY29uc3QgcmVmcyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICAuLi5wb3NpdGlvbi5yZWZzLFxuICAgIHNldFJlZmVyZW5jZSxcbiAgICBzZXRQb3NpdGlvblJlZmVyZW5jZSxcbiAgICBkb21SZWZlcmVuY2U6IGRvbVJlZmVyZW5jZVJlZlxuICB9KSwgW3Bvc2l0aW9uLnJlZnMsIHNldFJlZmVyZW5jZSwgc2V0UG9zaXRpb25SZWZlcmVuY2VdKTtcbiAgY29uc3QgZWxlbWVudHMgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24uZWxlbWVudHMsXG4gICAgZG9tUmVmZXJlbmNlOiBkb21SZWZlcmVuY2VcbiAgfSksIFtwb3NpdGlvbi5lbGVtZW50cywgZG9tUmVmZXJlbmNlXSk7XG4gIGNvbnN0IGNvbnRleHQgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24sXG4gICAgLi4ucm9vdENvbnRleHQsXG4gICAgcmVmcyxcbiAgICBlbGVtZW50cyxcbiAgICBub2RlSWRcbiAgfSksIFtwb3NpdGlvbiwgcmVmcywgZWxlbWVudHMsIG5vZGVJZCwgcm9vdENvbnRleHRdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICByb290Q29udGV4dC5kYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0ID0gY29udGV4dDtcbiAgICBjb25zdCBub2RlID0gdHJlZSA9PSBudWxsID8gdm9pZCAwIDogdHJlZS5ub2Rlc1JlZi5jdXJyZW50LmZpbmQobm9kZSA9PiBub2RlLmlkID09PSBub2RlSWQpO1xuICAgIGlmIChub2RlKSB7XG4gICAgICBub2RlLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24sXG4gICAgY29udGV4dCxcbiAgICByZWZzLFxuICAgIGVsZW1lbnRzXG4gIH0pLCBbcG9zaXRpb24sIHJlZnMsIGVsZW1lbnRzLCBjb250ZXh0XSk7XG59XG5cbmZ1bmN0aW9uIGlzTWFjU2FmYXJpKCkge1xuICByZXR1cm4gaXNNYWMoKSAmJiBpc1NhZmFyaSgpO1xufVxuLyoqXG4gKiBPcGVucyB0aGUgZmxvYXRpbmcgZWxlbWVudCB3aGlsZSB0aGUgcmVmZXJlbmNlIGVsZW1lbnQgaGFzIGZvY3VzLCBsaWtlIENTU1xuICogYDpmb2N1c2AuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRm9jdXNcbiAqL1xuZnVuY3Rpb24gdXNlRm9jdXMoY29udGV4dCwgcHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBldmVudHMsXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50c1xuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIHZpc2libGVPbmx5ID0gdHJ1ZVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGJsb2NrRm9jdXNSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB0aW1lb3V0UmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3Qga2V5Ym9hcmRNb2RhbGl0eVJlZiA9IFJlYWN0LnVzZVJlZih0cnVlKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBjb25zdCB3aW4gPSBnZXRXaW5kb3coZWxlbWVudHMuZG9tUmVmZXJlbmNlKTtcblxuICAgIC8vIElmIHRoZSByZWZlcmVuY2Ugd2FzIGZvY3VzZWQgYW5kIHRoZSB1c2VyIGxlZnQgdGhlIHRhYi93aW5kb3csIGFuZCB0aGVcbiAgICAvLyBmbG9hdGluZyBlbGVtZW50IHdhcyBub3Qgb3BlbiwgdGhlIGZvY3VzIHNob3VsZCBiZSBibG9ja2VkIHdoZW4gdGhleVxuICAgIC8vIHJldHVybiB0byB0aGUgdGFiL3dpbmRvdy5cbiAgICBmdW5jdGlvbiBvbkJsdXIoKSB7XG4gICAgICBpZiAoIW9wZW4gJiYgaXNIVE1MRWxlbWVudChlbGVtZW50cy5kb21SZWZlcmVuY2UpICYmIGVsZW1lbnRzLmRvbVJlZmVyZW5jZSA9PT0gYWN0aXZlRWxlbWVudChnZXREb2N1bWVudCQxKGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkpKSB7XG4gICAgICAgIGJsb2NrRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uS2V5RG93bigpIHtcbiAgICAgIGtleWJvYXJkTW9kYWxpdHlSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uUG9pbnRlckRvd24oKSB7XG4gICAgICBrZXlib2FyZE1vZGFsaXR5UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9XG4gICAgd2luLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBvbkJsdXIpO1xuICAgIGlmIChpc01hY1NhZmFyaSgpKSB7XG4gICAgICB3aW4uYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93biwgdHJ1ZSk7XG4gICAgICB3aW4uYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBvblBvaW50ZXJEb3duLCB0cnVlKTtcbiAgICB9XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdibHVyJywgb25CbHVyKTtcbiAgICAgIGlmIChpc01hY1NhZmFyaSgpKSB7XG4gICAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duLCB0cnVlKTtcbiAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgb25Qb2ludGVyRG93biwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW2VsZW1lbnRzLmRvbVJlZmVyZW5jZSwgb3BlbiwgZW5hYmxlZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIG9uT3BlbkNoYW5nZShfcmVmKSB7XG4gICAgICBsZXQge1xuICAgICAgICByZWFzb25cbiAgICAgIH0gPSBfcmVmO1xuICAgICAgaWYgKHJlYXNvbiA9PT0gJ3JlZmVyZW5jZS1wcmVzcycgfHwgcmVhc29uID09PSAnZXNjYXBlLWtleScpIHtcbiAgICAgICAgYmxvY2tGb2N1c1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgZXZlbnRzLm9uKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZXZlbnRzLm9mZignb3BlbmNoYW5nZScsIG9uT3BlbkNoYW5nZSk7XG4gICAgfTtcbiAgfSwgW2V2ZW50cywgZW5hYmxlZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0UmVmKTtcbiAgICB9O1xuICB9LCBbXSk7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBvbk1vdXNlTGVhdmUoKSB7XG4gICAgICBibG9ja0ZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9LFxuICAgIG9uRm9jdXMoZXZlbnQpIHtcbiAgICAgIGlmIChibG9ja0ZvY3VzUmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50Lm5hdGl2ZUV2ZW50KTtcbiAgICAgIGlmICh2aXNpYmxlT25seSAmJiBpc0VsZW1lbnQodGFyZ2V0KSkge1xuICAgICAgICAvLyBTYWZhcmkgZmFpbHMgdG8gbWF0Y2ggYDpmb2N1cy12aXNpYmxlYCBpZiBmb2N1cyB3YXMgaW5pdGlhbGx5XG4gICAgICAgIC8vIG91dHNpZGUgdGhlIGRvY3VtZW50LlxuICAgICAgICBpZiAoaXNNYWNTYWZhcmkoKSAmJiAhZXZlbnQucmVsYXRlZFRhcmdldCkge1xuICAgICAgICAgIGlmICgha2V5Ym9hcmRNb2RhbGl0eVJlZi5jdXJyZW50ICYmICFpc1R5cGVhYmxlRWxlbWVudCh0YXJnZXQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFtYXRjaGVzRm9jdXNWaXNpYmxlKHRhcmdldCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudC5uYXRpdmVFdmVudCwgJ2ZvY3VzJyk7XG4gICAgfSxcbiAgICBvbkJsdXIoZXZlbnQpIHtcbiAgICAgIGJsb2NrRm9jdXNSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgY29uc3QgcmVsYXRlZFRhcmdldCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG4gICAgICBjb25zdCBuYXRpdmVFdmVudCA9IGV2ZW50Lm5hdGl2ZUV2ZW50O1xuXG4gICAgICAvLyBIaXQgdGhlIG5vbi1tb2RhbCBmb2N1cyBtYW5hZ2VtZW50IHBvcnRhbCBndWFyZC4gRm9jdXMgd2lsbCBiZVxuICAgICAgLy8gbW92ZWQgaW50byB0aGUgZmxvYXRpbmcgZWxlbWVudCBpbW1lZGlhdGVseSBhZnRlci5cbiAgICAgIGNvbnN0IG1vdmVkVG9Gb2N1c0d1YXJkID0gaXNFbGVtZW50KHJlbGF0ZWRUYXJnZXQpICYmIHJlbGF0ZWRUYXJnZXQuaGFzQXR0cmlidXRlKGNyZWF0ZUF0dHJpYnV0ZSgnZm9jdXMtZ3VhcmQnKSkgJiYgcmVsYXRlZFRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScpID09PSAnb3V0c2lkZSc7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHRoZSB3aW5kb3cgYmx1ciBsaXN0ZW5lciB0byBmaXJlLlxuICAgICAgdGltZW91dFJlZi5jdXJyZW50ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB2YXIgX2RhdGFSZWYkY3VycmVudCRmbG9hO1xuICAgICAgICBjb25zdCBhY3RpdmVFbCA9IGFjdGl2ZUVsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlID8gZWxlbWVudHMuZG9tUmVmZXJlbmNlLm93bmVyRG9jdW1lbnQgOiBkb2N1bWVudCk7XG5cbiAgICAgICAgLy8gRm9jdXMgbGVmdCB0aGUgcGFnZSwga2VlcCBpdCBvcGVuLlxuICAgICAgICBpZiAoIXJlbGF0ZWRUYXJnZXQgJiYgYWN0aXZlRWwgPT09IGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFdoZW4gZm9jdXNpbmcgdGhlIHJlZmVyZW5jZSBlbGVtZW50IChlLmcuIHJlZ3VsYXIgY2xpY2spLCB0aGVuXG4gICAgICAgIC8vIGNsaWNraW5nIGludG8gdGhlIGZsb2F0aW5nIGVsZW1lbnQsIHByZXZlbnQgaXQgZnJvbSBoaWRpbmcuXG4gICAgICAgIC8vIE5vdGU6IGl0IG11c3QgYmUgZm9jdXNhYmxlLCBlLmcuIGB0YWJpbmRleD1cIi0xXCJgLlxuICAgICAgICAvLyBXZSBjYW4gbm90IHJlbHkgb24gcmVsYXRlZFRhcmdldCB0byBwb2ludCB0byB0aGUgY29ycmVjdCBlbGVtZW50XG4gICAgICAgIC8vIGFzIGl0IHdpbGwgb25seSBwb2ludCB0byB0aGUgc2hhZG93IGhvc3Qgb2YgdGhlIG5ld2x5IGZvY3VzZWQgZWxlbWVudFxuICAgICAgICAvLyBhbmQgbm90IHRoZSBlbGVtZW50IHRoYXQgYWN0dWFsbHkgaGFzIHJlY2VpdmVkIGZvY3VzIGlmIGl0IGlzIGxvY2F0ZWRcbiAgICAgICAgLy8gaW5zaWRlIGEgc2hhZG93IHJvb3QuXG4gICAgICAgIGlmIChjb250YWlucyQxKChfZGF0YVJlZiRjdXJyZW50JGZsb2EgPSBkYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGFSZWYkY3VycmVudCRmbG9hLnJlZnMuZmxvYXRpbmcuY3VycmVudCwgYWN0aXZlRWwpIHx8IGNvbnRhaW5zJDEoZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBhY3RpdmVFbCkgfHwgbW92ZWRUb0ZvY3VzR3VhcmQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBuYXRpdmVFdmVudCwgJ2ZvY3VzJyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pLCBbZGF0YVJlZiwgZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBvbk9wZW5DaGFuZ2UsIHZpc2libGVPbmx5XSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZV0pO1xufVxuXG5mdW5jdGlvbiBtZXJnZVByb3BzKHVzZXJQcm9wcywgcHJvcHNMaXN0LCBlbGVtZW50S2V5KSB7XG4gIGNvbnN0IG1hcCA9IG5ldyBNYXAoKTtcbiAgY29uc3QgaXNJdGVtID0gZWxlbWVudEtleSA9PT0gJ2l0ZW0nO1xuICBsZXQgZG9tVXNlclByb3BzID0gdXNlclByb3BzO1xuICBpZiAoaXNJdGVtICYmIHVzZXJQcm9wcykge1xuICAgIGNvbnN0IHtcbiAgICAgIFtBQ1RJVkVfS0VZXTogXyxcbiAgICAgIFtTRUxFQ1RFRF9LRVldOiBfXyxcbiAgICAgIC4uLnZhbGlkUHJvcHNcbiAgICB9ID0gdXNlclByb3BzO1xuICAgIGRvbVVzZXJQcm9wcyA9IHZhbGlkUHJvcHM7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICAuLi4oZWxlbWVudEtleSA9PT0gJ2Zsb2F0aW5nJyAmJiB7XG4gICAgICB0YWJJbmRleDogLTEsXG4gICAgICBbRk9DVVNBQkxFX0FUVFJJQlVURV06ICcnXG4gICAgfSksXG4gICAgLi4uZG9tVXNlclByb3BzLFxuICAgIC4uLnByb3BzTGlzdC5tYXAodmFsdWUgPT4ge1xuICAgICAgY29uc3QgcHJvcHNPckdldFByb3BzID0gdmFsdWUgPyB2YWx1ZVtlbGVtZW50S2V5XSA6IG51bGw7XG4gICAgICBpZiAodHlwZW9mIHByb3BzT3JHZXRQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gdXNlclByb3BzID8gcHJvcHNPckdldFByb3BzKHVzZXJQcm9wcykgOiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3BzT3JHZXRQcm9wcztcbiAgICB9KS5jb25jYXQodXNlclByb3BzKS5yZWR1Y2UoKGFjYywgcHJvcHMpID0+IHtcbiAgICAgIGlmICghcHJvcHMpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIE9iamVjdC5lbnRyaWVzKHByb3BzKS5mb3JFYWNoKF9yZWYgPT4ge1xuICAgICAgICBsZXQgW2tleSwgdmFsdWVdID0gX3JlZjtcbiAgICAgICAgaWYgKGlzSXRlbSAmJiBbQUNUSVZFX0tFWSwgU0VMRUNURURfS0VZXS5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChrZXkuaW5kZXhPZignb24nKSA9PT0gMCkge1xuICAgICAgICAgIGlmICghbWFwLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICBtYXAuc2V0KGtleSwgW10pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgX21hcCRnZXQ7XG4gICAgICAgICAgICAoX21hcCRnZXQgPSBtYXAuZ2V0KGtleSkpID09IG51bGwgfHwgX21hcCRnZXQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICBhY2Nba2V5XSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgdmFyIF9tYXAkZ2V0MjtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgICAgICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gKF9tYXAkZ2V0MiA9IG1hcC5nZXQoa2V5KSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9tYXAkZ2V0Mi5tYXAoZm4gPT4gZm4oLi4uYXJncykpLmZpbmQodmFsID0+IHZhbCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSlcbiAgfTtcbn1cbi8qKlxuICogTWVyZ2VzIGFuIGFycmF5IG9mIGludGVyYWN0aW9uIGhvb2tzJyBwcm9wcyBpbnRvIHByb3AgZ2V0dGVycywgYWxsb3dpbmdcbiAqIGV2ZW50IGhhbmRsZXIgZnVuY3Rpb25zIHRvIGJlIGNvbXBvc2VkIHRvZ2V0aGVyIHdpdGhvdXQgb3ZlcndyaXRpbmcgb25lXG4gKiBhbm90aGVyLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUludGVyYWN0aW9uc1xuICovXG5mdW5jdGlvbiB1c2VJbnRlcmFjdGlvbnMocHJvcHNMaXN0KSB7XG4gIGlmIChwcm9wc0xpc3QgPT09IHZvaWQgMCkge1xuICAgIHByb3BzTGlzdCA9IFtdO1xuICB9XG4gIGNvbnN0IHJlZmVyZW5jZURlcHMgPSBwcm9wc0xpc3QubWFwKGtleSA9PiBrZXkgPT0gbnVsbCA/IHZvaWQgMCA6IGtleS5yZWZlcmVuY2UpO1xuICBjb25zdCBmbG9hdGluZ0RlcHMgPSBwcm9wc0xpc3QubWFwKGtleSA9PiBrZXkgPT0gbnVsbCA/IHZvaWQgMCA6IGtleS5mbG9hdGluZyk7XG4gIGNvbnN0IGl0ZW1EZXBzID0gcHJvcHNMaXN0Lm1hcChrZXkgPT4ga2V5ID09IG51bGwgPyB2b2lkIDAgOiBrZXkuaXRlbSk7XG4gIGNvbnN0IGdldFJlZmVyZW5jZVByb3BzID0gUmVhY3QudXNlQ2FsbGJhY2sodXNlclByb3BzID0+IG1lcmdlUHJvcHModXNlclByb3BzLCBwcm9wc0xpc3QsICdyZWZlcmVuY2UnKSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICByZWZlcmVuY2VEZXBzKTtcbiAgY29uc3QgZ2V0RmxvYXRpbmdQcm9wcyA9IFJlYWN0LnVzZUNhbGxiYWNrKHVzZXJQcm9wcyA9PiBtZXJnZVByb3BzKHVzZXJQcm9wcywgcHJvcHNMaXN0LCAnZmxvYXRpbmcnKSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICBmbG9hdGluZ0RlcHMpO1xuICBjb25zdCBnZXRJdGVtUHJvcHMgPSBSZWFjdC51c2VDYWxsYmFjayh1c2VyUHJvcHMgPT4gbWVyZ2VQcm9wcyh1c2VyUHJvcHMsIHByb3BzTGlzdCwgJ2l0ZW0nKSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICBpdGVtRGVwcyk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgZ2V0UmVmZXJlbmNlUHJvcHMsXG4gICAgZ2V0RmxvYXRpbmdQcm9wcyxcbiAgICBnZXRJdGVtUHJvcHNcbiAgfSksIFtnZXRSZWZlcmVuY2VQcm9wcywgZ2V0RmxvYXRpbmdQcm9wcywgZ2V0SXRlbVByb3BzXSk7XG59XG5cbmNvbnN0IEVTQ0FQRSA9ICdFc2NhcGUnO1xuZnVuY3Rpb24gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKSB7XG4gIHN3aXRjaCAob3JpZW50YXRpb24pIHtcbiAgICBjYXNlICd2ZXJ0aWNhbCc6XG4gICAgICByZXR1cm4gdmVydGljYWw7XG4gICAgY2FzZSAnaG9yaXpvbnRhbCc6XG4gICAgICByZXR1cm4gaG9yaXpvbnRhbDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHZlcnRpY2FsIHx8IGhvcml6b250YWw7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzTWFpbk9yaWVudGF0aW9uS2V5KGtleSwgb3JpZW50YXRpb24pIHtcbiAgY29uc3QgdmVydGljYWwgPSBrZXkgPT09IEFSUk9XX1VQIHx8IGtleSA9PT0gQVJST1dfRE9XTjtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGtleSA9PT0gQVJST1dfTEVGVCB8fCBrZXkgPT09IEFSUk9XX1JJR0hUO1xuICByZXR1cm4gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKTtcbn1cbmZ1bmN0aW9uIGlzTWFpbk9yaWVudGF0aW9uVG9FbmRLZXkoa2V5LCBvcmllbnRhdGlvbiwgcnRsKSB7XG4gIGNvbnN0IHZlcnRpY2FsID0ga2V5ID09PSBBUlJPV19ET1dOO1xuICBjb25zdCBob3Jpem9udGFsID0gcnRsID8ga2V5ID09PSBBUlJPV19MRUZUIDoga2V5ID09PSBBUlJPV19SSUdIVDtcbiAgcmV0dXJuIGRvU3dpdGNoKG9yaWVudGF0aW9uLCB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCkgfHwga2V5ID09PSAnRW50ZXInIHx8IGtleSA9PT0gJyAnIHx8IGtleSA9PT0gJyc7XG59XG5mdW5jdGlvbiBpc0Nyb3NzT3JpZW50YXRpb25PcGVuS2V5KGtleSwgb3JpZW50YXRpb24sIHJ0bCkge1xuICBjb25zdCB2ZXJ0aWNhbCA9IHJ0bCA/IGtleSA9PT0gQVJST1dfTEVGVCA6IGtleSA9PT0gQVJST1dfUklHSFQ7XG4gIGNvbnN0IGhvcml6b250YWwgPSBrZXkgPT09IEFSUk9XX0RPV047XG4gIHJldHVybiBkb1N3aXRjaChvcmllbnRhdGlvbiwgdmVydGljYWwsIGhvcml6b250YWwpO1xufVxuZnVuY3Rpb24gaXNDcm9zc09yaWVudGF0aW9uQ2xvc2VLZXkoa2V5LCBvcmllbnRhdGlvbiwgcnRsLCBjb2xzKSB7XG4gIGNvbnN0IHZlcnRpY2FsID0gcnRsID8ga2V5ID09PSBBUlJPV19SSUdIVCA6IGtleSA9PT0gQVJST1dfTEVGVDtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGtleSA9PT0gQVJST1dfVVA7XG4gIGlmIChvcmllbnRhdGlvbiA9PT0gJ2JvdGgnIHx8IG9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgJiYgY29scyAmJiBjb2xzID4gMSkge1xuICAgIHJldHVybiBrZXkgPT09IEVTQ0FQRTtcbiAgfVxuICByZXR1cm4gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKTtcbn1cbi8qKlxuICogQWRkcyBhcnJvdyBrZXktYmFzZWQgbmF2aWdhdGlvbiBvZiBhIGxpc3Qgb2YgaXRlbXMsIGVpdGhlciB1c2luZyByZWFsIERPTVxuICogZm9jdXMgb3IgdmlydHVhbCBmb2N1cy5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VMaXN0TmF2aWdhdGlvblxuICovXG5mdW5jdGlvbiB1c2VMaXN0TmF2aWdhdGlvbihjb250ZXh0LCBwcm9wcykge1xuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZmxvYXRpbmdJZFxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGxpc3RSZWYsXG4gICAgYWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZTogdW5zdGFibGVfb25OYXZpZ2F0ZSA9ICgpID0+IHt9LFxuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIHNlbGVjdGVkSW5kZXggPSBudWxsLFxuICAgIGFsbG93RXNjYXBlID0gZmFsc2UsXG4gICAgbG9vcCA9IGZhbHNlLFxuICAgIG5lc3RlZCA9IGZhbHNlLFxuICAgIHJ0bCA9IGZhbHNlLFxuICAgIHZpcnR1YWwgPSBmYWxzZSxcbiAgICBmb2N1c0l0ZW1Pbk9wZW4gPSAnYXV0bycsXG4gICAgZm9jdXNJdGVtT25Ib3ZlciA9IHRydWUsXG4gICAgb3Blbk9uQXJyb3dLZXlEb3duID0gdHJ1ZSxcbiAgICBkaXNhYmxlZEluZGljZXMgPSB1bmRlZmluZWQsXG4gICAgb3JpZW50YXRpb24gPSAndmVydGljYWwnLFxuICAgIHBhcmVudE9yaWVudGF0aW9uLFxuICAgIGNvbHMgPSAxLFxuICAgIHNjcm9sbEl0ZW1JbnRvVmlldyA9IHRydWUsXG4gICAgdmlydHVhbEl0ZW1SZWYsXG4gICAgaXRlbVNpemVzLFxuICAgIGRlbnNlID0gZmFsc2VcbiAgfSA9IHByb3BzO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgaWYgKGFsbG93RXNjYXBlKSB7XG4gICAgICBpZiAoIWxvb3ApIHtcbiAgICAgICAgd2FybignYHVzZUxpc3ROYXZpZ2F0aW9uYCBsb29waW5nIG11c3QgYmUgZW5hYmxlZCB0byBhbGxvdyBlc2NhcGluZy4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghdmlydHVhbCkge1xuICAgICAgICB3YXJuKCdgdXNlTGlzdE5hdmlnYXRpb25gIG11c3QgYmUgdmlydHVhbCB0byBhbGxvdyBlc2NhcGluZy4nKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG9yaWVudGF0aW9uID09PSAndmVydGljYWwnICYmIGNvbHMgPiAxKSB7XG4gICAgICB3YXJuKCdJbiBncmlkIGxpc3QgbmF2aWdhdGlvbiBtb2RlIChgY29sc2AgPiAxKSwgdGhlIGBvcmllbnRhdGlvbmAgc2hvdWxkJywgJ2JlIGVpdGhlciBcImhvcml6b250YWxcIiBvciBcImJvdGhcIi4nKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgZmxvYXRpbmdGb2N1c0VsZW1lbnQgPSBnZXRGbG9hdGluZ0ZvY3VzRWxlbWVudChlbGVtZW50cy5mbG9hdGluZyk7XG4gIGNvbnN0IGZsb2F0aW5nRm9jdXNFbGVtZW50UmVmID0gdXNlTGF0ZXN0UmVmKGZsb2F0aW5nRm9jdXNFbGVtZW50KTtcbiAgY29uc3QgcGFyZW50SWQgPSB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCgpO1xuICBjb25zdCB0cmVlID0gdXNlRmxvYXRpbmdUcmVlKCk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgY29udGV4dC5kYXRhUmVmLmN1cnJlbnQub3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgfSwgW2NvbnRleHQsIG9yaWVudGF0aW9uXSk7XG4gIGNvbnN0IG9uTmF2aWdhdGUgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdW5zdGFibGVfb25OYXZpZ2F0ZShpbmRleFJlZi5jdXJyZW50ID09PSAtMSA/IG51bGwgOiBpbmRleFJlZi5jdXJyZW50KTtcbiAgfSk7XG4gIGNvbnN0IHR5cGVhYmxlQ29tYm9ib3hSZWZlcmVuY2UgPSBpc1R5cGVhYmxlQ29tYm9ib3goZWxlbWVudHMuZG9tUmVmZXJlbmNlKTtcbiAgY29uc3QgZm9jdXNJdGVtT25PcGVuUmVmID0gUmVhY3QudXNlUmVmKGZvY3VzSXRlbU9uT3Blbik7XG4gIGNvbnN0IGluZGV4UmVmID0gUmVhY3QudXNlUmVmKHNlbGVjdGVkSW5kZXggIT0gbnVsbCA/IHNlbGVjdGVkSW5kZXggOiAtMSk7XG4gIGNvbnN0IGtleVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgaXNQb2ludGVyTW9kYWxpdHlSZWYgPSBSZWFjdC51c2VSZWYodHJ1ZSk7XG4gIGNvbnN0IHByZXZpb3VzT25OYXZpZ2F0ZVJlZiA9IFJlYWN0LnVzZVJlZihvbk5hdmlnYXRlKTtcbiAgY29uc3QgcHJldmlvdXNNb3VudGVkUmVmID0gUmVhY3QudXNlUmVmKCEhZWxlbWVudHMuZmxvYXRpbmcpO1xuICBjb25zdCBwcmV2aW91c09wZW5SZWYgPSBSZWFjdC51c2VSZWYob3Blbik7XG4gIGNvbnN0IGZvcmNlU3luY0ZvY3VzUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgZm9yY2VTY3JvbGxJbnRvVmlld1JlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGRpc2FibGVkSW5kaWNlc1JlZiA9IHVzZUxhdGVzdFJlZihkaXNhYmxlZEluZGljZXMpO1xuICBjb25zdCBsYXRlc3RPcGVuUmVmID0gdXNlTGF0ZXN0UmVmKG9wZW4pO1xuICBjb25zdCBzY3JvbGxJdGVtSW50b1ZpZXdSZWYgPSB1c2VMYXRlc3RSZWYoc2Nyb2xsSXRlbUludG9WaWV3KTtcbiAgY29uc3Qgc2VsZWN0ZWRJbmRleFJlZiA9IHVzZUxhdGVzdFJlZihzZWxlY3RlZEluZGV4KTtcbiAgY29uc3QgW2FjdGl2ZUlkLCBzZXRBY3RpdmVJZF0gPSBSZWFjdC51c2VTdGF0ZSgpO1xuICBjb25zdCBbdmlydHVhbElkLCBzZXRWaXJ0dWFsSWRdID0gUmVhY3QudXNlU3RhdGUoKTtcbiAgY29uc3QgZm9jdXNJdGVtID0gdXNlRWZmZWN0RXZlbnQoKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHJ1bkZvY3VzKGl0ZW0pIHtcbiAgICAgIGlmICh2aXJ0dWFsKSB7XG4gICAgICAgIHZhciBfaXRlbSRpZDtcbiAgICAgICAgaWYgKChfaXRlbSRpZCA9IGl0ZW0uaWQpICE9IG51bGwgJiYgX2l0ZW0kaWQuZW5kc1dpdGgoJy1mdWktb3B0aW9uJykpIHtcbiAgICAgICAgICBpdGVtLmlkID0gZmxvYXRpbmdJZCArIFwiLVwiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygxNikuc2xpY2UoMiwgMTApO1xuICAgICAgICB9XG4gICAgICAgIHNldEFjdGl2ZUlkKGl0ZW0uaWQpO1xuICAgICAgICB0cmVlID09IG51bGwgfHwgdHJlZS5ldmVudHMuZW1pdCgndmlydHVhbGZvY3VzJywgaXRlbSk7XG4gICAgICAgIGlmICh2aXJ0dWFsSXRlbVJlZikge1xuICAgICAgICAgIHZpcnR1YWxJdGVtUmVmLmN1cnJlbnQgPSBpdGVtO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnF1ZXVlRm9jdXMoaXRlbSwge1xuICAgICAgICAgIHN5bmM6IGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQsXG4gICAgICAgICAgcHJldmVudFNjcm9sbDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgaW5pdGlhbEl0ZW0gPSBsaXN0UmVmLmN1cnJlbnRbaW5kZXhSZWYuY3VycmVudF07XG4gICAgY29uc3QgZm9yY2VTY3JvbGxJbnRvVmlldyA9IGZvcmNlU2Nyb2xsSW50b1ZpZXdSZWYuY3VycmVudDtcbiAgICBpZiAoaW5pdGlhbEl0ZW0pIHtcbiAgICAgIHJ1bkZvY3VzKGluaXRpYWxJdGVtKTtcbiAgICB9XG4gICAgY29uc3Qgc2NoZWR1bGVyID0gZm9yY2VTeW5jRm9jdXNSZWYuY3VycmVudCA/IHYgPT4gdigpIDogcmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuICAgIHNjaGVkdWxlcigoKSA9PiB7XG4gICAgICBjb25zdCB3YWl0ZWRJdGVtID0gbGlzdFJlZi5jdXJyZW50W2luZGV4UmVmLmN1cnJlbnRdIHx8IGluaXRpYWxJdGVtO1xuICAgICAgaWYgKCF3YWl0ZWRJdGVtKSByZXR1cm47XG4gICAgICBpZiAoIWluaXRpYWxJdGVtKSB7XG4gICAgICAgIHJ1bkZvY3VzKHdhaXRlZEl0ZW0pO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2Nyb2xsSW50b1ZpZXdPcHRpb25zID0gc2Nyb2xsSXRlbUludG9WaWV3UmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBzaG91bGRTY3JvbGxJbnRvVmlldyA9IHNjcm9sbEludG9WaWV3T3B0aW9ucyAmJiBpdGVtICYmIChmb3JjZVNjcm9sbEludG9WaWV3IHx8ICFpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50KTtcbiAgICAgIGlmIChzaG91bGRTY3JvbGxJbnRvVmlldykge1xuICAgICAgICAvLyBKU0RPTSBkb2Vzbid0IHN1cHBvcnQgYC5zY3JvbGxJbnRvVmlldygpYCBidXQgaXQncyB3aWRlbHkgc3VwcG9ydGVkXG4gICAgICAgIC8vIGJ5IGFsbCBicm93c2Vycy5cbiAgICAgICAgd2FpdGVkSXRlbS5zY3JvbGxJbnRvVmlldyA9PSBudWxsIHx8IHdhaXRlZEl0ZW0uc2Nyb2xsSW50b1ZpZXcodHlwZW9mIHNjcm9sbEludG9WaWV3T3B0aW9ucyA9PT0gJ2Jvb2xlYW4nID8ge1xuICAgICAgICAgIGJsb2NrOiAnbmVhcmVzdCcsXG4gICAgICAgICAgaW5saW5lOiAnbmVhcmVzdCdcbiAgICAgICAgfSA6IHNjcm9sbEludG9WaWV3T3B0aW9ucyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFN5bmMgYHNlbGVjdGVkSW5kZXhgIHRvIGJlIHRoZSBgYWN0aXZlSW5kZXhgIHVwb24gb3BlbmluZyB0aGUgZmxvYXRpbmdcbiAgLy8gZWxlbWVudC4gQWxzbywgcmVzZXQgYGFjdGl2ZUluZGV4YCB1cG9uIGNsb3NpbmcgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKG9wZW4gJiYgZWxlbWVudHMuZmxvYXRpbmcpIHtcbiAgICAgIGlmIChmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCAmJiBzZWxlY3RlZEluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgLy8gUmVnYXJkbGVzcyBvZiB0aGUgcG9pbnRlciBtb2RhbGl0eSwgd2Ugd2FudCB0byBlbnN1cmUgdGhlIHNlbGVjdGVkXG4gICAgICAgIC8vIGl0ZW0gY29tZXMgaW50byB2aWV3IHdoZW4gdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXMgb3BlbmVkLlxuICAgICAgICBmb3JjZVNjcm9sbEludG9WaWV3UmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJldmlvdXNNb3VudGVkUmVmLmN1cnJlbnQpIHtcbiAgICAgIC8vIFNpbmNlIHRoZSB1c2VyIGNhbiBzcGVjaWZ5IGBvbk5hdmlnYXRlYCBjb25kaXRpb25hbGx5XG4gICAgICAvLyAob25OYXZpZ2F0ZTogb3BlbiA/IHNldEFjdGl2ZUluZGV4IDogc2V0U2VsZWN0ZWRJbmRleCksXG4gICAgICAvLyB3ZSBzdG9yZSBhbmQgY2FsbCB0aGUgcHJldmlvdXMgZnVuY3Rpb24uXG4gICAgICBpbmRleFJlZi5jdXJyZW50ID0gLTE7XG4gICAgICBwcmV2aW91c09uTmF2aWdhdGVSZWYuY3VycmVudCgpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGVsZW1lbnRzLmZsb2F0aW5nLCBzZWxlY3RlZEluZGV4LCBvbk5hdmlnYXRlXSk7XG5cbiAgLy8gU3luYyBgYWN0aXZlSW5kZXhgIHRvIGJlIHRoZSBmb2N1c2VkIGl0ZW0gd2hpbGUgdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXNcbiAgLy8gb3Blbi5cbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoIW9wZW4pIHJldHVybjtcbiAgICBpZiAoIWVsZW1lbnRzLmZsb2F0aW5nKSByZXR1cm47XG4gICAgaWYgKGFjdGl2ZUluZGV4ID09IG51bGwpIHtcbiAgICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIGlmIChzZWxlY3RlZEluZGV4UmVmLmN1cnJlbnQgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFJlc2V0IHdoaWxlIHRoZSBmbG9hdGluZyBlbGVtZW50IHdhcyBvcGVuIChlLmcuIHRoZSBsaXN0IGNoYW5nZWQpLlxuICAgICAgaWYgKHByZXZpb3VzTW91bnRlZFJlZi5jdXJyZW50KSB7XG4gICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSAtMTtcbiAgICAgICAgZm9jdXNJdGVtKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEluaXRpYWwgc3luYy5cbiAgICAgIGlmICgoIXByZXZpb3VzT3BlblJlZi5jdXJyZW50IHx8ICFwcmV2aW91c01vdW50ZWRSZWYuY3VycmVudCkgJiYgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgJiYgKGtleVJlZi5jdXJyZW50ICE9IG51bGwgfHwgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgPT09IHRydWUgJiYga2V5UmVmLmN1cnJlbnQgPT0gbnVsbCkpIHtcbiAgICAgICAgbGV0IHJ1bnMgPSAwO1xuICAgICAgICBjb25zdCB3YWl0Rm9yTGlzdFBvcHVsYXRlZCA9ICgpID0+IHtcbiAgICAgICAgICBpZiAobGlzdFJlZi5jdXJyZW50WzBdID09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIGxldHRpbmcgdGhlIGJyb3dzZXIgcGFpbnQgaWYgcG9zc2libGUgb24gdGhlIGZpcnN0IHRyeSxcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB1c2UgckFGLiBEb24ndCB0cnkgbW9yZSB0aGFuIHR3aWNlLCBzaW5jZSBzb21ldGhpbmdcbiAgICAgICAgICAgIC8vIGlzIHdyb25nIG90aGVyd2lzZS5cbiAgICAgICAgICAgIGlmIChydW5zIDwgMikge1xuICAgICAgICAgICAgICBjb25zdCBzY2hlZHVsZXIgPSBydW5zID8gcmVxdWVzdEFuaW1hdGlvbkZyYW1lIDogcXVldWVNaWNyb3Rhc2s7XG4gICAgICAgICAgICAgIHNjaGVkdWxlcih3YWl0Rm9yTGlzdFBvcHVsYXRlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydW5zKys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBrZXlSZWYuY3VycmVudCA9PSBudWxsIHx8IGlzTWFpbk9yaWVudGF0aW9uVG9FbmRLZXkoa2V5UmVmLmN1cnJlbnQsIG9yaWVudGF0aW9uLCBydGwpIHx8IG5lc3RlZCA/IGdldE1pbkxpc3RJbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXNSZWYuY3VycmVudCkgOiBnZXRNYXhMaXN0SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzUmVmLmN1cnJlbnQpO1xuICAgICAgICAgICAga2V5UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgd2FpdEZvckxpc3RQb3B1bGF0ZWQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc0luZGV4T3V0T2ZMaXN0Qm91bmRzKGxpc3RSZWYsIGFjdGl2ZUluZGV4KSkge1xuICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGFjdGl2ZUluZGV4O1xuICAgICAgZm9jdXNJdGVtKCk7XG4gICAgICBmb3JjZVNjcm9sbEludG9WaWV3UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuLCBlbGVtZW50cy5mbG9hdGluZywgYWN0aXZlSW5kZXgsIHNlbGVjdGVkSW5kZXhSZWYsIG5lc3RlZCwgbGlzdFJlZiwgb3JpZW50YXRpb24sIHJ0bCwgb25OYXZpZ2F0ZSwgZm9jdXNJdGVtLCBkaXNhYmxlZEluZGljZXNSZWZdKTtcblxuICAvLyBFbnN1cmUgdGhlIHBhcmVudCBmbG9hdGluZyBlbGVtZW50IGhhcyBmb2N1cyB3aGVuIGEgbmVzdGVkIGNoaWxkIGNsb3Nlc1xuICAvLyB0byBhbGxvdyBhcnJvdyBrZXkgbmF2aWdhdGlvbiB0byB3b3JrIGFmdGVyIHRoZSBwb2ludGVyIGxlYXZlcyB0aGUgY2hpbGQuXG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgdmFyIF9ub2RlcyRmaW5kO1xuICAgIGlmICghZW5hYmxlZCB8fCBlbGVtZW50cy5mbG9hdGluZyB8fCAhdHJlZSB8fCB2aXJ0dWFsIHx8ICFwcmV2aW91c01vdW50ZWRSZWYuY3VycmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBub2RlcyA9IHRyZWUubm9kZXNSZWYuY3VycmVudDtcbiAgICBjb25zdCBwYXJlbnQgPSAoX25vZGVzJGZpbmQgPSBub2Rlcy5maW5kKG5vZGUgPT4gbm9kZS5pZCA9PT0gcGFyZW50SWQpKSA9PSBudWxsIHx8IChfbm9kZXMkZmluZCA9IF9ub2RlcyRmaW5kLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZXMkZmluZC5lbGVtZW50cy5mbG9hdGluZztcbiAgICBjb25zdCBhY3RpdmVFbCA9IGFjdGl2ZUVsZW1lbnQoZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZykpO1xuICAgIGNvbnN0IHRyZWVDb250YWluc0FjdGl2ZUVsID0gbm9kZXMuc29tZShub2RlID0+IG5vZGUuY29udGV4dCAmJiBjb250YWlucyQxKG5vZGUuY29udGV4dC5lbGVtZW50cy5mbG9hdGluZywgYWN0aXZlRWwpKTtcbiAgICBpZiAocGFyZW50ICYmICF0cmVlQ29udGFpbnNBY3RpdmVFbCAmJiBpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50KSB7XG4gICAgICBwYXJlbnQuZm9jdXMoe1xuICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBlbGVtZW50cy5mbG9hdGluZywgdHJlZSwgcGFyZW50SWQsIHZpcnR1YWxdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoIXRyZWUpIHJldHVybjtcbiAgICBpZiAoIXZpcnR1YWwpIHJldHVybjtcbiAgICBpZiAocGFyZW50SWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBoYW5kbGVWaXJ0dWFsRm9jdXMoaXRlbSkge1xuICAgICAgc2V0VmlydHVhbElkKGl0ZW0uaWQpO1xuICAgICAgaWYgKHZpcnR1YWxJdGVtUmVmKSB7XG4gICAgICAgIHZpcnR1YWxJdGVtUmVmLmN1cnJlbnQgPSBpdGVtO1xuICAgICAgfVxuICAgIH1cbiAgICB0cmVlLmV2ZW50cy5vbigndmlydHVhbGZvY3VzJywgaGFuZGxlVmlydHVhbEZvY3VzKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgdHJlZS5ldmVudHMub2ZmKCd2aXJ0dWFsZm9jdXMnLCBoYW5kbGVWaXJ0dWFsRm9jdXMpO1xuICAgIH07XG4gIH0sIFtlbmFibGVkLCB0cmVlLCB2aXJ0dWFsLCBwYXJlbnRJZCwgdmlydHVhbEl0ZW1SZWZdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBwcmV2aW91c09uTmF2aWdhdGVSZWYuY3VycmVudCA9IG9uTmF2aWdhdGU7XG4gICAgcHJldmlvdXNPcGVuUmVmLmN1cnJlbnQgPSBvcGVuO1xuICAgIHByZXZpb3VzTW91bnRlZFJlZi5jdXJyZW50ID0gISFlbGVtZW50cy5mbG9hdGluZztcbiAgfSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICBrZXlSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbb3Blbl0pO1xuICBjb25zdCBoYXNBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICE9IG51bGw7XG4gIGNvbnN0IGl0ZW0gPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBmdW5jdGlvbiBzeW5jQ3VycmVudFRhcmdldChjdXJyZW50VGFyZ2V0KSB7XG4gICAgICBpZiAoIW9wZW4pIHJldHVybjtcbiAgICAgIGNvbnN0IGluZGV4ID0gbGlzdFJlZi5jdXJyZW50LmluZGV4T2YoY3VycmVudFRhcmdldCk7XG4gICAgICBpZiAoaW5kZXggIT09IC0xICYmIGluZGV4UmVmLmN1cnJlbnQgIT09IGluZGV4KSB7XG4gICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBpbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBwcm9wcyA9IHtcbiAgICAgIG9uRm9jdXMoX3JlZikge1xuICAgICAgICBsZXQge1xuICAgICAgICAgIGN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSA9IF9yZWY7XG4gICAgICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICBzeW5jQ3VycmVudFRhcmdldChjdXJyZW50VGFyZ2V0KTtcbiAgICAgIH0sXG4gICAgICBvbkNsaWNrOiBfcmVmMiA9PiB7XG4gICAgICAgIGxldCB7XG4gICAgICAgICAgY3VycmVudFRhcmdldFxuICAgICAgICB9ID0gX3JlZjI7XG4gICAgICAgIHJldHVybiBjdXJyZW50VGFyZ2V0LmZvY3VzKHtcbiAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIC8vIFNhZmFyaVxuICAgICAgLi4uKGZvY3VzSXRlbU9uSG92ZXIgJiYge1xuICAgICAgICBvbk1vdXNlTW92ZShfcmVmMykge1xuICAgICAgICAgIGxldCB7XG4gICAgICAgICAgICBjdXJyZW50VGFyZ2V0XG4gICAgICAgICAgfSA9IF9yZWYzO1xuICAgICAgICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgIGZvcmNlU2Nyb2xsSW50b1ZpZXdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgICAgIHN5bmNDdXJyZW50VGFyZ2V0KGN1cnJlbnRUYXJnZXQpO1xuICAgICAgICB9LFxuICAgICAgICBvblBvaW50ZXJMZWF2ZShfcmVmNCkge1xuICAgICAgICAgIGxldCB7XG4gICAgICAgICAgICBwb2ludGVyVHlwZVxuICAgICAgICAgIH0gPSBfcmVmNDtcbiAgICAgICAgICBpZiAoIWlzUG9pbnRlck1vZGFsaXR5UmVmLmN1cnJlbnQgfHwgcG9pbnRlclR5cGUgPT09ICd0b3VjaCcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yY2VTeW5jRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IC0xO1xuICAgICAgICAgIG9uTmF2aWdhdGUoKTtcbiAgICAgICAgICBpZiAoIXZpcnR1YWwpIHtcbiAgICAgICAgICAgIHZhciBfZmxvYXRpbmdGb2N1c0VsZW1lbnQ7XG4gICAgICAgICAgICAoX2Zsb2F0aW5nRm9jdXNFbGVtZW50ID0gZmxvYXRpbmdGb2N1c0VsZW1lbnRSZWYuY3VycmVudCkgPT0gbnVsbCB8fCBfZmxvYXRpbmdGb2N1c0VsZW1lbnQuZm9jdXMoe1xuICAgICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfTtcbiAgICByZXR1cm4gcHJvcHM7XG4gIH0sIFtvcGVuLCBmbG9hdGluZ0ZvY3VzRWxlbWVudFJlZiwgZm9jdXNJdGVtT25Ib3ZlciwgbGlzdFJlZiwgb25OYXZpZ2F0ZSwgdmlydHVhbF0pO1xuICBjb25zdCBnZXRQYXJlbnRPcmllbnRhdGlvbiA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICB2YXIgX3RyZWUkbm9kZXNSZWYkY3VycmVuO1xuICAgIHJldHVybiBwYXJlbnRPcmllbnRhdGlvbiAhPSBudWxsID8gcGFyZW50T3JpZW50YXRpb24gOiB0cmVlID09IG51bGwgfHwgKF90cmVlJG5vZGVzUmVmJGN1cnJlbiA9IHRyZWUubm9kZXNSZWYuY3VycmVudC5maW5kKG5vZGUgPT4gbm9kZS5pZCA9PT0gcGFyZW50SWQpKSA9PSBudWxsIHx8IChfdHJlZSRub2Rlc1JlZiRjdXJyZW4gPSBfdHJlZSRub2Rlc1JlZiRjdXJyZW4uY29udGV4dCkgPT0gbnVsbCB8fCAoX3RyZWUkbm9kZXNSZWYkY3VycmVuID0gX3RyZWUkbm9kZXNSZWYkY3VycmVuLmRhdGFSZWYpID09IG51bGwgPyB2b2lkIDAgOiBfdHJlZSRub2Rlc1JlZiRjdXJyZW4uY3VycmVudC5vcmllbnRhdGlvbjtcbiAgfSwgW3BhcmVudElkLCB0cmVlLCBwYXJlbnRPcmllbnRhdGlvbl0pO1xuICBjb25zdCBjb21tb25PbktleURvd24gPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgaXNQb2ludGVyTW9kYWxpdHlSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuXG4gICAgLy8gV2hlbiBjb21wb3NpbmcgYSBjaGFyYWN0ZXIsIENocm9tZSBmaXJlcyBBcnJvd0Rvd24gdHdpY2UuIEZpcmVmb3gvU2FmYXJpXG4gICAgLy8gZG9uJ3QgYXBwZWFyIHRvIHN1ZmZlciBmcm9tIHRoaXMuIGBldmVudC5pc0NvbXBvc2luZ2AgaXMgYXZvaWRlZCBkdWUgdG9cbiAgICAvLyBTYWZhcmkgbm90IHN1cHBvcnRpbmcgaXQgcHJvcGVybHkgKGFsdGhvdWdoIGl0J3Mgbm90IG5lZWRlZCBpbiB0aGUgZmlyc3RcbiAgICAvLyBwbGFjZSBmb3IgU2FmYXJpLCBqdXN0IGF2b2lkaW5nIGFueSBwb3NzaWJsZSBpc3N1ZXMpLlxuICAgIGlmIChldmVudC53aGljaCA9PT0gMjI5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXMgYW5pbWF0aW5nIG91dCwgaWdub3JlIG5hdmlnYXRpb24uIE90aGVyd2lzZSxcbiAgICAvLyB0aGUgYGFjdGl2ZUluZGV4YCBnZXRzIHNldCB0byAwIGRlc3BpdGUgbm90IGJlaW5nIG9wZW4gc28gdGhlIG5leHQgdGltZVxuICAgIC8vIHRoZSB1c2VyIEFycm93RG93bnMsIHRoZSBmaXJzdCBpdGVtIHdvbid0IGJlIGZvY3VzZWQuXG4gICAgaWYgKCFsYXRlc3RPcGVuUmVmLmN1cnJlbnQgJiYgZXZlbnQuY3VycmVudFRhcmdldCA9PT0gZmxvYXRpbmdGb2N1c0VsZW1lbnRSZWYuY3VycmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAobmVzdGVkICYmIGlzQ3Jvc3NPcmllbnRhdGlvbkNsb3NlS2V5KGV2ZW50LmtleSwgb3JpZW50YXRpb24sIHJ0bCwgY29scykpIHtcbiAgICAgIC8vIElmIHRoZSBuZXN0ZWQgbGlzdCdzIGNsb3NlIGtleSBpcyBhbHNvIHRoZSBwYXJlbnQgbmF2aWdhdGlvbiBrZXksXG4gICAgICAvLyBsZXQgdGhlIHBhcmVudCBuYXZpZ2F0ZS4gT3RoZXJ3aXNlLCBzdG9wIHByb3BhZ2F0aW5nIHRoZSBldmVudC5cbiAgICAgIGlmICghaXNNYWluT3JpZW50YXRpb25LZXkoZXZlbnQua2V5LCBnZXRQYXJlbnRPcmllbnRhdGlvbigpKSkge1xuICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgfVxuICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2xpc3QtbmF2aWdhdGlvbicpO1xuICAgICAgaWYgKGlzSFRNTEVsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgICBpZiAodmlydHVhbCkge1xuICAgICAgICAgIHRyZWUgPT0gbnVsbCB8fCB0cmVlLmV2ZW50cy5lbWl0KCd2aXJ0dWFsZm9jdXMnLCBlbGVtZW50cy5kb21SZWZlcmVuY2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsZW1lbnRzLmRvbVJlZmVyZW5jZS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGluZGV4UmVmLmN1cnJlbnQ7XG4gICAgY29uc3QgbWluSW5kZXggPSBnZXRNaW5MaXN0SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBtYXhJbmRleCA9IGdldE1heExpc3RJbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXMpO1xuICAgIGlmICghdHlwZWFibGVDb21ib2JveFJlZmVyZW5jZSkge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0hvbWUnKSB7XG4gICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBtaW5JbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VuZCcpIHtcbiAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IG1heEluZGV4O1xuICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gR3JpZCBuYXZpZ2F0aW9uLlxuICAgIGlmIChjb2xzID4gMSkge1xuICAgICAgY29uc3Qgc2l6ZXMgPSBpdGVtU2l6ZXMgfHwgQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogbGlzdFJlZi5jdXJyZW50Lmxlbmd0aFxuICAgICAgfSwgKCkgPT4gKHtcbiAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgIGhlaWdodDogMVxuICAgICAgfSkpO1xuICAgICAgLy8gVG8gY2FsY3VsYXRlIG1vdmVtZW50cyBvbiB0aGUgZ3JpZCwgd2UgdXNlIGh5cG90aGV0aWNhbCBjZWxsIGluZGljZXNcbiAgICAgIC8vIGFzIGlmIGV2ZXJ5IGl0ZW0gd2FzIDF4MSwgdGhlbiBjb252ZXJ0IGJhY2sgdG8gcmVhbCBpbmRpY2VzLlxuICAgICAgY29uc3QgY2VsbE1hcCA9IGNyZWF0ZUdyaWRDZWxsTWFwKHNpemVzLCBjb2xzLCBkZW5zZSk7XG4gICAgICBjb25zdCBtaW5HcmlkSW5kZXggPSBjZWxsTWFwLmZpbmRJbmRleChpbmRleCA9PiBpbmRleCAhPSBudWxsICYmICFpc0xpc3RJbmRleERpc2FibGVkKGxpc3RSZWYsIGluZGV4LCBkaXNhYmxlZEluZGljZXMpKTtcbiAgICAgIC8vIGxhc3QgZW5hYmxlZCBpbmRleFxuICAgICAgY29uc3QgbWF4R3JpZEluZGV4ID0gY2VsbE1hcC5yZWR1Y2UoKGZvdW5kSW5kZXgsIGluZGV4LCBjZWxsSW5kZXgpID0+IGluZGV4ICE9IG51bGwgJiYgIWlzTGlzdEluZGV4RGlzYWJsZWQobGlzdFJlZiwgaW5kZXgsIGRpc2FibGVkSW5kaWNlcykgPyBjZWxsSW5kZXggOiBmb3VuZEluZGV4LCAtMSk7XG4gICAgICBjb25zdCBpbmRleCA9IGNlbGxNYXBbZ2V0R3JpZE5hdmlnYXRlZEluZGV4KHtcbiAgICAgICAgY3VycmVudDogY2VsbE1hcC5tYXAoaXRlbUluZGV4ID0+IGl0ZW1JbmRleCAhPSBudWxsID8gbGlzdFJlZi5jdXJyZW50W2l0ZW1JbmRleF0gOiBudWxsKVxuICAgICAgfSwge1xuICAgICAgICBldmVudCxcbiAgICAgICAgb3JpZW50YXRpb24sXG4gICAgICAgIGxvb3AsXG4gICAgICAgIHJ0bCxcbiAgICAgICAgY29scyxcbiAgICAgICAgLy8gdHJlYXQgdW5kZWZpbmVkIChlbXB0eSBncmlkIHNwYWNlcykgYXMgZGlzYWJsZWQgaW5kaWNlcyBzbyB3ZVxuICAgICAgICAvLyBkb24ndCBlbmQgdXAgaW4gdGhlbVxuICAgICAgICBkaXNhYmxlZEluZGljZXM6IGdldEdyaWRDZWxsSW5kaWNlcyhbLi4uKGRpc2FibGVkSW5kaWNlcyB8fCBsaXN0UmVmLmN1cnJlbnQubWFwKChfLCBpbmRleCkgPT4gaXNMaXN0SW5kZXhEaXNhYmxlZChsaXN0UmVmLCBpbmRleCkgPyBpbmRleCA6IHVuZGVmaW5lZCkpLCB1bmRlZmluZWRdLCBjZWxsTWFwKSxcbiAgICAgICAgbWluSW5kZXg6IG1pbkdyaWRJbmRleCxcbiAgICAgICAgbWF4SW5kZXg6IG1heEdyaWRJbmRleCxcbiAgICAgICAgcHJldkluZGV4OiBnZXRHcmlkQ2VsbEluZGV4T2ZDb3JuZXIoaW5kZXhSZWYuY3VycmVudCA+IG1heEluZGV4ID8gbWluSW5kZXggOiBpbmRleFJlZi5jdXJyZW50LCBzaXplcywgY2VsbE1hcCwgY29scyxcbiAgICAgICAgLy8gdXNlIGEgY29ybmVyIG1hdGNoaW5nIHRoZSBlZGdlIGNsb3Nlc3QgdG8gdGhlIGRpcmVjdGlvblxuICAgICAgICAvLyB3ZSdyZSBtb3ZpbmcgaW4gc28gd2UgZG9uJ3QgZW5kIHVwIGluIHRoZSBzYW1lIGl0ZW0uIFByZWZlclxuICAgICAgICAvLyB0b3AvbGVmdCBvdmVyIGJvdHRvbS9yaWdodC5cbiAgICAgICAgZXZlbnQua2V5ID09PSBBUlJPV19ET1dOID8gJ2JsJyA6IGV2ZW50LmtleSA9PT0gKHJ0bCA/IEFSUk9XX0xFRlQgOiBBUlJPV19SSUdIVCkgPyAndHInIDogJ3RsJyksXG4gICAgICAgIHN0b3BFdmVudDogdHJ1ZVxuICAgICAgfSldO1xuICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGluZGV4O1xuICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZW50YXRpb24gPT09ICdib3RoJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc01haW5PcmllbnRhdGlvbktleShldmVudC5rZXksIG9yaWVudGF0aW9uKSkge1xuICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcblxuICAgICAgLy8gUmVzZXQgdGhlIGluZGV4IGlmIG5vIGl0ZW0gaXMgZm9jdXNlZC5cbiAgICAgIGlmIChvcGVuICYmICF2aXJ0dWFsICYmIGFjdGl2ZUVsZW1lbnQoZXZlbnQuY3VycmVudFRhcmdldC5vd25lckRvY3VtZW50KSA9PT0gZXZlbnQuY3VycmVudFRhcmdldCkge1xuICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gaXNNYWluT3JpZW50YXRpb25Ub0VuZEtleShldmVudC5rZXksIG9yaWVudGF0aW9uLCBydGwpID8gbWluSW5kZXggOiBtYXhJbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoaXNNYWluT3JpZW50YXRpb25Ub0VuZEtleShldmVudC5rZXksIG9yaWVudGF0aW9uLCBydGwpKSB7XG4gICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGN1cnJlbnRJbmRleCA+PSBtYXhJbmRleCA/IGFsbG93RXNjYXBlICYmIGN1cnJlbnRJbmRleCAhPT0gbGlzdFJlZi5jdXJyZW50Lmxlbmd0aCA/IC0xIDogbWluSW5kZXggOiBmaW5kTm9uRGlzYWJsZWRMaXN0SW5kZXgobGlzdFJlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IE1hdGgubWluKG1heEluZGV4LCBmaW5kTm9uRGlzYWJsZWRMaXN0SW5kZXgobGlzdFJlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobG9vcCkge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBjdXJyZW50SW5kZXggPD0gbWluSW5kZXggPyBhbGxvd0VzY2FwZSAmJiBjdXJyZW50SW5kZXggIT09IC0xID8gbGlzdFJlZi5jdXJyZW50Lmxlbmd0aCA6IG1heEluZGV4IDogZmluZE5vbkRpc2FibGVkTGlzdEluZGV4KGxpc3RSZWYsIHtcbiAgICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IGN1cnJlbnRJbmRleCxcbiAgICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBNYXRoLm1heChtaW5JbmRleCwgZmluZE5vbkRpc2FibGVkTGlzdEluZGV4KGxpc3RSZWYsIHtcbiAgICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IGN1cnJlbnRJbmRleCxcbiAgICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzSW5kZXhPdXRPZkxpc3RCb3VuZHMobGlzdFJlZiwgaW5kZXhSZWYuY3VycmVudCkpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IC0xO1xuICAgICAgfVxuICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IGFyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIHJldHVybiB2aXJ0dWFsICYmIG9wZW4gJiYgaGFzQWN0aXZlSW5kZXggJiYge1xuICAgICAgJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCc6IHZpcnR1YWxJZCB8fCBhY3RpdmVJZFxuICAgIH07XG4gIH0sIFt2aXJ0dWFsLCBvcGVuLCBoYXNBY3RpdmVJbmRleCwgdmlydHVhbElkLCBhY3RpdmVJZF0pO1xuICBjb25zdCBmbG9hdGluZyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAnYXJpYS1vcmllbnRhdGlvbic6IG9yaWVudGF0aW9uID09PSAnYm90aCcgPyB1bmRlZmluZWQgOiBvcmllbnRhdGlvbixcbiAgICAgIC4uLighdHlwZWFibGVDb21ib2JveFJlZmVyZW5jZSA/IGFyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCA6IHt9KSxcbiAgICAgIG9uS2V5RG93bjogY29tbW9uT25LZXlEb3duLFxuICAgICAgb25Qb2ludGVyTW92ZSgpIHtcbiAgICAgICAgaXNQb2ludGVyTW9kYWxpdHlSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW2FyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCwgY29tbW9uT25LZXlEb3duLCBvcmllbnRhdGlvbiwgdHlwZWFibGVDb21ib2JveFJlZmVyZW5jZV0pO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBmdW5jdGlvbiBjaGVja1ZpcnR1YWxNb3VzZShldmVudCkge1xuICAgICAgaWYgKGZvY3VzSXRlbU9uT3BlbiA9PT0gJ2F1dG8nICYmIGlzVmlydHVhbENsaWNrKGV2ZW50Lm5hdGl2ZUV2ZW50KSkge1xuICAgICAgICBmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNoZWNrVmlydHVhbFBvaW50ZXIoZXZlbnQpIHtcbiAgICAgIC8vIGBwb2ludGVyZG93bmAgZmlyZXMgZmlyc3QsIHJlc2V0IHRoZSBzdGF0ZSB0aGVuIHBlcmZvcm0gdGhlIGNoZWNrcy5cbiAgICAgIGZvY3VzSXRlbU9uT3BlblJlZi5jdXJyZW50ID0gZm9jdXNJdGVtT25PcGVuO1xuICAgICAgaWYgKGZvY3VzSXRlbU9uT3BlbiA9PT0gJ2F1dG8nICYmIGlzVmlydHVhbFBvaW50ZXJFdmVudChldmVudC5uYXRpdmVFdmVudCkpIHtcbiAgICAgICAgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgLi4uYXJpYUFjdGl2ZURlc2NlbmRhbnRQcm9wLFxuICAgICAgb25LZXlEb3duKGV2ZW50KSB7XG4gICAgICAgIGlzUG9pbnRlck1vZGFsaXR5UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgaXNBcnJvd0tleSA9IGV2ZW50LmtleS5zdGFydHNXaXRoKCdBcnJvdycpO1xuICAgICAgICBjb25zdCBpc0hvbWVPckVuZEtleSA9IFsnSG9tZScsICdFbmQnXS5pbmNsdWRlcyhldmVudC5rZXkpO1xuICAgICAgICBjb25zdCBpc01vdmVLZXkgPSBpc0Fycm93S2V5IHx8IGlzSG9tZU9yRW5kS2V5O1xuICAgICAgICBjb25zdCBpc0Nyb3NzT3BlbktleSA9IGlzQ3Jvc3NPcmllbnRhdGlvbk9wZW5LZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbiwgcnRsKTtcbiAgICAgICAgY29uc3QgaXNDcm9zc0Nsb3NlS2V5ID0gaXNDcm9zc09yaWVudGF0aW9uQ2xvc2VLZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbiwgcnRsLCBjb2xzKTtcbiAgICAgICAgY29uc3QgaXNQYXJlbnRDcm9zc09wZW5LZXkgPSBpc0Nyb3NzT3JpZW50YXRpb25PcGVuS2V5KGV2ZW50LmtleSwgZ2V0UGFyZW50T3JpZW50YXRpb24oKSwgcnRsKTtcbiAgICAgICAgY29uc3QgaXNNYWluS2V5ID0gaXNNYWluT3JpZW50YXRpb25LZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbik7XG4gICAgICAgIGNvbnN0IGlzTmF2aWdhdGlvbktleSA9IChuZXN0ZWQgPyBpc1BhcmVudENyb3NzT3BlbktleSA6IGlzTWFpbktleSkgfHwgZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleS50cmltKCkgPT09ICcnO1xuICAgICAgICBpZiAodmlydHVhbCAmJiBvcGVuKSB7XG4gICAgICAgICAgY29uc3Qgcm9vdE5vZGUgPSB0cmVlID09IG51bGwgPyB2b2lkIDAgOiB0cmVlLm5vZGVzUmVmLmN1cnJlbnQuZmluZChub2RlID0+IG5vZGUucGFyZW50SWQgPT0gbnVsbCk7XG4gICAgICAgICAgY29uc3QgZGVlcGVzdE5vZGUgPSB0cmVlICYmIHJvb3ROb2RlID8gZ2V0RGVlcGVzdE5vZGUodHJlZS5ub2Rlc1JlZi5jdXJyZW50LCByb290Tm9kZS5pZCkgOiBudWxsO1xuICAgICAgICAgIGlmIChpc01vdmVLZXkgJiYgZGVlcGVzdE5vZGUgJiYgdmlydHVhbEl0ZW1SZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50T2JqZWN0ID0gbmV3IEtleWJvYXJkRXZlbnQoJ2tleWRvd24nLCB7XG4gICAgICAgICAgICAgIGtleTogZXZlbnQua2V5LFxuICAgICAgICAgICAgICBidWJibGVzOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChpc0Nyb3NzT3BlbktleSB8fCBpc0Nyb3NzQ2xvc2VLZXkpIHtcbiAgICAgICAgICAgICAgdmFyIF9kZWVwZXN0Tm9kZSRjb250ZXh0LCBfZGVlcGVzdE5vZGUkY29udGV4dDI7XG4gICAgICAgICAgICAgIGNvbnN0IGlzQ3VycmVudFRhcmdldCA9ICgoX2RlZXBlc3ROb2RlJGNvbnRleHQgPSBkZWVwZXN0Tm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RlZXBlc3ROb2RlJGNvbnRleHQuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSA9PT0gZXZlbnQuY3VycmVudFRhcmdldDtcbiAgICAgICAgICAgICAgY29uc3QgZGlzcGF0Y2hJdGVtID0gaXNDcm9zc0Nsb3NlS2V5ICYmICFpc0N1cnJlbnRUYXJnZXQgPyAoX2RlZXBlc3ROb2RlJGNvbnRleHQyID0gZGVlcGVzdE5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9kZWVwZXN0Tm9kZSRjb250ZXh0Mi5lbGVtZW50cy5kb21SZWZlcmVuY2UgOiBpc0Nyb3NzT3BlbktleSA/IGxpc3RSZWYuY3VycmVudC5maW5kKGl0ZW0gPT4gKGl0ZW0gPT0gbnVsbCA/IHZvaWQgMCA6IGl0ZW0uaWQpID09PSBhY3RpdmVJZCkgOiBudWxsO1xuICAgICAgICAgICAgICBpZiAoZGlzcGF0Y2hJdGVtKSB7XG4gICAgICAgICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgICAgICBkaXNwYXRjaEl0ZW0uZGlzcGF0Y2hFdmVudChldmVudE9iamVjdCk7XG4gICAgICAgICAgICAgICAgc2V0VmlydHVhbElkKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgoaXNNYWluS2V5IHx8IGlzSG9tZU9yRW5kS2V5KSAmJiBkZWVwZXN0Tm9kZS5jb250ZXh0KSB7XG4gICAgICAgICAgICAgIGlmIChkZWVwZXN0Tm9kZS5jb250ZXh0Lm9wZW4gJiYgZGVlcGVzdE5vZGUucGFyZW50SWQgJiYgZXZlbnQuY3VycmVudFRhcmdldCAhPT0gZGVlcGVzdE5vZGUuY29udGV4dC5lbGVtZW50cy5kb21SZWZlcmVuY2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2RlZXBlc3ROb2RlJGNvbnRleHQkO1xuICAgICAgICAgICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgICAgICAgICAgKF9kZWVwZXN0Tm9kZSRjb250ZXh0JCA9IGRlZXBlc3ROb2RlLmNvbnRleHQuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSA9PSBudWxsIHx8IF9kZWVwZXN0Tm9kZSRjb250ZXh0JC5kaXNwYXRjaEV2ZW50KGV2ZW50T2JqZWN0KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNvbW1vbk9uS2V5RG93bihldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgYSBmbG9hdGluZyBlbGVtZW50IHNob3VsZCBub3Qgb3BlbiBvbiBhcnJvdyBrZXkgZG93biwgYXZvaWRcbiAgICAgICAgLy8gc2V0dGluZyBgYWN0aXZlSW5kZXhgIHdoaWxlIGl0J3MgY2xvc2VkLlxuICAgICAgICBpZiAoIW9wZW4gJiYgIW9wZW5PbkFycm93S2V5RG93biAmJiBpc0Fycm93S2V5KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdmlnYXRpb25LZXkpIHtcbiAgICAgICAgICBjb25zdCBpc1BhcmVudE1haW5LZXkgPSBpc01haW5PcmllbnRhdGlvbktleShldmVudC5rZXksIGdldFBhcmVudE9yaWVudGF0aW9uKCkpO1xuICAgICAgICAgIGtleVJlZi5jdXJyZW50ID0gbmVzdGVkICYmIGlzUGFyZW50TWFpbktleSA/IG51bGwgOiBldmVudC5rZXk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lc3RlZCkge1xuICAgICAgICAgIGlmIChpc1BhcmVudENyb3NzT3BlbktleSkge1xuICAgICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGlmIChvcGVuKSB7XG4gICAgICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBnZXRNaW5MaXN0SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzUmVmLmN1cnJlbnQpO1xuICAgICAgICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc01haW5LZXkpIHtcbiAgICAgICAgICBpZiAoc2VsZWN0ZWRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICBpZiAoIW9wZW4gJiYgb3Blbk9uQXJyb3dLZXlEb3duKSB7XG4gICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29tbW9uT25LZXlEb3duKGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9wZW4pIHtcbiAgICAgICAgICAgIG9uTmF2aWdhdGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvbkZvY3VzKCkge1xuICAgICAgICBpZiAob3BlbiAmJiAhdmlydHVhbCkge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSAtMTtcbiAgICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvblBvaW50ZXJEb3duOiBjaGVja1ZpcnR1YWxQb2ludGVyLFxuICAgICAgb25Qb2ludGVyRW50ZXI6IGNoZWNrVmlydHVhbFBvaW50ZXIsXG4gICAgICBvbk1vdXNlRG93bjogY2hlY2tWaXJ0dWFsTW91c2UsXG4gICAgICBvbkNsaWNrOiBjaGVja1ZpcnR1YWxNb3VzZVxuICAgIH07XG4gIH0sIFthY3RpdmVJZCwgYXJpYUFjdGl2ZURlc2NlbmRhbnRQcm9wLCBjb2xzLCBjb21tb25PbktleURvd24sIGRpc2FibGVkSW5kaWNlc1JlZiwgZm9jdXNJdGVtT25PcGVuLCBsaXN0UmVmLCBuZXN0ZWQsIG9uTmF2aWdhdGUsIG9uT3BlbkNoYW5nZSwgb3Blbiwgb3Blbk9uQXJyb3dLZXlEb3duLCBvcmllbnRhdGlvbiwgZ2V0UGFyZW50T3JpZW50YXRpb24sIHJ0bCwgc2VsZWN0ZWRJbmRleCwgdHJlZSwgdmlydHVhbCwgdmlydHVhbEl0ZW1SZWZdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2UsXG4gICAgZmxvYXRpbmcsXG4gICAgaXRlbVxuICB9IDoge30sIFtlbmFibGVkLCByZWZlcmVuY2UsIGZsb2F0aW5nLCBpdGVtXSk7XG59XG5cbmNvbnN0IGNvbXBvbmVudFJvbGVUb0FyaWFSb2xlTWFwID0gLyojX19QVVJFX18qL25ldyBNYXAoW1snc2VsZWN0JywgJ2xpc3Rib3gnXSwgWydjb21ib2JveCcsICdsaXN0Ym94J10sIFsnbGFiZWwnLCBmYWxzZV1dKTtcblxuLyoqXG4gKiBBZGRzIGJhc2Ugc2NyZWVuIHJlYWRlciBwcm9wcyB0byB0aGUgcmVmZXJlbmNlIGFuZCBmbG9hdGluZyBlbGVtZW50cyBmb3IgYVxuICogZ2l2ZW4gZmxvYXRpbmcgZWxlbWVudCBgcm9sZWAuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlUm9sZVxuICovXG5mdW5jdGlvbiB1c2VSb2xlKGNvbnRleHQsIHByb3BzKSB7XG4gIHZhciBfZWxlbWVudHMkZG9tUmVmZXJlbmMsIF9jb21wb25lbnRSb2xlVG9BcmlhUjtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIGVsZW1lbnRzLFxuICAgIGZsb2F0aW5nSWQ6IGRlZmF1bHRGbG9hdGluZ0lkXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgcm9sZSA9ICdkaWFsb2cnXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgZGVmYXVsdFJlZmVyZW5jZUlkID0gdXNlSWQoKTtcbiAgY29uc3QgcmVmZXJlbmNlSWQgPSAoKF9lbGVtZW50cyRkb21SZWZlcmVuYyA9IGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50cyRkb21SZWZlcmVuYy5pZCkgfHwgZGVmYXVsdFJlZmVyZW5jZUlkO1xuICBjb25zdCBmbG9hdGluZ0lkID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgdmFyIF9nZXRGbG9hdGluZ0ZvY3VzRWxlbTtcbiAgICByZXR1cm4gKChfZ2V0RmxvYXRpbmdGb2N1c0VsZW0gPSBnZXRGbG9hdGluZ0ZvY3VzRWxlbWVudChlbGVtZW50cy5mbG9hdGluZykpID09IG51bGwgPyB2b2lkIDAgOiBfZ2V0RmxvYXRpbmdGb2N1c0VsZW0uaWQpIHx8IGRlZmF1bHRGbG9hdGluZ0lkO1xuICB9LCBbZWxlbWVudHMuZmxvYXRpbmcsIGRlZmF1bHRGbG9hdGluZ0lkXSk7XG4gIGNvbnN0IGFyaWFSb2xlID0gKF9jb21wb25lbnRSb2xlVG9BcmlhUiA9IGNvbXBvbmVudFJvbGVUb0FyaWFSb2xlTWFwLmdldChyb2xlKSkgIT0gbnVsbCA/IF9jb21wb25lbnRSb2xlVG9BcmlhUiA6IHJvbGU7XG4gIGNvbnN0IHBhcmVudElkID0gdXNlRmxvYXRpbmdQYXJlbnROb2RlSWQoKTtcbiAgY29uc3QgaXNOZXN0ZWQgPSBwYXJlbnRJZCAhPSBudWxsO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoYXJpYVJvbGUgPT09ICd0b29sdGlwJyB8fCByb2xlID09PSAnbGFiZWwnKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBbXCJhcmlhLVwiICsgKHJvbGUgPT09ICdsYWJlbCcgPyAnbGFiZWxsZWRieScgOiAnZGVzY3JpYmVkYnknKV06IG9wZW4gPyBmbG9hdGluZ0lkIDogdW5kZWZpbmVkXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgJ2FyaWEtZXhwYW5kZWQnOiBvcGVuID8gJ3RydWUnIDogJ2ZhbHNlJyxcbiAgICAgICdhcmlhLWhhc3BvcHVwJzogYXJpYVJvbGUgPT09ICdhbGVydGRpYWxvZycgPyAnZGlhbG9nJyA6IGFyaWFSb2xlLFxuICAgICAgJ2FyaWEtY29udHJvbHMnOiBvcGVuID8gZmxvYXRpbmdJZCA6IHVuZGVmaW5lZCxcbiAgICAgIC4uLihhcmlhUm9sZSA9PT0gJ2xpc3Rib3gnICYmIHtcbiAgICAgICAgcm9sZTogJ2NvbWJvYm94J1xuICAgICAgfSksXG4gICAgICAuLi4oYXJpYVJvbGUgPT09ICdtZW51JyAmJiB7XG4gICAgICAgIGlkOiByZWZlcmVuY2VJZFxuICAgICAgfSksXG4gICAgICAuLi4oYXJpYVJvbGUgPT09ICdtZW51JyAmJiBpc05lc3RlZCAmJiB7XG4gICAgICAgIHJvbGU6ICdtZW51aXRlbSdcbiAgICAgIH0pLFxuICAgICAgLi4uKHJvbGUgPT09ICdzZWxlY3QnICYmIHtcbiAgICAgICAgJ2FyaWEtYXV0b2NvbXBsZXRlJzogJ25vbmUnXG4gICAgICB9KSxcbiAgICAgIC4uLihyb2xlID09PSAnY29tYm9ib3gnICYmIHtcbiAgICAgICAgJ2FyaWEtYXV0b2NvbXBsZXRlJzogJ2xpc3QnXG4gICAgICB9KVxuICAgIH07XG4gIH0sIFthcmlhUm9sZSwgZmxvYXRpbmdJZCwgaXNOZXN0ZWQsIG9wZW4sIHJlZmVyZW5jZUlkLCByb2xlXSk7XG4gIGNvbnN0IGZsb2F0aW5nID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgZmxvYXRpbmdQcm9wcyA9IHtcbiAgICAgIGlkOiBmbG9hdGluZ0lkLFxuICAgICAgLi4uKGFyaWFSb2xlICYmIHtcbiAgICAgICAgcm9sZTogYXJpYVJvbGVcbiAgICAgIH0pXG4gICAgfTtcbiAgICBpZiAoYXJpYVJvbGUgPT09ICd0b29sdGlwJyB8fCByb2xlID09PSAnbGFiZWwnKSB7XG4gICAgICByZXR1cm4gZmxvYXRpbmdQcm9wcztcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZsb2F0aW5nUHJvcHMsXG4gICAgICAuLi4oYXJpYVJvbGUgPT09ICdtZW51JyAmJiB7XG4gICAgICAgICdhcmlhLWxhYmVsbGVkYnknOiByZWZlcmVuY2VJZFxuICAgICAgfSlcbiAgICB9O1xuICB9LCBbYXJpYVJvbGUsIGZsb2F0aW5nSWQsIHJlZmVyZW5jZUlkLCByb2xlXSk7XG4gIGNvbnN0IGl0ZW0gPSBSZWFjdC51c2VDYWxsYmFjayhfcmVmID0+IHtcbiAgICBsZXQge1xuICAgICAgYWN0aXZlLFxuICAgICAgc2VsZWN0ZWRcbiAgICB9ID0gX3JlZjtcbiAgICBjb25zdCBjb21tb25Qcm9wcyA9IHtcbiAgICAgIHJvbGU6ICdvcHRpb24nLFxuICAgICAgLi4uKGFjdGl2ZSAmJiB7XG4gICAgICAgIGlkOiBmbG9hdGluZ0lkICsgXCItZnVpLW9wdGlvblwiXG4gICAgICB9KVxuICAgIH07XG5cbiAgICAvLyBGb3IgYG1lbnVgLCB3ZSBhcmUgdW5hYmxlIHRvIHRlbGwgaWYgdGhlIGl0ZW0gaXMgYSBgbWVudWl0ZW1yYWRpb2BcbiAgICAvLyBvciBgbWVudWl0ZW1jaGVja2JveGAuIEZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSByZWFzb25zLCBhbHNvXG4gICAgLy8gYXZvaWQgZGVmYXVsdGluZyB0byBgbWVudWl0ZW1gIGFzIGl0IG1heSBvdmVyd3JpdGUgY3VzdG9tIHJvbGUgcHJvcHMuXG4gICAgc3dpdGNoIChyb2xlKSB7XG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmNvbW1vblByb3BzLFxuICAgICAgICAgICdhcmlhLXNlbGVjdGVkJzogYWN0aXZlICYmIHNlbGVjdGVkXG4gICAgICAgIH07XG4gICAgICBjYXNlICdjb21ib2JveCc6XG4gICAgICAgIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uUHJvcHMsXG4gICAgICAgICAgICAnYXJpYS1zZWxlY3RlZCc6IHNlbGVjdGVkXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH0sIFtmbG9hdGluZ0lkLCByb2xlXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nLFxuICAgIGl0ZW1cbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlLCBmbG9hdGluZywgaXRlbV0pO1xufVxuXG4vLyBDb252ZXJ0cyBhIEpTIHN0eWxlIGtleSBsaWtlIGBiYWNrZ3JvdW5kQ29sb3JgIHRvIGEgQ1NTIHRyYW5zaXRpb24tcHJvcGVydHlcbi8vIGxpa2UgYGJhY2tncm91bmQtY29sb3JgLlxuY29uc3QgY2FtZWxDYXNlVG9LZWJhYkNhc2UgPSBzdHIgPT4gc3RyLnJlcGxhY2UoL1tBLVpdKyg/IVthLXpdKXxbQS1aXS9nLCAoJCwgb2ZzKSA9PiAob2ZzID8gJy0nIDogJycpICsgJC50b0xvd2VyQ2FzZSgpKTtcbmZ1bmN0aW9uIGV4ZWNXaXRoQXJnc09yUmV0dXJuKHZhbHVlT3JGbiwgYXJncykge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlT3JGbiA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlT3JGbihhcmdzKSA6IHZhbHVlT3JGbjtcbn1cbmZ1bmN0aW9uIHVzZURlbGF5VW5tb3VudChvcGVuLCBkdXJhdGlvbk1zKSB7XG4gIGNvbnN0IFtpc01vdW50ZWQsIHNldElzTW91bnRlZF0gPSBSZWFjdC51c2VTdGF0ZShvcGVuKTtcbiAgaWYgKG9wZW4gJiYgIWlzTW91bnRlZCkge1xuICAgIHNldElzTW91bnRlZCh0cnVlKTtcbiAgfVxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3BlbiAmJiBpc01vdW50ZWQpIHtcbiAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHNldElzTW91bnRlZChmYWxzZSksIGR1cmF0aW9uTXMpO1xuICAgICAgcmV0dXJuICgpID0+IGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICB9XG4gIH0sIFtvcGVuLCBpc01vdW50ZWQsIGR1cmF0aW9uTXNdKTtcbiAgcmV0dXJuIGlzTW91bnRlZDtcbn1cbi8qKlxuICogUHJvdmlkZXMgYSBzdGF0dXMgc3RyaW5nIHRvIGFwcGx5IENTUyB0cmFuc2l0aW9ucyB0byBhIGZsb2F0aW5nIGVsZW1lbnQsXG4gKiBjb3JyZWN0bHkgaGFuZGxpbmcgcGxhY2VtZW50LWF3YXJlIHRyYW5zaXRpb25zLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZVRyYW5zaXRpb24jdXNldHJhbnNpdGlvbnN0YXR1c1xuICovXG5mdW5jdGlvbiB1c2VUcmFuc2l0aW9uU3RhdHVzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBlbGVtZW50czoge1xuICAgICAgZmxvYXRpbmdcbiAgICB9XG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZHVyYXRpb24gPSAyNTBcbiAgfSA9IHByb3BzO1xuICBjb25zdCBpc051bWJlckR1cmF0aW9uID0gdHlwZW9mIGR1cmF0aW9uID09PSAnbnVtYmVyJztcbiAgY29uc3QgY2xvc2VEdXJhdGlvbiA9IChpc051bWJlckR1cmF0aW9uID8gZHVyYXRpb24gOiBkdXJhdGlvbi5jbG9zZSkgfHwgMDtcbiAgY29uc3QgW3N0YXR1cywgc2V0U3RhdHVzXSA9IFJlYWN0LnVzZVN0YXRlKCd1bm1vdW50ZWQnKTtcbiAgY29uc3QgaXNNb3VudGVkID0gdXNlRGVsYXlVbm1vdW50KG9wZW4sIGNsb3NlRHVyYXRpb24pO1xuICBpZiAoIWlzTW91bnRlZCAmJiBzdGF0dXMgPT09ICdjbG9zZScpIHtcbiAgICBzZXRTdGF0dXMoJ3VubW91bnRlZCcpO1xuICB9XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFmbG9hdGluZykgcmV0dXJuO1xuICAgIGlmIChvcGVuKSB7XG4gICAgICBzZXRTdGF0dXMoJ2luaXRpYWwnKTtcbiAgICAgIGNvbnN0IGZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgLy8gRW5zdXJlIGl0IG9wZW5zIGJlZm9yZSBwYWludC4gV2l0aCBgRmxvYXRpbmdEZWxheUdyb3VwYCxcbiAgICAgICAgLy8gdGhpcyBhdm9pZHMgYSBmbGlja2VyIHdoZW4gbW92aW5nIGJldHdlZW4gZmxvYXRpbmcgZWxlbWVudHNcbiAgICAgICAgLy8gdG8gZW5zdXJlIG9uZSBpcyBhbHdheXMgb3BlbiB3aXRoIG5vIG1pc3NpbmcgZnJhbWVzLlxuICAgICAgICBSZWFjdERPTS5mbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgIHNldFN0YXR1cygnb3BlbicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUoZnJhbWUpO1xuICAgICAgfTtcbiAgICB9XG4gICAgc2V0U3RhdHVzKCdjbG9zZScpO1xuICB9LCBbb3BlbiwgZmxvYXRpbmddKTtcbiAgcmV0dXJuIHtcbiAgICBpc01vdW50ZWQsXG4gICAgc3RhdHVzXG4gIH07XG59XG4vKipcbiAqIFByb3ZpZGVzIHN0eWxlcyB0byBhcHBseSBDU1MgdHJhbnNpdGlvbnMgdG8gYSBmbG9hdGluZyBlbGVtZW50LCBjb3JyZWN0bHlcbiAqIGhhbmRsaW5nIHBsYWNlbWVudC1hd2FyZSB0cmFuc2l0aW9ucy4gV3JhcHBlciBhcm91bmQgYHVzZVRyYW5zaXRpb25TdGF0dXNgLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZVRyYW5zaXRpb24jdXNldHJhbnNpdGlvbnN0eWxlc1xuICovXG5mdW5jdGlvbiB1c2VUcmFuc2l0aW9uU3R5bGVzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgaW5pdGlhbDogdW5zdGFibGVfaW5pdGlhbCA9IHtcbiAgICAgIG9wYWNpdHk6IDBcbiAgICB9LFxuICAgIG9wZW46IHVuc3RhYmxlX29wZW4sXG4gICAgY2xvc2U6IHVuc3RhYmxlX2Nsb3NlLFxuICAgIGNvbW1vbjogdW5zdGFibGVfY29tbW9uLFxuICAgIGR1cmF0aW9uID0gMjUwXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgcGxhY2VtZW50ID0gY29udGV4dC5wbGFjZW1lbnQ7XG4gIGNvbnN0IHNpZGUgPSBwbGFjZW1lbnQuc3BsaXQoJy0nKVswXTtcbiAgY29uc3QgZm5BcmdzID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIHNpZGUsXG4gICAgcGxhY2VtZW50XG4gIH0pLCBbc2lkZSwgcGxhY2VtZW50XSk7XG4gIGNvbnN0IGlzTnVtYmVyRHVyYXRpb24gPSB0eXBlb2YgZHVyYXRpb24gPT09ICdudW1iZXInO1xuICBjb25zdCBvcGVuRHVyYXRpb24gPSAoaXNOdW1iZXJEdXJhdGlvbiA/IGR1cmF0aW9uIDogZHVyYXRpb24ub3BlbikgfHwgMDtcbiAgY29uc3QgY2xvc2VEdXJhdGlvbiA9IChpc051bWJlckR1cmF0aW9uID8gZHVyYXRpb24gOiBkdXJhdGlvbi5jbG9zZSkgfHwgMDtcbiAgY29uc3QgW3N0eWxlcywgc2V0U3R5bGVzXSA9IFJlYWN0LnVzZVN0YXRlKCgpID0+ICh7XG4gICAgLi4uZXhlY1dpdGhBcmdzT3JSZXR1cm4odW5zdGFibGVfY29tbW9uLCBmbkFyZ3MpLFxuICAgIC4uLmV4ZWNXaXRoQXJnc09yUmV0dXJuKHVuc3RhYmxlX2luaXRpYWwsIGZuQXJncylcbiAgfSkpO1xuICBjb25zdCB7XG4gICAgaXNNb3VudGVkLFxuICAgIHN0YXR1c1xuICB9ID0gdXNlVHJhbnNpdGlvblN0YXR1cyhjb250ZXh0LCB7XG4gICAgZHVyYXRpb25cbiAgfSk7XG4gIGNvbnN0IGluaXRpYWxSZWYgPSB1c2VMYXRlc3RSZWYodW5zdGFibGVfaW5pdGlhbCk7XG4gIGNvbnN0IG9wZW5SZWYgPSB1c2VMYXRlc3RSZWYodW5zdGFibGVfb3Blbik7XG4gIGNvbnN0IGNsb3NlUmVmID0gdXNlTGF0ZXN0UmVmKHVuc3RhYmxlX2Nsb3NlKTtcbiAgY29uc3QgY29tbW9uUmVmID0gdXNlTGF0ZXN0UmVmKHVuc3RhYmxlX2NvbW1vbik7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgaW5pdGlhbFN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKGluaXRpYWxSZWYuY3VycmVudCwgZm5BcmdzKTtcbiAgICBjb25zdCBjbG9zZVN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKGNsb3NlUmVmLmN1cnJlbnQsIGZuQXJncyk7XG4gICAgY29uc3QgY29tbW9uU3R5bGVzID0gZXhlY1dpdGhBcmdzT3JSZXR1cm4oY29tbW9uUmVmLmN1cnJlbnQsIGZuQXJncyk7XG4gICAgY29uc3Qgb3BlblN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKG9wZW5SZWYuY3VycmVudCwgZm5BcmdzKSB8fCBPYmplY3Qua2V5cyhpbml0aWFsU3R5bGVzKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBhY2Nba2V5XSA9ICcnO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gICAgaWYgKHN0YXR1cyA9PT0gJ2luaXRpYWwnKSB7XG4gICAgICBzZXRTdHlsZXMoc3R5bGVzID0+ICh7XG4gICAgICAgIHRyYW5zaXRpb25Qcm9wZXJ0eTogc3R5bGVzLnRyYW5zaXRpb25Qcm9wZXJ0eSxcbiAgICAgICAgLi4uY29tbW9uU3R5bGVzLFxuICAgICAgICAuLi5pbml0aWFsU3R5bGVzXG4gICAgICB9KSk7XG4gICAgfVxuICAgIGlmIChzdGF0dXMgPT09ICdvcGVuJykge1xuICAgICAgc2V0U3R5bGVzKHtcbiAgICAgICAgdHJhbnNpdGlvblByb3BlcnR5OiBPYmplY3Qua2V5cyhvcGVuU3R5bGVzKS5tYXAoY2FtZWxDYXNlVG9LZWJhYkNhc2UpLmpvaW4oJywnKSxcbiAgICAgICAgdHJhbnNpdGlvbkR1cmF0aW9uOiBvcGVuRHVyYXRpb24gKyBcIm1zXCIsXG4gICAgICAgIC4uLmNvbW1vblN0eWxlcyxcbiAgICAgICAgLi4ub3BlblN0eWxlc1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChzdGF0dXMgPT09ICdjbG9zZScpIHtcbiAgICAgIGNvbnN0IHN0eWxlcyA9IGNsb3NlU3R5bGVzIHx8IGluaXRpYWxTdHlsZXM7XG4gICAgICBzZXRTdHlsZXMoe1xuICAgICAgICB0cmFuc2l0aW9uUHJvcGVydHk6IE9iamVjdC5rZXlzKHN0eWxlcykubWFwKGNhbWVsQ2FzZVRvS2ViYWJDYXNlKS5qb2luKCcsJyksXG4gICAgICAgIHRyYW5zaXRpb25EdXJhdGlvbjogY2xvc2VEdXJhdGlvbiArIFwibXNcIixcbiAgICAgICAgLi4uY29tbW9uU3R5bGVzLFxuICAgICAgICAuLi5zdHlsZXNcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwgW2Nsb3NlRHVyYXRpb24sIGNsb3NlUmVmLCBpbml0aWFsUmVmLCBvcGVuUmVmLCBjb21tb25SZWYsIG9wZW5EdXJhdGlvbiwgc3RhdHVzLCBmbkFyZ3NdKTtcbiAgcmV0dXJuIHtcbiAgICBpc01vdW50ZWQsXG4gICAgc3R5bGVzXG4gIH07XG59XG5cbi8qKlxuICogUHJvdmlkZXMgYSBtYXRjaGluZyBjYWxsYmFjayB0aGF0IGNhbiBiZSB1c2VkIHRvIGZvY3VzIGFuIGl0ZW0gYXMgdGhlIHVzZXJcbiAqIHR5cGVzLCBvZnRlbiB1c2VkIGluIHRhbmRlbSB3aXRoIGB1c2VMaXN0TmF2aWdhdGlvbigpYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VUeXBlYWhlYWRcbiAqL1xuZnVuY3Rpb24gdXNlVHlwZWFoZWFkKGNvbnRleHQsIHByb3BzKSB7XG4gIHZhciBfcmVmO1xuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBkYXRhUmVmXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgbGlzdFJlZixcbiAgICBhY3RpdmVJbmRleCxcbiAgICBvbk1hdGNoOiB1bnN0YWJsZV9vbk1hdGNoLFxuICAgIG9uVHlwaW5nQ2hhbmdlOiB1bnN0YWJsZV9vblR5cGluZ0NoYW5nZSxcbiAgICBlbmFibGVkID0gdHJ1ZSxcbiAgICBmaW5kTWF0Y2ggPSBudWxsLFxuICAgIHJlc2V0TXMgPSA3NTAsXG4gICAgaWdub3JlS2V5cyA9IFtdLFxuICAgIHNlbGVjdGVkSW5kZXggPSBudWxsXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdGltZW91dElkUmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3Qgc3RyaW5nUmVmID0gUmVhY3QudXNlUmVmKCcnKTtcbiAgY29uc3QgcHJldkluZGV4UmVmID0gUmVhY3QudXNlUmVmKChfcmVmID0gc2VsZWN0ZWRJbmRleCAhPSBudWxsID8gc2VsZWN0ZWRJbmRleCA6IGFjdGl2ZUluZGV4KSAhPSBudWxsID8gX3JlZiA6IC0xKTtcbiAgY29uc3QgbWF0Y2hJbmRleFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3Qgb25NYXRjaCA9IHVzZUVmZmVjdEV2ZW50KHVuc3RhYmxlX29uTWF0Y2gpO1xuICBjb25zdCBvblR5cGluZ0NoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KHVuc3RhYmxlX29uVHlwaW5nQ2hhbmdlKTtcbiAgY29uc3QgZmluZE1hdGNoUmVmID0gdXNlTGF0ZXN0UmVmKGZpbmRNYXRjaCk7XG4gIGNvbnN0IGlnbm9yZUtleXNSZWYgPSB1c2VMYXRlc3RSZWYoaWdub3JlS2V5cyk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKG9wZW4pIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRJZFJlZik7XG4gICAgICBtYXRjaEluZGV4UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgc3RyaW5nUmVmLmN1cnJlbnQgPSAnJztcbiAgICB9XG4gIH0sIFtvcGVuXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgLy8gU3luYyBhcnJvdyBrZXkgbmF2aWdhdGlvbiBidXQgbm90IHR5cGVhaGVhZCBuYXZpZ2F0aW9uLlxuICAgIGlmIChvcGVuICYmIHN0cmluZ1JlZi5jdXJyZW50ID09PSAnJykge1xuICAgICAgdmFyIF9yZWYyO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSAoX3JlZjIgPSBzZWxlY3RlZEluZGV4ICE9IG51bGwgPyBzZWxlY3RlZEluZGV4IDogYWN0aXZlSW5kZXgpICE9IG51bGwgPyBfcmVmMiA6IC0xO1xuICAgIH1cbiAgfSwgW29wZW4sIHNlbGVjdGVkSW5kZXgsIGFjdGl2ZUluZGV4XSk7XG4gIGNvbnN0IHNldFR5cGluZ0NoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KHZhbHVlID0+IHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGlmICghZGF0YVJlZi5jdXJyZW50LnR5cGluZykge1xuICAgICAgICBkYXRhUmVmLmN1cnJlbnQudHlwaW5nID0gdmFsdWU7XG4gICAgICAgIG9uVHlwaW5nQ2hhbmdlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGFSZWYuY3VycmVudC50eXBpbmcpIHtcbiAgICAgICAgZGF0YVJlZi5jdXJyZW50LnR5cGluZyA9IHZhbHVlO1xuICAgICAgICBvblR5cGluZ0NoYW5nZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgY29uc3Qgb25LZXlEb3duID0gdXNlRWZmZWN0RXZlbnQoZXZlbnQgPT4ge1xuICAgIGZ1bmN0aW9uIGdldE1hdGNoaW5nSW5kZXgobGlzdCwgb3JkZXJlZExpc3QsIHN0cmluZykge1xuICAgICAgY29uc3Qgc3RyID0gZmluZE1hdGNoUmVmLmN1cnJlbnQgPyBmaW5kTWF0Y2hSZWYuY3VycmVudChvcmRlcmVkTGlzdCwgc3RyaW5nKSA6IG9yZGVyZWRMaXN0LmZpbmQodGV4dCA9PiAodGV4dCA9PSBudWxsID8gdm9pZCAwIDogdGV4dC50b0xvY2FsZUxvd2VyQ2FzZSgpLmluZGV4T2Yoc3RyaW5nLnRvTG9jYWxlTG93ZXJDYXNlKCkpKSA9PT0gMCk7XG4gICAgICByZXR1cm4gc3RyID8gbGlzdC5pbmRleE9mKHN0cikgOiAtMTtcbiAgICB9XG4gICAgY29uc3QgbGlzdENvbnRlbnQgPSBsaXN0UmVmLmN1cnJlbnQ7XG4gICAgaWYgKHN0cmluZ1JlZi5jdXJyZW50Lmxlbmd0aCA+IDAgJiYgc3RyaW5nUmVmLmN1cnJlbnRbMF0gIT09ICcgJykge1xuICAgICAgaWYgKGdldE1hdGNoaW5nSW5kZXgobGlzdENvbnRlbnQsIGxpc3RDb250ZW50LCBzdHJpbmdSZWYuY3VycmVudCkgPT09IC0xKSB7XG4gICAgICAgIHNldFR5cGluZ0NoYW5nZShmYWxzZSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJyAnKSB7XG4gICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChsaXN0Q29udGVudCA9PSBudWxsIHx8IGlnbm9yZUtleXNSZWYuY3VycmVudC5pbmNsdWRlcyhldmVudC5rZXkpIHx8XG4gICAgLy8gQ2hhcmFjdGVyIGtleS5cbiAgICBldmVudC5rZXkubGVuZ3RoICE9PSAxIHx8XG4gICAgLy8gTW9kaWZpZXIga2V5LlxuICAgIGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5hbHRLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG9wZW4gJiYgZXZlbnQua2V5ICE9PSAnICcpIHtcbiAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICBzZXRUeXBpbmdDaGFuZ2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQmFpbCBvdXQgaWYgdGhlIGxpc3QgY29udGFpbnMgYSB3b3JkIGxpa2UgXCJsbGFtYVwiIG9yIFwiYWFyb25cIi4gVE9ETzpcbiAgICAvLyBhbGxvdyBpdCBpbiB0aGlzIGNhc2UsIHRvby5cbiAgICBjb25zdCBhbGxvd1JhcGlkU3VjY2Vzc2lvbk9mRmlyc3RMZXR0ZXIgPSBsaXN0Q29udGVudC5ldmVyeSh0ZXh0ID0+IHtcbiAgICAgIHZhciBfdGV4dCQsIF90ZXh0JDI7XG4gICAgICByZXR1cm4gdGV4dCA/ICgoX3RleHQkID0gdGV4dFswXSkgPT0gbnVsbCA/IHZvaWQgMCA6IF90ZXh0JC50b0xvY2FsZUxvd2VyQ2FzZSgpKSAhPT0gKChfdGV4dCQyID0gdGV4dFsxXSkgPT0gbnVsbCA/IHZvaWQgMCA6IF90ZXh0JDIudG9Mb2NhbGVMb3dlckNhc2UoKSkgOiB0cnVlO1xuICAgIH0pO1xuXG4gICAgLy8gQWxsb3dzIHRoZSB1c2VyIHRvIGN5Y2xlIHRocm91Z2ggaXRlbXMgdGhhdCBzdGFydCB3aXRoIHRoZSBzYW1lIGxldHRlclxuICAgIC8vIGluIHJhcGlkIHN1Y2Nlc3Npb24uXG4gICAgaWYgKGFsbG93UmFwaWRTdWNjZXNzaW9uT2ZGaXJzdExldHRlciAmJiBzdHJpbmdSZWYuY3VycmVudCA9PT0gZXZlbnQua2V5KSB7XG4gICAgICBzdHJpbmdSZWYuY3VycmVudCA9ICcnO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSBtYXRjaEluZGV4UmVmLmN1cnJlbnQ7XG4gICAgfVxuICAgIHN0cmluZ1JlZi5jdXJyZW50ICs9IGV2ZW50LmtleTtcbiAgICBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0SWRSZWYpO1xuICAgIHRpbWVvdXRJZFJlZi5jdXJyZW50ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3RyaW5nUmVmLmN1cnJlbnQgPSAnJztcbiAgICAgIHByZXZJbmRleFJlZi5jdXJyZW50ID0gbWF0Y2hJbmRleFJlZi5jdXJyZW50O1xuICAgICAgc2V0VHlwaW5nQ2hhbmdlKGZhbHNlKTtcbiAgICB9LCByZXNldE1zKTtcbiAgICBjb25zdCBwcmV2SW5kZXggPSBwcmV2SW5kZXhSZWYuY3VycmVudDtcbiAgICBjb25zdCBpbmRleCA9IGdldE1hdGNoaW5nSW5kZXgobGlzdENvbnRlbnQsIFsuLi5saXN0Q29udGVudC5zbGljZSgocHJldkluZGV4IHx8IDApICsgMSksIC4uLmxpc3RDb250ZW50LnNsaWNlKDAsIChwcmV2SW5kZXggfHwgMCkgKyAxKV0sIHN0cmluZ1JlZi5jdXJyZW50KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBvbk1hdGNoKGluZGV4KTtcbiAgICAgIG1hdGNoSW5kZXhSZWYuY3VycmVudCA9IGluZGV4O1xuICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ICE9PSAnICcpIHtcbiAgICAgIHN0cmluZ1JlZi5jdXJyZW50ID0gJyc7XG4gICAgICBzZXRUeXBpbmdDaGFuZ2UoZmFsc2UpO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBvbktleURvd25cbiAgfSksIFtvbktleURvd25dKTtcbiAgY29uc3QgZmxvYXRpbmcgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgb25LZXlEb3duLFxuICAgICAgb25LZXlVcChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnICcpIHtcbiAgICAgICAgICBzZXRUeXBpbmdDaGFuZ2UoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW29uS2V5RG93biwgc2V0VHlwaW5nQ2hhbmdlXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZSwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gZ2V0QXJnc1dpdGhDdXN0b21GbG9hdGluZ0hlaWdodChzdGF0ZSwgaGVpZ2h0KSB7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgcmVjdHM6IHtcbiAgICAgIC4uLnN0YXRlLnJlY3RzLFxuICAgICAgZmxvYXRpbmc6IHtcbiAgICAgICAgLi4uc3RhdGUucmVjdHMuZmxvYXRpbmcsXG4gICAgICAgIGhlaWdodFxuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbi8qKlxuICogUG9zaXRpb25zIHRoZSBmbG9hdGluZyBlbGVtZW50IHN1Y2ggdGhhdCBhbiBpbm5lciBlbGVtZW50IGluc2lkZSBvZiBpdCBpc1xuICogYW5jaG9yZWQgdG8gdGhlIHJlZmVyZW5jZSBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL2lubmVyXG4gKiBAZGVwcmVjYXRlZFxuICovXG5jb25zdCBpbm5lciA9IHByb3BzID0+ICh7XG4gIG5hbWU6ICdpbm5lcicsXG4gIG9wdGlvbnM6IHByb3BzLFxuICBhc3luYyBmbihzdGF0ZSkge1xuICAgIGNvbnN0IHtcbiAgICAgIGxpc3RSZWYsXG4gICAgICBvdmVyZmxvd1JlZixcbiAgICAgIG9uRmFsbGJhY2tDaGFuZ2UsXG4gICAgICBvZmZzZXQ6IGlubmVyT2Zmc2V0ID0gMCxcbiAgICAgIGluZGV4ID0gMCxcbiAgICAgIG1pbkl0ZW1zVmlzaWJsZSA9IDQsXG4gICAgICByZWZlcmVuY2VPdmVyZmxvd1RocmVzaG9sZCA9IDAsXG4gICAgICBzY3JvbGxSZWYsXG4gICAgICAuLi5kZXRlY3RPdmVyZmxvd09wdGlvbnNcbiAgICB9ID0gZXZhbHVhdGUocHJvcHMsIHN0YXRlKTtcbiAgICBjb25zdCB7XG4gICAgICByZWN0cyxcbiAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgIGZsb2F0aW5nXG4gICAgICB9XG4gICAgfSA9IHN0YXRlO1xuICAgIGNvbnN0IGl0ZW0gPSBsaXN0UmVmLmN1cnJlbnRbaW5kZXhdO1xuICAgIGNvbnN0IHNjcm9sbEVsID0gKHNjcm9sbFJlZiA9PSBudWxsID8gdm9pZCAwIDogc2Nyb2xsUmVmLmN1cnJlbnQpIHx8IGZsb2F0aW5nO1xuXG4gICAgLy8gVmFsaWQgY29tYmluYXRpb25zOlxuICAgIC8vIDEuIEZsb2F0aW5nIGVsZW1lbnQgaXMgdGhlIHNjcm9sbFJlZiBhbmQgaGFzIGEgYm9yZGVyIChkZWZhdWx0KVxuICAgIC8vIDIuIEZsb2F0aW5nIGVsZW1lbnQgaXMgbm90IHRoZSBzY3JvbGxSZWYsIGZsb2F0aW5nIGVsZW1lbnQgaGFzIGEgYm9yZGVyXG4gICAgLy8gMy4gRmxvYXRpbmcgZWxlbWVudCBpcyBub3QgdGhlIHNjcm9sbFJlZiwgc2Nyb2xsUmVmIGhhcyBhIGJvcmRlclxuICAgIC8vIEZsb2F0aW5nID4gey4uLmdldEZsb2F0aW5nUHJvcHMoKX0gd3JhcHBlciA+IHNjcm9sbFJlZiA+IGl0ZW1zIGlzIG5vdFxuICAgIC8vIGFsbG93ZWQgYXMgVm9pY2VPdmVyIGRvZXNuJ3Qgd29yay5cbiAgICBjb25zdCBjbGllbnRUb3AgPSBmbG9hdGluZy5jbGllbnRUb3AgfHwgc2Nyb2xsRWwuY2xpZW50VG9wO1xuICAgIGNvbnN0IGZsb2F0aW5nSXNCb3JkZXJlZCA9IGZsb2F0aW5nLmNsaWVudFRvcCAhPT0gMDtcbiAgICBjb25zdCBzY3JvbGxFbElzQm9yZGVyZWQgPSBzY3JvbGxFbC5jbGllbnRUb3AgIT09IDA7XG4gICAgY29uc3QgZmxvYXRpbmdJc1Njcm9sbEVsID0gZmxvYXRpbmcgPT09IHNjcm9sbEVsO1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgIGlmICghc3RhdGUucGxhY2VtZW50LnN0YXJ0c1dpdGgoJ2JvdHRvbScpKSB7XG4gICAgICAgIHdhcm4oJ2BwbGFjZW1lbnRgIHNpZGUgbXVzdCBiZSBcImJvdHRvbVwiIHdoZW4gdXNpbmcgdGhlIGBpbm5lcmAnLCAnbWlkZGxld2FyZS4nKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFpdGVtKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IG5leHRBcmdzID0ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICAuLi4oYXdhaXQgb2Zmc2V0KC1pdGVtLm9mZnNldFRvcCAtIGZsb2F0aW5nLmNsaWVudFRvcCAtIHJlY3RzLnJlZmVyZW5jZS5oZWlnaHQgLyAyIC0gaXRlbS5vZmZzZXRIZWlnaHQgLyAyIC0gaW5uZXJPZmZzZXQpLmZuKHN0YXRlKSlcbiAgICB9O1xuICAgIGNvbnN0IG92ZXJmbG93ID0gYXdhaXQgZGV0ZWN0T3ZlcmZsb3coZ2V0QXJnc1dpdGhDdXN0b21GbG9hdGluZ0hlaWdodChuZXh0QXJncywgc2Nyb2xsRWwuc2Nyb2xsSGVpZ2h0ICsgY2xpZW50VG9wICsgZmxvYXRpbmcuY2xpZW50VG9wKSwgZGV0ZWN0T3ZlcmZsb3dPcHRpb25zKTtcbiAgICBjb25zdCByZWZPdmVyZmxvdyA9IGF3YWl0IGRldGVjdE92ZXJmbG93KG5leHRBcmdzLCB7XG4gICAgICAuLi5kZXRlY3RPdmVyZmxvd09wdGlvbnMsXG4gICAgICBlbGVtZW50Q29udGV4dDogJ3JlZmVyZW5jZSdcbiAgICB9KTtcbiAgICBjb25zdCBkaWZmWSA9IG1heCgwLCBvdmVyZmxvdy50b3ApO1xuICAgIGNvbnN0IG5leHRZID0gbmV4dEFyZ3MueSArIGRpZmZZO1xuICAgIGNvbnN0IGlzU2Nyb2xsYWJsZSA9IHNjcm9sbEVsLnNjcm9sbEhlaWdodCA+IHNjcm9sbEVsLmNsaWVudEhlaWdodDtcbiAgICBjb25zdCByb3VuZGVyID0gaXNTY3JvbGxhYmxlID8gdiA9PiB2IDogcm91bmQ7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gcm91bmRlcihtYXgoMCwgc2Nyb2xsRWwuc2Nyb2xsSGVpZ2h0ICsgKGZsb2F0aW5nSXNCb3JkZXJlZCAmJiBmbG9hdGluZ0lzU2Nyb2xsRWwgfHwgc2Nyb2xsRWxJc0JvcmRlcmVkID8gY2xpZW50VG9wICogMiA6IDApIC0gZGlmZlkgLSBtYXgoMCwgb3ZlcmZsb3cuYm90dG9tKSkpO1xuICAgIHNjcm9sbEVsLnN0eWxlLm1heEhlaWdodCA9IG1heEhlaWdodCArIFwicHhcIjtcbiAgICBzY3JvbGxFbC5zY3JvbGxUb3AgPSBkaWZmWTtcblxuICAgIC8vIFRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UsIGZhbGxiYWNrIHRvIHN0YW5kYXJkIGFuY2hvcmVkIHBvc2l0aW9uaW5nXG4gICAgaWYgKG9uRmFsbGJhY2tDaGFuZ2UpIHtcbiAgICAgIGNvbnN0IHNob3VsZEZhbGxiYWNrID0gc2Nyb2xsRWwub2Zmc2V0SGVpZ2h0IDwgaXRlbS5vZmZzZXRIZWlnaHQgKiBtaW4obWluSXRlbXNWaXNpYmxlLCBsaXN0UmVmLmN1cnJlbnQubGVuZ3RoKSAtIDEgfHwgcmVmT3ZlcmZsb3cudG9wID49IC1yZWZlcmVuY2VPdmVyZmxvd1RocmVzaG9sZCB8fCByZWZPdmVyZmxvdy5ib3R0b20gPj0gLXJlZmVyZW5jZU92ZXJmbG93VGhyZXNob2xkO1xuICAgICAgUmVhY3RET00uZmx1c2hTeW5jKCgpID0+IG9uRmFsbGJhY2tDaGFuZ2Uoc2hvdWxkRmFsbGJhY2spKTtcbiAgICB9XG4gICAgaWYgKG92ZXJmbG93UmVmKSB7XG4gICAgICBvdmVyZmxvd1JlZi5jdXJyZW50ID0gYXdhaXQgZGV0ZWN0T3ZlcmZsb3coZ2V0QXJnc1dpdGhDdXN0b21GbG9hdGluZ0hlaWdodCh7XG4gICAgICAgIC4uLm5leHRBcmdzLFxuICAgICAgICB5OiBuZXh0WVxuICAgICAgfSwgc2Nyb2xsRWwub2Zmc2V0SGVpZ2h0ICsgY2xpZW50VG9wICsgZmxvYXRpbmcuY2xpZW50VG9wKSwgZGV0ZWN0T3ZlcmZsb3dPcHRpb25zKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHk6IG5leHRZXG4gICAgfTtcbiAgfVxufSk7XG4vKipcbiAqIENoYW5nZXMgdGhlIGBpbm5lcmAgbWlkZGxld2FyZSdzIGBvZmZzZXRgIHVwb24gYSBgd2hlZWxgIGV2ZW50IHRvXG4gKiBleHBhbmQgdGhlIGZsb2F0aW5nIGVsZW1lbnQncyBoZWlnaHQsIHJldmVhbGluZyBtb3JlIGxpc3QgaXRlbXMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvaW5uZXJcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmZ1bmN0aW9uIHVzZUlubmVyT2Zmc2V0KGNvbnRleHQsIHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIGVsZW1lbnRzXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgb3ZlcmZsb3dSZWYsXG4gICAgc2Nyb2xsUmVmLFxuICAgIG9uQ2hhbmdlOiB1bnN0YWJsZV9vbkNoYW5nZVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IG9uQ2hhbmdlID0gdXNlRWZmZWN0RXZlbnQodW5zdGFibGVfb25DaGFuZ2UpO1xuICBjb25zdCBjb250cm9sbGVkU2Nyb2xsaW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgcHJldlNjcm9sbFRvcFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgaW5pdGlhbE92ZXJmbG93UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIG9uV2hlZWwoZSkge1xuICAgICAgaWYgKGUuY3RybEtleSB8fCAhZWwgfHwgb3ZlcmZsb3dSZWYuY3VycmVudCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRZID0gZS5kZWx0YVk7XG4gICAgICBjb25zdCBpc0F0VG9wID0gb3ZlcmZsb3dSZWYuY3VycmVudC50b3AgPj0gLTAuNTtcbiAgICAgIGNvbnN0IGlzQXRCb3R0b20gPSBvdmVyZmxvd1JlZi5jdXJyZW50LmJvdHRvbSA+PSAtMC41O1xuICAgICAgY29uc3QgcmVtYWluaW5nU2Nyb2xsID0gZWwuc2Nyb2xsSGVpZ2h0IC0gZWwuY2xpZW50SGVpZ2h0O1xuICAgICAgY29uc3Qgc2lnbiA9IGRZIDwgMCA/IC0xIDogMTtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IGRZIDwgMCA/ICdtYXgnIDogJ21pbic7XG4gICAgICBpZiAoZWwuc2Nyb2xsSGVpZ2h0IDw9IGVsLmNsaWVudEhlaWdodCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWlzQXRUb3AgJiYgZFkgPiAwIHx8ICFpc0F0Qm90dG9tICYmIGRZIDwgMCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIFJlYWN0RE9NLmZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgb25DaGFuZ2UoZCA9PiBkICsgTWF0aFttZXRob2RdKGRZLCByZW1haW5pbmdTY3JvbGwgKiBzaWduKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICgvZmlyZWZveC9pLnRlc3QoZ2V0VXNlckFnZW50KCkpKSB7XG4gICAgICAgIC8vIE5lZWRlZCB0byBwcm9wYWdhdGUgc2Nyb2xsaW5nIGR1cmluZyBtb21lbnR1bSBzY3JvbGxpbmcgcGhhc2Ugb25jZVxuICAgICAgICAvLyBpdCBnZXRzIGxpbWl0ZWQgYnkgdGhlIGJvdW5kYXJ5LiBVWCBpbXByb3ZlbWVudCwgbm90IGNyaXRpY2FsLlxuICAgICAgICBlbC5zY3JvbGxUb3AgKz0gZFk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGVsID0gKHNjcm9sbFJlZiA9PSBudWxsID8gdm9pZCAwIDogc2Nyb2xsUmVmLmN1cnJlbnQpIHx8IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgIGlmIChvcGVuICYmIGVsKSB7XG4gICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCd3aGVlbCcsIG9uV2hlZWwpO1xuXG4gICAgICAvLyBXYWl0IGZvciB0aGUgcG9zaXRpb24gdG8gYmUgcmVhZHkuXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgPSBlbC5zY3JvbGxUb3A7XG4gICAgICAgIGlmIChvdmVyZmxvd1JlZi5jdXJyZW50ICE9IG51bGwpIHtcbiAgICAgICAgICBpbml0aWFsT3ZlcmZsb3dSZWYuY3VycmVudCA9IHtcbiAgICAgICAgICAgIC4uLm92ZXJmbG93UmVmLmN1cnJlbnRcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHByZXZTY3JvbGxUb3BSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIGluaXRpYWxPdmVyZmxvd1JlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2hlZWwnLCBvbldoZWVsKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgb3BlbiwgZWxlbWVudHMuZmxvYXRpbmcsIG92ZXJmbG93UmVmLCBzY3JvbGxSZWYsIG9uQ2hhbmdlXSk7XG4gIGNvbnN0IGZsb2F0aW5nID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uS2V5RG93bigpIHtcbiAgICAgIGNvbnRyb2xsZWRTY3JvbGxpbmdSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSxcbiAgICBvbldoZWVsKCkge1xuICAgICAgY29udHJvbGxlZFNjcm9sbGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSxcbiAgICBvblBvaW50ZXJNb3ZlKCkge1xuICAgICAgY29udHJvbGxlZFNjcm9sbGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSxcbiAgICBvblNjcm9sbCgpIHtcbiAgICAgIGNvbnN0IGVsID0gKHNjcm9sbFJlZiA9PSBudWxsID8gdm9pZCAwIDogc2Nyb2xsUmVmLmN1cnJlbnQpIHx8IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgICAgaWYgKCFvdmVyZmxvd1JlZi5jdXJyZW50IHx8ICFlbCB8fCAhY29udHJvbGxlZFNjcm9sbGluZ1JlZi5jdXJyZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3Qgc2Nyb2xsRGlmZiA9IGVsLnNjcm9sbFRvcCAtIHByZXZTY3JvbGxUb3BSZWYuY3VycmVudDtcbiAgICAgICAgaWYgKG92ZXJmbG93UmVmLmN1cnJlbnQuYm90dG9tIDwgLTAuNSAmJiBzY3JvbGxEaWZmIDwgLTEgfHwgb3ZlcmZsb3dSZWYuY3VycmVudC50b3AgPCAtMC41ICYmIHNjcm9sbERpZmYgPiAxKSB7XG4gICAgICAgICAgUmVhY3RET00uZmx1c2hTeW5jKCgpID0+IG9uQ2hhbmdlKGQgPT4gZCArIHNjcm9sbERpZmYpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBbRmlyZWZveF0gV2FpdCBmb3IgdGhlIGhlaWdodCBjaGFuZ2UgdG8gaGF2ZSBiZWVuIGFwcGxpZWQuXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgPSBlbC5zY3JvbGxUb3A7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pLCBbZWxlbWVudHMuZmxvYXRpbmcsIG9uQ2hhbmdlLCBvdmVyZmxvd1JlZiwgc2Nyb2xsUmVmXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgZmxvYXRpbmdcbiAgfSA6IHt9LCBbZW5hYmxlZCwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gZ2V0Tm9kZUNoaWxkcmVuKG5vZGVzLCBpZCwgb25seU9wZW5DaGlsZHJlbikge1xuICBpZiAob25seU9wZW5DaGlsZHJlbiA9PT0gdm9pZCAwKSB7XG4gICAgb25seU9wZW5DaGlsZHJlbiA9IHRydWU7XG4gIH1cbiAgbGV0IGFsbENoaWxkcmVuID0gbm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgIHZhciBfbm9kZSRjb250ZXh0O1xuICAgIHJldHVybiBub2RlLnBhcmVudElkID09PSBpZCAmJiAoKF9ub2RlJGNvbnRleHQgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Lm9wZW4pO1xuICB9KTtcbiAgbGV0IGN1cnJlbnRDaGlsZHJlbiA9IGFsbENoaWxkcmVuO1xuICB3aGlsZSAoY3VycmVudENoaWxkcmVuLmxlbmd0aCkge1xuICAgIGN1cnJlbnRDaGlsZHJlbiA9IG9ubHlPcGVuQ2hpbGRyZW4gPyBub2Rlcy5maWx0ZXIobm9kZSA9PiB7XG4gICAgICB2YXIgX2N1cnJlbnRDaGlsZHJlbjtcbiAgICAgIHJldHVybiAoX2N1cnJlbnRDaGlsZHJlbiA9IGN1cnJlbnRDaGlsZHJlbikgPT0gbnVsbCA/IHZvaWQgMCA6IF9jdXJyZW50Q2hpbGRyZW4uc29tZShuID0+IHtcbiAgICAgICAgdmFyIF9ub2RlJGNvbnRleHQyO1xuICAgICAgICByZXR1cm4gbm9kZS5wYXJlbnRJZCA9PT0gbi5pZCAmJiAoKF9ub2RlJGNvbnRleHQyID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDIub3Blbik7XG4gICAgICB9KTtcbiAgICB9KSA6IG5vZGVzO1xuICAgIGFsbENoaWxkcmVuID0gYWxsQ2hpbGRyZW4uY29uY2F0KGN1cnJlbnRDaGlsZHJlbik7XG4gIH1cbiAgcmV0dXJuIGFsbENoaWxkcmVuO1xufVxuXG5mdW5jdGlvbiBpc1BvaW50SW5Qb2x5Z29uKHBvaW50LCBwb2x5Z29uKSB7XG4gIGNvbnN0IFt4LCB5XSA9IHBvaW50O1xuICBsZXQgaXNJbnNpZGUgPSBmYWxzZTtcbiAgY29uc3QgbGVuZ3RoID0gcG9seWdvbi5sZW5ndGg7XG4gIGZvciAobGV0IGkgPSAwLCBqID0gbGVuZ3RoIC0gMTsgaSA8IGxlbmd0aDsgaiA9IGkrKykge1xuICAgIGNvbnN0IFt4aSwgeWldID0gcG9seWdvbltpXSB8fCBbMCwgMF07XG4gICAgY29uc3QgW3hqLCB5al0gPSBwb2x5Z29uW2pdIHx8IFswLCAwXTtcbiAgICBjb25zdCBpbnRlcnNlY3QgPSB5aSA+PSB5ICE9PSB5aiA+PSB5ICYmIHggPD0gKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aTtcbiAgICBpZiAoaW50ZXJzZWN0KSB7XG4gICAgICBpc0luc2lkZSA9ICFpc0luc2lkZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGlzSW5zaWRlO1xufVxuZnVuY3Rpb24gaXNJbnNpZGUocG9pbnQsIHJlY3QpIHtcbiAgcmV0dXJuIHBvaW50WzBdID49IHJlY3QueCAmJiBwb2ludFswXSA8PSByZWN0LnggKyByZWN0LndpZHRoICYmIHBvaW50WzFdID49IHJlY3QueSAmJiBwb2ludFsxXSA8PSByZWN0LnkgKyByZWN0LmhlaWdodDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgc2FmZSBwb2x5Z29uIGFyZWEgdGhhdCB0aGUgdXNlciBjYW4gdHJhdmVyc2Ugd2l0aG91dCBjbG9zaW5nIHRoZVxuICogZmxvYXRpbmcgZWxlbWVudCBvbmNlIGxlYXZpbmcgdGhlIHJlZmVyZW5jZSBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUhvdmVyI3NhZmVwb2x5Z29uXG4gKi9cbmZ1bmN0aW9uIHNhZmVQb2x5Z29uKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgYnVmZmVyID0gMC41LFxuICAgIGJsb2NrUG9pbnRlckV2ZW50cyA9IGZhbHNlLFxuICAgIHJlcXVpcmVJbnRlbnQgPSB0cnVlXG4gIH0gPSBvcHRpb25zO1xuICBsZXQgdGltZW91dElkO1xuICBsZXQgaGFzTGFuZGVkID0gZmFsc2U7XG4gIGxldCBsYXN0WCA9IG51bGw7XG4gIGxldCBsYXN0WSA9IG51bGw7XG4gIGxldCBsYXN0Q3Vyc29yVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICBmdW5jdGlvbiBnZXRDdXJzb3JTcGVlZCh4LCB5KSB7XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBjb25zdCBlbGFwc2VkVGltZSA9IGN1cnJlbnRUaW1lIC0gbGFzdEN1cnNvclRpbWU7XG4gICAgaWYgKGxhc3RYID09PSBudWxsIHx8IGxhc3RZID09PSBudWxsIHx8IGVsYXBzZWRUaW1lID09PSAwKSB7XG4gICAgICBsYXN0WCA9IHg7XG4gICAgICBsYXN0WSA9IHk7XG4gICAgICBsYXN0Q3Vyc29yVGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGRlbHRhWCA9IHggLSBsYXN0WDtcbiAgICBjb25zdCBkZWx0YVkgPSB5IC0gbGFzdFk7XG4gICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLnNxcnQoZGVsdGFYICogZGVsdGFYICsgZGVsdGFZICogZGVsdGFZKTtcbiAgICBjb25zdCBzcGVlZCA9IGRpc3RhbmNlIC8gZWxhcHNlZFRpbWU7IC8vIHB4IC8gbXNcblxuICAgIGxhc3RYID0geDtcbiAgICBsYXN0WSA9IHk7XG4gICAgbGFzdEN1cnNvclRpbWUgPSBjdXJyZW50VGltZTtcbiAgICByZXR1cm4gc3BlZWQ7XG4gIH1cbiAgY29uc3QgZm4gPSBfcmVmID0+IHtcbiAgICBsZXQge1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBwbGFjZW1lbnQsXG4gICAgICBlbGVtZW50cyxcbiAgICAgIG9uQ2xvc2UsXG4gICAgICBub2RlSWQsXG4gICAgICB0cmVlXG4gICAgfSA9IF9yZWY7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIG9uTW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIG9uQ2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgaWYgKCFlbGVtZW50cy5kb21SZWZlcmVuY2UgfHwgIWVsZW1lbnRzLmZsb2F0aW5nIHx8IHBsYWNlbWVudCA9PSBudWxsIHx8IHggPT0gbnVsbCB8fCB5ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qge1xuICAgICAgICBjbGllbnRYLFxuICAgICAgICBjbGllbnRZXG4gICAgICB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCBjbGllbnRQb2ludCA9IFtjbGllbnRYLCBjbGllbnRZXTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldChldmVudCk7XG4gICAgICBjb25zdCBpc0xlYXZlID0gZXZlbnQudHlwZSA9PT0gJ21vdXNlbGVhdmUnO1xuICAgICAgY29uc3QgaXNPdmVyRmxvYXRpbmdFbCA9IGNvbnRhaW5zKGVsZW1lbnRzLmZsb2F0aW5nLCB0YXJnZXQpO1xuICAgICAgY29uc3QgaXNPdmVyUmVmZXJlbmNlRWwgPSBjb250YWlucyhlbGVtZW50cy5kb21SZWZlcmVuY2UsIHRhcmdldCk7XG4gICAgICBjb25zdCByZWZSZWN0ID0gZWxlbWVudHMuZG9tUmVmZXJlbmNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3QgcmVjdCA9IGVsZW1lbnRzLmZsb2F0aW5nLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qgc2lkZSA9IHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xuICAgICAgY29uc3QgY3Vyc29yTGVhdmVGcm9tUmlnaHQgPSB4ID4gcmVjdC5yaWdodCAtIHJlY3Qud2lkdGggLyAyO1xuICAgICAgY29uc3QgY3Vyc29yTGVhdmVGcm9tQm90dG9tID0geSA+IHJlY3QuYm90dG9tIC0gcmVjdC5oZWlnaHQgLyAyO1xuICAgICAgY29uc3QgaXNPdmVyUmVmZXJlbmNlUmVjdCA9IGlzSW5zaWRlKGNsaWVudFBvaW50LCByZWZSZWN0KTtcbiAgICAgIGNvbnN0IGlzRmxvYXRpbmdXaWRlciA9IHJlY3Qud2lkdGggPiByZWZSZWN0LndpZHRoO1xuICAgICAgY29uc3QgaXNGbG9hdGluZ1RhbGxlciA9IHJlY3QuaGVpZ2h0ID4gcmVmUmVjdC5oZWlnaHQ7XG4gICAgICBjb25zdCBsZWZ0ID0gKGlzRmxvYXRpbmdXaWRlciA/IHJlZlJlY3QgOiByZWN0KS5sZWZ0O1xuICAgICAgY29uc3QgcmlnaHQgPSAoaXNGbG9hdGluZ1dpZGVyID8gcmVmUmVjdCA6IHJlY3QpLnJpZ2h0O1xuICAgICAgY29uc3QgdG9wID0gKGlzRmxvYXRpbmdUYWxsZXIgPyByZWZSZWN0IDogcmVjdCkudG9wO1xuICAgICAgY29uc3QgYm90dG9tID0gKGlzRmxvYXRpbmdUYWxsZXIgPyByZWZSZWN0IDogcmVjdCkuYm90dG9tO1xuICAgICAgaWYgKGlzT3ZlckZsb2F0aW5nRWwpIHtcbiAgICAgICAgaGFzTGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKCFpc0xlYXZlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNPdmVyUmVmZXJlbmNlRWwpIHtcbiAgICAgICAgaGFzTGFuZGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaXNPdmVyUmVmZXJlbmNlRWwgJiYgIWlzTGVhdmUpIHtcbiAgICAgICAgaGFzTGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBQcmV2ZW50IG92ZXJsYXBwaW5nIGZsb2F0aW5nIGVsZW1lbnQgZnJvbSBiZWluZyBzdHVjayBpbiBhbiBvcGVuLWNsb3NlXG4gICAgICAvLyBsb29wOiBodHRwczovL2dpdGh1Yi5jb20vZmxvYXRpbmctdWkvZmxvYXRpbmctdWkvaXNzdWVzLzE5MTBcbiAgICAgIGlmIChpc0xlYXZlICYmIGlzRWxlbWVudChldmVudC5yZWxhdGVkVGFyZ2V0KSAmJiBjb250YWlucyhlbGVtZW50cy5mbG9hdGluZywgZXZlbnQucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBhbnkgbmVzdGVkIGNoaWxkIGlzIG9wZW4sIGFib3J0LlxuICAgICAgaWYgKHRyZWUgJiYgZ2V0Tm9kZUNoaWxkcmVuKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKS5zb21lKF9yZWYyID0+IHtcbiAgICAgICAgbGV0IHtcbiAgICAgICAgICBjb250ZXh0XG4gICAgICAgIH0gPSBfcmVmMjtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IGNvbnRleHQub3BlbjtcbiAgICAgIH0pKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIHBvaW50ZXIgaXMgbGVhdmluZyBmcm9tIHRoZSBvcHBvc2l0ZSBzaWRlLCB0aGUgXCJidWZmZXJcIiBsb2dpY1xuICAgICAgLy8gY3JlYXRlcyBhIHBvaW50IHdoZXJlIHRoZSBmbG9hdGluZyBlbGVtZW50IHJlbWFpbnMgb3BlbiwgYnV0IHNob3VsZCBiZVxuICAgICAgLy8gaWdub3JlZC5cbiAgICAgIC8vIEEgY29uc3RhbnQgb2YgMSBoYW5kbGVzIGZsb2F0aW5nIHBvaW50IHJvdW5kaW5nIGVycm9ycy5cbiAgICAgIGlmIChzaWRlID09PSAndG9wJyAmJiB5ID49IHJlZlJlY3QuYm90dG9tIC0gMSB8fCBzaWRlID09PSAnYm90dG9tJyAmJiB5IDw9IHJlZlJlY3QudG9wICsgMSB8fCBzaWRlID09PSAnbGVmdCcgJiYgeCA+PSByZWZSZWN0LnJpZ2h0IC0gMSB8fCBzaWRlID09PSAncmlnaHQnICYmIHggPD0gcmVmUmVjdC5sZWZ0ICsgMSkge1xuICAgICAgICByZXR1cm4gY2xvc2UoKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWdub3JlIHdoZW4gdGhlIGN1cnNvciBpcyB3aXRoaW4gdGhlIHJlY3Rhbmd1bGFyIHRyb3VnaCBiZXR3ZWVuIHRoZVxuICAgICAgLy8gdHdvIGVsZW1lbnRzLiBTaW5jZSB0aGUgdHJpYW5nbGUgaXMgY3JlYXRlZCBmcm9tIHRoZSBjdXJzb3IgcG9pbnQsXG4gICAgICAvLyB3aGljaCBjYW4gc3RhcnQgYmV5b25kIHRoZSByZWYgZWxlbWVudCdzIGVkZ2UsIHRyYXZlcnNpbmcgYmFjayBhbmRcbiAgICAgIC8vIGZvcnRoIGZyb20gdGhlIHJlZiB0byB0aGUgZmxvYXRpbmcgZWxlbWVudCBjYW4gY2F1c2UgaXQgdG8gY2xvc2UuIFRoaXNcbiAgICAgIC8vIGVuc3VyZXMgaXQgYWx3YXlzIHJlbWFpbnMgb3BlbiBpbiB0aGF0IGNhc2UuXG4gICAgICBsZXQgcmVjdFBvbHkgPSBbXTtcbiAgICAgIHN3aXRjaCAoc2lkZSkge1xuICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgIHJlY3RQb2x5ID0gW1tsZWZ0LCByZWZSZWN0LnRvcCArIDFdLCBbbGVmdCwgcmVjdC5ib3R0b20gLSAxXSwgW3JpZ2h0LCByZWN0LmJvdHRvbSAtIDFdLCBbcmlnaHQsIHJlZlJlY3QudG9wICsgMV1dO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgIHJlY3RQb2x5ID0gW1tsZWZ0LCByZWN0LnRvcCArIDFdLCBbbGVmdCwgcmVmUmVjdC5ib3R0b20gLSAxXSwgW3JpZ2h0LCByZWZSZWN0LmJvdHRvbSAtIDFdLCBbcmlnaHQsIHJlY3QudG9wICsgMV1dO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICByZWN0UG9seSA9IFtbcmVjdC5yaWdodCAtIDEsIGJvdHRvbV0sIFtyZWN0LnJpZ2h0IC0gMSwgdG9wXSwgW3JlZlJlY3QubGVmdCArIDEsIHRvcF0sIFtyZWZSZWN0LmxlZnQgKyAxLCBib3R0b21dXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgIHJlY3RQb2x5ID0gW1tyZWZSZWN0LnJpZ2h0IC0gMSwgYm90dG9tXSwgW3JlZlJlY3QucmlnaHQgLSAxLCB0b3BdLCBbcmVjdC5sZWZ0ICsgMSwgdG9wXSwgW3JlY3QubGVmdCArIDEsIGJvdHRvbV1dO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gZ2V0UG9seWdvbihfcmVmMykge1xuICAgICAgICBsZXQgW3gsIHldID0gX3JlZjM7XG4gICAgICAgIHN3aXRjaCAoc2lkZSkge1xuICAgICAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50T25lID0gW2lzRmxvYXRpbmdXaWRlciA/IHggKyBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyB4ICsgYnVmZmVyICogNCA6IHggLSBidWZmZXIgKiA0LCB5ICsgYnVmZmVyICsgMV07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW2lzRmxvYXRpbmdXaWRlciA/IHggLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyB4ICsgYnVmZmVyICogNCA6IHggLSBidWZmZXIgKiA0LCB5ICsgYnVmZmVyICsgMV07XG4gICAgICAgICAgICAgIGNvbnN0IGNvbW1vblBvaW50cyA9IFtbcmVjdC5sZWZ0LCBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IHJlY3QuYm90dG9tIC0gYnVmZmVyIDogaXNGbG9hdGluZ1dpZGVyID8gcmVjdC5ib3R0b20gLSBidWZmZXIgOiByZWN0LnRvcF0sIFtyZWN0LnJpZ2h0LCBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IGlzRmxvYXRpbmdXaWRlciA/IHJlY3QuYm90dG9tIC0gYnVmZmVyIDogcmVjdC50b3AgOiByZWN0LmJvdHRvbSAtIGJ1ZmZlcl1dO1xuICAgICAgICAgICAgICByZXR1cm4gW2N1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3bywgLi4uY29tbW9uUG9pbnRzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFtpc0Zsb2F0aW5nV2lkZXIgPyB4ICsgYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8geCArIGJ1ZmZlciAqIDQgOiB4IC0gYnVmZmVyICogNCwgeSAtIGJ1ZmZlcl07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW2lzRmxvYXRpbmdXaWRlciA/IHggLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyB4ICsgYnVmZmVyICogNCA6IHggLSBidWZmZXIgKiA0LCB5IC0gYnVmZmVyXTtcbiAgICAgICAgICAgICAgY29uc3QgY29tbW9uUG9pbnRzID0gW1tyZWN0LmxlZnQsIGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8gcmVjdC50b3AgKyBidWZmZXIgOiBpc0Zsb2F0aW5nV2lkZXIgPyByZWN0LnRvcCArIGJ1ZmZlciA6IHJlY3QuYm90dG9tXSwgW3JlY3QucmlnaHQsIGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8gaXNGbG9hdGluZ1dpZGVyID8gcmVjdC50b3AgKyBidWZmZXIgOiByZWN0LmJvdHRvbSA6IHJlY3QudG9wICsgYnVmZmVyXV07XG4gICAgICAgICAgICAgIHJldHVybiBbY3Vyc29yUG9pbnRPbmUsIGN1cnNvclBvaW50VHdvLCAuLi5jb21tb25Qb2ludHNdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFt4ICsgYnVmZmVyICsgMSwgaXNGbG9hdGluZ1RhbGxlciA/IHkgKyBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tQm90dG9tID8geSArIGJ1ZmZlciAqIDQgOiB5IC0gYnVmZmVyICogNF07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW3ggKyBidWZmZXIgKyAxLCBpc0Zsb2F0aW5nVGFsbGVyID8geSAtIGJ1ZmZlciAvIDIgOiBjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyB5ICsgYnVmZmVyICogNCA6IHkgLSBidWZmZXIgKiA0XTtcbiAgICAgICAgICAgICAgY29uc3QgY29tbW9uUG9pbnRzID0gW1tjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyByZWN0LnJpZ2h0IC0gYnVmZmVyIDogaXNGbG9hdGluZ1RhbGxlciA/IHJlY3QucmlnaHQgLSBidWZmZXIgOiByZWN0LmxlZnQsIHJlY3QudG9wXSwgW2N1cnNvckxlYXZlRnJvbUJvdHRvbSA/IGlzRmxvYXRpbmdUYWxsZXIgPyByZWN0LnJpZ2h0IC0gYnVmZmVyIDogcmVjdC5sZWZ0IDogcmVjdC5yaWdodCAtIGJ1ZmZlciwgcmVjdC5ib3R0b21dXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFsuLi5jb21tb25Qb2ludHMsIGN1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3b107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFt4IC0gYnVmZmVyLCBpc0Zsb2F0aW5nVGFsbGVyID8geSArIGJ1ZmZlciAvIDIgOiBjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyB5ICsgYnVmZmVyICogNCA6IHkgLSBidWZmZXIgKiA0XTtcbiAgICAgICAgICAgICAgY29uc3QgY3Vyc29yUG9pbnRUd28gPSBbeCAtIGJ1ZmZlciwgaXNGbG9hdGluZ1RhbGxlciA/IHkgLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tQm90dG9tID8geSArIGJ1ZmZlciAqIDQgOiB5IC0gYnVmZmVyICogNF07XG4gICAgICAgICAgICAgIGNvbnN0IGNvbW1vblBvaW50cyA9IFtbY3Vyc29yTGVhdmVGcm9tQm90dG9tID8gcmVjdC5sZWZ0ICsgYnVmZmVyIDogaXNGbG9hdGluZ1RhbGxlciA/IHJlY3QubGVmdCArIGJ1ZmZlciA6IHJlY3QucmlnaHQsIHJlY3QudG9wXSwgW2N1cnNvckxlYXZlRnJvbUJvdHRvbSA/IGlzRmxvYXRpbmdUYWxsZXIgPyByZWN0LmxlZnQgKyBidWZmZXIgOiByZWN0LnJpZ2h0IDogcmVjdC5sZWZ0ICsgYnVmZmVyLCByZWN0LmJvdHRvbV1dO1xuICAgICAgICAgICAgICByZXR1cm4gW2N1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3bywgLi4uY29tbW9uUG9pbnRzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzUG9pbnRJblBvbHlnb24oW2NsaWVudFgsIGNsaWVudFldLCByZWN0UG9seSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGhhc0xhbmRlZCAmJiAhaXNPdmVyUmVmZXJlbmNlUmVjdCkge1xuICAgICAgICByZXR1cm4gY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGlmICghaXNMZWF2ZSAmJiByZXF1aXJlSW50ZW50KSB7XG4gICAgICAgIGNvbnN0IGN1cnNvclNwZWVkID0gZ2V0Q3Vyc29yU3BlZWQoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSk7XG4gICAgICAgIGNvbnN0IGN1cnNvclNwZWVkVGhyZXNob2xkID0gMC4xO1xuICAgICAgICBpZiAoY3Vyc29yU3BlZWQgIT09IG51bGwgJiYgY3Vyc29yU3BlZWQgPCBjdXJzb3JTcGVlZFRocmVzaG9sZCkge1xuICAgICAgICAgIHJldHVybiBjbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlzUG9pbnRJblBvbHlnb24oW2NsaWVudFgsIGNsaWVudFldLCBnZXRQb2x5Z29uKFt4LCB5XSkpKSB7XG4gICAgICAgIGNsb3NlKCk7XG4gICAgICB9IGVsc2UgaWYgKCFoYXNMYW5kZWQgJiYgcmVxdWlyZUludGVudCkge1xuICAgICAgICB0aW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dChjbG9zZSwgNDApO1xuICAgICAgfVxuICAgIH07XG4gIH07XG4gIGZuLl9fb3B0aW9ucyA9IHtcbiAgICBibG9ja1BvaW50ZXJFdmVudHNcbiAgfTtcbiAgcmV0dXJuIGZuO1xufVxuXG5leHBvcnQgeyBDb21wb3NpdGUsIENvbXBvc2l0ZUl0ZW0sIEZsb2F0aW5nQXJyb3csIEZsb2F0aW5nRGVsYXlHcm91cCwgRmxvYXRpbmdGb2N1c01hbmFnZXIsIEZsb2F0aW5nTGlzdCwgRmxvYXRpbmdOb2RlLCBGbG9hdGluZ092ZXJsYXksIEZsb2F0aW5nUG9ydGFsLCBGbG9hdGluZ1RyZWUsIE5leHRGbG9hdGluZ0RlbGF5R3JvdXAsIGlubmVyLCBzYWZlUG9seWdvbiwgdXNlQ2xpY2ssIHVzZUNsaWVudFBvaW50LCB1c2VEZWxheUdyb3VwLCB1c2VEZWxheUdyb3VwQ29udGV4dCwgdXNlRGlzbWlzcywgdXNlRmxvYXRpbmcsIHVzZUZsb2F0aW5nTm9kZUlkLCB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCwgdXNlRmxvYXRpbmdQb3J0YWxOb2RlLCB1c2VGbG9hdGluZ1Jvb3RDb250ZXh0LCB1c2VGbG9hdGluZ1RyZWUsIHVzZUZvY3VzLCB1c2VIb3ZlciwgdXNlSWQsIHVzZUlubmVyT2Zmc2V0LCB1c2VJbnRlcmFjdGlvbnMsIHVzZUxpc3RJdGVtLCB1c2VMaXN0TmF2aWdhdGlvbiwgdXNlTWVyZ2VSZWZzLCB1c2VOZXh0RGVsYXlHcm91cCwgdXNlUm9sZSwgdXNlVHJhbnNpdGlvblN0YXR1cywgdXNlVHJhbnNp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Q0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0Isd0RBQVk7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsdURBQVc7QUFDckI7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGlDQUFnQjtBQUNoRCwwQkFBMEIsK0JBQWM7QUFDeEMsRUFBRSxtRUFBcUI7QUFDdkIsUUFBUSxzREFBUTtB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QTtBQUNBLGtDQUFrQyxZQUFZO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLHFEQUFTO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFc2xCIn0=\n//# sourceURL=webpack-internal:///../../../node_modules/@floating-ui/react/dist/floating-ui.react.mjs\n\n}");
1909
+ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n Composite: () => (Composite),\n CompositeItem: () => (CompositeItem),\n FloatingArrow: () => (FloatingArrow),\n FloatingDelayGroup: () => (FloatingDelayGroup),\n FloatingFocusManager: () => (FloatingFocusManager),\n FloatingList: () => (FloatingList),\n FloatingNode: () => (FloatingNode),\n FloatingOverlay: () => (FloatingOverlay),\n FloatingPortal: () => (FloatingPortal),\n FloatingTree: () => (FloatingTree),\n NextFloatingDelayGroup: () => (NextFloatingDelayGroup),\n arrow: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.arrow),\n autoPlacement: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.autoPlacement),\n autoUpdate: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.autoUpdate),\n computePosition: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.computePosition),\n detectOverflow: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.detectOverflow),\n flip: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.flip),\n getOverflowAncestors: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_5.getOverflowAncestors),\n hide: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.hide),\n inline: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.inline),\n inner: () => (inner),\n limitShift: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.limitShift),\n offset: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.offset),\n platform: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_4.platform),\n safePolygon: () => (safePolygon),\n shift: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.shift),\n size: () => (/* reexport safe */ _floating_ui_react_dom__rspack_import_3.size),\n useClick: () => (useClick),\n useClientPoint: () => (useClientPoint),\n useDelayGroup: () => (useDelayGroup),\n useDelayGroupContext: () => (useDelayGroupContext),\n useDismiss: () => (useDismiss),\n useFloating: () => (useFloating),\n useFloatingNodeId: () => (useFloatingNodeId),\n useFloatingParentNodeId: () => (useFloatingParentNodeId),\n useFloatingPortalNode: () => (useFloatingPortalNode),\n useFloatingRootContext: () => (useFloatingRootContext),\n useFloatingTree: () => (useFloatingTree),\n useFocus: () => (useFocus),\n useHover: () => (useHover),\n useId: () => (useId),\n useInnerOffset: () => (useInnerOffset),\n useInteractions: () => (useInteractions),\n useListItem: () => (useListItem),\n useListNavigation: () => (useListNavigation),\n useMergeRefs: () => (useMergeRefs),\n useNextDelayGroup: () => (useNextDelayGroup),\n useRole: () => (useRole),\n useTransitionStatus: () => (useTransitionStatus),\n useTransitionStyles: () => (useTransitionStyles),\n useTypeahead: () => (useTypeahead)\n});\n/* import */ var react__rspack_import_0 = __webpack_require__(\"webpack/sharing/consume/default/react/react\");\n/* import */ var react__rspack_import_0_default = /*#__PURE__*/__webpack_require__.n(react__rspack_import_0);\n/* import */ var _floating_ui_react_utils__rspack_import_6 = __webpack_require__(\"../../../node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs\");\n/* import */ var react_jsx_runtime__rspack_import_1 = __webpack_require__(\"webpack/sharing/consume/default/react/jsx-runtime/react/jsx-runtime\");\n/* import */ var react_jsx_runtime__rspack_import_1_default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__rspack_import_1);\n/* import */ var _floating_ui_react_dom__rspack_import_5 = __webpack_require__(\"../../../node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs\");\n/* import */ var tabbable__rspack_import_7 = __webpack_require__(\"../../../node_modules/tabbable/dist/index.esm.js\");\n/* import */ var react_dom__rspack_import_2 = __webpack_require__(\"webpack/sharing/consume/default/react-dom/react-dom\");\n/* import */ var react_dom__rspack_import_2_default = /*#__PURE__*/__webpack_require__.n(react_dom__rspack_import_2);\n/* import */ var _floating_ui_react_dom__rspack_import_3 = __webpack_require__(\"../../../node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs\");\n/* import */ var _floating_ui_react_dom__rspack_import_4 = __webpack_require__(\"../../../node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs\");\n/* import */ var _floating_ui_utils__rspack_import_8 = __webpack_require__(\"../../../node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs\");\n\n\n\n\n\n\n\n\n\n\n/**\n * Merges an array of refs into a single memoized callback ref or `null`.\n * @see https://floating-ui.com/docs/react-utils#usemergerefs\n */\nfunction useMergeRefs(refs) {\n const cleanupRef = react__rspack_import_0.useRef(undefined);\n const refEffect = react__rspack_import_0.useCallback(instance => {\n const cleanups = refs.map(ref => {\n if (ref == null) {\n return;\n }\n if (typeof ref === 'function') {\n const refCallback = ref;\n const refCleanup = refCallback(instance);\n return typeof refCleanup === 'function' ? refCleanup : () => {\n refCallback(null);\n };\n }\n ref.current = instance;\n return () => {\n ref.current = null;\n };\n });\n return () => {\n cleanups.forEach(refCleanup => refCleanup == null ? void 0 : refCleanup());\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, refs);\n return react__rspack_import_0.useMemo(() => {\n if (refs.every(ref => ref == null)) {\n return null;\n }\n return value => {\n if (cleanupRef.current) {\n cleanupRef.current();\n cleanupRef.current = undefined;\n }\n if (value != null) {\n cleanupRef.current = refEffect(value);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, refs);\n}\n\nfunction sortByDocumentPosition(a, b) {\n const position = a.compareDocumentPosition(b);\n if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n return -1;\n }\n if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) {\n return 1;\n }\n return 0;\n}\nconst FloatingListContext = /*#__PURE__*/react__rspack_import_0.createContext({\n register: () => {},\n unregister: () => {},\n map: /*#__PURE__*/new Map(),\n elementsRef: {\n current: []\n }\n});\n/**\n * Provides context for a list of items within the floating element.\n * @see https://floating-ui.com/docs/FloatingList\n */\nfunction FloatingList(props) {\n const {\n children,\n elementsRef,\n labelsRef\n } = props;\n const [nodes, setNodes] = react__rspack_import_0.useState(() => new Set());\n const register = react__rspack_import_0.useCallback(node => {\n setNodes(prevSet => new Set(prevSet).add(node));\n }, []);\n const unregister = react__rspack_import_0.useCallback(node => {\n setNodes(prevSet => {\n const set = new Set(prevSet);\n set.delete(node);\n return set;\n });\n }, []);\n const map = react__rspack_import_0.useMemo(() => {\n const newMap = new Map();\n const sortedNodes = Array.from(nodes.keys()).sort(sortByDocumentPosition);\n sortedNodes.forEach((node, index) => {\n newMap.set(node, index);\n });\n return newMap;\n }, [nodes]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingListContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n register,\n unregister,\n map,\n elementsRef,\n labelsRef\n }), [register, unregister, map, elementsRef, labelsRef]),\n children: children\n });\n}\n/**\n * Used to register a list item and its index (DOM position) in the\n * `FloatingList`.\n * @see https://floating-ui.com/docs/FloatingList#uselistitem\n */\nfunction useListItem(props) {\n if (props === void 0) {\n props = {};\n }\n const {\n label\n } = props;\n const {\n register,\n unregister,\n map,\n elementsRef,\n labelsRef\n } = react__rspack_import_0.useContext(FloatingListContext);\n const [index, setIndex] = react__rspack_import_0.useState(null);\n const componentRef = react__rspack_import_0.useRef(null);\n const ref = react__rspack_import_0.useCallback(node => {\n componentRef.current = node;\n if (index !== null) {\n elementsRef.current[index] = node;\n if (labelsRef) {\n var _node$textContent;\n const isLabelDefined = label !== undefined;\n labelsRef.current[index] = isLabelDefined ? label : (_node$textContent = node == null ? void 0 : node.textContent) != null ? _node$textContent : null;\n }\n }\n }, [index, elementsRef, labelsRef, label]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n const node = componentRef.current;\n if (node) {\n register(node);\n return () => {\n unregister(node);\n };\n }\n }, [register, unregister]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n const index = componentRef.current ? map.get(componentRef.current) : null;\n if (index != null) {\n setIndex(index);\n }\n }, [map]);\n return react__rspack_import_0.useMemo(() => ({\n ref,\n index: index == null ? -1 : index\n }), [index, ref]);\n}\n\nconst FOCUSABLE_ATTRIBUTE = 'data-floating-ui-focusable';\nconst ACTIVE_KEY = 'active';\nconst SELECTED_KEY = 'selected';\nconst ARROW_LEFT = 'ArrowLeft';\nconst ARROW_RIGHT = 'ArrowRight';\nconst ARROW_UP = 'ArrowUp';\nconst ARROW_DOWN = 'ArrowDown';\n\nfunction renderJsx(render, computedProps) {\n if (typeof render === 'function') {\n return render(computedProps);\n }\n if (render) {\n return /*#__PURE__*/react__rspack_import_0.cloneElement(render, computedProps);\n }\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"div\", {\n ...computedProps\n });\n}\nconst CompositeContext = /*#__PURE__*/react__rspack_import_0.createContext({\n activeIndex: 0,\n onNavigate: () => {}\n});\nconst horizontalKeys = [ARROW_LEFT, ARROW_RIGHT];\nconst verticalKeys = [ARROW_UP, ARROW_DOWN];\nconst allKeys = [...horizontalKeys, ...verticalKeys];\n\n/**\n * Creates a single tab stop whose items are navigated by arrow keys, which\n * provides list navigation outside of floating element contexts.\n *\n * This is useful to enable navigation of a list of items that aren’t part of a\n * floating element. A menubar is an example of a composite, with each reference\n * element being an item.\n * @see https://floating-ui.com/docs/Composite\n */\nconst Composite = /*#__PURE__*/react__rspack_import_0.forwardRef(function Composite(props, forwardedRef) {\n const {\n render,\n orientation = 'both',\n loop = true,\n rtl = false,\n cols = 1,\n disabledIndices,\n activeIndex: externalActiveIndex,\n onNavigate: externalSetActiveIndex,\n itemSizes,\n dense = false,\n ...domProps\n } = props;\n const [internalActiveIndex, internalSetActiveIndex] = react__rspack_import_0.useState(0);\n const activeIndex = externalActiveIndex != null ? externalActiveIndex : internalActiveIndex;\n const onNavigate = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(externalSetActiveIndex != null ? externalSetActiveIndex : internalSetActiveIndex);\n const elementsRef = react__rspack_import_0.useRef([]);\n const renderElementProps = render && typeof render !== 'function' ? render.props : {};\n const contextValue = react__rspack_import_0.useMemo(() => ({\n activeIndex,\n onNavigate\n }), [activeIndex, onNavigate]);\n const isGrid = cols > 1;\n function handleKeyDown(event) {\n if (!allKeys.includes(event.key)) return;\n let nextIndex = activeIndex;\n const minIndex = (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(elementsRef, disabledIndices);\n const maxIndex = (0,_floating_ui_react_utils__rspack_import_6.getMaxListIndex)(elementsRef, disabledIndices);\n const horizontalEndKey = rtl ? ARROW_LEFT : ARROW_RIGHT;\n const horizontalStartKey = rtl ? ARROW_RIGHT : ARROW_LEFT;\n if (isGrid) {\n const sizes = itemSizes || Array.from({\n length: elementsRef.current.length\n }, () => ({\n width: 1,\n height: 1\n }));\n // To calculate movements on the grid, we use hypothetical cell indices\n // as if every item was 1x1, then convert back to real indices.\n const cellMap = (0,_floating_ui_react_utils__rspack_import_6.createGridCellMap)(sizes, cols, dense);\n const minGridIndex = cellMap.findIndex(index => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(elementsRef, index, disabledIndices));\n // last enabled index\n const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(elementsRef, index, disabledIndices) ? cellIndex : foundIndex, -1);\n const maybeNextIndex = cellMap[(0,_floating_ui_react_utils__rspack_import_6.getGridNavigatedIndex)({\n current: cellMap.map(itemIndex => itemIndex ? elementsRef.current[itemIndex] : null)\n }, {\n event,\n orientation,\n loop,\n rtl,\n cols,\n // treat undefined (empty grid spaces) as disabled indices so we\n // don't end up in them\n disabledIndices: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndices)([...(disabledIndices || elementsRef.current.map((_, index) => (0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(elementsRef, index) ? index : undefined)), undefined], cellMap),\n minIndex: minGridIndex,\n maxIndex: maxGridIndex,\n prevIndex: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndexOfCorner)(activeIndex > maxIndex ? minIndex : activeIndex, sizes, cellMap, cols,\n // use a corner matching the edge closest to the direction we're\n // moving in so we don't end up in the same item. Prefer\n // top/left over bottom/right.\n event.key === ARROW_DOWN ? 'bl' : event.key === horizontalEndKey ? 'tr' : 'tl')\n })];\n if (maybeNextIndex != null) {\n nextIndex = maybeNextIndex;\n }\n }\n const toEndKeys = {\n horizontal: [horizontalEndKey],\n vertical: [ARROW_DOWN],\n both: [horizontalEndKey, ARROW_DOWN]\n }[orientation];\n const toStartKeys = {\n horizontal: [horizontalStartKey],\n vertical: [ARROW_UP],\n both: [horizontalStartKey, ARROW_UP]\n }[orientation];\n const preventedKeys = isGrid ? allKeys : {\n horizontal: horizontalKeys,\n vertical: verticalKeys,\n both: allKeys\n }[orientation];\n if (nextIndex === activeIndex && [...toEndKeys, ...toStartKeys].includes(event.key)) {\n if (loop && nextIndex === maxIndex && toEndKeys.includes(event.key)) {\n nextIndex = minIndex;\n } else if (loop && nextIndex === minIndex && toStartKeys.includes(event.key)) {\n nextIndex = maxIndex;\n } else {\n nextIndex = (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(elementsRef, {\n startingIndex: nextIndex,\n decrement: toStartKeys.includes(event.key),\n disabledIndices\n });\n }\n }\n if (nextIndex !== activeIndex && !(0,_floating_ui_react_utils__rspack_import_6.isIndexOutOfListBounds)(elementsRef, nextIndex)) {\n var _elementsRef$current$;\n event.stopPropagation();\n if (preventedKeys.includes(event.key)) {\n event.preventDefault();\n }\n onNavigate(nextIndex);\n (_elementsRef$current$ = elementsRef.current[nextIndex]) == null || _elementsRef$current$.focus();\n }\n }\n const computedProps = {\n ...domProps,\n ...renderElementProps,\n ref: forwardedRef,\n 'aria-orientation': orientation === 'both' ? undefined : orientation,\n onKeyDown(e) {\n domProps.onKeyDown == null || domProps.onKeyDown(e);\n renderElementProps.onKeyDown == null || renderElementProps.onKeyDown(e);\n handleKeyDown(e);\n }\n };\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(CompositeContext.Provider, {\n value: contextValue,\n children: /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingList, {\n elementsRef: elementsRef,\n children: renderJsx(render, computedProps)\n })\n });\n});\n/**\n * @see https://floating-ui.com/docs/Composite\n */\nconst CompositeItem = /*#__PURE__*/react__rspack_import_0.forwardRef(function CompositeItem(props, forwardedRef) {\n const {\n render,\n ...domProps\n } = props;\n const renderElementProps = render && typeof render !== 'function' ? render.props : {};\n const {\n activeIndex,\n onNavigate\n } = react__rspack_import_0.useContext(CompositeContext);\n const {\n ref,\n index\n } = useListItem();\n const mergedRef = useMergeRefs([ref, forwardedRef, renderElementProps.ref]);\n const isActive = activeIndex === index;\n const computedProps = {\n ...domProps,\n ...renderElementProps,\n ref: mergedRef,\n tabIndex: isActive ? 0 : -1,\n 'data-active': isActive ? '' : undefined,\n onFocus(e) {\n domProps.onFocus == null || domProps.onFocus(e);\n renderElementProps.onFocus == null || renderElementProps.onFocus(e);\n onNavigate(index);\n }\n };\n return renderJsx(render, computedProps);\n});\n\n// https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379\nconst SafeReact = {\n ...react__rspack_import_0\n};\n\nlet serverHandoffComplete = false;\nlet count = 0;\nconst genId = () => // Ensure the id is unique with multiple independent versions of Floating UI\n// on <React 18\n\"floating-ui-\" + Math.random().toString(36).slice(2, 6) + count++;\nfunction useFloatingId() {\n const [id, setId] = react__rspack_import_0.useState(() => serverHandoffComplete ? genId() : undefined);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (id == null) {\n setId(genId());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n react__rspack_import_0.useEffect(() => {\n serverHandoffComplete = true;\n }, []);\n return id;\n}\nconst useReactId = SafeReact.useId;\n\n/**\n * Uses React 18's built-in `useId()` when available, or falls back to a\n * slightly less performant (requiring a double render) implementation for\n * earlier React versions.\n * @see https://floating-ui.com/docs/react-utils#useid\n */\nconst useId = useReactId || useFloatingId;\n\nlet devMessageSet;\nif (true) {\n devMessageSet = /*#__PURE__*/new Set();\n}\nfunction warn() {\n var _devMessageSet;\n for (var _len = arguments.length, messages = new Array(_len), _key = 0; _key < _len; _key++) {\n messages[_key] = arguments[_key];\n }\n const message = \"Floating UI: \" + messages.join(' ');\n if (!((_devMessageSet = devMessageSet) != null && _devMessageSet.has(message))) {\n var _devMessageSet2;\n (_devMessageSet2 = devMessageSet) == null || _devMessageSet2.add(message);\n console.warn(message);\n }\n}\nfunction error() {\n var _devMessageSet3;\n for (var _len2 = arguments.length, messages = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n messages[_key2] = arguments[_key2];\n }\n const message = \"Floating UI: \" + messages.join(' ');\n if (!((_devMessageSet3 = devMessageSet) != null && _devMessageSet3.has(message))) {\n var _devMessageSet4;\n (_devMessageSet4 = devMessageSet) == null || _devMessageSet4.add(message);\n console.error(message);\n }\n}\n\n/**\n * Renders a pointing arrow triangle.\n * @see https://floating-ui.com/docs/FloatingArrow\n */\nconst FloatingArrow = /*#__PURE__*/react__rspack_import_0.forwardRef(function FloatingArrow(props, ref) {\n const {\n context: {\n placement,\n elements: {\n floating\n },\n middlewareData: {\n arrow,\n shift\n }\n },\n width = 14,\n height = 7,\n tipRadius = 0,\n strokeWidth = 0,\n staticOffset,\n stroke,\n d,\n style: {\n transform,\n ...restStyle\n } = {},\n ...rest\n } = props;\n if (true) {\n if (!ref) {\n warn('The `ref` prop is required for `FloatingArrow`.');\n }\n }\n const clipPathId = useId();\n const [isRTL, setIsRTL] = react__rspack_import_0.useState(false);\n\n // https://github.com/floating-ui/floating-ui/issues/2932\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!floating) return;\n const isRTL = (0,_floating_ui_react_dom__rspack_import_5.getComputedStyle)(floating).direction === 'rtl';\n if (isRTL) {\n setIsRTL(true);\n }\n }, [floating]);\n if (!floating) {\n return null;\n }\n const [side, alignment] = placement.split('-');\n const isVerticalSide = side === 'top' || side === 'bottom';\n let computedStaticOffset = staticOffset;\n if (isVerticalSide && shift != null && shift.x || !isVerticalSide && shift != null && shift.y) {\n computedStaticOffset = null;\n }\n\n // Strokes must be double the border width, this ensures the stroke's width\n // works as you'd expect.\n const computedStrokeWidth = strokeWidth * 2;\n const halfStrokeWidth = computedStrokeWidth / 2;\n const svgX = width / 2 * (tipRadius / -8 + 1);\n const svgY = height / 2 * tipRadius / 4;\n const isCustomShape = !!d;\n const yOffsetProp = computedStaticOffset && alignment === 'end' ? 'bottom' : 'top';\n let xOffsetProp = computedStaticOffset && alignment === 'end' ? 'right' : 'left';\n if (computedStaticOffset && isRTL) {\n xOffsetProp = alignment === 'end' ? 'left' : 'right';\n }\n const arrowX = (arrow == null ? void 0 : arrow.x) != null ? computedStaticOffset || arrow.x : '';\n const arrowY = (arrow == null ? void 0 : arrow.y) != null ? computedStaticOffset || arrow.y : '';\n const dValue = d || 'M0,0' + (\" H\" + width) + (\" L\" + (width - svgX) + \",\" + (height - svgY)) + (\" Q\" + width / 2 + \",\" + height + \" \" + svgX + \",\" + (height - svgY)) + ' Z';\n const rotation = {\n top: isCustomShape ? 'rotate(180deg)' : '',\n left: isCustomShape ? 'rotate(90deg)' : 'rotate(-90deg)',\n bottom: isCustomShape ? '' : 'rotate(180deg)',\n right: isCustomShape ? 'rotate(-90deg)' : 'rotate(90deg)'\n }[side];\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsxs)(\"svg\", {\n ...rest,\n \"aria-hidden\": true,\n ref: ref,\n width: isCustomShape ? width : width + computedStrokeWidth,\n height: width,\n viewBox: \"0 0 \" + width + \" \" + (height > width ? height : width),\n style: {\n position: 'absolute',\n pointerEvents: 'none',\n [xOffsetProp]: arrowX,\n [yOffsetProp]: arrowY,\n [side]: isVerticalSide || isCustomShape ? '100%' : \"calc(100% - \" + computedStrokeWidth / 2 + \"px)\",\n transform: [rotation, transform].filter(t => !!t).join(' '),\n ...restStyle\n },\n children: [computedStrokeWidth > 0 && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"path\", {\n clipPath: \"url(#\" + clipPathId + \")\",\n fill: \"none\",\n stroke: stroke\n // Account for the stroke on the fill path rendered below.\n ,\n strokeWidth: computedStrokeWidth + (d ? 0 : 1),\n d: dValue\n }), /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"path\", {\n stroke: computedStrokeWidth && !d ? rest.fill : 'none',\n d: dValue\n }), /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"clipPath\", {\n id: clipPathId,\n children: /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"rect\", {\n x: -halfStrokeWidth,\n y: halfStrokeWidth * (isCustomShape ? -1 : 1),\n width: width + computedStrokeWidth,\n height: width\n })\n })]\n });\n});\n\nfunction createEventEmitter() {\n const map = new Map();\n return {\n emit(event, data) {\n var _map$get;\n (_map$get = map.get(event)) == null || _map$get.forEach(listener => listener(data));\n },\n on(event, listener) {\n if (!map.has(event)) {\n map.set(event, new Set());\n }\n map.get(event).add(listener);\n },\n off(event, listener) {\n var _map$get2;\n (_map$get2 = map.get(event)) == null || _map$get2.delete(listener);\n }\n };\n}\n\nconst FloatingNodeContext = /*#__PURE__*/react__rspack_import_0.createContext(null);\nconst FloatingTreeContext = /*#__PURE__*/react__rspack_import_0.createContext(null);\n\n/**\n * Returns the parent node id for nested floating elements, if available.\n * Returns `null` for top-level floating elements.\n */\nconst useFloatingParentNodeId = () => {\n var _React$useContext;\n return ((_React$useContext = react__rspack_import_0.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;\n};\n\n/**\n * Returns the nearest floating tree context, if available.\n */\nconst useFloatingTree = () => react__rspack_import_0.useContext(FloatingTreeContext);\n\n/**\n * Registers a node into the `FloatingTree`, returning its id.\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction useFloatingNodeId(customParentId) {\n const id = useId();\n const tree = useFloatingTree();\n const reactParentId = useFloatingParentNodeId();\n const parentId = customParentId || reactParentId;\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!id) return;\n const node = {\n id,\n parentId\n };\n tree == null || tree.addNode(node);\n return () => {\n tree == null || tree.removeNode(node);\n };\n }, [tree, id, parentId]);\n return id;\n}\n/**\n * Provides parent node context for nested floating elements.\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction FloatingNode(props) {\n const {\n children,\n id\n } = props;\n const parentId = useFloatingParentNodeId();\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingNodeContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n id,\n parentId\n }), [id, parentId]),\n children: children\n });\n}\n/**\n * Provides context for nested floating elements when they are not children of\n * each other on the DOM.\n * This is not necessary in all cases, except when there must be explicit communication between parent and child floating elements. It is necessary for:\n * - The `bubbles` option in the `useDismiss()` Hook\n * - Nested virtual list navigation\n * - Nested floating elements that each open on hover\n * - Custom communication between parent and child floating elements\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction FloatingTree(props) {\n const {\n children\n } = props;\n const nodesRef = react__rspack_import_0.useRef([]);\n const addNode = react__rspack_import_0.useCallback(node => {\n nodesRef.current = [...nodesRef.current, node];\n }, []);\n const removeNode = react__rspack_import_0.useCallback(node => {\n nodesRef.current = nodesRef.current.filter(n => n !== node);\n }, []);\n const [events] = react__rspack_import_0.useState(() => createEventEmitter());\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingTreeContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n nodesRef,\n addNode,\n removeNode,\n events\n }), [addNode, removeNode, events]),\n children: children\n });\n}\n\nfunction createAttribute(name) {\n return \"data-floating-ui-\" + name;\n}\n\nfunction clearTimeoutIfSet(timeoutRef) {\n if (timeoutRef.current !== -1) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = -1;\n }\n}\n\nconst safePolygonIdentifier = /*#__PURE__*/createAttribute('safe-polygon');\nfunction getDelay(value, prop, pointerType) {\n if (pointerType && !(0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType)) {\n return 0;\n }\n if (typeof value === 'number') {\n return value;\n }\n if (typeof value === 'function') {\n const result = value();\n if (typeof result === 'number') {\n return result;\n }\n return result == null ? void 0 : result[prop];\n }\n return value == null ? void 0 : value[prop];\n}\nfunction getRestMs(value) {\n if (typeof value === 'function') {\n return value();\n }\n return value;\n}\n/**\n * Opens the floating element while hovering over the reference element, like\n * CSS `:hover`.\n * @see https://floating-ui.com/docs/useHover\n */\nfunction useHover(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n dataRef,\n events,\n elements\n } = context;\n const {\n enabled = true,\n delay = 0,\n handleClose = null,\n mouseOnly = false,\n restMs = 0,\n move = true\n } = props;\n const tree = useFloatingTree();\n const parentId = useFloatingParentNodeId();\n const handleCloseRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(handleClose);\n const delayRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(delay);\n const openRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(open);\n const restMsRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(restMs);\n const pointerTypeRef = react__rspack_import_0.useRef();\n const timeoutRef = react__rspack_import_0.useRef(-1);\n const handlerRef = react__rspack_import_0.useRef();\n const restTimeoutRef = react__rspack_import_0.useRef(-1);\n const blockMouseMoveRef = react__rspack_import_0.useRef(true);\n const performedPointerEventsMutationRef = react__rspack_import_0.useRef(false);\n const unbindMouseMoveRef = react__rspack_import_0.useRef(() => {});\n const restTimeoutPendingRef = react__rspack_import_0.useRef(false);\n const isHoverOpen = react__rspack_import_0.useCallback(() => {\n var _dataRef$current$open;\n const type = (_dataRef$current$open = dataRef.current.openEvent) == null ? void 0 : _dataRef$current$open.type;\n return (type == null ? void 0 : type.includes('mouse')) && type !== 'mousedown';\n }, [dataRef]);\n\n // When closing before opening, clear the delay timeouts to cancel it\n // from showing.\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onOpenChange(_ref) {\n let {\n open\n } = _ref;\n if (!open) {\n clearTimeoutIfSet(timeoutRef);\n clearTimeoutIfSet(restTimeoutRef);\n blockMouseMoveRef.current = true;\n restTimeoutPendingRef.current = false;\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n };\n }, [enabled, events]);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n if (!handleCloseRef.current) return;\n if (!open) return;\n function onLeave(event) {\n if (isHoverOpen()) {\n onOpenChange(false, event, 'hover');\n }\n }\n const html = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).documentElement;\n html.addEventListener('mouseleave', onLeave);\n return () => {\n html.removeEventListener('mouseleave', onLeave);\n };\n }, [elements.floating, open, onOpenChange, enabled, handleCloseRef, isHoverOpen]);\n const closeWithDelay = react__rspack_import_0.useCallback(function (event, runElseBranch, reason) {\n if (runElseBranch === void 0) {\n runElseBranch = true;\n }\n if (reason === void 0) {\n reason = 'hover';\n }\n const closeDelay = getDelay(delayRef.current, 'close', pointerTypeRef.current);\n if (closeDelay && !handlerRef.current) {\n clearTimeoutIfSet(timeoutRef);\n timeoutRef.current = window.setTimeout(() => onOpenChange(false, event, reason), closeDelay);\n } else if (runElseBranch) {\n clearTimeoutIfSet(timeoutRef);\n onOpenChange(false, event, reason);\n }\n }, [delayRef, onOpenChange]);\n const cleanupMouseMoveHandler = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n unbindMouseMoveRef.current();\n handlerRef.current = undefined;\n });\n const clearPointerEvents = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n if (performedPointerEventsMutationRef.current) {\n const body = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).body;\n body.style.pointerEvents = '';\n body.removeAttribute(safePolygonIdentifier);\n performedPointerEventsMutationRef.current = false;\n }\n });\n const isClickLikeOpenEvent = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n return dataRef.current.openEvent ? ['click', 'mousedown'].includes(dataRef.current.openEvent.type) : false;\n });\n\n // Registering the mouse events on the reference directly to bypass React's\n // delegation system. If the cursor was on a disabled element and then entered\n // the reference (no gap), `mouseenter` doesn't fire in the delegation system.\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onReferenceMouseEnter(event) {\n clearTimeoutIfSet(timeoutRef);\n blockMouseMoveRef.current = false;\n if (mouseOnly && !(0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerTypeRef.current) || getRestMs(restMsRef.current) > 0 && !getDelay(delayRef.current, 'open')) {\n return;\n }\n const openDelay = getDelay(delayRef.current, 'open', pointerTypeRef.current);\n if (openDelay) {\n timeoutRef.current = window.setTimeout(() => {\n if (!openRef.current) {\n onOpenChange(true, event, 'hover');\n }\n }, openDelay);\n } else if (!open) {\n onOpenChange(true, event, 'hover');\n }\n }\n function onReferenceMouseLeave(event) {\n if (isClickLikeOpenEvent()) {\n clearPointerEvents();\n return;\n }\n unbindMouseMoveRef.current();\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating);\n clearTimeoutIfSet(restTimeoutRef);\n restTimeoutPendingRef.current = false;\n if (handleCloseRef.current && dataRef.current.floatingContext) {\n // Prevent clearing `onScrollMouseLeave` timeout.\n if (!open) {\n clearTimeoutIfSet(timeoutRef);\n }\n handlerRef.current = handleCloseRef.current({\n ...dataRef.current.floatingContext,\n tree,\n x: event.clientX,\n y: event.clientY,\n onClose() {\n clearPointerEvents();\n cleanupMouseMoveHandler();\n if (!isClickLikeOpenEvent()) {\n closeWithDelay(event, true, 'safe-polygon');\n }\n }\n });\n const handler = handlerRef.current;\n doc.addEventListener('mousemove', handler);\n unbindMouseMoveRef.current = () => {\n doc.removeEventListener('mousemove', handler);\n };\n return;\n }\n\n // Allow interactivity without `safePolygon` on touch devices. With a\n // pointer, a short close delay is an alternative, so it should work\n // consistently.\n const shouldClose = pointerTypeRef.current === 'touch' ? !(0,_floating_ui_react_utils__rspack_import_6.contains)(elements.floating, event.relatedTarget) : true;\n if (shouldClose) {\n closeWithDelay(event);\n }\n }\n\n // Ensure the floating element closes after scrolling even if the pointer\n // did not move.\n // https://github.com/floating-ui/floating-ui/discussions/1692\n function onScrollMouseLeave(event) {\n if (isClickLikeOpenEvent()) return;\n if (!dataRef.current.floatingContext) return;\n handleCloseRef.current == null || handleCloseRef.current({\n ...dataRef.current.floatingContext,\n tree,\n x: event.clientX,\n y: event.clientY,\n onClose() {\n clearPointerEvents();\n cleanupMouseMoveHandler();\n if (!isClickLikeOpenEvent()) {\n closeWithDelay(event);\n }\n }\n })(event);\n }\n function onFloatingMouseEnter() {\n clearTimeoutIfSet(timeoutRef);\n }\n function onFloatingMouseLeave(event) {\n if (!isClickLikeOpenEvent()) {\n closeWithDelay(event, false);\n }\n }\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.domReference)) {\n const reference = elements.domReference;\n const floating = elements.floating;\n if (open) {\n reference.addEventListener('mouseleave', onScrollMouseLeave);\n }\n if (move) {\n reference.addEventListener('mousemove', onReferenceMouseEnter, {\n once: true\n });\n }\n reference.addEventListener('mouseenter', onReferenceMouseEnter);\n reference.addEventListener('mouseleave', onReferenceMouseLeave);\n if (floating) {\n floating.addEventListener('mouseleave', onScrollMouseLeave);\n floating.addEventListener('mouseenter', onFloatingMouseEnter);\n floating.addEventListener('mouseleave', onFloatingMouseLeave);\n }\n return () => {\n if (open) {\n reference.removeEventListener('mouseleave', onScrollMouseLeave);\n }\n if (move) {\n reference.removeEventListener('mousemove', onReferenceMouseEnter);\n }\n reference.removeEventListener('mouseenter', onReferenceMouseEnter);\n reference.removeEventListener('mouseleave', onReferenceMouseLeave);\n if (floating) {\n floating.removeEventListener('mouseleave', onScrollMouseLeave);\n floating.removeEventListener('mouseenter', onFloatingMouseEnter);\n floating.removeEventListener('mouseleave', onFloatingMouseLeave);\n }\n };\n }\n }, [elements, enabled, context, mouseOnly, move, closeWithDelay, cleanupMouseMoveHandler, clearPointerEvents, onOpenChange, open, openRef, tree, delayRef, handleCloseRef, dataRef, isClickLikeOpenEvent, restMsRef]);\n\n // Block pointer-events of every element other than the reference and floating\n // while the floating element is open and has a `handleClose` handler. Also\n // handles nested floating elements.\n // https://github.com/floating-ui/floating-ui/issues/1722\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n var _handleCloseRef$curre;\n if (!enabled) return;\n if (open && (_handleCloseRef$curre = handleCloseRef.current) != null && _handleCloseRef$curre.__options.blockPointerEvents && isHoverOpen()) {\n performedPointerEventsMutationRef.current = true;\n const floatingEl = elements.floating;\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.domReference) && floatingEl) {\n var _tree$nodesRef$curren;\n const body = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).body;\n body.setAttribute(safePolygonIdentifier, '');\n const ref = elements.domReference;\n const parentFloating = tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null ? void 0 : _tree$nodesRef$curren.elements.floating;\n if (parentFloating) {\n parentFloating.style.pointerEvents = '';\n }\n body.style.pointerEvents = 'none';\n ref.style.pointerEvents = 'auto';\n floatingEl.style.pointerEvents = 'auto';\n return () => {\n body.style.pointerEvents = '';\n ref.style.pointerEvents = '';\n floatingEl.style.pointerEvents = '';\n };\n }\n }\n }, [enabled, open, parentId, elements, tree, handleCloseRef, isHoverOpen]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!open) {\n pointerTypeRef.current = undefined;\n restTimeoutPendingRef.current = false;\n cleanupMouseMoveHandler();\n clearPointerEvents();\n }\n }, [open, cleanupMouseMoveHandler, clearPointerEvents]);\n react__rspack_import_0.useEffect(() => {\n return () => {\n cleanupMouseMoveHandler();\n clearTimeoutIfSet(timeoutRef);\n clearTimeoutIfSet(restTimeoutRef);\n clearPointerEvents();\n };\n }, [enabled, elements.domReference, cleanupMouseMoveHandler, clearPointerEvents]);\n const reference = react__rspack_import_0.useMemo(() => {\n function setPointerRef(event) {\n pointerTypeRef.current = event.pointerType;\n }\n return {\n onPointerDown: setPointerRef,\n onPointerEnter: setPointerRef,\n onMouseMove(event) {\n const {\n nativeEvent\n } = event;\n function handleMouseMove() {\n if (!blockMouseMoveRef.current && !openRef.current) {\n onOpenChange(true, nativeEvent, 'hover');\n }\n }\n if (mouseOnly && !(0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerTypeRef.current)) {\n return;\n }\n if (open || getRestMs(restMsRef.current) === 0) {\n return;\n }\n\n // Ignore insignificant movements to account for tremors.\n if (restTimeoutPendingRef.current && event.movementX ** 2 + event.movementY ** 2 < 2) {\n return;\n }\n clearTimeoutIfSet(restTimeoutRef);\n if (pointerTypeRef.current === 'touch') {\n handleMouseMove();\n } else {\n restTimeoutPendingRef.current = true;\n restTimeoutRef.current = window.setTimeout(handleMouseMove, getRestMs(restMsRef.current));\n }\n }\n };\n }, [mouseOnly, onOpenChange, open, openRef, restMsRef]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nconst NOOP = () => {};\nconst FloatingDelayGroupContext = /*#__PURE__*/react__rspack_import_0.createContext({\n delay: 0,\n initialDelay: 0,\n timeoutMs: 0,\n currentId: null,\n setCurrentId: NOOP,\n setState: NOOP,\n isInstantPhase: false\n});\n\n/**\n * @deprecated\n * Use the return value of `useDelayGroup()` instead.\n */\nconst useDelayGroupContext = () => react__rspack_import_0.useContext(FloatingDelayGroupContext);\n/**\n * Provides context for a group of floating elements that should share a\n * `delay`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction FloatingDelayGroup(props) {\n const {\n children,\n delay,\n timeoutMs = 0\n } = props;\n const [state, setState] = react__rspack_import_0.useReducer((prev, next) => ({\n ...prev,\n ...next\n }), {\n delay,\n timeoutMs,\n initialDelay: delay,\n currentId: null,\n isInstantPhase: false\n });\n const initialCurrentIdRef = react__rspack_import_0.useRef(null);\n const setCurrentId = react__rspack_import_0.useCallback(currentId => {\n setState({\n currentId\n });\n }, []);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (state.currentId) {\n if (initialCurrentIdRef.current === null) {\n initialCurrentIdRef.current = state.currentId;\n } else if (!state.isInstantPhase) {\n setState({\n isInstantPhase: true\n });\n }\n } else {\n if (state.isInstantPhase) {\n setState({\n isInstantPhase: false\n });\n }\n initialCurrentIdRef.current = null;\n }\n }, [state.currentId, state.isInstantPhase]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FloatingDelayGroupContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n ...state,\n setState,\n setCurrentId\n }), [state, setCurrentId]),\n children: children\n });\n}\n/**\n * Enables grouping when called inside a component that's a child of a\n * `FloatingDelayGroup`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction useDelayGroup(context, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n open,\n onOpenChange,\n floatingId\n } = context;\n const {\n id: optionId,\n enabled = true\n } = options;\n const id = optionId != null ? optionId : floatingId;\n const groupContext = useDelayGroupContext();\n const {\n currentId,\n setCurrentId,\n initialDelay,\n setState,\n timeoutMs\n } = groupContext;\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!currentId) return;\n setState({\n delay: {\n open: 1,\n close: getDelay(initialDelay, 'close')\n }\n });\n if (currentId !== id) {\n onOpenChange(false);\n }\n }, [enabled, id, onOpenChange, setState, currentId, initialDelay]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n function unset() {\n onOpenChange(false);\n setState({\n delay: initialDelay,\n currentId: null\n });\n }\n if (!enabled) return;\n if (!currentId) return;\n if (!open && currentId === id) {\n if (timeoutMs) {\n const timeout = window.setTimeout(unset, timeoutMs);\n return () => {\n clearTimeout(timeout);\n };\n }\n unset();\n }\n }, [enabled, open, setState, currentId, id, onOpenChange, initialDelay, timeoutMs]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (setCurrentId === NOOP || !open) return;\n setCurrentId(id);\n }, [enabled, open, setCurrentId, id]);\n return groupContext;\n}\n\nconst NextFloatingDelayGroupContext = /*#__PURE__*/react__rspack_import_0.createContext({\n hasProvider: false,\n timeoutMs: 0,\n delayRef: {\n current: 0\n },\n initialDelayRef: {\n current: 0\n },\n timeoutIdRef: {\n current: -1\n },\n currentIdRef: {\n current: null\n },\n currentContextRef: {\n current: null\n }\n});\n/**\n * Experimental next version of `FloatingDelayGroup` to become the default\n * in the future. This component is not yet stable.\n * Provides context for a group of floating elements that should share a\n * `delay`. Unlike `FloatingDelayGroup`, `useNextDelayGroup` with this\n * component does not cause a re-render of unrelated consumers of the\n * context when the delay changes.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction NextFloatingDelayGroup(props) {\n const {\n children,\n delay,\n timeoutMs = 0\n } = props;\n const delayRef = react__rspack_import_0.useRef(delay);\n const initialDelayRef = react__rspack_import_0.useRef(delay);\n const currentIdRef = react__rspack_import_0.useRef(null);\n const currentContextRef = react__rspack_import_0.useRef(null);\n const timeoutIdRef = react__rspack_import_0.useRef(-1);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(NextFloatingDelayGroupContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n hasProvider: true,\n delayRef,\n initialDelayRef,\n currentIdRef,\n timeoutMs,\n currentContextRef,\n timeoutIdRef\n }), [timeoutMs]),\n children: children\n });\n}\n/**\n * Enables grouping when called inside a component that's a child of a\n * `NextFloatingDelayGroup`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction useNextDelayGroup(context, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n open,\n onOpenChange,\n floatingId\n } = context;\n const {\n enabled = true\n } = options;\n const groupContext = react__rspack_import_0.useContext(NextFloatingDelayGroupContext);\n const {\n currentIdRef,\n delayRef,\n timeoutMs,\n initialDelayRef,\n currentContextRef,\n hasProvider,\n timeoutIdRef\n } = groupContext;\n const [isInstantPhase, setIsInstantPhase] = react__rspack_import_0.useState(false);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n function unset() {\n var _currentContextRef$cu;\n setIsInstantPhase(false);\n (_currentContextRef$cu = currentContextRef.current) == null || _currentContextRef$cu.setIsInstantPhase(false);\n currentIdRef.current = null;\n currentContextRef.current = null;\n delayRef.current = initialDelayRef.current;\n }\n if (!enabled) return;\n if (!currentIdRef.current) return;\n if (!open && currentIdRef.current === floatingId) {\n setIsInstantPhase(false);\n if (timeoutMs) {\n timeoutIdRef.current = window.setTimeout(unset, timeoutMs);\n return () => {\n clearTimeout(timeoutIdRef.current);\n };\n }\n unset();\n }\n }, [enabled, open, floatingId, currentIdRef, delayRef, timeoutMs, initialDelayRef, currentContextRef, timeoutIdRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!open) return;\n const prevContext = currentContextRef.current;\n const prevId = currentIdRef.current;\n currentContextRef.current = {\n onOpenChange,\n setIsInstantPhase\n };\n currentIdRef.current = floatingId;\n delayRef.current = {\n open: 0,\n close: getDelay(initialDelayRef.current, 'close')\n };\n if (prevId !== null && prevId !== floatingId) {\n clearTimeoutIfSet(timeoutIdRef);\n setIsInstantPhase(true);\n prevContext == null || prevContext.setIsInstantPhase(true);\n prevContext == null || prevContext.onOpenChange(false);\n } else {\n setIsInstantPhase(false);\n prevContext == null || prevContext.setIsInstantPhase(false);\n }\n }, [enabled, open, floatingId, onOpenChange, currentIdRef, delayRef, timeoutMs, initialDelayRef, currentContextRef, timeoutIdRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n return () => {\n currentContextRef.current = null;\n };\n }, [currentContextRef]);\n return react__rspack_import_0.useMemo(() => ({\n hasProvider,\n delayRef,\n isInstantPhase\n }), [hasProvider, delayRef, isInstantPhase]);\n}\n\nlet rafId = 0;\nfunction enqueueFocus(el, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n preventScroll = false,\n cancelPrevious = true,\n sync = false\n } = options;\n cancelPrevious && cancelAnimationFrame(rafId);\n const exec = () => el == null ? void 0 : el.focus({\n preventScroll\n });\n if (sync) {\n exec();\n } else {\n rafId = requestAnimationFrame(exec);\n }\n}\n\nfunction contains(parent, child) {\n if (!parent || !child) {\n return false;\n }\n const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();\n\n // First, attempt with faster native method\n if (parent.contains(child)) {\n return true;\n }\n\n // then fallback to custom implementation with Shadow DOM support\n if (rootNode && (0,_floating_ui_react_dom__rspack_import_5.isShadowRoot)(rootNode)) {\n let next = child;\n while (next) {\n if (parent === next) {\n return true;\n }\n // @ts-ignore\n next = next.parentNode || next.host;\n }\n }\n\n // Give up, the result is false\n return false;\n}\nfunction getTarget(event) {\n if ('composedPath' in event) {\n return event.composedPath()[0];\n }\n\n // TS thinks `event` is of type never as it assumes all browsers support\n // `composedPath()`, but browsers without shadow DOM don't.\n return event.target;\n}\nfunction getDocument(node) {\n return (node == null ? void 0 : node.ownerDocument) || document;\n}\n\n// Modified to add conditional `aria-hidden` support:\n// https://github.com/theKashey/aria-hidden/blob/9220c8f4a4fd35f63bee5510a9f41a37264382d4/src/index.ts\nlet counterMap = /*#__PURE__*/new WeakMap();\nlet uncontrolledElementsSet = /*#__PURE__*/new WeakSet();\nlet markerMap = {};\nlet lockCount$1 = 0;\nconst supportsInert = () => typeof HTMLElement !== 'undefined' && 'inert' in HTMLElement.prototype;\nconst unwrapHost = node => node && (node.host || unwrapHost(node.parentNode));\nconst correctElements = (parent, targets) => targets.map(target => {\n if (parent.contains(target)) {\n return target;\n }\n const correctedTarget = unwrapHost(target);\n if (parent.contains(correctedTarget)) {\n return correctedTarget;\n }\n return null;\n}).filter(x => x != null);\nfunction applyAttributeToOthers(uncorrectedAvoidElements, body, ariaHidden, inert) {\n const markerName = 'data-floating-ui-inert';\n const controlAttribute = inert ? 'inert' : ariaHidden ? 'aria-hidden' : null;\n const avoidElements = correctElements(body, uncorrectedAvoidElements);\n const elementsToKeep = new Set();\n const elementsToStop = new Set(avoidElements);\n const hiddenElements = [];\n if (!markerMap[markerName]) {\n markerMap[markerName] = new WeakMap();\n }\n const markerCounter = markerMap[markerName];\n avoidElements.forEach(keep);\n deep(body);\n elementsToKeep.clear();\n function keep(el) {\n if (!el || elementsToKeep.has(el)) {\n return;\n }\n elementsToKeep.add(el);\n el.parentNode && keep(el.parentNode);\n }\n function deep(parent) {\n if (!parent || elementsToStop.has(parent)) {\n return;\n }\n [].forEach.call(parent.children, node => {\n if ((0,_floating_ui_react_dom__rspack_import_5.getNodeName)(node) === 'script') return;\n if (elementsToKeep.has(node)) {\n deep(node);\n } else {\n const attr = controlAttribute ? node.getAttribute(controlAttribute) : null;\n const alreadyHidden = attr !== null && attr !== 'false';\n const currentCounterValue = counterMap.get(node) || 0;\n const counterValue = controlAttribute ? currentCounterValue + 1 : currentCounterValue;\n const markerValue = (markerCounter.get(node) || 0) + 1;\n counterMap.set(node, counterValue);\n markerCounter.set(node, markerValue);\n hiddenElements.push(node);\n if (counterValue === 1 && alreadyHidden) {\n uncontrolledElementsSet.add(node);\n }\n if (markerValue === 1) {\n node.setAttribute(markerName, '');\n }\n if (!alreadyHidden && controlAttribute) {\n node.setAttribute(controlAttribute, controlAttribute === 'inert' ? '' : 'true');\n }\n }\n });\n }\n lockCount$1++;\n return () => {\n hiddenElements.forEach(element => {\n const currentCounterValue = counterMap.get(element) || 0;\n const counterValue = controlAttribute ? currentCounterValue - 1 : currentCounterValue;\n const markerValue = (markerCounter.get(element) || 0) - 1;\n counterMap.set(element, counterValue);\n markerCounter.set(element, markerValue);\n if (!counterValue) {\n if (!uncontrolledElementsSet.has(element) && controlAttribute) {\n element.removeAttribute(controlAttribute);\n }\n uncontrolledElementsSet.delete(element);\n }\n if (!markerValue) {\n element.removeAttribute(markerName);\n }\n });\n lockCount$1--;\n if (!lockCount$1) {\n counterMap = new WeakMap();\n counterMap = new WeakMap();\n uncontrolledElementsSet = new WeakSet();\n markerMap = {};\n }\n };\n}\nfunction markOthers(avoidElements, ariaHidden, inert) {\n if (ariaHidden === void 0) {\n ariaHidden = false;\n }\n if (inert === void 0) {\n inert = false;\n }\n const body = getDocument(avoidElements[0]).body;\n return applyAttributeToOthers(avoidElements.concat(Array.from(body.querySelectorAll('[aria-live]'))), body, ariaHidden, inert);\n}\n\nconst HIDDEN_STYLES = {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'fixed',\n whiteSpace: 'nowrap',\n width: '1px',\n top: 0,\n left: 0\n};\nconst FocusGuard = /*#__PURE__*/react__rspack_import_0.forwardRef(function FocusGuard(props, ref) {\n const [role, setRole] = react__rspack_import_0.useState();\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if ((0,_floating_ui_react_utils__rspack_import_6.isSafari)()) {\n // Unlike other screen readers such as NVDA and JAWS, the virtual cursor\n // on VoiceOver does trigger the onFocus event, so we can use the focus\n // trap element. On Safari, only buttons trigger the onFocus event.\n // NB: \"group\" role in the Sandbox no longer appears to work, must be a\n // button role.\n setRole('button');\n }\n }, []);\n const restProps = {\n ref,\n tabIndex: 0,\n // Role is only for VoiceOver\n role,\n 'aria-hidden': role ? undefined : true,\n [createAttribute('focus-guard')]: '',\n style: HIDDEN_STYLES\n };\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"span\", {\n ...props,\n ...restProps\n });\n});\n\nconst PortalContext = /*#__PURE__*/react__rspack_import_0.createContext(null);\nconst attr = /*#__PURE__*/createAttribute('portal');\n/**\n * @see https://floating-ui.com/docs/FloatingPortal#usefloatingportalnode\n */\nfunction useFloatingPortalNode(props) {\n if (props === void 0) {\n props = {};\n }\n const {\n id,\n root\n } = props;\n const uniqueId = useId();\n const portalContext = usePortalContext();\n const [portalNode, setPortalNode] = react__rspack_import_0.useState(null);\n const portalNodeRef = react__rspack_import_0.useRef(null);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n return () => {\n portalNode == null || portalNode.remove();\n // Allow the subsequent layout effects to create a new node on updates.\n // The portal node will still be cleaned up on unmount.\n // https://github.com/floating-ui/floating-ui/issues/2454\n queueMicrotask(() => {\n portalNodeRef.current = null;\n });\n };\n }, [portalNode]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n // Wait for the uniqueId to be generated before creating the portal node in\n // React <18 (using `useFloatingId` instead of the native `useId`).\n // https://github.com/floating-ui/floating-ui/issues/2778\n if (!uniqueId) return;\n if (portalNodeRef.current) return;\n const existingIdRoot = id ? document.getElementById(id) : null;\n if (!existingIdRoot) return;\n const subRoot = document.createElement('div');\n subRoot.id = uniqueId;\n subRoot.setAttribute(attr, '');\n existingIdRoot.appendChild(subRoot);\n portalNodeRef.current = subRoot;\n setPortalNode(subRoot);\n }, [id, uniqueId]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n // Wait for the root to exist before creating the portal node. The root must\n // be stored in state, not a ref, for this to work reactively.\n if (root === null) return;\n if (!uniqueId) return;\n if (portalNodeRef.current) return;\n let container = root || (portalContext == null ? void 0 : portalContext.portalNode);\n if (container && !(0,_floating_ui_react_dom__rspack_import_5.isElement)(container)) container = container.current;\n container = container || document.body;\n let idWrapper = null;\n if (id) {\n idWrapper = document.createElement('div');\n idWrapper.id = id;\n container.appendChild(idWrapper);\n }\n const subRoot = document.createElement('div');\n subRoot.id = uniqueId;\n subRoot.setAttribute(attr, '');\n container = idWrapper || container;\n container.appendChild(subRoot);\n portalNodeRef.current = subRoot;\n setPortalNode(subRoot);\n }, [id, root, uniqueId, portalContext]);\n return portalNode;\n}\n/**\n * Portals the floating element into a given container element — by default,\n * outside of the app root and into the body.\n * This is necessary to ensure the floating element can appear outside any\n * potential parent containers that cause clipping (such as `overflow: hidden`),\n * while retaining its location in the React tree.\n * @see https://floating-ui.com/docs/FloatingPortal\n */\nfunction FloatingPortal(props) {\n const {\n children,\n id,\n root,\n preserveTabOrder = true\n } = props;\n const portalNode = useFloatingPortalNode({\n id,\n root\n });\n const [focusManagerState, setFocusManagerState] = react__rspack_import_0.useState(null);\n const beforeOutsideRef = react__rspack_import_0.useRef(null);\n const afterOutsideRef = react__rspack_import_0.useRef(null);\n const beforeInsideRef = react__rspack_import_0.useRef(null);\n const afterInsideRef = react__rspack_import_0.useRef(null);\n const modal = focusManagerState == null ? void 0 : focusManagerState.modal;\n const open = focusManagerState == null ? void 0 : focusManagerState.open;\n const shouldRenderGuards =\n // The FocusManager and therefore floating element are currently open/\n // rendered.\n !!focusManagerState &&\n // Guards are only for non-modal focus management.\n !focusManagerState.modal &&\n // Don't render if unmount is transitioning.\n focusManagerState.open && preserveTabOrder && !!(root || portalNode);\n\n // https://codesandbox.io/s/tabbable-portal-f4tng?file=/src/TabbablePortal.tsx\n react__rspack_import_0.useEffect(() => {\n if (!portalNode || !preserveTabOrder || modal) {\n return;\n }\n\n // Make sure elements inside the portal element are tabbable only when the\n // portal has already been focused, either by tabbing into a focus trap\n // element outside or using the mouse.\n function onFocus(event) {\n if (portalNode && (0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event)) {\n const focusing = event.type === 'focusin';\n const manageFocus = focusing ? _floating_ui_react_utils__rspack_import_6.enableFocusInside : _floating_ui_react_utils__rspack_import_6.disableFocusInside;\n manageFocus(portalNode);\n }\n }\n // Listen to the event on the capture phase so they run before the focus\n // trap elements onFocus prop is called.\n portalNode.addEventListener('focusin', onFocus, true);\n portalNode.addEventListener('focusout', onFocus, true);\n return () => {\n portalNode.removeEventListener('focusin', onFocus, true);\n portalNode.removeEventListener('focusout', onFocus, true);\n };\n }, [portalNode, preserveTabOrder, modal]);\n react__rspack_import_0.useEffect(() => {\n if (!portalNode) return;\n if (open) return;\n (0,_floating_ui_react_utils__rspack_import_6.enableFocusInside)(portalNode);\n }, [open, portalNode]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsxs)(PortalContext.Provider, {\n value: react__rspack_import_0.useMemo(() => ({\n preserveTabOrder,\n beforeOutsideRef,\n afterOutsideRef,\n beforeInsideRef,\n afterInsideRef,\n portalNode,\n setFocusManagerState\n }), [preserveTabOrder, portalNode]),\n children: [shouldRenderGuards && portalNode && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"outside\",\n ref: beforeOutsideRef,\n onFocus: event => {\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalNode)) {\n var _beforeInsideRef$curr;\n (_beforeInsideRef$curr = beforeInsideRef.current) == null || _beforeInsideRef$curr.focus();\n } else {\n const domReference = focusManagerState ? focusManagerState.domReference : null;\n const prevTabbable = (0,_floating_ui_react_utils__rspack_import_6.getPreviousTabbable)(domReference);\n prevTabbable == null || prevTabbable.focus();\n }\n }\n }), shouldRenderGuards && portalNode && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"span\", {\n \"aria-owns\": portalNode.id,\n style: HIDDEN_STYLES\n }), portalNode && /*#__PURE__*/react_dom__rspack_import_2.createPortal(children, portalNode), shouldRenderGuards && portalNode && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"outside\",\n ref: afterOutsideRef,\n onFocus: event => {\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalNode)) {\n var _afterInsideRef$curre;\n (_afterInsideRef$curre = afterInsideRef.current) == null || _afterInsideRef$curre.focus();\n } else {\n const domReference = focusManagerState ? focusManagerState.domReference : null;\n const nextTabbable = (0,_floating_ui_react_utils__rspack_import_6.getNextTabbable)(domReference);\n nextTabbable == null || nextTabbable.focus();\n (focusManagerState == null ? void 0 : focusManagerState.closeOnFocusOut) && (focusManagerState == null ? void 0 : focusManagerState.onOpenChange(false, event.nativeEvent, 'focus-out'));\n }\n }\n })]\n });\n}\nconst usePortalContext = () => react__rspack_import_0.useContext(PortalContext);\n\nfunction useLiteMergeRefs(refs) {\n return react__rspack_import_0.useMemo(() => {\n return value => {\n refs.forEach(ref => {\n if (ref) {\n ref.current = value;\n }\n });\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, refs);\n}\n\nconst LIST_LIMIT = 20;\nlet previouslyFocusedElements = [];\nfunction addPreviouslyFocusedElement(element) {\n previouslyFocusedElements = previouslyFocusedElements.filter(el => el.isConnected);\n if (element && (0,_floating_ui_react_dom__rspack_import_5.getNodeName)(element) !== 'body') {\n previouslyFocusedElements.push(element);\n if (previouslyFocusedElements.length > LIST_LIMIT) {\n previouslyFocusedElements = previouslyFocusedElements.slice(-20);\n }\n }\n}\nfunction getPreviouslyFocusedElement() {\n return previouslyFocusedElements.slice().reverse().find(el => el.isConnected);\n}\nfunction getFirstTabbableElement(container) {\n const tabbableOptions = (0,_floating_ui_react_utils__rspack_import_6.getTabbableOptions)();\n if ((0,tabbable__rspack_import_7.isTabbable)(container, tabbableOptions)) {\n return container;\n }\n return (0,tabbable__rspack_import_7.tabbable)(container, tabbableOptions)[0] || container;\n}\nfunction handleTabIndex(floatingFocusElement, orderRef) {\n var _floatingFocusElement;\n if (!orderRef.current.includes('floating') && !((_floatingFocusElement = floatingFocusElement.getAttribute('role')) != null && _floatingFocusElement.includes('dialog'))) {\n return;\n }\n const options = (0,_floating_ui_react_utils__rspack_import_6.getTabbableOptions)();\n const focusableElements = (0,tabbable__rspack_import_7.focusable)(floatingFocusElement, options);\n const tabbableContent = focusableElements.filter(element => {\n const dataTabIndex = element.getAttribute('data-tabindex') || '';\n return (0,tabbable__rspack_import_7.isTabbable)(element, options) || element.hasAttribute('data-tabindex') && !dataTabIndex.startsWith('-');\n });\n const tabIndex = floatingFocusElement.getAttribute('tabindex');\n if (orderRef.current.includes('floating') || tabbableContent.length === 0) {\n if (tabIndex !== '0') {\n floatingFocusElement.setAttribute('tabindex', '0');\n }\n } else if (tabIndex !== '-1' || floatingFocusElement.hasAttribute('data-tabindex') && floatingFocusElement.getAttribute('data-tabindex') !== '-1') {\n floatingFocusElement.setAttribute('tabindex', '-1');\n floatingFocusElement.setAttribute('data-tabindex', '-1');\n }\n}\nconst VisuallyHiddenDismiss = /*#__PURE__*/react__rspack_import_0.forwardRef(function VisuallyHiddenDismiss(props, ref) {\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"button\", {\n ...props,\n type: \"button\",\n ref: ref,\n tabIndex: -1,\n style: HIDDEN_STYLES\n });\n});\n/**\n * Provides focus management for the floating element.\n * @see https://floating-ui.com/docs/FloatingFocusManager\n */\nfunction FloatingFocusManager(props) {\n const {\n context,\n children,\n disabled = false,\n order = ['content'],\n guards: _guards = true,\n initialFocus = 0,\n returnFocus = true,\n restoreFocus = false,\n modal = true,\n visuallyHiddenDismiss = false,\n closeOnFocusOut = true,\n outsideElementsInert = false,\n getInsideElements: _getInsideElements = () => []\n } = props;\n const {\n open,\n onOpenChange,\n events,\n dataRef,\n elements: {\n domReference,\n floating\n }\n } = context;\n const getNodeId = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n var _dataRef$current$floa;\n return (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;\n });\n const getInsideElements = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(_getInsideElements);\n const ignoreInitialFocus = typeof initialFocus === 'number' && initialFocus < 0;\n // If the reference is a combobox and is typeable (e.g. input/textarea),\n // there are different focus semantics. The guards should not be rendered, but\n // aria-hidden should be applied to all nodes still. Further, the visually\n // hidden dismiss button should only appear at the end of the list, not the\n // start.\n const isUntrappedTypeableCombobox = (0,_floating_ui_react_utils__rspack_import_6.isTypeableCombobox)(domReference) && ignoreInitialFocus;\n\n // Force the guards to be rendered if the `inert` attribute is not supported.\n const inertSupported = supportsInert();\n const guards = inertSupported ? _guards : true;\n const useInert = !guards || inertSupported && outsideElementsInert;\n const orderRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(order);\n const initialFocusRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(initialFocus);\n const returnFocusRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(returnFocus);\n const tree = useFloatingTree();\n const portalContext = usePortalContext();\n const startDismissButtonRef = react__rspack_import_0.useRef(null);\n const endDismissButtonRef = react__rspack_import_0.useRef(null);\n const preventReturnFocusRef = react__rspack_import_0.useRef(false);\n const isPointerDownRef = react__rspack_import_0.useRef(false);\n const tabbableIndexRef = react__rspack_import_0.useRef(-1);\n const isInsidePortal = portalContext != null;\n const floatingFocusElement = (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)(floating);\n const getTabbableContent = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(function (container) {\n if (container === void 0) {\n container = floatingFocusElement;\n }\n return container ? (0,tabbable__rspack_import_7.tabbable)(container, (0,_floating_ui_react_utils__rspack_import_6.getTabbableOptions)()) : [];\n });\n const getTabbableElements = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(container => {\n const content = getTabbableContent(container);\n return orderRef.current.map(type => {\n if (domReference && type === 'reference') {\n return domReference;\n }\n if (floatingFocusElement && type === 'floating') {\n return floatingFocusElement;\n }\n return content;\n }).filter(Boolean).flat();\n });\n react__rspack_import_0.useEffect(() => {\n if (disabled) return;\n if (!modal) return;\n function onKeyDown(event) {\n if (event.key === 'Tab') {\n // The focus guards have nothing to focus, so we need to stop the event.\n if ((0,_floating_ui_react_utils__rspack_import_6.contains)(floatingFocusElement, (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement))) && getTabbableContent().length === 0 && !isUntrappedTypeableCombobox) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n }\n const els = getTabbableElements();\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n if (orderRef.current[0] === 'reference' && target === domReference) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n if (event.shiftKey) {\n enqueueFocus(els[els.length - 1]);\n } else {\n enqueueFocus(els[1]);\n }\n }\n if (orderRef.current[1] === 'floating' && target === floatingFocusElement && event.shiftKey) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n enqueueFocus(els[0]);\n }\n }\n }\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement);\n doc.addEventListener('keydown', onKeyDown);\n return () => {\n doc.removeEventListener('keydown', onKeyDown);\n };\n }, [disabled, domReference, floatingFocusElement, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);\n react__rspack_import_0.useEffect(() => {\n if (disabled) return;\n if (!floating) return;\n function handleFocusIn(event) {\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n const tabbableContent = getTabbableContent();\n const tabbableIndex = tabbableContent.indexOf(target);\n if (tabbableIndex !== -1) {\n tabbableIndexRef.current = tabbableIndex;\n }\n }\n floating.addEventListener('focusin', handleFocusIn);\n return () => {\n floating.removeEventListener('focusin', handleFocusIn);\n };\n }, [disabled, floating, getTabbableContent]);\n react__rspack_import_0.useEffect(() => {\n if (disabled) return;\n if (!closeOnFocusOut) return;\n\n // In Safari, buttons lose focus when pressing them.\n function handlePointerDown() {\n isPointerDownRef.current = true;\n setTimeout(() => {\n isPointerDownRef.current = false;\n });\n }\n function handleFocusOutside(event) {\n const relatedTarget = event.relatedTarget;\n const currentTarget = event.currentTarget;\n queueMicrotask(() => {\n const nodeId = getNodeId();\n const movedToUnrelatedNode = !((0,_floating_ui_react_utils__rspack_import_6.contains)(domReference, relatedTarget) || (0,_floating_ui_react_utils__rspack_import_6.contains)(floating, relatedTarget) || (0,_floating_ui_react_utils__rspack_import_6.contains)(relatedTarget, floating) || (0,_floating_ui_react_utils__rspack_import_6.contains)(portalContext == null ? void 0 : portalContext.portalNode, relatedTarget) || relatedTarget != null && relatedTarget.hasAttribute(createAttribute('focus-guard')) || tree && ((0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId).find(node => {\n var _node$context, _node$context2;\n return (0,_floating_ui_react_utils__rspack_import_6.contains)((_node$context = node.context) == null ? void 0 : _node$context.elements.floating, relatedTarget) || (0,_floating_ui_react_utils__rspack_import_6.contains)((_node$context2 = node.context) == null ? void 0 : _node$context2.elements.domReference, relatedTarget);\n }) || (0,_floating_ui_react_utils__rspack_import_6.getNodeAncestors)(tree.nodesRef.current, nodeId).find(node => {\n var _node$context3, _node$context4, _node$context5;\n return [(_node$context3 = node.context) == null ? void 0 : _node$context3.elements.floating, (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)((_node$context4 = node.context) == null ? void 0 : _node$context4.elements.floating)].includes(relatedTarget) || ((_node$context5 = node.context) == null ? void 0 : _node$context5.elements.domReference) === relatedTarget;\n })));\n if (currentTarget === domReference && floatingFocusElement) {\n handleTabIndex(floatingFocusElement, orderRef);\n }\n\n // Restore focus to the previous tabbable element index to prevent\n // focus from being lost outside the floating tree.\n if (restoreFocus && movedToUnrelatedNode && (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement)) === (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement).body) {\n // Let `FloatingPortal` effect knows that focus is still inside the\n // floating tree.\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(floatingFocusElement)) {\n floatingFocusElement.focus();\n }\n const prevTabbableIndex = tabbableIndexRef.current;\n const tabbableContent = getTabbableContent();\n const nodeToFocus = tabbableContent[prevTabbableIndex] || tabbableContent[tabbableContent.length - 1] || floatingFocusElement;\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(nodeToFocus)) {\n nodeToFocus.focus();\n }\n }\n\n // Focus did not move inside the floating tree, and there are no tabbable\n // portal guards to handle closing.\n if ((isUntrappedTypeableCombobox ? true : !modal) && relatedTarget && movedToUnrelatedNode && !isPointerDownRef.current &&\n // Fix React 18 Strict Mode returnFocus due to double rendering.\n relatedTarget !== getPreviouslyFocusedElement()) {\n preventReturnFocusRef.current = true;\n onOpenChange(false, event, 'focus-out');\n }\n });\n }\n if (floating && (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(domReference)) {\n domReference.addEventListener('focusout', handleFocusOutside);\n domReference.addEventListener('pointerdown', handlePointerDown);\n floating.addEventListener('focusout', handleFocusOutside);\n return () => {\n domReference.removeEventListener('focusout', handleFocusOutside);\n domReference.removeEventListener('pointerdown', handlePointerDown);\n floating.removeEventListener('focusout', handleFocusOutside);\n };\n }\n }, [disabled, domReference, floating, floatingFocusElement, modal, tree, portalContext, onOpenChange, closeOnFocusOut, restoreFocus, getTabbableContent, isUntrappedTypeableCombobox, getNodeId, orderRef]);\n const beforeGuardRef = react__rspack_import_0.useRef(null);\n const afterGuardRef = react__rspack_import_0.useRef(null);\n const mergedBeforeGuardRef = useLiteMergeRefs([beforeGuardRef, portalContext == null ? void 0 : portalContext.beforeInsideRef]);\n const mergedAfterGuardRef = useLiteMergeRefs([afterGuardRef, portalContext == null ? void 0 : portalContext.afterInsideRef]);\n react__rspack_import_0.useEffect(() => {\n var _portalContext$portal, _ancestors$find;\n if (disabled) return;\n if (!floating) return;\n\n // Don't hide portals nested within the parent portal.\n const portalNodes = Array.from((portalContext == null || (_portalContext$portal = portalContext.portalNode) == null ? void 0 : _portalContext$portal.querySelectorAll(\"[\" + createAttribute('portal') + \"]\")) || []);\n const ancestors = tree ? (0,_floating_ui_react_utils__rspack_import_6.getNodeAncestors)(tree.nodesRef.current, getNodeId()) : [];\n const ancestorFloatingNodes = tree && !modal ? ancestors.map(node => {\n var _node$context6;\n return (_node$context6 = node.context) == null ? void 0 : _node$context6.elements.floating;\n }) : [];\n const rootAncestorComboboxDomReference = (_ancestors$find = ancestors.find(node => {\n var _node$context7;\n return (0,_floating_ui_react_utils__rspack_import_6.isTypeableCombobox)(((_node$context7 = node.context) == null ? void 0 : _node$context7.elements.domReference) || null);\n })) == null || (_ancestors$find = _ancestors$find.context) == null ? void 0 : _ancestors$find.elements.domReference;\n const insideElements = [floating, rootAncestorComboboxDomReference, ...portalNodes, ...ancestorFloatingNodes, ...getInsideElements(), startDismissButtonRef.current, endDismissButtonRef.current, beforeGuardRef.current, afterGuardRef.current, portalContext == null ? void 0 : portalContext.beforeOutsideRef.current, portalContext == null ? void 0 : portalContext.afterOutsideRef.current, orderRef.current.includes('reference') || isUntrappedTypeableCombobox ? domReference : null].filter(x => x != null);\n const cleanup = modal || isUntrappedTypeableCombobox ? markOthers(insideElements, !useInert, useInert) : markOthers(insideElements);\n return () => {\n cleanup();\n };\n }, [disabled, domReference, floating, modal, orderRef, portalContext, isUntrappedTypeableCombobox, guards, useInert, tree, getNodeId, getInsideElements]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled || !(0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(floatingFocusElement)) return;\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement);\n const previouslyFocusedElement = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(doc);\n\n // Wait for any layout effect state setters to execute to set `tabIndex`.\n queueMicrotask(() => {\n const focusableElements = getTabbableElements(floatingFocusElement);\n const initialFocusValue = initialFocusRef.current;\n const elToFocus = (typeof initialFocusValue === 'number' ? focusableElements[initialFocusValue] : initialFocusValue.current) || floatingFocusElement;\n const focusAlreadyInsideFloatingEl = (0,_floating_ui_react_utils__rspack_import_6.contains)(floatingFocusElement, previouslyFocusedElement);\n if (!ignoreInitialFocus && !focusAlreadyInsideFloatingEl && open) {\n enqueueFocus(elToFocus, {\n preventScroll: elToFocus === floatingFocusElement\n });\n }\n });\n }, [disabled, open, floatingFocusElement, ignoreInitialFocus, getTabbableElements, initialFocusRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled || !floatingFocusElement) return;\n let preventReturnFocusScroll = false;\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(floatingFocusElement);\n const previouslyFocusedElement = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(doc);\n addPreviouslyFocusedElement(previouslyFocusedElement);\n\n // Dismissing via outside press should always ignore `returnFocus` to\n // prevent unwanted scrolling.\n function onOpenChange(_ref) {\n let {\n reason,\n event,\n nested\n } = _ref;\n if (['hover', 'safe-polygon'].includes(reason) && event.type === 'mouseleave') {\n preventReturnFocusRef.current = true;\n }\n if (reason !== 'outside-press') return;\n if (nested) {\n preventReturnFocusRef.current = false;\n preventReturnFocusScroll = true;\n } else if ((0,_floating_ui_react_utils__rspack_import_6.isVirtualClick)(event) || (0,_floating_ui_react_utils__rspack_import_6.isVirtualPointerEvent)(event)) {\n preventReturnFocusRef.current = false;\n } else {\n let isPreventScrollSupported = false;\n document.createElement('div').focus({\n get preventScroll() {\n isPreventScrollSupported = true;\n return false;\n }\n });\n if (isPreventScrollSupported) {\n preventReturnFocusRef.current = false;\n preventReturnFocusScroll = true;\n } else {\n preventReturnFocusRef.current = true;\n }\n }\n }\n events.on('openchange', onOpenChange);\n const fallbackEl = doc.createElement('span');\n fallbackEl.setAttribute('tabindex', '-1');\n fallbackEl.setAttribute('aria-hidden', 'true');\n Object.assign(fallbackEl.style, HIDDEN_STYLES);\n if (isInsidePortal && domReference) {\n domReference.insertAdjacentElement('afterend', fallbackEl);\n }\n function getReturnElement() {\n if (typeof returnFocusRef.current === 'boolean') {\n const el = domReference || getPreviouslyFocusedElement();\n return el && el.isConnected ? el : fallbackEl;\n }\n return returnFocusRef.current.current || fallbackEl;\n }\n return () => {\n events.off('openchange', onOpenChange);\n const activeEl = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(doc);\n const isFocusInsideFloatingTree = (0,_floating_ui_react_utils__rspack_import_6.contains)(floating, activeEl) || tree && (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, getNodeId()).some(node => {\n var _node$context8;\n return (0,_floating_ui_react_utils__rspack_import_6.contains)((_node$context8 = node.context) == null ? void 0 : _node$context8.elements.floating, activeEl);\n });\n const returnElement = getReturnElement();\n queueMicrotask(() => {\n // This is `returnElement`, if it's tabbable, or its first tabbable child.\n const tabbableReturnElement = getFirstTabbableElement(returnElement);\n if (\n // eslint-disable-next-line react-hooks/exhaustive-deps\n returnFocusRef.current && !preventReturnFocusRef.current && (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(tabbableReturnElement) && (\n // If the focus moved somewhere else after mount, avoid returning focus\n // since it likely entered a different element which should be\n // respected: https://github.com/floating-ui/floating-ui/issues/2607\n tabbableReturnElement !== activeEl && activeEl !== doc.body ? isFocusInsideFloatingTree : true)) {\n tabbableReturnElement.focus({\n preventScroll: preventReturnFocusScroll\n });\n }\n fallbackEl.remove();\n });\n };\n }, [disabled, floating, floatingFocusElement, returnFocusRef, dataRef, events, tree, isInsidePortal, domReference, getNodeId]);\n react__rspack_import_0.useEffect(() => {\n // The `returnFocus` cleanup behavior is inside a microtask; ensure we\n // wait for it to complete before resetting the flag.\n queueMicrotask(() => {\n preventReturnFocusRef.current = false;\n });\n }, [disabled]);\n\n // Synchronize the `context` & `modal` value to the FloatingPortal context.\n // It will decide whether or not it needs to render its own guards.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled) return;\n if (!portalContext) return;\n portalContext.setFocusManagerState({\n modal,\n closeOnFocusOut,\n open,\n onOpenChange,\n domReference\n });\n return () => {\n portalContext.setFocusManagerState(null);\n };\n }, [disabled, portalContext, modal, open, onOpenChange, closeOnFocusOut, domReference]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (disabled) return;\n if (!floatingFocusElement) return;\n handleTabIndex(floatingFocusElement, orderRef);\n }, [disabled, floatingFocusElement, orderRef]);\n function renderDismissButton(location) {\n if (disabled || !visuallyHiddenDismiss || !modal) {\n return null;\n }\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(VisuallyHiddenDismiss, {\n ref: location === 'start' ? startDismissButtonRef : endDismissButtonRef,\n onClick: event => onOpenChange(false, event.nativeEvent),\n children: typeof visuallyHiddenDismiss === 'string' ? visuallyHiddenDismiss : 'Dismiss'\n });\n }\n const shouldRenderGuards = !disabled && guards && (modal ? !isUntrappedTypeableCombobox : true) && (isInsidePortal || modal);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsxs)(react_jsx_runtime__rspack_import_1.Fragment, {\n children: [shouldRenderGuards && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"inside\",\n ref: mergedBeforeGuardRef,\n onFocus: event => {\n if (modal) {\n const els = getTabbableElements();\n enqueueFocus(order[0] === 'reference' ? els[0] : els[els.length - 1]);\n } else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {\n preventReturnFocusRef.current = false;\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalContext.portalNode)) {\n const nextTabbable = (0,_floating_ui_react_utils__rspack_import_6.getNextTabbable)(domReference);\n nextTabbable == null || nextTabbable.focus();\n } else {\n var _portalContext$before;\n (_portalContext$before = portalContext.beforeOutsideRef.current) == null || _portalContext$before.focus();\n }\n }\n }\n }), !isUntrappedTypeableCombobox && renderDismissButton('start'), children, renderDismissButton('end'), shouldRenderGuards && /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(FocusGuard, {\n \"data-type\": \"inside\",\n ref: mergedAfterGuardRef,\n onFocus: event => {\n if (modal) {\n enqueueFocus(getTabbableElements()[0]);\n } else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {\n if (closeOnFocusOut) {\n preventReturnFocusRef.current = true;\n }\n if ((0,_floating_ui_react_utils__rspack_import_6.isOutsideEvent)(event, portalContext.portalNode)) {\n const prevTabbable = (0,_floating_ui_react_utils__rspack_import_6.getPreviousTabbable)(domReference);\n prevTabbable == null || prevTabbable.focus();\n } else {\n var _portalContext$afterO;\n (_portalContext$afterO = portalContext.afterOutsideRef.current) == null || _portalContext$afterO.focus();\n }\n }\n }\n })]\n });\n}\n\nlet lockCount = 0;\nfunction enableScrollLock() {\n const isIOS = /iP(hone|ad|od)|iOS/.test((0,_floating_ui_react_utils__rspack_import_6.getPlatform)());\n const bodyStyle = document.body.style;\n // RTL <body> scrollbar\n const scrollbarX = Math.round(document.documentElement.getBoundingClientRect().left) + document.documentElement.scrollLeft;\n const paddingProp = scrollbarX ? 'paddingLeft' : 'paddingRight';\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n const scrollX = bodyStyle.left ? parseFloat(bodyStyle.left) : window.scrollX;\n const scrollY = bodyStyle.top ? parseFloat(bodyStyle.top) : window.scrollY;\n bodyStyle.overflow = 'hidden';\n if (scrollbarWidth) {\n bodyStyle[paddingProp] = scrollbarWidth + \"px\";\n }\n\n // Only iOS doesn't respect `overflow: hidden` on document.body, and this\n // technique has fewer side effects.\n if (isIOS) {\n var _window$visualViewpor, _window$visualViewpor2;\n // iOS 12 does not support `visualViewport`.\n const offsetLeft = ((_window$visualViewpor = window.visualViewport) == null ? void 0 : _window$visualViewpor.offsetLeft) || 0;\n const offsetTop = ((_window$visualViewpor2 = window.visualViewport) == null ? void 0 : _window$visualViewpor2.offsetTop) || 0;\n Object.assign(bodyStyle, {\n position: 'fixed',\n top: -(scrollY - Math.floor(offsetTop)) + \"px\",\n left: -(scrollX - Math.floor(offsetLeft)) + \"px\",\n right: '0'\n });\n }\n return () => {\n Object.assign(bodyStyle, {\n overflow: '',\n [paddingProp]: ''\n });\n if (isIOS) {\n Object.assign(bodyStyle, {\n position: '',\n top: '',\n left: '',\n right: ''\n });\n window.scrollTo(scrollX, scrollY);\n }\n };\n}\nlet cleanup = () => {};\n\n/**\n * Provides base styling for a fixed overlay element to dim content or block\n * pointer events behind a floating element.\n * It's a regular `<div>`, so it can be styled via any CSS solution you prefer.\n * @see https://floating-ui.com/docs/FloatingOverlay\n */\nconst FloatingOverlay = /*#__PURE__*/react__rspack_import_0.forwardRef(function FloatingOverlay(props, ref) {\n const {\n lockScroll = false,\n ...rest\n } = props;\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!lockScroll) return;\n lockCount++;\n if (lockCount === 1) {\n cleanup = enableScrollLock();\n }\n return () => {\n lockCount--;\n if (lockCount === 0) {\n cleanup();\n }\n };\n }, [lockScroll]);\n return /*#__PURE__*/(0,react_jsx_runtime__rspack_import_1.jsx)(\"div\", {\n ref: ref,\n ...rest,\n style: {\n position: 'fixed',\n overflow: 'auto',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...rest.style\n }\n });\n});\n\nfunction isButtonTarget(event) {\n return (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(event.target) && event.target.tagName === 'BUTTON';\n}\nfunction isAnchorTarget(event) {\n return (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(event.target) && event.target.tagName === 'A';\n}\nfunction isSpaceIgnored(element) {\n return (0,_floating_ui_react_utils__rspack_import_6.isTypeableElement)(element);\n}\n/**\n * Opens or closes the floating element when clicking the reference element.\n * @see https://floating-ui.com/docs/useClick\n */\nfunction useClick(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n dataRef,\n elements: {\n domReference\n }\n } = context;\n const {\n enabled = true,\n event: eventOption = 'click',\n toggle = true,\n ignoreMouse = false,\n keyboardHandlers = true,\n stickIfOpen = true\n } = props;\n const pointerTypeRef = react__rspack_import_0.useRef();\n const didKeyDownRef = react__rspack_import_0.useRef(false);\n const reference = react__rspack_import_0.useMemo(() => ({\n onPointerDown(event) {\n pointerTypeRef.current = event.pointerType;\n },\n onMouseDown(event) {\n const pointerType = pointerTypeRef.current;\n\n // Ignore all buttons except for the \"main\" button.\n // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\n if (event.button !== 0) return;\n if (eventOption === 'click') return;\n if ((0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;\n if (open && toggle && (dataRef.current.openEvent && stickIfOpen ? dataRef.current.openEvent.type === 'mousedown' : true)) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n // Prevent stealing focus from the floating element\n event.preventDefault();\n onOpenChange(true, event.nativeEvent, 'click');\n }\n },\n onClick(event) {\n const pointerType = pointerTypeRef.current;\n if (eventOption === 'mousedown' && pointerTypeRef.current) {\n pointerTypeRef.current = undefined;\n return;\n }\n if ((0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;\n if (open && toggle && (dataRef.current.openEvent && stickIfOpen ? dataRef.current.openEvent.type === 'click' : true)) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n },\n onKeyDown(event) {\n pointerTypeRef.current = undefined;\n if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event)) {\n return;\n }\n if (event.key === ' ' && !isSpaceIgnored(domReference)) {\n // Prevent scrolling\n event.preventDefault();\n didKeyDownRef.current = true;\n }\n if (isAnchorTarget(event)) {\n return;\n }\n if (event.key === 'Enter') {\n if (open && toggle) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n }\n },\n onKeyUp(event) {\n if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event) || isSpaceIgnored(domReference)) {\n return;\n }\n if (event.key === ' ' && didKeyDownRef.current) {\n didKeyDownRef.current = false;\n if (open && toggle) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n }\n }\n }), [dataRef, domReference, eventOption, ignoreMouse, keyboardHandlers, onOpenChange, open, stickIfOpen, toggle]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nfunction createVirtualElement(domElement, data) {\n let offsetX = null;\n let offsetY = null;\n let isAutoUpdateEvent = false;\n return {\n contextElement: domElement || undefined,\n getBoundingClientRect() {\n var _data$dataRef$current;\n const domRect = (domElement == null ? void 0 : domElement.getBoundingClientRect()) || {\n width: 0,\n height: 0,\n x: 0,\n y: 0\n };\n const isXAxis = data.axis === 'x' || data.axis === 'both';\n const isYAxis = data.axis === 'y' || data.axis === 'both';\n const canTrackCursorOnAutoUpdate = ['mouseenter', 'mousemove'].includes(((_data$dataRef$current = data.dataRef.current.openEvent) == null ? void 0 : _data$dataRef$current.type) || '') && data.pointerType !== 'touch';\n let width = domRect.width;\n let height = domRect.height;\n let x = domRect.x;\n let y = domRect.y;\n if (offsetX == null && data.x && isXAxis) {\n offsetX = domRect.x - data.x;\n }\n if (offsetY == null && data.y && isYAxis) {\n offsetY = domRect.y - data.y;\n }\n x -= offsetX || 0;\n y -= offsetY || 0;\n width = 0;\n height = 0;\n if (!isAutoUpdateEvent || canTrackCursorOnAutoUpdate) {\n width = data.axis === 'y' ? domRect.width : 0;\n height = data.axis === 'x' ? domRect.height : 0;\n x = isXAxis && data.x != null ? data.x : x;\n y = isYAxis && data.y != null ? data.y : y;\n } else if (isAutoUpdateEvent && !canTrackCursorOnAutoUpdate) {\n height = data.axis === 'x' ? domRect.height : height;\n width = data.axis === 'y' ? domRect.width : width;\n }\n isAutoUpdateEvent = true;\n return {\n width,\n height,\n x,\n y,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x\n };\n }\n };\n}\nfunction isMouseBasedEvent(event) {\n return event != null && event.clientX != null;\n}\n/**\n * Positions the floating element relative to a client point (in the viewport),\n * such as the mouse position. By default, it follows the mouse cursor.\n * @see https://floating-ui.com/docs/useClientPoint\n */\nfunction useClientPoint(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n dataRef,\n elements: {\n floating,\n domReference\n },\n refs\n } = context;\n const {\n enabled = true,\n axis = 'both',\n x = null,\n y = null\n } = props;\n const initialRef = react__rspack_import_0.useRef(false);\n const cleanupListenerRef = react__rspack_import_0.useRef(null);\n const [pointerType, setPointerType] = react__rspack_import_0.useState();\n const [reactive, setReactive] = react__rspack_import_0.useState([]);\n const setReference = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)((x, y) => {\n if (initialRef.current) return;\n\n // Prevent setting if the open event was not a mouse-like one\n // (e.g. focus to open, then hover over the reference element).\n // Only apply if the event exists.\n if (dataRef.current.openEvent && !isMouseBasedEvent(dataRef.current.openEvent)) {\n return;\n }\n refs.setPositionReference(createVirtualElement(domReference, {\n x,\n y,\n axis,\n dataRef,\n pointerType\n }));\n });\n const handleReferenceEnterOrMove = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n if (x != null || y != null) return;\n if (!open) {\n setReference(event.clientX, event.clientY);\n } else if (!cleanupListenerRef.current) {\n // If there's no cleanup, there's no listener, but we want to ensure\n // we add the listener if the cursor landed on the floating element and\n // then back on the reference (i.e. it's interactive).\n setReactive([]);\n }\n });\n\n // If the pointer is a mouse-like pointer, we want to continue following the\n // mouse even if the floating element is transitioning out. On touch\n // devices, this is undesirable because the floating element will move to\n // the dismissal touch point.\n const openCheck = (0,_floating_ui_react_utils__rspack_import_6.isMouseLikePointerType)(pointerType) ? floating : open;\n const addListener = react__rspack_import_0.useCallback(() => {\n // Explicitly specified `x`/`y` coordinates shouldn't add a listener.\n if (!openCheck || !enabled || x != null || y != null) return;\n const win = (0,_floating_ui_react_dom__rspack_import_5.getWindow)(floating);\n function handleMouseMove(event) {\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n if (!(0,_floating_ui_react_utils__rspack_import_6.contains)(floating, target)) {\n setReference(event.clientX, event.clientY);\n } else {\n win.removeEventListener('mousemove', handleMouseMove);\n cleanupListenerRef.current = null;\n }\n }\n if (!dataRef.current.openEvent || isMouseBasedEvent(dataRef.current.openEvent)) {\n win.addEventListener('mousemove', handleMouseMove);\n const cleanup = () => {\n win.removeEventListener('mousemove', handleMouseMove);\n cleanupListenerRef.current = null;\n };\n cleanupListenerRef.current = cleanup;\n return cleanup;\n }\n refs.setPositionReference(domReference);\n }, [openCheck, enabled, x, y, floating, dataRef, refs, domReference, setReference]);\n react__rspack_import_0.useEffect(() => {\n return addListener();\n }, [addListener, reactive]);\n react__rspack_import_0.useEffect(() => {\n if (enabled && !floating) {\n initialRef.current = false;\n }\n }, [enabled, floating]);\n react__rspack_import_0.useEffect(() => {\n if (!enabled && open) {\n initialRef.current = true;\n }\n }, [enabled, open]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (enabled && (x != null || y != null)) {\n initialRef.current = false;\n setReference(x, y);\n }\n }, [enabled, x, y, setReference]);\n const reference = react__rspack_import_0.useMemo(() => {\n function setPointerTypeRef(_ref) {\n let {\n pointerType\n } = _ref;\n setPointerType(pointerType);\n }\n return {\n onPointerDown: setPointerTypeRef,\n onPointerEnter: setPointerTypeRef,\n onMouseMove: handleReferenceEnterOrMove,\n onMouseEnter: handleReferenceEnterOrMove\n };\n }, [handleReferenceEnterOrMove]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nconst bubbleHandlerKeys = {\n pointerdown: 'onPointerDown',\n mousedown: 'onMouseDown',\n click: 'onClick'\n};\nconst captureHandlerKeys = {\n pointerdown: 'onPointerDownCapture',\n mousedown: 'onMouseDownCapture',\n click: 'onClickCapture'\n};\nconst normalizeProp = normalizable => {\n var _normalizable$escapeK, _normalizable$outside;\n return {\n escapeKey: typeof normalizable === 'boolean' ? normalizable : (_normalizable$escapeK = normalizable == null ? void 0 : normalizable.escapeKey) != null ? _normalizable$escapeK : false,\n outsidePress: typeof normalizable === 'boolean' ? normalizable : (_normalizable$outside = normalizable == null ? void 0 : normalizable.outsidePress) != null ? _normalizable$outside : true\n };\n};\n/**\n * Closes the floating element when a dismissal is requested — by default, when\n * the user presses the `escape` key or outside of the floating element.\n * @see https://floating-ui.com/docs/useDismiss\n */\nfunction useDismiss(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n elements,\n dataRef\n } = context;\n const {\n enabled = true,\n escapeKey = true,\n outsidePress: unstable_outsidePress = true,\n outsidePressEvent = 'pointerdown',\n referencePress = false,\n referencePressEvent = 'pointerdown',\n ancestorScroll = false,\n bubbles,\n capture\n } = props;\n const tree = useFloatingTree();\n const outsidePressFn = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(typeof unstable_outsidePress === 'function' ? unstable_outsidePress : () => false);\n const outsidePress = typeof unstable_outsidePress === 'function' ? outsidePressFn : unstable_outsidePress;\n const insideReactTreeRef = react__rspack_import_0.useRef(false);\n const endedOrStartedInsideRef = react__rspack_import_0.useRef(false);\n const {\n escapeKey: escapeKeyBubbles,\n outsidePress: outsidePressBubbles\n } = normalizeProp(bubbles);\n const {\n escapeKey: escapeKeyCapture,\n outsidePress: outsidePressCapture\n } = normalizeProp(capture);\n const isComposingRef = react__rspack_import_0.useRef(false);\n const closeOnEscapeKeyDown = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _dataRef$current$floa;\n if (!open || !enabled || !escapeKey || event.key !== 'Escape') {\n return;\n }\n\n // Wait until IME is settled. Pressing `Escape` while composing should\n // close the compose menu, but not the floating element.\n if (isComposingRef.current) {\n return;\n }\n const nodeId = (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;\n const children = tree ? (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId) : [];\n if (!escapeKeyBubbles) {\n event.stopPropagation();\n if (children.length > 0) {\n let shouldDismiss = true;\n children.forEach(child => {\n var _child$context;\n if ((_child$context = child.context) != null && _child$context.open && !child.context.dataRef.current.__escapeKeyBubbles) {\n shouldDismiss = false;\n return;\n }\n });\n if (!shouldDismiss) {\n return;\n }\n }\n }\n onOpenChange(false, (0,_floating_ui_react_utils__rspack_import_6.isReactEvent)(event) ? event.nativeEvent : event, 'escape-key');\n });\n const closeOnEscapeKeyDownCapture = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _getTarget2;\n const callback = () => {\n var _getTarget;\n closeOnEscapeKeyDown(event);\n (_getTarget = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget.removeEventListener('keydown', callback);\n };\n (_getTarget2 = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget2.addEventListener('keydown', callback);\n });\n const closeOnPressOutside = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _dataRef$current$floa2;\n // Given developers can stop the propagation of the synthetic event,\n // we can only be confident with a positive value.\n const insideReactTree = insideReactTreeRef.current;\n insideReactTreeRef.current = false;\n\n // When click outside is lazy (`click` event), handle dragging.\n // Don't close if:\n // - The click started inside the floating element.\n // - The click ended inside the floating element.\n const endedOrStartedInside = endedOrStartedInsideRef.current;\n endedOrStartedInsideRef.current = false;\n if (outsidePressEvent === 'click' && endedOrStartedInside) {\n return;\n }\n if (insideReactTree) {\n return;\n }\n if (typeof outsidePress === 'function' && !outsidePress(event)) {\n return;\n }\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event);\n const inertSelector = \"[\" + createAttribute('inert') + \"]\";\n const markers = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating).querySelectorAll(inertSelector);\n let targetRootAncestor = (0,_floating_ui_react_dom__rspack_import_5.isElement)(target) ? target : null;\n while (targetRootAncestor && !(0,_floating_ui_react_dom__rspack_import_5.isLastTraversableNode)(targetRootAncestor)) {\n const nextParent = (0,_floating_ui_react_dom__rspack_import_5.getParentNode)(targetRootAncestor);\n if ((0,_floating_ui_react_dom__rspack_import_5.isLastTraversableNode)(nextParent) || !(0,_floating_ui_react_dom__rspack_import_5.isElement)(nextParent)) {\n break;\n }\n targetRootAncestor = nextParent;\n }\n\n // Check if the click occurred on a third-party element injected after the\n // floating element rendered.\n if (markers.length && (0,_floating_ui_react_dom__rspack_import_5.isElement)(target) && !(0,_floating_ui_react_utils__rspack_import_6.isRootElement)(target) &&\n // Clicked on a direct ancestor (e.g. FloatingOverlay).\n !(0,_floating_ui_react_utils__rspack_import_6.contains)(target, elements.floating) &&\n // If the target root element contains none of the markers, then the\n // element was injected after the floating element rendered.\n Array.from(markers).every(marker => !(0,_floating_ui_react_utils__rspack_import_6.contains)(targetRootAncestor, marker))) {\n return;\n }\n\n // Check if the click occurred on the scrollbar\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(target) && floating) {\n const lastTraversableNode = (0,_floating_ui_react_dom__rspack_import_5.isLastTraversableNode)(target);\n const style = (0,_floating_ui_react_dom__rspack_import_5.getComputedStyle)(target);\n const scrollRe = /auto|scroll/;\n const isScrollableX = lastTraversableNode || scrollRe.test(style.overflowX);\n const isScrollableY = lastTraversableNode || scrollRe.test(style.overflowY);\n const canScrollX = isScrollableX && target.clientWidth > 0 && target.scrollWidth > target.clientWidth;\n const canScrollY = isScrollableY && target.clientHeight > 0 && target.scrollHeight > target.clientHeight;\n const isRTL = style.direction === 'rtl';\n\n // Check click position relative to scrollbar.\n // In some browsers it is possible to change the <body> (or window)\n // scrollbar to the left side, but is very rare and is difficult to\n // check for. Plus, for modal dialogs with backdrops, it is more\n // important that the backdrop is checked but not so much the window.\n const pressedVerticalScrollbar = canScrollY && (isRTL ? event.offsetX <= target.offsetWidth - target.clientWidth : event.offsetX > target.clientWidth);\n const pressedHorizontalScrollbar = canScrollX && event.offsetY > target.clientHeight;\n if (pressedVerticalScrollbar || pressedHorizontalScrollbar) {\n return;\n }\n }\n const nodeId = (_dataRef$current$floa2 = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa2.nodeId;\n const targetIsInsideChildren = tree && (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId).some(node => {\n var _node$context;\n return (0,_floating_ui_react_utils__rspack_import_6.isEventTargetWithin)(event, (_node$context = node.context) == null ? void 0 : _node$context.elements.floating);\n });\n if ((0,_floating_ui_react_utils__rspack_import_6.isEventTargetWithin)(event, elements.floating) || (0,_floating_ui_react_utils__rspack_import_6.isEventTargetWithin)(event, elements.domReference) || targetIsInsideChildren) {\n return;\n }\n const children = tree ? (0,_floating_ui_react_utils__rspack_import_6.getNodeChildren)(tree.nodesRef.current, nodeId) : [];\n if (children.length > 0) {\n let shouldDismiss = true;\n children.forEach(child => {\n var _child$context2;\n if ((_child$context2 = child.context) != null && _child$context2.open && !child.context.dataRef.current.__outsidePressBubbles) {\n shouldDismiss = false;\n return;\n }\n });\n if (!shouldDismiss) {\n return;\n }\n }\n onOpenChange(false, event, 'outside-press');\n });\n const closeOnPressOutsideCapture = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n var _getTarget4;\n const callback = () => {\n var _getTarget3;\n closeOnPressOutside(event);\n (_getTarget3 = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget3.removeEventListener(outsidePressEvent, callback);\n };\n (_getTarget4 = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event)) == null || _getTarget4.addEventListener(outsidePressEvent, callback);\n });\n react__rspack_import_0.useEffect(() => {\n if (!open || !enabled) {\n return;\n }\n dataRef.current.__escapeKeyBubbles = escapeKeyBubbles;\n dataRef.current.__outsidePressBubbles = outsidePressBubbles;\n let compositionTimeout = -1;\n function onScroll(event) {\n onOpenChange(false, event, 'ancestor-scroll');\n }\n function handleCompositionStart() {\n window.clearTimeout(compositionTimeout);\n isComposingRef.current = true;\n }\n function handleCompositionEnd() {\n // Safari fires `compositionend` before `keydown`, so we need to wait\n // until the next tick to set `isComposing` to `false`.\n // https://bugs.webkit.org/show_bug.cgi?id=165004\n compositionTimeout = window.setTimeout(() => {\n isComposingRef.current = false;\n },\n // 0ms or 1ms don't work in Safari. 5ms appears to consistently work.\n // Only apply to WebKit for the test to remain 0ms.\n (0,_floating_ui_react_dom__rspack_import_5.isWebKit)() ? 5 : 0);\n }\n const doc = (0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating);\n if (escapeKey) {\n doc.addEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);\n doc.addEventListener('compositionstart', handleCompositionStart);\n doc.addEventListener('compositionend', handleCompositionEnd);\n }\n outsidePress && doc.addEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);\n let ancestors = [];\n if (ancestorScroll) {\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.domReference)) {\n ancestors = (0,_floating_ui_react_dom__rspack_import_5.getOverflowAncestors)(elements.domReference);\n }\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.floating)) {\n ancestors = ancestors.concat((0,_floating_ui_react_dom__rspack_import_5.getOverflowAncestors)(elements.floating));\n }\n if (!(0,_floating_ui_react_dom__rspack_import_5.isElement)(elements.reference) && elements.reference && elements.reference.contextElement) {\n ancestors = ancestors.concat((0,_floating_ui_react_dom__rspack_import_5.getOverflowAncestors)(elements.reference.contextElement));\n }\n }\n\n // Ignore the visual viewport for scrolling dismissal (allow pinch-zoom)\n ancestors = ancestors.filter(ancestor => {\n var _doc$defaultView;\n return ancestor !== ((_doc$defaultView = doc.defaultView) == null ? void 0 : _doc$defaultView.visualViewport);\n });\n ancestors.forEach(ancestor => {\n ancestor.addEventListener('scroll', onScroll, {\n passive: true\n });\n });\n return () => {\n if (escapeKey) {\n doc.removeEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);\n doc.removeEventListener('compositionstart', handleCompositionStart);\n doc.removeEventListener('compositionend', handleCompositionEnd);\n }\n outsidePress && doc.removeEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);\n ancestors.forEach(ancestor => {\n ancestor.removeEventListener('scroll', onScroll);\n });\n window.clearTimeout(compositionTimeout);\n };\n }, [dataRef, elements, escapeKey, outsidePress, outsidePressEvent, open, onOpenChange, ancestorScroll, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, escapeKeyCapture, closeOnEscapeKeyDownCapture, closeOnPressOutside, outsidePressCapture, closeOnPressOutsideCapture]);\n react__rspack_import_0.useEffect(() => {\n insideReactTreeRef.current = false;\n }, [outsidePress, outsidePressEvent]);\n const reference = react__rspack_import_0.useMemo(() => ({\n onKeyDown: closeOnEscapeKeyDown,\n ...(referencePress && {\n [bubbleHandlerKeys[referencePressEvent]]: event => {\n onOpenChange(false, event.nativeEvent, 'reference-press');\n },\n ...(referencePressEvent !== 'click' && {\n onClick(event) {\n onOpenChange(false, event.nativeEvent, 'reference-press');\n }\n })\n })\n }), [closeOnEscapeKeyDown, onOpenChange, referencePress, referencePressEvent]);\n const floating = react__rspack_import_0.useMemo(() => ({\n onKeyDown: closeOnEscapeKeyDown,\n onMouseDown() {\n endedOrStartedInsideRef.current = true;\n },\n onMouseUp() {\n endedOrStartedInsideRef.current = true;\n },\n [captureHandlerKeys[outsidePressEvent]]: () => {\n insideReactTreeRef.current = true;\n }\n }), [closeOnEscapeKeyDown, outsidePressEvent]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nfunction useFloatingRootContext(options) {\n const {\n open = false,\n onOpenChange: onOpenChangeProp,\n elements: elementsProp\n } = options;\n const floatingId = useId();\n const dataRef = react__rspack_import_0.useRef({});\n const [events] = react__rspack_import_0.useState(() => createEventEmitter());\n const nested = useFloatingParentNodeId() != null;\n if (true) {\n const optionDomReference = elementsProp.reference;\n if (optionDomReference && !(0,_floating_ui_react_dom__rspack_import_5.isElement)(optionDomReference)) {\n error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `refs.setPositionReference()`', 'instead.');\n }\n }\n const [positionReference, setPositionReference] = react__rspack_import_0.useState(elementsProp.reference);\n const onOpenChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)((open, event, reason) => {\n dataRef.current.openEvent = open ? event : undefined;\n events.emit('openchange', {\n open,\n event,\n reason,\n nested\n });\n onOpenChangeProp == null || onOpenChangeProp(open, event, reason);\n });\n const refs = react__rspack_import_0.useMemo(() => ({\n setPositionReference\n }), []);\n const elements = react__rspack_import_0.useMemo(() => ({\n reference: positionReference || elementsProp.reference || null,\n floating: elementsProp.floating || null,\n domReference: elementsProp.reference\n }), [positionReference, elementsProp.reference, elementsProp.floating]);\n return react__rspack_import_0.useMemo(() => ({\n dataRef,\n open,\n onOpenChange,\n elements,\n events,\n floatingId,\n refs\n }), [open, onOpenChange, elements, events, floatingId, refs]);\n}\n\n/**\n * Provides data to position a floating element and context to add interactions.\n * @see https://floating-ui.com/docs/useFloating\n */\nfunction useFloating(options) {\n if (options === void 0) {\n options = {};\n }\n const {\n nodeId\n } = options;\n const internalRootContext = useFloatingRootContext({\n ...options,\n elements: {\n reference: null,\n floating: null,\n ...options.elements\n }\n });\n const rootContext = options.rootContext || internalRootContext;\n const computedElements = rootContext.elements;\n const [_domReference, setDomReference] = react__rspack_import_0.useState(null);\n const [positionReference, _setPositionReference] = react__rspack_import_0.useState(null);\n const optionDomReference = computedElements == null ? void 0 : computedElements.domReference;\n const domReference = optionDomReference || _domReference;\n const domReferenceRef = react__rspack_import_0.useRef(null);\n const tree = useFloatingTree();\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (domReference) {\n domReferenceRef.current = domReference;\n }\n }, [domReference]);\n const position = (0,_floating_ui_react_dom__rspack_import_3.useFloating)({\n ...options,\n elements: {\n ...computedElements,\n ...(positionReference && {\n reference: positionReference\n })\n }\n });\n const setPositionReference = react__rspack_import_0.useCallback(node => {\n const computedPositionReference = (0,_floating_ui_react_dom__rspack_import_5.isElement)(node) ? {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n getClientRects: () => node.getClientRects(),\n contextElement: node\n } : node;\n // Store the positionReference in state if the DOM reference is specified externally via the\n // `elements.reference` option. This ensures that it won't be overridden on future renders.\n _setPositionReference(computedPositionReference);\n position.refs.setReference(computedPositionReference);\n }, [position.refs]);\n const setReference = react__rspack_import_0.useCallback(node => {\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(node) || node === null) {\n domReferenceRef.current = node;\n setDomReference(node);\n }\n\n // Backwards-compatibility for passing a virtual element to `reference`\n // after it has set the DOM reference.\n if ((0,_floating_ui_react_dom__rspack_import_5.isElement)(position.refs.reference.current) || position.refs.reference.current === null ||\n // Don't allow setting virtual elements using the old technique back to\n // `null` to support `positionReference` + an unstable `reference`\n // callback ref.\n node !== null && !(0,_floating_ui_react_dom__rspack_import_5.isElement)(node)) {\n position.refs.setReference(node);\n }\n }, [position.refs]);\n const refs = react__rspack_import_0.useMemo(() => ({\n ...position.refs,\n setReference,\n setPositionReference,\n domReference: domReferenceRef\n }), [position.refs, setReference, setPositionReference]);\n const elements = react__rspack_import_0.useMemo(() => ({\n ...position.elements,\n domReference: domReference\n }), [position.elements, domReference]);\n const context = react__rspack_import_0.useMemo(() => ({\n ...position,\n ...rootContext,\n refs,\n elements,\n nodeId\n }), [position, refs, elements, nodeId, rootContext]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n rootContext.dataRef.current.floatingContext = context;\n const node = tree == null ? void 0 : tree.nodesRef.current.find(node => node.id === nodeId);\n if (node) {\n node.context = context;\n }\n });\n return react__rspack_import_0.useMemo(() => ({\n ...position,\n context,\n refs,\n elements\n }), [position, refs, elements, context]);\n}\n\nfunction isMacSafari() {\n return (0,_floating_ui_react_utils__rspack_import_6.isMac)() && (0,_floating_ui_react_utils__rspack_import_6.isSafari)();\n}\n/**\n * Opens the floating element while the reference element has focus, like CSS\n * `:focus`.\n * @see https://floating-ui.com/docs/useFocus\n */\nfunction useFocus(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n events,\n dataRef,\n elements\n } = context;\n const {\n enabled = true,\n visibleOnly = true\n } = props;\n const blockFocusRef = react__rspack_import_0.useRef(false);\n const timeoutRef = react__rspack_import_0.useRef(-1);\n const keyboardModalityRef = react__rspack_import_0.useRef(true);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n const win = (0,_floating_ui_react_dom__rspack_import_5.getWindow)(elements.domReference);\n\n // If the reference was focused and the user left the tab/window, and the\n // floating element was not open, the focus should be blocked when they\n // return to the tab/window.\n function onBlur() {\n if (!open && (0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(elements.domReference) && elements.domReference === (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.domReference))) {\n blockFocusRef.current = true;\n }\n }\n function onKeyDown() {\n keyboardModalityRef.current = true;\n }\n function onPointerDown() {\n keyboardModalityRef.current = false;\n }\n win.addEventListener('blur', onBlur);\n if (isMacSafari()) {\n win.addEventListener('keydown', onKeyDown, true);\n win.addEventListener('pointerdown', onPointerDown, true);\n }\n return () => {\n win.removeEventListener('blur', onBlur);\n if (isMacSafari()) {\n win.removeEventListener('keydown', onKeyDown, true);\n win.removeEventListener('pointerdown', onPointerDown, true);\n }\n };\n }, [elements.domReference, open, enabled]);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onOpenChange(_ref) {\n let {\n reason\n } = _ref;\n if (reason === 'reference-press' || reason === 'escape-key') {\n blockFocusRef.current = true;\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n };\n }, [events, enabled]);\n react__rspack_import_0.useEffect(() => {\n return () => {\n clearTimeoutIfSet(timeoutRef);\n };\n }, []);\n const reference = react__rspack_import_0.useMemo(() => ({\n onMouseLeave() {\n blockFocusRef.current = false;\n },\n onFocus(event) {\n if (blockFocusRef.current) return;\n const target = (0,_floating_ui_react_utils__rspack_import_6.getTarget)(event.nativeEvent);\n if (visibleOnly && (0,_floating_ui_react_dom__rspack_import_5.isElement)(target)) {\n // Safari fails to match `:focus-visible` if focus was initially\n // outside the document.\n if (isMacSafari() && !event.relatedTarget) {\n if (!keyboardModalityRef.current && !(0,_floating_ui_react_utils__rspack_import_6.isTypeableElement)(target)) {\n return;\n }\n } else if (!(0,_floating_ui_react_utils__rspack_import_6.matchesFocusVisible)(target)) {\n return;\n }\n }\n onOpenChange(true, event.nativeEvent, 'focus');\n },\n onBlur(event) {\n blockFocusRef.current = false;\n const relatedTarget = event.relatedTarget;\n const nativeEvent = event.nativeEvent;\n\n // Hit the non-modal focus management portal guard. Focus will be\n // moved into the floating element immediately after.\n const movedToFocusGuard = (0,_floating_ui_react_dom__rspack_import_5.isElement)(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';\n\n // Wait for the window blur listener to fire.\n timeoutRef.current = window.setTimeout(() => {\n var _dataRef$current$floa;\n const activeEl = (0,_floating_ui_react_utils__rspack_import_6.activeElement)(elements.domReference ? elements.domReference.ownerDocument : document);\n\n // Focus left the page, keep it open.\n if (!relatedTarget && activeEl === elements.domReference) return;\n\n // When focusing the reference element (e.g. regular click), then\n // clicking into the floating element, prevent it from hiding.\n // Note: it must be focusable, e.g. `tabindex=\"-1\"`.\n // We can not rely on relatedTarget to point to the correct element\n // as it will only point to the shadow host of the newly focused element\n // and not the element that actually has received focus if it is located\n // inside a shadow root.\n if ((0,_floating_ui_react_utils__rspack_import_6.contains)((_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.refs.floating.current, activeEl) || (0,_floating_ui_react_utils__rspack_import_6.contains)(elements.domReference, activeEl) || movedToFocusGuard) {\n return;\n }\n onOpenChange(false, nativeEvent, 'focus');\n });\n }\n }), [dataRef, elements.domReference, onOpenChange, visibleOnly]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nfunction mergeProps(userProps, propsList, elementKey) {\n const map = new Map();\n const isItem = elementKey === 'item';\n let domUserProps = userProps;\n if (isItem && userProps) {\n const {\n [ACTIVE_KEY]: _,\n [SELECTED_KEY]: __,\n ...validProps\n } = userProps;\n domUserProps = validProps;\n }\n return {\n ...(elementKey === 'floating' && {\n tabIndex: -1,\n [FOCUSABLE_ATTRIBUTE]: ''\n }),\n ...domUserProps,\n ...propsList.map(value => {\n const propsOrGetProps = value ? value[elementKey] : null;\n if (typeof propsOrGetProps === 'function') {\n return userProps ? propsOrGetProps(userProps) : null;\n }\n return propsOrGetProps;\n }).concat(userProps).reduce((acc, props) => {\n if (!props) {\n return acc;\n }\n Object.entries(props).forEach(_ref => {\n let [key, value] = _ref;\n if (isItem && [ACTIVE_KEY, SELECTED_KEY].includes(key)) {\n return;\n }\n if (key.indexOf('on') === 0) {\n if (!map.has(key)) {\n map.set(key, []);\n }\n if (typeof value === 'function') {\n var _map$get;\n (_map$get = map.get(key)) == null || _map$get.push(value);\n acc[key] = function () {\n var _map$get2;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n return (_map$get2 = map.get(key)) == null ? void 0 : _map$get2.map(fn => fn(...args)).find(val => val !== undefined);\n };\n }\n } else {\n acc[key] = value;\n }\n });\n return acc;\n }, {})\n };\n}\n/**\n * Merges an array of interaction hooks' props into prop getters, allowing\n * event handler functions to be composed together without overwriting one\n * another.\n * @see https://floating-ui.com/docs/useInteractions\n */\nfunction useInteractions(propsList) {\n if (propsList === void 0) {\n propsList = [];\n }\n const referenceDeps = propsList.map(key => key == null ? void 0 : key.reference);\n const floatingDeps = propsList.map(key => key == null ? void 0 : key.floating);\n const itemDeps = propsList.map(key => key == null ? void 0 : key.item);\n const getReferenceProps = react__rspack_import_0.useCallback(userProps => mergeProps(userProps, propsList, 'reference'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n referenceDeps);\n const getFloatingProps = react__rspack_import_0.useCallback(userProps => mergeProps(userProps, propsList, 'floating'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n floatingDeps);\n const getItemProps = react__rspack_import_0.useCallback(userProps => mergeProps(userProps, propsList, 'item'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n itemDeps);\n return react__rspack_import_0.useMemo(() => ({\n getReferenceProps,\n getFloatingProps,\n getItemProps\n }), [getReferenceProps, getFloatingProps, getItemProps]);\n}\n\nconst ESCAPE = 'Escape';\nfunction doSwitch(orientation, vertical, horizontal) {\n switch (orientation) {\n case 'vertical':\n return vertical;\n case 'horizontal':\n return horizontal;\n default:\n return vertical || horizontal;\n }\n}\nfunction isMainOrientationKey(key, orientation) {\n const vertical = key === ARROW_UP || key === ARROW_DOWN;\n const horizontal = key === ARROW_LEFT || key === ARROW_RIGHT;\n return doSwitch(orientation, vertical, horizontal);\n}\nfunction isMainOrientationToEndKey(key, orientation, rtl) {\n const vertical = key === ARROW_DOWN;\n const horizontal = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;\n return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key === ' ' || key === '';\n}\nfunction isCrossOrientationOpenKey(key, orientation, rtl) {\n const vertical = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;\n const horizontal = key === ARROW_DOWN;\n return doSwitch(orientation, vertical, horizontal);\n}\nfunction isCrossOrientationCloseKey(key, orientation, rtl, cols) {\n const vertical = rtl ? key === ARROW_RIGHT : key === ARROW_LEFT;\n const horizontal = key === ARROW_UP;\n if (orientation === 'both' || orientation === 'horizontal' && cols && cols > 1) {\n return key === ESCAPE;\n }\n return doSwitch(orientation, vertical, horizontal);\n}\n/**\n * Adds arrow key-based navigation of a list of items, either using real DOM\n * focus or virtual focus.\n * @see https://floating-ui.com/docs/useListNavigation\n */\nfunction useListNavigation(context, props) {\n const {\n open,\n onOpenChange,\n elements,\n floatingId\n } = context;\n const {\n listRef,\n activeIndex,\n onNavigate: unstable_onNavigate = () => {},\n enabled = true,\n selectedIndex = null,\n allowEscape = false,\n loop = false,\n nested = false,\n rtl = false,\n virtual = false,\n focusItemOnOpen = 'auto',\n focusItemOnHover = true,\n openOnArrowKeyDown = true,\n disabledIndices = undefined,\n orientation = 'vertical',\n parentOrientation,\n cols = 1,\n scrollItemIntoView = true,\n virtualItemRef,\n itemSizes,\n dense = false\n } = props;\n if (true) {\n if (allowEscape) {\n if (!loop) {\n warn('`useListNavigation` looping must be enabled to allow escaping.');\n }\n if (!virtual) {\n warn('`useListNavigation` must be virtual to allow escaping.');\n }\n }\n if (orientation === 'vertical' && cols > 1) {\n warn('In grid list navigation mode (`cols` > 1), the `orientation` should', 'be either \"horizontal\" or \"both\".');\n }\n }\n const floatingFocusElement = (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)(elements.floating);\n const floatingFocusElementRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(floatingFocusElement);\n const parentId = useFloatingParentNodeId();\n const tree = useFloatingTree();\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n context.dataRef.current.orientation = orientation;\n }, [context, orientation]);\n const onNavigate = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n unstable_onNavigate(indexRef.current === -1 ? null : indexRef.current);\n });\n const typeableComboboxReference = (0,_floating_ui_react_utils__rspack_import_6.isTypeableCombobox)(elements.domReference);\n const focusItemOnOpenRef = react__rspack_import_0.useRef(focusItemOnOpen);\n const indexRef = react__rspack_import_0.useRef(selectedIndex != null ? selectedIndex : -1);\n const keyRef = react__rspack_import_0.useRef(null);\n const isPointerModalityRef = react__rspack_import_0.useRef(true);\n const previousOnNavigateRef = react__rspack_import_0.useRef(onNavigate);\n const previousMountedRef = react__rspack_import_0.useRef(!!elements.floating);\n const previousOpenRef = react__rspack_import_0.useRef(open);\n const forceSyncFocusRef = react__rspack_import_0.useRef(false);\n const forceScrollIntoViewRef = react__rspack_import_0.useRef(false);\n const disabledIndicesRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(disabledIndices);\n const latestOpenRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(open);\n const scrollItemIntoViewRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(scrollItemIntoView);\n const selectedIndexRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(selectedIndex);\n const [activeId, setActiveId] = react__rspack_import_0.useState();\n const [virtualId, setVirtualId] = react__rspack_import_0.useState();\n const focusItem = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(() => {\n function runFocus(item) {\n if (virtual) {\n var _item$id;\n if ((_item$id = item.id) != null && _item$id.endsWith('-fui-option')) {\n item.id = floatingId + \"-\" + Math.random().toString(16).slice(2, 10);\n }\n setActiveId(item.id);\n tree == null || tree.events.emit('virtualfocus', item);\n if (virtualItemRef) {\n virtualItemRef.current = item;\n }\n } else {\n enqueueFocus(item, {\n sync: forceSyncFocusRef.current,\n preventScroll: true\n });\n }\n }\n const initialItem = listRef.current[indexRef.current];\n const forceScrollIntoView = forceScrollIntoViewRef.current;\n if (initialItem) {\n runFocus(initialItem);\n }\n const scheduler = forceSyncFocusRef.current ? v => v() : requestAnimationFrame;\n scheduler(() => {\n const waitedItem = listRef.current[indexRef.current] || initialItem;\n if (!waitedItem) return;\n if (!initialItem) {\n runFocus(waitedItem);\n }\n const scrollIntoViewOptions = scrollItemIntoViewRef.current;\n const shouldScrollIntoView = scrollIntoViewOptions && item && (forceScrollIntoView || !isPointerModalityRef.current);\n if (shouldScrollIntoView) {\n // JSDOM doesn't support `.scrollIntoView()` but it's widely supported\n // by all browsers.\n waitedItem.scrollIntoView == null || waitedItem.scrollIntoView(typeof scrollIntoViewOptions === 'boolean' ? {\n block: 'nearest',\n inline: 'nearest'\n } : scrollIntoViewOptions);\n }\n });\n });\n\n // Sync `selectedIndex` to be the `activeIndex` upon opening the floating\n // element. Also, reset `activeIndex` upon closing the floating element.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (open && elements.floating) {\n if (focusItemOnOpenRef.current && selectedIndex != null) {\n // Regardless of the pointer modality, we want to ensure the selected\n // item comes into view when the floating element is opened.\n forceScrollIntoViewRef.current = true;\n indexRef.current = selectedIndex;\n onNavigate();\n }\n } else if (previousMountedRef.current) {\n // Since the user can specify `onNavigate` conditionally\n // (onNavigate: open ? setActiveIndex : setSelectedIndex),\n // we store and call the previous function.\n indexRef.current = -1;\n previousOnNavigateRef.current();\n }\n }, [enabled, open, elements.floating, selectedIndex, onNavigate]);\n\n // Sync `activeIndex` to be the focused item while the floating element is\n // open.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!open) return;\n if (!elements.floating) return;\n if (activeIndex == null) {\n forceSyncFocusRef.current = false;\n if (selectedIndexRef.current != null) {\n return;\n }\n\n // Reset while the floating element was open (e.g. the list changed).\n if (previousMountedRef.current) {\n indexRef.current = -1;\n focusItem();\n }\n\n // Initial sync.\n if ((!previousOpenRef.current || !previousMountedRef.current) && focusItemOnOpenRef.current && (keyRef.current != null || focusItemOnOpenRef.current === true && keyRef.current == null)) {\n let runs = 0;\n const waitForListPopulated = () => {\n if (listRef.current[0] == null) {\n // Avoid letting the browser paint if possible on the first try,\n // otherwise use rAF. Don't try more than twice, since something\n // is wrong otherwise.\n if (runs < 2) {\n const scheduler = runs ? requestAnimationFrame : queueMicrotask;\n scheduler(waitForListPopulated);\n }\n runs++;\n } else {\n indexRef.current = keyRef.current == null || isMainOrientationToEndKey(keyRef.current, orientation, rtl) || nested ? (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(listRef, disabledIndicesRef.current) : (0,_floating_ui_react_utils__rspack_import_6.getMaxListIndex)(listRef, disabledIndicesRef.current);\n keyRef.current = null;\n onNavigate();\n }\n };\n waitForListPopulated();\n }\n } else if (!(0,_floating_ui_react_utils__rspack_import_6.isIndexOutOfListBounds)(listRef, activeIndex)) {\n indexRef.current = activeIndex;\n focusItem();\n forceScrollIntoViewRef.current = false;\n }\n }, [enabled, open, elements.floating, activeIndex, selectedIndexRef, nested, listRef, orientation, rtl, onNavigate, focusItem, disabledIndicesRef]);\n\n // Ensure the parent floating element has focus when a nested child closes\n // to allow arrow key navigation to work after the pointer leaves the child.\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n var _nodes$find;\n if (!enabled || elements.floating || !tree || virtual || !previousMountedRef.current) {\n return;\n }\n const nodes = tree.nodesRef.current;\n const parent = (_nodes$find = nodes.find(node => node.id === parentId)) == null || (_nodes$find = _nodes$find.context) == null ? void 0 : _nodes$find.elements.floating;\n const activeEl = (0,_floating_ui_react_utils__rspack_import_6.activeElement)((0,_floating_ui_react_utils__rspack_import_6.getDocument)(elements.floating));\n const treeContainsActiveEl = nodes.some(node => node.context && (0,_floating_ui_react_utils__rspack_import_6.contains)(node.context.elements.floating, activeEl));\n if (parent && !treeContainsActiveEl && isPointerModalityRef.current) {\n parent.focus({\n preventScroll: true\n });\n }\n }, [enabled, elements.floating, tree, parentId, virtual]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!enabled) return;\n if (!tree) return;\n if (!virtual) return;\n if (parentId) return;\n function handleVirtualFocus(item) {\n setVirtualId(item.id);\n if (virtualItemRef) {\n virtualItemRef.current = item;\n }\n }\n tree.events.on('virtualfocus', handleVirtualFocus);\n return () => {\n tree.events.off('virtualfocus', handleVirtualFocus);\n };\n }, [enabled, tree, virtual, parentId, virtualItemRef]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n previousOnNavigateRef.current = onNavigate;\n previousOpenRef.current = open;\n previousMountedRef.current = !!elements.floating;\n });\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!open) {\n keyRef.current = null;\n }\n }, [open]);\n const hasActiveIndex = activeIndex != null;\n const item = react__rspack_import_0.useMemo(() => {\n function syncCurrentTarget(currentTarget) {\n if (!open) return;\n const index = listRef.current.indexOf(currentTarget);\n if (index !== -1 && indexRef.current !== index) {\n indexRef.current = index;\n onNavigate();\n }\n }\n const props = {\n onFocus(_ref) {\n let {\n currentTarget\n } = _ref;\n forceSyncFocusRef.current = true;\n syncCurrentTarget(currentTarget);\n },\n onClick: _ref2 => {\n let {\n currentTarget\n } = _ref2;\n return currentTarget.focus({\n preventScroll: true\n });\n },\n // Safari\n ...(focusItemOnHover && {\n onMouseMove(_ref3) {\n let {\n currentTarget\n } = _ref3;\n forceSyncFocusRef.current = true;\n forceScrollIntoViewRef.current = false;\n syncCurrentTarget(currentTarget);\n },\n onPointerLeave(_ref4) {\n let {\n pointerType\n } = _ref4;\n if (!isPointerModalityRef.current || pointerType === 'touch') {\n return;\n }\n forceSyncFocusRef.current = true;\n indexRef.current = -1;\n onNavigate();\n if (!virtual) {\n var _floatingFocusElement;\n (_floatingFocusElement = floatingFocusElementRef.current) == null || _floatingFocusElement.focus({\n preventScroll: true\n });\n }\n }\n })\n };\n return props;\n }, [open, floatingFocusElementRef, focusItemOnHover, listRef, onNavigate, virtual]);\n const getParentOrientation = react__rspack_import_0.useCallback(() => {\n var _tree$nodesRef$curren;\n return parentOrientation != null ? parentOrientation : tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.dataRef) == null ? void 0 : _tree$nodesRef$curren.current.orientation;\n }, [parentId, tree, parentOrientation]);\n const commonOnKeyDown = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n isPointerModalityRef.current = false;\n forceSyncFocusRef.current = true;\n\n // When composing a character, Chrome fires ArrowDown twice. Firefox/Safari\n // don't appear to suffer from this. `event.isComposing` is avoided due to\n // Safari not supporting it properly (although it's not needed in the first\n // place for Safari, just avoiding any possible issues).\n if (event.which === 229) {\n return;\n }\n\n // If the floating element is animating out, ignore navigation. Otherwise,\n // the `activeIndex` gets set to 0 despite not being open so the next time\n // the user ArrowDowns, the first item won't be focused.\n if (!latestOpenRef.current && event.currentTarget === floatingFocusElementRef.current) {\n return;\n }\n if (nested && isCrossOrientationCloseKey(event.key, orientation, rtl, cols)) {\n // If the nested list's close key is also the parent navigation key,\n // let the parent navigate. Otherwise, stop propagating the event.\n if (!isMainOrientationKey(event.key, getParentOrientation())) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n }\n onOpenChange(false, event.nativeEvent, 'list-navigation');\n if ((0,_floating_ui_react_dom__rspack_import_5.isHTMLElement)(elements.domReference)) {\n if (virtual) {\n tree == null || tree.events.emit('virtualfocus', elements.domReference);\n } else {\n elements.domReference.focus();\n }\n }\n return;\n }\n const currentIndex = indexRef.current;\n const minIndex = (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(listRef, disabledIndices);\n const maxIndex = (0,_floating_ui_react_utils__rspack_import_6.getMaxListIndex)(listRef, disabledIndices);\n if (!typeableComboboxReference) {\n if (event.key === 'Home') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n indexRef.current = minIndex;\n onNavigate();\n }\n if (event.key === 'End') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n indexRef.current = maxIndex;\n onNavigate();\n }\n }\n\n // Grid navigation.\n if (cols > 1) {\n const sizes = itemSizes || Array.from({\n length: listRef.current.length\n }, () => ({\n width: 1,\n height: 1\n }));\n // To calculate movements on the grid, we use hypothetical cell indices\n // as if every item was 1x1, then convert back to real indices.\n const cellMap = (0,_floating_ui_react_utils__rspack_import_6.createGridCellMap)(sizes, cols, dense);\n const minGridIndex = cellMap.findIndex(index => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(listRef, index, disabledIndices));\n // last enabled index\n const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !(0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(listRef, index, disabledIndices) ? cellIndex : foundIndex, -1);\n const index = cellMap[(0,_floating_ui_react_utils__rspack_import_6.getGridNavigatedIndex)({\n current: cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null)\n }, {\n event,\n orientation,\n loop,\n rtl,\n cols,\n // treat undefined (empty grid spaces) as disabled indices so we\n // don't end up in them\n disabledIndices: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndices)([...(disabledIndices || listRef.current.map((_, index) => (0,_floating_ui_react_utils__rspack_import_6.isListIndexDisabled)(listRef, index) ? index : undefined)), undefined], cellMap),\n minIndex: minGridIndex,\n maxIndex: maxGridIndex,\n prevIndex: (0,_floating_ui_react_utils__rspack_import_6.getGridCellIndexOfCorner)(indexRef.current > maxIndex ? minIndex : indexRef.current, sizes, cellMap, cols,\n // use a corner matching the edge closest to the direction\n // we're moving in so we don't end up in the same item. Prefer\n // top/left over bottom/right.\n event.key === ARROW_DOWN ? 'bl' : event.key === (rtl ? ARROW_LEFT : ARROW_RIGHT) ? 'tr' : 'tl'),\n stopEvent: true\n })];\n if (index != null) {\n indexRef.current = index;\n onNavigate();\n }\n if (orientation === 'both') {\n return;\n }\n }\n if (isMainOrientationKey(event.key, orientation)) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n\n // Reset the index if no item is focused.\n if (open && !virtual && (0,_floating_ui_react_utils__rspack_import_6.activeElement)(event.currentTarget.ownerDocument) === event.currentTarget) {\n indexRef.current = isMainOrientationToEndKey(event.key, orientation, rtl) ? minIndex : maxIndex;\n onNavigate();\n return;\n }\n if (isMainOrientationToEndKey(event.key, orientation, rtl)) {\n if (loop) {\n indexRef.current = currentIndex >= maxIndex ? allowEscape && currentIndex !== listRef.current.length ? -1 : minIndex : (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n disabledIndices\n });\n } else {\n indexRef.current = Math.min(maxIndex, (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n disabledIndices\n }));\n }\n } else {\n if (loop) {\n indexRef.current = currentIndex <= minIndex ? allowEscape && currentIndex !== -1 ? listRef.current.length : maxIndex : (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n decrement: true,\n disabledIndices\n });\n } else {\n indexRef.current = Math.max(minIndex, (0,_floating_ui_react_utils__rspack_import_6.findNonDisabledListIndex)(listRef, {\n startingIndex: currentIndex,\n decrement: true,\n disabledIndices\n }));\n }\n }\n if ((0,_floating_ui_react_utils__rspack_import_6.isIndexOutOfListBounds)(listRef, indexRef.current)) {\n indexRef.current = -1;\n }\n onNavigate();\n }\n });\n const ariaActiveDescendantProp = react__rspack_import_0.useMemo(() => {\n return virtual && open && hasActiveIndex && {\n 'aria-activedescendant': virtualId || activeId\n };\n }, [virtual, open, hasActiveIndex, virtualId, activeId]);\n const floating = react__rspack_import_0.useMemo(() => {\n return {\n 'aria-orientation': orientation === 'both' ? undefined : orientation,\n ...(!typeableComboboxReference ? ariaActiveDescendantProp : {}),\n onKeyDown: commonOnKeyDown,\n onPointerMove() {\n isPointerModalityRef.current = true;\n }\n };\n }, [ariaActiveDescendantProp, commonOnKeyDown, orientation, typeableComboboxReference]);\n const reference = react__rspack_import_0.useMemo(() => {\n function checkVirtualMouse(event) {\n if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__rspack_import_6.isVirtualClick)(event.nativeEvent)) {\n focusItemOnOpenRef.current = true;\n }\n }\n function checkVirtualPointer(event) {\n // `pointerdown` fires first, reset the state then perform the checks.\n focusItemOnOpenRef.current = focusItemOnOpen;\n if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__rspack_import_6.isVirtualPointerEvent)(event.nativeEvent)) {\n focusItemOnOpenRef.current = true;\n }\n }\n return {\n ...ariaActiveDescendantProp,\n onKeyDown(event) {\n isPointerModalityRef.current = false;\n const isArrowKey = event.key.startsWith('Arrow');\n const isHomeOrEndKey = ['Home', 'End'].includes(event.key);\n const isMoveKey = isArrowKey || isHomeOrEndKey;\n const isCrossOpenKey = isCrossOrientationOpenKey(event.key, orientation, rtl);\n const isCrossCloseKey = isCrossOrientationCloseKey(event.key, orientation, rtl, cols);\n const isParentCrossOpenKey = isCrossOrientationOpenKey(event.key, getParentOrientation(), rtl);\n const isMainKey = isMainOrientationKey(event.key, orientation);\n const isNavigationKey = (nested ? isParentCrossOpenKey : isMainKey) || event.key === 'Enter' || event.key.trim() === '';\n if (virtual && open) {\n const rootNode = tree == null ? void 0 : tree.nodesRef.current.find(node => node.parentId == null);\n const deepestNode = tree && rootNode ? (0,_floating_ui_react_utils__rspack_import_6.getDeepestNode)(tree.nodesRef.current, rootNode.id) : null;\n if (isMoveKey && deepestNode && virtualItemRef) {\n const eventObject = new KeyboardEvent('keydown', {\n key: event.key,\n bubbles: true\n });\n if (isCrossOpenKey || isCrossCloseKey) {\n var _deepestNode$context, _deepestNode$context2;\n const isCurrentTarget = ((_deepestNode$context = deepestNode.context) == null ? void 0 : _deepestNode$context.elements.domReference) === event.currentTarget;\n const dispatchItem = isCrossCloseKey && !isCurrentTarget ? (_deepestNode$context2 = deepestNode.context) == null ? void 0 : _deepestNode$context2.elements.domReference : isCrossOpenKey ? listRef.current.find(item => (item == null ? void 0 : item.id) === activeId) : null;\n if (dispatchItem) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n dispatchItem.dispatchEvent(eventObject);\n setVirtualId(undefined);\n }\n }\n if ((isMainKey || isHomeOrEndKey) && deepestNode.context) {\n if (deepestNode.context.open && deepestNode.parentId && event.currentTarget !== deepestNode.context.elements.domReference) {\n var _deepestNode$context$;\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n (_deepestNode$context$ = deepestNode.context.elements.domReference) == null || _deepestNode$context$.dispatchEvent(eventObject);\n return;\n }\n }\n }\n return commonOnKeyDown(event);\n }\n // If a floating element should not open on arrow key down, avoid\n // setting `activeIndex` while it's closed.\n if (!open && !openOnArrowKeyDown && isArrowKey) {\n return;\n }\n if (isNavigationKey) {\n const isParentMainKey = isMainOrientationKey(event.key, getParentOrientation());\n keyRef.current = nested && isParentMainKey ? null : event.key;\n }\n if (nested) {\n if (isParentCrossOpenKey) {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n if (open) {\n indexRef.current = (0,_floating_ui_react_utils__rspack_import_6.getMinListIndex)(listRef, disabledIndicesRef.current);\n onNavigate();\n } else {\n onOpenChange(true, event.nativeEvent, 'list-navigation');\n }\n }\n return;\n }\n if (isMainKey) {\n if (selectedIndex != null) {\n indexRef.current = selectedIndex;\n }\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n if (!open && openOnArrowKeyDown) {\n onOpenChange(true, event.nativeEvent, 'list-navigation');\n } else {\n commonOnKeyDown(event);\n }\n if (open) {\n onNavigate();\n }\n }\n },\n onFocus() {\n if (open && !virtual) {\n indexRef.current = -1;\n onNavigate();\n }\n },\n onPointerDown: checkVirtualPointer,\n onPointerEnter: checkVirtualPointer,\n onMouseDown: checkVirtualMouse,\n onClick: checkVirtualMouse\n };\n }, [activeId, ariaActiveDescendantProp, cols, commonOnKeyDown, disabledIndicesRef, focusItemOnOpen, listRef, nested, onNavigate, onOpenChange, open, openOnArrowKeyDown, orientation, getParentOrientation, rtl, selectedIndex, tree, virtual, virtualItemRef]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating,\n item\n } : {}, [enabled, reference, floating, item]);\n}\n\nconst componentRoleToAriaRoleMap = /*#__PURE__*/new Map([['select', 'listbox'], ['combobox', 'listbox'], ['label', false]]);\n\n/**\n * Adds base screen reader props to the reference and floating elements for a\n * given floating element `role`.\n * @see https://floating-ui.com/docs/useRole\n */\nfunction useRole(context, props) {\n var _elements$domReferenc, _componentRoleToAriaR;\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n elements,\n floatingId: defaultFloatingId\n } = context;\n const {\n enabled = true,\n role = 'dialog'\n } = props;\n const defaultReferenceId = useId();\n const referenceId = ((_elements$domReferenc = elements.domReference) == null ? void 0 : _elements$domReferenc.id) || defaultReferenceId;\n const floatingId = react__rspack_import_0.useMemo(() => {\n var _getFloatingFocusElem;\n return ((_getFloatingFocusElem = (0,_floating_ui_react_utils__rspack_import_6.getFloatingFocusElement)(elements.floating)) == null ? void 0 : _getFloatingFocusElem.id) || defaultFloatingId;\n }, [elements.floating, defaultFloatingId]);\n const ariaRole = (_componentRoleToAriaR = componentRoleToAriaRoleMap.get(role)) != null ? _componentRoleToAriaR : role;\n const parentId = useFloatingParentNodeId();\n const isNested = parentId != null;\n const reference = react__rspack_import_0.useMemo(() => {\n if (ariaRole === 'tooltip' || role === 'label') {\n return {\n [\"aria-\" + (role === 'label' ? 'labelledby' : 'describedby')]: open ? floatingId : undefined\n };\n }\n return {\n 'aria-expanded': open ? 'true' : 'false',\n 'aria-haspopup': ariaRole === 'alertdialog' ? 'dialog' : ariaRole,\n 'aria-controls': open ? floatingId : undefined,\n ...(ariaRole === 'listbox' && {\n role: 'combobox'\n }),\n ...(ariaRole === 'menu' && {\n id: referenceId\n }),\n ...(ariaRole === 'menu' && isNested && {\n role: 'menuitem'\n }),\n ...(role === 'select' && {\n 'aria-autocomplete': 'none'\n }),\n ...(role === 'combobox' && {\n 'aria-autocomplete': 'list'\n })\n };\n }, [ariaRole, floatingId, isNested, open, referenceId, role]);\n const floating = react__rspack_import_0.useMemo(() => {\n const floatingProps = {\n id: floatingId,\n ...(ariaRole && {\n role: ariaRole\n })\n };\n if (ariaRole === 'tooltip' || role === 'label') {\n return floatingProps;\n }\n return {\n ...floatingProps,\n ...(ariaRole === 'menu' && {\n 'aria-labelledby': referenceId\n })\n };\n }, [ariaRole, floatingId, referenceId, role]);\n const item = react__rspack_import_0.useCallback(_ref => {\n let {\n active,\n selected\n } = _ref;\n const commonProps = {\n role: 'option',\n ...(active && {\n id: floatingId + \"-fui-option\"\n })\n };\n\n // For `menu`, we are unable to tell if the item is a `menuitemradio`\n // or `menuitemcheckbox`. For backwards-compatibility reasons, also\n // avoid defaulting to `menuitem` as it may overwrite custom role props.\n switch (role) {\n case 'select':\n return {\n ...commonProps,\n 'aria-selected': active && selected\n };\n case 'combobox':\n {\n return {\n ...commonProps,\n 'aria-selected': selected\n };\n }\n }\n return {};\n }, [floatingId, role]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating,\n item\n } : {}, [enabled, reference, floating, item]);\n}\n\n// Converts a JS style key like `backgroundColor` to a CSS transition-property\n// like `background-color`.\nconst camelCaseToKebabCase = str => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());\nfunction execWithArgsOrReturn(valueOrFn, args) {\n return typeof valueOrFn === 'function' ? valueOrFn(args) : valueOrFn;\n}\nfunction useDelayUnmount(open, durationMs) {\n const [isMounted, setIsMounted] = react__rspack_import_0.useState(open);\n if (open && !isMounted) {\n setIsMounted(true);\n }\n react__rspack_import_0.useEffect(() => {\n if (!open && isMounted) {\n const timeout = setTimeout(() => setIsMounted(false), durationMs);\n return () => clearTimeout(timeout);\n }\n }, [open, isMounted, durationMs]);\n return isMounted;\n}\n/**\n * Provides a status string to apply CSS transitions to a floating element,\n * correctly handling placement-aware transitions.\n * @see https://floating-ui.com/docs/useTransition#usetransitionstatus\n */\nfunction useTransitionStatus(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n elements: {\n floating\n }\n } = context;\n const {\n duration = 250\n } = props;\n const isNumberDuration = typeof duration === 'number';\n const closeDuration = (isNumberDuration ? duration : duration.close) || 0;\n const [status, setStatus] = react__rspack_import_0.useState('unmounted');\n const isMounted = useDelayUnmount(open, closeDuration);\n if (!isMounted && status === 'close') {\n setStatus('unmounted');\n }\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (!floating) return;\n if (open) {\n setStatus('initial');\n const frame = requestAnimationFrame(() => {\n // Ensure it opens before paint. With `FloatingDelayGroup`,\n // this avoids a flicker when moving between floating elements\n // to ensure one is always open with no missing frames.\n react_dom__rspack_import_2.flushSync(() => {\n setStatus('open');\n });\n });\n return () => {\n cancelAnimationFrame(frame);\n };\n }\n setStatus('close');\n }, [open, floating]);\n return {\n isMounted,\n status\n };\n}\n/**\n * Provides styles to apply CSS transitions to a floating element, correctly\n * handling placement-aware transitions. Wrapper around `useTransitionStatus`.\n * @see https://floating-ui.com/docs/useTransition#usetransitionstyles\n */\nfunction useTransitionStyles(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n initial: unstable_initial = {\n opacity: 0\n },\n open: unstable_open,\n close: unstable_close,\n common: unstable_common,\n duration = 250\n } = props;\n const placement = context.placement;\n const side = placement.split('-')[0];\n const fnArgs = react__rspack_import_0.useMemo(() => ({\n side,\n placement\n }), [side, placement]);\n const isNumberDuration = typeof duration === 'number';\n const openDuration = (isNumberDuration ? duration : duration.open) || 0;\n const closeDuration = (isNumberDuration ? duration : duration.close) || 0;\n const [styles, setStyles] = react__rspack_import_0.useState(() => ({\n ...execWithArgsOrReturn(unstable_common, fnArgs),\n ...execWithArgsOrReturn(unstable_initial, fnArgs)\n }));\n const {\n isMounted,\n status\n } = useTransitionStatus(context, {\n duration\n });\n const initialRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_initial);\n const openRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_open);\n const closeRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_close);\n const commonRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(unstable_common);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n const initialStyles = execWithArgsOrReturn(initialRef.current, fnArgs);\n const closeStyles = execWithArgsOrReturn(closeRef.current, fnArgs);\n const commonStyles = execWithArgsOrReturn(commonRef.current, fnArgs);\n const openStyles = execWithArgsOrReturn(openRef.current, fnArgs) || Object.keys(initialStyles).reduce((acc, key) => {\n acc[key] = '';\n return acc;\n }, {});\n if (status === 'initial') {\n setStyles(styles => ({\n transitionProperty: styles.transitionProperty,\n ...commonStyles,\n ...initialStyles\n }));\n }\n if (status === 'open') {\n setStyles({\n transitionProperty: Object.keys(openStyles).map(camelCaseToKebabCase).join(','),\n transitionDuration: openDuration + \"ms\",\n ...commonStyles,\n ...openStyles\n });\n }\n if (status === 'close') {\n const styles = closeStyles || initialStyles;\n setStyles({\n transitionProperty: Object.keys(styles).map(camelCaseToKebabCase).join(','),\n transitionDuration: closeDuration + \"ms\",\n ...commonStyles,\n ...styles\n });\n }\n }, [closeDuration, closeRef, initialRef, openRef, commonRef, openDuration, status, fnArgs]);\n return {\n isMounted,\n styles\n };\n}\n\n/**\n * Provides a matching callback that can be used to focus an item as the user\n * types, often used in tandem with `useListNavigation()`.\n * @see https://floating-ui.com/docs/useTypeahead\n */\nfunction useTypeahead(context, props) {\n var _ref;\n const {\n open,\n dataRef\n } = context;\n const {\n listRef,\n activeIndex,\n onMatch: unstable_onMatch,\n onTypingChange: unstable_onTypingChange,\n enabled = true,\n findMatch = null,\n resetMs = 750,\n ignoreKeys = [],\n selectedIndex = null\n } = props;\n const timeoutIdRef = react__rspack_import_0.useRef(-1);\n const stringRef = react__rspack_import_0.useRef('');\n const prevIndexRef = react__rspack_import_0.useRef((_ref = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref : -1);\n const matchIndexRef = react__rspack_import_0.useRef(null);\n const onMatch = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(unstable_onMatch);\n const onTypingChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(unstable_onTypingChange);\n const findMatchRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(findMatch);\n const ignoreKeysRef = (0,_floating_ui_react_utils__rspack_import_6.useLatestRef)(ignoreKeys);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n if (open) {\n clearTimeoutIfSet(timeoutIdRef);\n matchIndexRef.current = null;\n stringRef.current = '';\n }\n }, [open]);\n (0,_floating_ui_react_utils__rspack_import_6.useModernLayoutEffect)(() => {\n // Sync arrow key navigation but not typeahead navigation.\n if (open && stringRef.current === '') {\n var _ref2;\n prevIndexRef.current = (_ref2 = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref2 : -1;\n }\n }, [open, selectedIndex, activeIndex]);\n const setTypingChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(value => {\n if (value) {\n if (!dataRef.current.typing) {\n dataRef.current.typing = value;\n onTypingChange(value);\n }\n } else {\n if (dataRef.current.typing) {\n dataRef.current.typing = value;\n onTypingChange(value);\n }\n }\n });\n const onKeyDown = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(event => {\n function getMatchingIndex(list, orderedList, string) {\n const str = findMatchRef.current ? findMatchRef.current(orderedList, string) : orderedList.find(text => (text == null ? void 0 : text.toLocaleLowerCase().indexOf(string.toLocaleLowerCase())) === 0);\n return str ? list.indexOf(str) : -1;\n }\n const listContent = listRef.current;\n if (stringRef.current.length > 0 && stringRef.current[0] !== ' ') {\n if (getMatchingIndex(listContent, listContent, stringRef.current) === -1) {\n setTypingChange(false);\n } else if (event.key === ' ') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n }\n }\n if (listContent == null || ignoreKeysRef.current.includes(event.key) ||\n // Character key.\n event.key.length !== 1 ||\n // Modifier key.\n event.ctrlKey || event.metaKey || event.altKey) {\n return;\n }\n if (open && event.key !== ' ') {\n (0,_floating_ui_react_utils__rspack_import_6.stopEvent)(event);\n setTypingChange(true);\n }\n\n // Bail out if the list contains a word like \"llama\" or \"aaron\". TODO:\n // allow it in this case, too.\n const allowRapidSuccessionOfFirstLetter = listContent.every(text => {\n var _text$, _text$2;\n return text ? ((_text$ = text[0]) == null ? void 0 : _text$.toLocaleLowerCase()) !== ((_text$2 = text[1]) == null ? void 0 : _text$2.toLocaleLowerCase()) : true;\n });\n\n // Allows the user to cycle through items that start with the same letter\n // in rapid succession.\n if (allowRapidSuccessionOfFirstLetter && stringRef.current === event.key) {\n stringRef.current = '';\n prevIndexRef.current = matchIndexRef.current;\n }\n stringRef.current += event.key;\n clearTimeoutIfSet(timeoutIdRef);\n timeoutIdRef.current = window.setTimeout(() => {\n stringRef.current = '';\n prevIndexRef.current = matchIndexRef.current;\n setTypingChange(false);\n }, resetMs);\n const prevIndex = prevIndexRef.current;\n const index = getMatchingIndex(listContent, [...listContent.slice((prevIndex || 0) + 1), ...listContent.slice(0, (prevIndex || 0) + 1)], stringRef.current);\n if (index !== -1) {\n onMatch(index);\n matchIndexRef.current = index;\n } else if (event.key !== ' ') {\n stringRef.current = '';\n setTypingChange(false);\n }\n });\n const reference = react__rspack_import_0.useMemo(() => ({\n onKeyDown\n }), [onKeyDown]);\n const floating = react__rspack_import_0.useMemo(() => {\n return {\n onKeyDown,\n onKeyUp(event) {\n if (event.key === ' ') {\n setTypingChange(false);\n }\n }\n };\n }, [onKeyDown, setTypingChange]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nfunction getArgsWithCustomFloatingHeight(state, height) {\n return {\n ...state,\n rects: {\n ...state.rects,\n floating: {\n ...state.rects.floating,\n height\n }\n }\n };\n}\n/**\n * Positions the floating element such that an inner element inside of it is\n * anchored to the reference element.\n * @see https://floating-ui.com/docs/inner\n * @deprecated\n */\nconst inner = props => ({\n name: 'inner',\n options: props,\n async fn(state) {\n const {\n listRef,\n overflowRef,\n onFallbackChange,\n offset: innerOffset = 0,\n index = 0,\n minItemsVisible = 4,\n referenceOverflowThreshold = 0,\n scrollRef,\n ...detectOverflowOptions\n } = (0,_floating_ui_utils__rspack_import_8.evaluate)(props, state);\n const {\n rects,\n elements: {\n floating\n }\n } = state;\n const item = listRef.current[index];\n const scrollEl = (scrollRef == null ? void 0 : scrollRef.current) || floating;\n\n // Valid combinations:\n // 1. Floating element is the scrollRef and has a border (default)\n // 2. Floating element is not the scrollRef, floating element has a border\n // 3. Floating element is not the scrollRef, scrollRef has a border\n // Floating > {...getFloatingProps()} wrapper > scrollRef > items is not\n // allowed as VoiceOver doesn't work.\n const clientTop = floating.clientTop || scrollEl.clientTop;\n const floatingIsBordered = floating.clientTop !== 0;\n const scrollElIsBordered = scrollEl.clientTop !== 0;\n const floatingIsScrollEl = floating === scrollEl;\n if (true) {\n if (!state.placement.startsWith('bottom')) {\n warn('`placement` side must be \"bottom\" when using the `inner`', 'middleware.');\n }\n }\n if (!item) {\n return {};\n }\n const nextArgs = {\n ...state,\n ...(await (0,_floating_ui_react_dom__rspack_import_3.offset)(-item.offsetTop - floating.clientTop - rects.reference.height / 2 - item.offsetHeight / 2 - innerOffset).fn(state))\n };\n const overflow = await (0,_floating_ui_react_dom__rspack_import_4.detectOverflow)(getArgsWithCustomFloatingHeight(nextArgs, scrollEl.scrollHeight + clientTop + floating.clientTop), detectOverflowOptions);\n const refOverflow = await (0,_floating_ui_react_dom__rspack_import_4.detectOverflow)(nextArgs, {\n ...detectOverflowOptions,\n elementContext: 'reference'\n });\n const diffY = (0,_floating_ui_utils__rspack_import_8.max)(0, overflow.top);\n const nextY = nextArgs.y + diffY;\n const isScrollable = scrollEl.scrollHeight > scrollEl.clientHeight;\n const rounder = isScrollable ? v => v : _floating_ui_utils__rspack_import_8.round;\n const maxHeight = rounder((0,_floating_ui_utils__rspack_import_8.max)(0, scrollEl.scrollHeight + (floatingIsBordered && floatingIsScrollEl || scrollElIsBordered ? clientTop * 2 : 0) - diffY - (0,_floating_ui_utils__rspack_import_8.max)(0, overflow.bottom)));\n scrollEl.style.maxHeight = maxHeight + \"px\";\n scrollEl.scrollTop = diffY;\n\n // There is not enough space, fallback to standard anchored positioning\n if (onFallbackChange) {\n const shouldFallback = scrollEl.offsetHeight < item.offsetHeight * (0,_floating_ui_utils__rspack_import_8.min)(minItemsVisible, listRef.current.length) - 1 || refOverflow.top >= -referenceOverflowThreshold || refOverflow.bottom >= -referenceOverflowThreshold;\n react_dom__rspack_import_2.flushSync(() => onFallbackChange(shouldFallback));\n }\n if (overflowRef) {\n overflowRef.current = await (0,_floating_ui_react_dom__rspack_import_4.detectOverflow)(getArgsWithCustomFloatingHeight({\n ...nextArgs,\n y: nextY\n }, scrollEl.offsetHeight + clientTop + floating.clientTop), detectOverflowOptions);\n }\n return {\n y: nextY\n };\n }\n});\n/**\n * Changes the `inner` middleware's `offset` upon a `wheel` event to\n * expand the floating element's height, revealing more list items.\n * @see https://floating-ui.com/docs/inner\n * @deprecated\n */\nfunction useInnerOffset(context, props) {\n const {\n open,\n elements\n } = context;\n const {\n enabled = true,\n overflowRef,\n scrollRef,\n onChange: unstable_onChange\n } = props;\n const onChange = (0,_floating_ui_react_utils__rspack_import_6.useEffectEvent)(unstable_onChange);\n const controlledScrollingRef = react__rspack_import_0.useRef(false);\n const prevScrollTopRef = react__rspack_import_0.useRef(null);\n const initialOverflowRef = react__rspack_import_0.useRef(null);\n react__rspack_import_0.useEffect(() => {\n if (!enabled) return;\n function onWheel(e) {\n if (e.ctrlKey || !el || overflowRef.current == null) {\n return;\n }\n const dY = e.deltaY;\n const isAtTop = overflowRef.current.top >= -0.5;\n const isAtBottom = overflowRef.current.bottom >= -0.5;\n const remainingScroll = el.scrollHeight - el.clientHeight;\n const sign = dY < 0 ? -1 : 1;\n const method = dY < 0 ? 'max' : 'min';\n if (el.scrollHeight <= el.clientHeight) {\n return;\n }\n if (!isAtTop && dY > 0 || !isAtBottom && dY < 0) {\n e.preventDefault();\n react_dom__rspack_import_2.flushSync(() => {\n onChange(d => d + Math[method](dY, remainingScroll * sign));\n });\n } else if (/firefox/i.test((0,_floating_ui_react_utils__rspack_import_6.getUserAgent)())) {\n // Needed to propagate scrolling during momentum scrolling phase once\n // it gets limited by the boundary. UX improvement, not critical.\n el.scrollTop += dY;\n }\n }\n const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;\n if (open && el) {\n el.addEventListener('wheel', onWheel);\n\n // Wait for the position to be ready.\n requestAnimationFrame(() => {\n prevScrollTopRef.current = el.scrollTop;\n if (overflowRef.current != null) {\n initialOverflowRef.current = {\n ...overflowRef.current\n };\n }\n });\n return () => {\n prevScrollTopRef.current = null;\n initialOverflowRef.current = null;\n el.removeEventListener('wheel', onWheel);\n };\n }\n }, [enabled, open, elements.floating, overflowRef, scrollRef, onChange]);\n const floating = react__rspack_import_0.useMemo(() => ({\n onKeyDown() {\n controlledScrollingRef.current = true;\n },\n onWheel() {\n controlledScrollingRef.current = false;\n },\n onPointerMove() {\n controlledScrollingRef.current = false;\n },\n onScroll() {\n const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;\n if (!overflowRef.current || !el || !controlledScrollingRef.current) {\n return;\n }\n if (prevScrollTopRef.current !== null) {\n const scrollDiff = el.scrollTop - prevScrollTopRef.current;\n if (overflowRef.current.bottom < -0.5 && scrollDiff < -1 || overflowRef.current.top < -0.5 && scrollDiff > 1) {\n react_dom__rspack_import_2.flushSync(() => onChange(d => d + scrollDiff));\n }\n }\n\n // [Firefox] Wait for the height change to have been applied.\n requestAnimationFrame(() => {\n prevScrollTopRef.current = el.scrollTop;\n });\n }\n }), [elements.floating, onChange, overflowRef, scrollRef]);\n return react__rspack_import_0.useMemo(() => enabled ? {\n floating\n } : {}, [enabled, floating]);\n}\n\nfunction getNodeChildren(nodes, id, onlyOpenChildren) {\n if (onlyOpenChildren === void 0) {\n onlyOpenChildren = true;\n }\n let allChildren = nodes.filter(node => {\n var _node$context;\n return node.parentId === id && ((_node$context = node.context) == null ? void 0 : _node$context.open);\n });\n let currentChildren = allChildren;\n while (currentChildren.length) {\n currentChildren = onlyOpenChildren ? nodes.filter(node => {\n var _currentChildren;\n return (_currentChildren = currentChildren) == null ? void 0 : _currentChildren.some(n => {\n var _node$context2;\n return node.parentId === n.id && ((_node$context2 = node.context) == null ? void 0 : _node$context2.open);\n });\n }) : nodes;\n allChildren = allChildren.concat(currentChildren);\n }\n return allChildren;\n}\n\nfunction isPointInPolygon(point, polygon) {\n const [x, y] = point;\n let isInside = false;\n const length = polygon.length;\n for (let i = 0, j = length - 1; i < length; j = i++) {\n const [xi, yi] = polygon[i] || [0, 0];\n const [xj, yj] = polygon[j] || [0, 0];\n const intersect = yi >= y !== yj >= y && x <= (xj - xi) * (y - yi) / (yj - yi) + xi;\n if (intersect) {\n isInside = !isInside;\n }\n }\n return isInside;\n}\nfunction isInside(point, rect) {\n return point[0] >= rect.x && point[0] <= rect.x + rect.width && point[1] >= rect.y && point[1] <= rect.y + rect.height;\n}\n/**\n * Generates a safe polygon area that the user can traverse without closing the\n * floating element once leaving the reference element.\n * @see https://floating-ui.com/docs/useHover#safepolygon\n */\nfunction safePolygon(options) {\n if (options === void 0) {\n options = {};\n }\n const {\n buffer = 0.5,\n blockPointerEvents = false,\n requireIntent = true\n } = options;\n let timeoutId;\n let hasLanded = false;\n let lastX = null;\n let lastY = null;\n let lastCursorTime = performance.now();\n function getCursorSpeed(x, y) {\n const currentTime = performance.now();\n const elapsedTime = currentTime - lastCursorTime;\n if (lastX === null || lastY === null || elapsedTime === 0) {\n lastX = x;\n lastY = y;\n lastCursorTime = currentTime;\n return null;\n }\n const deltaX = x - lastX;\n const deltaY = y - lastY;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n const speed = distance / elapsedTime; // px / ms\n\n lastX = x;\n lastY = y;\n lastCursorTime = currentTime;\n return speed;\n }\n const fn = _ref => {\n let {\n x,\n y,\n placement,\n elements,\n onClose,\n nodeId,\n tree\n } = _ref;\n return function onMouseMove(event) {\n function close() {\n clearTimeout(timeoutId);\n onClose();\n }\n clearTimeout(timeoutId);\n if (!elements.domReference || !elements.floating || placement == null || x == null || y == null) {\n return;\n }\n const {\n clientX,\n clientY\n } = event;\n const clientPoint = [clientX, clientY];\n const target = getTarget(event);\n const isLeave = event.type === 'mouseleave';\n const isOverFloatingEl = contains(elements.floating, target);\n const isOverReferenceEl = contains(elements.domReference, target);\n const refRect = elements.domReference.getBoundingClientRect();\n const rect = elements.floating.getBoundingClientRect();\n const side = placement.split('-')[0];\n const cursorLeaveFromRight = x > rect.right - rect.width / 2;\n const cursorLeaveFromBottom = y > rect.bottom - rect.height / 2;\n const isOverReferenceRect = isInside(clientPoint, refRect);\n const isFloatingWider = rect.width > refRect.width;\n const isFloatingTaller = rect.height > refRect.height;\n const left = (isFloatingWider ? refRect : rect).left;\n const right = (isFloatingWider ? refRect : rect).right;\n const top = (isFloatingTaller ? refRect : rect).top;\n const bottom = (isFloatingTaller ? refRect : rect).bottom;\n if (isOverFloatingEl) {\n hasLanded = true;\n if (!isLeave) {\n return;\n }\n }\n if (isOverReferenceEl) {\n hasLanded = false;\n }\n if (isOverReferenceEl && !isLeave) {\n hasLanded = true;\n return;\n }\n\n // Prevent overlapping floating element from being stuck in an open-close\n // loop: https://github.com/floating-ui/floating-ui/issues/1910\n if (isLeave && (0,_floating_ui_react_dom__rspack_import_5.isElement)(event.relatedTarget) && contains(elements.floating, event.relatedTarget)) {\n return;\n }\n\n // If any nested child is open, abort.\n if (tree && getNodeChildren(tree.nodesRef.current, nodeId).some(_ref2 => {\n let {\n context\n } = _ref2;\n return context == null ? void 0 : context.open;\n })) {\n return;\n }\n\n // If the pointer is leaving from the opposite side, the \"buffer\" logic\n // creates a point where the floating element remains open, but should be\n // ignored.\n // A constant of 1 handles floating point rounding errors.\n if (side === 'top' && y >= refRect.bottom - 1 || side === 'bottom' && y <= refRect.top + 1 || side === 'left' && x >= refRect.right - 1 || side === 'right' && x <= refRect.left + 1) {\n return close();\n }\n\n // Ignore when the cursor is within the rectangular trough between the\n // two elements. Since the triangle is created from the cursor point,\n // which can start beyond the ref element's edge, traversing back and\n // forth from the ref to the floating element can cause it to close. This\n // ensures it always remains open in that case.\n let rectPoly = [];\n switch (side) {\n case 'top':\n rectPoly = [[left, refRect.top + 1], [left, rect.bottom - 1], [right, rect.bottom - 1], [right, refRect.top + 1]];\n break;\n case 'bottom':\n rectPoly = [[left, rect.top + 1], [left, refRect.bottom - 1], [right, refRect.bottom - 1], [right, rect.top + 1]];\n break;\n case 'left':\n rectPoly = [[rect.right - 1, bottom], [rect.right - 1, top], [refRect.left + 1, top], [refRect.left + 1, bottom]];\n break;\n case 'right':\n rectPoly = [[refRect.right - 1, bottom], [refRect.right - 1, top], [rect.left + 1, top], [rect.left + 1, bottom]];\n break;\n }\n function getPolygon(_ref3) {\n let [x, y] = _ref3;\n switch (side) {\n case 'top':\n {\n const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];\n const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];\n const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.bottom - buffer : isFloatingWider ? rect.bottom - buffer : rect.top], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.bottom - buffer : rect.top : rect.bottom - buffer]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n case 'bottom':\n {\n const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];\n const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];\n const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.top + buffer : isFloatingWider ? rect.top + buffer : rect.bottom], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.top + buffer : rect.bottom : rect.top + buffer]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n case 'left':\n {\n const cursorPointOne = [x + buffer + 1, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const cursorPointTwo = [x + buffer + 1, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const commonPoints = [[cursorLeaveFromBottom ? rect.right - buffer : isFloatingTaller ? rect.right - buffer : rect.left, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.right - buffer : rect.left : rect.right - buffer, rect.bottom]];\n return [...commonPoints, cursorPointOne, cursorPointTwo];\n }\n case 'right':\n {\n const cursorPointOne = [x - buffer, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const cursorPointTwo = [x - buffer, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const commonPoints = [[cursorLeaveFromBottom ? rect.left + buffer : isFloatingTaller ? rect.left + buffer : rect.right, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.left + buffer : rect.right : rect.left + buffer, rect.bottom]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n }\n }\n if (isPointInPolygon([clientX, clientY], rectPoly)) {\n return;\n }\n if (hasLanded && !isOverReferenceRect) {\n return close();\n }\n if (!isLeave && requireIntent) {\n const cursorSpeed = getCursorSpeed(event.clientX, event.clientY);\n const cursorSpeedThreshold = 0.1;\n if (cursorSpeed !== null && cursorSpeed < cursorSpeedThreshold) {\n return close();\n }\n }\n if (!isPointInPolygon([clientX, clientY], getPolygon([x, y]))) {\n close();\n } else if (!hasLanded && requireIntent) {\n timeoutId = window.setTimeout(close, 40);\n }\n };\n };\n fn.__options = {\n blockPointerEvents\n };\n return fn;\n}\n\n\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218L2hvbWUvcnVubmVyL3dvcmsvb3Blbm1ycy1lc20tY29yZS9vcGVubXJzLWVzbS1jb3JlL25vZGVfbW9kdWxlcy9AZmxvYXRpbmctdWkvcmVhY3QvZGlzdC9mbG9hdGluZy11aS5yZWFjdC5tanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9AZmxvYXRpbmctdWkvcmVhY3QvZGlzdC9mbG9hdGluZy11aS5yZWFjdC5tanM/MTA3ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QsIHVzZUVmZmVjdEV2ZW50LCBnZXRNaW5MaXN0SW5kZXgsIGdldE1heExpc3RJbmRleCwgY3JlYXRlR3JpZENlbGxNYXAsIGlzTGlzdEluZGV4RGlzYWJsZWQsIGdldEdyaWROYXZpZ2F0ZWRJbmRleCwgZ2V0R3JpZENlbGxJbmRleE9mQ29ybmVyLCBnZXRHcmlkQ2VsbEluZGljZXMsIGZpbmROb25EaXNhYmxlZExpc3RJbmRleCwgaXNJbmRleE91dE9mTGlzdEJvdW5kcywgdXNlTGF0ZXN0UmVmLCBnZXREb2N1bWVudCBhcyBnZXREb2N1bWVudCQxLCBpc01vdXNlTGlrZVBvaW50ZXJUeXBlLCBjb250YWlucyBhcyBjb250YWlucyQxLCBpc1NhZmFyaSwgZW5hYmxlRm9jdXNJbnNpZGUsIGlzT3V0c2lkZUV2ZW50LCBnZXRQcmV2aW91c1RhYmJhYmxlLCBnZXROZXh0VGFiYmFibGUsIGRpc2FibGVGb2N1c0luc2lkZSwgaXNUeXBlYWJsZUNvbWJvYm94LCBnZXRGbG9hdGluZ0ZvY3VzRWxlbWVudCwgZ2V0VGFiYmFibGVPcHRpb25zLCBnZXROb2RlQW5jZXN0b3JzLCBhY3RpdmVFbGVtZW50LCBnZXROb2RlQ2hpbGRyZW4gYXMgZ2V0Tm9kZUNoaWxkcmVuJDEsIHN0b3BFdmVudCwgZ2V0VGFyZ2V0IGFzIGdldFRhcmdldCQxLCBpc1ZpcnR1YWxDbGljaywgaXNWaXJ0dWFsUG9pbnRlckV2ZW50LCBnZXRQbGF0Zm9ybSwgaXNUeXBlYWJsZUVsZW1lbnQsIGlzUmVhY3RFdmVudCwgaXNSb290RWxlbWVudCwgaXNFdmVudFRhcmdldFdpdGhpbiwgbWF0Y2hlc0ZvY3VzVmlzaWJsZSwgaXNNYWMsIGdldERlZXBlc3ROb2RlLCBnZXRVc2VyQWdlbnQgfSBmcm9tICdAZmxvYXRpbmctdWkvcmVhY3QvdXRpbHMnO1xuaW1wb3J0IHsganN4LCBqc3hzLCBGcmFnbWVudCB9IGZyb20gJ3JlYWN0L2pzeC1ydW50aW1lJztcbmltcG9ydCB7IGdldENvbXB1dGVkU3R5bGUsIGlzRWxlbWVudCwgaXNTaGFkb3dSb290LCBnZXROb2RlTmFtZSwgaXNIVE1MRWxlbWVudCwgZ2V0V2luZG93LCBpc0xhc3RUcmF2ZXJzYWJsZU5vZGUsIGdldFBhcmVudE5vZGUsIGlzV2ViS2l0IH0gZnJvbSAnQGZsb2F0aW5nLXVpL3V0aWxzL2RvbSc7XG5pbXBvcnQgeyB0YWJiYWJsZSwgaXNUYWJiYWJsZSwgZm9jdXNhYmxlIH0gZnJvbSAndGFiYmFibGUnO1xuaW1wb3J0ICogYXMgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcbmltcG9ydCB7IGdldE92ZXJmbG93QW5jZXN0b3JzLCB1c2VGbG9hdGluZyBhcyB1c2VGbG9hdGluZyQxLCBvZmZzZXQsIGRldGVjdE92ZXJmbG93IH0gZnJvbSAnQGZsb2F0aW5nLXVpL3JlYWN0LWRvbSc7XG5leHBvcnQgeyBhcnJvdywgYXV0b1BsYWNlbWVudCwgYXV0b1VwZGF0ZSwgY29tcHV0ZVBvc2l0aW9uLCBkZXRlY3RPdmVyZmxvdywgZmxpcCwgZ2V0T3ZlcmZsb3dBbmNlc3RvcnMsIGhpZGUsIGlubGluZSwgbGltaXRTaGlmdCwgb2Zmc2V0LCBwbGF0Zm9ybSwgc2hpZnQsIHNpemUgfSBmcm9tICdAZmxvYXRpbmctdWkvcmVhY3QtZG9tJztcbmltcG9ydCB7IGV2YWx1YXRlLCBtYXgsIHJvdW5kLCBtaW4gfSBmcm9tICdAZmxvYXRpbmctdWkvdXRpbHMnO1xuXG4vKipcbiAqIE1lcmdlcyBhbiBhcnJheSBvZiByZWZzIGludG8gYSBzaW5nbGUgbWVtb2l6ZWQgY2FsbGJhY2sgcmVmIG9yIGBudWxsYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9yZWFjdC11dGlscyN1c2VtZXJnZXJlZnNcbiAqL1xuZnVuY3Rpb24gdXNlTWVyZ2VSZWZzKHJlZnMpIHtcbiAgY29uc3QgY2xlYW51cFJlZiA9IFJlYWN0LnVzZVJlZih1bmRlZmluZWQpO1xuICBjb25zdCByZWZFZmZlY3QgPSBSZWFjdC51c2VDYWxsYmFjayhpbnN0YW5jZSA9PiB7XG4gICAgY29uc3QgY2xlYW51cHMgPSByZWZzLm1hcChyZWYgPT4ge1xuICAgICAgaWYgKHJlZiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IHJlZkNhbGxiYWNrID0gcmVmO1xuICAgICAgICBjb25zdCByZWZDbGVhbnVwID0gcmVmQ2FsbGJhY2soaW5zdGFuY2UpO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHJlZkNsZWFudXAgPT09ICdmdW5jdGlvbicgPyByZWZDbGVhbnVwIDogKCkgPT4ge1xuICAgICAgICAgIHJlZkNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmVmLmN1cnJlbnQgPSBpbnN0YW5jZTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH07XG4gICAgfSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNsZWFudXBzLmZvckVhY2gocmVmQ2xlYW51cCA9PiByZWZDbGVhbnVwID09IG51bGwgPyB2b2lkIDAgOiByZWZDbGVhbnVwKCkpO1xuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCByZWZzKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChyZWZzLmV2ZXJ5KHJlZiA9PiByZWYgPT0gbnVsbCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUgPT4ge1xuICAgICAgaWYgKGNsZWFudXBSZWYuY3VycmVudCkge1xuICAgICAgICBjbGVhbnVwUmVmLmN1cnJlbnQoKTtcbiAgICAgICAgY2xlYW51cFJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgY2xlYW51cFJlZi5jdXJyZW50ID0gcmVmRWZmZWN0KHZhbHVlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgcmVmcyk7XG59XG5cbmZ1bmN0aW9uIHNvcnRCeURvY3VtZW50UG9zaXRpb24oYSwgYikge1xuICBjb25zdCBwb3NpdGlvbiA9IGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYik7XG4gIGlmIChwb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HIHx8IHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9DT05UQUlORURfQlkpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcgfHwgcG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5TKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5jb25zdCBGbG9hdGluZ0xpc3RDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQoe1xuICByZWdpc3RlcjogKCkgPT4ge30sXG4gIHVucmVnaXN0ZXI6ICgpID0+IHt9LFxuICBtYXA6IC8qI19fUFVSRV9fKi9uZXcgTWFwKCksXG4gIGVsZW1lbnRzUmVmOiB7XG4gICAgY3VycmVudDogW11cbiAgfVxufSk7XG4vKipcbiAqIFByb3ZpZGVzIGNvbnRleHQgZm9yIGEgbGlzdCBvZiBpdGVtcyB3aXRoaW4gdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdMaXN0XG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nTGlzdChwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgZWxlbWVudHNSZWYsXG4gICAgbGFiZWxzUmVmXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgW25vZGVzLCBzZXROb2Rlc10gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBuZXcgU2V0KCkpO1xuICBjb25zdCByZWdpc3RlciA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIHNldE5vZGVzKHByZXZTZXQgPT4gbmV3IFNldChwcmV2U2V0KS5hZGQobm9kZSkpO1xuICB9LCBbXSk7XG4gIGNvbnN0IHVucmVnaXN0ZXIgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBzZXROb2RlcyhwcmV2U2V0ID0+IHtcbiAgICAgIGNvbnN0IHNldCA9IG5ldyBTZXQocHJldlNldCk7XG4gICAgICBzZXQuZGVsZXRlKG5vZGUpO1xuICAgICAgcmV0dXJuIHNldDtcbiAgICB9KTtcbiAgfSwgW10pO1xuICBjb25zdCBtYXAgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBuZXdNYXAgPSBuZXcgTWFwKCk7XG4gICAgY29uc3Qgc29ydGVkTm9kZXMgPSBBcnJheS5mcm9tKG5vZGVzLmtleXMoKSkuc29ydChzb3J0QnlEb2N1bWVudFBvc2l0aW9uKTtcbiAgICBzb3J0ZWROb2Rlcy5mb3JFYWNoKChub2RlLCBpbmRleCkgPT4ge1xuICAgICAgbmV3TWFwLnNldChub2RlLCBpbmRleCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld01hcDtcbiAgfSwgW25vZGVzXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KEZsb2F0aW5nTGlzdENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgcmVnaXN0ZXIsXG4gICAgICB1bnJlZ2lzdGVyLFxuICAgICAgbWFwLFxuICAgICAgZWxlbWVudHNSZWYsXG4gICAgICBsYWJlbHNSZWZcbiAgICB9KSwgW3JlZ2lzdGVyLCB1bnJlZ2lzdGVyLCBtYXAsIGVsZW1lbnRzUmVmLCBsYWJlbHNSZWZdKSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5cbiAgfSk7XG59XG4vKipcbiAqIFVzZWQgdG8gcmVnaXN0ZXIgYSBsaXN0IGl0ZW0gYW5kIGl0cyBpbmRleCAoRE9NIHBvc2l0aW9uKSBpbiB0aGVcbiAqIGBGbG9hdGluZ0xpc3RgLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nTGlzdCN1c2VsaXN0aXRlbVxuICovXG5mdW5jdGlvbiB1c2VMaXN0SXRlbShwcm9wcykge1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIGxhYmVsXG4gIH0gPSBwcm9wcztcbiAgY29uc3Qge1xuICAgIHJlZ2lzdGVyLFxuICAgIHVucmVnaXN0ZXIsXG4gICAgbWFwLFxuICAgIGVsZW1lbnRzUmVmLFxuICAgIGxhYmVsc1JlZlxuICB9ID0gUmVhY3QudXNlQ29udGV4dChGbG9hdGluZ0xpc3RDb250ZXh0KTtcbiAgY29uc3QgW2luZGV4LCBzZXRJbmRleF0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3QgY29tcG9uZW50UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCByZWYgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBjb21wb25lbnRSZWYuY3VycmVudCA9IG5vZGU7XG4gICAgaWYgKGluZGV4ICE9PSBudWxsKSB7XG4gICAgICBlbGVtZW50c1JlZi5jdXJyZW50W2luZGV4XSA9IG5vZGU7XG4gICAgICBpZiAobGFiZWxzUmVmKSB7XG4gICAgICAgIHZhciBfbm9kZSR0ZXh0Q29udGVudDtcbiAgICAgICAgY29uc3QgaXNMYWJlbERlZmluZWQgPSBsYWJlbCAhPT0gdW5kZWZpbmVkO1xuICAgICAgICBsYWJlbHNSZWYuY3VycmVudFtpbmRleF0gPSBpc0xhYmVsRGVmaW5lZCA/IGxhYmVsIDogKF9ub2RlJHRleHRDb250ZW50ID0gbm9kZSA9PSBudWxsID8gdm9pZCAwIDogbm9kZS50ZXh0Q29udGVudCkgIT0gbnVsbCA/IF9ub2RlJHRleHRDb250ZW50IDogbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtpbmRleCwgZWxlbWVudHNSZWYsIGxhYmVsc1JlZiwgbGFiZWxdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBub2RlID0gY29tcG9uZW50UmVmLmN1cnJlbnQ7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHJlZ2lzdGVyKG5vZGUpO1xuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgdW5yZWdpc3Rlcihub2RlKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbcmVnaXN0ZXIsIHVucmVnaXN0ZXJdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBpbmRleCA9IGNvbXBvbmVudFJlZi5jdXJyZW50ID8gbWFwLmdldChjb21wb25lbnRSZWYuY3VycmVudCkgOiBudWxsO1xuICAgIGlmIChpbmRleCAhPSBudWxsKSB7XG4gICAgICBzZXRJbmRleChpbmRleCk7XG4gICAgfVxuICB9LCBbbWFwXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgcmVmLFxuICAgIGluZGV4OiBpbmRleCA9PSBudWxsID8gLTEgOiBpbmRleFxuICB9KSwgW2luZGV4LCByZWZdKTtcbn1cblxuY29uc3QgRk9DVVNBQkxFX0FUVFJJQlVURSA9ICdkYXRhLWZsb2F0aW5nLXVpLWZvY3VzYWJsZSc7XG5jb25zdCBBQ1RJVkVfS0VZID0gJ2FjdGl2ZSc7XG5jb25zdCBTRUxFQ1RFRF9LRVkgPSAnc2VsZWN0ZWQnO1xuY29uc3QgQVJST1dfTEVGVCA9ICdBcnJvd0xlZnQnO1xuY29uc3QgQVJST1dfUklHSFQgPSAnQXJyb3dSaWdodCc7XG5jb25zdCBBUlJPV19VUCA9ICdBcnJvd1VwJztcbmNvbnN0IEFSUk9XX0RPV04gPSAnQXJyb3dEb3duJztcblxuZnVuY3Rpb24gcmVuZGVySnN4KHJlbmRlciwgY29tcHV0ZWRQcm9wcykge1xuICBpZiAodHlwZW9mIHJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiByZW5kZXIoY29tcHV0ZWRQcm9wcyk7XG4gIH1cbiAgaWYgKHJlbmRlcikge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KHJlbmRlciwgY29tcHV0ZWRQcm9wcyk7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goXCJkaXZcIiwge1xuICAgIC4uLmNvbXB1dGVkUHJvcHNcbiAgfSk7XG59XG5jb25zdCBDb21wb3NpdGVDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQoe1xuICBhY3RpdmVJbmRleDogMCxcbiAgb25OYXZpZ2F0ZTogKCkgPT4ge31cbn0pO1xuY29uc3QgaG9yaXpvbnRhbEtleXMgPSBbQVJST1dfTEVGVCwgQVJST1dfUklHSFRdO1xuY29uc3QgdmVydGljYWxLZXlzID0gW0FSUk9XX1VQLCBBUlJPV19ET1dOXTtcbmNvbnN0IGFsbEtleXMgPSBbLi4uaG9yaXpvbnRhbEtleXMsIC4uLnZlcnRpY2FsS2V5c107XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNpbmdsZSB0YWIgc3RvcCB3aG9zZSBpdGVtcyBhcmUgbmF2aWdhdGVkIGJ5IGFycm93IGtleXMsIHdoaWNoXG4gKiBwcm92aWRlcyBsaXN0IG5hdmlnYXRpb24gb3V0c2lkZSBvZiBmbG9hdGluZyBlbGVtZW50IGNvbnRleHRzLlxuICpcbiAqIFRoaXMgaXMgdXNlZnVsIHRvIGVuYWJsZSBuYXZpZ2F0aW9uIG9mIGEgbGlzdCBvZiBpdGVtcyB0aGF0IGFyZW7igJl0IHBhcnQgb2YgYVxuICogZmxvYXRpbmcgZWxlbWVudC4gQSBtZW51YmFyIGlzIGFuIGV4YW1wbGUgb2YgYSBjb21wb3NpdGUsIHdpdGggZWFjaCByZWZlcmVuY2VcbiAqIGVsZW1lbnQgYmVpbmcgYW4gaXRlbS5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9Db21wb3NpdGVcbiAqL1xuY29uc3QgQ29tcG9zaXRlID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gQ29tcG9zaXRlKHByb3BzLCBmb3J3YXJkZWRSZWYpIHtcbiAgY29uc3Qge1xuICAgIHJlbmRlcixcbiAgICBvcmllbnRhdGlvbiA9ICdib3RoJyxcbiAgICBsb29wID0gdHJ1ZSxcbiAgICBydGwgPSBmYWxzZSxcbiAgICBjb2xzID0gMSxcbiAgICBkaXNhYmxlZEluZGljZXMsXG4gICAgYWN0aXZlSW5kZXg6IGV4dGVybmFsQWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZTogZXh0ZXJuYWxTZXRBY3RpdmVJbmRleCxcbiAgICBpdGVtU2l6ZXMsXG4gICAgZGVuc2UgPSBmYWxzZSxcbiAgICAuLi5kb21Qcm9wc1xuICB9ID0gcHJvcHM7XG4gIGNvbnN0IFtpbnRlcm5hbEFjdGl2ZUluZGV4LCBpbnRlcm5hbFNldEFjdGl2ZUluZGV4XSA9IFJlYWN0LnVzZVN0YXRlKDApO1xuICBjb25zdCBhY3RpdmVJbmRleCA9IGV4dGVybmFsQWN0aXZlSW5kZXggIT0gbnVsbCA/IGV4dGVybmFsQWN0aXZlSW5kZXggOiBpbnRlcm5hbEFjdGl2ZUluZGV4O1xuICBjb25zdCBvbk5hdmlnYXRlID0gdXNlRWZmZWN0RXZlbnQoZXh0ZXJuYWxTZXRBY3RpdmVJbmRleCAhPSBudWxsID8gZXh0ZXJuYWxTZXRBY3RpdmVJbmRleCA6IGludGVybmFsU2V0QWN0aXZlSW5kZXgpO1xuICBjb25zdCBlbGVtZW50c1JlZiA9IFJlYWN0LnVzZVJlZihbXSk7XG4gIGNvbnN0IHJlbmRlckVsZW1lbnRQcm9wcyA9IHJlbmRlciAmJiB0eXBlb2YgcmVuZGVyICE9PSAnZnVuY3Rpb24nID8gcmVuZGVyLnByb3BzIDoge307XG4gIGNvbnN0IGNvbnRleHRWYWx1ZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBhY3RpdmVJbmRleCxcbiAgICBvbk5hdmlnYXRlXG4gIH0pLCBbYWN0aXZlSW5kZXgsIG9uTmF2aWdhdGVdKTtcbiAgY29uc3QgaXNHcmlkID0gY29scyA+IDE7XG4gIGZ1bmN0aW9uIGhhbmRsZUtleURvd24oZXZlbnQpIHtcbiAgICBpZiAoIWFsbEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkgcmV0dXJuO1xuICAgIGxldCBuZXh0SW5kZXggPSBhY3RpdmVJbmRleDtcbiAgICBjb25zdCBtaW5JbmRleCA9IGdldE1pbkxpc3RJbmRleChlbGVtZW50c1JlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBtYXhJbmRleCA9IGdldE1heExpc3RJbmRleChlbGVtZW50c1JlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBob3Jpem9udGFsRW5kS2V5ID0gcnRsID8gQVJST1dfTEVGVCA6IEFSUk9XX1JJR0hUO1xuICAgIGNvbnN0IGhvcml6b250YWxTdGFydEtleSA9IHJ0bCA/IEFSUk9XX1JJR0hUIDogQVJST1dfTEVGVDtcbiAgICBpZiAoaXNHcmlkKSB7XG4gICAgICBjb25zdCBzaXplcyA9IGl0ZW1TaXplcyB8fCBBcnJheS5mcm9tKHtcbiAgICAgICAgbGVuZ3RoOiBlbGVtZW50c1JlZi5jdXJyZW50Lmxlbmd0aFxuICAgICAgfSwgKCkgPT4gKHtcbiAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgIGhlaWdodDogMVxuICAgICAgfSkpO1xuICAgICAgLy8gVG8gY2FsY3VsYXRlIG1vdmVtZW50cyBvbiB0aGUgZ3JpZCwgd2UgdXNlIGh5cG90aGV0aWNhbCBjZWxsIGluZGljZXNcbiAgICAgIC8vIGFzIGlmIGV2ZXJ5IGl0ZW0gd2FzIDF4MSwgdGhlbiBjb252ZXJ0IGJhY2sgdG8gcmVhbCBpbmRpY2VzLlxuICAgICAgY29uc3QgY2VsbE1hcCA9IGNyZWF0ZUdyaWRDZWxsTWFwKHNpemVzLCBjb2xzLCBkZW5zZSk7XG4gICAgICBjb25zdCBtaW5HcmlkSW5kZXggPSBjZWxsTWFwLmZpbmRJbmRleChpbmRleCA9PiBpbmRleCAhPSBudWxsICYmICFpc0xpc3RJbmRleERpc2FibGVkKGVsZW1lbnRzUmVmLCBpbmRleCwgZGlzYWJsZWRJbmRpY2VzKSk7XG4gICAgICAvLyBsYXN0IGVuYWJsZWQgaW5kZXhcbiAgICAgIGNvbnN0IG1heEdyaWRJbmRleCA9IGNlbGxNYXAucmVkdWNlKChmb3VuZEluZGV4LCBpbmRleCwgY2VsbEluZGV4KSA9PiBpbmRleCAhPSBudWxsICYmICFpc0xpc3RJbmRleERpc2FibGVkKGVsZW1lbnRzUmVmLCBpbmRleCwgZGlzYWJsZWRJbmRpY2VzKSA/IGNlbGxJbmRleCA6IGZvdW5kSW5kZXgsIC0xKTtcbiAgICAgIGNvbnN0IG1heWJlTmV4dEluZGV4ID0gY2VsbE1hcFtnZXRHcmlkTmF2aWdhdGVkSW5kZXgoe1xuICAgICAgICBjdXJyZW50OiBjZWxsTWFwLm1hcChpdGVtSW5kZXggPT4gaXRlbUluZGV4ID8gZWxlbWVudHNSZWYuY3VycmVudFtpdGVtSW5kZXhdIDogbnVsbClcbiAgICAgIH0sIHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIG9yaWVudGF0aW9uLFxuICAgICAgICBsb29wLFxuICAgICAgICBydGwsXG4gICAgICAgIGNvbHMsXG4gICAgICAgIC8vIHRyZWF0IHVuZGVmaW5lZCAoZW1wdHkgZ3JpZCBzcGFjZXMpIGFzIGRpc2FibGVkIGluZGljZXMgc28gd2VcbiAgICAgICAgLy8gZG9uJ3QgZW5kIHVwIGluIHRoZW1cbiAgICAgICAgZGlzYWJsZWRJbmRpY2VzOiBnZXRHcmlkQ2VsbEluZGljZXMoWy4uLihkaXNhYmxlZEluZGljZXMgfHwgZWxlbWVudHNSZWYuY3VycmVudC5tYXAoKF8sIGluZGV4KSA9PiBpc0xpc3RJbmRleERpc2FibGVkKGVsZW1lbnRzUmVmLCBpbmRleCkgPyBpbmRleCA6IHVuZGVmaW5lZCkpLCB1bmRlZmluZWRdLCBjZWxsTWFwKSxcbiAgICAgICAgbWluSW5kZXg6IG1pbkdyaWRJbmRleCxcbiAgICAgICAgbWF4SW5kZXg6IG1heEdyaWRJbmRleCxcbiAgICAgICAgcHJldkluZGV4OiBnZXRHcmlkQ2VsbEluZGV4T2ZDb3JuZXIoYWN0aXZlSW5kZXggPiBtYXhJbmRleCA/IG1pbkluZGV4IDogYWN0aXZlSW5kZXgsIHNpemVzLCBjZWxsTWFwLCBjb2xzLFxuICAgICAgICAvLyB1c2UgYSBjb3JuZXIgbWF0Y2hpbmcgdGhlIGVkZ2UgY2xvc2VzdCB0byB0aGUgZGlyZWN0aW9uIHdlJ3JlXG4gICAgICAgIC8vIG1vdmluZyBpbiBzbyB3ZSBkb24ndCBlbmQgdXAgaW4gdGhlIHNhbWUgaXRlbS4gUHJlZmVyXG4gICAgICAgIC8vIHRvcC9sZWZ0IG92ZXIgYm90dG9tL3JpZ2h0LlxuICAgICAgICBldmVudC5rZXkgPT09IEFSUk9XX0RPV04gPyAnYmwnIDogZXZlbnQua2V5ID09PSBob3Jpem9udGFsRW5kS2V5ID8gJ3RyJyA6ICd0bCcpXG4gICAgICB9KV07XG4gICAgICBpZiAobWF5YmVOZXh0SW5kZXggIT0gbnVsbCkge1xuICAgICAgICBuZXh0SW5kZXggPSBtYXliZU5leHRJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdG9FbmRLZXlzID0ge1xuICAgICAgaG9yaXpvbnRhbDogW2hvcml6b250YWxFbmRLZXldLFxuICAgICAgdmVydGljYWw6IFtBUlJPV19ET1dOXSxcbiAgICAgIGJvdGg6IFtob3Jpem9udGFsRW5kS2V5LCBBUlJPV19ET1dOXVxuICAgIH1bb3JpZW50YXRpb25dO1xuICAgIGNvbnN0IHRvU3RhcnRLZXlzID0ge1xuICAgICAgaG9yaXpvbnRhbDogW2hvcml6b250YWxTdGFydEtleV0sXG4gICAgICB2ZXJ0aWNhbDogW0FSUk9XX1VQXSxcbiAgICAgIGJvdGg6IFtob3Jpem9udGFsU3RhcnRLZXksIEFSUk9XX1VQXVxuICAgIH1bb3JpZW50YXRpb25dO1xuICAgIGNvbnN0IHByZXZlbnRlZEtleXMgPSBpc0dyaWQgPyBhbGxLZXlzIDoge1xuICAgICAgaG9yaXpvbnRhbDogaG9yaXpvbnRhbEtleXMsXG4gICAgICB2ZXJ0aWNhbDogdmVydGljYWxLZXlzLFxuICAgICAgYm90aDogYWxsS2V5c1xuICAgIH1bb3JpZW50YXRpb25dO1xuICAgIGlmIChuZXh0SW5kZXggPT09IGFjdGl2ZUluZGV4ICYmIFsuLi50b0VuZEtleXMsIC4uLnRvU3RhcnRLZXlzXS5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICBpZiAobG9vcCAmJiBuZXh0SW5kZXggPT09IG1heEluZGV4ICYmIHRvRW5kS2V5cy5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICAgIG5leHRJbmRleCA9IG1pbkluZGV4O1xuICAgICAgfSBlbHNlIGlmIChsb29wICYmIG5leHRJbmRleCA9PT0gbWluSW5kZXggJiYgdG9TdGFydEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgICBuZXh0SW5kZXggPSBtYXhJbmRleDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRJbmRleCA9IGZpbmROb25EaXNhYmxlZExpc3RJbmRleChlbGVtZW50c1JlZiwge1xuICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IG5leHRJbmRleCxcbiAgICAgICAgICBkZWNyZW1lbnQ6IHRvU3RhcnRLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSksXG4gICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobmV4dEluZGV4ICE9PSBhY3RpdmVJbmRleCAmJiAhaXNJbmRleE91dE9mTGlzdEJvdW5kcyhlbGVtZW50c1JlZiwgbmV4dEluZGV4KSkge1xuICAgICAgdmFyIF9lbGVtZW50c1JlZiRjdXJyZW50JDtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgaWYgKHByZXZlbnRlZEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgICAgb25OYXZpZ2F0ZShuZXh0SW5kZXgpO1xuICAgICAgKF9lbGVtZW50c1JlZiRjdXJyZW50JCA9IGVsZW1lbnRzUmVmLmN1cnJlbnRbbmV4dEluZGV4XSkgPT0gbnVsbCB8fCBfZWxlbWVudHNSZWYkY3VycmVudCQuZm9jdXMoKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgY29tcHV0ZWRQcm9wcyA9IHtcbiAgICAuLi5kb21Qcm9wcyxcbiAgICAuLi5yZW5kZXJFbGVtZW50UHJvcHMsXG4gICAgcmVmOiBmb3J3YXJkZWRSZWYsXG4gICAgJ2FyaWEtb3JpZW50YXRpb24nOiBvcmllbnRhdGlvbiA9PT0gJ2JvdGgnID8gdW5kZWZpbmVkIDogb3JpZW50YXRpb24sXG4gICAgb25LZXlEb3duKGUpIHtcbiAgICAgIGRvbVByb3BzLm9uS2V5RG93biA9PSBudWxsIHx8IGRvbVByb3BzLm9uS2V5RG93bihlKTtcbiAgICAgIHJlbmRlckVsZW1lbnRQcm9wcy5vbktleURvd24gPT0gbnVsbCB8fCByZW5kZXJFbGVtZW50UHJvcHMub25LZXlEb3duKGUpO1xuICAgICAgaGFuZGxlS2V5RG93bihlKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KENvbXBvc2l0ZUNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogY29udGV4dFZhbHVlLFxuICAgIGNoaWxkcmVuOiAvKiNfX1BVUkVfXyovanN4KEZsb2F0aW5nTGlzdCwge1xuICAgICAgZWxlbWVudHNSZWY6IGVsZW1lbnRzUmVmLFxuICAgICAgY2hpbGRyZW46IHJlbmRlckpzeChyZW5kZXIsIGNvbXB1dGVkUHJvcHMpXG4gICAgfSlcbiAgfSk7XG59KTtcbi8qKlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0NvbXBvc2l0ZVxuICovXG5jb25zdCBDb21wb3NpdGVJdGVtID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gQ29tcG9zaXRlSXRlbShwcm9wcywgZm9yd2FyZGVkUmVmKSB7XG4gIGNvbnN0IHtcbiAgICByZW5kZXIsXG4gICAgLi4uZG9tUHJvcHNcbiAgfSA9IHByb3BzO1xuICBjb25zdCByZW5kZXJFbGVtZW50UHJvcHMgPSByZW5kZXIgJiYgdHlwZW9mIHJlbmRlciAhPT0gJ2Z1bmN0aW9uJyA/IHJlbmRlci5wcm9wcyA6IHt9O1xuICBjb25zdCB7XG4gICAgYWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZVxuICB9ID0gUmVhY3QudXNlQ29udGV4dChDb21wb3NpdGVDb250ZXh0KTtcbiAgY29uc3Qge1xuICAgIHJlZixcbiAgICBpbmRleFxuICB9ID0gdXNlTGlzdEl0ZW0oKTtcbiAgY29uc3QgbWVyZ2VkUmVmID0gdXNlTWVyZ2VSZWZzKFtyZWYsIGZvcndhcmRlZFJlZiwgcmVuZGVyRWxlbWVudFByb3BzLnJlZl0pO1xuICBjb25zdCBpc0FjdGl2ZSA9IGFjdGl2ZUluZGV4ID09PSBpbmRleDtcbiAgY29uc3QgY29tcHV0ZWRQcm9wcyA9IHtcbiAgICAuLi5kb21Qcm9wcyxcbiAgICAuLi5yZW5kZXJFbGVtZW50UHJvcHMsXG4gICAgcmVmOiBtZXJnZWRSZWYsXG4gICAgdGFiSW5kZXg6IGlzQWN0aXZlID8gMCA6IC0xLFxuICAgICdkYXRhLWFjdGl2ZSc6IGlzQWN0aXZlID8gJycgOiB1bmRlZmluZWQsXG4gICAgb25Gb2N1cyhlKSB7XG4gICAgICBkb21Qcm9wcy5vbkZvY3VzID09IG51bGwgfHwgZG9tUHJvcHMub25Gb2N1cyhlKTtcbiAgICAgIHJlbmRlckVsZW1lbnRQcm9wcy5vbkZvY3VzID09IG51bGwgfHwgcmVuZGVyRWxlbWVudFByb3BzLm9uRm9jdXMoZSk7XG4gICAgICBvbk5hdmlnYXRlKGluZGV4KTtcbiAgICB9XG4gIH07XG4gIHJldHVybiByZW5kZXJKc3gocmVuZGVyLCBjb21wdXRlZFByb3BzKTtcbn0pO1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vbXVpL21hdGVyaWFsLXVpL2lzc3Vlcy80MTE5MCNpc3N1ZWNvbW1lbnQtMjA0MDg3MzM3OVxuY29uc3QgU2FmZVJlYWN0ID0ge1xuICAuLi5SZWFjdFxufTtcblxubGV0IHNlcnZlckhhbmRvZmZDb21wbGV0ZSA9IGZhbHNlO1xubGV0IGNvdW50ID0gMDtcbmNvbnN0IGdlbklkID0gKCkgPT4gLy8gRW5zdXJlIHRoZSBpZCBpcyB1bmlxdWUgd2l0aCBtdWx0aXBsZSBpbmRlcGVuZGVudCB2ZXJzaW9ucyBvZiBGbG9hdGluZyBVSVxuLy8gb24gPFJlYWN0IDE4XG5cImZsb2F0aW5nLXVpLVwiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgNikgKyBjb3VudCsrO1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdJZCgpIHtcbiAgY29uc3QgW2lkLCBzZXRJZF0gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBzZXJ2ZXJIYW5kb2ZmQ29tcGxldGUgPyBnZW5JZCgpIDogdW5kZWZpbmVkKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaWQgPT0gbnVsbCkge1xuICAgICAgc2V0SWQoZ2VuSWQoKSk7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgW10pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHNlcnZlckhhbmRvZmZDb21wbGV0ZSA9IHRydWU7XG4gIH0sIFtdKTtcbiAgcmV0dXJuIGlkO1xufVxuY29uc3QgdXNlUmVhY3RJZCA9IFNhZmVSZWFjdC51c2VJZDtcblxuLyoqXG4gKiBVc2VzIFJlYWN0IDE4J3MgYnVpbHQtaW4gYHVzZUlkKClgIHdoZW4gYXZhaWxhYmxlLCBvciBmYWxscyBiYWNrIHRvIGFcbiAqIHNsaWdodGx5IGxlc3MgcGVyZm9ybWFudCAocmVxdWlyaW5nIGEgZG91YmxlIHJlbmRlcikgaW1wbGVtZW50YXRpb24gZm9yXG4gKiBlYXJsaWVyIFJlYWN0IHZlcnNpb25zLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3JlYWN0LXV0aWxzI3VzZWlkXG4gKi9cbmNvbnN0IHVzZUlkID0gdXNlUmVhY3RJZCB8fCB1c2VGbG9hdGluZ0lkO1xuXG5sZXQgZGV2TWVzc2FnZVNldDtcbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgZGV2TWVzc2FnZVNldCA9IC8qI19fUFVSRV9fKi9uZXcgU2V0KCk7XG59XG5mdW5jdGlvbiB3YXJuKCkge1xuICB2YXIgX2Rldk1lc3NhZ2VTZXQ7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBtZXNzYWdlcyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBtZXNzYWdlc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuICBjb25zdCBtZXNzYWdlID0gXCJGbG9hdGluZyBVSTogXCIgKyBtZXNzYWdlcy5qb2luKCcgJyk7XG4gIGlmICghKChfZGV2TWVzc2FnZVNldCA9IGRldk1lc3NhZ2VTZXQpICE9IG51bGwgJiYgX2Rldk1lc3NhZ2VTZXQuaGFzKG1lc3NhZ2UpKSkge1xuICAgIHZhciBfZGV2TWVzc2FnZVNldDI7XG4gICAgKF9kZXZNZXNzYWdlU2V0MiA9IGRldk1lc3NhZ2VTZXQpID09IG51bGwgfHwgX2Rldk1lc3NhZ2VTZXQyLmFkZChtZXNzYWdlKTtcbiAgICBjb25zb2xlLndhcm4obWVzc2FnZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVycm9yKCkge1xuICB2YXIgX2Rldk1lc3NhZ2VTZXQzO1xuICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIG1lc3NhZ2VzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgbWVzc2FnZXNbX2tleTJdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgfVxuICBjb25zdCBtZXNzYWdlID0gXCJGbG9hdGluZyBVSTogXCIgKyBtZXNzYWdlcy5qb2luKCcgJyk7XG4gIGlmICghKChfZGV2TWVzc2FnZVNldDMgPSBkZXZNZXNzYWdlU2V0KSAhPSBudWxsICYmIF9kZXZNZXNzYWdlU2V0My5oYXMobWVzc2FnZSkpKSB7XG4gICAgdmFyIF9kZXZNZXNzYWdlU2V0NDtcbiAgICAoX2Rldk1lc3NhZ2VTZXQ0ID0gZGV2TWVzc2FnZVNldCkgPT0gbnVsbCB8fCBfZGV2TWVzc2FnZVNldDQuYWRkKG1lc3NhZ2UpO1xuICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgcG9pbnRpbmcgYXJyb3cgdHJpYW5nbGUuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdBcnJvd1xuICovXG5jb25zdCBGbG9hdGluZ0Fycm93ID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRmxvYXRpbmdBcnJvdyhwcm9wcywgcmVmKSB7XG4gIGNvbnN0IHtcbiAgICBjb250ZXh0OiB7XG4gICAgICBwbGFjZW1lbnQsXG4gICAgICBlbGVtZW50czoge1xuICAgICAgICBmbG9hdGluZ1xuICAgICAgfSxcbiAgICAgIG1pZGRsZXdhcmVEYXRhOiB7XG4gICAgICAgIGFycm93LFxuICAgICAgICBzaGlmdFxuICAgICAgfVxuICAgIH0sXG4gICAgd2lkdGggPSAxNCxcbiAgICBoZWlnaHQgPSA3LFxuICAgIHRpcFJhZGl1cyA9IDAsXG4gICAgc3Ryb2tlV2lkdGggPSAwLFxuICAgIHN0YXRpY09mZnNldCxcbiAgICBzdHJva2UsXG4gICAgZCxcbiAgICBzdHlsZToge1xuICAgICAgdHJhbnNmb3JtLFxuICAgICAgLi4ucmVzdFN0eWxlXG4gICAgfSA9IHt9LFxuICAgIC4uLnJlc3RcbiAgfSA9IHByb3BzO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgaWYgKCFyZWYpIHtcbiAgICAgIHdhcm4oJ1RoZSBgcmVmYCBwcm9wIGlzIHJlcXVpcmVkIGZvciBgRmxvYXRpbmdBcnJvd2AuJyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IGNsaXBQYXRoSWQgPSB1c2VJZCgpO1xuICBjb25zdCBbaXNSVEwsIHNldElzUlRMXSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKTtcblxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmxvYXRpbmctdWkvZmxvYXRpbmctdWkvaXNzdWVzLzI5MzJcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWZsb2F0aW5nKSByZXR1cm47XG4gICAgY29uc3QgaXNSVEwgPSBnZXRDb21wdXRlZFN0eWxlKGZsb2F0aW5nKS5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgIGlmIChpc1JUTCkge1xuICAgICAgc2V0SXNSVEwodHJ1ZSk7XG4gICAgfVxuICB9LCBbZmxvYXRpbmddKTtcbiAgaWYgKCFmbG9hdGluZykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IFtzaWRlLCBhbGlnbm1lbnRdID0gcGxhY2VtZW50LnNwbGl0KCctJyk7XG4gIGNvbnN0IGlzVmVydGljYWxTaWRlID0gc2lkZSA9PT0gJ3RvcCcgfHwgc2lkZSA9PT0gJ2JvdHRvbSc7XG4gIGxldCBjb21wdXRlZFN0YXRpY09mZnNldCA9IHN0YXRpY09mZnNldDtcbiAgaWYgKGlzVmVydGljYWxTaWRlICYmIHNoaWZ0ICE9IG51bGwgJiYgc2hpZnQueCB8fCAhaXNWZXJ0aWNhbFNpZGUgJiYgc2hpZnQgIT0gbnVsbCAmJiBzaGlmdC55KSB7XG4gICAgY29tcHV0ZWRTdGF0aWNPZmZzZXQgPSBudWxsO1xuICB9XG5cbiAgLy8gU3Ryb2tlcyBtdXN0IGJlIGRvdWJsZSB0aGUgYm9yZGVyIHdpZHRoLCB0aGlzIGVuc3VyZXMgdGhlIHN0cm9rZSdzIHdpZHRoXG4gIC8vIHdvcmtzIGFzIHlvdSdkIGV4cGVjdC5cbiAgY29uc3QgY29tcHV0ZWRTdHJva2VXaWR0aCA9IHN0cm9rZVdpZHRoICogMjtcbiAgY29uc3QgaGFsZlN0cm9rZVdpZHRoID0gY29tcHV0ZWRTdHJva2VXaWR0aCAvIDI7XG4gIGNvbnN0IHN2Z1ggPSB3aWR0aCAvIDIgKiAodGlwUmFkaXVzIC8gLTggKyAxKTtcbiAgY29uc3Qgc3ZnWSA9IGhlaWdodCAvIDIgKiB0aXBSYWRpdXMgLyA0O1xuICBjb25zdCBpc0N1c3RvbVNoYXBlID0gISFkO1xuICBjb25zdCB5T2Zmc2V0UHJvcCA9IGNvbXB1dGVkU3RhdGljT2Zmc2V0ICYmIGFsaWdubWVudCA9PT0gJ2VuZCcgPyAnYm90dG9tJyA6ICd0b3AnO1xuICBsZXQgeE9mZnNldFByb3AgPSBjb21wdXRlZFN0YXRpY09mZnNldCAmJiBhbGlnbm1lbnQgPT09ICdlbmQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgaWYgKGNvbXB1dGVkU3RhdGljT2Zmc2V0ICYmIGlzUlRMKSB7XG4gICAgeE9mZnNldFByb3AgPSBhbGlnbm1lbnQgPT09ICdlbmQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgfVxuICBjb25zdCBhcnJvd1ggPSAoYXJyb3cgPT0gbnVsbCA/IHZvaWQgMCA6IGFycm93LngpICE9IG51bGwgPyBjb21wdXRlZFN0YXRpY09mZnNldCB8fCBhcnJvdy54IDogJyc7XG4gIGNvbnN0IGFycm93WSA9IChhcnJvdyA9PSBudWxsID8gdm9pZCAwIDogYXJyb3cueSkgIT0gbnVsbCA/IGNvbXB1dGVkU3RhdGljT2Zmc2V0IHx8IGFycm93LnkgOiAnJztcbiAgY29uc3QgZFZhbHVlID0gZCB8fCAnTTAsMCcgKyAoXCIgSFwiICsgd2lkdGgpICsgKFwiIExcIiArICh3aWR0aCAtIHN2Z1gpICsgXCIsXCIgKyAoaGVpZ2h0IC0gc3ZnWSkpICsgKFwiIFFcIiArIHdpZHRoIC8gMiArIFwiLFwiICsgaGVpZ2h0ICsgXCIgXCIgKyBzdmdYICsgXCIsXCIgKyAoaGVpZ2h0IC0gc3ZnWSkpICsgJyBaJztcbiAgY29uc3Qgcm90YXRpb24gPSB7XG4gICAgdG9wOiBpc0N1c3RvbVNoYXBlID8gJ3JvdGF0ZSgxODBkZWcpJyA6ICcnLFxuICAgIGxlZnQ6IGlzQ3VzdG9tU2hhcGUgPyAncm90YXRlKDkwZGVnKScgOiAncm90YXRlKC05MGRlZyknLFxuICAgIGJvdHRvbTogaXNDdXN0b21TaGFwZSA/ICcnIDogJ3JvdGF0ZSgxODBkZWcpJyxcbiAgICByaWdodDogaXNDdXN0b21TaGFwZSA/ICdyb3RhdGUoLTkwZGVnKScgOiAncm90YXRlKDkwZGVnKSdcbiAgfVtzaWRlXTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3hzKFwic3ZnXCIsIHtcbiAgICAuLi5yZXN0LFxuICAgIFwiYXJpYS1oaWRkZW5cIjogdHJ1ZSxcbiAgICByZWY6IHJlZixcbiAgICB3aWR0aDogaXNDdXN0b21TaGFwZSA/IHdpZHRoIDogd2lkdGggKyBjb21wdXRlZFN0cm9rZVdpZHRoLFxuICAgIGhlaWdodDogd2lkdGgsXG4gICAgdmlld0JveDogXCIwIDAgXCIgKyB3aWR0aCArIFwiIFwiICsgKGhlaWdodCA+IHdpZHRoID8gaGVpZ2h0IDogd2lkdGgpLFxuICAgIHN0eWxlOiB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgIFt4T2Zmc2V0UHJvcF06IGFycm93WCxcbiAgICAgIFt5T2Zmc2V0UHJvcF06IGFycm93WSxcbiAgICAgIFtzaWRlXTogaXNWZXJ0aWNhbFNpZGUgfHwgaXNDdXN0b21TaGFwZSA/ICcxMDAlJyA6IFwiY2FsYygxMDAlIC0gXCIgKyBjb21wdXRlZFN0cm9rZVdpZHRoIC8gMiArIFwicHgpXCIsXG4gICAgICB0cmFuc2Zvcm06IFtyb3RhdGlvbiwgdHJhbnNmb3JtXS5maWx0ZXIodCA9PiAhIXQpLmpvaW4oJyAnKSxcbiAgICAgIC4uLnJlc3RTdHlsZVxuICAgIH0sXG4gICAgY2hpbGRyZW46IFtjb21wdXRlZFN0cm9rZVdpZHRoID4gMCAmJiAvKiNfX1BVUkVfXyovanN4KFwicGF0aFwiLCB7XG4gICAgICBjbGlwUGF0aDogXCJ1cmwoI1wiICsgY2xpcFBhdGhJZCArIFwiKVwiLFxuICAgICAgZmlsbDogXCJub25lXCIsXG4gICAgICBzdHJva2U6IHN0cm9rZVxuICAgICAgLy8gQWNjb3VudCBmb3IgdGhlIHN0cm9rZSBvbiB0aGUgZmlsbCBwYXRoIHJlbmRlcmVkIGJlbG93LlxuICAgICAgLFxuICAgICAgc3Ryb2tlV2lkdGg6IGNvbXB1dGVkU3Ryb2tlV2lkdGggKyAoZCA/IDAgOiAxKSxcbiAgICAgIGQ6IGRWYWx1ZVxuICAgIH0pLCAvKiNfX1BVUkVfXyovanN4KFwicGF0aFwiLCB7XG4gICAgICBzdHJva2U6IGNvbXB1dGVkU3Ryb2tlV2lkdGggJiYgIWQgPyByZXN0LmZpbGwgOiAnbm9uZScsXG4gICAgICBkOiBkVmFsdWVcbiAgICB9KSwgLyojX19QVVJFX18qL2pzeChcImNsaXBQYXRoXCIsIHtcbiAgICAgIGlkOiBjbGlwUGF0aElkLFxuICAgICAgY2hpbGRyZW46IC8qI19fUFVSRV9fKi9qc3goXCJyZWN0XCIsIHtcbiAgICAgICAgeDogLWhhbGZTdHJva2VXaWR0aCxcbiAgICAgICAgeTogaGFsZlN0cm9rZVdpZHRoICogKGlzQ3VzdG9tU2hhcGUgPyAtMSA6IDEpLFxuICAgICAgICB3aWR0aDogd2lkdGggKyBjb21wdXRlZFN0cm9rZVdpZHRoLFxuICAgICAgICBoZWlnaHQ6IHdpZHRoXG4gICAgICB9KVxuICAgIH0pXVxuICB9KTtcbn0pO1xuXG5mdW5jdGlvbiBjcmVhdGVFdmVudEVtaXR0ZXIoKSB7XG4gIGNvbnN0IG1hcCA9IG5ldyBNYXAoKTtcbiAgcmV0dXJuIHtcbiAgICBlbWl0KGV2ZW50LCBkYXRhKSB7XG4gICAgICB2YXIgX21hcCRnZXQ7XG4gICAgICAoX21hcCRnZXQgPSBtYXAuZ2V0KGV2ZW50KSkgPT0gbnVsbCB8fCBfbWFwJGdldC5mb3JFYWNoKGxpc3RlbmVyID0+IGxpc3RlbmVyKGRhdGEpKTtcbiAgICB9LFxuICAgIG9uKGV2ZW50LCBsaXN0ZW5lcikge1xuICAgICAgaWYgKCFtYXAuaGFzKGV2ZW50KSkge1xuICAgICAgICBtYXAuc2V0KGV2ZW50LCBuZXcgU2V0KCkpO1xuICAgICAgfVxuICAgICAgbWFwLmdldChldmVudCkuYWRkKGxpc3RlbmVyKTtcbiAgICB9LFxuICAgIG9mZihldmVudCwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBfbWFwJGdldDI7XG4gICAgICAoX21hcCRnZXQyID0gbWFwLmdldChldmVudCkpID09IG51bGwgfHwgX21hcCRnZXQyLmRlbGV0ZShsaXN0ZW5lcik7XG4gICAgfVxuICB9O1xufVxuXG5jb25zdCBGbG9hdGluZ05vZGVDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5jb25zdCBGbG9hdGluZ1RyZWVDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGFyZW50IG5vZGUgaWQgZm9yIG5lc3RlZCBmbG9hdGluZyBlbGVtZW50cywgaWYgYXZhaWxhYmxlLlxuICogUmV0dXJucyBgbnVsbGAgZm9yIHRvcC1sZXZlbCBmbG9hdGluZyBlbGVtZW50cy5cbiAqL1xuY29uc3QgdXNlRmxvYXRpbmdQYXJlbnROb2RlSWQgPSAoKSA9PiB7XG4gIHZhciBfUmVhY3QkdXNlQ29udGV4dDtcbiAgcmV0dXJuICgoX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KEZsb2F0aW5nTm9kZUNvbnRleHQpKSA9PSBudWxsID8gdm9pZCAwIDogX1JlYWN0JHVzZUNvbnRleHQuaWQpIHx8IG51bGw7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG5lYXJlc3QgZmxvYXRpbmcgdHJlZSBjb250ZXh0LCBpZiBhdmFpbGFibGUuXG4gKi9cbmNvbnN0IHVzZUZsb2F0aW5nVHJlZSA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdUcmVlQ29udGV4dCk7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgbm9kZSBpbnRvIHRoZSBgRmxvYXRpbmdUcmVlYCwgcmV0dXJuaW5nIGl0cyBpZC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ1RyZWVcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdOb2RlSWQoY3VzdG9tUGFyZW50SWQpIHtcbiAgY29uc3QgaWQgPSB1c2VJZCgpO1xuICBjb25zdCB0cmVlID0gdXNlRmxvYXRpbmdUcmVlKCk7XG4gIGNvbnN0IHJlYWN0UGFyZW50SWQgPSB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCgpO1xuICBjb25zdCBwYXJlbnRJZCA9IGN1c3RvbVBhcmVudElkIHx8IHJlYWN0UGFyZW50SWQ7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFpZCkgcmV0dXJuO1xuICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICBpZCxcbiAgICAgIHBhcmVudElkXG4gICAgfTtcbiAgICB0cmVlID09IG51bGwgfHwgdHJlZS5hZGROb2RlKG5vZGUpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0cmVlID09IG51bGwgfHwgdHJlZS5yZW1vdmVOb2RlKG5vZGUpO1xuICAgIH07XG4gIH0sIFt0cmVlLCBpZCwgcGFyZW50SWRdKTtcbiAgcmV0dXJuIGlkO1xufVxuLyoqXG4gKiBQcm92aWRlcyBwYXJlbnQgbm9kZSBjb250ZXh0IGZvciBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdUcmVlXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nTm9kZShwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgaWRcbiAgfSA9IHByb3BzO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KEZsb2F0aW5nTm9kZUNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgaWQsXG4gICAgICBwYXJlbnRJZFxuICAgIH0pLCBbaWQsIHBhcmVudElkXSksXG4gICAgY2hpbGRyZW46IGNoaWxkcmVuXG4gIH0pO1xufVxuLyoqXG4gKiBQcm92aWRlcyBjb250ZXh0IGZvciBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMgd2hlbiB0aGV5IGFyZSBub3QgY2hpbGRyZW4gb2ZcbiAqIGVhY2ggb3RoZXIgb24gdGhlIERPTS5cbiAqIFRoaXMgaXMgbm90IG5lY2Vzc2FyeSBpbiBhbGwgY2FzZXMsIGV4Y2VwdCB3aGVuIHRoZXJlIG11c3QgYmUgZXhwbGljaXQgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIHBhcmVudCBhbmQgY2hpbGQgZmxvYXRpbmcgZWxlbWVudHMuIEl0IGlzIG5lY2Vzc2FyeSBmb3I6XG4gKiAtIFRoZSBgYnViYmxlc2Agb3B0aW9uIGluIHRoZSBgdXNlRGlzbWlzcygpYCBIb29rXG4gKiAtIE5lc3RlZCB2aXJ0dWFsIGxpc3QgbmF2aWdhdGlvblxuICogLSBOZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMgdGhhdCBlYWNoIG9wZW4gb24gaG92ZXJcbiAqIC0gQ3VzdG9tIGNvbW11bmljYXRpb24gYmV0d2VlbiBwYXJlbnQgYW5kIGNoaWxkIGZsb2F0aW5nIGVsZW1lbnRzXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdUcmVlXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nVHJlZShwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW5cbiAgfSA9IHByb3BzO1xuICBjb25zdCBub2Rlc1JlZiA9IFJlYWN0LnVzZVJlZihbXSk7XG4gIGNvbnN0IGFkZE5vZGUgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBub2Rlc1JlZi5jdXJyZW50ID0gWy4uLm5vZGVzUmVmLmN1cnJlbnQsIG5vZGVdO1xuICB9LCBbXSk7XG4gIGNvbnN0IHJlbW92ZU5vZGUgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBub2Rlc1JlZi5jdXJyZW50ID0gbm9kZXNSZWYuY3VycmVudC5maWx0ZXIobiA9PiBuICE9PSBub2RlKTtcbiAgfSwgW10pO1xuICBjb25zdCBbZXZlbnRzXSA9IFJlYWN0LnVzZVN0YXRlKCgpID0+IGNyZWF0ZUV2ZW50RW1pdHRlcigpKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goRmxvYXRpbmdUcmVlQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgICBub2Rlc1JlZixcbiAgICAgIGFkZE5vZGUsXG4gICAgICByZW1vdmVOb2RlLFxuICAgICAgZXZlbnRzXG4gICAgfSksIFthZGROb2RlLCByZW1vdmVOb2RlLCBldmVudHNdKSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUF0dHJpYnV0ZShuYW1lKSB7XG4gIHJldHVybiBcImRhdGEtZmxvYXRpbmctdWktXCIgKyBuYW1lO1xufVxuXG5mdW5jdGlvbiBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0UmVmKSB7XG4gIGlmICh0aW1lb3V0UmVmLmN1cnJlbnQgIT09IC0xKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgdGltZW91dFJlZi5jdXJyZW50ID0gLTE7XG4gIH1cbn1cblxuY29uc3Qgc2FmZVBvbHlnb25JZGVudGlmaWVyID0gLyojX19QVVJFX18qL2NyZWF0ZUF0dHJpYnV0ZSgnc2FmZS1wb2x5Z29uJyk7XG5mdW5jdGlvbiBnZXREZWxheSh2YWx1ZSwgcHJvcCwgcG9pbnRlclR5cGUpIHtcbiAgaWYgKHBvaW50ZXJUeXBlICYmICFpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlKSkge1xuICAgIHJldHVybiAwO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCByZXN1bHQgPSB2YWx1ZSgpO1xuICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gdm9pZCAwIDogcmVzdWx0W3Byb3BdO1xuICB9XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gdm9pZCAwIDogdmFsdWVbcHJvcF07XG59XG5mdW5jdGlvbiBnZXRSZXN0TXModmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB2YWx1ZSgpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cbi8qKlxuICogT3BlbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2hpbGUgaG92ZXJpbmcgb3ZlciB0aGUgcmVmZXJlbmNlIGVsZW1lbnQsIGxpa2VcbiAqIENTUyBgOmhvdmVyYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VIb3ZlclxuICovXG5mdW5jdGlvbiB1c2VIb3Zlcihjb250ZXh0LCBwcm9wcykge1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGRhdGFSZWYsXG4gICAgZXZlbnRzLFxuICAgIGVsZW1lbnRzXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgZGVsYXkgPSAwLFxuICAgIGhhbmRsZUNsb3NlID0gbnVsbCxcbiAgICBtb3VzZU9ubHkgPSBmYWxzZSxcbiAgICByZXN0TXMgPSAwLFxuICAgIG1vdmUgPSB0cnVlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIGNvbnN0IGhhbmRsZUNsb3NlUmVmID0gdXNlTGF0ZXN0UmVmKGhhbmRsZUNsb3NlKTtcbiAgY29uc3QgZGVsYXlSZWYgPSB1c2VMYXRlc3RSZWYoZGVsYXkpO1xuICBjb25zdCBvcGVuUmVmID0gdXNlTGF0ZXN0UmVmKG9wZW4pO1xuICBjb25zdCByZXN0TXNSZWYgPSB1c2VMYXRlc3RSZWYocmVzdE1zKTtcbiAgY29uc3QgcG9pbnRlclR5cGVSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgY29uc3QgdGltZW91dFJlZiA9IFJlYWN0LnVzZVJlZigtMSk7XG4gIGNvbnN0IGhhbmRsZXJSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgY29uc3QgcmVzdFRpbWVvdXRSZWYgPSBSZWFjdC51c2VSZWYoLTEpO1xuICBjb25zdCBibG9ja01vdXNlTW92ZVJlZiA9IFJlYWN0LnVzZVJlZih0cnVlKTtcbiAgY29uc3QgcGVyZm9ybWVkUG9pbnRlckV2ZW50c011dGF0aW9uUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgdW5iaW5kTW91c2VNb3ZlUmVmID0gUmVhY3QudXNlUmVmKCgpID0+IHt9KTtcbiAgY29uc3QgcmVzdFRpbWVvdXRQZW5kaW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgaXNIb3Zlck9wZW4gPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkb3BlbjtcbiAgICBjb25zdCB0eXBlID0gKF9kYXRhUmVmJGN1cnJlbnQkb3BlbiA9IGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JG9wZW4udHlwZTtcbiAgICByZXR1cm4gKHR5cGUgPT0gbnVsbCA/IHZvaWQgMCA6IHR5cGUuaW5jbHVkZXMoJ21vdXNlJykpICYmIHR5cGUgIT09ICdtb3VzZWRvd24nO1xuICB9LCBbZGF0YVJlZl0pO1xuXG4gIC8vIFdoZW4gY2xvc2luZyBiZWZvcmUgb3BlbmluZywgY2xlYXIgdGhlIGRlbGF5IHRpbWVvdXRzIHRvIGNhbmNlbCBpdFxuICAvLyBmcm9tIHNob3dpbmcuXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgZnVuY3Rpb24gb25PcGVuQ2hhbmdlKF9yZWYpIHtcbiAgICAgIGxldCB7XG4gICAgICAgIG9wZW5cbiAgICAgIH0gPSBfcmVmO1xuICAgICAgaWYgKCFvcGVuKSB7XG4gICAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICAgIGJsb2NrTW91c2VNb3ZlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICByZXN0VGltZW91dFBlbmRpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBldmVudHMub24oJ29wZW5jaGFuZ2UnLCBvbk9wZW5DaGFuZ2UpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBldmVudHMub2ZmKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICB9O1xuICB9LCBbZW5hYmxlZCwgZXZlbnRzXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKCFoYW5kbGVDbG9zZVJlZi5jdXJyZW50KSByZXR1cm47XG4gICAgaWYgKCFvcGVuKSByZXR1cm47XG4gICAgZnVuY3Rpb24gb25MZWF2ZShldmVudCkge1xuICAgICAgaWYgKGlzSG92ZXJPcGVuKCkpIHtcbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudCwgJ2hvdmVyJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGh0bWwgPSBnZXREb2N1bWVudCQxKGVsZW1lbnRzLmZsb2F0aW5nKS5kb2N1bWVudEVsZW1lbnQ7XG4gICAgaHRtbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25MZWF2ZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGh0bWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uTGVhdmUpO1xuICAgIH07XG4gIH0sIFtlbGVtZW50cy5mbG9hdGluZywgb3Blbiwgb25PcGVuQ2hhbmdlLCBlbmFibGVkLCBoYW5kbGVDbG9zZVJlZiwgaXNIb3Zlck9wZW5dKTtcbiAgY29uc3QgY2xvc2VXaXRoRGVsYXkgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAoZXZlbnQsIHJ1bkVsc2VCcmFuY2gsIHJlYXNvbikge1xuICAgIGlmIChydW5FbHNlQnJhbmNoID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkVsc2VCcmFuY2ggPSB0cnVlO1xuICAgIH1cbiAgICBpZiAocmVhc29uID09PSB2b2lkIDApIHtcbiAgICAgIHJlYXNvbiA9ICdob3Zlcic7XG4gICAgfVxuICAgIGNvbnN0IGNsb3NlRGVsYXkgPSBnZXREZWxheShkZWxheVJlZi5jdXJyZW50LCAnY2xvc2UnLCBwb2ludGVyVHlwZVJlZi5jdXJyZW50KTtcbiAgICBpZiAoY2xvc2VEZWxheSAmJiAhaGFuZGxlclJlZi5jdXJyZW50KSB7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0UmVmKTtcbiAgICAgIHRpbWVvdXRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsIHJlYXNvbiksIGNsb3NlRGVsYXkpO1xuICAgIH0gZWxzZSBpZiAocnVuRWxzZUJyYW5jaCkge1xuICAgICAgY2xlYXJUaW1lb3V0SWZTZXQodGltZW91dFJlZik7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCByZWFzb24pO1xuICAgIH1cbiAgfSwgW2RlbGF5UmVmLCBvbk9wZW5DaGFuZ2VdKTtcbiAgY29uc3QgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdW5iaW5kTW91c2VNb3ZlUmVmLmN1cnJlbnQoKTtcbiAgICBoYW5kbGVyUmVmLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gIH0pO1xuICBjb25zdCBjbGVhclBvaW50ZXJFdmVudHMgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgaWYgKHBlcmZvcm1lZFBvaW50ZXJFdmVudHNNdXRhdGlvblJlZi5jdXJyZW50KSB7XG4gICAgICBjb25zdCBib2R5ID0gZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZykuYm9keTtcbiAgICAgIGJvZHkuc3R5bGUucG9pbnRlckV2ZW50cyA9ICcnO1xuICAgICAgYm9keS5yZW1vdmVBdHRyaWJ1dGUoc2FmZVBvbHlnb25JZGVudGlmaWVyKTtcbiAgICAgIHBlcmZvcm1lZFBvaW50ZXJFdmVudHNNdXRhdGlvblJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgY29uc3QgaXNDbGlja0xpa2VPcGVuRXZlbnQgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgcmV0dXJuIGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgPyBbJ2NsaWNrJywgJ21vdXNlZG93biddLmluY2x1ZGVzKGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQudHlwZSkgOiBmYWxzZTtcbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXJpbmcgdGhlIG1vdXNlIGV2ZW50cyBvbiB0aGUgcmVmZXJlbmNlIGRpcmVjdGx5IHRvIGJ5cGFzcyBSZWFjdCdzXG4gIC8vIGRlbGVnYXRpb24gc3lzdGVtLiBJZiB0aGUgY3Vyc29yIHdhcyBvbiBhIGRpc2FibGVkIGVsZW1lbnQgYW5kIHRoZW4gZW50ZXJlZFxuICAvLyB0aGUgcmVmZXJlbmNlIChubyBnYXApLCBgbW91c2VlbnRlcmAgZG9lc24ndCBmaXJlIGluIHRoZSBkZWxlZ2F0aW9uIHN5c3RlbS5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBvblJlZmVyZW5jZU1vdXNlRW50ZXIoZXZlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgICAgYmxvY2tNb3VzZU1vdmVSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgaWYgKG1vdXNlT25seSAmJiAhaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZVJlZi5jdXJyZW50KSB8fCBnZXRSZXN0TXMocmVzdE1zUmVmLmN1cnJlbnQpID4gMCAmJiAhZ2V0RGVsYXkoZGVsYXlSZWYuY3VycmVudCwgJ29wZW4nKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBvcGVuRGVsYXkgPSBnZXREZWxheShkZWxheVJlZi5jdXJyZW50LCAnb3BlbicsIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQpO1xuICAgICAgaWYgKG9wZW5EZWxheSkge1xuICAgICAgICB0aW1lb3V0UmVmLmN1cnJlbnQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaWYgKCFvcGVuUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudCwgJ2hvdmVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBvcGVuRGVsYXkpO1xuICAgICAgfSBlbHNlIGlmICghb3Blbikge1xuICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQsICdob3ZlcicpO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBvblJlZmVyZW5jZU1vdXNlTGVhdmUoZXZlbnQpIHtcbiAgICAgIGlmIChpc0NsaWNrTGlrZU9wZW5FdmVudCgpKSB7XG4gICAgICAgIGNsZWFyUG9pbnRlckV2ZW50cygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB1bmJpbmRNb3VzZU1vdmVSZWYuY3VycmVudCgpO1xuICAgICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZyk7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICByZXN0VGltZW91dFBlbmRpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgaWYgKGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQgJiYgZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCkge1xuICAgICAgICAvLyBQcmV2ZW50IGNsZWFyaW5nIGBvblNjcm9sbE1vdXNlTGVhdmVgIHRpbWVvdXQuXG4gICAgICAgIGlmICghb3Blbikge1xuICAgICAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgICAgICB9XG4gICAgICAgIGhhbmRsZXJSZWYuY3VycmVudCA9IGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQoe1xuICAgICAgICAgIC4uLmRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQsXG4gICAgICAgICAgdHJlZSxcbiAgICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgICAgICAgb25DbG9zZSgpIHtcbiAgICAgICAgICAgIGNsZWFyUG9pbnRlckV2ZW50cygpO1xuICAgICAgICAgICAgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmICghaXNDbGlja0xpa2VPcGVuRXZlbnQoKSkge1xuICAgICAgICAgICAgICBjbG9zZVdpdGhEZWxheShldmVudCwgdHJ1ZSwgJ3NhZmUtcG9seWdvbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBoYW5kbGVyUmVmLmN1cnJlbnQ7XG4gICAgICAgIGRvYy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBoYW5kbGVyKTtcbiAgICAgICAgdW5iaW5kTW91c2VNb3ZlUmVmLmN1cnJlbnQgPSAoKSA9PiB7XG4gICAgICAgICAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGhhbmRsZXIpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEFsbG93IGludGVyYWN0aXZpdHkgd2l0aG91dCBgc2FmZVBvbHlnb25gIG9uIHRvdWNoIGRldmljZXMuIFdpdGggYVxuICAgICAgLy8gcG9pbnRlciwgYSBzaG9ydCBjbG9zZSBkZWxheSBpcyBhbiBhbHRlcm5hdGl2ZSwgc28gaXQgc2hvdWxkIHdvcmtcbiAgICAgIC8vIGNvbnNpc3RlbnRseS5cbiAgICAgIGNvbnN0IHNob3VsZENsb3NlID0gcG9pbnRlclR5cGVSZWYuY3VycmVudCA9PT0gJ3RvdWNoJyA/ICFjb250YWlucyQxKGVsZW1lbnRzLmZsb2F0aW5nLCBldmVudC5yZWxhdGVkVGFyZ2V0KSA6IHRydWU7XG4gICAgICBpZiAoc2hvdWxkQ2xvc2UpIHtcbiAgICAgICAgY2xvc2VXaXRoRGVsYXkoZXZlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVuc3VyZSB0aGUgZmxvYXRpbmcgZWxlbWVudCBjbG9zZXMgYWZ0ZXIgc2Nyb2xsaW5nIGV2ZW4gaWYgdGhlIHBvaW50ZXJcbiAgICAvLyBkaWQgbm90IG1vdmUuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2Rpc2N1c3Npb25zLzE2OTJcbiAgICBmdW5jdGlvbiBvblNjcm9sbE1vdXNlTGVhdmUoZXZlbnQpIHtcbiAgICAgIGlmIChpc0NsaWNrTGlrZU9wZW5FdmVudCgpKSByZXR1cm47XG4gICAgICBpZiAoIWRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpIHJldHVybjtcbiAgICAgIGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQgPT0gbnVsbCB8fCBoYW5kbGVDbG9zZVJlZi5jdXJyZW50KHtcbiAgICAgICAgLi4uZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCxcbiAgICAgICAgdHJlZSxcbiAgICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgICAgb25DbG9zZSgpIHtcbiAgICAgICAgICBjbGVhclBvaW50ZXJFdmVudHMoKTtcbiAgICAgICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgICAgIGlmICghaXNDbGlja0xpa2VPcGVuRXZlbnQoKSkge1xuICAgICAgICAgICAgY2xvc2VXaXRoRGVsYXkoZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSkoZXZlbnQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvbkZsb2F0aW5nTW91c2VFbnRlcigpIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRSZWYpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvbkZsb2F0aW5nTW91c2VMZWF2ZShldmVudCkge1xuICAgICAgaWYgKCFpc0NsaWNrTGlrZU9wZW5FdmVudCgpKSB7XG4gICAgICAgIGNsb3NlV2l0aERlbGF5KGV2ZW50LCBmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgY29uc3QgcmVmZXJlbmNlID0gZWxlbWVudHMuZG9tUmVmZXJlbmNlO1xuICAgICAgY29uc3QgZmxvYXRpbmcgPSBlbGVtZW50cy5mbG9hdGluZztcbiAgICAgIGlmIChvcGVuKSB7XG4gICAgICAgIHJlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25TY3JvbGxNb3VzZUxlYXZlKTtcbiAgICAgIH1cbiAgICAgIGlmIChtb3ZlKSB7XG4gICAgICAgIHJlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvblJlZmVyZW5jZU1vdXNlRW50ZXIsIHtcbiAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBvblJlZmVyZW5jZU1vdXNlRW50ZXIpO1xuICAgICAgcmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBvblJlZmVyZW5jZU1vdXNlTGVhdmUpO1xuICAgICAgaWYgKGZsb2F0aW5nKSB7XG4gICAgICAgIGZsb2F0aW5nLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBvblNjcm9sbE1vdXNlTGVhdmUpO1xuICAgICAgICBmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgb25GbG9hdGluZ01vdXNlRW50ZXIpO1xuICAgICAgICBmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25GbG9hdGluZ01vdXNlTGVhdmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKG9wZW4pIHtcbiAgICAgICAgICByZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uU2Nyb2xsTW91c2VMZWF2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vdmUpIHtcbiAgICAgICAgICByZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25SZWZlcmVuY2VNb3VzZUVudGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIG9uUmVmZXJlbmNlTW91c2VFbnRlcik7XG4gICAgICAgIHJlZmVyZW5jZS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25SZWZlcmVuY2VNb3VzZUxlYXZlKTtcbiAgICAgICAgaWYgKGZsb2F0aW5nKSB7XG4gICAgICAgICAgZmxvYXRpbmcucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uU2Nyb2xsTW91c2VMZWF2ZSk7XG4gICAgICAgICAgZmxvYXRpbmcucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIG9uRmxvYXRpbmdNb3VzZUVudGVyKTtcbiAgICAgICAgICBmbG9hdGluZy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25GbG9hdGluZ01vdXNlTGVhdmUpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgfSwgW2VsZW1lbnRzLCBlbmFibGVkLCBjb250ZXh0LCBtb3VzZU9ubHksIG1vdmUsIGNsb3NlV2l0aERlbGF5LCBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlciwgY2xlYXJQb2ludGVyRXZlbnRzLCBvbk9wZW5DaGFuZ2UsIG9wZW4sIG9wZW5SZWYsIHRyZWUsIGRlbGF5UmVmLCBoYW5kbGVDbG9zZVJlZiwgZGF0YVJlZiwgaXNDbGlja0xpa2VPcGVuRXZlbnQsIHJlc3RNc1JlZl0pO1xuXG4gIC8vIEJsb2NrIHBvaW50ZXItZXZlbnRzIG9mIGV2ZXJ5IGVsZW1lbnQgb3RoZXIgdGhhbiB0aGUgcmVmZXJlbmNlIGFuZCBmbG9hdGluZ1xuICAvLyB3aGlsZSB0aGUgZmxvYXRpbmcgZWxlbWVudCBpcyBvcGVuIGFuZCBoYXMgYSBgaGFuZGxlQ2xvc2VgIGhhbmRsZXIuIEFsc29cbiAgLy8gaGFuZGxlcyBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMTcyMlxuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIHZhciBfaGFuZGxlQ2xvc2VSZWYkY3VycmU7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKG9wZW4gJiYgKF9oYW5kbGVDbG9zZVJlZiRjdXJyZSA9IGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQpICE9IG51bGwgJiYgX2hhbmRsZUNsb3NlUmVmJGN1cnJlLl9fb3B0aW9ucy5ibG9ja1BvaW50ZXJFdmVudHMgJiYgaXNIb3Zlck9wZW4oKSkge1xuICAgICAgcGVyZm9ybWVkUG9pbnRlckV2ZW50c011dGF0aW9uUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgY29uc3QgZmxvYXRpbmdFbCA9IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgICAgaWYgKGlzRWxlbWVudChlbGVtZW50cy5kb21SZWZlcmVuY2UpICYmIGZsb2F0aW5nRWwpIHtcbiAgICAgICAgdmFyIF90cmVlJG5vZGVzUmVmJGN1cnJlbjtcbiAgICAgICAgY29uc3QgYm9keSA9IGdldERvY3VtZW50JDEoZWxlbWVudHMuZmxvYXRpbmcpLmJvZHk7XG4gICAgICAgIGJvZHkuc2V0QXR0cmlidXRlKHNhZmVQb2x5Z29uSWRlbnRpZmllciwgJycpO1xuICAgICAgICBjb25zdCByZWYgPSBlbGVtZW50cy5kb21SZWZlcmVuY2U7XG4gICAgICAgIGNvbnN0IHBhcmVudEZsb2F0aW5nID0gdHJlZSA9PSBudWxsIHx8IChfdHJlZSRub2Rlc1JlZiRjdXJyZW4gPSB0cmVlLm5vZGVzUmVmLmN1cnJlbnQuZmluZChub2RlID0+IG5vZGUuaWQgPT09IHBhcmVudElkKSkgPT0gbnVsbCB8fCAoX3RyZWUkbm9kZXNSZWYkY3VycmVuID0gX3RyZWUkbm9kZXNSZWYkY3VycmVuLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfdHJlZSRub2Rlc1JlZiRjdXJyZW4uZWxlbWVudHMuZmxvYXRpbmc7XG4gICAgICAgIGlmIChwYXJlbnRGbG9hdGluZykge1xuICAgICAgICAgIHBhcmVudEZsb2F0aW5nLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgICAgfVxuICAgICAgICBib2R5LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgICAgIHJlZi5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgICAgICBmbG9hdGluZ0VsLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgYm9keS5zdHlsZS5wb2ludGVyRXZlbnRzID0gJyc7XG4gICAgICAgICAgcmVmLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgICAgICBmbG9hdGluZ0VsLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuLCBwYXJlbnRJZCwgZWxlbWVudHMsIHRyZWUsIGhhbmRsZUNsb3NlUmVmLCBpc0hvdmVyT3Blbl0pO1xuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3Blbikge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgIHJlc3RUaW1lb3V0UGVuZGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgY2xlYXJQb2ludGVyRXZlbnRzKCk7XG4gICAgfVxuICB9LCBbb3BlbiwgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIsIGNsZWFyUG9pbnRlckV2ZW50c10pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgY2xlYXJUaW1lb3V0SWZTZXQodGltZW91dFJlZik7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICBjbGVhclBvaW50ZXJFdmVudHMoKTtcbiAgICB9O1xuICB9LCBbZW5hYmxlZCwgZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlciwgY2xlYXJQb2ludGVyRXZlbnRzXSk7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHNldFBvaW50ZXJSZWYoZXZlbnQpIHtcbiAgICAgIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQgPSBldmVudC5wb2ludGVyVHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG9uUG9pbnRlckRvd246IHNldFBvaW50ZXJSZWYsXG4gICAgICBvblBvaW50ZXJFbnRlcjogc2V0UG9pbnRlclJlZixcbiAgICAgIG9uTW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBuYXRpdmVFdmVudFxuICAgICAgICB9ID0gZXZlbnQ7XG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZU1vdXNlTW92ZSgpIHtcbiAgICAgICAgICBpZiAoIWJsb2NrTW91c2VNb3ZlUmVmLmN1cnJlbnQgJiYgIW9wZW5SZWYuY3VycmVudCkge1xuICAgICAgICAgICAgb25PcGVuQ2hhbmdlKHRydWUsIG5hdGl2ZUV2ZW50LCAnaG92ZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vdXNlT25seSAmJiAhaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZVJlZi5jdXJyZW50KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3BlbiB8fCBnZXRSZXN0TXMocmVzdE1zUmVmLmN1cnJlbnQpID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWdub3JlIGluc2lnbmlmaWNhbnQgbW92ZW1lbnRzIHRvIGFjY291bnQgZm9yIHRyZW1vcnMuXG4gICAgICAgIGlmIChyZXN0VGltZW91dFBlbmRpbmdSZWYuY3VycmVudCAmJiBldmVudC5tb3ZlbWVudFggKiogMiArIGV2ZW50Lm1vdmVtZW50WSAqKiAyIDwgMikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjbGVhclRpbWVvdXRJZlNldChyZXN0VGltZW91dFJlZik7XG4gICAgICAgIGlmIChwb2ludGVyVHlwZVJlZi5jdXJyZW50ID09PSAndG91Y2gnKSB7XG4gICAgICAgICAgaGFuZGxlTW91c2VNb3ZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdFRpbWVvdXRQZW5kaW5nUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgIHJlc3RUaW1lb3V0UmVmLmN1cnJlbnQgPSB3aW5kb3cuc2V0VGltZW91dChoYW5kbGVNb3VzZU1vdmUsIGdldFJlc3RNcyhyZXN0TXNSZWYuY3VycmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW21vdXNlT25seSwgb25PcGVuQ2hhbmdlLCBvcGVuLCBvcGVuUmVmLCByZXN0TXNSZWZdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2VcbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlXSk7XG59XG5cbmNvbnN0IE5PT1AgPSAoKSA9PiB7fTtcbmNvbnN0IEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7XG4gIGRlbGF5OiAwLFxuICBpbml0aWFsRGVsYXk6IDAsXG4gIHRpbWVvdXRNczogMCxcbiAgY3VycmVudElkOiBudWxsLFxuICBzZXRDdXJyZW50SWQ6IE5PT1AsXG4gIHNldFN0YXRlOiBOT09QLFxuICBpc0luc3RhbnRQaGFzZTogZmFsc2Vcbn0pO1xuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKiBVc2UgdGhlIHJldHVybiB2YWx1ZSBvZiBgdXNlRGVsYXlHcm91cCgpYCBpbnN0ZWFkLlxuICovXG5jb25zdCB1c2VEZWxheUdyb3VwQ29udGV4dCA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdEZWxheUdyb3VwQ29udGV4dCk7XG4vKipcbiAqIFByb3ZpZGVzIGNvbnRleHQgZm9yIGEgZ3JvdXAgb2YgZmxvYXRpbmcgZWxlbWVudHMgdGhhdCBzaG91bGQgc2hhcmUgYVxuICogYGRlbGF5YC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gRmxvYXRpbmdEZWxheUdyb3VwKHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBjaGlsZHJlbixcbiAgICBkZWxheSxcbiAgICB0aW1lb3V0TXMgPSAwXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgW3N0YXRlLCBzZXRTdGF0ZV0gPSBSZWFjdC51c2VSZWR1Y2VyKChwcmV2LCBuZXh0KSA9PiAoe1xuICAgIC4uLnByZXYsXG4gICAgLi4ubmV4dFxuICB9KSwge1xuICAgIGRlbGF5LFxuICAgIHRpbWVvdXRNcyxcbiAgICBpbml0aWFsRGVsYXk6IGRlbGF5LFxuICAgIGN1cnJlbnRJZDogbnVsbCxcbiAgICBpc0luc3RhbnRQaGFzZTogZmFsc2VcbiAgfSk7XG4gIGNvbnN0IGluaXRpYWxDdXJyZW50SWRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHNldEN1cnJlbnRJZCA9IFJlYWN0LnVzZUNhbGxiYWNrKGN1cnJlbnRJZCA9PiB7XG4gICAgc2V0U3RhdGUoe1xuICAgICAgY3VycmVudElkXG4gICAgfSk7XG4gIH0sIFtdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoc3RhdGUuY3VycmVudElkKSB7XG4gICAgICBpZiAoaW5pdGlhbEN1cnJlbnRJZFJlZi5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAgIGluaXRpYWxDdXJyZW50SWRSZWYuY3VycmVudCA9IHN0YXRlLmN1cnJlbnRJZDtcbiAgICAgIH0gZWxzZSBpZiAoIXN0YXRlLmlzSW5zdGFudFBoYXNlKSB7XG4gICAgICAgIHNldFN0YXRlKHtcbiAgICAgICAgICBpc0luc3RhbnRQaGFzZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLmlzSW5zdGFudFBoYXNlKSB7XG4gICAgICAgIHNldFN0YXRlKHtcbiAgICAgICAgICBpc0luc3RhbnRQaGFzZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpbml0aWFsQ3VycmVudElkUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIH1cbiAgfSwgW3N0YXRlLmN1cnJlbnRJZCwgc3RhdGUuaXNJbnN0YW50UGhhc2VdKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goRmxvYXRpbmdEZWxheUdyb3VwQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIHNldFN0YXRlLFxuICAgICAgc2V0Q3VycmVudElkXG4gICAgfSksIFtzdGF0ZSwgc2V0Q3VycmVudElkXSksXG4gICAgY2hpbGRyZW46IGNoaWxkcmVuXG4gIH0pO1xufVxuLyoqXG4gKiBFbmFibGVzIGdyb3VwaW5nIHdoZW4gY2FsbGVkIGluc2lkZSBhIGNvbXBvbmVudCB0aGF0J3MgYSBjaGlsZCBvZiBhXG4gKiBgRmxvYXRpbmdEZWxheUdyb3VwYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gdXNlRGVsYXlHcm91cChjb250ZXh0LCBvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zID09PSB2b2lkIDApIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGZsb2F0aW5nSWRcbiAgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtcbiAgICBpZDogb3B0aW9uSWQsXG4gICAgZW5hYmxlZCA9IHRydWVcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGlkID0gb3B0aW9uSWQgIT0gbnVsbCA/IG9wdGlvbklkIDogZmxvYXRpbmdJZDtcbiAgY29uc3QgZ3JvdXBDb250ZXh0ID0gdXNlRGVsYXlHcm91cENvbnRleHQoKTtcbiAgY29uc3Qge1xuICAgIGN1cnJlbnRJZCxcbiAgICBzZXRDdXJyZW50SWQsXG4gICAgaW5pdGlhbERlbGF5LFxuICAgIHNldFN0YXRlLFxuICAgIHRpbWVvdXRNc1xuICB9ID0gZ3JvdXBDb250ZXh0O1xuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmICghY3VycmVudElkKSByZXR1cm47XG4gICAgc2V0U3RhdGUoe1xuICAgICAgZGVsYXk6IHtcbiAgICAgICAgb3BlbjogMSxcbiAgICAgICAgY2xvc2U6IGdldERlbGF5KGluaXRpYWxEZWxheSwgJ2Nsb3NlJylcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoY3VycmVudElkICE9PSBpZCkge1xuICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlKTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBpZCwgb25PcGVuQ2hhbmdlLCBzZXRTdGF0ZSwgY3VycmVudElkLCBpbml0aWFsRGVsYXldKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBmdW5jdGlvbiB1bnNldCgpIHtcbiAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSk7XG4gICAgICBzZXRTdGF0ZSh7XG4gICAgICAgIGRlbGF5OiBpbml0aWFsRGVsYXksXG4gICAgICAgIGN1cnJlbnRJZDogbnVsbFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmICghY3VycmVudElkKSByZXR1cm47XG4gICAgaWYgKCFvcGVuICYmIGN1cnJlbnRJZCA9PT0gaWQpIHtcbiAgICAgIGlmICh0aW1lb3V0TXMpIHtcbiAgICAgICAgY29uc3QgdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KHVuc2V0LCB0aW1lb3V0TXMpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHVuc2V0KCk7XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgb3Blbiwgc2V0U3RhdGUsIGN1cnJlbnRJZCwgaWQsIG9uT3BlbkNoYW5nZSwgaW5pdGlhbERlbGF5LCB0aW1lb3V0TXNdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoc2V0Q3VycmVudElkID09PSBOT09QIHx8ICFvcGVuKSByZXR1cm47XG4gICAgc2V0Q3VycmVudElkKGlkKTtcbiAgfSwgW2VuYWJsZWQsIG9wZW4sIHNldEN1cnJlbnRJZCwgaWRdKTtcbiAgcmV0dXJuIGdyb3VwQ29udGV4dDtcbn1cblxuY29uc3QgTmV4dEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7XG4gIGhhc1Byb3ZpZGVyOiBmYWxzZSxcbiAgdGltZW91dE1zOiAwLFxuICBkZWxheVJlZjoge1xuICAgIGN1cnJlbnQ6IDBcbiAgfSxcbiAgaW5pdGlhbERlbGF5UmVmOiB7XG4gICAgY3VycmVudDogMFxuICB9LFxuICB0aW1lb3V0SWRSZWY6IHtcbiAgICBjdXJyZW50OiAtMVxuICB9LFxuICBjdXJyZW50SWRSZWY6IHtcbiAgICBjdXJyZW50OiBudWxsXG4gIH0sXG4gIGN1cnJlbnRDb250ZXh0UmVmOiB7XG4gICAgY3VycmVudDogbnVsbFxuICB9XG59KTtcbi8qKlxuICogRXhwZXJpbWVudGFsIG5leHQgdmVyc2lvbiBvZiBgRmxvYXRpbmdEZWxheUdyb3VwYCB0byBiZWNvbWUgdGhlIGRlZmF1bHRcbiAqIGluIHRoZSBmdXR1cmUuIFRoaXMgY29tcG9uZW50IGlzIG5vdCB5ZXQgc3RhYmxlLlxuICogUHJvdmlkZXMgY29udGV4dCBmb3IgYSBncm91cCBvZiBmbG9hdGluZyBlbGVtZW50cyB0aGF0IHNob3VsZCBzaGFyZSBhXG4gKiBgZGVsYXlgLiBVbmxpa2UgYEZsb2F0aW5nRGVsYXlHcm91cGAsIGB1c2VOZXh0RGVsYXlHcm91cGAgd2l0aCB0aGlzXG4gKiBjb21wb25lbnQgZG9lcyBub3QgY2F1c2UgYSByZS1yZW5kZXIgb2YgdW5yZWxhdGVkIGNvbnN1bWVycyBvZiB0aGVcbiAqIGNvbnRleHQgd2hlbiB0aGUgZGVsYXkgY2hhbmdlcy5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gTmV4dEZsb2F0aW5nRGVsYXlHcm91cChwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgZGVsYXksXG4gICAgdGltZW91dE1zID0gMFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGRlbGF5UmVmID0gUmVhY3QudXNlUmVmKGRlbGF5KTtcbiAgY29uc3QgaW5pdGlhbERlbGF5UmVmID0gUmVhY3QudXNlUmVmKGRlbGF5KTtcbiAgY29uc3QgY3VycmVudElkUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBjdXJyZW50Q29udGV4dFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgdGltZW91dElkUmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9qc3goTmV4dEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgaGFzUHJvdmlkZXI6IHRydWUsXG4gICAgICBkZWxheVJlZixcbiAgICAgIGluaXRpYWxEZWxheVJlZixcbiAgICAgIGN1cnJlbnRJZFJlZixcbiAgICAgIHRpbWVvdXRNcyxcbiAgICAgIGN1cnJlbnRDb250ZXh0UmVmLFxuICAgICAgdGltZW91dElkUmVmXG4gICAgfSksIFt0aW1lb3V0TXNdKSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5cbiAgfSk7XG59XG4vKipcbiAqIEVuYWJsZXMgZ3JvdXBpbmcgd2hlbiBjYWxsZWQgaW5zaWRlIGEgY29tcG9uZW50IHRoYXQncyBhIGNoaWxkIG9mIGFcbiAqIGBOZXh0RmxvYXRpbmdEZWxheUdyb3VwYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gdXNlTmV4dERlbGF5R3JvdXAoY29udGV4dCwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBmbG9hdGluZ0lkXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWVcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGdyb3VwQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoTmV4dEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQpO1xuICBjb25zdCB7XG4gICAgY3VycmVudElkUmVmLFxuICAgIGRlbGF5UmVmLFxuICAgIHRpbWVvdXRNcyxcbiAgICBpbml0aWFsRGVsYXlSZWYsXG4gICAgY3VycmVudENvbnRleHRSZWYsXG4gICAgaGFzUHJvdmlkZXIsXG4gICAgdGltZW91dElkUmVmXG4gIH0gPSBncm91cENvbnRleHQ7XG4gIGNvbnN0IFtpc0luc3RhbnRQaGFzZSwgc2V0SXNJbnN0YW50UGhhc2VdID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpO1xuICB1c2VNb2Rlcm5MYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHVuc2V0KCkge1xuICAgICAgdmFyIF9jdXJyZW50Q29udGV4dFJlZiRjdTtcbiAgICAgIHNldElzSW5zdGFudFBoYXNlKGZhbHNlKTtcbiAgICAgIChfY3VycmVudENvbnRleHRSZWYkY3UgPSBjdXJyZW50Q29udGV4dFJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9jdXJyZW50Q29udGV4dFJlZiRjdS5zZXRJc0luc3RhbnRQaGFzZShmYWxzZSk7XG4gICAgICBjdXJyZW50SWRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBjdXJyZW50Q29udGV4dFJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIGRlbGF5UmVmLmN1cnJlbnQgPSBpbml0aWFsRGVsYXlSZWYuY3VycmVudDtcbiAgICB9XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKCFjdXJyZW50SWRSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgIGlmICghb3BlbiAmJiBjdXJyZW50SWRSZWYuY3VycmVudCA9PT0gZmxvYXRpbmdJZCkge1xuICAgICAgc2V0SXNJbnN0YW50UGhhc2UoZmFsc2UpO1xuICAgICAgaWYgKHRpbWVvdXRNcykge1xuICAgICAgICB0aW1lb3V0SWRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KHVuc2V0LCB0aW1lb3V0TXMpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWRSZWYuY3VycmVudCk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB1bnNldCgpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGZsb2F0aW5nSWQsIGN1cnJlbnRJZFJlZiwgZGVsYXlSZWYsIHRpbWVvdXRNcywgaW5pdGlhbERlbGF5UmVmLCBjdXJyZW50Q29udGV4dFJlZiwgdGltZW91dElkUmVmXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKCFvcGVuKSByZXR1cm47XG4gICAgY29uc3QgcHJldkNvbnRleHQgPSBjdXJyZW50Q29udGV4dFJlZi5jdXJyZW50O1xuICAgIGNvbnN0IHByZXZJZCA9IGN1cnJlbnRJZFJlZi5jdXJyZW50O1xuICAgIGN1cnJlbnRDb250ZXh0UmVmLmN1cnJlbnQgPSB7XG4gICAgICBvbk9wZW5DaGFuZ2UsXG4gICAgICBzZXRJc0luc3RhbnRQaGFzZVxuICAgIH07XG4gICAgY3VycmVudElkUmVmLmN1cnJlbnQgPSBmbG9hdGluZ0lkO1xuICAgIGRlbGF5UmVmLmN1cnJlbnQgPSB7XG4gICAgICBvcGVuOiAwLFxuICAgICAgY2xvc2U6IGdldERlbGF5KGluaXRpYWxEZWxheVJlZi5jdXJyZW50LCAnY2xvc2UnKVxuICAgIH07XG4gICAgaWYgKHByZXZJZCAhPT0gbnVsbCAmJiBwcmV2SWQgIT09IGZsb2F0aW5nSWQpIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRJZFJlZik7XG4gICAgICBzZXRJc0luc3RhbnRQaGFzZSh0cnVlKTtcbiAgICAgIHByZXZDb250ZXh0ID09IG51bGwgfHwgcHJldkNvbnRleHQuc2V0SXNJbnN0YW50UGhhc2UodHJ1ZSk7XG4gICAgICBwcmV2Q29udGV4dCA9PSBudWxsIHx8IHByZXZDb250ZXh0Lm9uT3BlbkNoYW5nZShmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldElzSW5zdGFudFBoYXNlKGZhbHNlKTtcbiAgICAgIHByZXZDb250ZXh0ID09IG51bGwgfHwgcHJldkNvbnRleHQuc2V0SXNJbnN0YW50UGhhc2UoZmFsc2UpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGZsb2F0aW5nSWQsIG9uT3BlbkNoYW5nZSwgY3VycmVudElkUmVmLCBkZWxheVJlZiwgdGltZW91dE1zLCBpbml0aWFsRGVsYXlSZWYsIGN1cnJlbnRDb250ZXh0UmVmLCB0aW1lb3V0SWRSZWZdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY3VycmVudENvbnRleHRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfTtcbiAgfSwgW2N1cnJlbnRDb250ZXh0UmVmXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgaGFzUHJvdmlkZXIsXG4gICAgZGVsYXlSZWYsXG4gICAgaXNJbnN0YW50UGhhc2VcbiAgfSksIFtoYXNQcm92aWRlciwgZGVsYXlSZWYsIGlzSW5zdGFudFBoYXNlXSk7XG59XG5cbmxldCByYWZJZCA9IDA7XG5mdW5jdGlvbiBlbnF1ZXVlRm9jdXMoZWwsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgcHJldmVudFNjcm9sbCA9IGZhbHNlLFxuICAgIGNhbmNlbFByZXZpb3VzID0gdHJ1ZSxcbiAgICBzeW5jID0gZmFsc2VcbiAgfSA9IG9wdGlvbnM7XG4gIGNhbmNlbFByZXZpb3VzICYmIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZklkKTtcbiAgY29uc3QgZXhlYyA9ICgpID0+IGVsID09IG51bGwgPyB2b2lkIDAgOiBlbC5mb2N1cyh7XG4gICAgcHJldmVudFNjcm9sbFxuICB9KTtcbiAgaWYgKHN5bmMpIHtcbiAgICBleGVjKCk7XG4gIH0gZWxzZSB7XG4gICAgcmFmSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZXhlYyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udGFpbnMocGFyZW50LCBjaGlsZCkge1xuICBpZiAoIXBhcmVudCB8fCAhY2hpbGQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgcm9vdE5vZGUgPSBjaGlsZC5nZXRSb290Tm9kZSA9PSBudWxsID8gdm9pZCAwIDogY2hpbGQuZ2V0Um9vdE5vZGUoKTtcblxuICAvLyBGaXJzdCwgYXR0ZW1wdCB3aXRoIGZhc3RlciBuYXRpdmUgbWV0aG9kXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyB0aGVuIGZhbGxiYWNrIHRvIGN1c3RvbSBpbXBsZW1lbnRhdGlvbiB3aXRoIFNoYWRvdyBET00gc3VwcG9ydFxuICBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgIGxldCBuZXh0ID0gY2hpbGQ7XG4gICAgd2hpbGUgKG5leHQpIHtcbiAgICAgIGlmIChwYXJlbnQgPT09IG5leHQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBuZXh0ID0gbmV4dC5wYXJlbnROb2RlIHx8IG5leHQuaG9zdDtcbiAgICB9XG4gIH1cblxuICAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG4gIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGdldFRhcmdldChldmVudCkge1xuICBpZiAoJ2NvbXBvc2VkUGF0aCcgaW4gZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQuY29tcG9zZWRQYXRoKClbMF07XG4gIH1cblxuICAvLyBUUyB0aGlua3MgYGV2ZW50YCBpcyBvZiB0eXBlIG5ldmVyIGFzIGl0IGFzc3VtZXMgYWxsIGJyb3dzZXJzIHN1cHBvcnRcbiAgLy8gYGNvbXBvc2VkUGF0aCgpYCwgYnV0IGJyb3dzZXJzIHdpdGhvdXQgc2hhZG93IERPTSBkb24ndC5cbiAgcmV0dXJuIGV2ZW50LnRhcmdldDtcbn1cbmZ1bmN0aW9uIGdldERvY3VtZW50KG5vZGUpIHtcbiAgcmV0dXJuIChub2RlID09IG51bGwgPyB2b2lkIDAgOiBub2RlLm93bmVyRG9jdW1lbnQpIHx8IGRvY3VtZW50O1xufVxuXG4vLyBNb2RpZmllZCB0byBhZGQgY29uZGl0aW9uYWwgYGFyaWEtaGlkZGVuYCBzdXBwb3J0OlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RoZUthc2hleS9hcmlhLWhpZGRlbi9ibG9iLzkyMjBjOGY0YTRmZDM1ZjYzYmVlNTUxMGE5ZjQxYTM3MjY0MzgyZDQvc3JjL2luZGV4LnRzXG5sZXQgY291bnRlck1hcCA9IC8qI19fUFVSRV9fKi9uZXcgV2Vha01hcCgpO1xubGV0IHVuY29udHJvbGxlZEVsZW1lbnRzU2V0ID0gLyojX19QVVJFX18qL25ldyBXZWFrU2V0KCk7XG5sZXQgbWFya2VyTWFwID0ge307XG5sZXQgbG9ja0NvdW50JDEgPSAwO1xuY29uc3Qgc3VwcG9ydHNJbmVydCA9ICgpID0+IHR5cGVvZiBIVE1MRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2luZXJ0JyBpbiBIVE1MRWxlbWVudC5wcm90b3R5cGU7XG5jb25zdCB1bndyYXBIb3N0ID0gbm9kZSA9PiBub2RlICYmIChub2RlLmhvc3QgfHwgdW53cmFwSG9zdChub2RlLnBhcmVudE5vZGUpKTtcbmNvbnN0IGNvcnJlY3RFbGVtZW50cyA9IChwYXJlbnQsIHRhcmdldHMpID0+IHRhcmdldHMubWFwKHRhcmdldCA9PiB7XG4gIGlmIChwYXJlbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbiAgY29uc3QgY29ycmVjdGVkVGFyZ2V0ID0gdW53cmFwSG9zdCh0YXJnZXQpO1xuICBpZiAocGFyZW50LmNvbnRhaW5zKGNvcnJlY3RlZFRhcmdldCkpIHtcbiAgICByZXR1cm4gY29ycmVjdGVkVGFyZ2V0O1xuICB9XG4gIHJldHVybiBudWxsO1xufSkuZmlsdGVyKHggPT4geCAhPSBudWxsKTtcbmZ1bmN0aW9uIGFwcGx5QXR0cmlidXRlVG9PdGhlcnModW5jb3JyZWN0ZWRBdm9pZEVsZW1lbnRzLCBib2R5LCBhcmlhSGlkZGVuLCBpbmVydCkge1xuICBjb25zdCBtYXJrZXJOYW1lID0gJ2RhdGEtZmxvYXRpbmctdWktaW5lcnQnO1xuICBjb25zdCBjb250cm9sQXR0cmlidXRlID0gaW5lcnQgPyAnaW5lcnQnIDogYXJpYUhpZGRlbiA/ICdhcmlhLWhpZGRlbicgOiBudWxsO1xuICBjb25zdCBhdm9pZEVsZW1lbnRzID0gY29ycmVjdEVsZW1lbnRzKGJvZHksIHVuY29ycmVjdGVkQXZvaWRFbGVtZW50cyk7XG4gIGNvbnN0IGVsZW1lbnRzVG9LZWVwID0gbmV3IFNldCgpO1xuICBjb25zdCBlbGVtZW50c1RvU3RvcCA9IG5ldyBTZXQoYXZvaWRFbGVtZW50cyk7XG4gIGNvbnN0IGhpZGRlbkVsZW1lbnRzID0gW107XG4gIGlmICghbWFya2VyTWFwW21hcmtlck5hbWVdKSB7XG4gICAgbWFya2VyTWFwW21hcmtlck5hbWVdID0gbmV3IFdlYWtNYXAoKTtcbiAgfVxuICBjb25zdCBtYXJrZXJDb3VudGVyID0gbWFya2VyTWFwW21hcmtlck5hbWVdO1xuICBhdm9pZEVsZW1lbnRzLmZvckVhY2goa2VlcCk7XG4gIGRlZXAoYm9keSk7XG4gIGVsZW1lbnRzVG9LZWVwLmNsZWFyKCk7XG4gIGZ1bmN0aW9uIGtlZXAoZWwpIHtcbiAgICBpZiAoIWVsIHx8IGVsZW1lbnRzVG9LZWVwLmhhcyhlbCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZWxlbWVudHNUb0tlZXAuYWRkKGVsKTtcbiAgICBlbC5wYXJlbnROb2RlICYmIGtlZXAoZWwucGFyZW50Tm9kZSk7XG4gIH1cbiAgZnVuY3Rpb24gZGVlcChwYXJlbnQpIHtcbiAgICBpZiAoIXBhcmVudCB8fCBlbGVtZW50c1RvU3RvcC5oYXMocGFyZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBbXS5mb3JFYWNoLmNhbGwocGFyZW50LmNoaWxkcmVuLCBub2RlID0+IHtcbiAgICAgIGlmIChnZXROb2RlTmFtZShub2RlKSA9PT0gJ3NjcmlwdCcpIHJldHVybjtcbiAgICAgIGlmIChlbGVtZW50c1RvS2VlcC5oYXMobm9kZSkpIHtcbiAgICAgICAgZGVlcChub2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGF0dHIgPSBjb250cm9sQXR0cmlidXRlID8gbm9kZS5nZXRBdHRyaWJ1dGUoY29udHJvbEF0dHJpYnV0ZSkgOiBudWxsO1xuICAgICAgICBjb25zdCBhbHJlYWR5SGlkZGVuID0gYXR0ciAhPT0gbnVsbCAmJiBhdHRyICE9PSAnZmFsc2UnO1xuICAgICAgICBjb25zdCBjdXJyZW50Q291bnRlclZhbHVlID0gY291bnRlck1hcC5nZXQobm9kZSkgfHwgMDtcbiAgICAgICAgY29uc3QgY291bnRlclZhbHVlID0gY29udHJvbEF0dHJpYnV0ZSA/IGN1cnJlbnRDb3VudGVyVmFsdWUgKyAxIDogY3VycmVudENvdW50ZXJWYWx1ZTtcbiAgICAgICAgY29uc3QgbWFya2VyVmFsdWUgPSAobWFya2VyQ291bnRlci5nZXQobm9kZSkgfHwgMCkgKyAxO1xuICAgICAgICBjb3VudGVyTWFwLnNldChub2RlLCBjb3VudGVyVmFsdWUpO1xuICAgICAgICBtYXJrZXJDb3VudGVyLnNldChub2RlLCBtYXJrZXJWYWx1ZSk7XG4gICAgICAgIGhpZGRlbkVsZW1lbnRzLnB1c2gobm9kZSk7XG4gICAgICAgIGlmIChjb3VudGVyVmFsdWUgPT09IDEgJiYgYWxyZWFkeUhpZGRlbikge1xuICAgICAgICAgIHVuY29udHJvbGxlZEVsZW1lbnRzU2V0LmFkZChub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWFya2VyVmFsdWUgPT09IDEpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShtYXJrZXJOYW1lLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbHJlYWR5SGlkZGVuICYmIGNvbnRyb2xBdHRyaWJ1dGUpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShjb250cm9sQXR0cmlidXRlLCBjb250cm9sQXR0cmlidXRlID09PSAnaW5lcnQnID8gJycgOiAndHJ1ZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgbG9ja0NvdW50JDErKztcbiAgcmV0dXJuICgpID0+IHtcbiAgICBoaWRkZW5FbGVtZW50cy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgY29uc3QgY3VycmVudENvdW50ZXJWYWx1ZSA9IGNvdW50ZXJNYXAuZ2V0KGVsZW1lbnQpIHx8IDA7XG4gICAgICBjb25zdCBjb3VudGVyVmFsdWUgPSBjb250cm9sQXR0cmlidXRlID8gY3VycmVudENvdW50ZXJWYWx1ZSAtIDEgOiBjdXJyZW50Q291bnRlclZhbHVlO1xuICAgICAgY29uc3QgbWFya2VyVmFsdWUgPSAobWFya2VyQ291bnRlci5nZXQoZWxlbWVudCkgfHwgMCkgLSAxO1xuICAgICAgY291bnRlck1hcC5zZXQoZWxlbWVudCwgY291bnRlclZhbHVlKTtcbiAgICAgIG1hcmtlckNvdW50ZXIuc2V0KGVsZW1lbnQsIG1hcmtlclZhbHVlKTtcbiAgICAgIGlmICghY291bnRlclZhbHVlKSB7XG4gICAgICAgIGlmICghdW5jb250cm9sbGVkRWxlbWVudHNTZXQuaGFzKGVsZW1lbnQpICYmIGNvbnRyb2xBdHRyaWJ1dGUpIHtcbiAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShjb250cm9sQXR0cmlidXRlKTtcbiAgICAgICAgfVxuICAgICAgICB1bmNvbnRyb2xsZWRFbGVtZW50c1NldC5kZWxldGUoZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBpZiAoIW1hcmtlclZhbHVlKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG1hcmtlck5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGxvY2tDb3VudCQxLS07XG4gICAgaWYgKCFsb2NrQ291bnQkMSkge1xuICAgICAgY291bnRlck1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICBjb3VudGVyTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgIHVuY29udHJvbGxlZEVsZW1lbnRzU2V0ID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgIG1hcmtlck1hcCA9IHt9O1xuICAgIH1cbiAgfTtcbn1cbmZ1bmN0aW9uIG1hcmtPdGhlcnMoYXZvaWRFbGVtZW50cywgYXJpYUhpZGRlbiwgaW5lcnQpIHtcbiAgaWYgKGFyaWFIaWRkZW4gPT09IHZvaWQgMCkge1xuICAgIGFyaWFIaWRkZW4gPSBmYWxzZTtcbiAgfVxuICBpZiAoaW5lcnQgPT09IHZvaWQgMCkge1xuICAgIGluZXJ0ID0gZmFsc2U7XG4gIH1cbiAgY29uc3QgYm9keSA9IGdldERvY3VtZW50KGF2b2lkRWxlbWVudHNbMF0pLmJvZHk7XG4gIHJldHVybiBhcHBseUF0dHJpYnV0ZVRvT3RoZXJzKGF2b2lkRWxlbWVudHMuY29uY2F0KEFycmF5LmZyb20oYm9keS5xdWVyeVNlbGVjdG9yQWxsKCdbYXJpYS1saXZlXScpKSksIGJvZHksIGFyaWFIaWRkZW4sIGluZXJ0KTtcbn1cblxuY29uc3QgSElEREVOX1NUWUxFUyA9IHtcbiAgYm9yZGVyOiAwLFxuICBjbGlwOiAncmVjdCgwIDAgMCAwKScsXG4gIGhlaWdodDogJzFweCcsXG4gIG1hcmdpbjogJy0xcHgnLFxuICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gIHBhZGRpbmc6IDAsXG4gIHBvc2l0aW9uOiAnZml4ZWQnLFxuICB3aGl0ZVNwYWNlOiAnbm93cmFwJyxcbiAgd2lkdGg6ICcxcHgnLFxuICB0b3A6IDAsXG4gIGxlZnQ6IDBcbn07XG5jb25zdCBGb2N1c0d1YXJkID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRm9jdXNHdWFyZChwcm9wcywgcmVmKSB7XG4gIGNvbnN0IFtyb2xlLCBzZXRSb2xlXSA9IFJlYWN0LnVzZVN0YXRlKCk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGlzU2FmYXJpKCkpIHtcbiAgICAgIC8vIFVubGlrZSBvdGhlciBzY3JlZW4gcmVhZGVycyBzdWNoIGFzIE5WREEgYW5kIEpBV1MsIHRoZSB2aXJ0dWFsIGN1cnNvclxuICAgICAgLy8gb24gVm9pY2VPdmVyIGRvZXMgdHJpZ2dlciB0aGUgb25Gb2N1cyBldmVudCwgc28gd2UgY2FuIHVzZSB0aGUgZm9jdXNcbiAgICAgIC8vIHRyYXAgZWxlbWVudC4gT24gU2FmYXJpLCBvbmx5IGJ1dHRvbnMgdHJpZ2dlciB0aGUgb25Gb2N1cyBldmVudC5cbiAgICAgIC8vIE5COiBcImdyb3VwXCIgcm9sZSBpbiB0aGUgU2FuZGJveCBubyBsb25nZXIgYXBwZWFycyB0byB3b3JrLCBtdXN0IGJlIGFcbiAgICAgIC8vIGJ1dHRvbiByb2xlLlxuICAgICAgc2V0Um9sZSgnYnV0dG9uJyk7XG4gICAgfVxuICB9LCBbXSk7XG4gIGNvbnN0IHJlc3RQcm9wcyA9IHtcbiAgICByZWYsXG4gICAgdGFiSW5kZXg6IDAsXG4gICAgLy8gUm9sZSBpcyBvbmx5IGZvciBWb2ljZU92ZXJcbiAgICByb2xlLFxuICAgICdhcmlhLWhpZGRlbic6IHJvbGUgPyB1bmRlZmluZWQgOiB0cnVlLFxuICAgIFtjcmVhdGVBdHRyaWJ1dGUoJ2ZvY3VzLWd1YXJkJyldOiAnJyxcbiAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICB9O1xuICByZXR1cm4gLyojX19QVVJFX18qL2pzeChcInNwYW5cIiwge1xuICAgIC4uLnByb3BzLFxuICAgIC4uLnJlc3RQcm9wc1xuICB9KTtcbn0pO1xuXG5jb25zdCBQb3J0YWxDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5jb25zdCBhdHRyID0gLyojX19QVVJFX18qL2NyZWF0ZUF0dHJpYnV0ZSgncG9ydGFsJyk7XG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ1BvcnRhbCN1c2VmbG9hdGluZ3BvcnRhbG5vZGVcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdQb3J0YWxOb2RlKHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgaWQsXG4gICAgcm9vdFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHVuaXF1ZUlkID0gdXNlSWQoKTtcbiAgY29uc3QgcG9ydGFsQ29udGV4dCA9IHVzZVBvcnRhbENvbnRleHQoKTtcbiAgY29uc3QgW3BvcnRhbE5vZGUsIHNldFBvcnRhbE5vZGVdID0gUmVhY3QudXNlU3RhdGUobnVsbCk7XG4gIGNvbnN0IHBvcnRhbE5vZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHBvcnRhbE5vZGUgPT0gbnVsbCB8fCBwb3J0YWxOb2RlLnJlbW92ZSgpO1xuICAgICAgLy8gQWxsb3cgdGhlIHN1YnNlcXVlbnQgbGF5b3V0IGVmZmVjdHMgdG8gY3JlYXRlIGEgbmV3IG5vZGUgb24gdXBkYXRlcy5cbiAgICAgIC8vIFRoZSBwb3J0YWwgbm9kZSB3aWxsIHN0aWxsIGJlIGNsZWFuZWQgdXAgb24gdW5tb3VudC5cbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMjQ1NFxuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICBwb3J0YWxOb2RlUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSwgW3BvcnRhbE5vZGVdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICAvLyBXYWl0IGZvciB0aGUgdW5pcXVlSWQgdG8gYmUgZ2VuZXJhdGVkIGJlZm9yZSBjcmVhdGluZyB0aGUgcG9ydGFsIG5vZGUgaW5cbiAgICAvLyBSZWFjdCA8MTggKHVzaW5nIGB1c2VGbG9hdGluZ0lkYCBpbnN0ZWFkIG9mIHRoZSBuYXRpdmUgYHVzZUlkYCkuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2lzc3Vlcy8yNzc4XG4gICAgaWYgKCF1bmlxdWVJZCkgcmV0dXJuO1xuICAgIGlmIChwb3J0YWxOb2RlUmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBjb25zdCBleGlzdGluZ0lkUm9vdCA9IGlkID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpIDogbnVsbDtcbiAgICBpZiAoIWV4aXN0aW5nSWRSb290KSByZXR1cm47XG4gICAgY29uc3Qgc3ViUm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHN1YlJvb3QuaWQgPSB1bmlxdWVJZDtcbiAgICBzdWJSb290LnNldEF0dHJpYnV0ZShhdHRyLCAnJyk7XG4gICAgZXhpc3RpbmdJZFJvb3QuYXBwZW5kQ2hpbGQoc3ViUm9vdCk7XG4gICAgcG9ydGFsTm9kZVJlZi5jdXJyZW50ID0gc3ViUm9vdDtcbiAgICBzZXRQb3J0YWxOb2RlKHN1YlJvb3QpO1xuICB9LCBbaWQsIHVuaXF1ZUlkXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgLy8gV2FpdCBmb3IgdGhlIHJvb3QgdG8gZXhpc3QgYmVmb3JlIGNyZWF0aW5nIHRoZSBwb3J0YWwgbm9kZS4gVGhlIHJvb3QgbXVzdFxuICAgIC8vIGJlIHN0b3JlZCBpbiBzdGF0ZSwgbm90IGEgcmVmLCBmb3IgdGhpcyB0byB3b3JrIHJlYWN0aXZlbHkuXG4gICAgaWYgKHJvb3QgPT09IG51bGwpIHJldHVybjtcbiAgICBpZiAoIXVuaXF1ZUlkKSByZXR1cm47XG4gICAgaWYgKHBvcnRhbE5vZGVSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgIGxldCBjb250YWluZXIgPSByb290IHx8IChwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpO1xuICAgIGlmIChjb250YWluZXIgJiYgIWlzRWxlbWVudChjb250YWluZXIpKSBjb250YWluZXIgPSBjb250YWluZXIuY3VycmVudDtcbiAgICBjb250YWluZXIgPSBjb250YWluZXIgfHwgZG9jdW1lbnQuYm9keTtcbiAgICBsZXQgaWRXcmFwcGVyID0gbnVsbDtcbiAgICBpZiAoaWQpIHtcbiAgICAgIGlkV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgaWRXcmFwcGVyLmlkID0gaWQ7XG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoaWRXcmFwcGVyKTtcbiAgICB9XG4gICAgY29uc3Qgc3ViUm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHN1YlJvb3QuaWQgPSB1bmlxdWVJZDtcbiAgICBzdWJSb290LnNldEF0dHJpYnV0ZShhdHRyLCAnJyk7XG4gICAgY29udGFpbmVyID0gaWRXcmFwcGVyIHx8IGNvbnRhaW5lcjtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoc3ViUm9vdCk7XG4gICAgcG9ydGFsTm9kZVJlZi5jdXJyZW50ID0gc3ViUm9vdDtcbiAgICBzZXRQb3J0YWxOb2RlKHN1YlJvb3QpO1xuICB9LCBbaWQsIHJvb3QsIHVuaXF1ZUlkLCBwb3J0YWxDb250ZXh0XSk7XG4gIHJldHVybiBwb3J0YWxOb2RlO1xufVxuLyoqXG4gKiBQb3J0YWxzIHRoZSBmbG9hdGluZyBlbGVtZW50IGludG8gYSBnaXZlbiBjb250YWluZXIgZWxlbWVudCDigJQgYnkgZGVmYXVsdCxcbiAqIG91dHNpZGUgb2YgdGhlIGFwcCByb290IGFuZCBpbnRvIHRoZSBib2R5LlxuICogVGhpcyBpcyBuZWNlc3NhcnkgdG8gZW5zdXJlIHRoZSBmbG9hdGluZyBlbGVtZW50IGNhbiBhcHBlYXIgb3V0c2lkZSBhbnlcbiAqIHBvdGVudGlhbCBwYXJlbnQgY29udGFpbmVycyB0aGF0IGNhdXNlIGNsaXBwaW5nIChzdWNoIGFzIGBvdmVyZmxvdzogaGlkZGVuYCksXG4gKiB3aGlsZSByZXRhaW5pbmcgaXRzIGxvY2F0aW9uIGluIHRoZSBSZWFjdCB0cmVlLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nUG9ydGFsXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nUG9ydGFsKHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBjaGlsZHJlbixcbiAgICBpZCxcbiAgICByb290LFxuICAgIHByZXNlcnZlVGFiT3JkZXIgPSB0cnVlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgcG9ydGFsTm9kZSA9IHVzZUZsb2F0aW5nUG9ydGFsTm9kZSh7XG4gICAgaWQsXG4gICAgcm9vdFxuICB9KTtcbiAgY29uc3QgW2ZvY3VzTWFuYWdlclN0YXRlLCBzZXRGb2N1c01hbmFnZXJTdGF0ZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3QgYmVmb3JlT3V0c2lkZVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgYWZ0ZXJPdXRzaWRlUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBiZWZvcmVJbnNpZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGFmdGVySW5zaWRlUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBtb2RhbCA9IGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5tb2RhbDtcbiAgY29uc3Qgb3BlbiA9IGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5vcGVuO1xuICBjb25zdCBzaG91bGRSZW5kZXJHdWFyZHMgPVxuICAvLyBUaGUgRm9jdXNNYW5hZ2VyIGFuZCB0aGVyZWZvcmUgZmxvYXRpbmcgZWxlbWVudCBhcmUgY3VycmVudGx5IG9wZW4vXG4gIC8vIHJlbmRlcmVkLlxuICAhIWZvY3VzTWFuYWdlclN0YXRlICYmXG4gIC8vIEd1YXJkcyBhcmUgb25seSBmb3Igbm9uLW1vZGFsIGZvY3VzIG1hbmFnZW1lbnQuXG4gICFmb2N1c01hbmFnZXJTdGF0ZS5tb2RhbCAmJlxuICAvLyBEb24ndCByZW5kZXIgaWYgdW5tb3VudCBpcyB0cmFuc2l0aW9uaW5nLlxuICBmb2N1c01hbmFnZXJTdGF0ZS5vcGVuICYmIHByZXNlcnZlVGFiT3JkZXIgJiYgISEocm9vdCB8fCBwb3J0YWxOb2RlKTtcblxuICAvLyBodHRwczovL2NvZGVzYW5kYm94LmlvL3MvdGFiYmFibGUtcG9ydGFsLWY0dG5nP2ZpbGU9L3NyYy9UYWJiYWJsZVBvcnRhbC50c3hcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXBvcnRhbE5vZGUgfHwgIXByZXNlcnZlVGFiT3JkZXIgfHwgbW9kYWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgZWxlbWVudHMgaW5zaWRlIHRoZSBwb3J0YWwgZWxlbWVudCBhcmUgdGFiYmFibGUgb25seSB3aGVuIHRoZVxuICAgIC8vIHBvcnRhbCBoYXMgYWxyZWFkeSBiZWVuIGZvY3VzZWQsIGVpdGhlciBieSB0YWJiaW5nIGludG8gYSBmb2N1cyB0cmFwXG4gICAgLy8gZWxlbWVudCBvdXRzaWRlIG9yIHVzaW5nIHRoZSBtb3VzZS5cbiAgICBmdW5jdGlvbiBvbkZvY3VzKGV2ZW50KSB7XG4gICAgICBpZiAocG9ydGFsTm9kZSAmJiBpc091dHNpZGVFdmVudChldmVudCkpIHtcbiAgICAgICAgY29uc3QgZm9jdXNpbmcgPSBldmVudC50eXBlID09PSAnZm9jdXNpbic7XG4gICAgICAgIGNvbnN0IG1hbmFnZUZvY3VzID0gZm9jdXNpbmcgPyBlbmFibGVGb2N1c0luc2lkZSA6IGRpc2FibGVGb2N1c0luc2lkZTtcbiAgICAgICAgbWFuYWdlRm9jdXMocG9ydGFsTm9kZSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIExpc3RlbiB0byB0aGUgZXZlbnQgb24gdGhlIGNhcHR1cmUgcGhhc2Ugc28gdGhleSBydW4gYmVmb3JlIHRoZSBmb2N1c1xuICAgIC8vIHRyYXAgZWxlbWVudHMgb25Gb2N1cyBwcm9wIGlzIGNhbGxlZC5cbiAgICBwb3J0YWxOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLCBvbkZvY3VzLCB0cnVlKTtcbiAgICBwb3J0YWxOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0Jywgb25Gb2N1cywgdHJ1ZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHBvcnRhbE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIG9uRm9jdXMsIHRydWUpO1xuICAgICAgcG9ydGFsTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIG9uRm9jdXMsIHRydWUpO1xuICAgIH07XG4gIH0sIFtwb3J0YWxOb2RlLCBwcmVzZXJ2ZVRhYk9yZGVyLCBtb2RhbF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghcG9ydGFsTm9kZSkgcmV0dXJuO1xuICAgIGlmIChvcGVuKSByZXR1cm47XG4gICAgZW5hYmxlRm9jdXNJbnNpZGUocG9ydGFsTm9kZSk7XG4gIH0sIFtvcGVuLCBwb3J0YWxOb2RlXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4cyhQb3J0YWxDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgdmFsdWU6IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICAgIHByZXNlcnZlVGFiT3JkZXIsXG4gICAgICBiZWZvcmVPdXRzaWRlUmVmLFxuICAgICAgYWZ0ZXJPdXRzaWRlUmVmLFxuICAgICAgYmVmb3JlSW5zaWRlUmVmLFxuICAgICAgYWZ0ZXJJbnNpZGVSZWYsXG4gICAgICBwb3J0YWxOb2RlLFxuICAgICAgc2V0Rm9jdXNNYW5hZ2VyU3RhdGVcbiAgICB9KSwgW3ByZXNlcnZlVGFiT3JkZXIsIHBvcnRhbE5vZGVdKSxcbiAgICBjaGlsZHJlbjogW3Nob3VsZFJlbmRlckd1YXJkcyAmJiBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9qc3goRm9jdXNHdWFyZCwge1xuICAgICAgXCJkYXRhLXR5cGVcIjogXCJvdXRzaWRlXCIsXG4gICAgICByZWY6IGJlZm9yZU91dHNpZGVSZWYsXG4gICAgICBvbkZvY3VzOiBldmVudCA9PiB7XG4gICAgICAgIGlmIChpc091dHNpZGVFdmVudChldmVudCwgcG9ydGFsTm9kZSkpIHtcbiAgICAgICAgICB2YXIgX2JlZm9yZUluc2lkZVJlZiRjdXJyO1xuICAgICAgICAgIChfYmVmb3JlSW5zaWRlUmVmJGN1cnIgPSBiZWZvcmVJbnNpZGVSZWYuY3VycmVudCkgPT0gbnVsbCB8fCBfYmVmb3JlSW5zaWRlUmVmJGN1cnIuZm9jdXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBkb21SZWZlcmVuY2UgPSBmb2N1c01hbmFnZXJTdGF0ZSA/IGZvY3VzTWFuYWdlclN0YXRlLmRvbVJlZmVyZW5jZSA6IG51bGw7XG4gICAgICAgICAgY29uc3QgcHJldlRhYmJhYmxlID0gZ2V0UHJldmlvdXNUYWJiYWJsZShkb21SZWZlcmVuY2UpO1xuICAgICAgICAgIHByZXZUYWJiYWJsZSA9PSBudWxsIHx8IHByZXZUYWJiYWJsZS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksIHNob3VsZFJlbmRlckd1YXJkcyAmJiBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9qc3goXCJzcGFuXCIsIHtcbiAgICAgIFwiYXJpYS1vd25zXCI6IHBvcnRhbE5vZGUuaWQsXG4gICAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICAgIH0pLCBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9SZWFjdERPTS5jcmVhdGVQb3J0YWwoY2hpbGRyZW4sIHBvcnRhbE5vZGUpLCBzaG91bGRSZW5kZXJHdWFyZHMgJiYgcG9ydGFsTm9kZSAmJiAvKiNfX1BVUkVfXyovanN4KEZvY3VzR3VhcmQsIHtcbiAgICAgIFwiZGF0YS10eXBlXCI6IFwib3V0c2lkZVwiLFxuICAgICAgcmVmOiBhZnRlck91dHNpZGVSZWYsXG4gICAgICBvbkZvY3VzOiBldmVudCA9PiB7XG4gICAgICAgIGlmIChpc091dHNpZGVFdmVudChldmVudCwgcG9ydGFsTm9kZSkpIHtcbiAgICAgICAgICB2YXIgX2FmdGVySW5zaWRlUmVmJGN1cnJlO1xuICAgICAgICAgIChfYWZ0ZXJJbnNpZGVSZWYkY3VycmUgPSBhZnRlckluc2lkZVJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9hZnRlckluc2lkZVJlZiRjdXJyZS5mb2N1cygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGRvbVJlZmVyZW5jZSA9IGZvY3VzTWFuYWdlclN0YXRlID8gZm9jdXNNYW5hZ2VyU3RhdGUuZG9tUmVmZXJlbmNlIDogbnVsbDtcbiAgICAgICAgICBjb25zdCBuZXh0VGFiYmFibGUgPSBnZXROZXh0VGFiYmFibGUoZG9tUmVmZXJlbmNlKTtcbiAgICAgICAgICBuZXh0VGFiYmFibGUgPT0gbnVsbCB8fCBuZXh0VGFiYmFibGUuZm9jdXMoKTtcbiAgICAgICAgICAoZm9jdXNNYW5hZ2VyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IGZvY3VzTWFuYWdlclN0YXRlLmNsb3NlT25Gb2N1c091dCkgJiYgKGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5vbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnZm9jdXMtb3V0JykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSldXG4gIH0pO1xufVxuY29uc3QgdXNlUG9ydGFsQ29udGV4dCA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoUG9ydGFsQ29udGV4dCk7XG5cbmZ1bmN0aW9uIHVzZUxpdGVNZXJnZVJlZnMocmVmcykge1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIHZhbHVlID0+IHtcbiAgICAgIHJlZnMuZm9yRWFjaChyZWYgPT4ge1xuICAgICAgICBpZiAocmVmKSB7XG4gICAgICAgICAgcmVmLmN1cnJlbnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIHJlZnMpO1xufVxuXG5jb25zdCBMSVNUX0xJTUlUID0gMjA7XG5sZXQgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cyA9IFtdO1xuZnVuY3Rpb24gYWRkUHJldmlvdXNseUZvY3VzZWRFbGVtZW50KGVsZW1lbnQpIHtcbiAgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cyA9IHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMuZmlsdGVyKGVsID0+IGVsLmlzQ29ubmVjdGVkKTtcbiAgaWYgKGVsZW1lbnQgJiYgZ2V0Tm9kZU5hbWUoZWxlbWVudCkgIT09ICdib2R5Jykge1xuICAgIHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICBpZiAocHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5sZW5ndGggPiBMSVNUX0xJTUlUKSB7XG4gICAgICBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnRzID0gcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5zbGljZSgtMjApO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZ2V0UHJldmlvdXNseUZvY3VzZWRFbGVtZW50KCkge1xuICByZXR1cm4gcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5zbGljZSgpLnJldmVyc2UoKS5maW5kKGVsID0+IGVsLmlzQ29ubmVjdGVkKTtcbn1cbmZ1bmN0aW9uIGdldEZpcnN0VGFiYmFibGVFbGVtZW50KGNvbnRhaW5lcikge1xuICBjb25zdCB0YWJiYWJsZU9wdGlvbnMgPSBnZXRUYWJiYWJsZU9wdGlvbnMoKTtcbiAgaWYgKGlzVGFiYmFibGUoY29udGFpbmVyLCB0YWJiYWJsZU9wdGlvbnMpKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgfVxuICByZXR1cm4gdGFiYmFibGUoY29udGFpbmVyLCB0YWJiYWJsZU9wdGlvbnMpWzBdIHx8IGNvbnRhaW5lcjtcbn1cbmZ1bmN0aW9uIGhhbmRsZVRhYkluZGV4KGZsb2F0aW5nRm9jdXNFbGVtZW50LCBvcmRlclJlZikge1xuICB2YXIgX2Zsb2F0aW5nRm9jdXNFbGVtZW50O1xuICBpZiAoIW9yZGVyUmVmLmN1cnJlbnQuaW5jbHVkZXMoJ2Zsb2F0aW5nJykgJiYgISgoX2Zsb2F0aW5nRm9jdXNFbGVtZW50ID0gZmxvYXRpbmdGb2N1c0VsZW1lbnQuZ2V0QXR0cmlidXRlKCdyb2xlJykpICE9IG51bGwgJiYgX2Zsb2F0aW5nRm9jdXNFbGVtZW50LmluY2x1ZGVzKCdkaWFsb2cnKSkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3Qgb3B0aW9ucyA9IGdldFRhYmJhYmxlT3B0aW9ucygpO1xuICBjb25zdCBmb2N1c2FibGVFbGVtZW50cyA9IGZvY3VzYWJsZShmbG9hdGluZ0ZvY3VzRWxlbWVudCwgb3B0aW9ucyk7XG4gIGNvbnN0IHRhYmJhYmxlQ29udGVudCA9IGZvY3VzYWJsZUVsZW1lbnRzLmZpbHRlcihlbGVtZW50ID0+IHtcbiAgICBjb25zdCBkYXRhVGFiSW5kZXggPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS10YWJpbmRleCcpIHx8ICcnO1xuICAgIHJldHVybiBpc1RhYmJhYmxlKGVsZW1lbnQsIG9wdGlvbnMpIHx8IGVsZW1lbnQuaGFzQXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JykgJiYgIWRhdGFUYWJJbmRleC5zdGFydHNXaXRoKCctJyk7XG4gIH0pO1xuICBjb25zdCB0YWJJbmRleCA9IGZsb2F0aW5nRm9jdXNFbGVtZW50LmdldEF0dHJpYnV0ZSgndGFiaW5kZXgnKTtcbiAgaWYgKG9yZGVyUmVmLmN1cnJlbnQuaW5jbHVkZXMoJ2Zsb2F0aW5nJykgfHwgdGFiYmFibGVDb250ZW50Lmxlbmd0aCA9PT0gMCkge1xuICAgIGlmICh0YWJJbmRleCAhPT0gJzAnKSB7XG4gICAgICBmbG9hdGluZ0ZvY3VzRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJzAnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGFiSW5kZXggIT09ICctMScgfHwgZmxvYXRpbmdGb2N1c0VsZW1lbnQuaGFzQXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JykgJiYgZmxvYXRpbmdGb2N1c0VsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JykgIT09ICctMScpIHtcbiAgICBmbG9hdGluZ0ZvY3VzRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJy0xJyk7XG4gICAgZmxvYXRpbmdGb2N1c0VsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXRhYmluZGV4JywgJy0xJyk7XG4gIH1cbn1cbmNvbnN0IFZpc3VhbGx5SGlkZGVuRGlzbWlzcyA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIFZpc3VhbGx5SGlkZGVuRGlzbWlzcyhwcm9wcywgcmVmKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovanN4KFwiYnV0dG9uXCIsIHtcbiAgICAuLi5wcm9wcyxcbiAgICB0eXBlOiBcImJ1dHRvblwiLFxuICAgIHJlZjogcmVmLFxuICAgIHRhYkluZGV4OiAtMSxcbiAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICB9KTtcbn0pO1xuLyoqXG4gKiBQcm92aWRlcyBmb2N1cyBtYW5hZ2VtZW50IGZvciB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0ZvY3VzTWFuYWdlclxuICovXG5mdW5jdGlvbiBGbG9hdGluZ0ZvY3VzTWFuYWdlcihwcm9wcykge1xuICBjb25zdCB7XG4gICAgY29udGV4dCxcbiAgICBjaGlsZHJlbixcbiAgICBkaXNhYmxlZCA9IGZhbHNlLFxuICAgIG9yZGVyID0gWydjb250ZW50J10sXG4gICAgZ3VhcmRzOiBfZ3VhcmRzID0gdHJ1ZSxcbiAgICBpbml0aWFsRm9jdXMgPSAwLFxuICAgIHJldHVybkZvY3VzID0gdHJ1ZSxcbiAgICByZXN0b3JlRm9jdXMgPSBmYWxzZSxcbiAgICBtb2RhbCA9IHRydWUsXG4gICAgdmlzdWFsbHlIaWRkZW5EaXNtaXNzID0gZmFsc2UsXG4gICAgY2xvc2VPbkZvY3VzT3V0ID0gdHJ1ZSxcbiAgICBvdXRzaWRlRWxlbWVudHNJbmVydCA9IGZhbHNlLFxuICAgIGdldEluc2lkZUVsZW1lbnRzOiBfZ2V0SW5zaWRlRWxlbWVudHMgPSAoKSA9PiBbXVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBldmVudHMsXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50czoge1xuICAgICAgZG9tUmVmZXJlbmNlLFxuICAgICAgZmxvYXRpbmdcbiAgICB9XG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCBnZXROb2RlSWQgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkZmxvYTtcbiAgICByZXR1cm4gKF9kYXRhUmVmJGN1cnJlbnQkZmxvYSA9IGRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JGZsb2Eubm9kZUlkO1xuICB9KTtcbiAgY29uc3QgZ2V0SW5zaWRlRWxlbWVudHMgPSB1c2VFZmZlY3RFdmVudChfZ2V0SW5zaWRlRWxlbWVudHMpO1xuICBjb25zdCBpZ25vcmVJbml0aWFsRm9jdXMgPSB0eXBlb2YgaW5pdGlhbEZvY3VzID09PSAnbnVtYmVyJyAmJiBpbml0aWFsRm9jdXMgPCAwO1xuICAvLyBJZiB0aGUgcmVmZXJlbmNlIGlzIGEgY29tYm9ib3ggYW5kIGlzIHR5cGVhYmxlIChlLmcuIGlucHV0L3RleHRhcmVhKSxcbiAgLy8gdGhlcmUgYXJlIGRpZmZlcmVudCBmb2N1cyBzZW1hbnRpY3MuIFRoZSBndWFyZHMgc2hvdWxkIG5vdCBiZSByZW5kZXJlZCwgYnV0XG4gIC8vIGFyaWEtaGlkZGVuIHNob3VsZCBiZSBhcHBsaWVkIHRvIGFsbCBub2RlcyBzdGlsbC4gRnVydGhlciwgdGhlIHZpc3VhbGx5XG4gIC8vIGhpZGRlbiBkaXNtaXNzIGJ1dHRvbiBzaG91bGQgb25seSBhcHBlYXIgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCwgbm90IHRoZVxuICAvLyBzdGFydC5cbiAgY29uc3QgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID0gaXNUeXBlYWJsZUNvbWJvYm94KGRvbVJlZmVyZW5jZSkgJiYgaWdub3JlSW5pdGlhbEZvY3VzO1xuXG4gIC8vIEZvcmNlIHRoZSBndWFyZHMgdG8gYmUgcmVuZGVyZWQgaWYgdGhlIGBpbmVydGAgYXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gIGNvbnN0IGluZXJ0U3VwcG9ydGVkID0gc3VwcG9ydHNJbmVydCgpO1xuICBjb25zdCBndWFyZHMgPSBpbmVydFN1cHBvcnRlZCA/IF9ndWFyZHMgOiB0cnVlO1xuICBjb25zdCB1c2VJbmVydCA9ICFndWFyZHMgfHwgaW5lcnRTdXBwb3J0ZWQgJiYgb3V0c2lkZUVsZW1lbnRzSW5lcnQ7XG4gIGNvbnN0IG9yZGVyUmVmID0gdXNlTGF0ZXN0UmVmKG9yZGVyKTtcbiAgY29uc3QgaW5pdGlhbEZvY3VzUmVmID0gdXNlTGF0ZXN0UmVmKGluaXRpYWxGb2N1cyk7XG4gIGNvbnN0IHJldHVybkZvY3VzUmVmID0gdXNlTGF0ZXN0UmVmKHJldHVybkZvY3VzKTtcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBwb3J0YWxDb250ZXh0ID0gdXNlUG9ydGFsQ29udGV4dCgpO1xuICBjb25zdCBzdGFydERpc21pc3NCdXR0b25SZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGVuZERpc21pc3NCdXR0b25SZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHByZXZlbnRSZXR1cm5Gb2N1c1JlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGlzUG9pbnRlckRvd25SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB0YWJiYWJsZUluZGV4UmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3QgaXNJbnNpZGVQb3J0YWwgPSBwb3J0YWxDb250ZXh0ICE9IG51bGw7XG4gIGNvbnN0IGZsb2F0aW5nRm9jdXNFbGVtZW50ID0gZ2V0RmxvYXRpbmdGb2N1c0VsZW1lbnQoZmxvYXRpbmcpO1xuICBjb25zdCBnZXRUYWJiYWJsZUNvbnRlbnQgPSB1c2VFZmZlY3RFdmVudChmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgaWYgKGNvbnRhaW5lciA9PT0gdm9pZCAwKSB7XG4gICAgICBjb250YWluZXIgPSBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRhaW5lciA/IHRhYmJhYmxlKGNvbnRhaW5lciwgZ2V0VGFiYmFibGVPcHRpb25zKCkpIDogW107XG4gIH0pO1xuICBjb25zdCBnZXRUYWJiYWJsZUVsZW1lbnRzID0gdXNlRWZmZWN0RXZlbnQoY29udGFpbmVyID0+IHtcbiAgICBjb25zdCBjb250ZW50ID0gZ2V0VGFiYmFibGVDb250ZW50KGNvbnRhaW5lcik7XG4gICAgcmV0dXJuIG9yZGVyUmVmLmN1cnJlbnQubWFwKHR5cGUgPT4ge1xuICAgICAgaWYgKGRvbVJlZmVyZW5jZSAmJiB0eXBlID09PSAncmVmZXJlbmNlJykge1xuICAgICAgICByZXR1cm4gZG9tUmVmZXJlbmNlO1xuICAgICAgfVxuICAgICAgaWYgKGZsb2F0aW5nRm9jdXNFbGVtZW50ICYmIHR5cGUgPT09ICdmbG9hdGluZycpIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0aW5nRm9jdXNFbGVtZW50O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfSkuZmlsdGVyKEJvb2xlYW4pLmZsYXQoKTtcbiAgfSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFtb2RhbCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIG9uS2V5RG93bihldmVudCkge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicpIHtcbiAgICAgICAgLy8gVGhlIGZvY3VzIGd1YXJkcyBoYXZlIG5vdGhpbmcgdG8gZm9jdXMsIHNvIHdlIG5lZWQgdG8gc3RvcCB0aGUgZXZlbnQuXG4gICAgICAgIGlmIChjb250YWlucyQxKGZsb2F0aW5nRm9jdXNFbGVtZW50LCBhY3RpdmVFbGVtZW50KGdldERvY3VtZW50JDEoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSkgJiYgZ2V0VGFiYmFibGVDb250ZW50KCkubGVuZ3RoID09PSAwICYmICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gpIHtcbiAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVscyA9IGdldFRhYmJhYmxlRWxlbWVudHMoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0VGFyZ2V0JDEoZXZlbnQpO1xuICAgICAgICBpZiAob3JkZXJSZWYuY3VycmVudFswXSA9PT0gJ3JlZmVyZW5jZScgJiYgdGFyZ2V0ID09PSBkb21SZWZlcmVuY2UpIHtcbiAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgIGlmIChldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgZW5xdWV1ZUZvY3VzKGVsc1tlbHMubGVuZ3RoIC0gMV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbnF1ZXVlRm9jdXMoZWxzWzFdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yZGVyUmVmLmN1cnJlbnRbMV0gPT09ICdmbG9hdGluZycgJiYgdGFyZ2V0ID09PSBmbG9hdGluZ0ZvY3VzRWxlbWVudCAmJiBldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgICAgZW5xdWV1ZUZvY3VzKGVsc1swXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQkMShmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleURvd24pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93bik7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBkb21SZWZlcmVuY2UsIGZsb2F0aW5nRm9jdXNFbGVtZW50LCBtb2RhbCwgb3JkZXJSZWYsIGlzVW50cmFwcGVkVHlwZWFibGVDb21ib2JveCwgZ2V0VGFiYmFibGVDb250ZW50LCBnZXRUYWJiYWJsZUVsZW1lbnRzXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFmbG9hdGluZykgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIGhhbmRsZUZvY3VzSW4oZXZlbnQpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50KTtcbiAgICAgIGNvbnN0IHRhYmJhYmxlQ29udGVudCA9IGdldFRhYmJhYmxlQ29udGVudCgpO1xuICAgICAgY29uc3QgdGFiYmFibGVJbmRleCA9IHRhYmJhYmxlQ29udGVudC5pbmRleE9mKHRhcmdldCk7XG4gICAgICBpZiAodGFiYmFibGVJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgdGFiYmFibGVJbmRleFJlZi5jdXJyZW50ID0gdGFiYmFibGVJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgZmxvYXRpbmcuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIGhhbmRsZUZvY3VzSW4pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBmbG9hdGluZy5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c2luJywgaGFuZGxlRm9jdXNJbik7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBmbG9hdGluZywgZ2V0VGFiYmFibGVDb250ZW50XSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFjbG9zZU9uRm9jdXNPdXQpIHJldHVybjtcblxuICAgIC8vIEluIFNhZmFyaSwgYnV0dG9ucyBsb3NlIGZvY3VzIHdoZW4gcHJlc3NpbmcgdGhlbS5cbiAgICBmdW5jdGlvbiBoYW5kbGVQb2ludGVyRG93bigpIHtcbiAgICAgIGlzUG9pbnRlckRvd25SZWYuY3VycmVudCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaXNQb2ludGVyRG93blJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaGFuZGxlRm9jdXNPdXRzaWRlKGV2ZW50KSB7XG4gICAgICBjb25zdCByZWxhdGVkVGFyZ2V0ID0gZXZlbnQucmVsYXRlZFRhcmdldDtcbiAgICAgIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBldmVudC5jdXJyZW50VGFyZ2V0O1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICBjb25zdCBub2RlSWQgPSBnZXROb2RlSWQoKTtcbiAgICAgICAgY29uc3QgbW92ZWRUb1VucmVsYXRlZE5vZGUgPSAhKGNvbnRhaW5zJDEoZG9tUmVmZXJlbmNlLCByZWxhdGVkVGFyZ2V0KSB8fCBjb250YWlucyQxKGZsb2F0aW5nLCByZWxhdGVkVGFyZ2V0KSB8fCBjb250YWlucyQxKHJlbGF0ZWRUYXJnZXQsIGZsb2F0aW5nKSB8fCBjb250YWlucyQxKHBvcnRhbENvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSwgcmVsYXRlZFRhcmdldCkgfHwgcmVsYXRlZFRhcmdldCAhPSBudWxsICYmIHJlbGF0ZWRUYXJnZXQuaGFzQXR0cmlidXRlKGNyZWF0ZUF0dHJpYnV0ZSgnZm9jdXMtZ3VhcmQnKSkgfHwgdHJlZSAmJiAoZ2V0Tm9kZUNoaWxkcmVuJDEodHJlZS5ub2Rlc1JlZi5jdXJyZW50LCBub2RlSWQpLmZpbmQobm9kZSA9PiB7XG4gICAgICAgICAgdmFyIF9ub2RlJGNvbnRleHQsIF9ub2RlJGNvbnRleHQyO1xuICAgICAgICAgIHJldHVybiBjb250YWlucyQxKChfbm9kZSRjb250ZXh0ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dC5lbGVtZW50cy5mbG9hdGluZywgcmVsYXRlZFRhcmdldCkgfHwgY29udGFpbnMkMSgoX25vZGUkY29udGV4dDIgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Mi5lbGVtZW50cy5kb21SZWZlcmVuY2UsIHJlbGF0ZWRUYXJnZXQpO1xuICAgICAgICB9KSB8fCBnZXROb2RlQW5jZXN0b3JzKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKS5maW5kKG5vZGUgPT4ge1xuICAgICAgICAgIHZhciBfbm9kZSRjb250ZXh0MywgX25vZGUkY29udGV4dDQsIF9ub2RlJGNvbnRleHQ1O1xuICAgICAgICAgIHJldHVybiBbKF9ub2RlJGNvbnRleHQzID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDMuZWxlbWVudHMuZmxvYXRpbmcsIGdldEZsb2F0aW5nRm9jdXNFbGVtZW50KChfbm9kZSRjb250ZXh0NCA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQ0LmVsZW1lbnRzLmZsb2F0aW5nKV0uaW5jbHVkZXMocmVsYXRlZFRhcmdldCkgfHwgKChfbm9kZSRjb250ZXh0NSA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQ1LmVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgPT09IHJlbGF0ZWRUYXJnZXQ7XG4gICAgICAgIH0pKSk7XG4gICAgICAgIGlmIChjdXJyZW50VGFyZ2V0ID09PSBkb21SZWZlcmVuY2UgJiYgZmxvYXRpbmdGb2N1c0VsZW1lbnQpIHtcbiAgICAgICAgICBoYW5kbGVUYWJJbmRleChmbG9hdGluZ0ZvY3VzRWxlbWVudCwgb3JkZXJSZWYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzdG9yZSBmb2N1cyB0byB0aGUgcHJldmlvdXMgdGFiYmFibGUgZWxlbWVudCBpbmRleCB0byBwcmV2ZW50XG4gICAgICAgIC8vIGZvY3VzIGZyb20gYmVpbmcgbG9zdCBvdXRzaWRlIHRoZSBmbG9hdGluZyB0cmVlLlxuICAgICAgICBpZiAocmVzdG9yZUZvY3VzICYmIG1vdmVkVG9VbnJlbGF0ZWROb2RlICYmIGFjdGl2ZUVsZW1lbnQoZ2V0RG9jdW1lbnQkMShmbG9hdGluZ0ZvY3VzRWxlbWVudCkpID09PSBnZXREb2N1bWVudCQxKGZsb2F0aW5nRm9jdXNFbGVtZW50KS5ib2R5KSB7XG4gICAgICAgICAgLy8gTGV0IGBGbG9hdGluZ1BvcnRhbGAgZWZmZWN0IGtub3dzIHRoYXQgZm9jdXMgaXMgc3RpbGwgaW5zaWRlIHRoZVxuICAgICAgICAgIC8vIGZsb2F0aW5nIHRyZWUuXG4gICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSB7XG4gICAgICAgICAgICBmbG9hdGluZ0ZvY3VzRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBwcmV2VGFiYmFibGVJbmRleCA9IHRhYmJhYmxlSW5kZXhSZWYuY3VycmVudDtcbiAgICAgICAgICBjb25zdCB0YWJiYWJsZUNvbnRlbnQgPSBnZXRUYWJiYWJsZUNvbnRlbnQoKTtcbiAgICAgICAgICBjb25zdCBub2RlVG9Gb2N1cyA9IHRhYmJhYmxlQ29udGVudFtwcmV2VGFiYmFibGVJbmRleF0gfHwgdGFiYmFibGVDb250ZW50W3RhYmJhYmxlQ29udGVudC5sZW5ndGggLSAxXSB8fCBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICAgICAgICBpZiAoaXNIVE1MRWxlbWVudChub2RlVG9Gb2N1cykpIHtcbiAgICAgICAgICAgIG5vZGVUb0ZvY3VzLmZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9jdXMgZGlkIG5vdCBtb3ZlIGluc2lkZSB0aGUgZmxvYXRpbmcgdHJlZSwgYW5kIHRoZXJlIGFyZSBubyB0YWJiYWJsZVxuICAgICAgICAvLyBwb3J0YWwgZ3VhcmRzIHRvIGhhbmRsZSBjbG9zaW5nLlxuICAgICAgICBpZiAoKGlzVW50cmFwcGVkVHlwZWFibGVDb21ib2JveCA/IHRydWUgOiAhbW9kYWwpICYmIHJlbGF0ZWRUYXJnZXQgJiYgbW92ZWRUb1VucmVsYXRlZE5vZGUgJiYgIWlzUG9pbnRlckRvd25SZWYuY3VycmVudCAmJlxuICAgICAgICAvLyBGaXggUmVhY3QgMTggU3RyaWN0IE1vZGUgcmV0dXJuRm9jdXMgZHVlIHRvIGRvdWJsZSByZW5kZXJpbmcuXG4gICAgICAgIHJlbGF0ZWRUYXJnZXQgIT09IGdldFByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCgpKSB7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsICdmb2N1cy1vdXQnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChmbG9hdGluZyAmJiBpc0hUTUxFbGVtZW50KGRvbVJlZmVyZW5jZSkpIHtcbiAgICAgIGRvbVJlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIGhhbmRsZUZvY3VzT3V0c2lkZSk7XG4gICAgICBkb21SZWZlcmVuY2UuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBoYW5kbGVQb2ludGVyRG93bik7XG4gICAgICBmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIGhhbmRsZUZvY3VzT3V0c2lkZSk7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBkb21SZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignZm9jdXNvdXQnLCBoYW5kbGVGb2N1c091dHNpZGUpO1xuICAgICAgICBkb21SZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBoYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGZsb2F0aW5nLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0JywgaGFuZGxlRm9jdXNPdXRzaWRlKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbZGlzYWJsZWQsIGRvbVJlZmVyZW5jZSwgZmxvYXRpbmcsIGZsb2F0aW5nRm9jdXNFbGVtZW50LCBtb2RhbCwgdHJlZSwgcG9ydGFsQ29udGV4dCwgb25PcGVuQ2hhbmdlLCBjbG9zZU9uRm9jdXNPdXQsIHJlc3RvcmVGb2N1cywgZ2V0VGFiYmFibGVDb250ZW50LCBpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gsIGdldE5vZGVJZCwgb3JkZXJSZWZdKTtcbiAgY29uc3QgYmVmb3JlR3VhcmRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGFmdGVyR3VhcmRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IG1lcmdlZEJlZm9yZUd1YXJkUmVmID0gdXNlTGl0ZU1lcmdlUmVmcyhbYmVmb3JlR3VhcmRSZWYsIHBvcnRhbENvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IHBvcnRhbENvbnRleHQuYmVmb3JlSW5zaWRlUmVmXSk7XG4gIGNvbnN0IG1lcmdlZEFmdGVyR3VhcmRSZWYgPSB1c2VMaXRlTWVyZ2VSZWZzKFthZnRlckd1YXJkUmVmLCBwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LmFmdGVySW5zaWRlUmVmXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgdmFyIF9wb3J0YWxDb250ZXh0JHBvcnRhbCwgX2FuY2VzdG9ycyRmaW5kO1xuICAgIGlmIChkaXNhYmxlZCkgcmV0dXJuO1xuICAgIGlmICghZmxvYXRpbmcpIHJldHVybjtcblxuICAgIC8vIERvbid0IGhpZGUgcG9ydGFscyBuZXN0ZWQgd2l0aGluIHRoZSBwYXJlbnQgcG9ydGFsLlxuICAgIGNvbnN0IHBvcnRhbE5vZGVzID0gQXJyYXkuZnJvbSgocG9ydGFsQ29udGV4dCA9PSBudWxsIHx8IChfcG9ydGFsQ29udGV4dCRwb3J0YWwgPSBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpID09IG51bGwgPyB2b2lkIDAgOiBfcG9ydGFsQ29udGV4dCRwb3J0YWwucXVlcnlTZWxlY3RvckFsbChcIltcIiArIGNyZWF0ZUF0dHJpYnV0ZSgncG9ydGFsJykgKyBcIl1cIikpIHx8IFtdKTtcbiAgICBjb25zdCBhbmNlc3RvcnMgPSB0cmVlID8gZ2V0Tm9kZUFuY2VzdG9ycyh0cmVlLm5vZGVzUmVmLmN1cnJlbnQsIGdldE5vZGVJZCgpKSA6IFtdO1xuICAgIGNvbnN0IGFuY2VzdG9yRmxvYXRpbmdOb2RlcyA9IHRyZWUgJiYgIW1vZGFsID8gYW5jZXN0b3JzLm1hcChub2RlID0+IHtcbiAgICAgIHZhciBfbm9kZSRjb250ZXh0NjtcbiAgICAgIHJldHVybiAoX25vZGUkY29udGV4dDYgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Ni5lbGVtZW50cy5mbG9hdGluZztcbiAgICB9KSA6IFtdO1xuICAgIGNvbnN0IHJvb3RBbmNlc3RvckNvbWJvYm94RG9tUmVmZXJlbmNlID0gKF9hbmNlc3RvcnMkZmluZCA9IGFuY2VzdG9ycy5maW5kKG5vZGUgPT4ge1xuICAgICAgdmFyIF9ub2RlJGNvbnRleHQ3O1xuICAgICAgcmV0dXJuIGlzVHlwZWFibGVDb21ib2JveCgoKF9ub2RlJGNvbnRleHQ3ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDcuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSB8fCBudWxsKTtcbiAgICB9KSkgPT0gbnVsbCB8fCAoX2FuY2VzdG9ycyRmaW5kID0gX2FuY2VzdG9ycyRmaW5kLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfYW5jZXN0b3JzJGZpbmQuZWxlbWVudHMuZG9tUmVmZXJlbmNlO1xuICAgIGNvbnN0IGluc2lkZUVsZW1lbnRzID0gW2Zsb2F0aW5nLCByb290QW5jZXN0b3JDb21ib2JveERvbVJlZmVyZW5jZSwgLi4ucG9ydGFsTm9kZXMsIC4uLmFuY2VzdG9yRmxvYXRpbmdOb2RlcywgLi4uZ2V0SW5zaWRlRWxlbWVudHMoKSwgc3RhcnREaXNtaXNzQnV0dG9uUmVmLmN1cnJlbnQsIGVuZERpc21pc3NCdXR0b25SZWYuY3VycmVudCwgYmVmb3JlR3VhcmRSZWYuY3VycmVudCwgYWZ0ZXJHdWFyZFJlZi5jdXJyZW50LCBwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LmJlZm9yZU91dHNpZGVSZWYuY3VycmVudCwgcG9ydGFsQ29udGV4dCA9PSBudWxsID8gdm9pZCAwIDogcG9ydGFsQ29udGV4dC5hZnRlck91dHNpZGVSZWYuY3VycmVudCwgb3JkZXJSZWYuY3VycmVudC5pbmNsdWRlcygncmVmZXJlbmNlJykgfHwgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID8gZG9tUmVmZXJlbmNlIDogbnVsbF0uZmlsdGVyKHggPT4geCAhPSBudWxsKTtcbiAgICBjb25zdCBjbGVhbnVwID0gbW9kYWwgfHwgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID8gbWFya090aGVycyhpbnNpZGVFbGVtZW50cywgIXVzZUluZXJ0LCB1c2VJbmVydCkgOiBtYXJrT3RoZXJzKGluc2lkZUVsZW1lbnRzKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH07XG4gIH0sIFtkaXNhYmxlZCwgZG9tUmVmZXJlbmNlLCBmbG9hdGluZywgbW9kYWwsIG9yZGVyUmVmLCBwb3J0YWxDb250ZXh0LCBpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gsIGd1YXJkcywgdXNlSW5lcnQsIHRyZWUsIGdldE5vZGVJZCwgZ2V0SW5zaWRlRWxlbWVudHNdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIWlzSFRNTEVsZW1lbnQoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSByZXR1cm47XG4gICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQkMShmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgY29uc3QgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50ID0gYWN0aXZlRWxlbWVudChkb2MpO1xuXG4gICAgLy8gV2FpdCBmb3IgYW55IGxheW91dCBlZmZlY3Qgc3RhdGUgc2V0dGVycyB0byBleGVjdXRlIHRvIHNldCBgdGFiSW5kZXhgLlxuICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgIGNvbnN0IGZvY3VzYWJsZUVsZW1lbnRzID0gZ2V0VGFiYmFibGVFbGVtZW50cyhmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgICBjb25zdCBpbml0aWFsRm9jdXNWYWx1ZSA9IGluaXRpYWxGb2N1c1JlZi5jdXJyZW50O1xuICAgICAgY29uc3QgZWxUb0ZvY3VzID0gKHR5cGVvZiBpbml0aWFsRm9jdXNWYWx1ZSA9PT0gJ251bWJlcicgPyBmb2N1c2FibGVFbGVtZW50c1tpbml0aWFsRm9jdXNWYWx1ZV0gOiBpbml0aWFsRm9jdXNWYWx1ZS5jdXJyZW50KSB8fCBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICAgIGNvbnN0IGZvY3VzQWxyZWFkeUluc2lkZUZsb2F0aW5nRWwgPSBjb250YWlucyQxKGZsb2F0aW5nRm9jdXNFbGVtZW50LCBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQpO1xuICAgICAgaWYgKCFpZ25vcmVJbml0aWFsRm9jdXMgJiYgIWZvY3VzQWxyZWFkeUluc2lkZUZsb2F0aW5nRWwgJiYgb3Blbikge1xuICAgICAgICBlbnF1ZXVlRm9jdXMoZWxUb0ZvY3VzLCB7XG4gICAgICAgICAgcHJldmVudFNjcm9sbDogZWxUb0ZvY3VzID09PSBmbG9hdGluZ0ZvY3VzRWxlbWVudFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSwgW2Rpc2FibGVkLCBvcGVuLCBmbG9hdGluZ0ZvY3VzRWxlbWVudCwgaWdub3JlSW5pdGlhbEZvY3VzLCBnZXRUYWJiYWJsZUVsZW1lbnRzLCBpbml0aWFsRm9jdXNSZWZdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIWZsb2F0aW5nRm9jdXNFbGVtZW50KSByZXR1cm47XG4gICAgbGV0IHByZXZlbnRSZXR1cm5Gb2N1c1Njcm9sbCA9IGZhbHNlO1xuICAgIGNvbnN0IGRvYyA9IGdldERvY3VtZW50JDEoZmxvYXRpbmdGb2N1c0VsZW1lbnQpO1xuICAgIGNvbnN0IHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCA9IGFjdGl2ZUVsZW1lbnQoZG9jKTtcbiAgICBhZGRQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQocHJldmlvdXNseUZvY3VzZWRFbGVtZW50KTtcblxuICAgIC8vIERpc21pc3NpbmcgdmlhIG91dHNpZGUgcHJlc3Mgc2hvdWxkIGFsd2F5cyBpZ25vcmUgYHJldHVybkZvY3VzYCB0b1xuICAgIC8vIHByZXZlbnQgdW53YW50ZWQgc2Nyb2xsaW5nLlxuICAgIGZ1bmN0aW9uIG9uT3BlbkNoYW5nZShfcmVmKSB7XG4gICAgICBsZXQge1xuICAgICAgICByZWFzb24sXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBuZXN0ZWRcbiAgICAgIH0gPSBfcmVmO1xuICAgICAgaWYgKFsnaG92ZXInLCAnc2FmZS1wb2x5Z29uJ10uaW5jbHVkZXMocmVhc29uKSAmJiBldmVudC50eXBlID09PSAnbW91c2VsZWF2ZScpIHtcbiAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlYXNvbiAhPT0gJ291dHNpZGUtcHJlc3MnKSByZXR1cm47XG4gICAgICBpZiAobmVzdGVkKSB7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1Njcm9sbCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGlzVmlydHVhbENsaWNrKGV2ZW50KSB8fCBpc1ZpcnR1YWxQb2ludGVyRXZlbnQoZXZlbnQpKSB7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgaXNQcmV2ZW50U2Nyb2xsU3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLmZvY3VzKHtcbiAgICAgICAgICBnZXQgcHJldmVudFNjcm9sbCgpIHtcbiAgICAgICAgICAgIGlzUHJldmVudFNjcm9sbFN1cHBvcnRlZCA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlzUHJldmVudFNjcm9sbFN1cHBvcnRlZCkge1xuICAgICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzU2Nyb2xsID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2ZW50UmV0dXJuRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZXZlbnRzLm9uKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICBjb25zdCBmYWxsYmFja0VsID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBmYWxsYmFja0VsLnNldEF0dHJpYnV0ZSgndGFiaW5kZXgnLCAnLTEnKTtcbiAgICBmYWxsYmFja0VsLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgIE9iamVjdC5hc3NpZ24oZmFsbGJhY2tFbC5zdHlsZSwgSElEREVOX1NUWUxFUyk7XG4gICAgaWYgKGlzSW5zaWRlUG9ydGFsICYmIGRvbVJlZmVyZW5jZSkge1xuICAgICAgZG9tUmVmZXJlbmNlLmluc2VydEFkamFjZW50RWxlbWVudCgnYWZ0ZXJlbmQnLCBmYWxsYmFja0VsKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0UmV0dXJuRWxlbWVudCgpIHtcbiAgICAgIGlmICh0eXBlb2YgcmV0dXJuRm9jdXNSZWYuY3VycmVudCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIGNvbnN0IGVsID0gZG9tUmVmZXJlbmNlIHx8IGdldFByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCgpO1xuICAgICAgICByZXR1cm4gZWwgJiYgZWwuaXNDb25uZWN0ZWQgPyBlbCA6IGZhbGxiYWNrRWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0dXJuRm9jdXNSZWYuY3VycmVudC5jdXJyZW50IHx8IGZhbGxiYWNrRWw7XG4gICAgfVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBldmVudHMub2ZmKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICAgIGNvbnN0IGFjdGl2ZUVsID0gYWN0aXZlRWxlbWVudChkb2MpO1xuICAgICAgY29uc3QgaXNGb2N1c0luc2lkZUZsb2F0aW5nVHJlZSA9IGNvbnRhaW5zJDEoZmxvYXRpbmcsIGFjdGl2ZUVsKSB8fCB0cmVlICYmIGdldE5vZGVDaGlsZHJlbiQxKHRyZWUubm9kZXNSZWYuY3VycmVudCwgZ2V0Tm9kZUlkKCkpLnNvbWUobm9kZSA9PiB7XG4gICAgICAgIHZhciBfbm9kZSRjb250ZXh0ODtcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5zJDEoKF9ub2RlJGNvbnRleHQ4ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDguZWxlbWVudHMuZmxvYXRpbmcsIGFjdGl2ZUVsKTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcmV0dXJuRWxlbWVudCA9IGdldFJldHVybkVsZW1lbnQoKTtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgLy8gVGhpcyBpcyBgcmV0dXJuRWxlbWVudGAsIGlmIGl0J3MgdGFiYmFibGUsIG9yIGl0cyBmaXJzdCB0YWJiYWJsZSBjaGlsZC5cbiAgICAgICAgY29uc3QgdGFiYmFibGVSZXR1cm5FbGVtZW50ID0gZ2V0Rmlyc3RUYWJiYWJsZUVsZW1lbnQocmV0dXJuRWxlbWVudCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICAgICAgICByZXR1cm5Gb2N1c1JlZi5jdXJyZW50ICYmICFwcmV2ZW50UmV0dXJuRm9jdXNSZWYuY3VycmVudCAmJiBpc0hUTUxFbGVtZW50KHRhYmJhYmxlUmV0dXJuRWxlbWVudCkgJiYgKFxuICAgICAgICAvLyBJZiB0aGUgZm9jdXMgbW92ZWQgc29tZXdoZXJlIGVsc2UgYWZ0ZXIgbW91bnQsIGF2b2lkIHJldHVybmluZyBmb2N1c1xuICAgICAgICAvLyBzaW5jZSBpdCBsaWtlbHkgZW50ZXJlZCBhIGRpZmZlcmVudCBlbGVtZW50IHdoaWNoIHNob3VsZCBiZVxuICAgICAgICAvLyByZXNwZWN0ZWQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMjYwN1xuICAgICAgICB0YWJiYWJsZVJldHVybkVsZW1lbnQgIT09IGFjdGl2ZUVsICYmIGFjdGl2ZUVsICE9PSBkb2MuYm9keSA/IGlzRm9jdXNJbnNpZGVGbG9hdGluZ1RyZWUgOiB0cnVlKSkge1xuICAgICAgICAgIHRhYmJhYmxlUmV0dXJuRWxlbWVudC5mb2N1cyh7XG4gICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiBwcmV2ZW50UmV0dXJuRm9jdXNTY3JvbGxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmYWxsYmFja0VsLnJlbW92ZSgpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBmbG9hdGluZywgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIHJldHVybkZvY3VzUmVmLCBkYXRhUmVmLCBldmVudHMsIHRyZWUsIGlzSW5zaWRlUG9ydGFsLCBkb21SZWZlcmVuY2UsIGdldE5vZGVJZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIC8vIFRoZSBgcmV0dXJuRm9jdXNgIGNsZWFudXAgYmVoYXZpb3IgaXMgaW5zaWRlIGEgbWljcm90YXNrOyBlbnN1cmUgd2VcbiAgICAvLyB3YWl0IGZvciBpdCB0byBjb21wbGV0ZSBiZWZvcmUgcmVzZXR0aW5nIHRoZSBmbGFnLlxuICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSk7XG4gIH0sIFtkaXNhYmxlZF0pO1xuXG4gIC8vIFN5bmNocm9uaXplIHRoZSBgY29udGV4dGAgJiBgbW9kYWxgIHZhbHVlIHRvIHRoZSBGbG9hdGluZ1BvcnRhbCBjb250ZXh0LlxuICAvLyBJdCB3aWxsIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCBpdCBuZWVkcyB0byByZW5kZXIgaXRzIG93biBndWFyZHMuXG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFwb3J0YWxDb250ZXh0KSByZXR1cm47XG4gICAgcG9ydGFsQ29udGV4dC5zZXRGb2N1c01hbmFnZXJTdGF0ZSh7XG4gICAgICBtb2RhbCxcbiAgICAgIGNsb3NlT25Gb2N1c091dCxcbiAgICAgIG9wZW4sXG4gICAgICBvbk9wZW5DaGFuZ2UsXG4gICAgICBkb21SZWZlcmVuY2VcbiAgICB9KTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgcG9ydGFsQ29udGV4dC5zZXRGb2N1c01hbmFnZXJTdGF0ZShudWxsKTtcbiAgICB9O1xuICB9LCBbZGlzYWJsZWQsIHBvcnRhbENvbnRleHQsIG1vZGFsLCBvcGVuLCBvbk9wZW5DaGFuZ2UsIGNsb3NlT25Gb2N1c091dCwgZG9tUmVmZXJlbmNlXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFmbG9hdGluZ0ZvY3VzRWxlbWVudCkgcmV0dXJuO1xuICAgIGhhbmRsZVRhYkluZGV4KGZsb2F0aW5nRm9jdXNFbGVtZW50LCBvcmRlclJlZik7XG4gIH0sIFtkaXNhYmxlZCwgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIG9yZGVyUmVmXSk7XG4gIGZ1bmN0aW9uIHJlbmRlckRpc21pc3NCdXR0b24obG9jYXRpb24pIHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIXZpc3VhbGx5SGlkZGVuRGlzbWlzcyB8fCAhbW9kYWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gLyojX19QVVJFX18qL2pzeChWaXN1YWxseUhpZGRlbkRpc21pc3MsIHtcbiAgICAgIHJlZjogbG9jYXRpb24gPT09ICdzdGFydCcgPyBzdGFydERpc21pc3NCdXR0b25SZWYgOiBlbmREaXNtaXNzQnV0dG9uUmVmLFxuICAgICAgb25DbGljazogZXZlbnQgPT4gb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCksXG4gICAgICBjaGlsZHJlbjogdHlwZW9mIHZpc3VhbGx5SGlkZGVuRGlzbWlzcyA9PT0gJ3N0cmluZycgPyB2aXN1YWxseUhpZGRlbkRpc21pc3MgOiAnRGlzbWlzcydcbiAgICB9KTtcbiAgfVxuICBjb25zdCBzaG91bGRSZW5kZXJHdWFyZHMgPSAhZGlzYWJsZWQgJiYgZ3VhcmRzICYmIChtb2RhbCA/ICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggOiB0cnVlKSAmJiAoaXNJbnNpZGVQb3J0YWwgfHwgbW9kYWwpO1xuICByZXR1cm4gLyojX19QVVJFX18qL2pzeHMoRnJhZ21lbnQsIHtcbiAgICBjaGlsZHJlbjogW3Nob3VsZFJlbmRlckd1YXJkcyAmJiAvKiNfX1BVUkVfXyovanN4KEZvY3VzR3VhcmQsIHtcbiAgICAgIFwiZGF0YS10eXBlXCI6IFwiaW5zaWRlXCIsXG4gICAgICByZWY6IG1lcmdlZEJlZm9yZUd1YXJkUmVmLFxuICAgICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgICBpZiAobW9kYWwpIHtcbiAgICAgICAgICBjb25zdCBlbHMgPSBnZXRUYWJiYWJsZUVsZW1lbnRzKCk7XG4gICAgICAgICAgZW5xdWV1ZUZvY3VzKG9yZGVyWzBdID09PSAncmVmZXJlbmNlJyA/IGVsc1swXSA6IGVsc1tlbHMubGVuZ3RoIC0gMV0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBvcnRhbENvbnRleHQgIT0gbnVsbCAmJiBwb3J0YWxDb250ZXh0LnByZXNlcnZlVGFiT3JkZXIgJiYgcG9ydGFsQ29udGV4dC5wb3J0YWxOb2RlKSB7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgICBpZiAoaXNPdXRzaWRlRXZlbnQoZXZlbnQsIHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IG5leHRUYWJiYWJsZSA9IGdldE5leHRUYWJiYWJsZShkb21SZWZlcmVuY2UpO1xuICAgICAgICAgICAgbmV4dFRhYmJhYmxlID09IG51bGwgfHwgbmV4dFRhYmJhYmxlLmZvY3VzKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBfcG9ydGFsQ29udGV4dCRiZWZvcmU7XG4gICAgICAgICAgICAoX3BvcnRhbENvbnRleHQkYmVmb3JlID0gcG9ydGFsQ29udGV4dC5iZWZvcmVPdXRzaWRlUmVmLmN1cnJlbnQpID09IG51bGwgfHwgX3BvcnRhbENvbnRleHQkYmVmb3JlLmZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggJiYgcmVuZGVyRGlzbWlzc0J1dHRvbignc3RhcnQnKSwgY2hpbGRyZW4sIHJlbmRlckRpc21pc3NCdXR0b24oJ2VuZCcpLCBzaG91bGRSZW5kZXJHdWFyZHMgJiYgLyojX19QVVJFX18qL2pzeChGb2N1c0d1YXJkLCB7XG4gICAgICBcImRhdGEtdHlwZVwiOiBcImluc2lkZVwiLFxuICAgICAgcmVmOiBtZXJnZWRBZnRlckd1YXJkUmVmLFxuICAgICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgICBpZiAobW9kYWwpIHtcbiAgICAgICAgICBlbnF1ZXVlRm9jdXMoZ2V0VGFiYmFibGVFbGVtZW50cygpWzBdKTtcbiAgICAgICAgfSBlbHNlIGlmIChwb3J0YWxDb250ZXh0ICE9IG51bGwgJiYgcG9ydGFsQ29udGV4dC5wcmVzZXJ2ZVRhYk9yZGVyICYmIHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSkge1xuICAgICAgICAgIGlmIChjbG9zZU9uRm9jdXNPdXQpIHtcbiAgICAgICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzT3V0c2lkZUV2ZW50KGV2ZW50LCBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2VGFiYmFibGUgPSBnZXRQcmV2aW91c1RhYmJhYmxlKGRvbVJlZmVyZW5jZSk7XG4gICAgICAgICAgICBwcmV2VGFiYmFibGUgPT0gbnVsbCB8fCBwcmV2VGFiYmFibGUuZm9jdXMoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIF9wb3J0YWxDb250ZXh0JGFmdGVyTztcbiAgICAgICAgICAgIChfcG9ydGFsQ29udGV4dCRhZnRlck8gPSBwb3J0YWxDb250ZXh0LmFmdGVyT3V0c2lkZVJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9wb3J0YWxDb250ZXh0JGFmdGVyTy5mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXVxuICB9KTtcbn1cblxubGV0IGxvY2tDb3VudCA9IDA7XG5mdW5jdGlvbiBlbmFibGVTY3JvbGxMb2NrKCkge1xuICBjb25zdCBpc0lPUyA9IC9pUChob25lfGFkfG9kKXxpT1MvLnRlc3QoZ2V0UGxhdGZvcm0oKSk7XG4gIGNvbnN0IGJvZHlTdHlsZSA9IGRvY3VtZW50LmJvZHkuc3R5bGU7XG4gIC8vIFJUTCA8Ym9keT4gc2Nyb2xsYmFyXG4gIGNvbnN0IHNjcm9sbGJhclggPSBNYXRoLnJvdW5kKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0KSArIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xuICBjb25zdCBwYWRkaW5nUHJvcCA9IHNjcm9sbGJhclggPyAncGFkZGluZ0xlZnQnIDogJ3BhZGRpbmdSaWdodCc7XG4gIGNvbnN0IHNjcm9sbGJhcldpZHRoID0gd2luZG93LmlubmVyV2lkdGggLSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gIGNvbnN0IHNjcm9sbFggPSBib2R5U3R5bGUubGVmdCA/IHBhcnNlRmxvYXQoYm9keVN0eWxlLmxlZnQpIDogd2luZG93LnNjcm9sbFg7XG4gIGNvbnN0IHNjcm9sbFkgPSBib2R5U3R5bGUudG9wID8gcGFyc2VGbG9hdChib2R5U3R5bGUudG9wKSA6IHdpbmRvdy5zY3JvbGxZO1xuICBib2R5U3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgaWYgKHNjcm9sbGJhcldpZHRoKSB7XG4gICAgYm9keVN0eWxlW3BhZGRpbmdQcm9wXSA9IHNjcm9sbGJhcldpZHRoICsgXCJweFwiO1xuICB9XG5cbiAgLy8gT25seSBpT1MgZG9lc24ndCByZXNwZWN0IGBvdmVyZmxvdzogaGlkZGVuYCBvbiBkb2N1bWVudC5ib2R5LCBhbmQgdGhpc1xuICAvLyB0ZWNobmlxdWUgaGFzIGZld2VyIHNpZGUgZWZmZWN0cy5cbiAgaWYgKGlzSU9TKSB7XG4gICAgdmFyIF93aW5kb3ckdmlzdWFsVmlld3BvciwgX3dpbmRvdyR2aXN1YWxWaWV3cG9yMjtcbiAgICAvLyBpT1MgMTIgZG9lcyBub3Qgc3VwcG9ydCBgdmlzdWFsVmlld3BvcnRgLlxuICAgIGNvbnN0IG9mZnNldExlZnQgPSAoKF93aW5kb3ckdmlzdWFsVmlld3BvciA9IHdpbmRvdy52aXN1YWxWaWV3cG9ydCkgPT0gbnVsbCA/IHZvaWQgMCA6IF93aW5kb3ckdmlzdWFsVmlld3Bvci5vZmZzZXRMZWZ0KSB8fCAwO1xuICAgIGNvbnN0IG9mZnNldFRvcCA9ICgoX3dpbmRvdyR2aXN1YWxWaWV3cG9yMiA9IHdpbmRvdy52aXN1YWxWaWV3cG9ydCkgPT0gbnVsbCA/IHZvaWQgMCA6IF93aW5kb3ckdmlzdWFsVmlld3BvcjIub2Zmc2V0VG9wKSB8fCAwO1xuICAgIE9iamVjdC5hc3NpZ24oYm9keVN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcbiAgICAgIHRvcDogLShzY3JvbGxZIC0gTWF0aC5mbG9vcihvZmZzZXRUb3ApKSArIFwicHhcIixcbiAgICAgIGxlZnQ6IC0oc2Nyb2xsWCAtIE1hdGguZmxvb3Iob2Zmc2V0TGVmdCkpICsgXCJweFwiLFxuICAgICAgcmlnaHQ6ICcwJ1xuICAgIH0pO1xuICB9XG4gIHJldHVybiAoKSA9PiB7XG4gICAgT2JqZWN0LmFzc2lnbihib2R5U3R5bGUsIHtcbiAgICAgIG92ZXJmbG93OiAnJyxcbiAgICAgIFtwYWRkaW5nUHJvcF06ICcnXG4gICAgfSk7XG4gICAgaWYgKGlzSU9TKSB7XG4gICAgICBPYmplY3QuYXNzaWduKGJvZHlTdHlsZSwge1xuICAgICAgICBwb3NpdGlvbjogJycsXG4gICAgICAgIHRvcDogJycsXG4gICAgICAgIGxlZnQ6ICcnLFxuICAgICAgICByaWdodDogJydcbiAgICAgIH0pO1xuICAgICAgd2luZG93LnNjcm9sbFRvKHNjcm9sbFgsIHNjcm9sbFkpO1xuICAgIH1cbiAgfTtcbn1cbmxldCBjbGVhbnVwID0gKCkgPT4ge307XG5cbi8qKlxuICogUHJvdmlkZXMgYmFzZSBzdHlsaW5nIGZvciBhIGZpeGVkIG92ZXJsYXkgZWxlbWVudCB0byBkaW0gY29udGVudCBvciBibG9ja1xuICogcG9pbnRlciBldmVudHMgYmVoaW5kIGEgZmxvYXRpbmcgZWxlbWVudC5cbiAqIEl0J3MgYSByZWd1bGFyIGA8ZGl2PmAsIHNvIGl0IGNhbiBiZSBzdHlsZWQgdmlhIGFueSBDU1Mgc29sdXRpb24geW91IHByZWZlci5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ092ZXJsYXlcbiAqL1xuY29uc3QgRmxvYXRpbmdPdmVybGF5ID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRmxvYXRpbmdPdmVybGF5KHByb3BzLCByZWYpIHtcbiAgY29uc3Qge1xuICAgIGxvY2tTY3JvbGwgPSBmYWxzZSxcbiAgICAuLi5yZXN0XG4gIH0gPSBwcm9wcztcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWxvY2tTY3JvbGwpIHJldHVybjtcbiAgICBsb2NrQ291bnQrKztcbiAgICBpZiAobG9ja0NvdW50ID09PSAxKSB7XG4gICAgICBjbGVhbnVwID0gZW5hYmxlU2Nyb2xsTG9jaygpO1xuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgbG9ja0NvdW50LS07XG4gICAgICBpZiAobG9ja0NvdW50ID09PSAwKSB7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbbG9ja1Njcm9sbF0pO1xuICByZXR1cm4gLyojX19QVVJFX18qL2pzeChcImRpdlwiLCB7XG4gICAgcmVmOiByZWYsXG4gICAgLi4ucmVzdCxcbiAgICBzdHlsZToge1xuICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICBvdmVyZmxvdzogJ2F1dG8nLFxuICAgICAgdG9wOiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgLi4ucmVzdC5zdHlsZVxuICAgIH1cbiAgfSk7XG59KTtcblxuZnVuY3Rpb24gaXNCdXR0b25UYXJnZXQoZXZlbnQpIHtcbiAgcmV0dXJuIGlzSFRNTEVsZW1lbnQoZXZlbnQudGFyZ2V0KSAmJiBldmVudC50YXJnZXQudGFnTmFtZSA9PT0gJ0JVVFRPTic7XG59XG5mdW5jdGlvbiBpc0FuY2hvclRhcmdldChldmVudCkge1xuICByZXR1cm4gaXNIVE1MRWxlbWVudChldmVudC50YXJnZXQpICYmIGV2ZW50LnRhcmdldC50YWdOYW1lID09PSAnQSc7XG59XG5mdW5jdGlvbiBpc1NwYWNlSWdub3JlZChlbGVtZW50KSB7XG4gIHJldHVybiBpc1R5cGVhYmxlRWxlbWVudChlbGVtZW50KTtcbn1cbi8qKlxuICogT3BlbnMgb3IgY2xvc2VzIHRoZSBmbG9hdGluZyBlbGVtZW50IHdoZW4gY2xpY2tpbmcgdGhlIHJlZmVyZW5jZSBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUNsaWNrXG4gKi9cbmZ1bmN0aW9uIHVzZUNsaWNrKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50czoge1xuICAgICAgZG9tUmVmZXJlbmNlXG4gICAgfVxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIGV2ZW50OiBldmVudE9wdGlvbiA9ICdjbGljaycsXG4gICAgdG9nZ2xlID0gdHJ1ZSxcbiAgICBpZ25vcmVNb3VzZSA9IGZhbHNlLFxuICAgIGtleWJvYXJkSGFuZGxlcnMgPSB0cnVlLFxuICAgIHN0aWNrSWZPcGVuID0gdHJ1ZVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHBvaW50ZXJUeXBlUmVmID0gUmVhY3QudXNlUmVmKCk7XG4gIGNvbnN0IGRpZEtleURvd25SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25Qb2ludGVyRG93bihldmVudCkge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IGV2ZW50LnBvaW50ZXJUeXBlO1xuICAgIH0sXG4gICAgb25Nb3VzZURvd24oZXZlbnQpIHtcbiAgICAgIGNvbnN0IHBvaW50ZXJUeXBlID0gcG9pbnRlclR5cGVSZWYuY3VycmVudDtcblxuICAgICAgLy8gSWdub3JlIGFsbCBidXR0b25zIGV4Y2VwdCBmb3IgdGhlIFwibWFpblwiIGJ1dHRvbi5cbiAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Nb3VzZUV2ZW50L2J1dHRvblxuICAgICAgaWYgKGV2ZW50LmJ1dHRvbiAhPT0gMCkgcmV0dXJuO1xuICAgICAgaWYgKGV2ZW50T3B0aW9uID09PSAnY2xpY2snKSByZXR1cm47XG4gICAgICBpZiAoaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZSwgdHJ1ZSkgJiYgaWdub3JlTW91c2UpIHJldHVybjtcbiAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSAmJiAoZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCAmJiBzdGlja0lmT3BlbiA/IGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgOiB0cnVlKSkge1xuICAgICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnY2xpY2snKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFByZXZlbnQgc3RlYWxpbmcgZm9jdXMgZnJvbSB0aGUgZmxvYXRpbmcgZWxlbWVudFxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgfVxuICAgIH0sXG4gICAgb25DbGljayhldmVudCkge1xuICAgICAgY29uc3QgcG9pbnRlclR5cGUgPSBwb2ludGVyVHlwZVJlZi5jdXJyZW50O1xuICAgICAgaWYgKGV2ZW50T3B0aW9uID09PSAnbW91c2Vkb3duJyAmJiBwb2ludGVyVHlwZVJlZi5jdXJyZW50KSB7XG4gICAgICAgIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlLCB0cnVlKSAmJiBpZ25vcmVNb3VzZSkgcmV0dXJuO1xuICAgICAgaWYgKG9wZW4gJiYgdG9nZ2xlICYmIChkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50ICYmIHN0aWNrSWZPcGVuID8gZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudC50eXBlID09PSAnY2xpY2snIDogdHJ1ZSkpIHtcbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgfVxuICAgIH0sXG4gICAgb25LZXlEb3duKGV2ZW50KSB7XG4gICAgICBwb2ludGVyVHlwZVJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHwgIWtleWJvYXJkSGFuZGxlcnMgfHwgaXNCdXR0b25UYXJnZXQoZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICcgJyAmJiAhaXNTcGFjZUlnbm9yZWQoZG9tUmVmZXJlbmNlKSkge1xuICAgICAgICAvLyBQcmV2ZW50IHNjcm9sbGluZ1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBkaWRLZXlEb3duUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKGlzQW5jaG9yVGFyZ2V0KGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSkge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIG9uS2V5VXAoZXZlbnQpIHtcbiAgICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkIHx8ICFrZXlib2FyZEhhbmRsZXJzIHx8IGlzQnV0dG9uVGFyZ2V0KGV2ZW50KSB8fCBpc1NwYWNlSWdub3JlZChkb21SZWZlcmVuY2UpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICcgJyAmJiBkaWRLZXlEb3duUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgZGlkS2V5RG93blJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSkge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pLCBbZGF0YVJlZiwgZG9tUmVmZXJlbmNlLCBldmVudE9wdGlvbiwgaWdub3JlTW91c2UsIGtleWJvYXJkSGFuZGxlcnMsIG9uT3BlbkNoYW5nZSwgb3Blbiwgc3RpY2tJZk9wZW4sIHRvZ2dsZV0pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiBlbmFibGVkID8ge1xuICAgIHJlZmVyZW5jZVxuICB9IDoge30sIFtlbmFibGVkLCByZWZlcmVuY2VdKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlydHVhbEVsZW1lbnQoZG9tRWxlbWVudCwgZGF0YSkge1xuICBsZXQgb2Zmc2V0WCA9IG51bGw7XG4gIGxldCBvZmZzZXRZID0gbnVsbDtcbiAgbGV0IGlzQXV0b1VwZGF0ZUV2ZW50ID0gZmFsc2U7XG4gIHJldHVybiB7XG4gICAgY29udGV4dEVsZW1lbnQ6IGRvbUVsZW1lbnQgfHwgdW5kZWZpbmVkLFxuICAgIGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIHtcbiAgICAgIHZhciBfZGF0YSRkYXRhUmVmJGN1cnJlbnQ7XG4gICAgICBjb25zdCBkb21SZWN0ID0gKGRvbUVsZW1lbnQgPT0gbnVsbCA/IHZvaWQgMCA6IGRvbUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpIHx8IHtcbiAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgIGhlaWdodDogMCxcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogMFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGlzWEF4aXMgPSBkYXRhLmF4aXMgPT09ICd4JyB8fCBkYXRhLmF4aXMgPT09ICdib3RoJztcbiAgICAgIGNvbnN0IGlzWUF4aXMgPSBkYXRhLmF4aXMgPT09ICd5JyB8fCBkYXRhLmF4aXMgPT09ICdib3RoJztcbiAgICAgIGNvbnN0IGNhblRyYWNrQ3Vyc29yT25BdXRvVXBkYXRlID0gWydtb3VzZWVudGVyJywgJ21vdXNlbW92ZSddLmluY2x1ZGVzKCgoX2RhdGEkZGF0YVJlZiRjdXJyZW50ID0gZGF0YS5kYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGEkZGF0YVJlZiRjdXJyZW50LnR5cGUpIHx8ICcnKSAmJiBkYXRhLnBvaW50ZXJUeXBlICE9PSAndG91Y2gnO1xuICAgICAgbGV0IHdpZHRoID0gZG9tUmVjdC53aWR0aDtcbiAgICAgIGxldCBoZWlnaHQgPSBkb21SZWN0LmhlaWdodDtcbiAgICAgIGxldCB4ID0gZG9tUmVjdC54O1xuICAgICAgbGV0IHkgPSBkb21SZWN0Lnk7XG4gICAgICBpZiAob2Zmc2V0WCA9PSBudWxsICYmIGRhdGEueCAmJiBpc1hBeGlzKSB7XG4gICAgICAgIG9mZnNldFggPSBkb21SZWN0LnggLSBkYXRhLng7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0WSA9PSBudWxsICYmIGRhdGEueSAmJiBpc1lBeGlzKSB7XG4gICAgICAgIG9mZnNldFkgPSBkb21SZWN0LnkgLSBkYXRhLnk7XG4gICAgICB9XG4gICAgICB4IC09IG9mZnNldFggfHwgMDtcbiAgICAgIHkgLT0gb2Zmc2V0WSB8fCAwO1xuICAgICAgd2lkdGggPSAwO1xuICAgICAgaGVpZ2h0ID0gMDtcbiAgICAgIGlmICghaXNBdXRvVXBkYXRlRXZlbnQgfHwgY2FuVHJhY2tDdXJzb3JPbkF1dG9VcGRhdGUpIHtcbiAgICAgICAgd2lkdGggPSBkYXRhLmF4aXMgPT09ICd5JyA/IGRvbVJlY3Qud2lkdGggOiAwO1xuICAgICAgICBoZWlnaHQgPSBkYXRhLmF4aXMgPT09ICd4JyA/IGRvbVJlY3QuaGVpZ2h0IDogMDtcbiAgICAgICAgeCA9IGlzWEF4aXMgJiYgZGF0YS54ICE9IG51bGwgPyBkYXRhLnggOiB4O1xuICAgICAgICB5ID0gaXNZQXhpcyAmJiBkYXRhLnkgIT0gbnVsbCA/IGRhdGEueSA6IHk7XG4gICAgICB9IGVsc2UgaWYgKGlzQXV0b1VwZGF0ZUV2ZW50ICYmICFjYW5UcmFja0N1cnNvck9uQXV0b1VwZGF0ZSkge1xuICAgICAgICBoZWlnaHQgPSBkYXRhLmF4aXMgPT09ICd4JyA/IGRvbVJlY3QuaGVpZ2h0IDogaGVpZ2h0O1xuICAgICAgICB3aWR0aCA9IGRhdGEuYXhpcyA9PT0gJ3knID8gZG9tUmVjdC53aWR0aCA6IHdpZHRoO1xuICAgICAgfVxuICAgICAgaXNBdXRvVXBkYXRlRXZlbnQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodCxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgICAgdG9wOiB5LFxuICAgICAgICByaWdodDogeCArIHdpZHRoLFxuICAgICAgICBib3R0b206IHkgKyBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IHhcbiAgICAgIH07XG4gICAgfVxuICB9O1xufVxuZnVuY3Rpb24gaXNNb3VzZUJhc2VkRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIGV2ZW50ICE9IG51bGwgJiYgZXZlbnQuY2xpZW50WCAhPSBudWxsO1xufVxuLyoqXG4gKiBQb3NpdGlvbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgcmVsYXRpdmUgdG8gYSBjbGllbnQgcG9pbnQgKGluIHRoZSB2aWV3cG9ydCksXG4gKiBzdWNoIGFzIHRoZSBtb3VzZSBwb3NpdGlvbi4gQnkgZGVmYXVsdCwgaXQgZm9sbG93cyB0aGUgbW91c2UgY3Vyc29yLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUNsaWVudFBvaW50XG4gKi9cbmZ1bmN0aW9uIHVzZUNsaWVudFBvaW50KGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBkYXRhUmVmLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICBmbG9hdGluZyxcbiAgICAgIGRvbVJlZmVyZW5jZVxuICAgIH0sXG4gICAgcmVmc1xuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIGF4aXMgPSAnYm90aCcsXG4gICAgeCA9IG51bGwsXG4gICAgeSA9IG51bGxcbiAgfSA9IHByb3BzO1xuICBjb25zdCBpbml0aWFsUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgY2xlYW51cExpc3RlbmVyUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBbcG9pbnRlclR5cGUsIHNldFBvaW50ZXJUeXBlXSA9IFJlYWN0LnVzZVN0YXRlKCk7XG4gIGNvbnN0IFtyZWFjdGl2ZSwgc2V0UmVhY3RpdmVdID0gUmVhY3QudXNlU3RhdGUoW10pO1xuICBjb25zdCBzZXRSZWZlcmVuY2UgPSB1c2VFZmZlY3RFdmVudCgoeCwgeSkgPT4ge1xuICAgIGlmIChpbml0aWFsUmVmLmN1cnJlbnQpIHJldHVybjtcblxuICAgIC8vIFByZXZlbnQgc2V0dGluZyBpZiB0aGUgb3BlbiBldmVudCB3YXMgbm90IGEgbW91c2UtbGlrZSBvbmVcbiAgICAvLyAoZS5nLiBmb2N1cyB0byBvcGVuLCB0aGVuIGhvdmVyIG92ZXIgdGhlIHJlZmVyZW5jZSBlbGVtZW50KS5cbiAgICAvLyBPbmx5IGFwcGx5IGlmIHRoZSBldmVudCBleGlzdHMuXG4gICAgaWYgKGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgJiYgIWlzTW91c2VCYXNlZEV2ZW50KGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlZnMuc2V0UG9zaXRpb25SZWZlcmVuY2UoY3JlYXRlVmlydHVhbEVsZW1lbnQoZG9tUmVmZXJlbmNlLCB7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIGF4aXMsXG4gICAgICBkYXRhUmVmLFxuICAgICAgcG9pbnRlclR5cGVcbiAgICB9KSk7XG4gIH0pO1xuICBjb25zdCBoYW5kbGVSZWZlcmVuY2VFbnRlck9yTW92ZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICBpZiAoeCAhPSBudWxsIHx8IHkgIT0gbnVsbCkgcmV0dXJuO1xuICAgIGlmICghb3Blbikge1xuICAgICAgc2V0UmVmZXJlbmNlKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xuICAgIH0gZWxzZSBpZiAoIWNsZWFudXBMaXN0ZW5lclJlZi5jdXJyZW50KSB7XG4gICAgICAvLyBJZiB0aGVyZSdzIG5vIGNsZWFudXAsIHRoZXJlJ3Mgbm8gbGlzdGVuZXIsIGJ1dCB3ZSB3YW50IHRvIGVuc3VyZVxuICAgICAgLy8gd2UgYWRkIHRoZSBsaXN0ZW5lciBpZiB0aGUgY3Vyc29yIGxhbmRlZCBvbiB0aGUgZmxvYXRpbmcgZWxlbWVudCBhbmRcbiAgICAgIC8vIHRoZW4gYmFjayBvbiB0aGUgcmVmZXJlbmNlIChpLmUuIGl0J3MgaW50ZXJhY3RpdmUpLlxuICAgICAgc2V0UmVhY3RpdmUoW10pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gSWYgdGhlIHBvaW50ZXIgaXMgYSBtb3VzZS1saWtlIHBvaW50ZXIsIHdlIHdhbnQgdG8gY29udGludWUgZm9sbG93aW5nIHRoZVxuICAvLyBtb3VzZSBldmVuIGlmIHRoZSBmbG9hdGluZyBlbGVtZW50IGlzIHRyYW5zaXRpb25pbmcgb3V0LiBPbiB0b3VjaFxuICAvLyBkZXZpY2VzLCB0aGlzIGlzIHVuZGVzaXJhYmxlIGJlY2F1c2UgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2lsbCBtb3ZlIHRvXG4gIC8vIHRoZSBkaXNtaXNzYWwgdG91Y2ggcG9pbnQuXG4gIGNvbnN0IG9wZW5DaGVjayA9IGlzTW91c2VMaWtlUG9pbnRlclR5cGUocG9pbnRlclR5cGUpID8gZmxvYXRpbmcgOiBvcGVuO1xuICBjb25zdCBhZGRMaXN0ZW5lciA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAvLyBFeHBsaWNpdGx5IHNwZWNpZmllZCBgeGAvYHlgIGNvb3JkaW5hdGVzIHNob3VsZG4ndCBhZGQgYSBsaXN0ZW5lci5cbiAgICBpZiAoIW9wZW5DaGVjayB8fCAhZW5hYmxlZCB8fCB4ICE9IG51bGwgfHwgeSAhPSBudWxsKSByZXR1cm47XG4gICAgY29uc3Qgd2luID0gZ2V0V2luZG93KGZsb2F0aW5nKTtcbiAgICBmdW5jdGlvbiBoYW5kbGVNb3VzZU1vdmUoZXZlbnQpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50KTtcbiAgICAgIGlmICghY29udGFpbnMkMShmbG9hdGluZywgdGFyZ2V0KSkge1xuICAgICAgICBzZXRSZWZlcmVuY2UoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgaGFuZGxlTW91c2VNb3ZlKTtcbiAgICAgICAgY2xlYW51cExpc3RlbmVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgfHwgaXNNb3VzZUJhc2VkRXZlbnQoZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCkpIHtcbiAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBoYW5kbGVNb3VzZU1vdmUpO1xuICAgICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGhhbmRsZU1vdXNlTW92ZSk7XG4gICAgICAgIGNsZWFudXBMaXN0ZW5lclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH07XG4gICAgICBjbGVhbnVwTGlzdGVuZXJSZWYuY3VycmVudCA9IGNsZWFudXA7XG4gICAgICByZXR1cm4gY2xlYW51cDtcbiAgICB9XG4gICAgcmVmcy5zZXRQb3NpdGlvblJlZmVyZW5jZShkb21SZWZlcmVuY2UpO1xuICB9LCBbb3BlbkNoZWNrLCBlbmFibGVkLCB4LCB5LCBmbG9hdGluZywgZGF0YVJlZiwgcmVmcywgZG9tUmVmZXJlbmNlLCBzZXRSZWZlcmVuY2VdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gYWRkTGlzdGVuZXIoKTtcbiAgfSwgW2FkZExpc3RlbmVyLCByZWFjdGl2ZV0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChlbmFibGVkICYmICFmbG9hdGluZykge1xuICAgICAgaW5pdGlhbFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgZmxvYXRpbmddKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQgJiYgb3Blbikge1xuICAgICAgaW5pdGlhbFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGVuYWJsZWQgJiYgKHggIT0gbnVsbCB8fCB5ICE9IG51bGwpKSB7XG4gICAgICBpbml0aWFsUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIHNldFJlZmVyZW5jZSh4LCB5KTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCB4LCB5LCBzZXRSZWZlcmVuY2VdKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgZnVuY3Rpb24gc2V0UG9pbnRlclR5cGVSZWYoX3JlZikge1xuICAgICAgbGV0IHtcbiAgICAgICAgcG9pbnRlclR5cGVcbiAgICAgIH0gPSBfcmVmO1xuICAgICAgc2V0UG9pbnRlclR5cGUocG9pbnRlclR5cGUpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb25Qb2ludGVyRG93bjogc2V0UG9pbnRlclR5cGVSZWYsXG4gICAgICBvblBvaW50ZXJFbnRlcjogc2V0UG9pbnRlclR5cGVSZWYsXG4gICAgICBvbk1vdXNlTW92ZTogaGFuZGxlUmVmZXJlbmNlRW50ZXJPck1vdmUsXG4gICAgICBvbk1vdXNlRW50ZXI6IGhhbmRsZVJlZmVyZW5jZUVudGVyT3JNb3ZlXG4gICAgfTtcbiAgfSwgW2hhbmRsZVJlZmVyZW5jZUVudGVyT3JNb3ZlXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZV0pO1xufVxuXG5jb25zdCBidWJibGVIYW5kbGVyS2V5cyA9IHtcbiAgcG9pbnRlcmRvd246ICdvblBvaW50ZXJEb3duJyxcbiAgbW91c2Vkb3duOiAnb25Nb3VzZURvd24nLFxuICBjbGljazogJ29uQ2xpY2snXG59O1xuY29uc3QgY2FwdHVyZUhhbmRsZXJLZXlzID0ge1xuICBwb2ludGVyZG93bjogJ29uUG9pbnRlckRvd25DYXB0dXJlJyxcbiAgbW91c2Vkb3duOiAnb25Nb3VzZURvd25DYXB0dXJlJyxcbiAgY2xpY2s6ICdvbkNsaWNrQ2FwdHVyZSdcbn07XG5jb25zdCBub3JtYWxpemVQcm9wID0gbm9ybWFsaXphYmxlID0+IHtcbiAgdmFyIF9ub3JtYWxpemFibGUkZXNjYXBlSywgX25vcm1hbGl6YWJsZSRvdXRzaWRlO1xuICByZXR1cm4ge1xuICAgIGVzY2FwZUtleTogdHlwZW9mIG5vcm1hbGl6YWJsZSA9PT0gJ2Jvb2xlYW4nID8gbm9ybWFsaXphYmxlIDogKF9ub3JtYWxpemFibGUkZXNjYXBlSyA9IG5vcm1hbGl6YWJsZSA9PSBudWxsID8gdm9pZCAwIDogbm9ybWFsaXphYmxlLmVzY2FwZUtleSkgIT0gbnVsbCA/IF9ub3JtYWxpemFibGUkZXNjYXBlSyA6IGZhbHNlLFxuICAgIG91dHNpZGVQcmVzczogdHlwZW9mIG5vcm1hbGl6YWJsZSA9PT0gJ2Jvb2xlYW4nID8gbm9ybWFsaXphYmxlIDogKF9ub3JtYWxpemFibGUkb3V0c2lkZSA9IG5vcm1hbGl6YWJsZSA9PSBudWxsID8gdm9pZCAwIDogbm9ybWFsaXphYmxlLm91dHNpZGVQcmVzcykgIT0gbnVsbCA/IF9ub3JtYWxpemFibGUkb3V0c2lkZSA6IHRydWVcbiAgfTtcbn07XG4vKipcbiAqIENsb3NlcyB0aGUgZmxvYXRpbmcgZWxlbWVudCB3aGVuIGEgZGlzbWlzc2FsIGlzIHJlcXVlc3RlZCDigJQgYnkgZGVmYXVsdCwgd2hlblxuICogdGhlIHVzZXIgcHJlc3NlcyB0aGUgYGVzY2FwZWAga2V5IG9yIG91dHNpZGUgb2YgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRGlzbWlzc1xuICovXG5mdW5jdGlvbiB1c2VEaXNtaXNzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZGF0YVJlZlxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIGVzY2FwZUtleSA9IHRydWUsXG4gICAgb3V0c2lkZVByZXNzOiB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgPSB0cnVlLFxuICAgIG91dHNpZGVQcmVzc0V2ZW50ID0gJ3BvaW50ZXJkb3duJyxcbiAgICByZWZlcmVuY2VQcmVzcyA9IGZhbHNlLFxuICAgIHJlZmVyZW5jZVByZXNzRXZlbnQgPSAncG9pbnRlcmRvd24nLFxuICAgIGFuY2VzdG9yU2Nyb2xsID0gZmFsc2UsXG4gICAgYnViYmxlcyxcbiAgICBjYXB0dXJlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBvdXRzaWRlUHJlc3NGbiA9IHVzZUVmZmVjdEV2ZW50KHR5cGVvZiB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgPT09ICdmdW5jdGlvbicgPyB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgOiAoKSA9PiBmYWxzZSk7XG4gIGNvbnN0IG91dHNpZGVQcmVzcyA9IHR5cGVvZiB1bnN0YWJsZV9vdXRzaWRlUHJlc3MgPT09ICdmdW5jdGlvbicgPyBvdXRzaWRlUHJlc3NGbiA6IHVuc3RhYmxlX291dHNpZGVQcmVzcztcbiAgY29uc3QgaW5zaWRlUmVhY3RUcmVlUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB7XG4gICAgZXNjYXBlS2V5OiBlc2NhcGVLZXlCdWJibGVzLFxuICAgIG91dHNpZGVQcmVzczogb3V0c2lkZVByZXNzQnViYmxlc1xuICB9ID0gbm9ybWFsaXplUHJvcChidWJibGVzKTtcbiAgY29uc3Qge1xuICAgIGVzY2FwZUtleTogZXNjYXBlS2V5Q2FwdHVyZSxcbiAgICBvdXRzaWRlUHJlc3M6IG91dHNpZGVQcmVzc0NhcHR1cmVcbiAgfSA9IG5vcm1hbGl6ZVByb3AoY2FwdHVyZSk7XG4gIGNvbnN0IGlzQ29tcG9zaW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgY2xvc2VPbkVzY2FwZUtleURvd24gPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkZmxvYTtcbiAgICBpZiAoIW9wZW4gfHwgIWVuYWJsZWQgfHwgIWVzY2FwZUtleSB8fCBldmVudC5rZXkgIT09ICdFc2NhcGUnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gV2FpdCB1bnRpbCBJTUUgaXMgc2V0dGxlZC4gUHJlc3NpbmcgYEVzY2FwZWAgd2hpbGUgY29tcG9zaW5nIHNob3VsZFxuICAgIC8vIGNsb3NlIHRoZSBjb21wb3NlIG1lbnUsIGJ1dCBub3QgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gICAgaWYgKGlzQ29tcG9zaW5nUmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9kZUlkID0gKF9kYXRhUmVmJGN1cnJlbnQkZmxvYSA9IGRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JGZsb2Eubm9kZUlkO1xuICAgIGNvbnN0IGNoaWxkcmVuID0gdHJlZSA/IGdldE5vZGVDaGlsZHJlbiQxKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKSA6IFtdO1xuICAgIGlmICghZXNjYXBlS2V5QnViYmxlcykge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICBsZXQgc2hvdWxkRGlzbWlzcyA9IHRydWU7XG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgIHZhciBfY2hpbGQkY29udGV4dDtcbiAgICAgICAgICBpZiAoKF9jaGlsZCRjb250ZXh0ID0gY2hpbGQuY29udGV4dCkgIT0gbnVsbCAmJiBfY2hpbGQkY29udGV4dC5vcGVuICYmICFjaGlsZC5jb250ZXh0LmRhdGFSZWYuY3VycmVudC5fX2VzY2FwZUtleUJ1YmJsZXMpIHtcbiAgICAgICAgICAgIHNob3VsZERpc21pc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXNob3VsZERpc21pc3MpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBpc1JlYWN0RXZlbnQoZXZlbnQpID8gZXZlbnQubmF0aXZlRXZlbnQgOiBldmVudCwgJ2VzY2FwZS1rZXknKTtcbiAgfSk7XG4gIGNvbnN0IGNsb3NlT25Fc2NhcGVLZXlEb3duQ2FwdHVyZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2dldFRhcmdldDI7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICB2YXIgX2dldFRhcmdldDtcbiAgICAgIGNsb3NlT25Fc2NhcGVLZXlEb3duKGV2ZW50KTtcbiAgICAgIChfZ2V0VGFyZ2V0ID0gZ2V0VGFyZ2V0JDEoZXZlbnQpKSA9PSBudWxsIHx8IF9nZXRUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGNhbGxiYWNrKTtcbiAgICB9O1xuICAgIChfZ2V0VGFyZ2V0MiA9IGdldFRhcmdldCQxKGV2ZW50KSkgPT0gbnVsbCB8fCBfZ2V0VGFyZ2V0Mi5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgY2FsbGJhY2spO1xuICB9KTtcbiAgY29uc3QgY2xvc2VPblByZXNzT3V0c2lkZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2RhdGFSZWYkY3VycmVudCRmbG9hMjtcbiAgICAvLyBHaXZlbiBkZXZlbG9wZXJzIGNhbiBzdG9wIHRoZSBwcm9wYWdhdGlvbiBvZiB0aGUgc3ludGhldGljIGV2ZW50LFxuICAgIC8vIHdlIGNhbiBvbmx5IGJlIGNvbmZpZGVudCB3aXRoIGEgcG9zaXRpdmUgdmFsdWUuXG4gICAgY29uc3QgaW5zaWRlUmVhY3RUcmVlID0gaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQ7XG4gICAgaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQgPSBmYWxzZTtcblxuICAgIC8vIFdoZW4gY2xpY2sgb3V0c2lkZSBpcyBsYXp5IChgY2xpY2tgIGV2ZW50KSwgaGFuZGxlIGRyYWdnaW5nLlxuICAgIC8vIERvbid0IGNsb3NlIGlmOlxuICAgIC8vIC0gVGhlIGNsaWNrIHN0YXJ0ZWQgaW5zaWRlIHRoZSBmbG9hdGluZyBlbGVtZW50LlxuICAgIC8vIC0gVGhlIGNsaWNrIGVuZGVkIGluc2lkZSB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAgICBjb25zdCBlbmRlZE9yU3RhcnRlZEluc2lkZSA9IGVuZGVkT3JTdGFydGVkSW5zaWRlUmVmLmN1cnJlbnQ7XG4gICAgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIGlmIChvdXRzaWRlUHJlc3NFdmVudCA9PT0gJ2NsaWNrJyAmJiBlbmRlZE9yU3RhcnRlZEluc2lkZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaW5zaWRlUmVhY3RUcmVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb3V0c2lkZVByZXNzID09PSAnZnVuY3Rpb24nICYmICFvdXRzaWRlUHJlc3MoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50KTtcbiAgICBjb25zdCBpbmVydFNlbGVjdG9yID0gXCJbXCIgKyBjcmVhdGVBdHRyaWJ1dGUoJ2luZXJ0JykgKyBcIl1cIjtcbiAgICBjb25zdCBtYXJrZXJzID0gZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZykucXVlcnlTZWxlY3RvckFsbChpbmVydFNlbGVjdG9yKTtcbiAgICBsZXQgdGFyZ2V0Um9vdEFuY2VzdG9yID0gaXNFbGVtZW50KHRhcmdldCkgPyB0YXJnZXQgOiBudWxsO1xuICAgIHdoaWxlICh0YXJnZXRSb290QW5jZXN0b3IgJiYgIWlzTGFzdFRyYXZlcnNhYmxlTm9kZSh0YXJnZXRSb290QW5jZXN0b3IpKSB7XG4gICAgICBjb25zdCBuZXh0UGFyZW50ID0gZ2V0UGFyZW50Tm9kZSh0YXJnZXRSb290QW5jZXN0b3IpO1xuICAgICAgaWYgKGlzTGFzdFRyYXZlcnNhYmxlTm9kZShuZXh0UGFyZW50KSB8fCAhaXNFbGVtZW50KG5leHRQYXJlbnQpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdGFyZ2V0Um9vdEFuY2VzdG9yID0gbmV4dFBhcmVudDtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgY2xpY2sgb2NjdXJyZWQgb24gYSB0aGlyZC1wYXJ0eSBlbGVtZW50IGluamVjdGVkIGFmdGVyIHRoZVxuICAgIC8vIGZsb2F0aW5nIGVsZW1lbnQgcmVuZGVyZWQuXG4gICAgaWYgKG1hcmtlcnMubGVuZ3RoICYmIGlzRWxlbWVudCh0YXJnZXQpICYmICFpc1Jvb3RFbGVtZW50KHRhcmdldCkgJiZcbiAgICAvLyBDbGlja2VkIG9uIGEgZGlyZWN0IGFuY2VzdG9yIChlLmcuIEZsb2F0aW5nT3ZlcmxheSkuXG4gICAgIWNvbnRhaW5zJDEodGFyZ2V0LCBlbGVtZW50cy5mbG9hdGluZykgJiZcbiAgICAvLyBJZiB0aGUgdGFyZ2V0IHJvb3QgZWxlbWVudCBjb250YWlucyBub25lIG9mIHRoZSBtYXJrZXJzLCB0aGVuIHRoZVxuICAgIC8vIGVsZW1lbnQgd2FzIGluamVjdGVkIGFmdGVyIHRoZSBmbG9hdGluZyBlbGVtZW50IHJlbmRlcmVkLlxuICAgIEFycmF5LmZyb20obWFya2VycykuZXZlcnkobWFya2VyID0+ICFjb250YWlucyQxKHRhcmdldFJvb3RBbmNlc3RvciwgbWFya2VyKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgY2xpY2sgb2NjdXJyZWQgb24gdGhlIHNjcm9sbGJhclxuICAgIGlmIChpc0hUTUxFbGVtZW50KHRhcmdldCkgJiYgZmxvYXRpbmcpIHtcbiAgICAgIGNvbnN0IGxhc3RUcmF2ZXJzYWJsZU5vZGUgPSBpc0xhc3RUcmF2ZXJzYWJsZU5vZGUodGFyZ2V0KTtcbiAgICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpO1xuICAgICAgY29uc3Qgc2Nyb2xsUmUgPSAvYXV0b3xzY3JvbGwvO1xuICAgICAgY29uc3QgaXNTY3JvbGxhYmxlWCA9IGxhc3RUcmF2ZXJzYWJsZU5vZGUgfHwgc2Nyb2xsUmUudGVzdChzdHlsZS5vdmVyZmxvd1gpO1xuICAgICAgY29uc3QgaXNTY3JvbGxhYmxlWSA9IGxhc3RUcmF2ZXJzYWJsZU5vZGUgfHwgc2Nyb2xsUmUudGVzdChzdHlsZS5vdmVyZmxvd1kpO1xuICAgICAgY29uc3QgY2FuU2Nyb2xsWCA9IGlzU2Nyb2xsYWJsZVggJiYgdGFyZ2V0LmNsaWVudFdpZHRoID4gMCAmJiB0YXJnZXQuc2Nyb2xsV2lkdGggPiB0YXJnZXQuY2xpZW50V2lkdGg7XG4gICAgICBjb25zdCBjYW5TY3JvbGxZID0gaXNTY3JvbGxhYmxlWSAmJiB0YXJnZXQuY2xpZW50SGVpZ2h0ID4gMCAmJiB0YXJnZXQuc2Nyb2xsSGVpZ2h0ID4gdGFyZ2V0LmNsaWVudEhlaWdodDtcbiAgICAgIGNvbnN0IGlzUlRMID0gc3R5bGUuZGlyZWN0aW9uID09PSAncnRsJztcblxuICAgICAgLy8gQ2hlY2sgY2xpY2sgcG9zaXRpb24gcmVsYXRpdmUgdG8gc2Nyb2xsYmFyLlxuICAgICAgLy8gSW4gc29tZSBicm93c2VycyBpdCBpcyBwb3NzaWJsZSB0byBjaGFuZ2UgdGhlIDxib2R5PiAob3Igd2luZG93KVxuICAgICAgLy8gc2Nyb2xsYmFyIHRvIHRoZSBsZWZ0IHNpZGUsIGJ1dCBpcyB2ZXJ5IHJhcmUgYW5kIGlzIGRpZmZpY3VsdCB0b1xuICAgICAgLy8gY2hlY2sgZm9yLiBQbHVzLCBmb3IgbW9kYWwgZGlhbG9ncyB3aXRoIGJhY2tkcm9wcywgaXQgaXMgbW9yZVxuICAgICAgLy8gaW1wb3J0YW50IHRoYXQgdGhlIGJhY2tkcm9wIGlzIGNoZWNrZWQgYnV0IG5vdCBzbyBtdWNoIHRoZSB3aW5kb3cuXG4gICAgICBjb25zdCBwcmVzc2VkVmVydGljYWxTY3JvbGxiYXIgPSBjYW5TY3JvbGxZICYmIChpc1JUTCA/IGV2ZW50Lm9mZnNldFggPD0gdGFyZ2V0Lm9mZnNldFdpZHRoIC0gdGFyZ2V0LmNsaWVudFdpZHRoIDogZXZlbnQub2Zmc2V0WCA+IHRhcmdldC5jbGllbnRXaWR0aCk7XG4gICAgICBjb25zdCBwcmVzc2VkSG9yaXpvbnRhbFNjcm9sbGJhciA9IGNhblNjcm9sbFggJiYgZXZlbnQub2Zmc2V0WSA+IHRhcmdldC5jbGllbnRIZWlnaHQ7XG4gICAgICBpZiAocHJlc3NlZFZlcnRpY2FsU2Nyb2xsYmFyIHx8IHByZXNzZWRIb3Jpem9udGFsU2Nyb2xsYmFyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3Qgbm9kZUlkID0gKF9kYXRhUmVmJGN1cnJlbnQkZmxvYTIgPSBkYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGFSZWYkY3VycmVudCRmbG9hMi5ub2RlSWQ7XG4gICAgY29uc3QgdGFyZ2V0SXNJbnNpZGVDaGlsZHJlbiA9IHRyZWUgJiYgZ2V0Tm9kZUNoaWxkcmVuJDEodHJlZS5ub2Rlc1JlZi5jdXJyZW50LCBub2RlSWQpLnNvbWUobm9kZSA9PiB7XG4gICAgICB2YXIgX25vZGUkY29udGV4dDtcbiAgICAgIHJldHVybiBpc0V2ZW50VGFyZ2V0V2l0aGluKGV2ZW50LCAoX25vZGUkY29udGV4dCA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQuZWxlbWVudHMuZmxvYXRpbmcpO1xuICAgIH0pO1xuICAgIGlmIChpc0V2ZW50VGFyZ2V0V2l0aGluKGV2ZW50LCBlbGVtZW50cy5mbG9hdGluZykgfHwgaXNFdmVudFRhcmdldFdpdGhpbihldmVudCwgZWxlbWVudHMuZG9tUmVmZXJlbmNlKSB8fCB0YXJnZXRJc0luc2lkZUNoaWxkcmVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNoaWxkcmVuID0gdHJlZSA/IGdldE5vZGVDaGlsZHJlbiQxKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKSA6IFtdO1xuICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICBsZXQgc2hvdWxkRGlzbWlzcyA9IHRydWU7XG4gICAgICBjaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAgICAgdmFyIF9jaGlsZCRjb250ZXh0MjtcbiAgICAgICAgaWYgKChfY2hpbGQkY29udGV4dDIgPSBjaGlsZC5jb250ZXh0KSAhPSBudWxsICYmIF9jaGlsZCRjb250ZXh0Mi5vcGVuICYmICFjaGlsZC5jb250ZXh0LmRhdGFSZWYuY3VycmVudC5fX291dHNpZGVQcmVzc0J1YmJsZXMpIHtcbiAgICAgICAgICBzaG91bGREaXNtaXNzID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmICghc2hvdWxkRGlzbWlzcykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsICdvdXRzaWRlLXByZXNzJyk7XG4gIH0pO1xuICBjb25zdCBjbG9zZU9uUHJlc3NPdXRzaWRlQ2FwdHVyZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2dldFRhcmdldDQ7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICB2YXIgX2dldFRhcmdldDM7XG4gICAgICBjbG9zZU9uUHJlc3NPdXRzaWRlKGV2ZW50KTtcbiAgICAgIChfZ2V0VGFyZ2V0MyA9IGdldFRhcmdldCQxKGV2ZW50KSkgPT0gbnVsbCB8fCBfZ2V0VGFyZ2V0My5yZW1vdmVFdmVudExpc3RlbmVyKG91dHNpZGVQcmVzc0V2ZW50LCBjYWxsYmFjayk7XG4gICAgfTtcbiAgICAoX2dldFRhcmdldDQgPSBnZXRUYXJnZXQkMShldmVudCkpID09IG51bGwgfHwgX2dldFRhcmdldDQuYWRkRXZlbnRMaXN0ZW5lcihvdXRzaWRlUHJlc3NFdmVudCwgY2FsbGJhY2spO1xuICB9KTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIW9wZW4gfHwgIWVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGF0YVJlZi5jdXJyZW50Ll9fZXNjYXBlS2V5QnViYmxlcyA9IGVzY2FwZUtleUJ1YmJsZXM7XG4gICAgZGF0YVJlZi5jdXJyZW50Ll9fb3V0c2lkZVByZXNzQnViYmxlcyA9IG91dHNpZGVQcmVzc0J1YmJsZXM7XG4gICAgbGV0IGNvbXBvc2l0aW9uVGltZW91dCA9IC0xO1xuICAgIGZ1bmN0aW9uIG9uU2Nyb2xsKGV2ZW50KSB7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCAnYW5jZXN0b3Itc2Nyb2xsJyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGhhbmRsZUNvbXBvc2l0aW9uU3RhcnQoKSB7XG4gICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KGNvbXBvc2l0aW9uVGltZW91dCk7XG4gICAgICBpc0NvbXBvc2luZ1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaGFuZGxlQ29tcG9zaXRpb25FbmQoKSB7XG4gICAgICAvLyBTYWZhcmkgZmlyZXMgYGNvbXBvc2l0aW9uZW5kYCBiZWZvcmUgYGtleWRvd25gLCBzbyB3ZSBuZWVkIHRvIHdhaXRcbiAgICAgIC8vIHVudGlsIHRoZSBuZXh0IHRpY2sgdG8gc2V0IGBpc0NvbXBvc2luZ2AgdG8gYGZhbHNlYC5cbiAgICAgIC8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNjUwMDRcbiAgICAgIGNvbXBvc2l0aW9uVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaXNDb21wb3NpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIC8vIDBtcyBvciAxbXMgZG9uJ3Qgd29yayBpbiBTYWZhcmkuIDVtcyBhcHBlYXJzIHRvIGNvbnNpc3RlbnRseSB3b3JrLlxuICAgICAgLy8gT25seSBhcHBseSB0byBXZWJLaXQgZm9yIHRoZSB0ZXN0IHRvIHJlbWFpbiAwbXMuXG4gICAgICBpc1dlYktpdCgpID8gNSA6IDApO1xuICAgIH1cbiAgICBjb25zdCBkb2MgPSBnZXREb2N1bWVudCQxKGVsZW1lbnRzLmZsb2F0aW5nKTtcbiAgICBpZiAoZXNjYXBlS2V5KSB7XG4gICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGVzY2FwZUtleUNhcHR1cmUgPyBjbG9zZU9uRXNjYXBlS2V5RG93bkNhcHR1cmUgOiBjbG9zZU9uRXNjYXBlS2V5RG93biwgZXNjYXBlS2V5Q2FwdHVyZSk7XG4gICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25zdGFydCcsIGhhbmRsZUNvbXBvc2l0aW9uU3RhcnQpO1xuICAgICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbXBvc2l0aW9uZW5kJywgaGFuZGxlQ29tcG9zaXRpb25FbmQpO1xuICAgIH1cbiAgICBvdXRzaWRlUHJlc3MgJiYgZG9jLmFkZEV2ZW50TGlzdGVuZXIob3V0c2lkZVByZXNzRXZlbnQsIG91dHNpZGVQcmVzc0NhcHR1cmUgPyBjbG9zZU9uUHJlc3NPdXRzaWRlQ2FwdHVyZSA6IGNsb3NlT25QcmVzc091dHNpZGUsIG91dHNpZGVQcmVzc0NhcHR1cmUpO1xuICAgIGxldCBhbmNlc3RvcnMgPSBbXTtcbiAgICBpZiAoYW5jZXN0b3JTY3JvbGwpIHtcbiAgICAgIGlmIChpc0VsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgICBhbmNlc3RvcnMgPSBnZXRPdmVyZmxvd0FuY2VzdG9ycyhlbGVtZW50cy5kb21SZWZlcmVuY2UpO1xuICAgICAgfVxuICAgICAgaWYgKGlzRWxlbWVudChlbGVtZW50cy5mbG9hdGluZykpIHtcbiAgICAgICAgYW5jZXN0b3JzID0gYW5jZXN0b3JzLmNvbmNhdChnZXRPdmVyZmxvd0FuY2VzdG9ycyhlbGVtZW50cy5mbG9hdGluZykpO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0VsZW1lbnQoZWxlbWVudHMucmVmZXJlbmNlKSAmJiBlbGVtZW50cy5yZWZlcmVuY2UgJiYgZWxlbWVudHMucmVmZXJlbmNlLmNvbnRleHRFbGVtZW50KSB7XG4gICAgICAgIGFuY2VzdG9ycyA9IGFuY2VzdG9ycy5jb25jYXQoZ2V0T3ZlcmZsb3dBbmNlc3RvcnMoZWxlbWVudHMucmVmZXJlbmNlLmNvbnRleHRFbGVtZW50KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWdub3JlIHRoZSB2aXN1YWwgdmlld3BvcnQgZm9yIHNjcm9sbGluZyBkaXNtaXNzYWwgKGFsbG93IHBpbmNoLXpvb20pXG4gICAgYW5jZXN0b3JzID0gYW5jZXN0b3JzLmZpbHRlcihhbmNlc3RvciA9PiB7XG4gICAgICB2YXIgX2RvYyRkZWZhdWx0VmlldztcbiAgICAgIHJldHVybiBhbmNlc3RvciAhPT0gKChfZG9jJGRlZmF1bHRWaWV3ID0gZG9jLmRlZmF1bHRWaWV3KSA9PSBudWxsID8gdm9pZCAwIDogX2RvYyRkZWZhdWx0Vmlldy52aXN1YWxWaWV3cG9ydCk7XG4gICAgfSk7XG4gICAgYW5jZXN0b3JzLmZvckVhY2goYW5jZXN0b3IgPT4ge1xuICAgICAgYW5jZXN0b3IuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgb25TY3JvbGwsIHtcbiAgICAgICAgcGFzc2l2ZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmIChlc2NhcGVLZXkpIHtcbiAgICAgICAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBlc2NhcGVLZXlDYXB0dXJlID8gY2xvc2VPbkVzY2FwZUtleURvd25DYXB0dXJlIDogY2xvc2VPbkVzY2FwZUtleURvd24sIGVzY2FwZUtleUNhcHR1cmUpO1xuICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25zdGFydCcsIGhhbmRsZUNvbXBvc2l0aW9uU3RhcnQpO1xuICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25lbmQnLCBoYW5kbGVDb21wb3NpdGlvbkVuZCk7XG4gICAgICB9XG4gICAgICBvdXRzaWRlUHJlc3MgJiYgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIob3V0c2lkZVByZXNzRXZlbnQsIG91dHNpZGVQcmVzc0NhcHR1cmUgPyBjbG9zZU9uUHJlc3NPdXRzaWRlQ2FwdHVyZSA6IGNsb3NlT25QcmVzc091dHNpZGUsIG91dHNpZGVQcmVzc0NhcHR1cmUpO1xuICAgICAgYW5jZXN0b3JzLmZvckVhY2goYW5jZXN0b3IgPT4ge1xuICAgICAgICBhbmNlc3Rvci5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCk7XG4gICAgICB9KTtcbiAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQoY29tcG9zaXRpb25UaW1lb3V0KTtcbiAgICB9O1xuICB9LCBbZGF0YVJlZiwgZWxlbWVudHMsIGVzY2FwZUtleSwgb3V0c2lkZVByZXNzLCBvdXRzaWRlUHJlc3NFdmVudCwgb3Blbiwgb25PcGVuQ2hhbmdlLCBhbmNlc3RvclNjcm9sbCwgZW5hYmxlZCwgZXNjYXBlS2V5QnViYmxlcywgb3V0c2lkZVByZXNzQnViYmxlcywgY2xvc2VPbkVzY2FwZUtleURvd24sIGVzY2FwZUtleUNhcHR1cmUsIGNsb3NlT25Fc2NhcGVLZXlEb3duQ2FwdHVyZSwgY2xvc2VPblByZXNzT3V0c2lkZSwgb3V0c2lkZVByZXNzQ2FwdHVyZSwgY2xvc2VPblByZXNzT3V0c2lkZUNhcHR1cmVdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpbnNpZGVSZWFjdFRyZWVSZWYuY3VycmVudCA9IGZhbHNlO1xuICB9LCBbb3V0c2lkZVByZXNzLCBvdXRzaWRlUHJlc3NFdmVudF0pO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25LZXlEb3duOiBjbG9zZU9uRXNjYXBlS2V5RG93bixcbiAgICAuLi4ocmVmZXJlbmNlUHJlc3MgJiYge1xuICAgICAgW2J1YmJsZUhhbmRsZXJLZXlzW3JlZmVyZW5jZVByZXNzRXZlbnRdXTogZXZlbnQgPT4ge1xuICAgICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAncmVmZXJlbmNlLXByZXNzJyk7XG4gICAgICB9LFxuICAgICAgLi4uKHJlZmVyZW5jZVByZXNzRXZlbnQgIT09ICdjbGljaycgJiYge1xuICAgICAgICBvbkNsaWNrKGV2ZW50KSB7XG4gICAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ3JlZmVyZW5jZS1wcmVzcycpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH0pLCBbY2xvc2VPbkVzY2FwZUtleURvd24sIG9uT3BlbkNoYW5nZSwgcmVmZXJlbmNlUHJlc3MsIHJlZmVyZW5jZVByZXNzRXZlbnRdKTtcbiAgY29uc3QgZmxvYXRpbmcgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25LZXlEb3duOiBjbG9zZU9uRXNjYXBlS2V5RG93bixcbiAgICBvbk1vdXNlRG93bigpIHtcbiAgICAgIGVuZGVkT3JTdGFydGVkSW5zaWRlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH0sXG4gICAgb25Nb3VzZVVwKCkge1xuICAgICAgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSxcbiAgICBbY2FwdHVyZUhhbmRsZXJLZXlzW291dHNpZGVQcmVzc0V2ZW50XV06ICgpID0+IHtcbiAgICAgIGluc2lkZVJlYWN0VHJlZVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0pLCBbY2xvc2VPbkVzY2FwZUtleURvd24sIG91dHNpZGVQcmVzc0V2ZW50XSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZSwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gdXNlRmxvYXRpbmdSb290Q29udGV4dChvcHRpb25zKSB7XG4gIGNvbnN0IHtcbiAgICBvcGVuID0gZmFsc2UsXG4gICAgb25PcGVuQ2hhbmdlOiBvbk9wZW5DaGFuZ2VQcm9wLFxuICAgIGVsZW1lbnRzOiBlbGVtZW50c1Byb3BcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGZsb2F0aW5nSWQgPSB1c2VJZCgpO1xuICBjb25zdCBkYXRhUmVmID0gUmVhY3QudXNlUmVmKHt9KTtcbiAgY29uc3QgW2V2ZW50c10gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBjcmVhdGVFdmVudEVtaXR0ZXIoKSk7XG4gIGNvbnN0IG5lc3RlZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCkgIT0gbnVsbDtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgIGNvbnN0IG9wdGlvbkRvbVJlZmVyZW5jZSA9IGVsZW1lbnRzUHJvcC5yZWZlcmVuY2U7XG4gICAgaWYgKG9wdGlvbkRvbVJlZmVyZW5jZSAmJiAhaXNFbGVtZW50KG9wdGlvbkRvbVJlZmVyZW5jZSkpIHtcbiAgICAgIGVycm9yKCdDYW5ub3QgcGFzcyBhIHZpcnR1YWwgZWxlbWVudCB0byB0aGUgYGVsZW1lbnRzLnJlZmVyZW5jZWAgb3B0aW9uLCcsICdhcyBpdCBtdXN0IGJlIGEgcmVhbCBET00gZWxlbWVudC4gVXNlIGByZWZzLnNldFBvc2l0aW9uUmVmZXJlbmNlKClgJywgJ2luc3RlYWQuJyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IFtwb3NpdGlvblJlZmVyZW5jZSwgc2V0UG9zaXRpb25SZWZlcmVuY2VdID0gUmVhY3QudXNlU3RhdGUoZWxlbWVudHNQcm9wLnJlZmVyZW5jZSk7XG4gIGNvbnN0IG9uT3BlbkNoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KChvcGVuLCBldmVudCwgcmVhc29uKSA9PiB7XG4gICAgZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCA9IG9wZW4gPyBldmVudCA6IHVuZGVmaW5lZDtcbiAgICBldmVudHMuZW1pdCgnb3BlbmNoYW5nZScsIHtcbiAgICAgIG9wZW4sXG4gICAgICBldmVudCxcbiAgICAgIHJlYXNvbixcbiAgICAgIG5lc3RlZFxuICAgIH0pO1xuICAgIG9uT3BlbkNoYW5nZVByb3AgPT0gbnVsbCB8fCBvbk9wZW5DaGFuZ2VQcm9wKG9wZW4sIGV2ZW50LCByZWFzb24pO1xuICB9KTtcbiAgY29uc3QgcmVmcyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBzZXRQb3NpdGlvblJlZmVyZW5jZVxuICB9KSwgW10pO1xuICBjb25zdCBlbGVtZW50cyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICByZWZlcmVuY2U6IHBvc2l0aW9uUmVmZXJlbmNlIHx8IGVsZW1lbnRzUHJvcC5yZWZlcmVuY2UgfHwgbnVsbCxcbiAgICBmbG9hdGluZzogZWxlbWVudHNQcm9wLmZsb2F0aW5nIHx8IG51bGwsXG4gICAgZG9tUmVmZXJlbmNlOiBlbGVtZW50c1Byb3AucmVmZXJlbmNlXG4gIH0pLCBbcG9zaXRpb25SZWZlcmVuY2UsIGVsZW1lbnRzUHJvcC5yZWZlcmVuY2UsIGVsZW1lbnRzUHJvcC5mbG9hdGluZ10pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIGRhdGFSZWYsXG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZXZlbnRzLFxuICAgIGZsb2F0aW5nSWQsXG4gICAgcmVmc1xuICB9KSwgW29wZW4sIG9uT3BlbkNoYW5nZSwgZWxlbWVudHMsIGV2ZW50cywgZmxvYXRpbmdJZCwgcmVmc10pO1xufVxuXG4vKipcbiAqIFByb3ZpZGVzIGRhdGEgdG8gcG9zaXRpb24gYSBmbG9hdGluZyBlbGVtZW50IGFuZCBjb250ZXh0IHRvIGFkZCBpbnRlcmFjdGlvbnMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRmxvYXRpbmdcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmcob3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBub2RlSWRcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGludGVybmFsUm9vdENvbnRleHQgPSB1c2VGbG9hdGluZ1Jvb3RDb250ZXh0KHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICByZWZlcmVuY2U6IG51bGwsXG4gICAgICBmbG9hdGluZzogbnVsbCxcbiAgICAgIC4uLm9wdGlvbnMuZWxlbWVudHNcbiAgICB9XG4gIH0pO1xuICBjb25zdCByb290Q29udGV4dCA9IG9wdGlvbnMucm9vdENvbnRleHQgfHwgaW50ZXJuYWxSb290Q29udGV4dDtcbiAgY29uc3QgY29tcHV0ZWRFbGVtZW50cyA9IHJvb3RDb250ZXh0LmVsZW1lbnRzO1xuICBjb25zdCBbX2RvbVJlZmVyZW5jZSwgc2V0RG9tUmVmZXJlbmNlXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpO1xuICBjb25zdCBbcG9zaXRpb25SZWZlcmVuY2UsIF9zZXRQb3NpdGlvblJlZmVyZW5jZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3Qgb3B0aW9uRG9tUmVmZXJlbmNlID0gY29tcHV0ZWRFbGVtZW50cyA9PSBudWxsID8gdm9pZCAwIDogY29tcHV0ZWRFbGVtZW50cy5kb21SZWZlcmVuY2U7XG4gIGNvbnN0IGRvbVJlZmVyZW5jZSA9IG9wdGlvbkRvbVJlZmVyZW5jZSB8fCBfZG9tUmVmZXJlbmNlO1xuICBjb25zdCBkb21SZWZlcmVuY2VSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZG9tUmVmZXJlbmNlKSB7XG4gICAgICBkb21SZWZlcmVuY2VSZWYuY3VycmVudCA9IGRvbVJlZmVyZW5jZTtcbiAgICB9XG4gIH0sIFtkb21SZWZlcmVuY2VdKTtcbiAgY29uc3QgcG9zaXRpb24gPSB1c2VGbG9hdGluZyQxKHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICAuLi5jb21wdXRlZEVsZW1lbnRzLFxuICAgICAgLi4uKHBvc2l0aW9uUmVmZXJlbmNlICYmIHtcbiAgICAgICAgcmVmZXJlbmNlOiBwb3NpdGlvblJlZmVyZW5jZVxuICAgICAgfSlcbiAgICB9XG4gIH0pO1xuICBjb25zdCBzZXRQb3NpdGlvblJlZmVyZW5jZSA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIGNvbnN0IGNvbXB1dGVkUG9zaXRpb25SZWZlcmVuY2UgPSBpc0VsZW1lbnQobm9kZSkgPyB7XG4gICAgICBnZXRCb3VuZGluZ0NsaWVudFJlY3Q6ICgpID0+IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICBnZXRDbGllbnRSZWN0czogKCkgPT4gbm9kZS5nZXRDbGllbnRSZWN0cygpLFxuICAgICAgY29udGV4dEVsZW1lbnQ6IG5vZGVcbiAgICB9IDogbm9kZTtcbiAgICAvLyBTdG9yZSB0aGUgcG9zaXRpb25SZWZlcmVuY2UgaW4gc3RhdGUgaWYgdGhlIERPTSByZWZlcmVuY2UgaXMgc3BlY2lmaWVkIGV4dGVybmFsbHkgdmlhIHRoZVxuICAgIC8vIGBlbGVtZW50cy5yZWZlcmVuY2VgIG9wdGlvbi4gVGhpcyBlbnN1cmVzIHRoYXQgaXQgd29uJ3QgYmUgb3ZlcnJpZGRlbiBvbiBmdXR1cmUgcmVuZGVycy5cbiAgICBfc2V0UG9zaXRpb25SZWZlcmVuY2UoY29tcHV0ZWRQb3NpdGlvblJlZmVyZW5jZSk7XG4gICAgcG9zaXRpb24ucmVmcy5zZXRSZWZlcmVuY2UoY29tcHV0ZWRQb3NpdGlvblJlZmVyZW5jZSk7XG4gIH0sIFtwb3NpdGlvbi5yZWZzXSk7XG4gIGNvbnN0IHNldFJlZmVyZW5jZSA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIGlmIChpc0VsZW1lbnQobm9kZSkgfHwgbm9kZSA9PT0gbnVsbCkge1xuICAgICAgZG9tUmVmZXJlbmNlUmVmLmN1cnJlbnQgPSBub2RlO1xuICAgICAgc2V0RG9tUmVmZXJlbmNlKG5vZGUpO1xuICAgIH1cblxuICAgIC8vIEJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IGZvciBwYXNzaW5nIGEgdmlydHVhbCBlbGVtZW50IHRvIGByZWZlcmVuY2VgXG4gICAgLy8gYWZ0ZXIgaXQgaGFzIHNldCB0aGUgRE9NIHJlZmVyZW5jZS5cbiAgICBpZiAoaXNFbGVtZW50KHBvc2l0aW9uLnJlZnMucmVmZXJlbmNlLmN1cnJlbnQpIHx8IHBvc2l0aW9uLnJlZnMucmVmZXJlbmNlLmN1cnJlbnQgPT09IG51bGwgfHxcbiAgICAvLyBEb24ndCBhbGxvdyBzZXR0aW5nIHZpcnR1YWwgZWxlbWVudHMgdXNpbmcgdGhlIG9sZCB0ZWNobmlxdWUgYmFjayB0b1xuICAgIC8vIGBudWxsYCB0byBzdXBwb3J0IGBwb3NpdGlvblJlZmVyZW5jZWAgKyBhbiB1bnN0YWJsZSBgcmVmZXJlbmNlYFxuICAgIC8vIGNhbGxiYWNrIHJlZi5cbiAgICBub2RlICE9PSBudWxsICYmICFpc0VsZW1lbnQobm9kZSkpIHtcbiAgICAgIHBvc2l0aW9uLnJlZnMuc2V0UmVmZXJlbmNlKG5vZGUpO1xuICAgIH1cbiAgfSwgW3Bvc2l0aW9uLnJlZnNdKTtcbiAgY29uc3QgcmVmcyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICAuLi5wb3NpdGlvbi5yZWZzLFxuICAgIHNldFJlZmVyZW5jZSxcbiAgICBzZXRQb3NpdGlvblJlZmVyZW5jZSxcbiAgICBkb21SZWZlcmVuY2U6IGRvbVJlZmVyZW5jZVJlZlxuICB9KSwgW3Bvc2l0aW9uLnJlZnMsIHNldFJlZmVyZW5jZSwgc2V0UG9zaXRpb25SZWZlcmVuY2VdKTtcbiAgY29uc3QgZWxlbWVudHMgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24uZWxlbWVudHMsXG4gICAgZG9tUmVmZXJlbmNlOiBkb21SZWZlcmVuY2VcbiAgfSksIFtwb3NpdGlvbi5lbGVtZW50cywgZG9tUmVmZXJlbmNlXSk7XG4gIGNvbnN0IGNvbnRleHQgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24sXG4gICAgLi4ucm9vdENvbnRleHQsXG4gICAgcmVmcyxcbiAgICBlbGVtZW50cyxcbiAgICBub2RlSWRcbiAgfSksIFtwb3NpdGlvbiwgcmVmcywgZWxlbWVudHMsIG5vZGVJZCwgcm9vdENvbnRleHRdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICByb290Q29udGV4dC5kYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0ID0gY29udGV4dDtcbiAgICBjb25zdCBub2RlID0gdHJlZSA9PSBudWxsID8gdm9pZCAwIDogdHJlZS5ub2Rlc1JlZi5jdXJyZW50LmZpbmQobm9kZSA9PiBub2RlLmlkID09PSBub2RlSWQpO1xuICAgIGlmIChub2RlKSB7XG4gICAgICBub2RlLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24sXG4gICAgY29udGV4dCxcbiAgICByZWZzLFxuICAgIGVsZW1lbnRzXG4gIH0pLCBbcG9zaXRpb24sIHJlZnMsIGVsZW1lbnRzLCBjb250ZXh0XSk7XG59XG5cbmZ1bmN0aW9uIGlzTWFjU2FmYXJpKCkge1xuICByZXR1cm4gaXNNYWMoKSAmJiBpc1NhZmFyaSgpO1xufVxuLyoqXG4gKiBPcGVucyB0aGUgZmxvYXRpbmcgZWxlbWVudCB3aGlsZSB0aGUgcmVmZXJlbmNlIGVsZW1lbnQgaGFzIGZvY3VzLCBsaWtlIENTU1xuICogYDpmb2N1c2AuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRm9jdXNcbiAqL1xuZnVuY3Rpb24gdXNlRm9jdXMoY29udGV4dCwgcHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBldmVudHMsXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50c1xuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIHZpc2libGVPbmx5ID0gdHJ1ZVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGJsb2NrRm9jdXNSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB0aW1lb3V0UmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3Qga2V5Ym9hcmRNb2RhbGl0eVJlZiA9IFJlYWN0LnVzZVJlZih0cnVlKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBjb25zdCB3aW4gPSBnZXRXaW5kb3coZWxlbWVudHMuZG9tUmVmZXJlbmNlKTtcblxuICAgIC8vIElmIHRoZSByZWZlcmVuY2Ugd2FzIGZvY3VzZWQgYW5kIHRoZSB1c2VyIGxlZnQgdGhlIHRhYi93aW5kb3csIGFuZCB0aGVcbiAgICAvLyBmbG9hdGluZyBlbGVtZW50IHdhcyBub3Qgb3BlbiwgdGhlIGZvY3VzIHNob3VsZCBiZSBibG9ja2VkIHdoZW4gdGhleVxuICAgIC8vIHJldHVybiB0byB0aGUgdGFiL3dpbmRvdy5cbiAgICBmdW5jdGlvbiBvbkJsdXIoKSB7XG4gICAgICBpZiAoIW9wZW4gJiYgaXNIVE1MRWxlbWVudChlbGVtZW50cy5kb21SZWZlcmVuY2UpICYmIGVsZW1lbnRzLmRvbVJlZmVyZW5jZSA9PT0gYWN0aXZlRWxlbWVudChnZXREb2N1bWVudCQxKGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkpKSB7XG4gICAgICAgIGJsb2NrRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uS2V5RG93bigpIHtcbiAgICAgIGtleWJvYXJkTW9kYWxpdHlSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uUG9pbnRlckRvd24oKSB7XG4gICAgICBrZXlib2FyZE1vZGFsaXR5UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9XG4gICAgd2luLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCBvbkJsdXIpO1xuICAgIGlmIChpc01hY1NhZmFyaSgpKSB7XG4gICAgICB3aW4uYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93biwgdHJ1ZSk7XG4gICAgICB3aW4uYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBvblBvaW50ZXJEb3duLCB0cnVlKTtcbiAgICB9XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdibHVyJywgb25CbHVyKTtcbiAgICAgIGlmIChpc01hY1NhZmFyaSgpKSB7XG4gICAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duLCB0cnVlKTtcbiAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgb25Qb2ludGVyRG93biwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW2VsZW1lbnRzLmRvbVJlZmVyZW5jZSwgb3BlbiwgZW5hYmxlZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIG9uT3BlbkNoYW5nZShfcmVmKSB7XG4gICAgICBsZXQge1xuICAgICAgICByZWFzb25cbiAgICAgIH0gPSBfcmVmO1xuICAgICAgaWYgKHJlYXNvbiA9PT0gJ3JlZmVyZW5jZS1wcmVzcycgfHwgcmVhc29uID09PSAnZXNjYXBlLWtleScpIHtcbiAgICAgICAgYmxvY2tGb2N1c1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgZXZlbnRzLm9uKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZXZlbnRzLm9mZignb3BlbmNoYW5nZScsIG9uT3BlbkNoYW5nZSk7XG4gICAgfTtcbiAgfSwgW2V2ZW50cywgZW5hYmxlZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0UmVmKTtcbiAgICB9O1xuICB9LCBbXSk7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBvbk1vdXNlTGVhdmUoKSB7XG4gICAgICBibG9ja0ZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9LFxuICAgIG9uRm9jdXMoZXZlbnQpIHtcbiAgICAgIGlmIChibG9ja0ZvY3VzUmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldCQxKGV2ZW50Lm5hdGl2ZUV2ZW50KTtcbiAgICAgIGlmICh2aXNpYmxlT25seSAmJiBpc0VsZW1lbnQodGFyZ2V0KSkge1xuICAgICAgICAvLyBTYWZhcmkgZmFpbHMgdG8gbWF0Y2ggYDpmb2N1cy12aXNpYmxlYCBpZiBmb2N1cyB3YXMgaW5pdGlhbGx5XG4gICAgICAgIC8vIG91dHNpZGUgdGhlIGRvY3VtZW50LlxuICAgICAgICBpZiAoaXNNYWNTYWZhcmkoKSAmJiAhZXZlbnQucmVsYXRlZFRhcmdldCkge1xuICAgICAgICAgIGlmICgha2V5Ym9hcmRNb2RhbGl0eVJlZi5jdXJyZW50ICYmICFpc1R5cGVhYmxlRWxlbWVudCh0YXJnZXQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFtYXRjaGVzRm9jdXNWaXNpYmxlKHRhcmdldCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudC5uYXRpdmVFdmVudCwgJ2ZvY3VzJyk7XG4gICAgfSxcbiAgICBvbkJsdXIoZXZlbnQpIHtcbiAgICAgIGJsb2NrRm9jdXNSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgY29uc3QgcmVsYXRlZFRhcmdldCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG4gICAgICBjb25zdCBuYXRpdmVFdmVudCA9IGV2ZW50Lm5hdGl2ZUV2ZW50O1xuXG4gICAgICAvLyBIaXQgdGhlIG5vbi1tb2RhbCBmb2N1cyBtYW5hZ2VtZW50IHBvcnRhbCBndWFyZC4gRm9jdXMgd2lsbCBiZVxuICAgICAgLy8gbW92ZWQgaW50byB0aGUgZmxvYXRpbmcgZWxlbWVudCBpbW1lZGlhdGVseSBhZnRlci5cbiAgICAgIGNvbnN0IG1vdmVkVG9Gb2N1c0d1YXJkID0gaXNFbGVtZW50KHJlbGF0ZWRUYXJnZXQpICYmIHJlbGF0ZWRUYXJnZXQuaGFzQXR0cmlidXRlKGNyZWF0ZUF0dHJpYnV0ZSgnZm9jdXMtZ3VhcmQnKSkgJiYgcmVsYXRlZFRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScpID09PSAnb3V0c2lkZSc7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHRoZSB3aW5kb3cgYmx1ciBsaXN0ZW5lciB0byBmaXJlLlxuICAgICAgdGltZW91dFJlZi5jdXJyZW50ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB2YXIgX2RhdGFSZWYkY3VycmVudCRmbG9hO1xuICAgICAgICBjb25zdCBhY3RpdmVFbCA9IGFjdGl2ZUVsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlID8gZWxlbWVudHMuZG9tUmVmZXJlbmNlLm93bmVyRG9jdW1lbnQgOiBkb2N1bWVudCk7XG5cbiAgICAgICAgLy8gRm9jdXMgbGVmdCB0aGUgcGFnZSwga2VlcCBpdCBvcGVuLlxuICAgICAgICBpZiAoIXJlbGF0ZWRUYXJnZXQgJiYgYWN0aXZlRWwgPT09IGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFdoZW4gZm9jdXNpbmcgdGhlIHJlZmVyZW5jZSBlbGVtZW50IChlLmcuIHJlZ3VsYXIgY2xpY2spLCB0aGVuXG4gICAgICAgIC8vIGNsaWNraW5nIGludG8gdGhlIGZsb2F0aW5nIGVsZW1lbnQsIHByZXZlbnQgaXQgZnJvbSBoaWRpbmcuXG4gICAgICAgIC8vIE5vdGU6IGl0IG11c3QgYmUgZm9jdXNhYmxlLCBlLmcuIGB0YWJpbmRleD1cIi0xXCJgLlxuICAgICAgICAvLyBXZSBjYW4gbm90IHJlbHkgb24gcmVsYXRlZFRhcmdldCB0byBwb2ludCB0byB0aGUgY29ycmVjdCBlbGVtZW50XG4gICAgICAgIC8vIGFzIGl0IHdpbGwgb25seSBwb2ludCB0byB0aGUgc2hhZG93IGhvc3Qgb2YgdGhlIG5ld2x5IGZvY3VzZWQgZWxlbWVudFxuICAgICAgICAvLyBhbmQgbm90IHRoZSBlbGVtZW50IHRoYXQgYWN0dWFsbHkgaGFzIHJlY2VpdmVkIGZvY3VzIGlmIGl0IGlzIGxvY2F0ZWRcbiAgICAgICAgLy8gaW5zaWRlIGEgc2hhZG93IHJvb3QuXG4gICAgICAgIGlmIChjb250YWlucyQxKChfZGF0YVJlZiRjdXJyZW50JGZsb2EgPSBkYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGFSZWYkY3VycmVudCRmbG9hLnJlZnMuZmxvYXRpbmcuY3VycmVudCwgYWN0aXZlRWwpIHx8IGNvbnRhaW5zJDEoZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBhY3RpdmVFbCkgfHwgbW92ZWRUb0ZvY3VzR3VhcmQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBuYXRpdmVFdmVudCwgJ2ZvY3VzJyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pLCBbZGF0YVJlZiwgZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBvbk9wZW5DaGFuZ2UsIHZpc2libGVPbmx5XSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZV0pO1xufVxuXG5mdW5jdGlvbiBtZXJnZVByb3BzKHVzZXJQcm9wcywgcHJvcHNMaXN0LCBlbGVtZW50S2V5KSB7XG4gIGNvbnN0IG1hcCA9IG5ldyBNYXAoKTtcbiAgY29uc3QgaXNJdGVtID0gZWxlbWVudEtleSA9PT0gJ2l0ZW0nO1xuICBsZXQgZG9tVXNlclByb3BzID0gdXNlclByb3BzO1xuICBpZiAoaXNJdGVtICYmIHVzZXJQcm9wcykge1xuICAgIGNvbnN0IHtcbiAgICAgIFtBQ1RJVkVfS0VZXTogXyxcbiAgICAgIFtTRUxFQ1RFRF9LRVldOiBfXyxcbiAgICAgIC4uLnZhbGlkUHJvcHNcbiAgICB9ID0gdXNlclByb3BzO1xuICAgIGRvbVVzZXJQcm9wcyA9IHZhbGlkUHJvcHM7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICAuLi4oZWxlbWVudEtleSA9PT0gJ2Zsb2F0aW5nJyAmJiB7XG4gICAgICB0YWJJbmRleDogLTEsXG4gICAgICBbRk9DVVNBQkxFX0FUVFJJQlVURV06ICcnXG4gICAgfSksXG4gICAgLi4uZG9tVXNlclByb3BzLFxuICAgIC4uLnByb3BzTGlzdC5tYXAodmFsdWUgPT4ge1xuICAgICAgY29uc3QgcHJvcHNPckdldFByb3BzID0gdmFsdWUgPyB2YWx1ZVtlbGVtZW50S2V5XSA6IG51bGw7XG4gICAgICBpZiAodHlwZW9mIHByb3BzT3JHZXRQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gdXNlclByb3BzID8gcHJvcHNPckdldFByb3BzKHVzZXJQcm9wcykgOiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3BzT3JHZXRQcm9wcztcbiAgICB9KS5jb25jYXQodXNlclByb3BzKS5yZWR1Y2UoKGFjYywgcHJvcHMpID0+IHtcbiAgICAgIGlmICghcHJvcHMpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIE9iamVjdC5lbnRyaWVzKHByb3BzKS5mb3JFYWNoKF9yZWYgPT4ge1xuICAgICAgICBsZXQgW2tleSwgdmFsdWVdID0gX3JlZjtcbiAgICAgICAgaWYgKGlzSXRlbSAmJiBbQUNUSVZFX0tFWSwgU0VMRUNURURfS0VZXS5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChrZXkuaW5kZXhPZignb24nKSA9PT0gMCkge1xuICAgICAgICAgIGlmICghbWFwLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICBtYXAuc2V0KGtleSwgW10pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgX21hcCRnZXQ7XG4gICAgICAgICAgICAoX21hcCRnZXQgPSBtYXAuZ2V0KGtleSkpID09IG51bGwgfHwgX21hcCRnZXQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICBhY2Nba2V5XSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgdmFyIF9tYXAkZ2V0MjtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgICAgICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gKF9tYXAkZ2V0MiA9IG1hcC5nZXQoa2V5KSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9tYXAkZ2V0Mi5tYXAoZm4gPT4gZm4oLi4uYXJncykpLmZpbmQodmFsID0+IHZhbCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSlcbiAgfTtcbn1cbi8qKlxuICogTWVyZ2VzIGFuIGFycmF5IG9mIGludGVyYWN0aW9uIGhvb2tzJyBwcm9wcyBpbnRvIHByb3AgZ2V0dGVycywgYWxsb3dpbmdcbiAqIGV2ZW50IGhhbmRsZXIgZnVuY3Rpb25zIHRvIGJlIGNvbXBvc2VkIHRvZ2V0aGVyIHdpdGhvdXQgb3ZlcndyaXRpbmcgb25lXG4gKiBhbm90aGVyLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUludGVyYWN0aW9uc1xuICovXG5mdW5jdGlvbiB1c2VJbnRlcmFjdGlvbnMocHJvcHNMaXN0KSB7XG4gIGlmIChwcm9wc0xpc3QgPT09IHZvaWQgMCkge1xuICAgIHByb3BzTGlzdCA9IFtdO1xuICB9XG4gIGNvbnN0IHJlZmVyZW5jZURlcHMgPSBwcm9wc0xpc3QubWFwKGtleSA9PiBrZXkgPT0gbnVsbCA/IHZvaWQgMCA6IGtleS5yZWZlcmVuY2UpO1xuICBjb25zdCBmbG9hdGluZ0RlcHMgPSBwcm9wc0xpc3QubWFwKGtleSA9PiBrZXkgPT0gbnVsbCA/IHZvaWQgMCA6IGtleS5mbG9hdGluZyk7XG4gIGNvbnN0IGl0ZW1EZXBzID0gcHJvcHNMaXN0Lm1hcChrZXkgPT4ga2V5ID09IG51bGwgPyB2b2lkIDAgOiBrZXkuaXRlbSk7XG4gIGNvbnN0IGdldFJlZmVyZW5jZVByb3BzID0gUmVhY3QudXNlQ2FsbGJhY2sodXNlclByb3BzID0+IG1lcmdlUHJvcHModXNlclByb3BzLCBwcm9wc0xpc3QsICdyZWZlcmVuY2UnKSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICByZWZlcmVuY2VEZXBzKTtcbiAgY29uc3QgZ2V0RmxvYXRpbmdQcm9wcyA9IFJlYWN0LnVzZUNhbGxiYWNrKHVzZXJQcm9wcyA9PiBtZXJnZVByb3BzKHVzZXJQcm9wcywgcHJvcHNMaXN0LCAnZmxvYXRpbmcnKSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICBmbG9hdGluZ0RlcHMpO1xuICBjb25zdCBnZXRJdGVtUHJvcHMgPSBSZWFjdC51c2VDYWxsYmFjayh1c2VyUHJvcHMgPT4gbWVyZ2VQcm9wcyh1c2VyUHJvcHMsIHByb3BzTGlzdCwgJ2l0ZW0nKSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICBpdGVtRGVwcyk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgZ2V0UmVmZXJlbmNlUHJvcHMsXG4gICAgZ2V0RmxvYXRpbmdQcm9wcyxcbiAgICBnZXRJdGVtUHJvcHNcbiAgfSksIFtnZXRSZWZlcmVuY2VQcm9wcywgZ2V0RmxvYXRpbmdQcm9wcywgZ2V0SXRlbVByb3BzXSk7XG59XG5cbmNvbnN0IEVTQ0FQRSA9ICdFc2NhcGUnO1xuZnVuY3Rpb24gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKSB7XG4gIHN3aXRjaCAob3JpZW50YXRpb24pIHtcbiAgICBjYXNlICd2ZXJ0aWNhbCc6XG4gICAgICByZXR1cm4gdmVydGljYWw7XG4gICAgY2FzZSAnaG9yaXpvbnRhbCc6XG4gICAgICByZXR1cm4gaG9yaXpvbnRhbDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHZlcnRpY2FsIHx8IGhvcml6b250YWw7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzTWFpbk9yaWVudGF0aW9uS2V5KGtleSwgb3JpZW50YXRpb24pIHtcbiAgY29uc3QgdmVydGljYWwgPSBrZXkgPT09IEFSUk9XX1VQIHx8IGtleSA9PT0gQVJST1dfRE9XTjtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGtleSA9PT0gQVJST1dfTEVGVCB8fCBrZXkgPT09IEFSUk9XX1JJR0hUO1xuICByZXR1cm4gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKTtcbn1cbmZ1bmN0aW9uIGlzTWFpbk9yaWVudGF0aW9uVG9FbmRLZXkoa2V5LCBvcmllbnRhdGlvbiwgcnRsKSB7XG4gIGNvbnN0IHZlcnRpY2FsID0ga2V5ID09PSBBUlJPV19ET1dOO1xuICBjb25zdCBob3Jpem9udGFsID0gcnRsID8ga2V5ID09PSBBUlJPV19MRUZUIDoga2V5ID09PSBBUlJPV19SSUdIVDtcbiAgcmV0dXJuIGRvU3dpdGNoKG9yaWVudGF0aW9uLCB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCkgfHwga2V5ID09PSAnRW50ZXInIHx8IGtleSA9PT0gJyAnIHx8IGtleSA9PT0gJyc7XG59XG5mdW5jdGlvbiBpc0Nyb3NzT3JpZW50YXRpb25PcGVuS2V5KGtleSwgb3JpZW50YXRpb24sIHJ0bCkge1xuICBjb25zdCB2ZXJ0aWNhbCA9IHJ0bCA/IGtleSA9PT0gQVJST1dfTEVGVCA6IGtleSA9PT0gQVJST1dfUklHSFQ7XG4gIGNvbnN0IGhvcml6b250YWwgPSBrZXkgPT09IEFSUk9XX0RPV047XG4gIHJldHVybiBkb1N3aXRjaChvcmllbnRhdGlvbiwgdmVydGljYWwsIGhvcml6b250YWwpO1xufVxuZnVuY3Rpb24gaXNDcm9zc09yaWVudGF0aW9uQ2xvc2VLZXkoa2V5LCBvcmllbnRhdGlvbiwgcnRsLCBjb2xzKSB7XG4gIGNvbnN0IHZlcnRpY2FsID0gcnRsID8ga2V5ID09PSBBUlJPV19SSUdIVCA6IGtleSA9PT0gQVJST1dfTEVGVDtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGtleSA9PT0gQVJST1dfVVA7XG4gIGlmIChvcmllbnRhdGlvbiA9PT0gJ2JvdGgnIHx8IG9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgJiYgY29scyAmJiBjb2xzID4gMSkge1xuICAgIHJldHVybiBrZXkgPT09IEVTQ0FQRTtcbiAgfVxuICByZXR1cm4gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKTtcbn1cbi8qKlxuICogQWRkcyBhcnJvdyBrZXktYmFzZWQgbmF2aWdhdGlvbiBvZiBhIGxpc3Qgb2YgaXRlbXMsIGVpdGhlciB1c2luZyByZWFsIERPTVxuICogZm9jdXMgb3IgdmlydHVhbCBmb2N1cy5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VMaXN0TmF2aWdhdGlvblxuICovXG5mdW5jdGlvbiB1c2VMaXN0TmF2aWdhdGlvbihjb250ZXh0LCBwcm9wcykge1xuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZmxvYXRpbmdJZFxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGxpc3RSZWYsXG4gICAgYWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZTogdW5zdGFibGVfb25OYXZpZ2F0ZSA9ICgpID0+IHt9LFxuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIHNlbGVjdGVkSW5kZXggPSBudWxsLFxuICAgIGFsbG93RXNjYXBlID0gZmFsc2UsXG4gICAgbG9vcCA9IGZhbHNlLFxuICAgIG5lc3RlZCA9IGZhbHNlLFxuICAgIHJ0bCA9IGZhbHNlLFxuICAgIHZpcnR1YWwgPSBmYWxzZSxcbiAgICBmb2N1c0l0ZW1Pbk9wZW4gPSAnYXV0bycsXG4gICAgZm9jdXNJdGVtT25Ib3ZlciA9IHRydWUsXG4gICAgb3Blbk9uQXJyb3dLZXlEb3duID0gdHJ1ZSxcbiAgICBkaXNhYmxlZEluZGljZXMgPSB1bmRlZmluZWQsXG4gICAgb3JpZW50YXRpb24gPSAndmVydGljYWwnLFxuICAgIHBhcmVudE9yaWVudGF0aW9uLFxuICAgIGNvbHMgPSAxLFxuICAgIHNjcm9sbEl0ZW1JbnRvVmlldyA9IHRydWUsXG4gICAgdmlydHVhbEl0ZW1SZWYsXG4gICAgaXRlbVNpemVzLFxuICAgIGRlbnNlID0gZmFsc2VcbiAgfSA9IHByb3BzO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgaWYgKGFsbG93RXNjYXBlKSB7XG4gICAgICBpZiAoIWxvb3ApIHtcbiAgICAgICAgd2FybignYHVzZUxpc3ROYXZpZ2F0aW9uYCBsb29waW5nIG11c3QgYmUgZW5hYmxlZCB0byBhbGxvdyBlc2NhcGluZy4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghdmlydHVhbCkge1xuICAgICAgICB3YXJuKCdgdXNlTGlzdE5hdmlnYXRpb25gIG11c3QgYmUgdmlydHVhbCB0byBhbGxvdyBlc2NhcGluZy4nKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG9yaWVudGF0aW9uID09PSAndmVydGljYWwnICYmIGNvbHMgPiAxKSB7XG4gICAgICB3YXJuKCdJbiBncmlkIGxpc3QgbmF2aWdhdGlvbiBtb2RlIChgY29sc2AgPiAxKSwgdGhlIGBvcmllbnRhdGlvbmAgc2hvdWxkJywgJ2JlIGVpdGhlciBcImhvcml6b250YWxcIiBvciBcImJvdGhcIi4nKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgZmxvYXRpbmdGb2N1c0VsZW1lbnQgPSBnZXRGbG9hdGluZ0ZvY3VzRWxlbWVudChlbGVtZW50cy5mbG9hdGluZyk7XG4gIGNvbnN0IGZsb2F0aW5nRm9jdXNFbGVtZW50UmVmID0gdXNlTGF0ZXN0UmVmKGZsb2F0aW5nRm9jdXNFbGVtZW50KTtcbiAgY29uc3QgcGFyZW50SWQgPSB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCgpO1xuICBjb25zdCB0cmVlID0gdXNlRmxvYXRpbmdUcmVlKCk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgY29udGV4dC5kYXRhUmVmLmN1cnJlbnQub3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgfSwgW2NvbnRleHQsIG9yaWVudGF0aW9uXSk7XG4gIGNvbnN0IG9uTmF2aWdhdGUgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdW5zdGFibGVfb25OYXZpZ2F0ZShpbmRleFJlZi5jdXJyZW50ID09PSAtMSA/IG51bGwgOiBpbmRleFJlZi5jdXJyZW50KTtcbiAgfSk7XG4gIGNvbnN0IHR5cGVhYmxlQ29tYm9ib3hSZWZlcmVuY2UgPSBpc1R5cGVhYmxlQ29tYm9ib3goZWxlbWVudHMuZG9tUmVmZXJlbmNlKTtcbiAgY29uc3QgZm9jdXNJdGVtT25PcGVuUmVmID0gUmVhY3QudXNlUmVmKGZvY3VzSXRlbU9uT3Blbik7XG4gIGNvbnN0IGluZGV4UmVmID0gUmVhY3QudXNlUmVmKHNlbGVjdGVkSW5kZXggIT0gbnVsbCA/IHNlbGVjdGVkSW5kZXggOiAtMSk7XG4gIGNvbnN0IGtleVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgaXNQb2ludGVyTW9kYWxpdHlSZWYgPSBSZWFjdC51c2VSZWYodHJ1ZSk7XG4gIGNvbnN0IHByZXZpb3VzT25OYXZpZ2F0ZVJlZiA9IFJlYWN0LnVzZVJlZihvbk5hdmlnYXRlKTtcbiAgY29uc3QgcHJldmlvdXNNb3VudGVkUmVmID0gUmVhY3QudXNlUmVmKCEhZWxlbWVudHMuZmxvYXRpbmcpO1xuICBjb25zdCBwcmV2aW91c09wZW5SZWYgPSBSZWFjdC51c2VSZWYob3Blbik7XG4gIGNvbnN0IGZvcmNlU3luY0ZvY3VzUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgZm9yY2VTY3JvbGxJbnRvVmlld1JlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGRpc2FibGVkSW5kaWNlc1JlZiA9IHVzZUxhdGVzdFJlZihkaXNhYmxlZEluZGljZXMpO1xuICBjb25zdCBsYXRlc3RPcGVuUmVmID0gdXNlTGF0ZXN0UmVmKG9wZW4pO1xuICBjb25zdCBzY3JvbGxJdGVtSW50b1ZpZXdSZWYgPSB1c2VMYXRlc3RSZWYoc2Nyb2xsSXRlbUludG9WaWV3KTtcbiAgY29uc3Qgc2VsZWN0ZWRJbmRleFJlZiA9IHVzZUxhdGVzdFJlZihzZWxlY3RlZEluZGV4KTtcbiAgY29uc3QgW2FjdGl2ZUlkLCBzZXRBY3RpdmVJZF0gPSBSZWFjdC51c2VTdGF0ZSgpO1xuICBjb25zdCBbdmlydHVhbElkLCBzZXRWaXJ0dWFsSWRdID0gUmVhY3QudXNlU3RhdGUoKTtcbiAgY29uc3QgZm9jdXNJdGVtID0gdXNlRWZmZWN0RXZlbnQoKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHJ1bkZvY3VzKGl0ZW0pIHtcbiAgICAgIGlmICh2aXJ0dWFsKSB7XG4gICAgICAgIHZhciBfaXRlbSRpZDtcbiAgICAgICAgaWYgKChfaXRlbSRpZCA9IGl0ZW0uaWQpICE9IG51bGwgJiYgX2l0ZW0kaWQuZW5kc1dpdGgoJy1mdWktb3B0aW9uJykpIHtcbiAgICAgICAgICBpdGVtLmlkID0gZmxvYXRpbmdJZCArIFwiLVwiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygxNikuc2xpY2UoMiwgMTApO1xuICAgICAgICB9XG4gICAgICAgIHNldEFjdGl2ZUlkKGl0ZW0uaWQpO1xuICAgICAgICB0cmVlID09IG51bGwgfHwgdHJlZS5ldmVudHMuZW1pdCgndmlydHVhbGZvY3VzJywgaXRlbSk7XG4gICAgICAgIGlmICh2aXJ0dWFsSXRlbVJlZikge1xuICAgICAgICAgIHZpcnR1YWxJdGVtUmVmLmN1cnJlbnQgPSBpdGVtO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnF1ZXVlRm9jdXMoaXRlbSwge1xuICAgICAgICAgIHN5bmM6IGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQsXG4gICAgICAgICAgcHJldmVudFNjcm9sbDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgaW5pdGlhbEl0ZW0gPSBsaXN0UmVmLmN1cnJlbnRbaW5kZXhSZWYuY3VycmVudF07XG4gICAgY29uc3QgZm9yY2VTY3JvbGxJbnRvVmlldyA9IGZvcmNlU2Nyb2xsSW50b1ZpZXdSZWYuY3VycmVudDtcbiAgICBpZiAoaW5pdGlhbEl0ZW0pIHtcbiAgICAgIHJ1bkZvY3VzKGluaXRpYWxJdGVtKTtcbiAgICB9XG4gICAgY29uc3Qgc2NoZWR1bGVyID0gZm9yY2VTeW5jRm9jdXNSZWYuY3VycmVudCA/IHYgPT4gdigpIDogcmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuICAgIHNjaGVkdWxlcigoKSA9PiB7XG4gICAgICBjb25zdCB3YWl0ZWRJdGVtID0gbGlzdFJlZi5jdXJyZW50W2luZGV4UmVmLmN1cnJlbnRdIHx8IGluaXRpYWxJdGVtO1xuICAgICAgaWYgKCF3YWl0ZWRJdGVtKSByZXR1cm47XG4gICAgICBpZiAoIWluaXRpYWxJdGVtKSB7XG4gICAgICAgIHJ1bkZvY3VzKHdhaXRlZEl0ZW0pO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2Nyb2xsSW50b1ZpZXdPcHRpb25zID0gc2Nyb2xsSXRlbUludG9WaWV3UmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBzaG91bGRTY3JvbGxJbnRvVmlldyA9IHNjcm9sbEludG9WaWV3T3B0aW9ucyAmJiBpdGVtICYmIChmb3JjZVNjcm9sbEludG9WaWV3IHx8ICFpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50KTtcbiAgICAgIGlmIChzaG91bGRTY3JvbGxJbnRvVmlldykge1xuICAgICAgICAvLyBKU0RPTSBkb2Vzbid0IHN1cHBvcnQgYC5zY3JvbGxJbnRvVmlldygpYCBidXQgaXQncyB3aWRlbHkgc3VwcG9ydGVkXG4gICAgICAgIC8vIGJ5IGFsbCBicm93c2Vycy5cbiAgICAgICAgd2FpdGVkSXRlbS5zY3JvbGxJbnRvVmlldyA9PSBudWxsIHx8IHdhaXRlZEl0ZW0uc2Nyb2xsSW50b1ZpZXcodHlwZW9mIHNjcm9sbEludG9WaWV3T3B0aW9ucyA9PT0gJ2Jvb2xlYW4nID8ge1xuICAgICAgICAgIGJsb2NrOiAnbmVhcmVzdCcsXG4gICAgICAgICAgaW5saW5lOiAnbmVhcmVzdCdcbiAgICAgICAgfSA6IHNjcm9sbEludG9WaWV3T3B0aW9ucyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFN5bmMgYHNlbGVjdGVkSW5kZXhgIHRvIGJlIHRoZSBgYWN0aXZlSW5kZXhgIHVwb24gb3BlbmluZyB0aGUgZmxvYXRpbmdcbiAgLy8gZWxlbWVudC4gQWxzbywgcmVzZXQgYGFjdGl2ZUluZGV4YCB1cG9uIGNsb3NpbmcgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKG9wZW4gJiYgZWxlbWVudHMuZmxvYXRpbmcpIHtcbiAgICAgIGlmIChmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCAmJiBzZWxlY3RlZEluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgLy8gUmVnYXJkbGVzcyBvZiB0aGUgcG9pbnRlciBtb2RhbGl0eSwgd2Ugd2FudCB0byBlbnN1cmUgdGhlIHNlbGVjdGVkXG4gICAgICAgIC8vIGl0ZW0gY29tZXMgaW50byB2aWV3IHdoZW4gdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXMgb3BlbmVkLlxuICAgICAgICBmb3JjZVNjcm9sbEludG9WaWV3UmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJldmlvdXNNb3VudGVkUmVmLmN1cnJlbnQpIHtcbiAgICAgIC8vIFNpbmNlIHRoZSB1c2VyIGNhbiBzcGVjaWZ5IGBvbk5hdmlnYXRlYCBjb25kaXRpb25hbGx5XG4gICAgICAvLyAob25OYXZpZ2F0ZTogb3BlbiA/IHNldEFjdGl2ZUluZGV4IDogc2V0U2VsZWN0ZWRJbmRleCksXG4gICAgICAvLyB3ZSBzdG9yZSBhbmQgY2FsbCB0aGUgcHJldmlvdXMgZnVuY3Rpb24uXG4gICAgICBpbmRleFJlZi5jdXJyZW50ID0gLTE7XG4gICAgICBwcmV2aW91c09uTmF2aWdhdGVSZWYuY3VycmVudCgpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGVsZW1lbnRzLmZsb2F0aW5nLCBzZWxlY3RlZEluZGV4LCBvbk5hdmlnYXRlXSk7XG5cbiAgLy8gU3luYyBgYWN0aXZlSW5kZXhgIHRvIGJlIHRoZSBmb2N1c2VkIGl0ZW0gd2hpbGUgdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXNcbiAgLy8gb3Blbi5cbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoIW9wZW4pIHJldHVybjtcbiAgICBpZiAoIWVsZW1lbnRzLmZsb2F0aW5nKSByZXR1cm47XG4gICAgaWYgKGFjdGl2ZUluZGV4ID09IG51bGwpIHtcbiAgICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIGlmIChzZWxlY3RlZEluZGV4UmVmLmN1cnJlbnQgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFJlc2V0IHdoaWxlIHRoZSBmbG9hdGluZyBlbGVtZW50IHdhcyBvcGVuIChlLmcuIHRoZSBsaXN0IGNoYW5nZWQpLlxuICAgICAgaWYgKHByZXZpb3VzTW91bnRlZFJlZi5jdXJyZW50KSB7XG4gICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSAtMTtcbiAgICAgICAgZm9jdXNJdGVtKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEluaXRpYWwgc3luYy5cbiAgICAgIGlmICgoIXByZXZpb3VzT3BlblJlZi5jdXJyZW50IHx8ICFwcmV2aW91c01vdW50ZWRSZWYuY3VycmVudCkgJiYgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgJiYgKGtleVJlZi5jdXJyZW50ICE9IG51bGwgfHwgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgPT09IHRydWUgJiYga2V5UmVmLmN1cnJlbnQgPT0gbnVsbCkpIHtcbiAgICAgICAgbGV0IHJ1bnMgPSAwO1xuICAgICAgICBjb25zdCB3YWl0Rm9yTGlzdFBvcHVsYXRlZCA9ICgpID0+IHtcbiAgICAgICAgICBpZiAobGlzdFJlZi5jdXJyZW50WzBdID09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIGxldHRpbmcgdGhlIGJyb3dzZXIgcGFpbnQgaWYgcG9zc2libGUgb24gdGhlIGZpcnN0IHRyeSxcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB1c2UgckFGLiBEb24ndCB0cnkgbW9yZSB0aGFuIHR3aWNlLCBzaW5jZSBzb21ldGhpbmdcbiAgICAgICAgICAgIC8vIGlzIHdyb25nIG90aGVyd2lzZS5cbiAgICAgICAgICAgIGlmIChydW5zIDwgMikge1xuICAgICAgICAgICAgICBjb25zdCBzY2hlZHVsZXIgPSBydW5zID8gcmVxdWVzdEFuaW1hdGlvbkZyYW1lIDogcXVldWVNaWNyb3Rhc2s7XG4gICAgICAgICAgICAgIHNjaGVkdWxlcih3YWl0Rm9yTGlzdFBvcHVsYXRlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydW5zKys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBrZXlSZWYuY3VycmVudCA9PSBudWxsIHx8IGlzTWFpbk9yaWVudGF0aW9uVG9FbmRLZXkoa2V5UmVmLmN1cnJlbnQsIG9yaWVudGF0aW9uLCBydGwpIHx8IG5lc3RlZCA/IGdldE1pbkxpc3RJbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXNSZWYuY3VycmVudCkgOiBnZXRNYXhMaXN0SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzUmVmLmN1cnJlbnQpO1xuICAgICAgICAgICAga2V5UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgd2FpdEZvckxpc3RQb3B1bGF0ZWQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc0luZGV4T3V0T2ZMaXN0Qm91bmRzKGxpc3RSZWYsIGFjdGl2ZUluZGV4KSkge1xuICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGFjdGl2ZUluZGV4O1xuICAgICAgZm9jdXNJdGVtKCk7XG4gICAgICBmb3JjZVNjcm9sbEludG9WaWV3UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuLCBlbGVtZW50cy5mbG9hdGluZywgYWN0aXZlSW5kZXgsIHNlbGVjdGVkSW5kZXhSZWYsIG5lc3RlZCwgbGlzdFJlZiwgb3JpZW50YXRpb24sIHJ0bCwgb25OYXZpZ2F0ZSwgZm9jdXNJdGVtLCBkaXNhYmxlZEluZGljZXNSZWZdKTtcblxuICAvLyBFbnN1cmUgdGhlIHBhcmVudCBmbG9hdGluZyBlbGVtZW50IGhhcyBmb2N1cyB3aGVuIGEgbmVzdGVkIGNoaWxkIGNsb3Nlc1xuICAvLyB0byBhbGxvdyBhcnJvdyBrZXkgbmF2aWdhdGlvbiB0byB3b3JrIGFmdGVyIHRoZSBwb2ludGVyIGxlYXZlcyB0aGUgY2hpbGQuXG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgdmFyIF9ub2RlcyRmaW5kO1xuICAgIGlmICghZW5hYmxlZCB8fCBlbGVtZW50cy5mbG9hdGluZyB8fCAhdHJlZSB8fCB2aXJ0dWFsIHx8ICFwcmV2aW91c01vdW50ZWRSZWYuY3VycmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBub2RlcyA9IHRyZWUubm9kZXNSZWYuY3VycmVudDtcbiAgICBjb25zdCBwYXJlbnQgPSAoX25vZGVzJGZpbmQgPSBub2Rlcy5maW5kKG5vZGUgPT4gbm9kZS5pZCA9PT0gcGFyZW50SWQpKSA9PSBudWxsIHx8IChfbm9kZXMkZmluZCA9IF9ub2RlcyRmaW5kLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZXMkZmluZC5lbGVtZW50cy5mbG9hdGluZztcbiAgICBjb25zdCBhY3RpdmVFbCA9IGFjdGl2ZUVsZW1lbnQoZ2V0RG9jdW1lbnQkMShlbGVtZW50cy5mbG9hdGluZykpO1xuICAgIGNvbnN0IHRyZWVDb250YWluc0FjdGl2ZUVsID0gbm9kZXMuc29tZShub2RlID0+IG5vZGUuY29udGV4dCAmJiBjb250YWlucyQxKG5vZGUuY29udGV4dC5lbGVtZW50cy5mbG9hdGluZywgYWN0aXZlRWwpKTtcbiAgICBpZiAocGFyZW50ICYmICF0cmVlQ29udGFpbnNBY3RpdmVFbCAmJiBpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50KSB7XG4gICAgICBwYXJlbnQuZm9jdXMoe1xuICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBlbGVtZW50cy5mbG9hdGluZywgdHJlZSwgcGFyZW50SWQsIHZpcnR1YWxdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoIXRyZWUpIHJldHVybjtcbiAgICBpZiAoIXZpcnR1YWwpIHJldHVybjtcbiAgICBpZiAocGFyZW50SWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBoYW5kbGVWaXJ0dWFsRm9jdXMoaXRlbSkge1xuICAgICAgc2V0VmlydHVhbElkKGl0ZW0uaWQpO1xuICAgICAgaWYgKHZpcnR1YWxJdGVtUmVmKSB7XG4gICAgICAgIHZpcnR1YWxJdGVtUmVmLmN1cnJlbnQgPSBpdGVtO1xuICAgICAgfVxuICAgIH1cbiAgICB0cmVlLmV2ZW50cy5vbigndmlydHVhbGZvY3VzJywgaGFuZGxlVmlydHVhbEZvY3VzKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgdHJlZS5ldmVudHMub2ZmKCd2aXJ0dWFsZm9jdXMnLCBoYW5kbGVWaXJ0dWFsRm9jdXMpO1xuICAgIH07XG4gIH0sIFtlbmFibGVkLCB0cmVlLCB2aXJ0dWFsLCBwYXJlbnRJZCwgdmlydHVhbEl0ZW1SZWZdKTtcbiAgdXNlTW9kZXJuTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBwcmV2aW91c09uTmF2aWdhdGVSZWYuY3VycmVudCA9IG9uTmF2aWdhdGU7XG4gICAgcHJldmlvdXNPcGVuUmVmLmN1cnJlbnQgPSBvcGVuO1xuICAgIHByZXZpb3VzTW91bnRlZFJlZi5jdXJyZW50ID0gISFlbGVtZW50cy5mbG9hdGluZztcbiAgfSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICBrZXlSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbb3Blbl0pO1xuICBjb25zdCBoYXNBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICE9IG51bGw7XG4gIGNvbnN0IGl0ZW0gPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBmdW5jdGlvbiBzeW5jQ3VycmVudFRhcmdldChjdXJyZW50VGFyZ2V0KSB7XG4gICAgICBpZiAoIW9wZW4pIHJldHVybjtcbiAgICAgIGNvbnN0IGluZGV4ID0gbGlzdFJlZi5jdXJyZW50LmluZGV4T2YoY3VycmVudFRhcmdldCk7XG4gICAgICBpZiAoaW5kZXggIT09IC0xICYmIGluZGV4UmVmLmN1cnJlbnQgIT09IGluZGV4KSB7XG4gICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBpbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBwcm9wcyA9IHtcbiAgICAgIG9uRm9jdXMoX3JlZikge1xuICAgICAgICBsZXQge1xuICAgICAgICAgIGN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSA9IF9yZWY7XG4gICAgICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICBzeW5jQ3VycmVudFRhcmdldChjdXJyZW50VGFyZ2V0KTtcbiAgICAgIH0sXG4gICAgICBvbkNsaWNrOiBfcmVmMiA9PiB7XG4gICAgICAgIGxldCB7XG4gICAgICAgICAgY3VycmVudFRhcmdldFxuICAgICAgICB9ID0gX3JlZjI7XG4gICAgICAgIHJldHVybiBjdXJyZW50VGFyZ2V0LmZvY3VzKHtcbiAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIC8vIFNhZmFyaVxuICAgICAgLi4uKGZvY3VzSXRlbU9uSG92ZXIgJiYge1xuICAgICAgICBvbk1vdXNlTW92ZShfcmVmMykge1xuICAgICAgICAgIGxldCB7XG4gICAgICAgICAgICBjdXJyZW50VGFyZ2V0XG4gICAgICAgICAgfSA9IF9yZWYzO1xuICAgICAgICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgIGZvcmNlU2Nyb2xsSW50b1ZpZXdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgICAgIHN5bmNDdXJyZW50VGFyZ2V0KGN1cnJlbnRUYXJnZXQpO1xuICAgICAgICB9LFxuICAgICAgICBvblBvaW50ZXJMZWF2ZShfcmVmNCkge1xuICAgICAgICAgIGxldCB7XG4gICAgICAgICAgICBwb2ludGVyVHlwZVxuICAgICAgICAgIH0gPSBfcmVmNDtcbiAgICAgICAgICBpZiAoIWlzUG9pbnRlck1vZGFsaXR5UmVmLmN1cnJlbnQgfHwgcG9pbnRlclR5cGUgPT09ICd0b3VjaCcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yY2VTeW5jRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IC0xO1xuICAgICAgICAgIG9uTmF2aWdhdGUoKTtcbiAgICAgICAgICBpZiAoIXZpcnR1YWwpIHtcbiAgICAgICAgICAgIHZhciBfZmxvYXRpbmdGb2N1c0VsZW1lbnQ7XG4gICAgICAgICAgICAoX2Zsb2F0aW5nRm9jdXNFbGVtZW50ID0gZmxvYXRpbmdGb2N1c0VsZW1lbnRSZWYuY3VycmVudCkgPT0gbnVsbCB8fCBfZmxvYXRpbmdGb2N1c0VsZW1lbnQuZm9jdXMoe1xuICAgICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfTtcbiAgICByZXR1cm4gcHJvcHM7XG4gIH0sIFtvcGVuLCBmbG9hdGluZ0ZvY3VzRWxlbWVudFJlZiwgZm9jdXNJdGVtT25Ib3ZlciwgbGlzdFJlZiwgb25OYXZpZ2F0ZSwgdmlydHVhbF0pO1xuICBjb25zdCBnZXRQYXJlbnRPcmllbnRhdGlvbiA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICB2YXIgX3RyZWUkbm9kZXNSZWYkY3VycmVuO1xuICAgIHJldHVybiBwYXJlbnRPcmllbnRhdGlvbiAhPSBudWxsID8gcGFyZW50T3JpZW50YXRpb24gOiB0cmVlID09IG51bGwgfHwgKF90cmVlJG5vZGVzUmVmJGN1cnJlbiA9IHRyZWUubm9kZXNSZWYuY3VycmVudC5maW5kKG5vZGUgPT4gbm9kZS5pZCA9PT0gcGFyZW50SWQpKSA9PSBudWxsIHx8IChfdHJlZSRub2Rlc1JlZiRjdXJyZW4gPSBfdHJlZSRub2Rlc1JlZiRjdXJyZW4uY29udGV4dCkgPT0gbnVsbCB8fCAoX3RyZWUkbm9kZXNSZWYkY3VycmVuID0gX3RyZWUkbm9kZXNSZWYkY3VycmVuLmRhdGFSZWYpID09IG51bGwgPyB2b2lkIDAgOiBfdHJlZSRub2Rlc1JlZiRjdXJyZW4uY3VycmVudC5vcmllbnRhdGlvbjtcbiAgfSwgW3BhcmVudElkLCB0cmVlLCBwYXJlbnRPcmllbnRhdGlvbl0pO1xuICBjb25zdCBjb21tb25PbktleURvd24gPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgaXNQb2ludGVyTW9kYWxpdHlSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIGZvcmNlU3luY0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuXG4gICAgLy8gV2hlbiBjb21wb3NpbmcgYSBjaGFyYWN0ZXIsIENocm9tZSBmaXJlcyBBcnJvd0Rvd24gdHdpY2UuIEZpcmVmb3gvU2FmYXJpXG4gICAgLy8gZG9uJ3QgYXBwZWFyIHRvIHN1ZmZlciBmcm9tIHRoaXMuIGBldmVudC5pc0NvbXBvc2luZ2AgaXMgYXZvaWRlZCBkdWUgdG9cbiAgICAvLyBTYWZhcmkgbm90IHN1cHBvcnRpbmcgaXQgcHJvcGVybHkgKGFsdGhvdWdoIGl0J3Mgbm90IG5lZWRlZCBpbiB0aGUgZmlyc3RcbiAgICAvLyBwbGFjZSBmb3IgU2FmYXJpLCBqdXN0IGF2b2lkaW5nIGFueSBwb3NzaWJsZSBpc3N1ZXMpLlxuICAgIGlmIChldmVudC53aGljaCA9PT0gMjI5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXMgYW5pbWF0aW5nIG91dCwgaWdub3JlIG5hdmlnYXRpb24uIE90aGVyd2lzZSxcbiAgICAvLyB0aGUgYGFjdGl2ZUluZGV4YCBnZXRzIHNldCB0byAwIGRlc3BpdGUgbm90IGJlaW5nIG9wZW4gc28gdGhlIG5leHQgdGltZVxuICAgIC8vIHRoZSB1c2VyIEFycm93RG93bnMsIHRoZSBmaXJzdCBpdGVtIHdvbid0IGJlIGZvY3VzZWQuXG4gICAgaWYgKCFsYXRlc3RPcGVuUmVmLmN1cnJlbnQgJiYgZXZlbnQuY3VycmVudFRhcmdldCA9PT0gZmxvYXRpbmdGb2N1c0VsZW1lbnRSZWYuY3VycmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAobmVzdGVkICYmIGlzQ3Jvc3NPcmllbnRhdGlvbkNsb3NlS2V5KGV2ZW50LmtleSwgb3JpZW50YXRpb24sIHJ0bCwgY29scykpIHtcbiAgICAgIC8vIElmIHRoZSBuZXN0ZWQgbGlzdCdzIGNsb3NlIGtleSBpcyBhbHNvIHRoZSBwYXJlbnQgbmF2aWdhdGlvbiBrZXksXG4gICAgICAvLyBsZXQgdGhlIHBhcmVudCBuYXZpZ2F0ZS4gT3RoZXJ3aXNlLCBzdG9wIHByb3BhZ2F0aW5nIHRoZSBldmVudC5cbiAgICAgIGlmICghaXNNYWluT3JpZW50YXRpb25LZXkoZXZlbnQua2V5LCBnZXRQYXJlbnRPcmllbnRhdGlvbigpKSkge1xuICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgfVxuICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2xpc3QtbmF2aWdhdGlvbicpO1xuICAgICAgaWYgKGlzSFRNTEVsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgICBpZiAodmlydHVhbCkge1xuICAgICAgICAgIHRyZWUgPT0gbnVsbCB8fCB0cmVlLmV2ZW50cy5lbWl0KCd2aXJ0dWFsZm9jdXMnLCBlbGVtZW50cy5kb21SZWZlcmVuY2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsZW1lbnRzLmRvbVJlZmVyZW5jZS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGluZGV4UmVmLmN1cnJlbnQ7XG4gICAgY29uc3QgbWluSW5kZXggPSBnZXRNaW5MaXN0SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBtYXhJbmRleCA9IGdldE1heExpc3RJbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXMpO1xuICAgIGlmICghdHlwZWFibGVDb21ib2JveFJlZmVyZW5jZSkge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0hvbWUnKSB7XG4gICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBtaW5JbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VuZCcpIHtcbiAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IG1heEluZGV4O1xuICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gR3JpZCBuYXZpZ2F0aW9uLlxuICAgIGlmIChjb2xzID4gMSkge1xuICAgICAgY29uc3Qgc2l6ZXMgPSBpdGVtU2l6ZXMgfHwgQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogbGlzdFJlZi5jdXJyZW50Lmxlbmd0aFxuICAgICAgfSwgKCkgPT4gKHtcbiAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgIGhlaWdodDogMVxuICAgICAgfSkpO1xuICAgICAgLy8gVG8gY2FsY3VsYXRlIG1vdmVtZW50cyBvbiB0aGUgZ3JpZCwgd2UgdXNlIGh5cG90aGV0aWNhbCBjZWxsIGluZGljZXNcbiAgICAgIC8vIGFzIGlmIGV2ZXJ5IGl0ZW0gd2FzIDF4MSwgdGhlbiBjb252ZXJ0IGJhY2sgdG8gcmVhbCBpbmRpY2VzLlxuICAgICAgY29uc3QgY2VsbE1hcCA9IGNyZWF0ZUdyaWRDZWxsTWFwKHNpemVzLCBjb2xzLCBkZW5zZSk7XG4gICAgICBjb25zdCBtaW5HcmlkSW5kZXggPSBjZWxsTWFwLmZpbmRJbmRleChpbmRleCA9PiBpbmRleCAhPSBudWxsICYmICFpc0xpc3RJbmRleERpc2FibGVkKGxpc3RSZWYsIGluZGV4LCBkaXNhYmxlZEluZGljZXMpKTtcbiAgICAgIC8vIGxhc3QgZW5hYmxlZCBpbmRleFxuICAgICAgY29uc3QgbWF4R3JpZEluZGV4ID0gY2VsbE1hcC5yZWR1Y2UoKGZvdW5kSW5kZXgsIGluZGV4LCBjZWxsSW5kZXgpID0+IGluZGV4ICE9IG51bGwgJiYgIWlzTGlzdEluZGV4RGlzYWJsZWQobGlzdFJlZiwgaW5kZXgsIGRpc2FibGVkSW5kaWNlcykgPyBjZWxsSW5kZXggOiBmb3VuZEluZGV4LCAtMSk7XG4gICAgICBjb25zdCBpbmRleCA9IGNlbGxNYXBbZ2V0R3JpZE5hdmlnYXRlZEluZGV4KHtcbiAgICAgICAgY3VycmVudDogY2VsbE1hcC5tYXAoaXRlbUluZGV4ID0+IGl0ZW1JbmRleCAhPSBudWxsID8gbGlzdFJlZi5jdXJyZW50W2l0ZW1JbmRleF0gOiBudWxsKVxuICAgICAgfSwge1xuICAgICAgICBldmVudCxcbiAgICAgICAgb3JpZW50YXRpb24sXG4gICAgICAgIGxvb3AsXG4gICAgICAgIHJ0bCxcbiAgICAgICAgY29scyxcbiAgICAgICAgLy8gdHJlYXQgdW5kZWZpbmVkIChlbXB0eSBncmlkIHNwYWNlcykgYXMgZGlzYWJsZWQgaW5kaWNlcyBzbyB3ZVxuICAgICAgICAvLyBkb24ndCBlbmQgdXAgaW4gdGhlbVxuICAgICAgICBkaXNhYmxlZEluZGljZXM6IGdldEdyaWRDZWxsSW5kaWNlcyhbLi4uKGRpc2FibGVkSW5kaWNlcyB8fCBsaXN0UmVmLmN1cnJlbnQubWFwKChfLCBpbmRleCkgPT4gaXNMaXN0SW5kZXhEaXNhYmxlZChsaXN0UmVmLCBpbmRleCkgPyBpbmRleCA6IHVuZGVmaW5lZCkpLCB1bmRlZmluZWRdLCBjZWxsTWFwKSxcbiAgICAgICAgbWluSW5kZXg6IG1pbkdyaWRJbmRleCxcbiAgICAgICAgbWF4SW5kZXg6IG1heEdyaWRJbmRleCxcbiAgICAgICAgcHJldkluZGV4OiBnZXRHcmlkQ2VsbEluZGV4T2ZDb3JuZXIoaW5kZXhSZWYuY3VycmVudCA+IG1heEluZGV4ID8gbWluSW5kZXggOiBpbmRleFJlZi5jdXJyZW50LCBzaXplcywgY2VsbE1hcCwgY29scyxcbiAgICAgICAgLy8gdXNlIGEgY29ybmVyIG1hdGNoaW5nIHRoZSBlZGdlIGNsb3Nlc3QgdG8gdGhlIGRpcmVjdGlvblxuICAgICAgICAvLyB3ZSdyZSBtb3ZpbmcgaW4gc28gd2UgZG9uJ3QgZW5kIHVwIGluIHRoZSBzYW1lIGl0ZW0uIFByZWZlclxuICAgICAgICAvLyB0b3AvbGVmdCBvdmVyIGJvdHRvbS9yaWdodC5cbiAgICAgICAgZXZlbnQua2V5ID09PSBBUlJPV19ET1dOID8gJ2JsJyA6IGV2ZW50LmtleSA9PT0gKHJ0bCA/IEFSUk9XX0xFRlQgOiBBUlJPV19SSUdIVCkgPyAndHInIDogJ3RsJyksXG4gICAgICAgIHN0b3BFdmVudDogdHJ1ZVxuICAgICAgfSldO1xuICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGluZGV4O1xuICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZW50YXRpb24gPT09ICdib3RoJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc01haW5PcmllbnRhdGlvbktleShldmVudC5rZXksIG9yaWVudGF0aW9uKSkge1xuICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcblxuICAgICAgLy8gUmVzZXQgdGhlIGluZGV4IGlmIG5vIGl0ZW0gaXMgZm9jdXNlZC5cbiAgICAgIGlmIChvcGVuICYmICF2aXJ0dWFsICYmIGFjdGl2ZUVsZW1lbnQoZXZlbnQuY3VycmVudFRhcmdldC5vd25lckRvY3VtZW50KSA9PT0gZXZlbnQuY3VycmVudFRhcmdldCkge1xuICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gaXNNYWluT3JpZW50YXRpb25Ub0VuZEtleShldmVudC5rZXksIG9yaWVudGF0aW9uLCBydGwpID8gbWluSW5kZXggOiBtYXhJbmRleDtcbiAgICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoaXNNYWluT3JpZW50YXRpb25Ub0VuZEtleShldmVudC5rZXksIG9yaWVudGF0aW9uLCBydGwpKSB7XG4gICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGN1cnJlbnRJbmRleCA+PSBtYXhJbmRleCA/IGFsbG93RXNjYXBlICYmIGN1cnJlbnRJbmRleCAhPT0gbGlzdFJlZi5jdXJyZW50Lmxlbmd0aCA/IC0xIDogbWluSW5kZXggOiBmaW5kTm9uRGlzYWJsZWRMaXN0SW5kZXgobGlzdFJlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IE1hdGgubWluKG1heEluZGV4LCBmaW5kTm9uRGlzYWJsZWRMaXN0SW5kZXgobGlzdFJlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobG9vcCkge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBjdXJyZW50SW5kZXggPD0gbWluSW5kZXggPyBhbGxvd0VzY2FwZSAmJiBjdXJyZW50SW5kZXggIT09IC0xID8gbGlzdFJlZi5jdXJyZW50Lmxlbmd0aCA6IG1heEluZGV4IDogZmluZE5vbkRpc2FibGVkTGlzdEluZGV4KGxpc3RSZWYsIHtcbiAgICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IGN1cnJlbnRJbmRleCxcbiAgICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBNYXRoLm1heChtaW5JbmRleCwgZmluZE5vbkRpc2FibGVkTGlzdEluZGV4KGxpc3RSZWYsIHtcbiAgICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IGN1cnJlbnRJbmRleCxcbiAgICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzSW5kZXhPdXRPZkxpc3RCb3VuZHMobGlzdFJlZiwgaW5kZXhSZWYuY3VycmVudCkpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IC0xO1xuICAgICAgfVxuICAgICAgb25OYXZpZ2F0ZSgpO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IGFyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIHJldHVybiB2aXJ0dWFsICYmIG9wZW4gJiYgaGFzQWN0aXZlSW5kZXggJiYge1xuICAgICAgJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCc6IHZpcnR1YWxJZCB8fCBhY3RpdmVJZFxuICAgIH07XG4gIH0sIFt2aXJ0dWFsLCBvcGVuLCBoYXNBY3RpdmVJbmRleCwgdmlydHVhbElkLCBhY3RpdmVJZF0pO1xuICBjb25zdCBmbG9hdGluZyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAnYXJpYS1vcmllbnRhdGlvbic6IG9yaWVudGF0aW9uID09PSAnYm90aCcgPyB1bmRlZmluZWQgOiBvcmllbnRhdGlvbixcbiAgICAgIC4uLighdHlwZWFibGVDb21ib2JveFJlZmVyZW5jZSA/IGFyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCA6IHt9KSxcbiAgICAgIG9uS2V5RG93bjogY29tbW9uT25LZXlEb3duLFxuICAgICAgb25Qb2ludGVyTW92ZSgpIHtcbiAgICAgICAgaXNQb2ludGVyTW9kYWxpdHlSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW2FyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCwgY29tbW9uT25LZXlEb3duLCBvcmllbnRhdGlvbiwgdHlwZWFibGVDb21ib2JveFJlZmVyZW5jZV0pO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBmdW5jdGlvbiBjaGVja1ZpcnR1YWxNb3VzZShldmVudCkge1xuICAgICAgaWYgKGZvY3VzSXRlbU9uT3BlbiA9PT0gJ2F1dG8nICYmIGlzVmlydHVhbENsaWNrKGV2ZW50Lm5hdGl2ZUV2ZW50KSkge1xuICAgICAgICBmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNoZWNrVmlydHVhbFBvaW50ZXIoZXZlbnQpIHtcbiAgICAgIC8vIGBwb2ludGVyZG93bmAgZmlyZXMgZmlyc3QsIHJlc2V0IHRoZSBzdGF0ZSB0aGVuIHBlcmZvcm0gdGhlIGNoZWNrcy5cbiAgICAgIGZvY3VzSXRlbU9uT3BlblJlZi5jdXJyZW50ID0gZm9jdXNJdGVtT25PcGVuO1xuICAgICAgaWYgKGZvY3VzSXRlbU9uT3BlbiA9PT0gJ2F1dG8nICYmIGlzVmlydHVhbFBvaW50ZXJFdmVudChldmVudC5uYXRpdmVFdmVudCkpIHtcbiAgICAgICAgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgLi4uYXJpYUFjdGl2ZURlc2NlbmRhbnRQcm9wLFxuICAgICAgb25LZXlEb3duKGV2ZW50KSB7XG4gICAgICAgIGlzUG9pbnRlck1vZGFsaXR5UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgaXNBcnJvd0tleSA9IGV2ZW50LmtleS5zdGFydHNXaXRoKCdBcnJvdycpO1xuICAgICAgICBjb25zdCBpc0hvbWVPckVuZEtleSA9IFsnSG9tZScsICdFbmQnXS5pbmNsdWRlcyhldmVudC5rZXkpO1xuICAgICAgICBjb25zdCBpc01vdmVLZXkgPSBpc0Fycm93S2V5IHx8IGlzSG9tZU9yRW5kS2V5O1xuICAgICAgICBjb25zdCBpc0Nyb3NzT3BlbktleSA9IGlzQ3Jvc3NPcmllbnRhdGlvbk9wZW5LZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbiwgcnRsKTtcbiAgICAgICAgY29uc3QgaXNDcm9zc0Nsb3NlS2V5ID0gaXNDcm9zc09yaWVudGF0aW9uQ2xvc2VLZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbiwgcnRsLCBjb2xzKTtcbiAgICAgICAgY29uc3QgaXNQYXJlbnRDcm9zc09wZW5LZXkgPSBpc0Nyb3NzT3JpZW50YXRpb25PcGVuS2V5KGV2ZW50LmtleSwgZ2V0UGFyZW50T3JpZW50YXRpb24oKSwgcnRsKTtcbiAgICAgICAgY29uc3QgaXNNYWluS2V5ID0gaXNNYWluT3JpZW50YXRpb25LZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbik7XG4gICAgICAgIGNvbnN0IGlzTmF2aWdhdGlvbktleSA9IChuZXN0ZWQgPyBpc1BhcmVudENyb3NzT3BlbktleSA6IGlzTWFpbktleSkgfHwgZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleS50cmltKCkgPT09ICcnO1xuICAgICAgICBpZiAodmlydHVhbCAmJiBvcGVuKSB7XG4gICAgICAgICAgY29uc3Qgcm9vdE5vZGUgPSB0cmVlID09IG51bGwgPyB2b2lkIDAgOiB0cmVlLm5vZGVzUmVmLmN1cnJlbnQuZmluZChub2RlID0+IG5vZGUucGFyZW50SWQgPT0gbnVsbCk7XG4gICAgICAgICAgY29uc3QgZGVlcGVzdE5vZGUgPSB0cmVlICYmIHJvb3ROb2RlID8gZ2V0RGVlcGVzdE5vZGUodHJlZS5ub2Rlc1JlZi5jdXJyZW50LCByb290Tm9kZS5pZCkgOiBudWxsO1xuICAgICAgICAgIGlmIChpc01vdmVLZXkgJiYgZGVlcGVzdE5vZGUgJiYgdmlydHVhbEl0ZW1SZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50T2JqZWN0ID0gbmV3IEtleWJvYXJkRXZlbnQoJ2tleWRvd24nLCB7XG4gICAgICAgICAgICAgIGtleTogZXZlbnQua2V5LFxuICAgICAgICAgICAgICBidWJibGVzOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChpc0Nyb3NzT3BlbktleSB8fCBpc0Nyb3NzQ2xvc2VLZXkpIHtcbiAgICAgICAgICAgICAgdmFyIF9kZWVwZXN0Tm9kZSRjb250ZXh0LCBfZGVlcGVzdE5vZGUkY29udGV4dDI7XG4gICAgICAgICAgICAgIGNvbnN0IGlzQ3VycmVudFRhcmdldCA9ICgoX2RlZXBlc3ROb2RlJGNvbnRleHQgPSBkZWVwZXN0Tm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RlZXBlc3ROb2RlJGNvbnRleHQuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSA9PT0gZXZlbnQuY3VycmVudFRhcmdldDtcbiAgICAgICAgICAgICAgY29uc3QgZGlzcGF0Y2hJdGVtID0gaXNDcm9zc0Nsb3NlS2V5ICYmICFpc0N1cnJlbnRUYXJnZXQgPyAoX2RlZXBlc3ROb2RlJGNvbnRleHQyID0gZGVlcGVzdE5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9kZWVwZXN0Tm9kZSRjb250ZXh0Mi5lbGVtZW50cy5kb21SZWZlcmVuY2UgOiBpc0Nyb3NzT3BlbktleSA/IGxpc3RSZWYuY3VycmVudC5maW5kKGl0ZW0gPT4gKGl0ZW0gPT0gbnVsbCA/IHZvaWQgMCA6IGl0ZW0uaWQpID09PSBhY3RpdmVJZCkgOiBudWxsO1xuICAgICAgICAgICAgICBpZiAoZGlzcGF0Y2hJdGVtKSB7XG4gICAgICAgICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgICAgICBkaXNwYXRjaEl0ZW0uZGlzcGF0Y2hFdmVudChldmVudE9iamVjdCk7XG4gICAgICAgICAgICAgICAgc2V0VmlydHVhbElkKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgoaXNNYWluS2V5IHx8IGlzSG9tZU9yRW5kS2V5KSAmJiBkZWVwZXN0Tm9kZS5jb250ZXh0KSB7XG4gICAgICAgICAgICAgIGlmIChkZWVwZXN0Tm9kZS5jb250ZXh0Lm9wZW4gJiYgZGVlcGVzdE5vZGUucGFyZW50SWQgJiYgZXZlbnQuY3VycmVudFRhcmdldCAhPT0gZGVlcGVzdE5vZGUuY29udGV4dC5lbGVtZW50cy5kb21SZWZlcmVuY2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2RlZXBlc3ROb2RlJGNvbnRleHQkO1xuICAgICAgICAgICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgICAgICAgICAgKF9kZWVwZXN0Tm9kZSRjb250ZXh0JCA9IGRlZXBlc3ROb2RlLmNvbnRleHQuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSA9PSBudWxsIHx8IF9kZWVwZXN0Tm9kZSRjb250ZXh0JC5kaXNwYXRjaEV2ZW50KGV2ZW50T2JqZWN0KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNvbW1vbk9uS2V5RG93bihldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgYSBmbG9hdGluZyBlbGVtZW50IHNob3VsZCBub3Qgb3BlbiBvbiBhcnJvdyBrZXkgZG93biwgYXZvaWRcbiAgICAgICAgLy8gc2V0dGluZyBgYWN0aXZlSW5kZXhgIHdoaWxlIGl0J3MgY2xvc2VkLlxuICAgICAgICBpZiAoIW9wZW4gJiYgIW9wZW5PbkFycm93S2V5RG93biAmJiBpc0Fycm93S2V5KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdmlnYXRpb25LZXkpIHtcbiAgICAgICAgICBjb25zdCBpc1BhcmVudE1haW5LZXkgPSBpc01haW5PcmllbnRhdGlvbktleShldmVudC5rZXksIGdldFBhcmVudE9yaWVudGF0aW9uKCkpO1xuICAgICAgICAgIGtleVJlZi5jdXJyZW50ID0gbmVzdGVkICYmIGlzUGFyZW50TWFpbktleSA/IG51bGwgOiBldmVudC5rZXk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lc3RlZCkge1xuICAgICAgICAgIGlmIChpc1BhcmVudENyb3NzT3BlbktleSkge1xuICAgICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGlmIChvcGVuKSB7XG4gICAgICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBnZXRNaW5MaXN0SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzUmVmLmN1cnJlbnQpO1xuICAgICAgICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc01haW5LZXkpIHtcbiAgICAgICAgICBpZiAoc2VsZWN0ZWRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICBpZiAoIW9wZW4gJiYgb3Blbk9uQXJyb3dLZXlEb3duKSB7XG4gICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29tbW9uT25LZXlEb3duKGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9wZW4pIHtcbiAgICAgICAgICAgIG9uTmF2aWdhdGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvbkZvY3VzKCkge1xuICAgICAgICBpZiAob3BlbiAmJiAhdmlydHVhbCkge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSAtMTtcbiAgICAgICAgICBvbk5hdmlnYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvblBvaW50ZXJEb3duOiBjaGVja1ZpcnR1YWxQb2ludGVyLFxuICAgICAgb25Qb2ludGVyRW50ZXI6IGNoZWNrVmlydHVhbFBvaW50ZXIsXG4gICAgICBvbk1vdXNlRG93bjogY2hlY2tWaXJ0dWFsTW91c2UsXG4gICAgICBvbkNsaWNrOiBjaGVja1ZpcnR1YWxNb3VzZVxuICAgIH07XG4gIH0sIFthY3RpdmVJZCwgYXJpYUFjdGl2ZURlc2NlbmRhbnRQcm9wLCBjb2xzLCBjb21tb25PbktleURvd24sIGRpc2FibGVkSW5kaWNlc1JlZiwgZm9jdXNJdGVtT25PcGVuLCBsaXN0UmVmLCBuZXN0ZWQsIG9uTmF2aWdhdGUsIG9uT3BlbkNoYW5nZSwgb3Blbiwgb3Blbk9uQXJyb3dLZXlEb3duLCBvcmllbnRhdGlvbiwgZ2V0UGFyZW50T3JpZW50YXRpb24sIHJ0bCwgc2VsZWN0ZWRJbmRleCwgdHJlZSwgdmlydHVhbCwgdmlydHVhbEl0ZW1SZWZdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2UsXG4gICAgZmxvYXRpbmcsXG4gICAgaXRlbVxuICB9IDoge30sIFtlbmFibGVkLCByZWZlcmVuY2UsIGZsb2F0aW5nLCBpdGVtXSk7XG59XG5cbmNvbnN0IGNvbXBvbmVudFJvbGVUb0FyaWFSb2xlTWFwID0gLyojX19QVVJFX18qL25ldyBNYXAoW1snc2VsZWN0JywgJ2xpc3Rib3gnXSwgWydjb21ib2JveCcsICdsaXN0Ym94J10sIFsnbGFiZWwnLCBmYWxzZV1dKTtcblxuLyoqXG4gKiBBZGRzIGJhc2Ugc2NyZWVuIHJlYWRlciBwcm9wcyB0byB0aGUgcmVmZXJlbmNlIGFuZCBmbG9hdGluZyBlbGVtZW50cyBmb3IgYVxuICogZ2l2ZW4gZmxvYXRpbmcgZWxlbWVudCBgcm9sZWAuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlUm9sZVxuICovXG5mdW5jdGlvbiB1c2VSb2xlKGNvbnRleHQsIHByb3BzKSB7XG4gIHZhciBfZWxlbWVudHMkZG9tUmVmZXJlbmMsIF9jb21wb25lbnRSb2xlVG9BcmlhUjtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIGVsZW1lbnRzLFxuICAgIGZsb2F0aW5nSWQ6IGRlZmF1bHRGbG9hdGluZ0lkXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgcm9sZSA9ICdkaWFsb2cnXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgZGVmYXVsdFJlZmVyZW5jZUlkID0gdXNlSWQoKTtcbiAgY29uc3QgcmVmZXJlbmNlSWQgPSAoKF9lbGVtZW50cyRkb21SZWZlcmVuYyA9IGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50cyRkb21SZWZlcmVuYy5pZCkgfHwgZGVmYXVsdFJlZmVyZW5jZUlkO1xuICBjb25zdCBmbG9hdGluZ0lkID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgdmFyIF9nZXRGbG9hdGluZ0ZvY3VzRWxlbTtcbiAgICByZXR1cm4gKChfZ2V0RmxvYXRpbmdGb2N1c0VsZW0gPSBnZXRGbG9hdGluZ0ZvY3VzRWxlbWVudChlbGVtZW50cy5mbG9hdGluZykpID09IG51bGwgPyB2b2lkIDAgOiBfZ2V0RmxvYXRpbmdGb2N1c0VsZW0uaWQpIHx8IGRlZmF1bHRGbG9hdGluZ0lkO1xuICB9LCBbZWxlbWVudHMuZmxvYXRpbmcsIGRlZmF1bHRGbG9hdGluZ0lkXSk7XG4gIGNvbnN0IGFyaWFSb2xlID0gKF9jb21wb25lbnRSb2xlVG9BcmlhUiA9IGNvbXBvbmVudFJvbGVUb0FyaWFSb2xlTWFwLmdldChyb2xlKSkgIT0gbnVsbCA/IF9jb21wb25lbnRSb2xlVG9BcmlhUiA6IHJvbGU7XG4gIGNvbnN0IHBhcmVudElkID0gdXNlRmxvYXRpbmdQYXJlbnROb2RlSWQoKTtcbiAgY29uc3QgaXNOZXN0ZWQgPSBwYXJlbnRJZCAhPSBudWxsO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoYXJpYVJvbGUgPT09ICd0b29sdGlwJyB8fCByb2xlID09PSAnbGFiZWwnKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBbXCJhcmlhLVwiICsgKHJvbGUgPT09ICdsYWJlbCcgPyAnbGFiZWxsZWRieScgOiAnZGVzY3JpYmVkYnknKV06IG9wZW4gPyBmbG9hdGluZ0lkIDogdW5kZWZpbmVkXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgJ2FyaWEtZXhwYW5kZWQnOiBvcGVuID8gJ3RydWUnIDogJ2ZhbHNlJyxcbiAgICAgICdhcmlhLWhhc3BvcHVwJzogYXJpYVJvbGUgPT09ICdhbGVydGRpYWxvZycgPyAnZGlhbG9nJyA6IGFyaWFSb2xlLFxuICAgICAgJ2FyaWEtY29udHJvbHMnOiBvcGVuID8gZmxvYXRpbmdJZCA6IHVuZGVmaW5lZCxcbiAgICAgIC4uLihhcmlhUm9sZSA9PT0gJ2xpc3Rib3gnICYmIHtcbiAgICAgICAgcm9sZTogJ2NvbWJvYm94J1xuICAgICAgfSksXG4gICAgICAuLi4oYXJpYVJvbGUgPT09ICdtZW51JyAmJiB7XG4gICAgICAgIGlkOiByZWZlcmVuY2VJZFxuICAgICAgfSksXG4gICAgICAuLi4oYXJpYVJvbGUgPT09ICdtZW51JyAmJiBpc05lc3RlZCAmJiB7XG4gICAgICAgIHJvbGU6ICdtZW51aXRlbSdcbiAgICAgIH0pLFxuICAgICAgLi4uKHJvbGUgPT09ICdzZWxlY3QnICYmIHtcbiAgICAgICAgJ2FyaWEtYXV0b2NvbXBsZXRlJzogJ25vbmUnXG4gICAgICB9KSxcbiAgICAgIC4uLihyb2xlID09PSAnY29tYm9ib3gnICYmIHtcbiAgICAgICAgJ2FyaWEtYXV0b2NvbXBsZXRlJzogJ2xpc3QnXG4gICAgICB9KVxuICAgIH07XG4gIH0sIFthcmlhUm9sZSwgZmxvYXRpbmdJZCwgaXNOZXN0ZWQsIG9wZW4sIHJlZmVyZW5jZUlkLCByb2xlXSk7XG4gIGNvbnN0IGZsb2F0aW5nID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgZmxvYXRpbmdQcm9wcyA9IHtcbiAgICAgIGlkOiBmbG9hdGluZ0lkLFxuICAgICAgLi4uKGFyaWFSb2xlICYmIHtcbiAgICAgICAgcm9sZTogYXJpYVJvbGVcbiAgICAgIH0pXG4gICAgfTtcbiAgICBpZiAoYXJpYVJvbGUgPT09ICd0b29sdGlwJyB8fCByb2xlID09PSAnbGFiZWwnKSB7XG4gICAgICByZXR1cm4gZmxvYXRpbmdQcm9wcztcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZsb2F0aW5nUHJvcHMsXG4gICAgICAuLi4oYXJpYVJvbGUgPT09ICdtZW51JyAmJiB7XG4gICAgICAgICdhcmlhLWxhYmVsbGVkYnknOiByZWZlcmVuY2VJZFxuICAgICAgfSlcbiAgICB9O1xuICB9LCBbYXJpYVJvbGUsIGZsb2F0aW5nSWQsIHJlZmVyZW5jZUlkLCByb2xlXSk7XG4gIGNvbnN0IGl0ZW0gPSBSZWFjdC51c2VDYWxsYmFjayhfcmVmID0+IHtcbiAgICBsZXQge1xuICAgICAgYWN0aXZlLFxuICAgICAgc2VsZWN0ZWRcbiAgICB9ID0gX3JlZjtcbiAgICBjb25zdCBjb21tb25Qcm9wcyA9IHtcbiAgICAgIHJvbGU6ICdvcHRpb24nLFxuICAgICAgLi4uKGFjdGl2ZSAmJiB7XG4gICAgICAgIGlkOiBmbG9hdGluZ0lkICsgXCItZnVpLW9wdGlvblwiXG4gICAgICB9KVxuICAgIH07XG5cbiAgICAvLyBGb3IgYG1lbnVgLCB3ZSBhcmUgdW5hYmxlIHRvIHRlbGwgaWYgdGhlIGl0ZW0gaXMgYSBgbWVudWl0ZW1yYWRpb2BcbiAgICAvLyBvciBgbWVudWl0ZW1jaGVja2JveGAuIEZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSByZWFzb25zLCBhbHNvXG4gICAgLy8gYXZvaWQgZGVmYXVsdGluZyB0byBgbWVudWl0ZW1gIGFzIGl0IG1heSBvdmVyd3JpdGUgY3VzdG9tIHJvbGUgcHJvcHMuXG4gICAgc3dpdGNoIChyb2xlKSB7XG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmNvbW1vblByb3BzLFxuICAgICAgICAgICdhcmlhLXNlbGVjdGVkJzogYWN0aXZlICYmIHNlbGVjdGVkXG4gICAgICAgIH07XG4gICAgICBjYXNlICdjb21ib2JveCc6XG4gICAgICAgIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uUHJvcHMsXG4gICAgICAgICAgICAnYXJpYS1zZWxlY3RlZCc6IHNlbGVjdGVkXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH0sIFtmbG9hdGluZ0lkLCByb2xlXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nLFxuICAgIGl0ZW1cbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlLCBmbG9hdGluZywgaXRlbV0pO1xufVxuXG4vLyBDb252ZXJ0cyBhIEpTIHN0eWxlIGtleSBsaWtlIGBiYWNrZ3JvdW5kQ29sb3JgIHRvIGEgQ1NTIHRyYW5zaXRpb24tcHJvcGVydHlcbi8vIGxpa2UgYGJhY2tncm91bmQtY29sb3JgLlxuY29uc3QgY2FtZWxDYXNlVG9LZWJhYkNhc2UgPSBzdHIgPT4gc3RyLnJlcGxhY2UoL1tBLVpdKyg/IVthLXpdKXxbQS1aXS9nLCAoJCwgb2ZzKSA9PiAob2ZzID8gJy0nIDogJycpICsgJC50b0xvd2VyQ2FzZSgpKTtcbmZ1bmN0aW9uIGV4ZWNXaXRoQXJnc09yUmV0dXJuKHZhbHVlT3JGbiwgYXJncykge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlT3JGbiA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlT3JGbihhcmdzKSA6IHZhbHVlT3JGbjtcbn1cbmZ1bmN0aW9uIHVzZURlbGF5VW5tb3VudChvcGVuLCBkdXJhdGlvbk1zKSB7XG4gIGNvbnN0IFtpc01vdW50ZWQsIHNldElzTW91bnRlZF0gPSBSZWFjdC51c2VTdGF0ZShvcGVuKTtcbiAgaWYgKG9wZW4gJiYgIWlzTW91bnRlZCkge1xuICAgIHNldElzTW91bnRlZCh0cnVlKTtcbiAgfVxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3BlbiAmJiBpc01vdW50ZWQpIHtcbiAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHNldElzTW91bnRlZChmYWxzZSksIGR1cmF0aW9uTXMpO1xuICAgICAgcmV0dXJuICgpID0+IGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICB9XG4gIH0sIFtvcGVuLCBpc01vdW50ZWQsIGR1cmF0aW9uTXNdKTtcbiAgcmV0dXJuIGlzTW91bnRlZDtcbn1cbi8qKlxuICogUHJvdmlkZXMgYSBzdGF0dXMgc3RyaW5nIHRvIGFwcGx5IENTUyB0cmFuc2l0aW9ucyB0byBhIGZsb2F0aW5nIGVsZW1lbnQsXG4gKiBjb3JyZWN0bHkgaGFuZGxpbmcgcGxhY2VtZW50LWF3YXJlIHRyYW5zaXRpb25zLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZVRyYW5zaXRpb24jdXNldHJhbnNpdGlvbnN0YXR1c1xuICovXG5mdW5jdGlvbiB1c2VUcmFuc2l0aW9uU3RhdHVzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBlbGVtZW50czoge1xuICAgICAgZmxvYXRpbmdcbiAgICB9XG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZHVyYXRpb24gPSAyNTBcbiAgfSA9IHByb3BzO1xuICBjb25zdCBpc051bWJlckR1cmF0aW9uID0gdHlwZW9mIGR1cmF0aW9uID09PSAnbnVtYmVyJztcbiAgY29uc3QgY2xvc2VEdXJhdGlvbiA9IChpc051bWJlckR1cmF0aW9uID8gZHVyYXRpb24gOiBkdXJhdGlvbi5jbG9zZSkgfHwgMDtcbiAgY29uc3QgW3N0YXR1cywgc2V0U3RhdHVzXSA9IFJlYWN0LnVzZVN0YXRlKCd1bm1vdW50ZWQnKTtcbiAgY29uc3QgaXNNb3VudGVkID0gdXNlRGVsYXlVbm1vdW50KG9wZW4sIGNsb3NlRHVyYXRpb24pO1xuICBpZiAoIWlzTW91bnRlZCAmJiBzdGF0dXMgPT09ICdjbG9zZScpIHtcbiAgICBzZXRTdGF0dXMoJ3VubW91bnRlZCcpO1xuICB9XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFmbG9hdGluZykgcmV0dXJuO1xuICAgIGlmIChvcGVuKSB7XG4gICAgICBzZXRTdGF0dXMoJ2luaXRpYWwnKTtcbiAgICAgIGNvbnN0IGZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgLy8gRW5zdXJlIGl0IG9wZW5zIGJlZm9yZSBwYWludC4gV2l0aCBgRmxvYXRpbmdEZWxheUdyb3VwYCxcbiAgICAgICAgLy8gdGhpcyBhdm9pZHMgYSBmbGlja2VyIHdoZW4gbW92aW5nIGJldHdlZW4gZmxvYXRpbmcgZWxlbWVudHNcbiAgICAgICAgLy8gdG8gZW5zdXJlIG9uZSBpcyBhbHdheXMgb3BlbiB3aXRoIG5vIG1pc3NpbmcgZnJhbWVzLlxuICAgICAgICBSZWFjdERPTS5mbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgIHNldFN0YXR1cygnb3BlbicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUoZnJhbWUpO1xuICAgICAgfTtcbiAgICB9XG4gICAgc2V0U3RhdHVzKCdjbG9zZScpO1xuICB9LCBbb3BlbiwgZmxvYXRpbmddKTtcbiAgcmV0dXJuIHtcbiAgICBpc01vdW50ZWQsXG4gICAgc3RhdHVzXG4gIH07XG59XG4vKipcbiAqIFByb3ZpZGVzIHN0eWxlcyB0byBhcHBseSBDU1MgdHJhbnNpdGlvbnMgdG8gYSBmbG9hdGluZyBlbGVtZW50LCBjb3JyZWN0bHlcbiAqIGhhbmRsaW5nIHBsYWNlbWVudC1hd2FyZSB0cmFuc2l0aW9ucy4gV3JhcHBlciBhcm91bmQgYHVzZVRyYW5zaXRpb25TdGF0dXNgLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZVRyYW5zaXRpb24jdXNldHJhbnNpdGlvbnN0eWxlc1xuICovXG5mdW5jdGlvbiB1c2VUcmFuc2l0aW9uU3R5bGVzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgaW5pdGlhbDogdW5zdGFibGVfaW5pdGlhbCA9IHtcbiAgICAgIG9wYWNpdHk6IDBcbiAgICB9LFxuICAgIG9wZW46IHVuc3RhYmxlX29wZW4sXG4gICAgY2xvc2U6IHVuc3RhYmxlX2Nsb3NlLFxuICAgIGNvbW1vbjogdW5zdGFibGVfY29tbW9uLFxuICAgIGR1cmF0aW9uID0gMjUwXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgcGxhY2VtZW50ID0gY29udGV4dC5wbGFjZW1lbnQ7XG4gIGNvbnN0IHNpZGUgPSBwbGFjZW1lbnQuc3BsaXQoJy0nKVswXTtcbiAgY29uc3QgZm5BcmdzID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIHNpZGUsXG4gICAgcGxhY2VtZW50XG4gIH0pLCBbc2lkZSwgcGxhY2VtZW50XSk7XG4gIGNvbnN0IGlzTnVtYmVyRHVyYXRpb24gPSB0eXBlb2YgZHVyYXRpb24gPT09ICdudW1iZXInO1xuICBjb25zdCBvcGVuRHVyYXRpb24gPSAoaXNOdW1iZXJEdXJhdGlvbiA/IGR1cmF0aW9uIDogZHVyYXRpb24ub3BlbikgfHwgMDtcbiAgY29uc3QgY2xvc2VEdXJhdGlvbiA9IChpc051bWJlckR1cmF0aW9uID8gZHVyYXRpb24gOiBkdXJhdGlvbi5jbG9zZSkgfHwgMDtcbiAgY29uc3QgW3N0eWxlcywgc2V0U3R5bGVzXSA9IFJlYWN0LnVzZVN0YXRlKCgpID0+ICh7XG4gICAgLi4uZXhlY1dpdGhBcmdzT3JSZXR1cm4odW5zdGFibGVfY29tbW9uLCBmbkFyZ3MpLFxuICAgIC4uLmV4ZWNXaXRoQXJnc09yUmV0dXJuKHVuc3RhYmxlX2luaXRpYWwsIGZuQXJncylcbiAgfSkpO1xuICBjb25zdCB7XG4gICAgaXNNb3VudGVkLFxuICAgIHN0YXR1c1xuICB9ID0gdXNlVHJhbnNpdGlvblN0YXR1cyhjb250ZXh0LCB7XG4gICAgZHVyYXRpb25cbiAgfSk7XG4gIGNvbnN0IGluaXRpYWxSZWYgPSB1c2VMYXRlc3RSZWYodW5zdGFibGVfaW5pdGlhbCk7XG4gIGNvbnN0IG9wZW5SZWYgPSB1c2VMYXRlc3RSZWYodW5zdGFibGVfb3Blbik7XG4gIGNvbnN0IGNsb3NlUmVmID0gdXNlTGF0ZXN0UmVmKHVuc3RhYmxlX2Nsb3NlKTtcbiAgY29uc3QgY29tbW9uUmVmID0gdXNlTGF0ZXN0UmVmKHVuc3RhYmxlX2NvbW1vbik7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgaW5pdGlhbFN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKGluaXRpYWxSZWYuY3VycmVudCwgZm5BcmdzKTtcbiAgICBjb25zdCBjbG9zZVN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKGNsb3NlUmVmLmN1cnJlbnQsIGZuQXJncyk7XG4gICAgY29uc3QgY29tbW9uU3R5bGVzID0gZXhlY1dpdGhBcmdzT3JSZXR1cm4oY29tbW9uUmVmLmN1cnJlbnQsIGZuQXJncyk7XG4gICAgY29uc3Qgb3BlblN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKG9wZW5SZWYuY3VycmVudCwgZm5BcmdzKSB8fCBPYmplY3Qua2V5cyhpbml0aWFsU3R5bGVzKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBhY2Nba2V5XSA9ICcnO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gICAgaWYgKHN0YXR1cyA9PT0gJ2luaXRpYWwnKSB7XG4gICAgICBzZXRTdHlsZXMoc3R5bGVzID0+ICh7XG4gICAgICAgIHRyYW5zaXRpb25Qcm9wZXJ0eTogc3R5bGVzLnRyYW5zaXRpb25Qcm9wZXJ0eSxcbiAgICAgICAgLi4uY29tbW9uU3R5bGVzLFxuICAgICAgICAuLi5pbml0aWFsU3R5bGVzXG4gICAgICB9KSk7XG4gICAgfVxuICAgIGlmIChzdGF0dXMgPT09ICdvcGVuJykge1xuICAgICAgc2V0U3R5bGVzKHtcbiAgICAgICAgdHJhbnNpdGlvblByb3BlcnR5OiBPYmplY3Qua2V5cyhvcGVuU3R5bGVzKS5tYXAoY2FtZWxDYXNlVG9LZWJhYkNhc2UpLmpvaW4oJywnKSxcbiAgICAgICAgdHJhbnNpdGlvbkR1cmF0aW9uOiBvcGVuRHVyYXRpb24gKyBcIm1zXCIsXG4gICAgICAgIC4uLmNvbW1vblN0eWxlcyxcbiAgICAgICAgLi4ub3BlblN0eWxlc1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChzdGF0dXMgPT09ICdjbG9zZScpIHtcbiAgICAgIGNvbnN0IHN0eWxlcyA9IGNsb3NlU3R5bGVzIHx8IGluaXRpYWxTdHlsZXM7XG4gICAgICBzZXRTdHlsZXMoe1xuICAgICAgICB0cmFuc2l0aW9uUHJvcGVydHk6IE9iamVjdC5rZXlzKHN0eWxlcykubWFwKGNhbWVsQ2FzZVRvS2ViYWJDYXNlKS5qb2luKCcsJyksXG4gICAgICAgIHRyYW5zaXRpb25EdXJhdGlvbjogY2xvc2VEdXJhdGlvbiArIFwibXNcIixcbiAgICAgICAgLi4uY29tbW9uU3R5bGVzLFxuICAgICAgICAuLi5zdHlsZXNcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwgW2Nsb3NlRHVyYXRpb24sIGNsb3NlUmVmLCBpbml0aWFsUmVmLCBvcGVuUmVmLCBjb21tb25SZWYsIG9wZW5EdXJhdGlvbiwgc3RhdHVzLCBmbkFyZ3NdKTtcbiAgcmV0dXJuIHtcbiAgICBpc01vdW50ZWQsXG4gICAgc3R5bGVzXG4gIH07XG59XG5cbi8qKlxuICogUHJvdmlkZXMgYSBtYXRjaGluZyBjYWxsYmFjayB0aGF0IGNhbiBiZSB1c2VkIHRvIGZvY3VzIGFuIGl0ZW0gYXMgdGhlIHVzZXJcbiAqIHR5cGVzLCBvZnRlbiB1c2VkIGluIHRhbmRlbSB3aXRoIGB1c2VMaXN0TmF2aWdhdGlvbigpYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VUeXBlYWhlYWRcbiAqL1xuZnVuY3Rpb24gdXNlVHlwZWFoZWFkKGNvbnRleHQsIHByb3BzKSB7XG4gIHZhciBfcmVmO1xuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBkYXRhUmVmXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgbGlzdFJlZixcbiAgICBhY3RpdmVJbmRleCxcbiAgICBvbk1hdGNoOiB1bnN0YWJsZV9vbk1hdGNoLFxuICAgIG9uVHlwaW5nQ2hhbmdlOiB1bnN0YWJsZV9vblR5cGluZ0NoYW5nZSxcbiAgICBlbmFibGVkID0gdHJ1ZSxcbiAgICBmaW5kTWF0Y2ggPSBudWxsLFxuICAgIHJlc2V0TXMgPSA3NTAsXG4gICAgaWdub3JlS2V5cyA9IFtdLFxuICAgIHNlbGVjdGVkSW5kZXggPSBudWxsXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdGltZW91dElkUmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3Qgc3RyaW5nUmVmID0gUmVhY3QudXNlUmVmKCcnKTtcbiAgY29uc3QgcHJldkluZGV4UmVmID0gUmVhY3QudXNlUmVmKChfcmVmID0gc2VsZWN0ZWRJbmRleCAhPSBudWxsID8gc2VsZWN0ZWRJbmRleCA6IGFjdGl2ZUluZGV4KSAhPSBudWxsID8gX3JlZiA6IC0xKTtcbiAgY29uc3QgbWF0Y2hJbmRleFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3Qgb25NYXRjaCA9IHVzZUVmZmVjdEV2ZW50KHVuc3RhYmxlX29uTWF0Y2gpO1xuICBjb25zdCBvblR5cGluZ0NoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KHVuc3RhYmxlX29uVHlwaW5nQ2hhbmdlKTtcbiAgY29uc3QgZmluZE1hdGNoUmVmID0gdXNlTGF0ZXN0UmVmKGZpbmRNYXRjaCk7XG4gIGNvbnN0IGlnbm9yZUtleXNSZWYgPSB1c2VMYXRlc3RSZWYoaWdub3JlS2V5cyk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKG9wZW4pIHtcbiAgICAgIGNsZWFyVGltZW91dElmU2V0KHRpbWVvdXRJZFJlZik7XG4gICAgICBtYXRjaEluZGV4UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgc3RyaW5nUmVmLmN1cnJlbnQgPSAnJztcbiAgICB9XG4gIH0sIFtvcGVuXSk7XG4gIHVzZU1vZGVybkxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgLy8gU3luYyBhcnJvdyBrZXkgbmF2aWdhdGlvbiBidXQgbm90IHR5cGVhaGVhZCBuYXZpZ2F0aW9uLlxuICAgIGlmIChvcGVuICYmIHN0cmluZ1JlZi5jdXJyZW50ID09PSAnJykge1xuICAgICAgdmFyIF9yZWYyO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSAoX3JlZjIgPSBzZWxlY3RlZEluZGV4ICE9IG51bGwgPyBzZWxlY3RlZEluZGV4IDogYWN0aXZlSW5kZXgpICE9IG51bGwgPyBfcmVmMiA6IC0xO1xuICAgIH1cbiAgfSwgW29wZW4sIHNlbGVjdGVkSW5kZXgsIGFjdGl2ZUluZGV4XSk7XG4gIGNvbnN0IHNldFR5cGluZ0NoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KHZhbHVlID0+IHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGlmICghZGF0YVJlZi5jdXJyZW50LnR5cGluZykge1xuICAgICAgICBkYXRhUmVmLmN1cnJlbnQudHlwaW5nID0gdmFsdWU7XG4gICAgICAgIG9uVHlwaW5nQ2hhbmdlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGFSZWYuY3VycmVudC50eXBpbmcpIHtcbiAgICAgICAgZGF0YVJlZi5jdXJyZW50LnR5cGluZyA9IHZhbHVlO1xuICAgICAgICBvblR5cGluZ0NoYW5nZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgY29uc3Qgb25LZXlEb3duID0gdXNlRWZmZWN0RXZlbnQoZXZlbnQgPT4ge1xuICAgIGZ1bmN0aW9uIGdldE1hdGNoaW5nSW5kZXgobGlzdCwgb3JkZXJlZExpc3QsIHN0cmluZykge1xuICAgICAgY29uc3Qgc3RyID0gZmluZE1hdGNoUmVmLmN1cnJlbnQgPyBmaW5kTWF0Y2hSZWYuY3VycmVudChvcmRlcmVkTGlzdCwgc3RyaW5nKSA6IG9yZGVyZWRMaXN0LmZpbmQodGV4dCA9PiAodGV4dCA9PSBudWxsID8gdm9pZCAwIDogdGV4dC50b0xvY2FsZUxvd2VyQ2FzZSgpLmluZGV4T2Yoc3RyaW5nLnRvTG9jYWxlTG93ZXJDYXNlKCkpKSA9PT0gMCk7XG4gICAgICByZXR1cm4gc3RyID8gbGlzdC5pbmRleE9mKHN0cikgOiAtMTtcbiAgICB9XG4gICAgY29uc3QgbGlzdENvbnRlbnQgPSBsaXN0UmVmLmN1cnJlbnQ7XG4gICAgaWYgKHN0cmluZ1JlZi5jdXJyZW50Lmxlbmd0aCA+IDAgJiYgc3RyaW5nUmVmLmN1cnJlbnRbMF0gIT09ICcgJykge1xuICAgICAgaWYgKGdldE1hdGNoaW5nSW5kZXgobGlzdENvbnRlbnQsIGxpc3RDb250ZW50LCBzdHJpbmdSZWYuY3VycmVudCkgPT09IC0xKSB7XG4gICAgICAgIHNldFR5cGluZ0NoYW5nZShmYWxzZSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJyAnKSB7XG4gICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChsaXN0Q29udGVudCA9PSBudWxsIHx8IGlnbm9yZUtleXNSZWYuY3VycmVudC5pbmNsdWRlcyhldmVudC5rZXkpIHx8XG4gICAgLy8gQ2hhcmFjdGVyIGtleS5cbiAgICBldmVudC5rZXkubGVuZ3RoICE9PSAxIHx8XG4gICAgLy8gTW9kaWZpZXIga2V5LlxuICAgIGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5hbHRLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG9wZW4gJiYgZXZlbnQua2V5ICE9PSAnICcpIHtcbiAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICBzZXRUeXBpbmdDaGFuZ2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQmFpbCBvdXQgaWYgdGhlIGxpc3QgY29udGFpbnMgYSB3b3JkIGxpa2UgXCJsbGFtYVwiIG9yIFwiYWFyb25cIi4gVE9ETzpcbiAgICAvLyBhbGxvdyBpdCBpbiB0aGlzIGNhc2UsIHRvby5cbiAgICBjb25zdCBhbGxvd1JhcGlkU3VjY2Vzc2lvbk9mRmlyc3RMZXR0ZXIgPSBsaXN0Q29udGVudC5ldmVyeSh0ZXh0ID0+IHtcbiAgICAgIHZhciBfdGV4dCQsIF90ZXh0JDI7XG4gICAgICByZXR1cm4gdGV4dCA/ICgoX3RleHQkID0gdGV4dFswXSkgPT0gbnVsbCA/IHZvaWQgMCA6IF90ZXh0JC50b0xvY2FsZUxvd2VyQ2FzZSgpKSAhPT0gKChfdGV4dCQyID0gdGV4dFsxXSkgPT0gbnVsbCA/IHZvaWQgMCA6IF90ZXh0JDIudG9Mb2NhbGVMb3dlckNhc2UoKSkgOiB0cnVlO1xuICAgIH0pO1xuXG4gICAgLy8gQWxsb3dzIHRoZSB1c2VyIHRvIGN5Y2xlIHRocm91Z2ggaXRlbXMgdGhhdCBzdGFydCB3aXRoIHRoZSBzYW1lIGxldHRlclxuICAgIC8vIGluIHJhcGlkIHN1Y2Nlc3Npb24uXG4gICAgaWYgKGFsbG93UmFwaWRTdWNjZXNzaW9uT2ZGaXJzdExldHRlciAmJiBzdHJpbmdSZWYuY3VycmVudCA9PT0gZXZlbnQua2V5KSB7XG4gICAgICBzdHJpbmdSZWYuY3VycmVudCA9ICcnO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSBtYXRjaEluZGV4UmVmLmN1cnJlbnQ7XG4gICAgfVxuICAgIHN0cmluZ1JlZi5jdXJyZW50ICs9IGV2ZW50LmtleTtcbiAgICBjbGVhclRpbWVvdXRJZlNldCh0aW1lb3V0SWRSZWYpO1xuICAgIHRpbWVvdXRJZFJlZi5jdXJyZW50ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3RyaW5nUmVmLmN1cnJlbnQgPSAnJztcbiAgICAgIHByZXZJbmRleFJlZi5jdXJyZW50ID0gbWF0Y2hJbmRleFJlZi5jdXJyZW50O1xuICAgICAgc2V0VHlwaW5nQ2hhbmdlKGZhbHNlKTtcbiAgICB9LCByZXNldE1zKTtcbiAgICBjb25zdCBwcmV2SW5kZXggPSBwcmV2SW5kZXhSZWYuY3VycmVudDtcbiAgICBjb25zdCBpbmRleCA9IGdldE1hdGNoaW5nSW5kZXgobGlzdENvbnRlbnQsIFsuLi5saXN0Q29udGVudC5zbGljZSgocHJldkluZGV4IHx8IDApICsgMSksIC4uLmxpc3RDb250ZW50LnNsaWNlKDAsIChwcmV2SW5kZXggfHwgMCkgKyAxKV0sIHN0cmluZ1JlZi5jdXJyZW50KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBvbk1hdGNoKGluZGV4KTtcbiAgICAgIG1hdGNoSW5kZXhSZWYuY3VycmVudCA9IGluZGV4O1xuICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ICE9PSAnICcpIHtcbiAgICAgIHN0cmluZ1JlZi5jdXJyZW50ID0gJyc7XG4gICAgICBzZXRUeXBpbmdDaGFuZ2UoZmFsc2UpO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBvbktleURvd25cbiAgfSksIFtvbktleURvd25dKTtcbiAgY29uc3QgZmxvYXRpbmcgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgb25LZXlEb3duLFxuICAgICAgb25LZXlVcChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnICcpIHtcbiAgICAgICAgICBzZXRUeXBpbmdDaGFuZ2UoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW29uS2V5RG93biwgc2V0VHlwaW5nQ2hhbmdlXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZSwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gZ2V0QXJnc1dpdGhDdXN0b21GbG9hdGluZ0hlaWdodChzdGF0ZSwgaGVpZ2h0KSB7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgcmVjdHM6IHtcbiAgICAgIC4uLnN0YXRlLnJlY3RzLFxuICAgICAgZmxvYXRpbmc6IHtcbiAgICAgICAgLi4uc3RhdGUucmVjdHMuZmxvYXRpbmcsXG4gICAgICAgIGhlaWdodFxuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbi8qKlxuICogUG9zaXRpb25zIHRoZSBmbG9hdGluZyBlbGVtZW50IHN1Y2ggdGhhdCBhbiBpbm5lciBlbGVtZW50IGluc2lkZSBvZiBpdCBpc1xuICogYW5jaG9yZWQgdG8gdGhlIHJlZmVyZW5jZSBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL2lubmVyXG4gKiBAZGVwcmVjYXRlZFxuICovXG5jb25zdCBpbm5lciA9IHByb3BzID0+ICh7XG4gIG5hbWU6ICdpbm5lcicsXG4gIG9wdGlvbnM6IHByb3BzLFxuICBhc3luYyBmbihzdGF0ZSkge1xuICAgIGNvbnN0IHtcbiAgICAgIGxpc3RSZWYsXG4gICAgICBvdmVyZmxvd1JlZixcbiAgICAgIG9uRmFsbGJhY2tDaGFuZ2UsXG4gICAgICBvZmZzZXQ6IGlubmVyT2Zmc2V0ID0gMCxcbiAgICAgIGluZGV4ID0gMCxcbiAgICAgIG1pbkl0ZW1zVmlzaWJsZSA9IDQsXG4gICAgICByZWZlcmVuY2VPdmVyZmxvd1RocmVzaG9sZCA9IDAsXG4gICAgICBzY3JvbGxSZWYsXG4gICAgICAuLi5kZXRlY3RPdmVyZmxvd09wdGlvbnNcbiAgICB9ID0gZXZhbHVhdGUocHJvcHMsIHN0YXRlKTtcbiAgICBjb25zdCB7XG4gICAgICByZWN0cyxcbiAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgIGZsb2F0aW5nXG4gICAgICB9XG4gICAgfSA9IHN0YXRlO1xuICAgIGNvbnN0IGl0ZW0gPSBsaXN0UmVmLmN1cnJlbnRbaW5kZXhdO1xuICAgIGNvbnN0IHNjcm9sbEVsID0gKHNjcm9sbFJlZiA9PSBudWxsID8gdm9pZCAwIDogc2Nyb2xsUmVmLmN1cnJlbnQpIHx8IGZsb2F0aW5nO1xuXG4gICAgLy8gVmFsaWQgY29tYmluYXRpb25zOlxuICAgIC8vIDEuIEZsb2F0aW5nIGVsZW1lbnQgaXMgdGhlIHNjcm9sbFJlZiBhbmQgaGFzIGEgYm9yZGVyIChkZWZhdWx0KVxuICAgIC8vIDIuIEZsb2F0aW5nIGVsZW1lbnQgaXMgbm90IHRoZSBzY3JvbGxSZWYsIGZsb2F0aW5nIGVsZW1lbnQgaGFzIGEgYm9yZGVyXG4gICAgLy8gMy4gRmxvYXRpbmcgZWxlbWVudCBpcyBub3QgdGhlIHNjcm9sbFJlZiwgc2Nyb2xsUmVmIGhhcyBhIGJvcmRlclxuICAgIC8vIEZsb2F0aW5nID4gey4uLmdldEZsb2F0aW5nUHJvcHMoKX0gd3JhcHBlciA+IHNjcm9sbFJlZiA+IGl0ZW1zIGlzIG5vdFxuICAgIC8vIGFsbG93ZWQgYXMgVm9pY2VPdmVyIGRvZXNuJ3Qgd29yay5cbiAgICBjb25zdCBjbGllbnRUb3AgPSBmbG9hdGluZy5jbGllbnRUb3AgfHwgc2Nyb2xsRWwuY2xpZW50VG9wO1xuICAgIGNvbnN0IGZsb2F0aW5nSXNCb3JkZXJlZCA9IGZsb2F0aW5nLmNsaWVudFRvcCAhPT0gMDtcbiAgICBjb25zdCBzY3JvbGxFbElzQm9yZGVyZWQgPSBzY3JvbGxFbC5jbGllbnRUb3AgIT09IDA7XG4gICAgY29uc3QgZmxvYXRpbmdJc1Njcm9sbEVsID0gZmxvYXRpbmcgPT09IHNjcm9sbEVsO1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgIGlmICghc3RhdGUucGxhY2VtZW50LnN0YXJ0c1dpdGgoJ2JvdHRvbScpKSB7XG4gICAgICAgIHdhcm4oJ2BwbGFjZW1lbnRgIHNpZGUgbXVzdCBiZSBcImJvdHRvbVwiIHdoZW4gdXNpbmcgdGhlIGBpbm5lcmAnLCAnbWlkZGxld2FyZS4nKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFpdGVtKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IG5leHRBcmdzID0ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICAuLi4oYXdhaXQgb2Zmc2V0KC1pdGVtLm9mZnNldFRvcCAtIGZsb2F0aW5nLmNsaWVudFRvcCAtIHJlY3RzLnJlZmVyZW5jZS5oZWlnaHQgLyAyIC0gaXRlbS5vZmZzZXRIZWlnaHQgLyAyIC0gaW5uZXJPZmZzZXQpLmZuKHN0YXRlKSlcbiAgICB9O1xuICAgIGNvbnN0IG92ZXJmbG93ID0gYXdhaXQgZGV0ZWN0T3ZlcmZsb3coZ2V0QXJnc1dpdGhDdXN0b21GbG9hdGluZ0hlaWdodChuZXh0QXJncywgc2Nyb2xsRWwuc2Nyb2xsSGVpZ2h0ICsgY2xpZW50VG9wICsgZmxvYXRpbmcuY2xpZW50VG9wKSwgZGV0ZWN0T3ZlcmZsb3dPcHRpb25zKTtcbiAgICBjb25zdCByZWZPdmVyZmxvdyA9IGF3YWl0IGRldGVjdE92ZXJmbG93KG5leHRBcmdzLCB7XG4gICAgICAuLi5kZXRlY3RPdmVyZmxvd09wdGlvbnMsXG4gICAgICBlbGVtZW50Q29udGV4dDogJ3JlZmVyZW5jZSdcbiAgICB9KTtcbiAgICBjb25zdCBkaWZmWSA9IG1heCgwLCBvdmVyZmxvdy50b3ApO1xuICAgIGNvbnN0IG5leHRZID0gbmV4dEFyZ3MueSArIGRpZmZZO1xuICAgIGNvbnN0IGlzU2Nyb2xsYWJsZSA9IHNjcm9sbEVsLnNjcm9sbEhlaWdodCA+IHNjcm9sbEVsLmNsaWVudEhlaWdodDtcbiAgICBjb25zdCByb3VuZGVyID0gaXNTY3JvbGxhYmxlID8gdiA9PiB2IDogcm91bmQ7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gcm91bmRlcihtYXgoMCwgc2Nyb2xsRWwuc2Nyb2xsSGVpZ2h0ICsgKGZsb2F0aW5nSXNCb3JkZXJlZCAmJiBmbG9hdGluZ0lzU2Nyb2xsRWwgfHwgc2Nyb2xsRWxJc0JvcmRlcmVkID8gY2xpZW50VG9wICogMiA6IDApIC0gZGlmZlkgLSBtYXgoMCwgb3ZlcmZsb3cuYm90dG9tKSkpO1xuICAgIHNjcm9sbEVsLnN0eWxlLm1heEhlaWdodCA9IG1heEhlaWdodCArIFwicHhcIjtcbiAgICBzY3JvbGxFbC5zY3JvbGxUb3AgPSBkaWZmWTtcblxuICAgIC8vIFRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UsIGZhbGxiYWNrIHRvIHN0YW5kYXJkIGFuY2hvcmVkIHBvc2l0aW9uaW5nXG4gICAgaWYgKG9uRmFsbGJhY2tDaGFuZ2UpIHtcbiAgICAgIGNvbnN0IHNob3VsZEZhbGxiYWNrID0gc2Nyb2xsRWwub2Zmc2V0SGVpZ2h0IDwgaXRlbS5vZmZzZXRIZWlnaHQgKiBtaW4obWluSXRlbXNWaXNpYmxlLCBsaXN0UmVmLmN1cnJlbnQubGVuZ3RoKSAtIDEgfHwgcmVmT3ZlcmZsb3cudG9wID49IC1yZWZlcmVuY2VPdmVyZmxvd1RocmVzaG9sZCB8fCByZWZPdmVyZmxvdy5ib3R0b20gPj0gLXJlZmVyZW5jZU92ZXJmbG93VGhyZXNob2xkO1xuICAgICAgUmVhY3RET00uZmx1c2hTeW5jKCgpID0+IG9uRmFsbGJhY2tDaGFuZ2Uoc2hvdWxkRmFsbGJhY2spKTtcbiAgICB9XG4gICAgaWYgKG92ZXJmbG93UmVmKSB7XG4gICAgICBvdmVyZmxvd1JlZi5jdXJyZW50ID0gYXdhaXQgZGV0ZWN0T3ZlcmZsb3coZ2V0QXJnc1dpdGhDdXN0b21GbG9hdGluZ0hlaWdodCh7XG4gICAgICAgIC4uLm5leHRBcmdzLFxuICAgICAgICB5OiBuZXh0WVxuICAgICAgfSwgc2Nyb2xsRWwub2Zmc2V0SGVpZ2h0ICsgY2xpZW50VG9wICsgZmxvYXRpbmcuY2xpZW50VG9wKSwgZGV0ZWN0T3ZlcmZsb3dPcHRpb25zKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHk6IG5leHRZXG4gICAgfTtcbiAgfVxufSk7XG4vKipcbiAqIENoYW5nZXMgdGhlIGBpbm5lcmAgbWlkZGxld2FyZSdzIGBvZmZzZXRgIHVwb24gYSBgd2hlZWxgIGV2ZW50IHRvXG4gKiBleHBhbmQgdGhlIGZsb2F0aW5nIGVsZW1lbnQncyBoZWlnaHQsIHJldmVhbGluZyBtb3JlIGxpc3QgaXRlbXMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvaW5uZXJcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmZ1bmN0aW9uIHVzZUlubmVyT2Zmc2V0KGNvbnRleHQsIHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIGVsZW1lbnRzXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgb3ZlcmZsb3dSZWYsXG4gICAgc2Nyb2xsUmVmLFxuICAgIG9uQ2hhbmdlOiB1bnN0YWJsZV9vbkNoYW5nZVxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IG9uQ2hhbmdlID0gdXNlRWZmZWN0RXZlbnQodW5zdGFibGVfb25DaGFuZ2UpO1xuICBjb25zdCBjb250cm9sbGVkU2Nyb2xsaW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgcHJldlNjcm9sbFRvcFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgaW5pdGlhbE92ZXJmbG93UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIG9uV2hlZWwoZSkge1xuICAgICAgaWYgKGUuY3RybEtleSB8fCAhZWwgfHwgb3ZlcmZsb3dSZWYuY3VycmVudCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRZID0gZS5kZWx0YVk7XG4gICAgICBjb25zdCBpc0F0VG9wID0gb3ZlcmZsb3dSZWYuY3VycmVudC50b3AgPj0gLTAuNTtcbiAgICAgIGNvbnN0IGlzQXRCb3R0b20gPSBvdmVyZmxvd1JlZi5jdXJyZW50LmJvdHRvbSA+PSAtMC41O1xuICAgICAgY29uc3QgcmVtYWluaW5nU2Nyb2xsID0gZWwuc2Nyb2xsSGVpZ2h0IC0gZWwuY2xpZW50SGVpZ2h0O1xuICAgICAgY29uc3Qgc2lnbiA9IGRZIDwgMCA/IC0xIDogMTtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IGRZIDwgMCA/ICdtYXgnIDogJ21pbic7XG4gICAgICBpZiAoZWwuc2Nyb2xsSGVpZ2h0IDw9IGVsLmNsaWVudEhlaWdodCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWlzQXRUb3AgJiYgZFkgPiAwIHx8ICFpc0F0Qm90dG9tICYmIGRZIDwgMCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIFJlYWN0RE9NLmZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgb25DaGFuZ2UoZCA9PiBkICsgTWF0aFttZXRob2RdKGRZLCByZW1haW5pbmdTY3JvbGwgKiBzaWduKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICgvZmlyZWZveC9pLnRlc3QoZ2V0VXNlckFnZW50KCkpKSB7XG4gICAgICAgIC8vIE5lZWRlZCB0byBwcm9wYWdhdGUgc2Nyb2xsaW5nIGR1cmluZyBtb21lbnR1bSBzY3JvbGxpbmcgcGhhc2Ugb25jZVxuICAgICAgICAvLyBpdCBnZXRzIGxpbWl0ZWQgYnkgdGhlIGJvdW5kYXJ5LiBVWCBpbXByb3ZlbWVudCwgbm90IGNyaXRpY2FsLlxuICAgICAgICBlbC5zY3JvbGxUb3AgKz0gZFk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGVsID0gKHNjcm9sbFJlZiA9PSBudWxsID8gdm9pZCAwIDogc2Nyb2xsUmVmLmN1cnJlbnQpIHx8IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgIGlmIChvcGVuICYmIGVsKSB7XG4gICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCd3aGVlbCcsIG9uV2hlZWwpO1xuXG4gICAgICAvLyBXYWl0IGZvciB0aGUgcG9zaXRpb24gdG8gYmUgcmVhZHkuXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgPSBlbC5zY3JvbGxUb3A7XG4gICAgICAgIGlmIChvdmVyZmxvd1JlZi5jdXJyZW50ICE9IG51bGwpIHtcbiAgICAgICAgICBpbml0aWFsT3ZlcmZsb3dSZWYuY3VycmVudCA9IHtcbiAgICAgICAgICAgIC4uLm92ZXJmbG93UmVmLmN1cnJlbnRcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHByZXZTY3JvbGxUb3BSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIGluaXRpYWxPdmVyZmxvd1JlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2hlZWwnLCBvbldoZWVsKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgb3BlbiwgZWxlbWVudHMuZmxvYXRpbmcsIG92ZXJmbG93UmVmLCBzY3JvbGxSZWYsIG9uQ2hhbmdlXSk7XG4gIGNvbnN0IGZsb2F0aW5nID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uS2V5RG93bigpIHtcbiAgICAgIGNvbnRyb2xsZWRTY3JvbGxpbmdSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSxcbiAgICBvbldoZWVsKCkge1xuICAgICAgY29udHJvbGxlZFNjcm9sbGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSxcbiAgICBvblBvaW50ZXJNb3ZlKCkge1xuICAgICAgY29udHJvbGxlZFNjcm9sbGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSxcbiAgICBvblNjcm9sbCgpIHtcbiAgICAgIGNvbnN0IGVsID0gKHNjcm9sbFJlZiA9PSBudWxsID8gdm9pZCAwIDogc2Nyb2xsUmVmLmN1cnJlbnQpIHx8IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgICAgaWYgKCFvdmVyZmxvd1JlZi5jdXJyZW50IHx8ICFlbCB8fCAhY29udHJvbGxlZFNjcm9sbGluZ1JlZi5jdXJyZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3Qgc2Nyb2xsRGlmZiA9IGVsLnNjcm9sbFRvcCAtIHByZXZTY3JvbGxUb3BSZWYuY3VycmVudDtcbiAgICAgICAgaWYgKG92ZXJmbG93UmVmLmN1cnJlbnQuYm90dG9tIDwgLTAuNSAmJiBzY3JvbGxEaWZmIDwgLTEgfHwgb3ZlcmZsb3dSZWYuY3VycmVudC50b3AgPCAtMC41ICYmIHNjcm9sbERpZmYgPiAxKSB7XG4gICAgICAgICAgUmVhY3RET00uZmx1c2hTeW5jKCgpID0+IG9uQ2hhbmdlKGQgPT4gZCArIHNjcm9sbERpZmYpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBbRmlyZWZveF0gV2FpdCBmb3IgdGhlIGhlaWdodCBjaGFuZ2UgdG8gaGF2ZSBiZWVuIGFwcGxpZWQuXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgPSBlbC5zY3JvbGxUb3A7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pLCBbZWxlbWVudHMuZmxvYXRpbmcsIG9uQ2hhbmdlLCBvdmVyZmxvd1JlZiwgc2Nyb2xsUmVmXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgZmxvYXRpbmdcbiAgfSA6IHt9LCBbZW5hYmxlZCwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gZ2V0Tm9kZUNoaWxkcmVuKG5vZGVzLCBpZCwgb25seU9wZW5DaGlsZHJlbikge1xuICBpZiAob25seU9wZW5DaGlsZHJlbiA9PT0gdm9pZCAwKSB7XG4gICAgb25seU9wZW5DaGlsZHJlbiA9IHRydWU7XG4gIH1cbiAgbGV0IGFsbENoaWxkcmVuID0gbm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgIHZhciBfbm9kZSRjb250ZXh0O1xuICAgIHJldHVybiBub2RlLnBhcmVudElkID09PSBpZCAmJiAoKF9ub2RlJGNvbnRleHQgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Lm9wZW4pO1xuICB9KTtcbiAgbGV0IGN1cnJlbnRDaGlsZHJlbiA9IGFsbENoaWxkcmVuO1xuICB3aGlsZSAoY3VycmVudENoaWxkcmVuLmxlbmd0aCkge1xuICAgIGN1cnJlbnRDaGlsZHJlbiA9IG9ubHlPcGVuQ2hpbGRyZW4gPyBub2Rlcy5maWx0ZXIobm9kZSA9PiB7XG4gICAgICB2YXIgX2N1cnJlbnRDaGlsZHJlbjtcbiAgICAgIHJldHVybiAoX2N1cnJlbnRDaGlsZHJlbiA9IGN1cnJlbnRDaGlsZHJlbikgPT0gbnVsbCA/IHZvaWQgMCA6IF9jdXJyZW50Q2hpbGRyZW4uc29tZShuID0+IHtcbiAgICAgICAgdmFyIF9ub2RlJGNvbnRleHQyO1xuICAgICAgICByZXR1cm4gbm9kZS5wYXJlbnRJZCA9PT0gbi5pZCAmJiAoKF9ub2RlJGNvbnRleHQyID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDIub3Blbik7XG4gICAgICB9KTtcbiAgICB9KSA6IG5vZGVzO1xuICAgIGFsbENoaWxkcmVuID0gYWxsQ2hpbGRyZW4uY29uY2F0KGN1cnJlbnRDaGlsZHJlbik7XG4gIH1cbiAgcmV0dXJuIGFsbENoaWxkcmVuO1xufVxuXG5mdW5jdGlvbiBpc1BvaW50SW5Qb2x5Z29uKHBvaW50LCBwb2x5Z29uKSB7XG4gIGNvbnN0IFt4LCB5XSA9IHBvaW50O1xuICBsZXQgaXNJbnNpZGUgPSBmYWxzZTtcbiAgY29uc3QgbGVuZ3RoID0gcG9seWdvbi5sZW5ndGg7XG4gIGZvciAobGV0IGkgPSAwLCBqID0gbGVuZ3RoIC0gMTsgaSA8IGxlbmd0aDsgaiA9IGkrKykge1xuICAgIGNvbnN0IFt4aSwgeWldID0gcG9seWdvbltpXSB8fCBbMCwgMF07XG4gICAgY29uc3QgW3hqLCB5al0gPSBwb2x5Z29uW2pdIHx8IFswLCAwXTtcbiAgICBjb25zdCBpbnRlcnNlY3QgPSB5aSA+PSB5ICE9PSB5aiA+PSB5ICYmIHggPD0gKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aTtcbiAgICBpZiAoaW50ZXJzZWN0KSB7XG4gICAgICBpc0luc2lkZSA9ICFpc0luc2lkZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGlzSW5zaWRlO1xufVxuZnVuY3Rpb24gaXNJbnNpZGUocG9pbnQsIHJlY3QpIHtcbiAgcmV0dXJuIHBvaW50WzBdID49IHJlY3QueCAmJiBwb2ludFswXSA8PSByZWN0LnggKyByZWN0LndpZHRoICYmIHBvaW50WzFdID49IHJlY3QueSAmJiBwb2ludFsxXSA8PSByZWN0LnkgKyByZWN0LmhlaWdodDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgc2FmZSBwb2x5Z29uIGFyZWEgdGhhdCB0aGUgdXNlciBjYW4gdHJhdmVyc2Ugd2l0aG91dCBjbG9zaW5nIHRoZVxuICogZmxvYXRpbmcgZWxlbWVudCBvbmNlIGxlYXZpbmcgdGhlIHJlZmVyZW5jZSBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUhvdmVyI3NhZmVwb2x5Z29uXG4gKi9cbmZ1bmN0aW9uIHNhZmVQb2x5Z29uKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgYnVmZmVyID0gMC41LFxuICAgIGJsb2NrUG9pbnRlckV2ZW50cyA9IGZhbHNlLFxuICAgIHJlcXVpcmVJbnRlbnQgPSB0cnVlXG4gIH0gPSBvcHRpb25zO1xuICBsZXQgdGltZW91dElkO1xuICBsZXQgaGFzTGFuZGVkID0gZmFsc2U7XG4gIGxldCBsYXN0WCA9IG51bGw7XG4gIGxldCBsYXN0WSA9IG51bGw7XG4gIGxldCBsYXN0Q3Vyc29yVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICBmdW5jdGlvbiBnZXRDdXJzb3JTcGVlZCh4LCB5KSB7XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBjb25zdCBlbGFwc2VkVGltZSA9IGN1cnJlbnRUaW1lIC0gbGFzdEN1cnNvclRpbWU7XG4gICAgaWYgKGxhc3RYID09PSBudWxsIHx8IGxhc3RZID09PSBudWxsIHx8IGVsYXBzZWRUaW1lID09PSAwKSB7XG4gICAgICBsYXN0WCA9IHg7XG4gICAgICBsYXN0WSA9IHk7XG4gICAgICBsYXN0Q3Vyc29yVGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGRlbHRhWCA9IHggLSBsYXN0WDtcbiAgICBjb25zdCBkZWx0YVkgPSB5IC0gbGFzdFk7XG4gICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLnNxcnQoZGVsdGFYICogZGVsdGFYICsgZGVsdGFZICogZGVsdGFZKTtcbiAgICBjb25zdCBzcGVlZCA9IGRpc3RhbmNlIC8gZWxhcHNlZFRpbWU7IC8vIHB4IC8gbXNcblxuICAgIGxhc3RYID0geDtcbiAgICBsYXN0WSA9IHk7XG4gICAgbGFzdEN1cnNvclRpbWUgPSBjdXJyZW50VGltZTtcbiAgICByZXR1cm4gc3BlZWQ7XG4gIH1cbiAgY29uc3QgZm4gPSBfcmVmID0+IHtcbiAgICBsZXQge1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBwbGFjZW1lbnQsXG4gICAgICBlbGVtZW50cyxcbiAgICAgIG9uQ2xvc2UsXG4gICAgICBub2RlSWQsXG4gICAgICB0cmVlXG4gICAgfSA9IF9yZWY7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIG9uTW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIG9uQ2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgaWYgKCFlbGVtZW50cy5kb21SZWZlcmVuY2UgfHwgIWVsZW1lbnRzLmZsb2F0aW5nIHx8IHBsYWNlbWVudCA9PSBudWxsIHx8IHggPT0gbnVsbCB8fCB5ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qge1xuICAgICAgICBjbGllbnRYLFxuICAgICAgICBjbGllbnRZXG4gICAgICB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCBjbGllbnRQb2ludCA9IFtjbGllbnRYLCBjbGllbnRZXTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldChldmVudCk7XG4gICAgICBjb25zdCBpc0xlYXZlID0gZXZlbnQudHlwZSA9PT0gJ21vdXNlbGVhdmUnO1xuICAgICAgY29uc3QgaXNPdmVyRmxvYXRpbmdFbCA9IGNvbnRhaW5zKGVsZW1lbnRzLmZsb2F0aW5nLCB0YXJnZXQpO1xuICAgICAgY29uc3QgaXNPdmVyUmVmZXJlbmNlRWwgPSBjb250YWlucyhlbGVtZW50cy5kb21SZWZlcmVuY2UsIHRhcmdldCk7XG4gICAgICBjb25zdCByZWZSZWN0ID0gZWxlbWVudHMuZG9tUmVmZXJlbmNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3QgcmVjdCA9IGVsZW1lbnRzLmZsb2F0aW5nLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qgc2lkZSA9IHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xuICAgICAgY29uc3QgY3Vyc29yTGVhdmVGcm9tUmlnaHQgPSB4ID4gcmVjdC5yaWdodCAtIHJlY3Qud2lkdGggLyAyO1xuICAgICAgY29uc3QgY3Vyc29yTGVhdmVGcm9tQm90dG9tID0geSA+IHJlY3QuYm90dG9tIC0gcmVjdC5oZWlnaHQgLyAyO1xuICAgICAgY29uc3QgaXNPdmVyUmVmZXJlbmNlUmVjdCA9IGlzSW5zaWRlKGNsaWVudFBvaW50LCByZWZSZWN0KTtcbiAgICAgIGNvbnN0IGlzRmxvYXRpbmdXaWRlciA9IHJlY3Qud2lkdGggPiByZWZSZWN0LndpZHRoO1xuICAgICAgY29uc3QgaXNGbG9hdGluZ1RhbGxlciA9IHJlY3QuaGVpZ2h0ID4gcmVmUmVjdC5oZWlnaHQ7XG4gICAgICBjb25zdCBsZWZ0ID0gKGlzRmxvYXRpbmdXaWRlciA/IHJlZlJlY3QgOiByZWN0KS5sZWZ0O1xuICAgICAgY29uc3QgcmlnaHQgPSAoaXNGbG9hdGluZ1dpZGVyID8gcmVmUmVjdCA6IHJlY3QpLnJpZ2h0O1xuICAgICAgY29uc3QgdG9wID0gKGlzRmxvYXRpbmdUYWxsZXIgPyByZWZSZWN0IDogcmVjdCkudG9wO1xuICAgICAgY29uc3QgYm90dG9tID0gKGlzRmxvYXRpbmdUYWxsZXIgPyByZWZSZWN0IDogcmVjdCkuYm90dG9tO1xuICAgICAgaWYgKGlzT3ZlckZsb2F0aW5nRWwpIHtcbiAgICAgICAgaGFzTGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKCFpc0xlYXZlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNPdmVyUmVmZXJlbmNlRWwpIHtcbiAgICAgICAgaGFzTGFuZGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaXNPdmVyUmVmZXJlbmNlRWwgJiYgIWlzTGVhdmUpIHtcbiAgICAgICAgaGFzTGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBQcmV2ZW50IG92ZXJsYXBwaW5nIGZsb2F0aW5nIGVsZW1lbnQgZnJvbSBiZWluZyBzdHVjayBpbiBhbiBvcGVuLWNsb3NlXG4gICAgICAvLyBsb29wOiBodHRwczovL2dpdGh1Yi5jb20vZmxvYXRpbmctdWkvZmxvYXRpbmctdWkvaXNzdWVzLzE5MTBcbiAgICAgIGlmIChpc0xlYXZlICYmIGlzRWxlbWVudChldmVudC5yZWxhdGVkVGFyZ2V0KSAmJiBjb250YWlucyhlbGVtZW50cy5mbG9hdGluZywgZXZlbnQucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBhbnkgbmVzdGVkIGNoaWxkIGlzIG9wZW4sIGFib3J0LlxuICAgICAgaWYgKHRyZWUgJiYgZ2V0Tm9kZUNoaWxkcmVuKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKS5zb21lKF9yZWYyID0+IHtcbiAgICAgICAgbGV0IHtcbiAgICAgICAgICBjb250ZXh0XG4gICAgICAgIH0gPSBfcmVmMjtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IGNvbnRleHQub3BlbjtcbiAgICAgIH0pKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIHBvaW50ZXIgaXMgbGVhdmluZyBmcm9tIHRoZSBvcHBvc2l0ZSBzaWRlLCB0aGUgXCJidWZmZXJcIiBsb2dpY1xuICAgICAgLy8gY3JlYXRlcyBhIHBvaW50IHdoZXJlIHRoZSBmbG9hdGluZyBlbGVtZW50IHJlbWFpbnMgb3BlbiwgYnV0IHNob3VsZCBiZVxuICAgICAgLy8gaWdub3JlZC5cbiAgICAgIC8vIEEgY29uc3RhbnQgb2YgMSBoYW5kbGVzIGZsb2F0aW5nIHBvaW50IHJvdW5kaW5nIGVycm9ycy5cbiAgICAgIGlmIChzaWRlID09PSAndG9wJyAmJiB5ID49IHJlZlJlY3QuYm90dG9tIC0gMSB8fCBzaWRlID09PSAnYm90dG9tJyAmJiB5IDw9IHJlZlJlY3QudG9wICsgMSB8fCBzaWRlID09PSAnbGVmdCcgJiYgeCA+PSByZWZSZWN0LnJpZ2h0IC0gMSB8fCBzaWRlID09PSAncmlnaHQnICYmIHggPD0gcmVmUmVjdC5sZWZ0ICsgMSkge1xuICAgICAgICByZXR1cm4gY2xvc2UoKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWdub3JlIHdoZW4gdGhlIGN1cnNvciBpcyB3aXRoaW4gdGhlIHJlY3Rhbmd1bGFyIHRyb3VnaCBiZXR3ZWVuIHRoZVxuICAgICAgLy8gdHdvIGVsZW1lbnRzLiBTaW5jZSB0aGUgdHJpYW5nbGUgaXMgY3JlYXRlZCBmcm9tIHRoZSBjdXJzb3IgcG9pbnQsXG4gICAgICAvLyB3aGljaCBjYW4gc3RhcnQgYmV5b25kIHRoZSByZWYgZWxlbWVudCdzIGVkZ2UsIHRyYXZlcnNpbmcgYmFjayBhbmRcbiAgICAgIC8vIGZvcnRoIGZyb20gdGhlIHJlZiB0byB0aGUgZmxvYXRpbmcgZWxlbWVudCBjYW4gY2F1c2UgaXQgdG8gY2xvc2UuIFRoaXNcbiAgICAgIC8vIGVuc3VyZXMgaXQgYWx3YXlzIHJlbWFpbnMgb3BlbiBpbiB0aGF0IGNhc2UuXG4gICAgICBsZXQgcmVjdFBvbHkgPSBbXTtcbiAgICAgIHN3aXRjaCAoc2lkZSkge1xuICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgIHJlY3RQb2x5ID0gW1tsZWZ0LCByZWZSZWN0LnRvcCArIDFdLCBbbGVmdCwgcmVjdC5ib3R0b20gLSAxXSwgW3JpZ2h0LCByZWN0LmJvdHRvbSAtIDFdLCBbcmlnaHQsIHJlZlJlY3QudG9wICsgMV1dO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgIHJlY3RQb2x5ID0gW1tsZWZ0LCByZWN0LnRvcCArIDFdLCBbbGVmdCwgcmVmUmVjdC5ib3R0b20gLSAxXSwgW3JpZ2h0LCByZWZSZWN0LmJvdHRvbSAtIDFdLCBbcmlnaHQsIHJlY3QudG9wICsgMV1dO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICByZWN0UG9seSA9IFtbcmVjdC5yaWdodCAtIDEsIGJvdHRvbV0sIFtyZWN0LnJpZ2h0IC0gMSwgdG9wXSwgW3JlZlJlY3QubGVmdCArIDEsIHRvcF0sIFtyZWZSZWN0LmxlZnQgKyAxLCBib3R0b21dXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgIHJlY3RQb2x5ID0gW1tyZWZSZWN0LnJpZ2h0IC0gMSwgYm90dG9tXSwgW3JlZlJlY3QucmlnaHQgLSAxLCB0b3BdLCBbcmVjdC5sZWZ0ICsgMSwgdG9wXSwgW3JlY3QubGVmdCArIDEsIGJvdHRvbV1dO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gZ2V0UG9seWdvbihfcmVmMykge1xuICAgICAgICBsZXQgW3gsIHldID0gX3JlZjM7XG4gICAgICAgIHN3aXRjaCAoc2lkZSkge1xuICAgICAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50T25lID0gW2lzRmxvYXRpbmdXaWRlciA/IHggKyBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyB4ICsgYnVmZmVyICogNCA6IHggLSBidWZmZXIgKiA0LCB5ICsgYnVmZmVyICsgMV07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW2lzRmxvYXRpbmdXaWRlciA/IHggLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyB4ICsgYnVmZmVyICogNCA6IHggLSBidWZmZXIgKiA0LCB5ICsgYnVmZmVyICsgMV07XG4gICAgICAgICAgICAgIGNvbnN0IGNvbW1vblBvaW50cyA9IFtbcmVjdC5sZWZ0LCBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IHJlY3QuYm90dG9tIC0gYnVmZmVyIDogaXNGbG9hdGluZ1dpZGVyID8gcmVjdC5ib3R0b20gLSBidWZmZXIgOiByZWN0LnRvcF0sIFtyZWN0LnJpZ2h0LCBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IGlzRmxvYXRpbmdXaWRlciA/IHJlY3QuYm90dG9tIC0gYnVmZmVyIDogcmVjdC50b3AgOiByZWN0LmJvdHRvbSAtIGJ1ZmZlcl1dO1xuICAgICAgICAgICAgICByZXR1cm4gW2N1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3bywgLi4uY29tbW9uUG9pbnRzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFtpc0Zsb2F0aW5nV2lkZXIgPyB4ICsgYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8geCArIGJ1ZmZlciAqIDQgOiB4IC0gYnVmZmVyICogNCwgeSAtIGJ1ZmZlcl07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW2lzRmxvYXRpbmdXaWRlciA/IHggLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyB4ICsgYnVmZmVyICogNCA6IHggLSBidWZmZXIgKiA0LCB5IC0gYnVmZmVyXTtcbiAgICAgICAgICAgICAgY29uc3QgY29tbW9uUG9pbnRzID0gW1tyZWN0LmxlZnQsIGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8gcmVjdC50b3AgKyBidWZmZXIgOiBpc0Zsb2F0aW5nV2lkZXIgPyByZWN0LnRvcCArIGJ1ZmZlciA6IHJlY3QuYm90dG9tXSwgW3JlY3QucmlnaHQsIGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8gaXNGbG9hdGluZ1dpZGVyID8gcmVjdC50b3AgKyBidWZmZXIgOiByZWN0LmJvdHRvbSA6IHJlY3QudG9wICsgYnVmZmVyXV07XG4gICAgICAgICAgICAgIHJldHVybiBbY3Vyc29yUG9pbnRPbmUsIGN1cnNvclBvaW50VHdvLCAuLi5jb21tb25Qb2ludHNdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFt4ICsgYnVmZmVyICsgMSwgaXNGbG9hdGluZ1RhbGxlciA/IHkgKyBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tQm90dG9tID8geSArIGJ1ZmZlciAqIDQgOiB5IC0gYnVmZmVyICogNF07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW3ggKyBidWZmZXIgKyAxLCBpc0Zsb2F0aW5nVGFsbGVyID8geSAtIGJ1ZmZlciAvIDIgOiBjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyB5ICsgYnVmZmVyICogNCA6IHkgLSBidWZmZXIgKiA0XTtcbiAgICAgICAgICAgICAgY29uc3QgY29tbW9uUG9pbnRzID0gW1tjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyByZWN0LnJpZ2h0IC0gYnVmZmVyIDogaXNGbG9hdGluZ1RhbGxlciA/IHJlY3QucmlnaHQgLSBidWZmZXIgOiByZWN0LmxlZnQsIHJlY3QudG9wXSwgW2N1cnNvckxlYXZlRnJvbUJvdHRvbSA/IGlzRmxvYXRpbmdUYWxsZXIgPyByZWN0LnJpZ2h0IC0gYnVmZmVyIDogcmVjdC5sZWZ0IDogcmVjdC5yaWdodCAtIGJ1ZmZlciwgcmVjdC5ib3R0b21dXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFsuLi5jb21tb25Qb2ludHMsIGN1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3b107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFt4IC0gYnVmZmVyLCBpc0Zsb2F0aW5nVGFsbGVyID8geSArIGJ1ZmZlciAvIDIgOiBjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyB5ICsgYnVmZmVyICogNCA6IHkgLSBidWZmZXIgKiA0XTtcbiAgICAgICAgICAgICAgY29uc3QgY3Vyc29yUG9pbnRUd28gPSBbeCAtIGJ1ZmZlciwgaXNGbG9hdGluZ1RhbGxlciA/IHkgLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tQm90dG9tID8geSArIGJ1ZmZlciAqIDQgOiB5IC0gYnVmZmVyICogNF07XG4gICAgICAgICAgICAgIGNvbnN0IGNvbW1vblBvaW50cyA9IFtbY3Vyc29yTGVhdmVGcm9tQm90dG9tID8gcmVjdC5sZWZ0ICsgYnVmZmVyIDogaXNGbG9hdGluZ1RhbGxlciA/IHJlY3QubGVmdCArIGJ1ZmZlciA6IHJlY3QucmlnaHQsIHJlY3QudG9wXSwgW2N1cnNvckxlYXZlRnJvbUJvdHRvbSA/IGlzRmxvYXRpbmdUYWxsZXIgPyByZWN0LmxlZnQgKyBidWZmZXIgOiByZWN0LnJpZ2h0IDogcmVjdC5sZWZ0ICsgYnVmZmVyLCByZWN0LmJvdHRvbV1dO1xuICAgICAgICAgICAgICByZXR1cm4gW2N1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3bywgLi4uY29tbW9uUG9pbnRzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzUG9pbnRJblBvbHlnb24oW2NsaWVudFgsIGNsaWVudFldLCByZWN0UG9seSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGhhc0xhbmRlZCAmJiAhaXNPdmVyUmVmZXJlbmNlUmVjdCkge1xuICAgICAgICByZXR1cm4gY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGlmICghaXNMZWF2ZSAmJiByZXF1aXJlSW50ZW50KSB7XG4gICAgICAgIGNvbnN0IGN1cnNvclNwZWVkID0gZ2V0Q3Vyc29yU3BlZWQoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSk7XG4gICAgICAgIGNvbnN0IGN1cnNvclNwZWVkVGhyZXNob2xkID0gMC4xO1xuICAgICAgICBpZiAoY3Vyc29yU3BlZWQgIT09IG51bGwgJiYgY3Vyc29yU3BlZWQgPCBjdXJzb3JTcGVlZFRocmVzaG9sZCkge1xuICAgICAgICAgIHJldHVybiBjbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlzUG9pbnRJblBvbHlnb24oW2NsaWVudFgsIGNsaWVudFldLCBnZXRQb2x5Z29uKFt4LCB5XSkpKSB7XG4gICAgICAgIGNsb3NlKCk7XG4gICAgICB9IGVsc2UgaWYgKCFoYXNMYW5kZWQgJiYgcmVxdWlyZUludGVudCkge1xuICAgICAgICB0aW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dChjbG9zZSwgNDApO1xuICAgICAgfVxuICAgIH07XG4gIH07XG4gIGZuLl9fb3B0aW9ucyA9IHtcbiAgICBibG9ja1BvaW50ZXJFdmVudHNcbiAgfTtcbiAgcmV0dXJuIGZuO1xufVxuXG5leHBvcnQgeyBDb21wb3NpdGUsIENvbXBvc2l0ZUl0ZW0sIEZsb2F0aW5nQXJyb3csIEZsb2F0aW5nRGVsYXlHcm91cCwgRmxvYXRpbmdGb2N1c01hbmFnZXIsIEZsb2F0aW5nTGlzdCwgRmxvYXRpbmdOb2RlLCBGbG9hdGluZ092ZXJsYXksIEZsb2F0aW5nUG9ydGFsLCBGbG9hdGluZ1RyZWUsIE5leHRGbG9hdGluZ0RlbGF5R3JvdXAsIGlubmVyLCBzYWZlUG9seWdvbiwgdXNlQ2xpY2ssIHVzZUNsaWVudFBvaW50LCB1c2VEZWxheUdyb3VwLCB1c2VEZWxheUdyb3VwQ29udGV4dCwgdXNlRGlzbWlzcywgdXNlRmxvYXRpbmcsIHVzZUZsb2F0aW5nTm9kZUlkLCB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCwgdXNlRmxvYXRpbmdQb3J0YWxOb2RlLCB1c2VGbG9hdGluZ1Jvb3RDb250ZXh0LCB1c2VGbG9hdGluZ1RyZWUsIHVzZUZvY3VzLCB1c2VIb3ZlciwgdXNlSWQsIHVzZUlubmVyT2Zmc2V0LCB1c2VJbnRlcmFjdGlvbnMsIHVzZUxpc3RJdGVtLCB1c2VMaXN0TmF2aWdhdGlvbiwgdXNlTWVyZ2VSZWZzLCB1c2VOZXh0RGVsYXlHcm91cCwgdXNlUm9sZSwgdXNlVHJhbnNpdGlvblN0YXR1cywgdXNlVHJhbnNp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Q0E7QUFDQSxrQ0FBa0MsWUFBWTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDOztBQUUxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQixxREFBUztBQUM5QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXNsQiJ9\n//# sourceURL=webpack-internal:///../../../node_modules/@floating-ui/react/dist/floating-ui.react.mjs\n\n}");
1910
1910
 
1911
1911
  },
1912
1912
  "../../../node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {