UNPKG

react-native-scroll-to-child

Version:
389 lines (378 loc) 62.8 kB
'use strict'; var React = require('react'); var reactNative = require('react-native'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var React__default = /*#__PURE__*/_interopDefault(React); var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/compute-scroll.tsx var computeScrollY = /* @__PURE__ */ __name((scrollViewLayout, viewLayout, scrollY, insets, align) => { const { height: scrollViewHeight, y: scrollViewY } = scrollViewLayout; const { height: childHeight, y: viewY } = viewLayout; const viewTopY = viewY - scrollViewY; const viewBottomY = viewTopY + childHeight; const computationData = { scrollViewHeight, scrollY, viewTopY, viewBottomY, insets }; const computeFn = alignmentsY[align]; if (!computeFn) throw new Error(`align=${align} not supported`); return computeFn(computationData); }, "computeScrollY"); var computeScrollYAuto = /* @__PURE__ */ __name((data) => { const { scrollY } = data; const scrollYTop = computeScrollYStart(data); if (scrollY > scrollYTop) { return scrollYTop; } const scrollYBottom = computeScrollYEnd(data); if (scrollY < scrollYBottom) { return scrollYBottom; } return scrollY; }, "computeScrollYAuto"); var computeScrollYStart = /* @__PURE__ */ __name(({ scrollY, viewTopY, insets }) => { return scrollY + viewTopY - (insets.top || 0); }, "computeScrollYStart"); var computeScrollYEnd = /* @__PURE__ */ __name(({ scrollViewHeight, scrollY, viewBottomY, insets }) => { return scrollY + viewBottomY - scrollViewHeight + (insets.bottom || 0); }, "computeScrollYEnd"); var computeScrollYCenter = /* @__PURE__ */ __name((data) => { return (computeScrollYStart(data) + computeScrollYEnd(data)) / 2; }, "computeScrollYCenter"); var alignmentsY = { auto: computeScrollYAuto, start: computeScrollYStart, end: computeScrollYEnd, center: computeScrollYCenter }; var computeScrollX = /* @__PURE__ */ __name((scrollViewLayout, viewLayout, scrollX, insets, align) => { const { width: scrollViewWidth, x: scrollViewX } = scrollViewLayout; const { width: childWidth, x: viewX } = viewLayout; const viewLeftX = viewX - scrollViewX; const viewRightX = viewLeftX + childWidth; const computationData = { scrollViewWidth, scrollX, viewLeftX, viewRightX, insets }; const computeFn = alignmentsX[align]; if (!computeFn) throw new Error(`align=${align} not supported for horizontal scrolling`); return computeFn(computationData); }, "computeScrollX"); var computeScrollXAuto = /* @__PURE__ */ __name((data) => { const { scrollX } = data; const scrollXLeft = computeScrollXStart(data); if (scrollX > scrollXLeft) { return scrollXLeft; } const scrollXRight = computeScrollXEnd(data); if (scrollX < scrollXRight) { return scrollXRight; } return scrollX; }, "computeScrollXAuto"); var computeScrollXStart = /* @__PURE__ */ __name(({ scrollX, viewLeftX, insets }) => { return scrollX + viewLeftX - (insets.left || 0); }, "computeScrollXStart"); var computeScrollXEnd = /* @__PURE__ */ __name(({ scrollViewWidth, scrollX, viewRightX, insets }) => { return scrollX + viewRightX - scrollViewWidth + (insets.right || 0); }, "computeScrollXEnd"); var computeScrollXCenter = /* @__PURE__ */ __name((data) => { return (computeScrollXStart(data) + computeScrollXEnd(data)) / 2; }, "computeScrollXCenter"); var alignmentsX = { auto: computeScrollXAuto, start: computeScrollXStart, end: computeScrollXEnd, center: computeScrollXCenter }; var measureElement = /* @__PURE__ */ __name((element) => { const node = reactNative.findNodeHandle(element); if (!node) return Promise.reject(new Error("Unable to find node handle")); return new Promise((resolve) => { reactNative.UIManager.measureInWindow(node, (x, y, width, height) => resolve({ x, y, width, height })); }); }, "measureElement"); var throttle = /* @__PURE__ */ __name((func, limit) => { let inThrottle = false; return function(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; }, "throttle"); // src/config.tsx var DefaultOptions = { align: "auto", animated: true, immediate: false, insets: { top: 0, bottom: 0, left: 0, right: 0 }, computeScrollY, computeScrollX, measureElement }; var normalizeOptions = /* @__PURE__ */ __name((options = {}, fallbackOptions = DefaultOptions) => ({ ...fallbackOptions, ...options, insets: { ...fallbackOptions.insets, ...options.insets } }), "normalizeOptions"); var DefaultHOCConfig = { // The method to extract the raw ScrollView node from the ref we got, if it's not directly the ScrollView itself getScrollViewNode: /* @__PURE__ */ __name((scrollView) => { const rnVersion = reactNative.Platform.constants.reactNativeVersion; const isPreRN062 = rnVersion ? rnVersion.major === 0 && rnVersion.minor < 62 : false; if (typeof scrollView.getNode === "function" && isPreRN062) { return scrollView.getNode(); } return scrollView; }, "getScrollViewNode"), // Default value for throttling, can be overridden by user with props scrollEventThrottle: 16, // ScrollIntoView options, can be offered by <ScrollIntoView /> comp or imperative usage options: DefaultOptions }; var normalizeHOCConfig = /* @__PURE__ */ __name((config = {}) => ({ ...DefaultHOCConfig, ...config, options: normalizeOptions(config.options, DefaultOptions) }), "normalizeHOCConfig"); // src/api.tsx var scrollIntoView = /* @__PURE__ */ __name(async (scrollView, view, scrollY, scrollX, options) => { if (!scrollView || !view) { throw new Error("ScrollView and target View must be provided"); } const { align, animated, computeScrollY: computeScrollY2, computeScrollX: computeScrollX2, measureElement: measureElement2, insets } = normalizeOptions(options); try { const [scrollViewLayout, viewLayout] = await Promise.all([measureElement2(scrollView), measureElement2(view)]); const targetScrollY = computeScrollY2(scrollViewLayout, viewLayout, scrollY, insets, align); const targetScrollX = computeScrollX2(scrollViewLayout, viewLayout, scrollX, insets, align); const scrollParams = { x: targetScrollX, y: targetScrollY, animated }; const scrollResponder = scrollView.getScrollResponder(); if (scrollResponder.scrollResponderScrollTo) { scrollResponder.scrollResponderScrollTo(scrollParams); } else { scrollView.scrollTo(scrollParams); } } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; throw new Error(`Failed to scroll into view: ${errorMessage}`); } }, "scrollIntoView"); var _ScrollIntoViewAPI = class _ScrollIntoViewAPI { constructor(dependencies) { this.dependencies = dependencies; this.validateDependencies(dependencies); } validateDependencies(deps) { const requiredDepKeys = [ "getScrollView", "getScrollY", "getScrollX", "getDefaultOptions" ]; for (const key of requiredDepKeys) { if (typeof deps[key] !== "function") { throw new Error(`Dependency "${key}" must be a function.`); } } } getNormalizedOptions = /* @__PURE__ */ __name((options = {}) => normalizeOptions(options, this.dependencies.getDefaultOptions()), "getNormalizedOptions"); scrollIntoView = /* @__PURE__ */ __name((view, options) => { const normalizedOptions = this.getNormalizedOptions(options); return normalizedOptions.immediate ? this.scrollIntoViewImmediate(view, normalizedOptions) : this.scrollIntoViewThrottled(view, normalizedOptions); }, "scrollIntoView"); performScroll = /* @__PURE__ */ __name((view, options) => { return scrollIntoView( this.dependencies.getScrollView(), view, this.dependencies.getScrollY(), this.dependencies.getScrollX(), options ); }, "performScroll"); scrollIntoViewThrottled = throttle(this.performScroll, 16); scrollIntoViewImmediate = this.performScroll; }; __name(_ScrollIntoViewAPI, "ScrollIntoViewAPI"); var ScrollIntoViewAPI = _ScrollIntoViewAPI; // src/context.tsx var Context = React__default.default.createContext(null); var context_default = Context; var APIConsumer = Context.Consumer; var ProvideAPI = /* @__PURE__ */ __name(({ dependencies, children }) => { const api = React__default.default.useMemo(() => new ScrollIntoViewAPI(dependencies), [dependencies]); return /* @__PURE__ */ React__default.default.createElement(Context.Provider, { value: api }, children); }, "ProvideAPI"); // src/container.tsx var showNotInContextWarning = throttle(() => { console.warn( "ScrollIntoView API is not provided in React context. Make sure you wrapped your ScrollView component with wrapScrollView(ScrollView)" ); }, 5e3); var ContainerBase = React.forwardRef((props, ref) => { const { enabled = true, onMount = true, onUpdate = true, scrollIntoViewKey, scrollIntoViewOptions, scrollIntoViewAPI, children, align, animated, immediate, insets, measureElement: measureElement2, computeScrollY: computeScrollY2, computeScrollX: computeScrollX2, ...rest } = props; const containerRef = React.useRef(null); const unmounted = React.useRef(false); const prevProps = React.useRef({ enabled, scrollIntoViewKey }); const ensureApiProvided = React.useCallback(() => { if (!scrollIntoViewAPI) { showNotInContextWarning(); return false; } return true; }, [scrollIntoViewAPI]); const getPropsOptions = React.useCallback(() => { const COMPONENT_DEFAULT_ANIMATED = true; const COMPONENT_DEFAULT_IMMEDIATE = false; const mergedOptions = { animated: COMPONENT_DEFAULT_ANIMATED, immediate: COMPONENT_DEFAULT_IMMEDIATE, ...scrollIntoViewOptions }; const optionProps = [ "animated", "immediate", "align", "insets", "measureElement", "computeScrollY", "computeScrollX" ]; const propsToMerge = { animated, immediate, align, insets, measureElement: measureElement2, computeScrollY: computeScrollY2, computeScrollX: computeScrollX2 }; for (const key of optionProps) { if (propsToMerge[key] !== void 0) { mergedOptions[key] = propsToMerge[key]; } } return mergedOptions; }, [scrollIntoViewOptions, animated, immediate, align, insets, measureElement2, computeScrollY2, computeScrollX2]); const scrollIntoView2 = React.useCallback( (providedOptions = {}) => { if (unmounted.current || !ensureApiProvided()) return; const currentContainerRef = containerRef.current; if (!currentContainerRef) return; const options = { ...getPropsOptions(), ...providedOptions }; if (scrollIntoViewAPI) { scrollIntoViewAPI.scrollIntoView(currentContainerRef, options); } }, [ensureApiProvided, getPropsOptions, scrollIntoViewAPI] ); React.useEffect(() => { let timerId; if (onMount && enabled) { timerId = setTimeout(() => { if (!unmounted.current) { scrollIntoView2(); } }, 0); } return () => { if (timerId) { clearTimeout(timerId); } }; }, [enabled, onMount, scrollIntoView2]); React.useEffect(() => { const prevEnabled = prevProps.current.enabled; const prevKey = prevProps.current.scrollIntoViewKey; const needsUpdateScroll = onUpdate && enabled && (!prevEnabled || scrollIntoViewKey !== prevKey); if (needsUpdateScroll) { scrollIntoView2(); } if (prevEnabled !== enabled || prevKey !== scrollIntoViewKey) { prevProps.current = { enabled, scrollIntoViewKey }; } }, [enabled, onUpdate, scrollIntoViewKey, scrollIntoView2]); React.useEffect(() => { return () => { unmounted.current = true; }; }, []); return /* @__PURE__ */ React__default.default.createElement(reactNative.View, { ...rest, ref: ref || containerRef, collapsable: false }, children); }); ContainerBase.displayName = "ContainerBase"; var Container = React.forwardRef((props, ref) => /* @__PURE__ */ React__default.default.createElement(APIConsumer, null, (apiFromContext) => apiFromContext && /* @__PURE__ */ React__default.default.createElement(ContainerBase, { ref, ...props, scrollIntoViewAPI: apiFromContext }))); var wrapScrollViewHOC = /* @__PURE__ */ __name((ScrollViewComp, config = {}) => { const { getScrollViewNode, scrollEventThrottle, options } = normalizeHOCConfig(config); const ScrollViewWrapper = React.forwardRef((props, ref) => { var _a, _b; const internalRef = React.useRef(null); const scrollY = React.useRef(((_a = props.contentOffset) == null ? void 0 : _a.y) || 0); const scrollX = React.useRef(((_b = props.contentOffset) == null ? void 0 : _b.x) || 0); const handleScroll = React.useCallback((event) => { scrollY.current = event.nativeEvent.contentOffset.y; scrollX.current = event.nativeEvent.contentOffset.x; }, []); const dependencies = { getScrollView: /* @__PURE__ */ __name(() => { if (!internalRef.current) throw new Error("ScrollView ref is not set"); return getScrollViewNode(internalRef.current); }, "getScrollView"), getScrollY: /* @__PURE__ */ __name(() => scrollY.current, "getScrollY"), getScrollX: /* @__PURE__ */ __name(() => scrollX.current, "getScrollX"), getDefaultOptions: /* @__PURE__ */ __name(() => normalizeOptions(props.scrollIntoViewOptions, options), "getDefaultOptions") }; React.useImperativeHandle(ref, () => internalRef.current, []); const scrollViewProps = { ...props, ref: internalRef, scrollEventThrottle: props.scrollEventThrottle || scrollEventThrottle, onScroll: reactNative.Animated.forkEvent(props.onScroll, handleScroll) }; return /* @__PURE__ */ React__default.default.createElement(ScrollViewComp, { ...scrollViewProps }, /* @__PURE__ */ React__default.default.createElement(ProvideAPI, { dependencies }, props.children)); }); ScrollViewWrapper.displayName = `ScrollIntoViewWrapper(${ScrollViewComp.displayName || ScrollViewComp.name || "Component"})`; return ScrollViewWrapper; }, "wrapScrollViewHOC"); function useScrollIntoViewContext() { const value = React.useContext(context_default); if (value === null) { throw new Error( "ScrollIntoView context is missing. Ensure your ScrollView is wrapped with wrapScrollView() and is an ancestor in the component tree." ); } return value; } __name(useScrollIntoViewContext, "useScrollIntoViewContext"); function useScrollIntoView() { const { scrollIntoView: scrollIntoView2 } = useScrollIntoViewContext(); return scrollIntoView2; } __name(useScrollIntoView, "useScrollIntoView"); // src/index.ts var ScrollIntoView = Container; var wrapScrollView = /* @__PURE__ */ __name((comp, config) => wrapScrollViewHOC(comp, config), "wrapScrollView"); exports.ScrollIntoView = ScrollIntoView; exports.useScrollIntoView = useScrollIntoView; exports.wrapScrollView = wrapScrollView; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wdXRlLXNjcm9sbC50c3giLCIuLi9zcmMvdXRpbHMudHN4IiwiLi4vc3JjL2NvbmZpZy50c3giLCIuLi9zcmMvYXBpLnRzeCIsIi4uL3NyYy9jb250ZXh0LnRzeCIsIi4uL3NyYy9jb250YWluZXIudHN4IiwiLi4vc3JjL2hvYy50c3giLCIuLi9zcmMvaG9va3MudHN4IiwiLi4vc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbImZpbmROb2RlSGFuZGxlIiwiVUlNYW5hZ2VyIiwiUGxhdGZvcm0iLCJjb21wdXRlU2Nyb2xsWSIsImNvbXB1dGVTY3JvbGxYIiwibWVhc3VyZUVsZW1lbnQiLCJSZWFjdCIsImZvcndhcmRSZWYiLCJ1c2VSZWYiLCJ1c2VDYWxsYmFjayIsInNjcm9sbEludG9WaWV3IiwidXNlRWZmZWN0IiwiVmlldyIsInVzZUltcGVyYXRpdmVIYW5kbGUiLCJBbmltYXRlZCIsInVzZUNvbnRleHQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFXTyxJQUFNLGlDQUFpQixNQUFBLENBQUEsQ0FDMUIsZ0JBQUEsRUFDQSxVQUFBLEVBQ0EsT0FBQSxFQUNBLFFBQ0EsS0FBQSxLQUNDO0FBQ0QsRUFBQSxNQUFNLEVBQUUsTUFBQSxFQUFRLGdCQUFBLEVBQWtCLENBQUEsRUFBRyxhQUFZLEdBQUksZ0JBQUE7QUFDckQsRUFBQSxNQUFNLEVBQUUsTUFBQSxFQUFRLFdBQUEsRUFBYSxDQUFBLEVBQUcsT0FBTSxHQUFJLFVBQUE7QUFFMUMsRUFBQSxNQUFNLFdBQVcsS0FBQSxHQUFRLFdBQUE7QUFDekIsRUFBQSxNQUFNLGNBQWMsUUFBQSxHQUFXLFdBQUE7QUFFL0IsRUFBQSxNQUFNLGtCQUFrQixFQUFFLGdCQUFBLEVBQWtCLE9BQUEsRUFBUyxRQUFBLEVBQVUsYUFBYSxNQUFBLEVBQU87QUFFbkYsRUFBQSxNQUFNLFNBQUEsR0FBWSxZQUFZLEtBQUssQ0FBQTtBQUNuQyxFQUFBLElBQUksQ0FBRSxTQUFBLEVBQW1CLE1BQU0sSUFB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MEJBQUEsQ0FBQTtBQVVGLFNBQVMsaUJBQUEsR0FBeUQ7QUFDckUsRUFBQSxNQUFNLEVBQUUsY0FBQSxFQUFBTCxlQUFBQSxFQUFlLEdBQUksd0JBQUEsRUFBeUI7QUFDcEQsRUFBQSxPQUFPQSxlQUFBQTtBQUNYO0FBSGdCLE1BQUEsQ0FBQSxpQkFBQSxFQUFBLG1CQUFBLENBQUE7OztBQ1JULElBQU0sY0FBQSxHQUFpQjtBQUV2QixJQUFNLGlDQUFpQixNQUFBLENBQUEsQ0FBQyxJQUFBLEVBQTJCLFdBQThCLGlCQUFBLENBQWtCLElBQUEsRUFBTSxNQUFNLENBQUEsRUFBeEYsZ0JBQUEiLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBbGlnbiwgSW5zZXRzIH0gZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IHR5cGUgeyBMYXlvdXRSZWN0YW5nbGUgfSBmcm9tICdyZWFjdC1uYXRpdmUnO1xuXG50eXBlIENvbXB1dGF0aW9uRGF0YSA9IHtcbiAgICBzY3JvbGxWaWV3SGVpZ2h0OiBudW1iZXI7XG4gICAgc2Nyb2xsWTogbnVtYmVyO1xuICAgIHZpZXdUb3BZOiBudW1iZXI7XG4gICAgdmlld0JvdHRvbVk6IG51bWJlcjtcbiAgICBpbnNldHM6IEluc2V0cztcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWSA9IChcbiAgICBzY3JvbGxWaWV3TGF5b3V0OiBMYXlvdXRSZWN0YW5nbGUsXG4gICAgdmlld0xheW91dDogTGF5b3V0UmVjdGFuZ2xlLFxuICAgIHNjcm9sbFk6IG51bWJlcixcbiAgICBpbnNldHM6IEluc2V0cyxcbiAgICBhbGlnbjogQWxpZ25cbikgPT4ge1xuICAgIGNvbnN0IHsgaGVpZ2h0OiBzY3JvbGxWaWV3SGVpZ2h0LCB5OiBzY3JvbGxWaWV3WSB9ID0gc2Nyb2xsVmlld0xheW91dDtcbiAgICBjb25zdCB7IGhlaWdodDogY2hpbGRIZWlnaHQsIHk6IHZpZXdZIH0gPSB2aWV3TGF5b3V0O1xuXG4gICAgY29uc3Qgdmlld1RvcFkgPSB2aWV3WSAtIHNjcm9sbFZpZXdZO1xuICAgIGNvbnN0IHZpZXdCb3R0b21ZID0gdmlld1RvcFkgKyBjaGlsZEhlaWdodDtcblxuICAgIGNvbnN0IGNvbXB1dGF0aW9uRGF0YSA9IHsgc2Nyb2xsVmlld0hlaWdodCwgc2Nyb2xsWSwgdmlld1RvcFksIHZpZXdCb3R0b21ZLCBpbnNldHMgfTtcblxuICAgIGNvbnN0IGNvbXB1dGVGbiA9IGFsaWdubWVudHNZW2FsaWduXTtcbiAgICBpZiAoIShjb21wdXRlRm4gYXMgYW55KSkgdGhyb3cgbmV3IEVycm9yKGBhbGlnbj0ke2FsaWdufSBub3Qgc3VwcG9ydGVkYCk7XG5cbiAgICByZXR1cm4gY29tcHV0ZUZuKGNvbXB1dGF0aW9uRGF0YSk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFlBdXRvID0gKGRhdGE6IENvbXB1dGF0aW9uRGF0YSk6IG51bWJlciA9PiB7XG4gICAgY29uc3QgeyBzY3JvbGxZIH0gPSBkYXRhO1xuICAgIGNvbnN0IHNjcm9sbFlUb3AgPSBjb21wdXRlU2Nyb2xsWVN0YXJ0KGRhdGEpO1xuICAgIGlmIChzY3JvbGxZID4gc2Nyb2xsWVRvcCkge1xuICAgICAgICByZXR1cm4gc2Nyb2xsWVRvcDtcbiAgICB9XG4gICAgY29uc3Qgc2Nyb2xsWUJvdHRvbSA9IGNvbXB1dGVTY3JvbGxZRW5kKGRhdGEpO1xuICAgIGlmIChzY3JvbGxZIDwgc2Nyb2xsWUJvdHRvbSkge1xuICAgICAgICByZXR1cm4gc2Nyb2xsWUJvdHRvbTtcbiAgICB9XG4gICAgcmV0dXJuIHNjcm9sbFk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFlTdGFydCA9ICh7IHNjcm9sbFksIHZpZXdUb3BZLCBpbnNldHMgfTogQ29tcHV0YXRpb25EYXRhKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gc2Nyb2xsWSArIHZpZXdUb3BZIC0gKGluc2V0cy50b3AgfHwgMCk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFlFbmQgPSAoeyBzY3JvbGxWaWV3SGVpZ2h0LCBzY3JvbGxZLCB2aWV3Qm90dG9tWSwgaW5zZXRzIH06IENvbXB1dGF0aW9uRGF0YSk6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIHNjcm9sbFkgKyB2aWV3Qm90dG9tWSAtIHNjcm9sbFZpZXdIZWlnaHQgKyAoaW5zZXRzLmJvdHRvbSB8fCAwKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWUNlbnRlciA9IChkYXRhOiBDb21wdXRhdGlvbkRhdGEpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiAoY29tcHV0ZVNjcm9sbFlTdGFydChkYXRhKSArIGNvbXB1dGVTY3JvbGxZRW5kKGRhdGEpKSAvIDI7XG59O1xuXG5jb25zdCBhbGlnbm1lbnRzWTogUmVjb3JkPEFsaWduLCAoZGF0YTogQ29tcHV0YXRpb25EYXRhKSA9PiBudW1iZXI+ID0ge1xuICAgIGF1dG86IGNvbXB1dGVTY3JvbGxZQXV0byxcbiAgICBzdGFydDogY29tcHV0ZVNjcm9sbFlTdGFydCxcbiAgICBlbmQ6IGNvbXB1dGVTY3JvbGxZRW5kLFxuICAgIGNlbnRlcjogY29tcHV0ZVNjcm9sbFlDZW50ZXJcbn07XG5cbnR5cGUgQ29tcHV0YXRpb25EYXRhWCA9IHtcbiAgICBzY3JvbGxWaWV3V2lkdGg6IG51bWJlcjtcbiAgICBzY3JvbGxYOiBudW1iZXI7XG4gICAgdmlld0xlZnRYOiBudW1iZXI7XG4gICAgdmlld1JpZ2h0WDogbnVtYmVyO1xuICAgIGluc2V0czogSW5zZXRzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxYID0gKFxuICAgIHNjcm9sbFZpZXdMYXlvdXQ6IExheW91dFJlY3RhbmdsZSxcbiAgICB2aWV3TGF5b3V0OiBMYXlvdXRSZWN0YW5nbGUsXG4gICAgc2Nyb2xsWDogbnVtYmVyLFxuICAgIGluc2V0czogSW5zZXRzLFxuICAgIGFsaWduOiBBbGlnblxuKTogbnVtYmVyID0+IHtcbiAgICBjb25zdCB7IHdpZHRoOiBzY3JvbGxWaWV3V2lkdGgsIHg6IHNjcm9sbFZpZXdYIH0gPSBzY3JvbGxWaWV3TGF5b3V0O1xuICAgIGNvbnN0IHsgd2lkdGg6IGNoaWxkV2lkdGgsIHg6IHZpZXdYIH0gPSB2aWV3TGF5b3V0O1xuXG4gICAgY29uc3Qgdmlld0xlZnRYID0gdmlld1ggLSBzY3JvbGxWaWV3WDtcbiAgICBjb25zdCB2aWV3UmlnaHRYID0gdmlld0xlZnRYICsgY2hpbGRXaWR0aDtcblxuICAgIGNvbnN0IGNvbXB1dGF0aW9uRGF0YTogQ29tcHV0YXRpb25EYXRhWCA9IHsgc2Nyb2xsVmlld1dpZHRoLCBzY3JvbGxYLCB2aWV3TGVmdFgsIHZpZXdSaWdodFgsIGluc2V0cyB9O1xuXG4gICAgY29uc3QgY29tcHV0ZUZuID0gYWxpZ25tZW50c1hbYWxpZ25dO1xuICAgIGlmICghKGNvbXB1dGVGbiBhcyBhbnkpKSB0aHJvdyBuZXcgRXJyb3IoYGFsaWduPSR7YWxpZ259IG5vdCBzdXBwb3J0ZWQgZm9yIGhvcml6b250YWwgc2Nyb2xsaW5nYCk7XG5cbiAgICByZXR1cm4gY29tcHV0ZUZuKGNvbXB1dGF0aW9uRGF0YSk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFhBdXRvID0gKGRhdGE6IENvbXB1dGF0aW9uRGF0YVgpOiBudW1iZXIgPT4ge1xuICAgIGNvbnN0IHsgc2Nyb2xsWCB9ID0gZGF0YTtcbiAgICBjb25zdCBzY3JvbGxYTGVmdCA9IGNvbXB1dGVTY3JvbGxYU3RhcnQoZGF0YSk7XG4gICAgaWYgKHNjcm9sbFggPiBzY3JvbGxYTGVmdCkge1xuICAgICAgICByZXR1cm4gc2Nyb2xsWExlZnQ7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbFhSaWdodCA9IGNvbXB1dGVTY3JvbGxYRW5kKGRhdGEpO1xuICAgIGlmIChzY3JvbGxYIDwgc2Nyb2xsWFJpZ2h0KSB7XG4gICAgICAgIHJldHVybiBzY3JvbGxYUmlnaHQ7XG4gICAgfVxuICAgIHJldHVybiBzY3JvbGxYO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxYU3RhcnQgPSAoeyBzY3JvbGxYLCB2aWV3TGVmdFgsIGluc2V0cyB9OiBDb21wdXRhdGlvbkRhdGFYKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gc2Nyb2xsWCArIHZpZXdMZWZ0WCAtIChpbnNldHMubGVmdCB8fCAwKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWEVuZCA9ICh7IHNjcm9sbFZpZXdXaWR0aCwgc2Nyb2xsWCwgdmlld1JpZ2h0WCwgaW5zZXRzIH06IENvbXB1dGF0aW9uRGF0YVgpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiBzY3JvbGxYICsgdmlld1JpZ2h0WCAtIHNjcm9sbFZpZXdXaWR0aCArIChpbnNldHMucmlnaHQgfHwgMCk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFhDZW50ZXIgPSAoZGF0YTogQ29tcHV0YXRpb25EYXRhWCk6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIChjb21wdXRlU2Nyb2xsWFN0YXJ0KGRhdGEpICsgY29tcHV0ZVNjcm9sbFhFbmQoZGF0YSkpIC8gMjtcbn07XG5cbmNvbnN0IGFsaWdubWVudHNYOiBSZWNvcmQ8QWxpZ24sIChkYXRhOiBDb21wdXRhdGlvbkRhdGFYKSA9PiBudW1iZXI+ID0ge1xuICAgIGF1dG86IGNvbXB1dGVTY3JvbGxYQXV0byxcbiAgICBzdGFydDogY29tcHV0ZVNjcm9sbFhTdGFydCxcbiAgICBlbmQ6IGNvbXB1dGVTY3JvbGxYRW5kLFxuICAgIGNlbnRlcjogY29tcHV0ZVNjcm9sbFhDZW50ZXJcbn07XG4iLCJpbXBvcnQgeyBmaW5kTm9kZUhhbmRsZSwgVUlNYW5hZ2VyIH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxuaW1wb3J0IHR5cGUgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHR5cGUgeyBMYXlvdXRSZWN0YW5nbGUgfSBmcm9tICdyZWFjdC1uYXRpdmUnO1xuXG50eXBlIEZpbmROb2RlSGFuZGxlQXJnID0gbnVsbCB8IG51bWJlciB8IFJlYWN0LkNvbXBvbmVudDxhbnksIGFueT4gfCBSZWFjdC5Db21wb25lbnRDbGFzczxhbnk+O1xuXG5leHBvcnQgY29uc3QgbWVhc3VyZUVsZW1lbnQgPSAoZWxlbWVudDogRmluZE5vZGVIYW5kbGVBcmcpOiBQcm9taXNlPExheW91dFJlY3RhbmdsZT4gPT4ge1xuICAgIGNvbnN0IG5vZGUgPSBmaW5kTm9kZUhhbmRsZShlbGVtZW50KTtcbiAgICBpZiAoIW5vZGUpIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgaGFuZGxlJykpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPExheW91dFJlY3RhbmdsZT4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgVUlNYW5hZ2VyLm1lYXN1cmVJbldpbmRvdyhub2RlLCAoeCwgeSwgd2lkdGgsIGhlaWdodCkgPT4gcmVzb2x2ZSh7IHgsIHksIHdpZHRoLCBoZWlnaHQgfSkpO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHRocm90dGxlID0gPFQgZXh0ZW5kcyAoLi4uYXJnczogYW55W10pID0+IHZvaWQ+KGZ1bmM6IFQsIGxpbWl0OiBudW1iZXIpOiBUID0+IHtcbiAgICBsZXQgaW5UaHJvdHRsZSA9IGZhbHNlO1xuICAgIHJldHVybiBmdW5jdGlvbiAodGhpczogdW5rbm93biwgLi4uYXJnczogUGFyYW1ldGVyczxUPikge1xuICAgICAgICBpZiAoIWluVGhyb3R0bGUpIHtcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICBpblRocm90dGxlID0gdHJ1ZTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gKGluVGhyb3R0bGUgPSBmYWxzZSksIGxpbWl0KTtcbiAgICAgICAgfVxuICAgIH0gYXMgVDtcbn07XG4iLCJpbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbmltcG9ydCB7IGNvbXB1dGVTY3JvbGxYLCBjb21wdXRlU2Nyb2xsWSB9IGZyb20gJy4vY29tcHV0ZS1zY3JvbGwnO1xuaW1wb3J0IHsgbWVhc3VyZUVsZW1lbnQgfSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHR5cGUgeyBTY3JvbGxWaWV3IH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxuZXhwb3J0IHR5cGUgSW5zZXRzID0ge1xuICAgIHRvcD86IG51bWJlcjtcbiAgICBib3R0b20/OiBudW1iZXI7XG4gICAgbGVmdD86IG51bWJlcjtcbiAgICByaWdodD86IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIEFsaWduID0gJ2F1dG8nIHwgJ3N0YXJ0JyB8ICdlbmQnIHwgJ2NlbnRlcic7XG5cbmV4cG9ydCB0eXBlIEZ1bGxPcHRpb25zID0ge1xuICAgIGFsaWduOiBBbGlnbjtcbiAgICBhbmltYXRlZDogYm9vbGVhbjtcbiAgICBpbW1lZGlhdGU6IGJvb2xlYW47XG4gICAgaW5zZXRzOiBJbnNldHM7XG4gICAgY29tcHV0ZVNjcm9sbFk6IHR5cGVvZiBjb21wdXRlU2Nyb2xsWTtcbiAgICBjb21wdXRlU2Nyb2xsWDogdHlwZW9mIGNvbXB1dGVTY3JvbGxYO1xuICAgIG1lYXN1cmVFbGVtZW50OiB0eXBlb2YgbWVhc3VyZUVsZW1lbnQ7XG59O1xuXG5leHBvcnQgdHlwZSBQYXJ0aWFsT3B0aW9ucyA9IFBhcnRpYWw8RnVsbE9wdGlvbnM+O1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdE9wdGlvbnM6IEZ1bGxPcHRpb25zID0ge1xuICAgIGFsaWduOiAnYXV0bycsXG4gICAgYW5pbWF0ZWQ6IHRydWUsXG4gICAgaW1tZWRpYXRlOiBmYWxzZSxcbiAgICBpbnNldHM6IHtcbiAgICAgICAgdG9wOiAwLFxuICAgICAgICBib3R0b206IDAsXG4gICAgICAgIGxlZnQ6IDAsXG4gICAgICAgIHJpZ2h0OiAwXG4gICAgfSxcbiAgICBjb21wdXRlU2Nyb2xsWSxcbiAgICBjb21wdXRlU2Nyb2xsWCxcbiAgICBtZWFzdXJlRWxlbWVudFxufTtcblxuZXhwb3J0IHR5cGUgT3B0aW9uS2V5ID0ga2V5b2YgRnVsbE9wdGlvbnM7XG5leHBvcnQgY29uc3QgT3B0aW9uS2V5czogT3B0aW9uS2V5W10gPSBPYmplY3Qua2V5cyhEZWZhdWx0T3B0aW9ucykgYXMgT3B0aW9uS2V5W107XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemVPcHRpb25zID0gKG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zID0ge30sIGZhbGxiYWNrT3B0aW9uczogRnVsbE9wdGlvbnMgPSBEZWZhdWx0T3B0aW9ucykgPT4gKHtcbiAgICAuLi5mYWxsYmFja09wdGlvbnMsXG4gICAgLi4ub3B0aW9ucyxcbiAgICBpbnNldHM6IHtcbiAgICAgICAgLi4uZmFsbGJhY2tPcHRpb25zLmluc2V0cyxcbiAgICAgICAgLi4ub3B0aW9ucy5pbnNldHNcbiAgICB9XG59KTtcblxuZXhwb3J0IHR5cGUgRnVsbEhPQ0NvbmZpZyA9IHtcbiAgICBnZXRTY3JvbGxWaWV3Tm9kZTogKHNjcm9sbFZpZXc6IFNjcm9sbFZpZXcpID0+IFNjcm9sbFZpZXc7XG4gICAgc2Nyb2xsRXZlbnRUaHJvdHRsZTogMTY7XG4gICAgb3B0aW9uczogUGFydGlhbE9wdGlvbnM7XG59O1xuZXhwb3J0IHR5cGUgUGFydGlhbEhPQ0NvbmZpZyA9IFBhcnRpYWw8RnVsbEhPQ0NvbmZpZz47XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0SE9DQ29uZmlnOiBGdWxsSE9DQ29uZmlnID0ge1xuICAgIC8vIFRoZSBtZXRob2QgdG8gZXh0cmFjdCB0aGUgcmF3IFNjcm9sbFZpZXcgbm9kZSBmcm9tIHRoZSByZWYgd2UgZ290LCBpZiBpdCdzIG5vdCBkaXJlY3RseSB0aGUgU2Nyb2xsVmlldyBpdHNlbGZcbiAgICBnZXRTY3JvbGxWaWV3Tm9kZTogKHNjcm9sbFZpZXc6IFNjcm9sbFZpZXcpID0+IHtcbiAgICAgICAgLy8gc2Nyb2xsVmlldy5nZXROb2RlKCkgd2FzIHVzZWQgZm9yIEFuaW1hdGVkLlNjcm9sbFZpZXcgY29tcG9uZW50cyBidXQgaXMgZGVwcmVjYXRlZCBzaW5jZSBSTiAwLjYyLlxuICAgICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC1uYXRpdmUvY29tbWl0LzY2ZTcyYmI0ZTAwYWFmYmNiOWY0NTBlZDVkYjI2MWQ5OGY5OWY4MmFcbiAgICAgICAgLy8gV2Ugb25seSBhdHRlbXB0IHRvIGNhbGwgaXQgaWYgaXQgZXhpc3RzIGFuZCB3ZSdyZSBvbiBhbiBvbGRlciBSTiB2ZXJzaW9uLlxuICAgICAgICBjb25zdCByblZlcnNpb24gPSBQbGF0Zm9ybS5jb25zdGFudHMucmVhY3ROYXRpdmVWZXJzaW9uO1xuICAgICAgICBjb25zdCBpc1ByZVJOMDYyID0gKHJuVmVyc2lvbiBhcyBhbnkpID8gcm5WZXJzaW9uLm1ham9yID09PSAwICYmIHJuVmVyc2lvbi5taW5vciA8IDYyIDogZmFsc2U7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgZ2V0Tm9kZSBleGlzdHMgb24gdGhlIHNjcm9sbFZpZXcgb2JqZWN0IChjb21tb24gZm9yIEFuaW1hdGVkLlNjcm9sbFZpZXcpXG4gICAgICAgIC8vIGFuZCBpZiB3ZSBhcmUgb24gYSBSZWFjdCBOYXRpdmUgdmVyc2lvbiB3aGVyZSBpdCB3YXMgcmVjb21tZW5kZWQuXG4gICAgICAgIGlmICh0eXBlb2YgKHNjcm9sbFZpZXcgYXMgYW55KS5nZXROb2RlID09PSAnZnVuY3Rpb24nICYmIGlzUHJlUk4wNjIpIHtcbiAgICAgICAgICAgIHJldHVybiAoc2Nyb2xsVmlldyBhcyBhbnkpLmdldE5vZGUoKTsgLy8gQ2FsbCBnZXROb2RlIGlmIGFwcGxpY2FibGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2Nyb2xsVmlldzsgLy8gT3RoZXJ3aXNlLCByZXR1cm4gdGhlIHNjcm9sbFZpZXcgZGlyZWN0bHlcbiAgICB9LFxuICAgIC8vIERlZmF1bHQgdmFsdWUgZm9yIHRocm90dGxpbmcsIGNhbiBiZSBvdmVycmlkZGVuIGJ5IHVzZXIgd2l0aCBwcm9wc1xuICAgIHNjcm9sbEV2ZW50VGhyb3R0bGU6IDE2LFxuICAgIC8vIFNjcm9sbEludG9WaWV3IG9wdGlvbnMsIGNhbiBiZSBvZmZlcmVkIGJ5IDxTY3JvbGxJbnRvVmlldyAvPiBjb21wIG9yIGltcGVyYXRpdmUgdXNhZ2VcbiAgICBvcHRpb25zOiBEZWZhdWx0T3B0aW9uc1xufTtcblxuZXhwb3J0IGNvbnN0IG5vcm1hbGl6ZUhPQ0NvbmZpZyA9IChjb25maWc6IFBhcnRpYWxIT0NDb25maWcgPSB7fSkgPT4gKHtcbiAgICAuLi5EZWZhdWx0SE9DQ29uZmlnLFxuICAgIC4uLmNvbmZpZyxcbiAgICBvcHRpb25zOiBub3JtYWxpemVPcHRpb25zKGNvbmZpZy5vcHRpb25zLCBEZWZhdWx0T3B0aW9ucylcbn0pO1xuIiwiaW1wb3J0IHsgbm9ybWFsaXplT3B0aW9ucyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IHRocm90dGxlIH0gZnJvbSAnLi91dGlscyc7XG5cbmltcG9ydCB0eXBlIHsgRnVsbE9wdGlvbnMsIFBhcnRpYWxPcHRpb25zIH0gZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IHR5cGUgeyBTY3JvbGxWaWV3LCBWaWV3IH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxudHlwZSBTY3JvbGxQYXJhbXMgPSB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyBhbmltYXRlZDogYm9vbGVhbiB9O1xuXG5leHBvcnQgY29uc3Qgc2Nyb2xsSW50b1ZpZXcgPSBhc3luYyAoXG4gICAgc2Nyb2xsVmlldzogU2Nyb2xsVmlldyxcbiAgICB2aWV3OiBWaWV3LFxuICAgIHNjcm9sbFk6IG51bWJlcixcbiAgICBzY3JvbGxYOiBudW1iZXIsXG4gICAgb3B0aW9uczogUGFydGlhbE9wdGlvbnNcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmICghKHNjcm9sbFZpZXcgYXMgYW55KSB8fCAhKHZpZXcgYXMgYW55KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Njcm9sbFZpZXcgYW5kIHRhcmdldCBWaWV3IG11c3QgYmUgcHJvdmlkZWQnKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGFsaWduLCBhbmltYXRlZCwgY29tcHV0ZVNjcm9sbFksIGNvbXB1dGVTY3JvbGxYLCBtZWFzdXJlRWxlbWVudCwgaW5zZXRzIH0gPSBub3JtYWxpemVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgW3Njcm9sbFZpZXdMYXlvdXQsIHZpZXdMYXlvdXRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW21lYXN1cmVFbGVtZW50KHNjcm9sbFZpZXcpLCBtZWFzdXJlRWxlbWVudCh2aWV3KV0pO1xuXG4gICAgICAgIGNvbnN0IHRhcmdldFNjcm9sbFkgPSBjb21wdXRlU2Nyb2xsWShzY3JvbGxWaWV3TGF5b3V0LCB2aWV3TGF5b3V0LCBzY3JvbGxZLCBpbnNldHMsIGFsaWduKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0U2Nyb2xsWCA9IGNvbXB1dGVTY3JvbGxYKHNjcm9sbFZpZXdMYXlvdXQsIHZpZXdMYXlvdXQsIHNjcm9sbFgsIGluc2V0cywgYWxpZ24pO1xuICAgICAgICBjb25zdCBzY3JvbGxQYXJhbXM6IFNjcm9sbFBhcmFtcyA9IHsgeDogdGFyZ2V0U2Nyb2xsWCwgeTogdGFyZ2V0U2Nyb2xsWSwgYW5pbWF0ZWQgfTtcblxuICAgICAgICBjb25zdCBzY3JvbGxSZXNwb25kZXIgPSBzY3JvbGxWaWV3LmdldFNjcm9sbFJlc3BvbmRlcigpO1xuICAgICAgICBpZiAoKHNjcm9sbFJlc3BvbmRlciBhcyBhbnkpLnNjcm9sbFJlc3BvbmRlclNjcm9sbFRvKSB7XG4gICAgICAgICAgICBzY3JvbGxSZXNwb25kZXIuc2Nyb2xsUmVzcG9uZGVyU2Nyb2xsVG8oc2Nyb2xsUGFyYW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNjcm9sbFZpZXcuc2Nyb2xsVG8oc2Nyb2xsUGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBzY3JvbGwgaW50byB2aWV3OiAke2Vycm9yTWVzc2FnZX1gKTtcbiAgICB9XG59O1xuXG50eXBlIEdldFNjcm9sbFZpZXcgPSAoKSA9PiBTY3JvbGxWaWV3O1xudHlwZSBHZXRTY3JvbGxZID0gKCkgPT4gbnVtYmVyO1xudHlwZSBHZXRTY3JvbGxYID0gKCkgPT4gbnVtYmVyO1xudHlwZSBHZXREZWZhdWx0T3B0aW9ucyA9ICgpID0+IEZ1bGxPcHRpb25zO1xuXG5leHBvcnQgdHlwZSBTY3JvbGxJbnRvVmlld0RlcGVuZGVuY2llcyA9IHtcbiAgICByZWFkb25seSBnZXRTY3JvbGxWaWV3OiBHZXRTY3JvbGxWaWV3O1xuICAgIHJlYWRvbmx5IGdldFNjcm9sbFk6IEdldFNjcm9sbFk7XG4gICAgcmVhZG9ubHkgZ2V0U2Nyb2xsWDogR2V0U2Nyb2xsWDtcbiAgICByZWFkb25seSBnZXREZWZhdWx0T3B0aW9uczogR2V0RGVmYXVsdE9wdGlvbnM7XG59O1xuXG5leHBvcnQgY2xhc3MgU2Nyb2xsSW50b1ZpZXdBUEkge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZGVwZW5kZW5jaWVzOiBTY3JvbGxJbnRvVmlld0RlcGVuZGVuY2llcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlRGVwZW5kZW5jaWVzKGRlcGVuZGVuY2llcyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB2YWxpZGF0ZURlcGVuZGVuY2llcyhkZXBzOiBTY3JvbGxJbnRvVmlld0RlcGVuZGVuY2llcyk6IHZvaWQge1xuICAgICAgICBjb25zdCByZXF1aXJlZERlcEtleXM6IChrZXlvZiBTY3JvbGxJbnRvVmlld0RlcGVuZGVuY2llcylbXSA9IFtcbiAgICAgICAgICAgICdnZXRTY3JvbGxWaWV3JyxcbiAgICAgICAgICAgICdnZXRTY3JvbGxZJyxcbiAgICAgICAgICAgICdnZXRTY3JvbGxYJyxcbiAgICAgICAgICAgICdnZXREZWZhdWx0T3B0aW9ucydcbiAgICAgICAgXTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgcmVxdWlyZWREZXBLZXlzKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGRlcHNba2V5XSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRGVwZW5kZW5jeSBcIiR7a2V5fVwiIG11c3QgYmUgYSBmdW5jdGlvbi5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Tm9ybWFsaXplZE9wdGlvbnMgPSAob3B0aW9uczogUGFydGlhbE9wdGlvbnMgPSB7fSk6IEZ1bGxPcHRpb25zID0+XG4gICAgICAgIG5vcm1hbGl6ZU9wdGlvbnMob3B0aW9ucywgdGhpcy5kZXBlbmRlbmNpZXMuZ2V0RGVmYXVsdE9wdGlvbnMoKSk7XG5cbiAgICBwdWJsaWMgc2Nyb2xsSW50b1ZpZXcgPSAodmlldzogVmlldywgb3B0aW9ucz86IFBhcnRpYWxPcHRpb25zKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRPcHRpb25zID0gdGhpcy5nZXROb3JtYWxpemVkT3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRPcHRpb25zLmltbWVkaWF0ZVxuICAgICAgICAgICAgPyB0aGlzLnNjcm9sbEludG9WaWV3SW1tZWRpYXRlKHZpZXcsIG5vcm1hbGl6ZWRPcHRpb25zKVxuICAgICAgICAgICAgOiB0aGlzLnNjcm9sbEludG9WaWV3VGhyb3R0bGVkKHZpZXcsIG5vcm1hbGl6ZWRPcHRpb25zKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBwZXJmb3JtU2Nyb2xsID0gKHZpZXc6IFZpZXcsIG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIHJldHVybiBzY3JvbGxJbnRvVmlldyhcbiAgICAgICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLmdldFNjcm9sbFZpZXcoKSxcbiAgICAgICAgICAgIHZpZXcsXG4gICAgICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5nZXRTY3JvbGxZKCksXG4gICAgICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5nZXRTY3JvbGxYKCksXG4gICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgc2Nyb2xsSW50b1ZpZXdUaHJvdHRsZWQgPSB0aHJvdHRsZSh0aGlzLnBlcmZvcm1TY3JvbGwsIDE2KTtcblxuICAgIHByaXZhdGUgc2Nyb2xsSW50b1ZpZXdJbW1lZGlhdGUgPSB0aGlzLnBlcmZvcm1TY3JvbGw7XG59XG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBTY3JvbGxJbnRvVmlld0FQSSB9IGZyb20gJy4vYXBpJztcblxuaW1wb3J0IHR5cGUgeyBTY3JvbGxJbnRvVmlld0RlcGVuZGVuY2llcyB9IGZyb20gJy4vYXBpJztcblxuY29uc3QgQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8U2Nyb2xsSW50b1ZpZXdBUEkgfCBudWxsPihudWxsKTtcblxuZXhwb3J0IGRlZmF1bHQgQ29udGV4dDtcblxuZXhwb3J0IGNvbnN0IEFQSUNvbnN1bWVyID0gQ29udGV4dC5Db25zdW1lcjtcblxuaW50ZXJmYWNlIFByb3ZpZGVBUElQcm9wcyB7XG4gICAgZGVwZW5kZW5jaWVzOiBTY3JvbGxJbnRvVmlld0RlcGVuZGVuY2llcztcbiAgICBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlO1xufVxuXG5leHBvcnQgY29uc3QgUHJvdmlkZUFQSTogUmVhY3QuRkM8UHJvdmlkZUFQSVByb3BzPiA9ICh7IGRlcGVuZGVuY2llcywgY2hpbGRyZW4gfSkgPT4ge1xuICAgIGNvbnN0