UNPKG

react-native-scroll-to-child

Version:
381 lines (373 loc) 62.2 kB
import React, { forwardRef, useRef, useCallback, useEffect, useContext, useImperativeHandle } from 'react'; import { View, Animated, findNodeHandle, UIManager, Platform } from 'react-native'; 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 = findNodeHandle(element); if (!node) return Promise.reject(new Error("Unable to find node handle")); return new Promise((resolve) => { 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 = 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.createContext(null); var context_default = Context; var APIConsumer = Context.Consumer; var ProvideAPI = /* @__PURE__ */ __name(({ dependencies, children }) => { const api = React.useMemo(() => new ScrollIntoViewAPI(dependencies), [dependencies]); return /* @__PURE__ */ React.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 = 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 = useRef(null); const unmounted = useRef(false); const prevProps = useRef({ enabled, scrollIntoViewKey }); const ensureApiProvided = useCallback(() => { if (!scrollIntoViewAPI) { showNotInContextWarning(); return false; } return true; }, [scrollIntoViewAPI]); const getPropsOptions = 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 = 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] ); useEffect(() => { let timerId; if (onMount && enabled) { timerId = setTimeout(() => { if (!unmounted.current) { scrollIntoView2(); } }, 0); } return () => { if (timerId) { clearTimeout(timerId); } }; }, [enabled, onMount, scrollIntoView2]); 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]); useEffect(() => { return () => { unmounted.current = true; }; }, []); return /* @__PURE__ */ React.createElement(View, { ...rest, ref: ref || containerRef, collapsable: false }, children); }); ContainerBase.displayName = "ContainerBase"; var Container = forwardRef((props, ref) => /* @__PURE__ */ React.createElement(APIConsumer, null, (apiFromContext) => apiFromContext && /* @__PURE__ */ React.createElement(ContainerBase, { ref, ...props, scrollIntoViewAPI: apiFromContext }))); var wrapScrollViewHOC = /* @__PURE__ */ __name((ScrollViewComp, config = {}) => { const { getScrollViewNode, scrollEventThrottle, options } = normalizeHOCConfig(config); const ScrollViewWrapper = forwardRef((props, ref) => { var _a, _b; const internalRef = useRef(null); const scrollY = useRef(((_a = props.contentOffset) == null ? void 0 : _a.y) || 0); const scrollX = useRef(((_b = props.contentOffset) == null ? void 0 : _b.x) || 0); const handleScroll = 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") }; useImperativeHandle(ref, () => internalRef.current, []); const scrollViewProps = { ...props, ref: internalRef, scrollEventThrottle: props.scrollEventThrottle || scrollEventThrottle, onScroll: Animated.forkEvent(props.onScroll, handleScroll) }; return /* @__PURE__ */ React.createElement(ScrollViewComp, { ...scrollViewProps }, /* @__PURE__ */ React.createElement(ProvideAPI, { dependencies }, props.children)); }); ScrollViewWrapper.displayName = `ScrollIntoViewWrapper(${ScrollViewComp.displayName || ScrollViewComp.name || "Component"})`; return ScrollViewWrapper; }, "wrapScrollViewHOC"); function useScrollIntoViewContext() { const value = 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"); export { ScrollIntoView, useScrollIntoView, wrapScrollView }; //# sourceMappingURL=index.js.map //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wdXRlLXNjcm9sbC50c3giLCIuLi9zcmMvdXRpbHMudHN4IiwiLi4vc3JjL2NvbmZpZy50c3giLCIuLi9zcmMvYXBpLnRzeCIsIi4uL3NyYy9jb250ZXh0LnRzeCIsIi4uL3NyYy9jb250YWluZXIudHN4IiwiLi4vc3JjL2hvYy50c3giLCIuLi9zcmMvaG9va3MudHN4IiwiLi4vc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbImNvbXB1dGVTY3JvbGxZIiwiY29tcHV0ZVNjcm9sbFgiLCJtZWFzdXJlRWxlbWVudCIsInNjcm9sbEludG9WaWV3IiwiUmVhY3QiLCJmb3J3YXJkUmVmIiwidXNlUmVmIiwidXNlQ2FsbGJhY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFXTyxJQUFNLGlDQUFpQixNQUFBLENBQUEsQ0FDMUIsZ0JBQUEsRUFDQSxVQUFBLEVBQ0EsT0FBQSxFQUNBLFFBQ0EsS0FBQSxLQUNDO0FBQ0QsRUFBQSxNQUFNLEVBQUUsTUFBQSxFQUFRLGdCQUFBLEVBQWtCLENBQUEsRUFBRyxhQUFZLEdBQUksZ0JBQUE7QUFDckQsRUFBQSxNQUFNLEVBQUUsTUFBQSxFQUFRLFdBQUEsRUFBYSxDQUFBLEVBQUcsT0FBTSxHQUFJLFVBQUE7QUFFMUMsRUFBQSxNQUFNLFdBQVcsS0FBQSxHQUFRLFdBQUE7QUFDekIsRUFBQSxNQUFNLGNBQWMsUUFBQSxHQUFXLFdBQUE7QUFFL0IsRUFBQSxNQUFNLGtCQUFrQixFQUFFLGdCQUFBLEVBQWtCLE9BQUEsRUFBUyxRQUFBLEVBQVUsYUFBYSxNQUFBLEVBQU87QUFFbkYsRUFBQSxNQUFNLFNBQUEsR0FBWSxZQUFZLEtBQUssQ0FBQTtBQUNuQyxFQUFBLElBQUksQ0FBRSxTQUFBLEVBQW1CLE1BQU0sSUFBSSxLQUFBLENBQU0sQ0FBQSxNQUFBLEVBQVMsS0FBSyxDQUFBLGNBQUEsQ0FBZ0IsQ0FBQTtBQUV2RSxFQUFBLE9BQU8sVUFBVSxlQUFlLENBQUE7QUFDcEMsQ0FBQSxFQW5COEIsZ0JBQUEsQ0FB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QUEsQ0FBQTs7O0FDUlQsSUFBTSxjQUFBLEdBQWlCO0FBRXZCLElBQU0saUNBQWlCLE1BQUEsQ0FBQSxDQUFDLElBQUEsRUFBMkIsV0FBOEIsaUJBQUEsQ0FBa0IsSUFBQSxFQUFNLE1BQU0sQ0FBQSxFQUF4RixnQkFBQSIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQWxpZ24sIEluc2V0cyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB0eXBlIHsgTGF5b3V0UmVjdGFuZ2xlIH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxudHlwZSBDb21wdXRhdGlvbkRhdGEgPSB7XG4gICAgc2Nyb2xsVmlld0hlaWdodDogbnVtYmVyO1xuICAgIHNjcm9sbFk6IG51bWJlcjtcbiAgICB2aWV3VG9wWTogbnVtYmVyO1xuICAgIHZpZXdCb3R0b21ZOiBudW1iZXI7XG4gICAgaW5zZXRzOiBJbnNldHM7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFkgPSAoXG4gICAgc2Nyb2xsVmlld0xheW91dDogTGF5b3V0UmVjdGFuZ2xlLFxuICAgIHZpZXdMYXlvdXQ6IExheW91dFJlY3RhbmdsZSxcbiAgICBzY3JvbGxZOiBudW1iZXIsXG4gICAgaW5zZXRzOiBJbnNldHMsXG4gICAgYWxpZ246IEFsaWduXG4pID0+IHtcbiAgICBjb25zdCB7IGhlaWdodDogc2Nyb2xsVmlld0hlaWdodCwgeTogc2Nyb2xsVmlld1kgfSA9IHNjcm9sbFZpZXdMYXlvdXQ7XG4gICAgY29uc3QgeyBoZWlnaHQ6IGNoaWxkSGVpZ2h0LCB5OiB2aWV3WSB9ID0gdmlld0xheW91dDtcblxuICAgIGNvbnN0IHZpZXdUb3BZID0gdmlld1kgLSBzY3JvbGxWaWV3WTtcbiAgICBjb25zdCB2aWV3Qm90dG9tWSA9IHZpZXdUb3BZICsgY2hpbGRIZWlnaHQ7XG5cbiAgICBjb25zdCBjb21wdXRhdGlvbkRhdGEgPSB7IHNjcm9sbFZpZXdIZWlnaHQsIHNjcm9sbFksIHZpZXdUb3BZLCB2aWV3Qm90dG9tWSwgaW5zZXRzIH07XG5cbiAgICBjb25zdCBjb21wdXRlRm4gPSBhbGlnbm1lbnRzWVthbGlnbl07XG4gICAgaWYgKCEoY29tcHV0ZUZuIGFzIGFueSkpIHRocm93IG5ldyBFcnJvcihgYWxpZ249JHthbGlnbn0gbm90IHN1cHBvcnRlZGApO1xuXG4gICAgcmV0dXJuIGNvbXB1dGVGbihjb21wdXRhdGlvbkRhdGEpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxZQXV0byA9IChkYXRhOiBDb21wdXRhdGlvbkRhdGEpOiBudW1iZXIgPT4ge1xuICAgIGNvbnN0IHsgc2Nyb2xsWSB9ID0gZGF0YTtcbiAgICBjb25zdCBzY3JvbGxZVG9wID0gY29tcHV0ZVNjcm9sbFlTdGFydChkYXRhKTtcbiAgICBpZiAoc2Nyb2xsWSA+IHNjcm9sbFlUb3ApIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbFlUb3A7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbFlCb3R0b20gPSBjb21wdXRlU2Nyb2xsWUVuZChkYXRhKTtcbiAgICBpZiAoc2Nyb2xsWSA8IHNjcm9sbFlCb3R0b20pIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbFlCb3R0b207XG4gICAgfVxuICAgIHJldHVybiBzY3JvbGxZO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxZU3RhcnQgPSAoeyBzY3JvbGxZLCB2aWV3VG9wWSwgaW5zZXRzIH06IENvbXB1dGF0aW9uRGF0YSk6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIHNjcm9sbFkgKyB2aWV3VG9wWSAtIChpbnNldHMudG9wIHx8IDApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxZRW5kID0gKHsgc2Nyb2xsVmlld0hlaWdodCwgc2Nyb2xsWSwgdmlld0JvdHRvbVksIGluc2V0cyB9OiBDb21wdXRhdGlvbkRhdGEpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiBzY3JvbGxZICsgdmlld0JvdHRvbVkgLSBzY3JvbGxWaWV3SGVpZ2h0ICsgKGluc2V0cy5ib3R0b20gfHwgMCk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFlDZW50ZXIgPSAoZGF0YTogQ29tcHV0YXRpb25EYXRhKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gKGNvbXB1dGVTY3JvbGxZU3RhcnQoZGF0YSkgKyBjb21wdXRlU2Nyb2xsWUVuZChkYXRhKSkgLyAyO1xufTtcblxuY29uc3QgYWxpZ25tZW50c1k6IFJlY29yZDxBbGlnbiwgKGRhdGE6IENvbXB1dGF0aW9uRGF0YSkgPT4gbnVtYmVyPiA9IHtcbiAgICBhdXRvOiBjb21wdXRlU2Nyb2xsWUF1dG8sXG4gICAgc3RhcnQ6IGNvbXB1dGVTY3JvbGxZU3RhcnQsXG4gICAgZW5kOiBjb21wdXRlU2Nyb2xsWUVuZCxcbiAgICBjZW50ZXI6IGNvbXB1dGVTY3JvbGxZQ2VudGVyXG59O1xuXG50eXBlIENvbXB1dGF0aW9uRGF0YVggPSB7XG4gICAgc2Nyb2xsVmlld1dpZHRoOiBudW1iZXI7XG4gICAgc2Nyb2xsWDogbnVtYmVyO1xuICAgIHZpZXdMZWZ0WDogbnVtYmVyO1xuICAgIHZpZXdSaWdodFg6IG51bWJlcjtcbiAgICBpbnNldHM6IEluc2V0cztcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWCA9IChcbiAgICBzY3JvbGxWaWV3TGF5b3V0OiBMYXlvdXRSZWN0YW5nbGUsXG4gICAgdmlld0xheW91dDogTGF5b3V0UmVjdGFuZ2xlLFxuICAgIHNjcm9sbFg6IG51bWJlcixcbiAgICBpbnNldHM6IEluc2V0cyxcbiAgICBhbGlnbjogQWxpZ25cbik6IG51bWJlciA9PiB7XG4gICAgY29uc3QgeyB3aWR0aDogc2Nyb2xsVmlld1dpZHRoLCB4OiBzY3JvbGxWaWV3WCB9ID0gc2Nyb2xsVmlld0xheW91dDtcbiAgICBjb25zdCB7IHdpZHRoOiBjaGlsZFdpZHRoLCB4OiB2aWV3WCB9ID0gdmlld0xheW91dDtcblxuICAgIGNvbnN0IHZpZXdMZWZ0WCA9IHZpZXdYIC0gc2Nyb2xsVmlld1g7XG4gICAgY29uc3Qgdmlld1JpZ2h0WCA9IHZpZXdMZWZ0WCArIGNoaWxkV2lkdGg7XG5cbiAgICBjb25zdCBjb21wdXRhdGlvbkRhdGE6IENvbXB1dGF0aW9uRGF0YVggPSB7IHNjcm9sbFZpZXdXaWR0aCwgc2Nyb2xsWCwgdmlld0xlZnRYLCB2aWV3UmlnaHRYLCBpbnNldHMgfTtcblxuICAgIGNvbnN0IGNvbXB1dGVGbiA9IGFsaWdubWVudHNYW2FsaWduXTtcbiAgICBpZiAoIShjb21wdXRlRm4gYXMgYW55KSkgdGhyb3cgbmV3IEVycm9yKGBhbGlnbj0ke2FsaWdufSBub3Qgc3VwcG9ydGVkIGZvciBob3Jpem9udGFsIHNjcm9sbGluZ2ApO1xuXG4gICAgcmV0dXJuIGNvbXB1dGVGbihjb21wdXRhdGlvbkRhdGEpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxYQXV0byA9IChkYXRhOiBDb21wdXRhdGlvbkRhdGFYKTogbnVtYmVyID0+IHtcbiAgICBjb25zdCB7IHNjcm9sbFggfSA9IGRhdGE7XG4gICAgY29uc3Qgc2Nyb2xsWExlZnQgPSBjb21wdXRlU2Nyb2xsWFN0YXJ0KGRhdGEpO1xuICAgIGlmIChzY3JvbGxYID4gc2Nyb2xsWExlZnQpIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbFhMZWZ0O1xuICAgIH1cbiAgICBjb25zdCBzY3JvbGxYUmlnaHQgPSBjb21wdXRlU2Nyb2xsWEVuZChkYXRhKTtcbiAgICBpZiAoc2Nyb2xsWCA8IHNjcm9sbFhSaWdodCkge1xuICAgICAgICByZXR1cm4gc2Nyb2xsWFJpZ2h0O1xuICAgIH1cbiAgICByZXR1cm4gc2Nyb2xsWDtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWFN0YXJ0ID0gKHsgc2Nyb2xsWCwgdmlld0xlZnRYLCBpbnNldHMgfTogQ29tcHV0YXRpb25EYXRhWCk6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIHNjcm9sbFggKyB2aWV3TGVmdFggLSAoaW5zZXRzLmxlZnQgfHwgMCk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFhFbmQgPSAoeyBzY3JvbGxWaWV3V2lkdGgsIHNjcm9sbFgsIHZpZXdSaWdodFgsIGluc2V0cyB9OiBDb21wdXRhdGlvbkRhdGFYKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gc2Nyb2xsWCArIHZpZXdSaWdodFggLSBzY3JvbGxWaWV3V2lkdGggKyAoaW5zZXRzLnJpZ2h0IHx8IDApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxYQ2VudGVyID0gKGRhdGE6IENvbXB1dGF0aW9uRGF0YVgpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiAoY29tcHV0ZVNjcm9sbFhTdGFydChkYXRhKSArIGNvbXB1dGVTY3JvbGxYRW5kKGRhdGEpKSAvIDI7XG59O1xuXG5jb25zdCBhbGlnbm1lbnRzWDogUmVjb3JkPEFsaWduLCAoZGF0YTogQ29tcHV0YXRpb25EYXRhWCkgPT4gbnVtYmVyPiA9IHtcbiAgICBhdXRvOiBjb21wdXRlU2Nyb2xsWEF1dG8sXG4gICAgc3RhcnQ6IGNvbXB1dGVTY3JvbGxYU3RhcnQsXG4gICAgZW5kOiBjb21wdXRlU2Nyb2xsWEVuZCxcbiAgICBjZW50ZXI6IGNvbXB1dGVTY3JvbGxYQ2VudGVyXG59O1xuIiwiaW1wb3J0IHsgZmluZE5vZGVIYW5kbGUsIFVJTWFuYWdlciB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbmltcG9ydCB0eXBlIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB0eXBlIHsgTGF5b3V0UmVjdGFuZ2xlIH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxudHlwZSBGaW5kTm9kZUhhbmRsZUFyZyA9IG51bGwgfCBudW1iZXIgfCBSZWFjdC5Db21wb25lbnQ8YW55LCBhbnk+IHwgUmVhY3QuQ29tcG9uZW50Q2xhc3M8YW55PjtcblxuZXhwb3J0IGNvbnN0IG1lYXN1cmVFbGVtZW50ID0gKGVsZW1lbnQ6IEZpbmROb2RlSGFuZGxlQXJnKTogUHJvbWlzZTxMYXlvdXRSZWN0YW5nbGU+ID0+IHtcbiAgICBjb25zdCBub2RlID0gZmluZE5vZGVIYW5kbGUoZWxlbWVudCk7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIGhhbmRsZScpKTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxMYXlvdXRSZWN0YW5nbGU+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgIFVJTWFuYWdlci5tZWFzdXJlSW5XaW5kb3cobm9kZSwgKHgsIHksIHdpZHRoLCBoZWlnaHQpID0+IHJlc29sdmUoeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0pKTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCB0aHJvdHRsZSA9IDxUIGV4dGVuZHMgKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkPihmdW5jOiBULCBsaW1pdDogbnVtYmVyKTogVCA9PiB7XG4gICAgbGV0IGluVGhyb3R0bGUgPSBmYWxzZTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRoaXM6IHVua25vd24sIC4uLmFyZ3M6IFBhcmFtZXRlcnM8VD4pIHtcbiAgICAgICAgaWYgKCFpblRocm90dGxlKSB7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgaW5UaHJvdHRsZSA9IHRydWU7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IChpblRocm90dGxlID0gZmFsc2UpLCBsaW1pdCk7XG4gICAgICAgIH1cbiAgICB9IGFzIFQ7XG59O1xuIiwiaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdyZWFjdC1uYXRpdmUnO1xuXG5pbXBvcnQgeyBjb21wdXRlU2Nyb2xsWCwgY29tcHV0ZVNjcm9sbFkgfSBmcm9tICcuL2NvbXB1dGUtc2Nyb2xsJztcbmltcG9ydCB7IG1lYXN1cmVFbGVtZW50IH0gZnJvbSAnLi91dGlscyc7XG5cbmltcG9ydCB0eXBlIHsgU2Nyb2xsVmlldyB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbmV4cG9ydCB0eXBlIEluc2V0cyA9IHtcbiAgICB0b3A/OiBudW1iZXI7XG4gICAgYm90dG9tPzogbnVtYmVyO1xuICAgIGxlZnQ/OiBudW1iZXI7XG4gICAgcmlnaHQ/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBBbGlnbiA9ICdhdXRvJyB8ICdzdGFydCcgfCAnZW5kJyB8ICdjZW50ZXInO1xuXG5leHBvcnQgdHlwZSBGdWxsT3B0aW9ucyA9IHtcbiAgICBhbGlnbjogQWxpZ247XG4gICAgYW5pbWF0ZWQ6IGJvb2xlYW47XG4gICAgaW1tZWRpYXRlOiBib29sZWFuO1xuICAgIGluc2V0czogSW5zZXRzO1xuICAgIGNvbXB1dGVTY3JvbGxZOiB0eXBlb2YgY29tcHV0ZVNjcm9sbFk7XG4gICAgY29tcHV0ZVNjcm9sbFg6IHR5cGVvZiBjb21wdXRlU2Nyb2xsWDtcbiAgICBtZWFzdXJlRWxlbWVudDogdHlwZW9mIG1lYXN1cmVFbGVtZW50O1xufTtcblxuZXhwb3J0IHR5cGUgUGFydGlhbE9wdGlvbnMgPSBQYXJ0aWFsPEZ1bGxPcHRpb25zPjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRPcHRpb25zOiBGdWxsT3B0aW9ucyA9IHtcbiAgICBhbGlnbjogJ2F1dG8nLFxuICAgIGFuaW1hdGVkOiB0cnVlLFxuICAgIGltbWVkaWF0ZTogZmFsc2UsXG4gICAgaW5zZXRzOiB7XG4gICAgICAgIHRvcDogMCxcbiAgICAgICAgYm90dG9tOiAwLFxuICAgICAgICBsZWZ0OiAwLFxuICAgICAgICByaWdodDogMFxuICAgIH0sXG4gICAgY29tcHV0ZVNjcm9sbFksXG4gICAgY29tcHV0ZVNjcm9sbFgsXG4gICAgbWVhc3VyZUVsZW1lbnRcbn07XG5cbmV4cG9ydCB0eXBlIE9wdGlvbktleSA9IGtleW9mIEZ1bGxPcHRpb25zO1xuZXhwb3J0IGNvbnN0IE9wdGlvbktleXM6IE9wdGlvbktleVtdID0gT2JqZWN0LmtleXMoRGVmYXVsdE9wdGlvbnMpIGFzIE9wdGlvbktleVtdO1xuXG5leHBvcnQgY29uc3Qgbm9ybWFsaXplT3B0aW9ucyA9IChvcHRpb25zOiBQYXJ0aWFsT3B0aW9ucyA9IHt9LCBmYWxsYmFja09wdGlvbnM6IEZ1bGxPcHRpb25zID0gRGVmYXVsdE9wdGlvbnMpID0+ICh7XG4gICAgLi4uZmFsbGJhY2tPcHRpb25zLFxuICAgIC4uLm9wdGlvbnMsXG4gICAgaW5zZXRzOiB7XG4gICAgICAgIC4uLmZhbGxiYWNrT3B0aW9ucy5pbnNldHMsXG4gICAgICAgIC4uLm9wdGlvbnMuaW5zZXRzXG4gICAgfVxufSk7XG5cbmV4cG9ydCB0eXBlIEZ1bGxIT0NDb25maWcgPSB7XG4gICAgZ2V0U2Nyb2xsVmlld05vZGU6IChzY3JvbGxWaWV3OiBTY3JvbGxWaWV3KSA9PiBTY3JvbGxWaWV3O1xuICAgIHNjcm9sbEV2ZW50VGhyb3R0bGU6IDE2O1xuICAgIG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zO1xufTtcbmV4cG9ydCB0eXBlIFBhcnRpYWxIT0NDb25maWcgPSBQYXJ0aWFsPEZ1bGxIT0NDb25maWc+O1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdEhPQ0NvbmZpZzogRnVsbEhPQ0NvbmZpZyA9IHtcbiAgICAvLyBUaGUgbWV0aG9kIHRvIGV4dHJhY3QgdGhlIHJhdyBTY3JvbGxWaWV3IG5vZGUgZnJvbSB0aGUgcmVmIHdlIGdvdCwgaWYgaXQncyBub3QgZGlyZWN0bHkgdGhlIFNjcm9sbFZpZXcgaXRzZWxmXG4gICAgZ2V0U2Nyb2xsVmlld05vZGU6IChzY3JvbGxWaWV3OiBTY3JvbGxWaWV3KSA9PiB7XG4gICAgICAgIC8vIHNjcm9sbFZpZXcuZ2V0Tm9kZSgpIHdhcyB1c2VkIGZvciBBbmltYXRlZC5TY3JvbGxWaWV3IGNvbXBvbmVudHMgYnV0IGlzIGRlcHJlY2F0ZWQgc2luY2UgUk4gMC42Mi5cbiAgICAgICAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QtbmF0aXZlL2NvbW1pdC82NmU3MmJiNGUwMGFhZmJjYjlmNDUwZWQ1ZGIyNjFkOThmOTlmODJhXG4gICAgICAgIC8vIFdlIG9ubHkgYXR0ZW1wdCB0byBjYWxsIGl0IGlmIGl0IGV4aXN0cyBhbmQgd2UncmUgb24gYW4gb2xkZXIgUk4gdmVyc2lvbi5cbiAgICAgICAgY29uc3Qgcm5WZXJzaW9uID0gUGxhdGZvcm0uY29uc3RhbnRzLnJlYWN0TmF0aXZlVmVyc2lvbjtcbiAgICAgICAgY29uc3QgaXNQcmVSTjA2MiA9IChyblZlcnNpb24gYXMgYW55KSA/IHJuVmVyc2lvbi5tYWpvciA9PT0gMCAmJiByblZlcnNpb24ubWlub3IgPCA2MiA6IGZhbHNlO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGdldE5vZGUgZXhpc3RzIG9uIHRoZSBzY3JvbGxWaWV3IG9iamVjdCAoY29tbW9uIGZvciBBbmltYXRlZC5TY3JvbGxWaWV3KVxuICAgICAgICAvLyBhbmQgaWYgd2UgYXJlIG9uIGEgUmVhY3QgTmF0aXZlIHZlcnNpb24gd2hlcmUgaXQgd2FzIHJlY29tbWVuZGVkLlxuICAgICAgICBpZiAodHlwZW9mIChzY3JvbGxWaWV3IGFzIGFueSkuZ2V0Tm9kZSA9PT0gJ2Z1bmN0aW9uJyAmJiBpc1ByZVJOMDYyKSB7XG4gICAgICAgICAgICByZXR1cm4gKHNjcm9sbFZpZXcgYXMgYW55KS5nZXROb2RlKCk7IC8vIENhbGwgZ2V0Tm9kZSBpZiBhcHBsaWNhYmxlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjcm9sbFZpZXc7IC8vIE90aGVyd2lzZSwgcmV0dXJuIHRoZSBzY3JvbGxWaWV3IGRpcmVjdGx5XG4gICAgfSxcbiAgICAvLyBEZWZhdWx0IHZhbHVlIGZvciB0aHJvdHRsaW5nLCBjYW4gYmUgb3ZlcnJpZGRlbiBieSB1c2VyIHdpdGggcHJvcHNcbiAgICBzY3JvbGxFdmVudFRocm90dGxlOiAxNixcbiAgICAvLyBTY3JvbGxJbnRvVmlldyBvcHRpb25zLCBjYW4gYmUgb2ZmZXJlZCBieSA8U2Nyb2xsSW50b1ZpZXcgLz4gY29tcCBvciBpbXBlcmF0aXZlIHVzYWdlXG4gICAgb3B0aW9uczogRGVmYXVsdE9wdGlvbnNcbn07XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemVIT0NDb25maWcgPSAoY29uZmlnOiBQYXJ0aWFsSE9DQ29uZmlnID0ge30pID0+ICh7XG4gICAgLi4uRGVmYXVsdEhPQ0NvbmZpZyxcbiAgICAuLi5jb25maWcsXG4gICAgb3B0aW9uczogbm9ybWFsaXplT3B0aW9ucyhjb25maWcub3B0aW9ucywgRGVmYXVsdE9wdGlvbnMpXG59KTtcbiIsImltcG9ydCB7IG5vcm1hbGl6ZU9wdGlvbnMgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyB0aHJvdHRsZSB9IGZyb20gJy4vdXRpbHMnO1xuXG5pbXBvcnQgdHlwZSB7IEZ1bGxPcHRpb25zLCBQYXJ0aWFsT3B0aW9ucyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB0eXBlIHsgU2Nyb2xsVmlldywgVmlldyB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbnR5cGUgU2Nyb2xsUGFyYW1zID0geyB4OiBudW1iZXI7IHk6IG51bWJlcjsgYW5pbWF0ZWQ6IGJvb2xlYW4gfTtcblxuZXhwb3J0IGNvbnN0IHNjcm9sbEludG9WaWV3ID0gYXN5bmMgKFxuICAgIHNjcm9sbFZpZXc6IFNjcm9sbFZpZXcsXG4gICAgdmlldzogVmlldyxcbiAgICBzY3JvbGxZOiBudW1iZXIsXG4gICAgc2Nyb2xsWDogbnVtYmVyLFxuICAgIG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAoIShzY3JvbGxWaWV3IGFzIGFueSkgfHwgISh2aWV3IGFzIGFueSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY3JvbGxWaWV3IGFuZCB0YXJnZXQgVmlldyBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhbGlnbiwgYW5pbWF0ZWQsIGNvbXB1dGVTY3JvbGxZLCBjb21wdXRlU2Nyb2xsWCwgbWVhc3VyZUVsZW1lbnQsIGluc2V0cyB9ID0gbm9ybWFsaXplT3B0aW9ucyhvcHRpb25zKTtcblxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IFtzY3JvbGxWaWV3TGF5b3V0LCB2aWV3TGF5b3V0XSA9IGF3YWl0IFByb21pc2UuYWxsKFttZWFzdXJlRWxlbWVudChzY3JvbGxWaWV3KSwgbWVhc3VyZUVsZW1lbnQodmlldyldKTtcblxuICAgICAgICBjb25zdCB0YXJnZXRTY3JvbGxZID0gY29tcHV0ZVNjcm9sbFkoc2Nyb2xsVmlld0xheW91dCwgdmlld0xheW91dCwgc2Nyb2xsWSwgaW5zZXRzLCBhbGlnbik7XG4gICAgICAgIGNvbnN0IHRhcmdldFNjcm9sbFggPSBjb21wdXRlU2Nyb2xsWChzY3JvbGxWaWV3TGF5b3V0LCB2aWV3TGF5b3V0LCBzY3JvbGxYLCBpbnNldHMsIGFsaWduKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsUGFyYW1zOiBTY3JvbGxQYXJhbXMgPSB7IHg6IHRhcmdldFNjcm9sbFgsIHk6IHRhcmdldFNjcm9sbFksIGFuaW1hdGVkIH07XG5cbiAgICAgICAgY29uc3Qgc2Nyb2xsUmVzcG9uZGVyID0gc2Nyb2xsVmlldy5nZXRTY3JvbGxSZXNwb25kZXIoKTtcbiAgICAgICAgaWYgKChzY3JvbGxSZXNwb25kZXIgYXMgYW55KS5zY3JvbGxSZXNwb25kZXJTY3JvbGxUbykge1xuICAgICAgICAgICAgc2Nyb2xsUmVzcG9uZGVyLnNjcm9sbFJlc3BvbmRlclNjcm9sbFRvKHNjcm9sbFBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzY3JvbGxWaWV3LnNjcm9sbFRvKHNjcm9sbFBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmtub3duIGVycm9yJztcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gc2Nyb2xsIGludG8gdmlldzogJHtlcnJvck1lc3NhZ2V9YCk7XG4gICAgfVxufTtcblxudHlwZSBHZXRTY3JvbGxWaWV3ID0gKCkgPT4gU2Nyb2xsVmlldztcbnR5cGUgR2V0U2Nyb2xsWSA9ICgpID0+IG51bWJlcjtcbnR5cGUgR2V0U2Nyb2xsWCA9ICgpID0+IG51bWJlcjtcbnR5cGUgR2V0RGVmYXVsdE9wdGlvbnMgPSAoKSA9PiBGdWxsT3B0aW9ucztcblxuZXhwb3J0IHR5cGUgU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMgPSB7XG4gICAgcmVhZG9ubHkgZ2V0U2Nyb2xsVmlldzogR2V0U2Nyb2xsVmlldztcbiAgICByZWFkb25seSBnZXRTY3JvbGxZOiBHZXRTY3JvbGxZO1xuICAgIHJlYWRvbmx5IGdldFNjcm9sbFg6IEdldFNjcm9sbFg7XG4gICAgcmVhZG9ubHkgZ2V0RGVmYXVsdE9wdGlvbnM6IEdldERlZmF1bHRPcHRpb25zO1xufTtcblxuZXhwb3J0IGNsYXNzIFNjcm9sbEludG9WaWV3QVBJIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlcGVuZGVuY2llczogU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZURlcGVuZGVuY2llcyhkZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdmFsaWRhdGVEZXBlbmRlbmNpZXMoZGVwczogU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcmVxdWlyZWREZXBLZXlzOiAoa2V5b2YgU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMpW10gPSBbXG4gICAgICAgICAgICAnZ2V0U2Nyb2xsVmlldycsXG4gICAgICAgICAgICAnZ2V0U2Nyb2xsWScsXG4gICAgICAgICAgICAnZ2V0U2Nyb2xsWCcsXG4gICAgICAgICAgICAnZ2V0RGVmYXVsdE9wdGlvbnMnXG4gICAgICAgIF07XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHJlcXVpcmVkRGVwS2V5cykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBkZXBzW2tleV0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERlcGVuZGVuY3kgXCIke2tleX1cIiBtdXN0IGJlIGEgZnVuY3Rpb24uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE5vcm1hbGl6ZWRPcHRpb25zID0gKG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zID0ge30pOiBGdWxsT3B0aW9ucyA9PlxuICAgICAgICBub3JtYWxpemVPcHRpb25zKG9wdGlvbnMsIHRoaXMuZGVwZW5kZW5jaWVzLmdldERlZmF1bHRPcHRpb25zKCkpO1xuXG4gICAgcHVibGljIHNjcm9sbEludG9WaWV3ID0gKHZpZXc6IFZpZXcsIG9wdGlvbnM/OiBQYXJ0aWFsT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBjb25zdCBub3JtYWxpemVkT3B0aW9ucyA9IHRoaXMuZ2V0Tm9ybWFsaXplZE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBub3JtYWxpemVkT3B0aW9ucy5pbW1lZGlhdGVcbiAgICAgICAgICAgID8gdGhpcy5zY3JvbGxJbnRvVmlld0ltbWVkaWF0ZSh2aWV3LCBub3JtYWxpemVkT3B0aW9ucylcbiAgICAgICAgICAgIDogdGhpcy5zY3JvbGxJbnRvVmlld1Rocm90dGxlZCh2aWV3LCBub3JtYWxpemVkT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgcGVyZm9ybVNjcm9sbCA9ICh2aWV3OiBWaWV3LCBvcHRpb25zOiBQYXJ0aWFsT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICByZXR1cm4gc2Nyb2xsSW50b1ZpZXcoXG4gICAgICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5nZXRTY3JvbGxWaWV3KCksXG4gICAgICAgICAgICB2aWV3LFxuICAgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZ2V0U2Nyb2xsWSgpLFxuICAgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZ2V0U2Nyb2xsWCgpLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICApO1xuICAgIH07XG5cbiAgICBwcml2YXRlIHNjcm9sbEludG9WaWV3VGhyb3R0bGVkID0gdGhyb3R0bGUodGhpcy5wZXJmb3JtU2Nyb2xsLCAxNik7XG5cbiAgICBwcml2YXRlIHNjcm9sbEludG9WaWV3SW1tZWRpYXRlID0gdGhpcy5wZXJmb3JtU2Nyb2xsO1xufVxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgU2Nyb2xsSW50b1ZpZXdBUEkgfSBmcm9tICcuL2FwaSc7XG5cbmltcG9ydCB0eXBlIHsgU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMgfSBmcm9tICcuL2FwaSc7XG5cbmNvbnN0IENvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PFNjcm9sbEludG9WaWV3QVBJIHwgbnVsbD4obnVsbCk7XG5cbmV4cG9ydCBkZWZhdWx0IENvbnRleHQ7XG5cbmV4cG9ydCBjb25zdCBBUElDb25zdW1lciA9IENvbnRleHQuQ29uc3VtZXI7XG5cbmludGVyZmFjZSBQcm92aWRlQVBJUHJvcHMge1xuICAgIGRlcGVuZGVuY2llczogU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXM7XG4gICAgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZTtcbn1cblxuZXhwb3J0IGNvbnN0IFByb3ZpZGVBUEk6IFJlYWN0LkZDPFByb3ZpZGVBUElQcm9wcz4gPSAoeyBkZXBlbmRlbmNpZXMsIGNoaWxkcmVuIH0pID0+IHtcbiAgICBjb25zdCBhcGkgPSBSZWFjdC51c2VNZW1vKCgpID0+IG5ldyBTY3JvbGxJbnRvVmlld0FQSShkZXBlbmRlbmNpZXMpLCBbZGVwZW5kZW5jaWVzXSk7XG4gICAgcmV0dXJuIDxDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXthcGl9PntjaGlsZHJlbn08L0NvbnRleHQuUHJvdmlkZXI+O1xufTtcbiIsImltcG9ydCBSZWFjdCwgeyBmb3J3YXJkUmVmLCB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxuaW1wb3J0IHsgQVBJQ29uc3VtZXIgfSBmcm9tICcuL2NvbnRleHQnO1xuaW1wb3J0IHsgdGhyb3R0bGUgfSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHR5cGUgeyBTY3JvbGxJbnRvVmlld0FQSSB9IGZyb20gJy4vYXBpJztcbmltcG9ydCB0eXBlIHsgUGFydGlhbE9wdGlvbnMgfSBmcm9tICcuL2NvbmZpZyc7XG5p