import { DefaultViewerParams, ViewerEvent, DefaultLightConfiguration, LegacyViewer, FilteringExtension } from "/_nuxt/@fs/D:/speckle-server/packages/viewer/dist/index.js"; import { inject, ref, provide } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; import { useScopedState } from "/_nuxt/lib/common/composables/scopedState.ts"; import { isNonNullable } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/index.js"; import { useApolloClient, useLazyQuery, useQuery } from "/_nuxt/node_modules/@vue/apollo-composable/dist/index.mjs?v=e4f18c29"; import { projectViewerResourcesQuery, viewerLoadedResourcesQuery, viewerLoadedThreadsQuery, viewerModelVersionsQuery } from "/_nuxt/lib/viewer/graphql/queries.ts"; import { convertThrowIntoFetchResult, getFirstErrorMessage } from "/_nuxt/lib/common/helpers/graphql.ts"; import { nanoid } from "/_nuxt/node_modules/.cache/vite/client/deps/nanoid.js?v=e4f18c29"; import { ToastNotificationType, useGlobalToast } from "/_nuxt/lib/common/composables/toast.ts"; import { setupUrlHashState } from "/_nuxt/lib/viewer/composables/setup/urlHashState.ts"; import { Vector3 } from "/_nuxt/node_modules/.cache/vite/client/deps/three.js?v=e4f18c29"; import { writableAsyncComputed } from "/_nuxt/lib/common/composables/async.ts"; import { setupUiDiffState } from "/_nuxt/lib/viewer/composables/setup/diff.ts"; import { useDiffUtilities, useMeasurementUtilities } from "/_nuxt/lib/viewer/composables/ui.ts"; import { useFilterUtilities } from "/_nuxt/lib/viewer/composables/filtering/filtering.ts"; import { useCreateViewerFilteringDataStore } from "/_nuxt/lib/viewer/composables/filtering/dataStore.ts"; import { flatten, isUndefined, reduce } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29"; import { setupViewerCommentBubbles } from "/_nuxt/lib/viewer/composables/setup/comments.ts"; import { InjectableViewerStateKey, useSetupViewerScope } from "/_nuxt/lib/viewer/composables/setup/core.ts"; import { useSynchronizedCookie } from "/_nuxt/lib/common/composables/reactiveCookie.ts"; import { buildManualPromise } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js"; import { PassReader } from "/_nuxt/lib/viewer/extensions/PassReader.ts"; import { createGetParamFromResources, isAllModelsResource, isModelFolderResource, isModelResource, isObjectResource, parseUrlParameters, resourceBuilder, ViewerModelResource, ViewerObjectResource } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/viewer/helpers/route.js"; import { getTargetObjectIds } from "/_nuxt/lib/object-sidebar/helpers.ts"; import { useBuildSavedViewsCoreState, useBuildSavedViewsUIState } from "/_nuxt/lib/viewer/composables/savedViews/state.ts"; import { useViewModesSetup } from "/_nuxt/lib/viewer/composables/setup/viewMode.ts"; import { useMeasurementsSetup } from "/_nuxt/lib/viewer/composables/setup/measurements.ts"; import { useFiltersSetup } from "/_nuxt/lib/viewer/composables/setup/filters.ts"; import { useViewerPanelsSetup } from "/_nuxt/lib/viewer/composables/setup/panels.ts"; import { ViewerRenderPageType } from "/_nuxt/lib/viewer/helpers/state.ts"; import { HighlightExtension } from "/_nuxt/lib/viewer/composables/setup/highlighting.ts"; import { shallowRef, onMounted, onBeforeUnmount, computed, watch, onServerPrefetch, markRaw } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; import { useRuntimeConfig } from "/_nuxt/node_modules/nuxt/dist/app/nuxt.js?v=e4f18c29"; import { useRoute } from "/_nuxt/node_modules/nuxt/dist/app/composables/router.js?v=e4f18c29"; import { useError, createError } from "/_nuxt/node_modules/nuxt/dist/app/composables/error.js?v=e4f18c29"; import { useLogger } from "/_nuxt/composables/logging.ts"; const GlobalViewerDataKey = Symbol("GlobalViewerData"); function createViewerDataBuilder(params) { return () => { if (false) return void 0; const container = document.createElement("div"); container.id = "renderer"; container.style.display = "block"; container.style.width = "100%"; container.style.height = "100%"; const viewer = new LegacyViewer(container, { ...DefaultViewerParams, verbose: !!(true && params.viewerDebug) }); viewer.createExtension(HighlightExtension); viewer.createExtension(PassReader); const initPromise = viewer.init(); return { instance: viewer, container, initPromise }; }; } function setupViewerMetadata(params) { const { viewer } = params; const worldTree = shallowRef(void 0); const filteringState = shallowRef(void 0); const views = ref([]); const filteringDataStore = useCreateViewerFilteringDataStore(); const refreshWorldTreeAndFilters = async () => { worldTree.value = viewer.getWorldTree(); views.value = viewer.getViews(); }; const updateFilteringState = (newState) => { filteringState.value = newState && Object.keys(newState).length > 0 ? newState : void 0; }; onMounted(() => { viewer.on(ViewerEvent.LoadComplete, refreshWorldTreeAndFilters); viewer.getExtension(FilteringExtension).on(ViewerEvent.FilteringStateSet, updateFilteringState); }); onBeforeUnmount(() => { viewer.removeListener(ViewerEvent.LoadComplete, refreshWorldTreeAndFilters); viewer.getExtension(FilteringExtension).removeListener(ViewerEvent.FilteringStateSet, updateFilteringState); }); return { worldTree: computed(() => worldTree.value), filteringState: computed(() => filteringState.value), views: computed(() => views.value), filteringDataStore }; } function setupInitialState(params) { const { public: { viewerDebug } } = useRuntimeConfig(); const route = useRoute(); const sessionId = computed(() => nanoid()); const isInitialized = ref(false); const { instance, initPromise, container } = useScopedState( GlobalViewerDataKey, createViewerDataBuilder({ viewerDebug: viewerDebug || route.query.viewerVerbose === "1" }) ) || { initPromise: Promise.resolve() }; initPromise.then(() => isInitialized.value = true); const hasDoneInitialLoad = ref(false); return { pageType: computed(() => params.pageType), projectId: params.projectId, sessionId, viewer: false ? { instance: void 0, container: void 0, init: { promise: new Promise(() => { }), ref: computed(() => false) }, metadata: { worldTree: computed(() => void 0), views: computed(() => []), filteringState: computed(() => void 0) }, hasDoneInitialLoad } : { instance, container, init: { promise: initPromise, ref: computed(() => isInitialized.value) }, metadata: setupViewerMetadata({ viewer: instance }), hasDoneInitialLoad }, urlHashState: setupUrlHashState() }; } function setupResourceRequest(state, params) { const resourceIdString = params.resourceIdString; const resources = writableAsyncComputed({ get: () => resourceBuilder().addResources(resourceIdString.value).toResources(), set: async (newResources) => { const newIdString = createGetParamFromResources(newResources); await resourceIdString.update(newIdString); }, initialState: [], asyncRead: false }); const discussionLoadedVersionOnly = useSynchronizedCookie( "discussionLoadedVersionOnly", { default: () => true } ); const threadFilters = ref({ loadedVersionsOnly: discussionLoadedVersionOnly.value }); const switchModelToVersion = async (modelId, versionId) => { const resourceArr = resources.value.slice(); const resourceIdx = resourceArr.findIndex( (r) => isModelResource(r) && r.modelId === modelId ); if (resourceIdx !== -1) { const newResources = resources.value.slice(); newResources.splice(resourceIdx, 1, new ViewerModelResource(modelId, versionId)); await resources.update(newResources); } else { await resources.update([ new ViewerModelResource(modelId, versionId), ...resources.value ]); } }; watch( () => threadFilters.value.loadedVersionsOnly, (newVal, oldVal) => { if (newVal !== oldVal && newVal !== discussionLoadedVersionOnly.value) { discussionLoadedVersionOnly.value = newVal; } } ); return { ...state, resources: { request: { savedView: useBuildSavedViewsCoreState(state, params), items: resources, resourceIdString, threadFilters, switchModelToVersion } } }; } function setupResponseResourceItems(state) { const globalError = useError(); const { projectId, resources: { request: { resourceIdString, savedView: { id: savedViewId, loadOriginal } } }, urlHashState: { savedView: urlHashSavedView } } = state; const initLoadDone = ref(false ? false : true); const { result: resolvedResourcesResult, variables: resourceItemsQueryVariables, onError, onResult } = useQuery( projectViewerResourcesQuery, () => ({ projectId: projectId.value, resourceUrlString: resourceIdString.value, ...isUndefined(savedViewId.value) ? { // Omit entirely if undefined to allow for implicit/home views } : { // Load specific or load NONE savedViewId: savedViewId.value }, savedViewSettings: { loadOriginal: loadOriginal.value || false } }), { keepPreviousResult: true } ); onError((err) => { globalError.value = createError({ statusCode: 500, message: `Viewer resource resolution failed: ${err}` }); initLoadDone.value = true; }); onResult(async (res) => { initLoadDone.value = true; const data = res.data?.project?.viewerResourcesExtended; if (!data) return; const incomingResourceIdString = resourceBuilder().addResources( data.resourceIdString ); const existing = resourceBuilder().addResources(resourceIdString.value); if (!incomingResourceIdString.isEqualTo(existing)) { await resourceIdString.update(incomingResourceIdString.toString()); } if (data.request?.savedViewId && data.request.savedViewId !== data.savedView?.id) { savedViewId.value = null; void urlHashSavedView.update(null); } }); const resourceItemsExtended = computed( () => resolvedResourcesResult.value?.project?.viewerResourcesExtended ); const resolvedResourceGroups = computed( () => resourceItemsExtended.value?.groups || [] ); const resourceItems = computed(() => { const versionItems = []; const modelItems = []; const folderItems = []; const objectItems = []; const allModelItems = []; for (const group of resolvedResourceGroups.value) { const [resource] = parseUrlParameters(group.identifier); for (const item of group.items) { if (isModelResource(resource)) { if (resource.versionId) { versionItems.push(item); } else { modelItems.push(item); } } else if (isAllModelsResource(resource)) { allModelItems.push(item); } else if (isModelFolderResource(resource)) { folderItems.push(item); } else if (isObjectResource(resource)) { objectItems.push(item); } } } const orderedItems = [ ...versionItems, ...modelItems, ...folderItems, ...allModelItems, ...objectItems ]; const encounteredModels = /* @__PURE__ */ new Set(); const encounteredObjects = /* @__PURE__ */ new Set(); const finalItems = []; for (const item of orderedItems) { const modelId = item.modelId; const objectId = item.objectId; if (modelId && encounteredModels.has(modelId)) continue; if (encounteredObjects.has(objectId)) continue; finalItems.push(item); if (modelId) encounteredModels.add(modelId); encounteredObjects.add(objectId); } return finalItems; }); const resourceItemsIds = computed( () => resourceItems.value.map((i) => { if (i.modelId) { return new ViewerModelResource(i.modelId, i.versionId || void 0).toString(); } else { return new ViewerObjectResource(i.objectId).toString(); } }) ); const resourceItemsLoaded = computed(() => initLoadDone.value); const savedView = computed(() => { const idToLoad = savedViewId.value; const idLoaded = resolvedResourcesResult.value?.project?.viewerResourcesExtended.savedView?.id; const savedViewFromRes = resolvedResourcesResult.value?.project?.viewerResourcesExtended.savedView || void 0; if (idToLoad && idToLoad !== idLoaded) return void 0; if (!idToLoad && !idLoaded) return savedViewFromRes; return savedViewFromRes; }); const isFederatedView = computed(() => resourceItems.value.length > 1); const concreteResourceIdString = computed(() => { const builder = resourceBuilder(); for (const resource of resourceItems.value) { if (resource.modelId && resource.versionId) { builder.addModel(resource.modelId, resource.versionId); } else { builder.addObject(resource.objectId); } } const finalString = builder.toString(); return finalString || resourceIdString.value; }); return { resourceItemsExtended, resourceItemsIds, resourceItems, resourceItemsQueryVariables: computed(() => resourceItemsQueryVariables.value), resourceItemsLoaded, savedView, isFederatedView, concreteResourceIdString }; } function setupResponseResourceData(state, resourceItemsData) { const apollo = useApolloClient().client; const globalError = useError(); const { triggerNotification } = useGlobalToast(); const logger = useLogger(); const { projectId, resources: { request: { resourceIdString, threadFilters } }, urlHashState: { diff } } = state; const { resourceItems, resourceItemsLoaded } = resourceItemsData; const initLoadDone = ref(false ? false : true); const objects = computed( () => resourceItems.value.filter((i) => !i.modelId && !i.versionId) ); const nonObjectResourceItems = computed( () => resourceItems.value.filter( (r) => !!r.modelId ) ); const diffVersionIds = computed( () => flatten( (diff.value?.diffs || []).map((d) => [d.versionA.versionId, d.versionB.versionId]) ) ); const versionIds = computed( () => [ ...nonObjectResourceItems.value.map((r) => r.versionId), ...diffVersionIds.value ].sort() ); const versionCursors = ref({}); const viewerLoadedResourcesVariablesFunc = () => ({ projectId: projectId.value, modelIds: nonObjectResourceItems.value.map((r) => r.modelId).sort(), versionIds: versionIds.value }); const { result: viewerLoadedResourcesResult, loading: viewerLoadedResourcesLoading, variables: viewerLoadedResourcesVariables, onError: onViewerLoadedResourcesError, onResult: onViewerLoadedResourcesResult, load: loadViewerLoadedResources } = useLazyQuery(viewerLoadedResourcesQuery, viewerLoadedResourcesVariablesFunc, { keepPreviousResult: true }); const serverResourcesLoadedPromise = buildManualPromise(); if (false) { watch( () => resourceItemsLoaded.value, async (newVal, oldVal) => { if (!newVal || oldVal) return; await loadViewerLoadedResources(); serverResourcesLoadedPromise.resolve(); }, { flush: "sync" } ); } else { loadViewerLoadedResources(); serverResourcesLoadedPromise.resolve(); } const project = computed(() => viewerLoadedResourcesResult.value?.project); const models = computed(() => project.value?.models?.items || []); const modelsAndVersionIds = computed( () => nonObjectResourceItems.value.map((r) => ({ versionId: r.versionId, model: models.value.find((m) => m.id === r.modelId) })).filter((o) => !!(o.versionId && o.model)) ); const availableModelsAndVersions = computed(() => { const modelItems = models.value; return reduce( modelItems, (res, entry) => { res.push({ model: entry, versions: [...entry.loadedVersion.items, ...entry.versions.items] }); return res; }, [] ); }); onViewerLoadedResourcesError((err) => { const isWorkingLoad = !!viewerLoadedResourcesResult.value?.project.models.items; if (isWorkingLoad) { return; } globalError.value = createError({ statusCode: 500, message: `Viewer loaded resource resolution failed: ${err}` }); initLoadDone.value = true; }); onViewerLoadedResourcesResult((res) => { initLoadDone.value = true; if (!res.data?.project?.models) return; for (const model of res.data.project.models.items) { const modelId = model.id; if (versionCursors.value[modelId]) continue; const cursor = model.versions.cursor; if (!cursor) continue; versionCursors.value[modelId] = cursor; } }); const loadMoreVersions = async (modelId) => { const cursor = versionCursors.value[modelId]; const baseVariables = viewerLoadedResourcesVariablesFunc(); const { data, errors } = await apollo.query({ query: viewerModelVersionsQuery, variables: { projectId: baseVariables.projectId, modelId, versionsCursor: cursor }, fetchPolicy: "network-only" }).catch(convertThrowIntoFetchResult); if (!data?.project?.model?.versions) { triggerNotification({ type: ToastNotificationType.Danger, title: "Can't load more versions", description: getFirstErrorMessage(errors) }); return; } if (data.project.model.versions.cursor) { versionCursors.value[modelId] = data.project.model.versions.cursor; } }; const { result: viewerLoadedThreadsResult, onError: onViewerLoadedThreadsError, variables: threadsQueryVariables } = useQuery( viewerLoadedThreadsQuery, () => ({ projectId: projectId.value, filter: { ...threadFilters.value, resourceIdString: resourceIdString.value } }), () => ({ keepPreviousResult: true, // Dont need threads when in presentation mode enabled: state.pageType.value !== ViewerRenderPageType.Presentation }) ); const commentThreadsMetadata = computed( () => viewerLoadedThreadsResult.value?.project?.commentThreads ); const commentThreads = computed(() => commentThreadsMetadata.value?.items || []); onViewerLoadedThreadsError((err) => { const isWorkingLoad = !!viewerLoadedThreadsResult.value?.project.commentThreads.items; if (isWorkingLoad) { return; } triggerNotification({ type: ToastNotificationType.Danger, title: "Comment loading failed", description: `${err.message}` }); logger.error(err); }); onServerPrefetch(async () => { await Promise.all([serverResourcesLoadedPromise.promise]); }); return { objects, commentThreads, commentThreadsMetadata, modelsAndVersionIds, availableModelsAndVersions, project, resourceQueryVariables: computed(() => viewerLoadedResourcesVariables.value), threadsQueryVariables: computed(() => threadsQueryVariables.value), loadMoreVersions, resourcesLoaded: computed(() => initLoadDone.value), resourcesLoading: computed(() => viewerLoadedResourcesLoading.value) }; } function setupResourceResponse(state) { const resourceItemsData = setupResponseResourceItems(state); const loadedResourceData = setupResponseResourceData(state, resourceItemsData); return { ...state, resources: { request: { ...state.resources.request }, response: { ...resourceItemsData, ...loadedResourceData } } }; } function setupInterfaceState(state) { const isLoading = ref(false); const loading = computed({ get: () => isLoading.value, set: (newVal) => isLoading.value = !!newVal }); const loadProgress = ref(0); const hasLoadedQueuedUpModels = ref(false); const { filters } = useFiltersSetup(); const { viewMode } = useViewModesSetup(); const highlightedObjectIds = ref([]); const spotlightUserSessionId = ref(null); const lightConfig = ref(DefaultLightConfiguration); const explodeFactor = ref(0); const selection = ref(null); const selectedObjectIds = computed( () => new Set( filters.selectedObjects.value.flatMap( (o) => getTargetObjectIds(o) ) ) ); const { commentThreads, openThread, newThreadEditor } = setupViewerCommentBubbles({ state }); const isTyping = ref(false); const hideBubbles = ref(false); const diffState = setupUiDiffState(state); const position = ref(new Vector3()); const target = ref(new Vector3()); const isOrthoProjection = ref(false); return { ...state, ui: { viewMode, diff: { ...diffState }, selection, lightConfig, explodeFactor, spotlightUserSessionId, loading, loadProgress, threads: { items: commentThreads, openThread: { thread: openThread, isTyping, newThreadEditor }, hideBubbles }, camera: { // position: wrapRefWithTracking(position, 'position'), // target: wrapRefWithTracking(target, 'target'), position, target, isOrthoProjection }, sectionBox: ref(null), sectionBoxContext: { visible: ref(false), edited: ref(false) }, windowSelection: { enabled: ref(false) }, filters: { ...filters, selectedObjectIds }, highlightedObjectIds, measurement: useMeasurementsSetup(), savedViews: useBuildSavedViewsUIState(), panels: useViewerPanelsSetup(), hasLoadedQueuedUpModels } }; } export function useSetupViewer(params) { const initState = setupInitialState(params); const initialStateWithRequest = setupResourceRequest(initState, params); const stateWithResources = setupResourceResponse(initialStateWithRequest); const state = setupInterfaceState(stateWithResources); const rawState = markRaw(state); provide(InjectableViewerStateKey, rawState); return rawState; } export function useInjectedViewerState() { const state = inject(InjectableViewerStateKey); return state; } export function useInjectedViewer() { const { viewer } = useInjectedViewerState(); return viewer; } export function useInjectedViewerLoadedResources() { const { resources } = useInjectedViewerState(); return resources.response; } export function useInjectedViewerRequestedResources() { const { resources } = useInjectedViewerState(); return resources.request; } export function useInjectedViewerInterfaceState() { const { ui } = useInjectedViewerState(); return ui; } export function useResetUiState() { const { ui: { camera, sectionBox, highlightedObjectIds, lightConfig, viewMode } } = useInjectedViewerState(); const { resetFilters } = useFilterUtilities(); const { endDiff } = useDiffUtilities(); const { reset: resetMeasurements } = useMeasurementUtilities(); return () => { camera.isOrthoProjection.value = false; sectionBox.value = null; highlightedObjectIds.value = []; lightConfig.value = { ...DefaultLightConfiguration }; viewMode.resetViewMode(); resetFilters(); resetMeasurements(); endDiff(); }; } export { InjectableViewerStateKey, useSetupViewerScope }; //# sourceMappingURL=data:application/json;base64,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QXVCO0FBQ3RDLFNBQU87QUFDVDtBQUVPLGdCQUFTLGtCQUFrQjtBQUNoQyxRQUFNO0FBQUEsSUFDSixJQUFJLEVBQUUsUUFBUSxZQUFZLHNCQUFzQixhQUFhLFNBQVM7QUFBQSxFQUN4RSxJQUFJLHVCQUF1QjtBQUMzQixRQUFNLEVBQUUsYUFBYSxJQUFJLG1CQUFtQjtBQUM1QyxRQUFNLEVBQUUsUUFBUSxJQUFJLGlCQUFpQjtBQUNyQyxRQUFNLEVBQUUsT0FBTyxrQkFBa0IsSUFBSSx3QkFBd0I7QUFFN0QsU0FBTyxNQUFNO0FBQ1gsV0FBTyxrQkFBa0IsUUFBUTtBQUNqQyxlQUFXLFFBQVE7QUFDbkIseUJBQXFCLFFBQVEsQ0FBQztBQUM5QixnQkFBWSxRQUFRLEVBQUUsR0FBRywwQkFBMEI7QUFDbkQsYUFBUyxjQUFjO0FBQ3ZCLGlCQUFhO0FBQ2Isc0JBQWtCO0FBQ2xCLFlBQVE7QUFBQSxFQUNWO0FBQ0Y7QUFFQSxTQUFTLDBCQUEwQiIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsic2V0dXAudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBEZWZhdWx0Vmlld2VyUGFyYW1zLFxyXG4gIFZpZXdlckV2ZW50LFxyXG4gIERlZmF1bHRMaWdodENvbmZpZ3VyYXRpb24sXHJcbiAgTGVnYWN5Vmlld2VyLFxyXG4gIEZpbHRlcmluZ0V4dGVuc2lvblxyXG59IGZyb20gJ0BzcGVja2xlL3ZpZXdlcidcclxuaW1wb3J0IHR5cGUge1xyXG4gIFZpZXdNb2RlLFxyXG4gIEZpbHRlcmluZ1N0YXRlLFxyXG4gIFN1bkxpZ2h0Q29uZmlndXJhdGlvbixcclxuICBTcGVja2xlVmlldyxcclxuICBEaWZmUmVzdWx0LFxyXG4gIFZpZXdlcixcclxuICBXb3JsZFRyZWUsXHJcbiAgVmlzdWFsRGlmZk1vZGVcclxufSBmcm9tICdAc3BlY2tsZS92aWV3ZXInXHJcbmltcG9ydCB7IGluamVjdCwgcmVmLCBwcm92aWRlIH0gZnJvbSAndnVlJ1xyXG5pbXBvcnQgdHlwZSB7IENvbXB1dGVkUmVmLCBXcml0YWJsZUNvbXB1dGVkUmVmLCBSYXcsIFJlZiwgU2hhbGxvd1JlZiB9IGZyb20gJ3Z1ZSdcclxuaW1wb3J0IHsgdXNlU2NvcGVkU3RhdGUgfSBmcm9tICd+fi9saWIvY29tbW9uL2NvbXBvc2FibGVzL3Njb3BlZFN0YXRlJ1xyXG5pbXBvcnQgdHlwZSB7IE1heWJlTnVsbE9yVW5kZWZpbmVkLCBOdWxsYWJsZSwgT3B0aW9uYWwgfSBmcm9tICdAc3BlY2tsZS9zaGFyZWQnXHJcbmltcG9ydCB7IGlzTm9uTnVsbGFibGUgfSBmcm9tICdAc3BlY2tsZS9zaGFyZWQnXHJcbmltcG9ydCB7IHVzZUFwb2xsb0NsaWVudCwgdXNlTGF6eVF1ZXJ5LCB1c2VRdWVyeSB9IGZyb20gJ0B2dWUvYXBvbGxvLWNvbXBvc2FibGUnXHJcbmltcG9ydCB7XHJcbiAgcHJvamVjdFZpZXdlclJlc291cmNlc1F1ZXJ5LFxyXG4gIHZpZXdlckxvYWRlZFJlc291cmNlc1F1ZXJ5LFxyXG4gIHZpZXdlckxvYWRlZFRocmVhZHNRdWVyeSxcclxuICB2aWV3ZXJNb2RlbFZlcnNpb25zUXVlcnlcclxufSBmcm9tICd+fi9saWIvdmlld2VyL2dyYXBocWwvcXVlcmllcydcclxuaW1wb3J0IHR5cGUge1xyXG4gIFByb2plY3RWaWV3ZXJSZXNvdXJjZXNRdWVyeVZhcmlhYmxlcyxcclxuICBWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeSxcclxuICBWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeVZhcmlhYmxlcyxcclxuICBWaWV3ZXJMb2FkZWRUaHJlYWRzUXVlcnksXHJcbiAgVmlld2VyUmVzb3VyY2VJdGVtLFxyXG4gIFZpZXdlckxvYWRlZFRocmVhZHNRdWVyeVZhcmlhYmxlcyxcclxuICBQcm9qZWN0Q29tbWVudHNGaWx0ZXIsXHJcbiAgVmlld2VyTW9kZWxWZXJzaW9uQ2FyZEl0ZW1GcmFnbWVudCxcclxuICBVc2VWaWV3ZXJTYXZlZFZpZXdTZXR1cF9TYXZlZFZpZXdGcmFnbWVudCxcclxuICBQcm9qZWN0Vmlld2VyUmVzb3VyY2VzUXVlcnlcclxufSBmcm9tICd+fi9saWIvY29tbW9uL2dlbmVyYXRlZC9ncWwvZ3JhcGhxbCdcclxuaW1wb3J0IHR5cGUgeyBTZXROb25OdWxsYWJsZSwgR2V0IH0gZnJvbSAndHlwZS1mZXN0J1xyXG5pbXBvcnQge1xyXG4gIGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdCxcclxuICBnZXRGaXJzdEVycm9yTWVzc2FnZVxyXG59IGZyb20gJ35+L2xpYi9jb21tb24vaGVscGVycy9ncmFwaHFsJ1xyXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tICduYW5vaWQnXHJcbmltcG9ydCB7IFRvYXN0Tm90aWZpY2F0aW9uVHlwZSwgdXNlR2xvYmFsVG9hc3QgfSBmcm9tICd+fi9saWIvY29tbW9uL2NvbXBvc2FibGVzL3RvYXN0J1xyXG5pbXBvcnQgdHlwZSB7IENvbW1lbnRCdWJibGVNb2RlbCB9IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvY29tbWVudEJ1YmJsZXMnXHJcbmltcG9ydCB7IHNldHVwVXJsSGFzaFN0YXRlIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC91cmxIYXNoU3RhdGUnXHJcbmltcG9ydCB0eXBlIHtcclxuICBNb2RlbHNTdWJWaWV3LFxyXG4gIEFjdGl2ZVBhbmVsLFxyXG4gIFNwZWNrbGVPYmplY3RcclxufSBmcm9tICd+L2xpYi92aWV3ZXIvaGVscGVycy9zY2VuZUV4cGxvcmVyJ1xyXG5pbXBvcnQgeyBWZWN0b3IzIH0gZnJvbSAndGhyZWUnXHJcbmltcG9ydCB7IHdyaXRhYmxlQXN5bmNDb21wdXRlZCB9IGZyb20gJ35+L2xpYi9jb21tb24vY29tcG9zYWJsZXMvYXN5bmMnXHJcbmltcG9ydCB0eXBlIHsgQXN5bmNXcml0YWJsZUNvbXB1dGVkUmVmIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9jb21wb3NhYmxlcy9hc3luYydcclxuaW1wb3J0IHsgc2V0dXBVaURpZmZTdGF0ZSB9IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2V0dXAvZGlmZidcclxuaW1wb3J0IHR5cGUgeyBEaWZmU3RhdGVDb21tYW5kIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC9kaWZmJ1xyXG5pbXBvcnQgeyB1c2VEaWZmVXRpbGl0aWVzLCB1c2VNZWFzdXJlbWVudFV0aWxpdGllcyB9IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvdWknXHJcbmltcG9ydCB7IHVzZUZpbHRlclV0aWxpdGllcyB9IGZyb20gJ34vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9maWx0ZXJpbmcvZmlsdGVyaW5nJ1xyXG5pbXBvcnQgeyB1c2VDcmVhdGVWaWV3ZXJGaWx0ZXJpbmdEYXRhU3RvcmUgfSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvZmlsdGVyaW5nL2RhdGFTdG9yZSdcclxuaW1wb3J0IHsgZmxhdHRlbiwgaXNVbmRlZmluZWQsIHJlZHVjZSB9IGZyb20gJ2xvZGFzaC1lcydcclxuaW1wb3J0IHsgc2V0dXBWaWV3ZXJDb21tZW50QnViYmxlcyB9IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2V0dXAvY29tbWVudHMnXHJcbmltcG9ydCB7XHJcbiAgSW5qZWN0YWJsZVZpZXdlclN0YXRlS2V5LFxyXG4gIHVzZVNldHVwVmlld2VyU2NvcGVcclxufSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2V0dXAvY29yZSdcclxuaW1wb3J0IHsgdXNlU3luY2hyb25pemVkQ29va2llIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9jb21wb3NhYmxlcy9yZWFjdGl2ZUNvb2tpZSdcclxuaW1wb3J0IHsgYnVpbGRNYW51YWxQcm9taXNlIH0gZnJvbSAnQHNwZWNrbGUvdWktY29tcG9uZW50cydcclxuaW1wb3J0IHsgUGFzc1JlYWRlciB9IGZyb20gJy4uL2V4dGVuc2lvbnMvUGFzc1JlYWRlcidcclxuaW1wb3J0IHR5cGUge1xyXG4gIE1lYXN1cmVtZW50RGF0YSxcclxuICBNZWFzdXJlbWVudE9wdGlvbnMsXHJcbiAgU2VjdGlvbkJveERhdGFcclxufSBmcm9tICdAc3BlY2tsZS9zaGFyZWQvdmlld2VyL3N0YXRlJ1xyXG5pbXBvcnQge1xyXG4gIGNyZWF0ZUdldFBhcmFtRnJvbVJlc291cmNlcyxcclxuICBpc0FsbE1vZGVsc1Jlc291cmNlLFxyXG4gIGlzTW9kZWxGb2xkZXJSZXNvdXJjZSxcclxuICBpc01vZGVsUmVzb3VyY2UsXHJcbiAgaXNPYmplY3RSZXNvdXJjZSxcclxuICBwYXJzZVVybFBhcmFtZXRlcnMsXHJcbiAgcmVzb3VyY2VCdWlsZGVyLFxyXG4gIFZpZXdlck1vZGVsUmVzb3VyY2UsXHJcbiAgVmlld2VyT2JqZWN0UmVzb3VyY2UsXHJcbiAgdHlwZSBWaWV3ZXJSZXNvdXJjZVxyXG59IGZyb20gJ0BzcGVja2xlL3NoYXJlZC92aWV3ZXIvcm91dGUnXHJcbmltcG9ydCB0eXBlIHsgU2F2ZWRWaWV3VXJsU2V0dGluZ3MgfSBmcm9tICd+L2xpYi92aWV3ZXIvaGVscGVycy9zYXZlZFZpZXdzJ1xyXG5pbXBvcnQgdHlwZSB7IEZpbHRlckRhdGEgfSBmcm9tICd+L2xpYi92aWV3ZXIvaGVscGVycy9maWx0ZXJzL3R5cGVzJ1xuaW1wb3J0IHsgZ2V0VGFyZ2V0T2JqZWN0SWRzIH0gZnJvbSAnfi9saWIvb2JqZWN0LXNpZGViYXIvaGVscGVycydcbmltcG9ydCB7XG4gIHVzZUJ1aWxkU2F2ZWRWaWV3c0NvcmVTdGF0ZSxcbiAgdXNlQnVpbGRTYXZlZFZpZXdzVUlTdGF0ZSxcbiAgdHlwZSBTYXZlZFZpZXdzVUlTdGF0ZVxufSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2F2ZWRWaWV3cy9zdGF0ZSdcclxuaW1wb3J0IHR5cGUgeyBkZWZhdWx0RWRnZUNvbG9yVmFsdWUgfSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2V0dXAvdmlld01vZGUnXHJcbmltcG9ydCB7IHVzZVZpZXdNb2Rlc1NldHVwIH0gZnJvbSAnfi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3NldHVwL3ZpZXdNb2RlJ1xyXG5pbXBvcnQgeyB1c2VNZWFzdXJlbWVudHNTZXR1cCB9IGZyb20gJ34vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC9tZWFzdXJlbWVudHMnXHJcbmltcG9ydCB7IHVzZUZpbHRlcnNTZXR1cCB9IGZyb20gJ34vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC9maWx0ZXJzJ1xyXG5pbXBvcnQgeyB1c2VWaWV3ZXJQYW5lbHNTZXR1cCB9IGZyb20gJ34vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC9wYW5lbHMnXHJcbmltcG9ydCB7IFZpZXdlclJlbmRlclBhZ2VUeXBlIH0gZnJvbSAnfi9saWIvdmlld2VyL2hlbHBlcnMvc3RhdGUnXHJcbmltcG9ydCB7IEhpZ2hsaWdodEV4dGVuc2lvbiB9IGZyb20gJ34vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC9oaWdobGlnaHRpbmcnXHJcblxyXG5leHBvcnQgdHlwZSBMb2FkZWRNb2RlbCA9IE5vbk51bGxhYmxlPFxyXG4gIEdldDxWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeSwgJ3Byb2plY3QubW9kZWxzLml0ZW1zWzBdJz5cclxuPlxyXG5leHBvcnQgdHlwZSBMb2FkZWRUaHJlYWRzTWV0YWRhdGEgPSBOb25OdWxsYWJsZTxcclxuICBHZXQ8Vmlld2VyTG9hZGVkVGhyZWFkc1F1ZXJ5LCAncHJvamVjdC5jb21tZW50VGhyZWFkcyc+XHJcbj5cclxuZXhwb3J0IHR5cGUgTG9hZGVkQ29tbWVudFRocmVhZCA9IE5vbk51bGxhYmxlPEdldDxMb2FkZWRUaHJlYWRzTWV0YWRhdGEsICdpdGVtc1swXSc+PlxyXG50eXBlIExvYWRlZFNhdmVkVmlldyA9IFVzZVZpZXdlclNhdmVkVmlld1NldHVwX1NhdmVkVmlld0ZyYWdtZW50XHJcbnR5cGUgTG9hZGVkRXh0ZW5kZWRSZXNvdXJjZUl0ZW1zID1cclxuICB8IEdldDxQcm9qZWN0Vmlld2VyUmVzb3VyY2VzUXVlcnksICdwcm9qZWN0LnZpZXdlclJlc291cmNlc0V4dGVuZGVkJz5cclxuICB8IG51bGxcclxuICB8IHVuZGVmaW5lZFxyXG5cclxuZXhwb3J0IHR5cGUgSW5qZWN0YWJsZVZpZXdlclN0YXRlID0gUmVhZG9ubHk8e1xyXG4gIC8qKlxyXG4gICAqIFRoZSBwcm9qZWN0IHdoaWNoIHdlJ3JlIG9wZW5pbmcgaW4gdGhlIHZpZXdlciAoYWxsIGxvYWRlZCBtb2RlbHMgc2hvdWxkIGJlbG9uZyB0byBpdClcclxuICAgKi9cclxuICBwcm9qZWN0SWQ6IEFzeW5jV3JpdGFibGVDb21wdXRlZFJlZjxzdHJpbmc+XHJcbiAgLyoqXHJcbiAgICogVXNlciB2aWV3ZXIgc2Vzc2lvbiBJRC4gVGhlIHNhbWUgdXNlciB3aWxsIGhhdmUgZGlmZmVyZW50IElEcyBpbiBkaWZmZXJlbnQgdGFicyBpZiBtdWx0aXBsZSBhcmUgb3Blbi5cclxuICAgKiBUaGlzIGlzIHVzZWQgdG8gaWdub3JlIHVzZXIgYWN0aXZpdHkgbWVzc2FnZXMgZnJvbSB0aGUgc2FtZSB0YWIuXHJcbiAgICovXHJcbiAgc2Vzc2lvbklkOiBDb21wdXRlZFJlZjxzdHJpbmc+XHJcbiAgLyoqXHJcbiAgICogVGhlIHR5cGUgb2YgcGFnZSB0aGF0IHRoaXMgc3RhdGUgaXMgcG93ZXJpbmcuIEJhc2VkIG9uIHRoaXMsIGNlcnRhaW4gZmVhdHVyZXMvVUlzXHJcbiAgICogY2FuIGJlIHRvZ2dsZWQuXHJcbiAgICpcclxuICAgKiBEZWZhdWx0OiBWaWV3ZXIgKG1haW4gdmlld2VyIHBhZ2UpLCBidXQgY2FuIGFsc28gYmUgUHJlc2VudGF0aW9uXHJcbiAgICovXHJcbiAgcGFnZVR5cGU6IENvbXB1dGVkUmVmPFZpZXdlclJlbmRlclBhZ2VUeXBlPlxyXG4gIC8qKlxyXG4gICAqIFRoZSBhY3R1YWwgVmlld2VyIGluc3RhbmNlIGFuZCByZWxhdGVkIG9iamVjdHMuXHJcbiAgICogTm90ZTogVGhpcyBpcyBnb2luZyB0byBiZSB1bmRlZmluZWQgaW4gU1NSIVxyXG4gICAqL1xyXG4gIHZpZXdlcjoge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYWN0dWFsIHZpZXdlciBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICBpbnN0YW5jZTogTGVnYWN5Vmlld2VyXHJcbiAgICAvKipcclxuICAgICAqIENvbnRhaW5lciBvbnRvIHdoaWNoIHRoZSBWaWV3ZXIgaW5zdGFuY2UgaXMgYXR0YWNoZWRcclxuICAgICAqL1xyXG4gICAgY29udGFpbmVyOiBIVE1MRWxlbWVudFxyXG4gICAgLyoqXHJcbiAgICAgKiBGb3IgY2hlY2tpbmcgd2hlbiB2aWV3ZXIuaW5pdCgpIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIGluaXQ6IHtcclxuICAgICAgcHJvbWlzZTogUHJvbWlzZTx2b2lkPlxyXG4gICAgICByZWY6IENvbXB1dGVkUmVmPGJvb2xlYW4+XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFZhcmlvdXMgdmFsdWVzIHRoYXQgcmVwcmVzZW50IHRoZSBjdXJyZW50IFZpZXdlciBpbnN0YW5jZSBzdGF0ZVxyXG4gICAgICovXHJcbiAgICBtZXRhZGF0YToge1xyXG4gICAgICAvKipcclxuICAgICAgICogQmFzZWQgb24gYSBzaGFsbG93IHJlZlxyXG4gICAgICAgKi9cclxuICAgICAgd29ybGRUcmVlOiBDb21wdXRlZFJlZjxPcHRpb25hbDxXb3JsZFRyZWU+PlxyXG4gICAgICB2aWV3czogQ29tcHV0ZWRSZWY8U3BlY2tsZVZpZXdbXT5cclxuICAgICAgZmlsdGVyaW5nU3RhdGU6IENvbXB1dGVkUmVmPE9wdGlvbmFsPEZpbHRlcmluZ1N0YXRlPj5cclxuICAgICAgZmlsdGVyaW5nRGF0YVN0b3JlOiBSZXR1cm5UeXBlPHR5cGVvZiB1c2VDcmVhdGVWaWV3ZXJGaWx0ZXJpbmdEYXRhU3RvcmU+XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgdGhlIFZpZXdlciBoYXMgZmluaXNoZWQgZG9pbmcgdGhlIGluaXRpYWwgb2JqZWN0IGxvYWRpbmdcclxuICAgICAqL1xyXG4gICAgaGFzRG9uZUluaXRpYWxMb2FkOiBSZWY8Ym9vbGVhbj5cclxuICB9XHJcbiAgLyoqXHJcbiAgICogTG9hZGVkL2xvYWRhYmxlIHJlc291cmNlc1xyXG4gICAqL1xyXG4gIHJlc291cmNlczoge1xyXG4gICAgLyoqXHJcbiAgICAgKiBTdGF0ZSBvZiByZXNvdXJjZSBpZGVudGlmaWVycyB0aGF0IHNob3VsZCBiZSBsb2FkZWQgKHRpZWQgdG8gdGhlIFVSTCBwYXJhbSlcclxuICAgICAqL1xyXG4gICAgcmVxdWVzdDoge1xyXG4gICAgICAvKipcclxuICAgICAgICogU2F2ZWQgdmlldyBwYXJhbWV0ZXJzLCB0aGF0IGFmZmVjdCB3aGF0IHJlc291cmNlcyB3ZSdyZSBsb2FkaW5nIGFuZCBob3dcclxuICAgICAgICovXHJcbiAgICAgIHNhdmVkVmlldzoge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBzcGVjaWZpYyB2aWV3IHRvIGxvYWQuXHJcbiAgICAgICAgICogTnVsbCAtIGxvYWQgTk8gc2F2ZWQgdmlldywgbm90IGV2ZW4gaW1wbGljaXQvaG9tZSB2aWV3c1xyXG4gICAgICAgICAqIFVuZGVmaW5lZCAtIGxvYWQgbm8gc3BlY2lmaWMgdmlldywgYnV0IGFsbG93IGZvciBpbXBsaWNpdCB2aWV3cyAoaW5pdCB2YWx1ZSlcclxuICAgICAgICAgKiBTcGVjaWZpYyBJRCAtIGxvYWQgdGhpcyBzcGVjaWZpYyB2aWV3XHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBOb3RlOiBUaGUgaW1wbGljYXRpb24gaGVyZSBpcyB0aGF0IHJlc3BvbnNlLnNhdmVkVmlldyBjYW4gYmUgbG9hZGVkL3NldCwgZXZlbiB3aGVuXHJcbiAgICAgICAgICogdGhpcyB2YWx1ZSBpcyBmYWxzeSAodW5kZWZpbmVkKSwgYmVjYXVzZSBhbiBpbXBsaWNpdC9ob21lIHZpZXcgd2FzIHJlc29sdmVkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWQ6IFJlZjxzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkPlxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEJ5IGRlZmF1bHQgd2UgdXNlIGxhdGVzdCBvciBhbHJlYWR5IGxvYWRlZCB2ZXJzaW9ucywgYnV0IHRoaXMgYWxsb3dzXHJcbiAgICAgICAgICogdXMgdG8gbG9hZCB0aGUgdmVyc2lvbnMgb3JpZ2luYWxseSBzcGVjaWZpZWQgd2hlbiBjcmVhdGluZyB0aGUgdmlld1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGxvYWRPcmlnaW5hbDogUmVmPGJvb2xlYW4+XHJcbiAgICAgIH1cclxuICAgICAgLyoqXHJcbiAgICAgICAqIEFsbCBjdXJyZW50bHkgcmVxdWVzdGVkIGlkZW50aWZpZXJzLiBZb3VcclxuICAgICAgICogY2FuIHdyaXRlIHRvIHRoaXMgdG8gY2hhbmdlIHdoaWNoIHJlc291cmNlcyBzaG91bGQgYmUgbG9hZGVkLlxyXG4gICAgICAgKi9cclxuICAgICAgaXRlbXM6IEFzeW5jV3JpdGFibGVDb21wdXRlZFJlZjxWaWV3ZXJSZXNvdXJjZVtdPlxyXG4gICAgICAvKipcclxuICAgICAgICogQWxsIGN1cnJlbnRseSByZXF1ZXN0ZWQgaWRlbnRpZmllcnMgaW4gYSBjb21tYS1kZWxpbWl0ZWQgc3RyaW5nLCB0aGUgd2F5IGl0J3NcclxuICAgICAgICogcmVwcmVzZW50ZWQgaW4gdGhlIFVSTC4gSXMgd3JpdGFibGUgYWxzby5cclxuICAgICAgICovXHJcbiAgICAgIHJlc291cmNlSWRTdHJpbmc6IEFzeW5jV3JpdGFibGVDb21wdXRlZFJlZjxzdHJpbmc+XHJcblxyXG4gICAgICAvKipcclxuICAgICAgICogV3JpdGFibGUgY29tcHV0ZWQgZm9yIHJlYWRpbmcvd3JpdGluZyBjdXJyZW50IHRocmVhZCBmaWx0ZXJzXHJcbiAgICAgICAqL1xyXG4gICAgICB0aHJlYWRGaWx0ZXJzOiBSZWY8T21pdDxQcm9qZWN0Q29tbWVudHNGaWx0ZXIsICdyZXNvdXJjZUlkU3RyaW5nJz4+XHJcblxyXG4gICAgICAvKipcclxuICAgICAgICogSGVscGVyIGZvciBzd2l0Y2hpbmcgbW9kZWwgdG8gYSBzcGVjaWZpYyB2ZXJzaW9uIChvciBqdXN0IGxhdGVzdClcclxuICAgICAgICovXHJcbiAgICAgIHN3aXRjaE1vZGVsVG9WZXJzaW9uOiAobW9kZWxJZDogc3RyaW5nLCB2ZXJzaW9uSWQ/OiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD5cclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU3RhdGUgb2YgcmVzb2x2ZWQsIHZhbGlkYXRlZCAmIGRlLWR1cGxpY2F0ZWQgcmVzb3VyY2VzIHRoYXQgYXJlIGxvYWRlZCBpbiB0aGUgdmlld2VyLiBUaGVzZVxyXG4gICAgICogYXJlIHJlc29sdmVkIGZyb20gbXVsdGlwbGUgR1FMIHJlcXVlc3RzIGFuZCB1cGRhdGUgd2hlbmV2ZXIgcmVzb3VyY2VzLnJlcXVlc3QgdXBkYXRlcy5cclxuICAgICAqL1xyXG4gICAgcmVzcG9uc2U6IHtcclxuICAgICAgLyoqXHJcbiAgICAgICAqIE1ldGFkYXRhIGFib3V0IGxvYWRlZCBpdGVtc1xyXG4gICAgICAgKi9cclxuICAgICAgcmVzb3VyY2VJdGVtczogQ29tcHV0ZWRSZWY8Vmlld2VyUmVzb3VyY2VJdGVtW10+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBBY3R1YWxseSBsb2FkZWQgcmVzb3VyY2UgaXRlbXMgYnV0IGluIHN0cmluZyBpZCBmb3JtYXRcclxuICAgICAgICovXHJcbiAgICAgIHJlc291cmNlSXRlbXNJZHM6IENvbXB1dGVkUmVmPHN0cmluZ1tdPlxyXG4gICAgICAvKipcclxuICAgICAgICogVmFyaWFibGVzIHVzZWQgdG8gbG9hZCByZXNvdXJjZSBpdGVtcyBpZGVudGlmaWVkIGJ5IFVSTCBpZGVudGlmaWVycy4gUmVsZXZhbnQgd2hlbiBtYWtpbmcgY2FjaGUgdXBkYXRlc1xyXG4gICAgICAgKi9cclxuICAgICAgcmVzb3VyY2VJdGVtc1F1ZXJ5VmFyaWFibGVzOiBDb21wdXRlZFJlZjxcclxuICAgICAgICBPcHRpb25hbDxQcm9qZWN0Vmlld2VyUmVzb3VyY2VzUXVlcnlWYXJpYWJsZXM+XHJcbiAgICAgID5cclxuICAgICAgcmVzb3VyY2VJdGVtc0V4dGVuZGVkOiBDb21wdXRlZFJlZjxMb2FkZWRFeHRlbmRlZFJlc291cmNlSXRlbXM+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgaW5pdGlhbCByZXNvdXJjZSBpdGVtcyBsb2FkIGhhcyBoYXBwZW5lZCAodXNlZnVsIGluIFNTUilcclxuICAgICAgICovXHJcbiAgICAgIHJlc291cmNlSXRlbXNMb2FkZWQ6IENvbXB1dGVkUmVmPGJvb2xlYW4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgaW5pdGlhbCByZXNvdXJjZXMgKG1vZGVscywgb2JqZWN0cyBldGMuKSBoYXZlIGJlZW4gbG9hZGVkICh1c2VmdWwgaW4gU1NSKVxyXG4gICAgICAgKi9cclxuICAgICAgcmVzb3VyY2VzTG9hZGVkOiBDb21wdXRlZFJlZjxib29sZWFuPlxyXG4gICAgICAvKipcclxuICAgICAgICogTW9kZWwgR1FMIG9iamVjdHMgcGFpcmVkIHdpdGggdGhlaXIgbG9hZGVkIHZlcnNpb24gSURzXHJcbiAgICAgICAqL1xyXG4gICAgICBtb2RlbHNBbmRWZXJzaW9uSWRzOiBDb21wdXRlZFJlZjxBcnJheTx7IG1vZGVsOiBMb2FkZWRNb2RlbDsgdmVyc2lvbklkOiBzdHJpbmcgfT4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBBbGwgYXZhaWxhYmxlIChyZXRyaWV2ZWQgZnJvbSBHUUwpIG1vZGVscyBhbmQgdGhlaXIgdmVyc2lvbnNcclxuICAgICAgICovXHJcbiAgICAgIGF2YWlsYWJsZU1vZGVsc0FuZFZlcnNpb25zOiBDb21wdXRlZFJlZjxcclxuICAgICAgICBBcnJheTx7IG1vZGVsOiBMb2FkZWRNb2RlbDsgdmVyc2lvbnM6IExvYWRlZE1vZGVsWyd2ZXJzaW9ucyddWydpdGVtcyddIH0+XHJcbiAgICAgID5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIERldGFjaGVkIG9iamVjdHMgKG5vdCBtb2RlbHMvdmVyc2lvbnMpXHJcbiAgICAgICAqL1xyXG4gICAgICBvYmplY3RzOiBDb21wdXRlZFJlZjxWaWV3ZXJSZXNvdXJjZUl0ZW1bXT5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIENvbW1lbnQgdGhyZWFkcyBmb3IgYWxsIGxvYWRlZCByZXNvdXJjZXNcclxuICAgICAgICovXHJcbiAgICAgIGNvbW1lbnRUaHJlYWRzOiBDb21wdXRlZFJlZjxBcnJheTxMb2FkZWRDb21tZW50VGhyZWFkPj5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIE1ldGFkYXRhIGFib3V0IHJlcXVlc3RlZCBjb21tZW50IHRocmVhZHMgKGUuZy4gdG90YWwgY291bnRzKVxyXG4gICAgICAgKi9cclxuICAgICAgY29tbWVudFRocmVhZHNNZXRhZGF0YTogQ29tcHV0ZWRSZWY8T3B0aW9uYWw8TG9hZGVkVGhyZWFkc01ldGFkYXRhPj5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIFByb2plY3QgbWFpbiBtZXRhZGF0YVxyXG4gICAgICAgKi9cclxuICAgICAgcHJvamVjdDogQ29tcHV0ZWRSZWY8T3B0aW9uYWw8R2V0PFZpZXdlckxvYWRlZFJlc291cmNlc1F1ZXJ5LCAncHJvamVjdCc+Pj5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIFZhcmlhYmxlcyB1c2VkIHRvIGxvYWQgdGhlIHJlc291cmNlIHF1ZXJ5LiBSZWxldmFudCB3aGVuIG1ha2luZyBjYWNoZSB1cGRhdGVzLlxyXG4gICAgICAgKi9cclxuICAgICAgcmVzb3VyY2VRdWVyeVZhcmlhYmxlczogQ29tcHV0ZWRSZWY8T3B0aW9uYWw8Vmlld2VyTG9hZGVkUmVzb3VyY2VzUXVlcnlWYXJpYWJsZXM+PlxyXG4gICAgICAvKipcclxuICAgICAgICogVmFyaWFibGVzIHVzZWQgdG8gbG9hZCB0aGUgdGhyZWFkcyBxdWVyeS4gUmVsZXZhbnQgd2hlbiBtYWtpbmcgY2FjaGUgdXBkYXRlcy5cclxuICAgICAgICovXHJcbiAgICAgIHRocmVhZHNRdWVyeVZhcmlhYmxlczogQ29tcHV0ZWRSZWY8T3B0aW9uYWw8Vmlld2VyTG9hZGVkVGhyZWFkc1F1ZXJ5VmFyaWFibGVzPj5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIEZldGNoIHRoZSBuZXh0IHBhZ2Ugb2YgdmVyc2lvbnMgZm9yIGEgbG9hZGVkIG1vZGVsXHJcbiAgICAgICAqL1xyXG4gICAgICBsb2FkTW9yZVZlcnNpb25zOiAobW9kZWxJZDogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+XHJcbiAgICAgIHJlc291cmNlc0xvYWRpbmc6IENvbXB1dGVkUmVmPGJvb2xlYW4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBMb2FkZWQgc2F2ZWQgdmlldywgaWYgYW55XHJcbiAgICAgICAqL1xyXG4gICAgICBzYXZlZFZpZXc6IENvbXB1dGVkUmVmPE9wdGlvbmFsPExvYWRlZFNhdmVkVmlldz4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBXaGV0aGVyIHdlJ3JlIGluIGEgZmVkZXJhdGVkIHZpZXcgLSBsb2FkaW5nIG11bHRpcGxlIG1vZGVscy9vYmplY3RzLiBXZSBqdWRnZSBieSB0aGUgYWN0dWFsXHJcbiAgICAgICAqIHJlc291cmNlcyBiZWluZyBsb2FkZWQgbm90IGp1c3QgdGhlIHJlc291cmNlSWRTdHJpbmcuIFRoZSBzdHJpbmcgY291bGQgcmVmZXIgdG8gbXVsdGlwbGUgbW9kZWxzLFxyXG4gICAgICAgKiBidXQgaWYgbm9uZSBvZiB0aGVtIGFjdHVhbGx5IGV4aXN0IGFuZCBhcmUgbG9hZGVkIHRoZW4gSSB3b3VsZG4ndCBjb3VudCB0aGF0IGFzIGEgZmVkZXJhdGVkIHZpZXcuXHJcbiAgICAgICAqL1xyXG4gICAgICBpc0ZlZGVyYXRlZFZpZXc6IENvbXB1dGVkUmVmPGJvb2xlYW4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBXZSBkb24ndCB3YW50IHRvIHNhdmUgYSBjb21tZW50IG9yIHZpZXcgdy8gaW1wbGljaXQgaWRlbnRpZmllcnMgbGlrZSBvbmVzIHRoYXQgb25seSBoYXZlIGEgbW9kZWwgSUQgb3IgYSBmb2xkZXIgcHJlZml4LCBiZWNhdXNlXHJcbiAgICAgICAqIHRob3NlIGNhbiByZXNvbHZlIHRvIGNvbXBsZXRlbHkgZGlmZmVyZW50IHZlcnNpb25zL29iamVjdHMgYXMgdGltZSBnb2VzIG9uXHJcbiAgICAgICAqL1xyXG4gICAgICBjb25jcmV0ZVJlc291cmNlSWRTdHJpbmc6IENvbXB1dGVkUmVmPHN0cmluZz5cclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogSW50ZXJmYWNlIHN0YXRlXHJcbiAgICovXHJcbiAgdWk6IHtcclxuICAgIC8qKlxyXG4gICAgICogVGhyZWFkIGFuZCB0aGVpciBidWJibGUgc3RhdGVcclxuICAgICAqL1xyXG4gICAgdGhyZWFkczoge1xyXG4gICAgICAvKipcclxuICAgICAgICogQ29tbWVudCBidWJibGUgbW9kZWxzIGtleWVkIGJ5IGNvbW1lbnQgSURcclxuICAgICAgICovXHJcbiAgICAgIGl0ZW1zOiBSZWY8UmVjb3JkPHN0cmluZywgQ29tbWVudEJ1YmJsZU1vZGVsPj5cclxuICAgICAgb3BlblRocmVhZDoge1xyXG4gICAgICAgIHRocmVhZDogQ29tcHV0ZWRSZWY8T3B0aW9uYWw8Q29tbWVudEJ1YmJsZU1vZGVsPj5cclxuICAgICAgICBpc1R5cGluZzogUmVmPGJvb2xlYW4+XHJcbiAgICAgICAgbmV3VGhyZWFkRWRpdG9yOiBSZWY8Ym9vbGVhbj5cclxuICAgICAgfVxyXG4gICAgICBoaWRlQnViYmxlczogUmVmPGJvb2xlYW4+XHJcbiAgICB9XHJcbiAgICBzcG90bGlnaHRVc2VyU2Vzc2lvbklkOiBSZWY8TnVsbGFibGU8c3RyaW5nPj5cclxuICAgIGZpbHRlcnM6IHtcclxuICAgICAgaXNvbGF0ZWRPYmplY3RJZHM6IFJlZjxzdHJpbmdbXT5cclxuICAgICAgaGlkZGVuT2JqZWN0SWRzOiBSZWY8c3RyaW5nW10+XHJcbiAgICAgIHNlbGVjdGVkT2JqZWN0czogUmVmPFJhdzxTcGVja2xlT2JqZWN0PltdPlxyXG4gICAgICAvKipcclxuICAgICAgICogRm9yIHF1aWNrIG9iamVjdCBJRCBsb29rdXBzXHJcbiAgICAgICAqL1xyXG4gICAgICBzZWxlY3RlZE9iamVjdElkczogQ29tcHV0ZWRSZWY8U2V0PHN0cmluZz4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBTZXQgb2YgY3VycmVudGx5IGlzb2xhdGVkIG9iamVjdCBJRHMgZm9yIGVmZmljaWVudCBsb29rdXBzXHJcbiAgICAgICAqL1xyXG4gICAgICBpc29sYXRlZE9iamVjdHNTZXQ6IENvbXB1dGVkUmVmPFNldDxzdHJpbmc+IHwgbnVsbD5cclxuXHJcbiAgICAgIC8vIE11bHRpLWZpbHRlciBzeXN0ZW1cclxuICAgICAgcHJvcGVydHlGaWx0ZXJzOiBSZWY8RmlsdGVyRGF0YVtdPlxyXG4gICAgICBmaWx0ZXJlZE9iamVjdHNDb3VudDogUmVmPG51bWJlcj5cclxuICAgICAgaGFzQW55RmlsdGVyc0FwcGxpZWQ6IENvbXB1dGVkUmVmPGJvb2xlYW4+XHJcbiAgICAgIGFjdGl2ZUNvbG9yRmlsdGVySWQ6IFJlZjxzdHJpbmcgfCBudWxsPlxyXG4gICAgfVxyXG4gICAgY2FtZXJhOiB7XHJcbiAgICAgIHBvc2l0aW9uOiBSZWY8VmVjdG9yMz5cclxuICAgICAgdGFyZ2V0OiBSZWY8VmVjdG9yMz5cclxuICAgICAgaXNPcnRob1Byb2plY3Rpb246IFJlZjxib29sZWFuPlxyXG4gICAgfVxyXG4gICAgdmlld01vZGU6IHtcclxuICAgICAgbW9kZTogUmVmPFZpZXdNb2RlPlxyXG4gICAgICBlZGdlc0VuYWJsZWQ6IFJlZjxib29sZWFuPlxyXG4gICAgICBlZGdlc1dlaWdodDogUmVmPG51bWJlcj5cclxuICAgICAgb3V0bGluZU9wYWNpdHk6IFJlZjxudW1iZXI+XHJcbiAgICAgIGVkZ2VzQ29sb3I6IFJlZjx0eXBlb2YgZGVmYXVsdEVkZ2VDb2xvclZhbHVlIHwgbnVtYmVyPlxyXG4gICAgICBmaW5hbEVkZ2VzQ29sb3I6IENvbXB1dGVkUmVmPG51bWJlcj5cclxuICAgICAgZGVmYXVsdEVkZ2VzQ29sb3I6IENvbXB1dGVkUmVmPG51bWJlcj5cclxuICAgICAgcmVzZXRWaWV3TW9kZTogKCkgPT4gdm9pZFxyXG4gICAgfVxyXG4gICAgZGlmZjoge1xyXG4gICAgICBuZXdWZXJzaW9uOiBDb21wdXRlZFJlZjxWaWV3ZXJNb2RlbFZlcnNpb25DYXJkSXRlbUZyYWdtZW50IHwgdW5kZWZpbmVkPlxyXG4gICAgICBvbGRWZXJzaW9uOiBDb21wdXRlZFJlZjxWaWV3ZXJNb2RlbFZlcnNpb25DYXJkSXRlbUZyYWdtZW50IHwgdW5kZWZpbmVkPlxyXG4gICAgICB0aW1lOiBSZWY8bnVtYmVyPlxyXG4gICAgICBtb2RlOiBSZWY8VmlzdWFsRGlmZk1vZGU+XHJcbiAgICAgIHJlc3VsdDogU2hhbGxvd1JlZjxPcHRpb25hbDxEaWZmUmVzdWx0Pj4gLy9Db21wdXRlZFJlZjxPcHRpb25hbDxEaWZmUmVzdWx0Pj5cclxuICAgICAgZW5hYmxlZDogUmVmPGJvb2xlYW4+XHJcbiAgICB9XHJcbiAgICBzZWN0aW9uQm94OiBSZWY8TnVsbGFibGU8U2VjdGlvbkJveERhdGE+PlxyXG4gICAgc2VjdGlvbkJveENvbnRleHQ6IHtcbiAgICAgIHZpc2libGU6IFJlZjxib29sZWFuPlxuICAgICAgZWRpdGVkOiBSZWY8Ym9vbGVhbj5cbiAgICB9XG4gICAgd2luZG93U2VsZWN0aW9uOiB7XG4gICAgICBlbmFibGVkOiBSZWY8Ym9vbGVhbj5cbiAgICB9XG4gICAgaGlnaGxpZ2h0ZWRPYmplY3RJZHM6IFJlZjxzdHJpbmdbXT5cbiAgICBsaWdodENvbmZpZzogUmVmPFN1bkxpZ2h0Q29uZmlndXJhdGlvbj5cclxuICAgIGV4cGxvZGVGYWN0b3I6IFJlZjxudW1iZXI+XHJcbiAgICBsb2FkaW5nOiBXcml0YWJsZUNvbXB1dGVkUmVmPGJvb2xlYW4+XHJcbiAgICBsb2FkUHJvZ3Jlc3M6IFJlZjxudW1iZXI+XHJcbiAgICAvKipcclxuICAgICAqIFNpbWlsYXIgdG8gaGFzRG9uZUluaXRpYWxMb2FkLCBidXQgYWxzbyB1cGRhdGVkIGZvciBmb2xsb3dpbmcgbG9hZHMuIFVzZWZ1bCBmb3IgdHJhY2tpbmdcclxuICAgICAqIGlmIGFuIGVudGlyZSBzZXQgb2YgbW9kZWxzIChlLmcuIGZlZGVyYXRlZCB2aWV3KSBoYXMgbG9hZGVkLlxyXG4gICAgICovXHJcbiAgICBoYXNMb2FkZWRRdWV1ZWRVcE1vZGVsczogUmVmPGJvb2xlYW4+XHJcbiAgICBzZWxlY3Rpb246IFJlZjxOdWxsYWJsZTxWZWN0b3IzPj5cclxuICAgIG1lYXN1cmVtZW50OiB7XHJcbiAgICAgIGVuYWJsZWQ6IFJlZjxib29sZWFuPlxyXG4gICAgICBvcHRpb25zOiBSZWY8TWVhc3VyZW1lbnRPcHRpb25zPlxyXG4gICAgICBtZWFzdXJlbWVudHM6IFJlZjxBcnJheTxNZWFzdXJlbWVudERhdGE+PlxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBWYXJpb3VzIHNhdmVkIHZpZXdzIFVJIHNldHRpbmdzXHJcbiAgICAgKi9cclxuICAgIHNhdmVkVmlld3M6IFNhdmVkVmlld3NVSVN0YXRlXHJcbiAgICAvKipcclxuICAgICAqIE9wZW5lZCB2aWV3ZXIgcGFuZWwgc2V0dGluZ3NcclxuICAgICAqL1xyXG4gICAgcGFuZWxzOiB7XHJcbiAgICAgIGFjdGl2ZTogUmVmPEFjdGl2ZVBhbmVsPlxyXG4gICAgICBtb2RlbHNTdWJWaWV3OiBSZWY8TW9kZWxzU3ViVmlldz5cclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogU3RhdGUgc3RvcmVkIGluIHRoZSBhbmNob3Igc3RyaW5nIG9mIHRoZSBVUkxcclxuICAgKi9cclxuICB1cmxIYXNoU3RhdGU6IHtcclxuICAgIGZvY3VzZWRUaHJlYWRJZDogQXN5bmNXcml0YWJsZUNvbXB1dGVkUmVmPE51bGxhYmxlPHN0cmluZz4+XHJcbiAgICBkaWZmOiBBc3luY1dyaXRhYmxlQ29tcHV0ZWRSZWY8TnVsbGFibGU8RGlmZlN0YXRlQ29tbWFuZD4+XHJcbiAgICAvKipcclxuICAgICAqIENvcmUgc291cmNlIG9mIHRydXRoIGlzIHVuZGVyIGByZXNvdXJjZXMucmVxdWVzdC5zYXZlZFZpZXdgLCBidXQgdGhpcyBhbGxvd3NcclxuICAgICAqIHRoZSBzYXZlZCB2aWV3IHNldHRpbmdzIHRvIGJlIFVSTCBjb250cm9sbGVkXHJcbiAgICAgKi9cclxuICAgIHNhdmVkVmlldzogQXN5bmNXcml0YWJsZUNvbXB1dGVkUmVmPE51bGxhYmxlPFNhdmVkVmlld1VybFNldHRpbmdzPj5cclxuICB9XHJcbn0+XHJcblxyXG50eXBlIENhY2hlZFZpZXdlclN0YXRlID0gUGljazxcclxuICBJbmplY3RhYmxlVmlld2VyU3RhdGVbJ3ZpZXdlciddLFxyXG4gICdjb250YWluZXInIHwgJ2luc3RhbmNlJ1xyXG4+ICYge1xyXG4gIGluaXRQcm9taXNlOiBQcm9taXNlPHZvaWQ+XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIEluaXRpYWxTZXR1cFN0YXRlID0gUGljazxcclxuICBJbmplY3RhYmxlVmlld2VyU3RhdGUsXHJcbiAgJ3Byb2plY3RJZCcgfCAndmlld2VyJyB8ICdzZXNzaW9uSWQnIHwgJ3VybEhhc2hTdGF0ZScgfCAncGFnZVR5cGUnXHJcbj5cclxuXHJcbnR5cGUgSW5pdGlhbFN0YXRlV2l0aFJlcXVlc3QgPSBJbml0aWFsU2V0dXBTdGF0ZSAmIHtcclxuICByZXNvdXJjZXM6IHsgcmVxdWVzdDogSW5qZWN0YWJsZVZpZXdlclN0YXRlWydyZXNvdXJjZXMnXVsncmVxdWVzdCddIH1cclxufVxyXG5cclxuZXhwb3J0IHR5cGUgSW5pdGlhbFN0YXRlV2l0aFJlcXVlc3RBbmRSZXNwb25zZSA9IEluaXRpYWxTZXR1cFN0YXRlICZcclxuICBQaWNrPEluamVjdGFibGVWaWV3ZXJTdGF0ZSwgJ3Jlc291cmNlcyc+XHJcblxyXG5leHBvcnQgdHlwZSBJbml0aWFsU3RhdGVXaXRoVXJsSGFzaFN0YXRlID0gSW5pdGlhbFN0YXRlV2l0aFJlcXVlc3RBbmRSZXNwb25zZVxyXG5cclxuZXhwb3J0IHR5cGUgSW5pdGlhbFN0YXRlV2l0aEludGVyZmFjZSA9IEluaXRpYWxTdGF0ZVdpdGhVcmxIYXNoU3RhdGUgJlxyXG4gIFBpY2s8SW5qZWN0YWJsZVZpZXdlclN0YXRlLCAndWknPlxyXG5cclxuLyoqXHJcbiAqIFNjb3BlZCBzdGF0ZSBrZXkgZm9yICd2aWV3ZXInIG1ldGFkYXRhLCBhcyB3ZSByZXVzZSBpdCBiZXR3ZWVuIHJvdXRlc1xyXG4gKi9cclxuY29uc3QgR2xvYmFsVmlld2VyRGF0YUtleSA9IFN5bWJvbCgnR2xvYmFsVmlld2VyRGF0YScpXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVWaWV3ZXJEYXRhQnVpbGRlcihwYXJhbXM6IHsgdmlld2VyRGVidWc6IGJvb2xlYW4gfSkge1xyXG4gIHJldHVybiAoKSA9PiB7XHJcbiAgICBpZiAoaW1wb3J0Lm1ldGEuc2VydmVyKVxyXG4gICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIHVzZSBudWxsYWJsZSBjaGVja3MgZXZlcnl3aGVyZSwgc28gdGhlIG5pY2VyIHJvdXRlIGhlcmUgZW5kc1xyXG4gICAgICAvLyB1cCBiZWluZyB0ZWxsaW5nIFRTIHRvIGlnbm9yZSB0aGUgdW5kZWZpbmVkcyAtIHlvdSBzaG91bGRuJ3QgdXNlIGFueSBvZiB0aGlzIGluIFNTUiBhbnl3YXlcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIENhY2hlZFZpZXdlclN0YXRlXHJcblxyXG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcclxuICAgIGNvbnRhaW5lci5pZCA9ICdyZW5kZXJlcidcclxuICAgIGNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xyXG4gICAgY29udGFpbmVyLnN0eWxlLndpZHRoID0gJzEwMCUnXHJcbiAgICBjb250YWluZXIuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnXHJcblxyXG4gICAgY29uc3Qgdmlld2VyID0gbmV3IExlZ2FjeVZpZXdlcihjb250YWluZXIsIHtcclxuICAgICAgLi4uRGVmYXVsdFZpZXdlclBhcmFtcyxcclxuICAgICAgdmVyYm9zZTogISEoaW1wb3J0Lm1ldGEuY2xpZW50ICYmIHBhcmFtcy52aWV3ZXJEZWJ1ZylcclxuICAgIH0pXHJcbiAgICB2aWV3ZXIuY3JlYXRlRXh0ZW5zaW9uKEhpZ2hsaWdodEV4dGVuc2lvbilcclxuICAgIHZpZXdlci5jcmVhdGVFeHRlbnNpb24oUGFzc1JlYWRlcilcclxuICAgIGNvbnN0IGluaXRQcm9taXNlID0gdmlld2VyLmluaXQoKVxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGluc3RhbmNlOiB2aWV3ZXIsXHJcbiAgICAgIGNvbnRhaW5lcixcclxuICAgICAgaW5pdFByb21pc2VcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldHVwVmlld2VyTWV0YWRhdGEocGFyYW1zOiB7XHJcbiAgdmlld2VyOiBWaWV3ZXJcclxufSk6IEluaXRpYWxTZXR1cFN0YXRlWyd2aWV3ZXInXVsnbWV0YWRhdGEnXSB7XHJcbiAgY29uc3QgeyB2aWV3ZXIgfSA9IHBhcmFtc1xyXG5cclxuICBjb25zdCB3b3JsZFRyZWUgPSBzaGFsbG93UmVmKHVuZGVmaW5lZCBhcyBPcHRpb25hbDxXb3JsZFRyZWU+KVxyXG4gIGNvbnN0IGZpbHRlcmluZ1N0YXRlID0gc2hhbGxvd1JlZih1bmRlZmluZWQgYXMgT3B0aW9uYWw8RmlsdGVyaW5nU3RhdGU+KVxyXG4gIGNvbnN0IHZpZXdzID0gcmVmKFtdIGFzIFNwZWNrbGVWaWV3W10pXHJcblxyXG4gIGNvbnN0IGZpbHRlcmluZ0RhdGFTdG9yZSA9IHVzZUNyZWF0ZVZpZXdlckZpbHRlcmluZ0RhdGFTdG9yZSgpXHJcblxyXG4gIGNvbnN0IHJlZnJlc2hXb3JsZFRyZWVBbmRGaWx0ZXJzID0gYXN5bmMgKCkgPT4ge1xyXG4gICAgd29ybGRUcmVlLnZhbHVlID0gdmlld2VyLmdldFdvcmxkVHJlZSgpXHJcbiAgICB2aWV3cy52YWx1ZSA9IHZpZXdlci5nZXRWaWV3cygpXHJcbiAgfVxyXG4gIGNvbnN0IHVwZGF0ZUZpbHRlcmluZ1N0YXRlID0gKG5ld1N0YXRlOiBNYXliZU51bGxPclVuZGVmaW5lZDxGaWx0ZXJpbmdTdGF0ZT4pID0+IHtcclxuICAgIC8vIHRyZWF0aW5nIHt9LCBudWxsLCB1bmRlZmluZWQgYXMgdGhlIHNhbWUsIHRvIGF2b2lkIHVubmVjZXNzYXJ5IHVwZGF0ZXNcclxuICAgIGZpbHRlcmluZ1N0YXRlLnZhbHVlID1cclxuICAgICAgbmV3U3RhdGUgJiYgT2JqZWN0LmtleXMobmV3U3RhdGUpLmxlbmd0aCA+IDAgPyBuZXdTdGF0ZSA6IHVuZGVmaW5lZFxyXG4gIH1cclxuXHJcbiAgb25Nb3VudGVkKCgpID0+IHtcclxuICAgIHZpZXdlci5vbihWaWV3ZXJFdmVudC5Mb2FkQ29tcGxldGUsIHJlZnJlc2hXb3JsZFRyZWVBbmRGaWx0ZXJzKVxyXG4gICAgdmlld2VyXHJcbiAgICAgIC5nZXRFeHRlbnNpb24oRmlsdGVyaW5nRXh0ZW5zaW9uKVxyXG4gICAgICAub24oVmlld2VyRXZlbnQuRmlsdGVyaW5nU3RhdGVTZXQsIHVwZGF0ZUZpbHRlcmluZ1N0YXRlKVxyXG4gIH0pXHJcblxyXG4gIG9uQmVmb3JlVW5tb3VudCgoKSA9PiB7XHJcbiAgICB2aWV3ZXIucmVtb3ZlTGlzdGVuZXIoVmlld2VyRXZlbnQuTG9hZENvbXBsZXRlLCByZWZyZXNoV29ybGRUcmVlQW5kRmlsdGVycylcclxuICAgIHZpZXdlclxyXG4gICAgICAuZ2V0RXh0ZW5zaW9uKEZpbHRlcmluZ0V4dGVuc2lvbilcclxuICAgICAgLnJlbW92ZUxpc3RlbmVyKFZpZXdlckV2ZW50LkZpbHRlcmluZ1N0YXRlU2V0LCB1cGRhdGVGaWx0ZXJpbmdTdGF0ZSlcclxuICB9KVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgd29ybGRUcmVlOiBjb21wdXRlZCgoKSA9PiB3b3JsZFRyZWUudmFsdWUpLFxyXG4gICAgZmlsdGVyaW5nU3RhdGU6IGNvbXB1dGVkKCgpID0+IGZpbHRlcmluZ1N0YXRlLnZhbHVlKSxcclxuICAgIHZpZXdzOiBjb21wdXRlZCgoKSA9PiB2aWV3cy52YWx1ZSksXHJcbiAgICBmaWx0ZXJpbmdEYXRhU3RvcmVcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTZXR1cCBhY3R1YWwgdmlld2VyIGluc3RhbmNlICYgcmVsYXRlZCBkYXRhXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXR1cEluaXRpYWxTdGF0ZShwYXJhbXM6IFVzZVNldHVwVmlld2VyUGFyYW1zKTogSW5pdGlhbFNldHVwU3RhdGUge1xyXG4gIGNvbnN0IHtcclxuICAgIHB1YmxpYzogeyB2aWV3ZXJEZWJ1ZyB9XHJcbiAgfSA9IHVzZVJ1bnRpbWVDb25maWcoKVxyXG5cclxuICBjb25zdCByb3V0ZSA9IHVzZVJvdXRlKClcclxuICBjb25zdCBzZXNzaW9uSWQgPSBjb21wdXRlZCgoKSA9PiBuYW5vaWQoKSlcclxuICBjb25zdCBpc0luaXRpYWxpemVkID0gcmVmKGZhbHNlKVxyXG4gIGNvbnN0IHsgaW5zdGFuY2UsIGluaXRQcm9taXNlLCBjb250YWluZXIgfSA9IHVzZVNjb3BlZFN0YXRlKFxyXG4gICAgR2xvYmFsVmlld2VyRGF0YUtleSxcclxuICAgIGNyZWF0ZVZpZXdlckRhdGFCdWlsZGVyKHtcclxuICAgICAgdmlld2VyRGVidWc6IHZpZXdlckRlYnVnIHx8IHJvdXRlLnF1ZXJ5LnZpZXdlclZlcmJvc2UgPT09ICcxJ1xyXG4gICAgfSlcclxuICApIHx8IHsgaW5pdFByb21pc2U6IFByb21pc2UucmVzb2x2ZSgpIH1cclxuICBpbml0UHJvbWlzZS50aGVuKCgpID0+IChpc0luaXRpYWxpemVkLnZhbHVlID0gdHJ1ZSkpXHJcbiAgY29uc3QgaGFzRG9uZUluaXRpYWxMb2FkID0gcmVmKGZhbHNlKVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgcGFnZVR5cGU6IGNvbXB1dGVkKCgpID0+IHBhcmFtcy5wYWdlVHlwZSksXHJcbiAgICBwcm9qZWN0SWQ6IHBhcmFtcy5wcm9qZWN0SWQsXHJcbiAgICBzZXNzaW9uSWQsXHJcbiAgICB2aWV3ZXI6IGltcG9ydC5tZXRhLnNlcnZlclxyXG4gICAgICA/ICh7XHJcbiAgICAgICAgICBpbnN0YW5jZTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgY29udGFpbmVyOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICBpbml0OiB7XHJcbiAgICAgICAgICAgIHByb21pc2U6IG5ldyBQcm9taXNlKCgpID0+IHt9KSxcclxuICAgICAgICAgICAgcmVmOiBjb21wdXRlZCgoKSA9PiBmYWxzZSlcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBtZXRhZGF0YToge1xyXG4gICAgICAgICAgICB3b3JsZFRyZWU6IGNvbXB1dGVkKCgpID0+IHVuZGVmaW5lZCksXHJcbiAgICAgICAgICAgIHZpZXdzOiBjb21wdXRlZCgoKSA9PiBbXSksXHJcbiAgICAgICAgICAgIGZpbHRlcmluZ1N0YXRlOiBjb21wdXRlZCgoKSA9PiB1bmRlZmluZWQpXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgaGFzRG9uZUluaXRpYWxMb2FkXHJcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIEluaXRpYWxTZXR1cFN0YXRlWyd2aWV3ZXInXSlcclxuICAgICAgOiB7XHJcbiAgICAgICAgICBpbnN0YW5jZSxcclxuICAgICAgICAgIGNvbnRhaW5lcixcclxuICAgICAgICAgIGluaXQ6IHtcclxuICAgICAgICAgICAgcHJvbWlzZTogaW5pdFByb21pc2UsXHJcbiAgICAgICAgICAgIHJlZjogY29tcHV0ZWQoKCkgPT4gaXNJbml0aWFsaXplZC52YWx1ZSlcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBtZXRhZGF0YTogc2V0dXBWaWV3ZXJNZXRhZGF0YSh7IHZpZXdlcjogaW5zdGFuY2UgfSksXHJcbiAgICAgICAgICBoYXNEb25lSW5pdGlhbExvYWRcclxuICAgICAgICB9LFxyXG4gICAgdXJsSGFzaFN0YXRlOiBzZXR1cFVybEhhc2hTdGF0ZSgpXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogU2V0dXAgcmVzb3VyY2UgcmVxdWVzdHMgKHRpZWQgdG8gVVJMIHJlc291cmNlIGlkZW50aWZpZXIgcGFyYW0pXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXR1cFJlc291cmNlUmVxdWVzdChcclxuICBzdGF0ZTogSW5pdGlhbFNldHVwU3RhdGUsXHJcbiAgcGFyYW1zOiBVc2VTZXR1cFZpZXdlclBhcmFtc1xyXG4pOiBJbml0aWFsU3RhdGVXaXRoUmVxdWVzdCB7XHJcbiAgY29uc3QgcmVzb3VyY2VJZFN0cmluZyA9IHBhcmFtcy5yZXNvdXJjZUlkU3RyaW5nXHJcblxyXG4gIGNvbnN0IHJlc291cmNlcyA9IHdyaXRhYmxlQXN5bmNDb21wdXRlZCh7XHJcbiAgICBnZXQ6ICgpID0+IHJlc291cmNlQnVpbGRlcigpLmFkZFJlc291cmNlcyhyZXNvdXJjZUlkU3RyaW5nLnZhbHVlKS50b1Jlc291cmNlcygpLFxyXG4gICAgc2V0OiBhc3luYyAobmV3UmVzb3VyY2VzKSA9PiB7XHJcbiAgICAgIGNvbnN0IG5ld0lkU3RyaW5nID0gY3JlYXRlR2V0UGFyYW1Gcm9tUmVzb3VyY2VzKG5ld1Jlc291cmNlcylcclxuICAgICAgYXdhaXQgcmVzb3VyY2VJZFN0cmluZy51cGRhdGUobmV3SWRTdHJpbmcpXHJcbiAgICB9LFxyXG4gICAgaW5pdGlhbFN0YXRlOiBbXSxcclxuICAgIGFzeW5jUmVhZDogZmFsc2VcclxuICB9KVxyXG5cclxuICBjb25zdCBkaXNjdXNzaW9uTG9hZGVkVmVyc2lvbk9ubHkgPSB1c2VTeW5jaHJvbml6ZWRDb29raWU8Ym9vbGVhbj4oXHJcbiAgICAnZGlzY3Vzc2lvbkxvYWRlZFZlcnNpb25Pbmx5JyxcclxuICAgIHtcclxuICAgICAgZGVmYXVsdDogKCkgPT4gdHJ1ZVxyXG4gICAgfVxyXG4gIClcclxuXHJcbiAgY29uc3QgdGhyZWFkRmlsdGVycyA9IHJlZih7IGxvYWRlZFZlcnNpb25zT25seTogZGlzY3Vzc2lvbkxvYWRlZFZlcnNpb25Pbmx5LnZhbHVlIH0pXHJcblxyXG4gIGNvbnN0IHN3aXRjaE1vZGVsVG9WZXJzaW9uID0gYXN5bmMgKG1vZGVsSWQ6IHN0cmluZywgdmVyc2lvbklkPzogc3RyaW5nKSA9PiB7XHJcbiAgICBjb25zdCByZXNvdXJjZUFyciA9IHJlc291cmNlcy52YWx1ZS5zbGljZSgpXHJcblxyXG4gICAgY29uc3QgcmVzb3VyY2VJZHggPSByZXNvdXJjZUFyci5maW5kSW5kZXgoXHJcbiAgICAgIChyKSA9PiBpc01vZGVsUmVzb3VyY2UocikgJiYgci5tb2RlbElkID09PSBtb2RlbElkXHJcbiAgICApXHJcblxyXG4gICAgaWYgKHJlc291cmNlSWR4ICE9PSAtMSkge1xyXG4gICAgICAvLyBSZXBsYWNlXHJcbiAgICAgIGNvbnN0IG5ld1Jlc291cmNlcyA9IHJlc291cmNlcy52YWx1ZS5zbGljZSgpXHJcbiAgICAgIG5ld1Jlc291cmNlcy5zcGxpY2UocmVzb3VyY2VJZHgsIDEsIG5ldyBWaWV3ZXJNb2RlbFJlc291cmNlKG1vZGVsSWQsIHZlcnNpb25JZCkpXHJcblxyXG4gICAgICBhd2FpdCByZXNvdXJjZXMudXBkYXRlKG5ld1Jlc291cmNlcylcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIEFkZCBuZXcgb25lIGFuZCBhbGxvdyBkZS1kdXBsaWNhdGlvbiB0byBkbyBpdHMgdGhpbmdcclxuICAgICAgYXdhaXQgcmVzb3VyY2VzLnVwZGF0ZShbXHJcbiAgICAgICAgbmV3IFZpZXdlck1vZGVsUmVzb3VyY2UobW9kZWxJZCwgdmVyc2lvbklkKSxcclxuICAgICAgICAuLi5yZXNvdXJjZXMudmFsdWVcclxuICAgICAgXSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHdhdGNoKFxyXG4gICAgKCkgPT4gdGhyZWFkRmlsdGVycy52YWx1ZS5sb2FkZWRWZXJzaW9uc09ubHksXHJcbiAgICAobmV3VmFsLCBvbGRWYWwpID0+IHtcclxuICAgICAgaWYgKG5ld1ZhbCAhPT0gb2xkVmFsICYmIG5ld1ZhbCAhPT0gZGlzY3Vzc2lvbkxvYWRlZFZlcnNpb25Pbmx5LnZhbHVlKSB7XHJcbiAgICAgICAgZGlzY3Vzc2lvbkxvYWRlZFZlcnNpb25Pbmx5LnZhbHVlID0gbmV3VmFsXHJcbiAgICAgIH1cclxuICAgIH1cclxuICApXHJcblxyXG4gIHJldHVybiB7XHJcbiAgICAuLi5zdGF0ZSxcclxuICAgIHJlc291cmNlczoge1xyXG4gICAgICByZXF1ZXN0OiB7XHJcbiAgICAgICAgc2F2ZWRWaWV3OiB1c2VCdWlsZFNhdmVkVmlld3NDb3JlU3RhdGUoc3RhdGUsIHBhcmFtcyksXHJcbiAgICAgICAgaXRlbXM6IHJlc291cmNlcyxcclxuICAgICAgICByZXNvdXJjZUlkU3RyaW5nLFxyXG4gICAgICAgIHRocmVhZEZpbHRlcnMsXHJcbiAgICAgICAgc3dpdGNoTW9kZWxUb1ZlcnNpb25cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFBhcnNlIFVSTCByZXNvdXJjZSByZXF1ZXN0IGFuZCBmaWd1cmUgb3V0IHRoZSBhY3R1YWwgcmVzb3VyY2UgaXRlbXMgd2UgbmVlZCB0byBsb2FkIGluIHRoZSB2aWV3ZXJcclxuICogdGhyb3VnaCB0aGUgR1FMIEFQSVxyXG4gKi9cclxuZnVuY3Rpb24gc2V0dXBSZXNwb25zZVJlc291cmNlSXRlbXMoXHJcbiAgc3RhdGU6IEluaXRpYWxTdGF0ZVdpdGhSZXF1ZXN0XHJcbik6IFBpY2s8XHJcbiAgSW5qZWN0YWJsZVZpZXdlclN0YXRlWydyZXNvdXJjZXMnXVsncmVzcG9uc2UnXSxcclxuICB8ICdyZXNvdXJjZUl0ZW1zJ1xyXG4gIHwgJ3Jlc291cmNlSXRlbXNRdWVyeVZhcmlhYmxlcydcclxuICB8ICdyZXNvdXJjZUl0ZW1zTG9hZGVkJ1xyXG4gIHwgJ3NhdmVkVmlldydcclxuICB8ICdpc0ZlZGVyYXRlZFZpZXcnXHJcbiAgfCAncmVzb3VyY2VJdGVtc0V4dGVuZGVkJ1xyXG4gIHwgJ3Jlc291cmNlSXRlbXNJZHMnXHJcbiAgfCAnY29uY3JldGVSZXNvdXJjZUlkU3RyaW5nJ1xyXG4+IHtcclxuICBjb25zdCBnbG9iYWxFcnJvciA9IHVzZUVycm9yKClcclxuICBjb25zdCB7XHJcbiAgICBwcm9qZWN0SWQsXHJcbiAgICByZXNvdXJjZXM6IHtcclxuICAgICAgcmVxdWVzdDoge1xyXG4gICAgICAgIHJlc291cmNlSWRTdHJpbmcsXHJcbiAgICAgICAgc2F2ZWRWaWV3OiB7IGlkOiBzYXZlZFZpZXdJZCwgbG9hZE9yaWdpbmFsIH1cclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIHVybEhhc2hTdGF0ZTogeyBzYXZlZFZpZXc6IHVybEhhc2hTYXZlZFZpZXcgfVxyXG4gIH0gPSBzdGF0ZVxyXG5cclxuICBjb25zdCBpbml0TG9hZERvbmUgPSByZWYoaW1wb3J0Lm1ldGEuc2VydmVyID8gZmFsc2UgOiB0cnVlKVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlcyBhY3R1YWwgcmVzb3VyY2VzIHRvIGxvYWQ6XHJcbiAgICogLSBWaWV3ZXIgUmVzb3VyY2UgR3JvdXBzIGFuZCBpdGVtc1xyXG4gICAqIC0gU2F2ZWQgVmlldyB0aGF0IHdhcyB1c2VkLCBpZiBhbnlcclxuICAgKlxyXG4gICAqIEJvdGggbXVzdCBiZSBsb2FkZWQgdG9nZXRoZXIgdG8gYXZvaWQgcmFjZSBjb25kaXRpb25zLiBUaGV5IGJvdGggY2hhbmdlXHJcbiAgICogd2hhdCBleGFjdGx5IGVuZHMgdXAgYmVpbmcgbG9hZGVkLCBzbyBpdHMgaW1wb3J0YW50IHRoZXkncmUgaW4gc3luYy5cclxuICAgKi9cclxuICBjb25zdCB7XHJcbiAgICByZXN1bHQ6IHJlc29sdmVkUmVzb3VyY2VzUmVzdWx0LFxyXG4gICAgdmFyaWFibGVzOiByZXNvdXJjZUl0ZW1zUXVlcnlWYXJpYWJsZXMsXHJcbiAgICBvbkVycm9yLFxyXG4gICAgb25SZXN1bHRcclxuICB9ID0gdXNlUXVlcnkoXHJcbiAgICBwcm9qZWN0Vmlld2VyUmVzb3VyY2VzUXVlcnksXHJcbiAgICAoKSA9PiAoe1xyXG4gICAgICBwcm9qZWN0SWQ6IHByb2plY3RJZC52YWx1ZSxcclxuICAgICAgcmVzb3VyY2VVcmxTdHJpbmc6IHJlc291cmNlSWRTdHJpbmcudmFsdWUsXHJcbiAgICAgIC4uLihpc1VuZGVmaW5lZChzYXZlZFZpZXdJZC52YWx1ZSlcclxuICAgICAgICA/IHtcclxuICAgICAgICAgICAgLy8gT21pdCBlbnRpcmVseSBpZiB1bmRlZmluZWQgdG8gYWxsb3cgZm9yIGltcGxpY2l0L2hvbWUgdmlld3NcclxuICAgICAgICAgIH1cclxuICAgICAgICA6IHtcclxuICAgICAgICAgICAgLy8gTG9hZCBzcGVjaWZpYyBvciBsb2FkIE5PTkVcclxuICAgICAgICAgICAgc2F2ZWRWaWV3SWQ6IHNhdmVkVmlld0lkLnZhbHVlXHJcbiAgICAgICAgICB9KSxcclxuICAgICAgc2F2ZWRWaWV3U2V0dGluZ3M6IHtcclxuICAgICAgICBsb2FkT3JpZ2luYWw6IGxvYWRPcmlnaW5hbC52YWx1ZSB8fCBmYWxzZVxyXG4gICAgICB9XHJcbiAgICB9KSxcclxuICAgIHsga2VlcFByZXZpb3VzUmVzdWx0OiB0cnVlIH1cclxuICApXHJcblxyXG4gIG9uRXJyb3IoKGVycikgPT4ge1xyXG4gICAgZ2xvYmFsRXJyb3IudmFsdWUgPSBjcmVhdGVFcnJvcih7XHJcbiAgICAgIHN0YXR1c0NvZGU6IDUwMCxcclxuICAgICAgbWVzc2FnZTogYFZpZXdlciByZXNvdXJjZSByZXNvbHV0aW9uIGZhaWxlZDogJHtlcnJ9YFxyXG4gICAgfSlcclxuICAgIGluaXRMb2FkRG9uZS52YWx1ZSA9IHRydWVcclxuICB9KVxyXG5cclxuICBvblJlc3VsdChhc3luYyAocmVzKSA9PiB7XHJcbiAgICBpbml0TG9hZERvbmUudmFsdWUgPSB0cnVlXHJcblxyXG4gICAgY29uc3QgZGF0YSA9IHJlcy5kYXRhPy5wcm9qZWN0Py52aWV3ZXJSZXNvdXJjZXNFeHRlbmRlZFxyXG4gICAgaWYgKCFkYXRhKSByZXR1cm5cclxuXHJcbiAgICAvLyBJZiBzYXZlZCB2aWV3IHJlc29sdmVkLCB1cGRhdGUgcmVzb3VyY2VJZFN0cmluZyBmcm9tIHJlc3BvbnNlXHJcbiAgICAvLyBjYXVzZSBpdCBtYXkgaGF2ZSBjaGFuZ2VkXHJcbiAgICBjb25zdCBpbmNvbWluZ1Jlc291cmNlSWRTdHJpbmcgPSByZXNvdXJjZUJ1aWxkZXIoKS5hZGRSZXNvdXJjZXMoXHJcbiAgICAgIGRhdGEucmVzb3VyY2VJZFN0cmluZ1xyXG4gICAgKVxyXG4gICAgY29uc3QgZXhpc3RpbmcgPSByZXNvdXJjZUJ1aWxkZXIoKS5hZGRSZXNvdXJjZXMocmVzb3VyY2VJZFN0cmluZy52YWx1ZSlcclxuICAgIGlmICghaW5jb21pbmdSZXNvdXJjZUlkU3RyaW5nLmlzRXF1YWxUbyhleGlzdGluZykpIHtcclxuICAgICAgYXdhaXQgcmVzb3VyY2VJZFN0cmluZy51cGRhdGUoaW5jb21pbmdSZXNvdXJjZUlkU3RyaW5nLnRvU3RyaW5nKCkpXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgc2F2ZWRWaWV3SWQgcmVmZXJlZCB0byBhbiBpbnZhbGlkIG9uZVxyXG4gICAgaWYgKGRhdGEucmVxdWVzdD8uc2F2ZWRWaWV3SWQgJiYgZGF0YS5yZXF1ZXN0LnNhdmVkVmlld0lkICE9PSBkYXRhLnNhdmVkVmlldz8uaWQpIHtcclxuICAgICAgLy8gc3dpdGNoIHRvIFwibm8gdmlld1wiXHJcbiAgICAgIHNhdmVkVmlld0lkLnZhbHVlID0gbnVsbFxyXG4gICAgICB2b2lkIHVybEhhc2hTYXZlZFZpZXcudXBkYXRlKG51bGwpXHJcbiAgICB9XHJcbiAgfSlcclxuXHJcbiAgY29uc3QgcmVzb3VyY2VJdGVtc0V4dGVuZGVkID0gY29tcHV0ZWQoXHJcbiAgICAoKSA9PiByZXNvbHZlZFJlc291cmNlc1Jlc3VsdC52YWx1ZT8ucHJvamVjdD8udmlld2VyUmVzb3VyY2VzRXh0ZW5kZWRcclxuICApXHJcblxyXG4gIGNvbnN0IHJlc29sdmVkUmVzb3VyY2VHcm91cHMgPSBjb21wdXRlZChcclxuICAgICgpID0+IHJlc291cmNlSXRlbXNFeHRlbmRlZC52YWx1ZT8uZ3JvdXBzIHx8IFtdXHJcbiAgKVxyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZWQgJiBkZS1kdXBsaWNhdGVkIHJlc291cmNlcyB0aGF0IHNob3VsZCBiZSBsb2FkZWQgaW4gdGhlIHZpZXdlclxyXG4gICAqL1xyXG4gIGNvbnN0IHJlc291cmNlSXRlbXMgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICAvKipcclxuICAgICAqIEZsYXR0ZW4gcmVzdWx0cyBpbnRvIGFuIGFycmF5IG9mIGl0ZW1zIHRoYXQgYXJlIHByb3Blcmx5IG9yZGVyZWQgYWNjb3JkaW5nIHRvIHJlc291cmNlIGlkZW50aWZpZXIgcHJpb3JpdHkuXHJcbiAgICAgKiBMb2FkaW5nIHByaW9yaXR5OiBNb2RlbCB3LyB2ZXJzaW9uID4gTW9kZWwgPiBGb2xkZXIgbmFtZSA+IE9iamVjdCBJRFxyXG4gICAgICovXHJcbiAgICBjb25zdCB2ZXJzaW9uSXRlbXM6IFZpZXdlclJlc291cmNlSXRlbVtdID0gW11cclxuICAgIGNvbnN0IG1vZGVsSXRlbXM6IFZpZXdlclJlc291cmNlSXRlbVtdID0gW11cclxuICAgIGNvbnN0IGZvbGRlckl0ZW1zOiBWaWV3ZXJSZXNvdXJjZUl0ZW1bXSA9IFtdXHJcbiAgICBjb25zdCBvYmplY3RJdGVtczogVmlld2VyUmVzb3VyY2VJdGVtW10gPSBbXVxyXG4gICAgY29uc3QgYWxsTW9kZWxJdGVtczogVmlld2VyUmVzb3VyY2VJdGVtW10gPSBbXVxyXG4gICAgZm9yIChjb25zdCBncm91cCBvZiByZXNvbHZlZFJlc291cmNlR3JvdXBzLnZhbHVlKSB7XHJcbiAgICAgIGNvbnN0IFtyZXNvdXJjZV0gPSBwYXJzZVVybFBhcmFtZXRlcnMoZ3JvdXAuaWRlbnRpZmllcilcclxuXHJcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cC5pdGVtcykge1xyXG4gICAgICAgIGlmIChpc01vZGVsUmVzb3VyY2UocmVzb3VyY2UpKSB7XHJcbiAgICAgICAgICBpZiAocmVzb3VyY2UudmVyc2lvbklkKSB7XHJcbiAgICAgICAgICAgIHZlcnNpb25JdGVtcy5wdXNoKGl0ZW0pXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBtb2RlbEl0ZW1zLnB1c2goaXRlbSlcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGlzQWxsTW9kZWxzUmVzb3VyY2UocmVzb3VyY2UpKSB7XHJcbiAgICAgICAgICBhbGxNb2RlbEl0ZW1zLnB1c2goaXRlbSlcclxuICAgICAgICB9IGVsc2UgaWYgKGlzTW9kZWxGb2xkZXJSZXNvdXJjZShyZXNvdXJjZSkpIHtcclxuICAgICAgICAgIGZvbGRlckl0ZW1zLnB1c2goaXRlbSlcclxuICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0UmVzb3VyY2UocmVzb3VyY2UpKSB7XHJcbiAgICAgICAgICBvYmplY3RJdGVtcy5wdXNoKGl0ZW0pXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgb3JkZXJlZEl0ZW1zID0gW1xyXG4gICAgICAuLi52ZXJzaW9uSXRlbXMsXHJcbiAgICAgIC4uLm1vZGVsSXRlbXMsXHJcbiAgICAgIC4uLmZvbGRlckl0ZW1zLFxyXG4gICAgICAuLi5hbGxNb2RlbEl0ZW1zLFxyXG4gICAgICAuLi5vYmplY3RJdGVtc1xyXG4gICAgXVxyXG5cclxuICAgIC8vIEdldCByaWQgb2YgZHVwbGljYXRlcyAtIG9ubHkgMSByZXNvdXJjZSBwZXIgb2JqZWN0SWRcclxuICAgIGNvbnN0IGVuY291bnRlcmVkTW9kZWxzID0gbmV3IFNldDxzdHJpbmc+KClcclxuICAgIGNvbnN0IGVuY291bnRlcmVkT2JqZWN0cyA9IG5ldyBTZXQ8c3RyaW5nPigpXHJcbiAgICBjb25zdCBmaW5hbEl0ZW1zOiBWaWV3ZXJSZXNvdXJjZUl0ZW1bXSA9IFtdXHJcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2Ygb3JkZXJlZEl0ZW1zKSB7XHJcbiAgICAgIGNvbnN0IG1vZGVsSWQgPSBpdGVtLm1vZGVsSWRcclxuICAgICAgY29uc3Qgb2JqZWN0SWQgPSBpdGVtLm9iamVjdElkXHJcblxyXG4gICAgICAvLyBVbmNvbW1lbnRpbmcgdGhlIGZvbGxvd2luZyBsaW5lIHJlc29sdmVkIG1vZGVsIGR1cGxpY2F0aW9uIGlzc3VlcyBpbiB0aGUgTW9kZWwgUGFuZWxcclxuICAgICAgLy8gd2l0aG91dCBhZmZlY3RpbmcgZGlmZmluZyBmdW5jdGlvbmFsaXR5LiBJZiBmdXR1cmUgZGlmZmluZyBwcm9ibGVtcyBhcmlzZSwgcmV2aXNpdCB0aGlzLlxyXG4gICAgICBpZiAobW9kZWxJZCAmJiBlbmNvdW50ZXJlZE1vZGVscy5oYXMobW9kZWxJZCkpIGNvbnRpbnVlXHJcbiAgICAgIGlmIChlbmNvdW50ZXJlZE9iamVjdHMuaGFzKG9iamVjdElkKSkgY29udGludWVcclxuXHJcbiAgICAgIGZpbmFsSXRlbXMucHVzaChpdGVtKVxyXG4gICAgICBpZiAobW9kZWxJZCkgZW5jb3VudGVyZWRNb2RlbHMuYWRkKG1vZGVsSWQpXHJcbiAgICAgIGVuY291bnRlcmVkT2JqZWN0cy5hZGQob2JqZWN0SWQpXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGZpbmFsSXRlbXNcclxuICB9KVxyXG5cclxuICBjb25zdCByZXNvdXJjZUl0ZW1zSWRzID0gY29tcHV0ZWQoKCkgPT5cclxuICAgIHJlc291cmNlSXRlbXMudmFsdWUubWFwKChpKSA9PiB7XHJcbiAgICAgIGlmIChpLm1vZGVsSWQpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFZpZXdlck1vZGVsUmVzb3VyY2UoaS5tb2RlbElkLCBpLnZlcnNpb25JZCB8fCB1bmRlZmluZWQpLnRvU3RyaW5nKClcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gbmV3IFZpZXdlck9iamVjdFJlc291cmNlKGkub2JqZWN0SWQpLnRvU3RyaW5nKClcclxuICAgICAgfVxyXG4gICAgfSlcclxuICApXHJcbiAgY29uc3QgcmVzb3VyY2VJdGVtc0xvYWRlZCA9IGNvbXB1dGVkKCgpID0+IGluaXRMb2FkRG9uZS52YWx1ZSlcclxuXHJcbiAgY29uc3Qgc2F2ZWRWaWV3ID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgaWRUb0xvYWQgPSBzYXZlZFZpZXdJZC52YWx1ZVxyXG4gICAgY29uc3QgaWRMb2FkZWQgPVxyXG4gICAgICByZXNvbHZlZFJlc291cmNlc1Jlc3VsdC52YWx1ZT8ucHJvamVjdD8udmlld2VyUmVzb3VyY2VzRXh0ZW5kZWQuc2F2ZWRWaWV3Py5pZFxyXG4gICAgY29uc3Qgc2F2ZWRWaWV3RnJvbVJlcyA9XHJcbiAgICAgIHJlc29sdmVkUmVzb3VyY2VzUmVzdWx0LnZhbHVlPy5wcm9qZWN0Py52aWV3ZXJSZXNvdXJjZXNFeHRlbmRlZC5zYXZlZFZpZXcgfHxcclxuICAgICAgdW5kZWZpbmVkXHJcblxyXG4gICAgaWYgKGlkVG9Mb2FkICYmIGlkVG9Mb2FkICE9PSBpZExvYWRlZCkgcmV0dXJuIHVuZGVmaW5lZCAvLyBzdGFsZSBxdWVyeVxyXG4gICAgaWYgKCFpZFRvTG9hZCAmJiAhaWRMb2FkZWQpIHJldHVybiBzYXZlZFZpZXdGcm9tUmVzIC8vIGNvdWxkIGJlIGhvbWUgdmlld1xyXG5cclxuICAgIHJldHVybiBzYXZlZFZpZXdGcm9tUmVzXHJcbiAgfSlcclxuXHJcbiAgY29uc3QgaXNGZWRlcmF0ZWRWaWV3ID0gY29tcHV0ZWQoKCkgPT4gcmVzb3VyY2VJdGVtcy52YWx1ZS5sZW5ndGggPiAxKVxyXG4gIGNvbnN0IGNvbmNyZXRlUmVzb3VyY2VJZFN0cmluZyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIGNvbnN0IGJ1aWxkZXIgPSByZXNvdXJjZUJ1aWxkZXIoKVxyXG5cclxuICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VJdGVtcy52YWx1ZSkge1xyXG4gICAgICBpZiAocmVzb3VyY2UubW9kZWxJZCAmJiByZXNvdXJjZS52ZXJzaW9uSWQpIHtcclxuICAgICAgICBidWlsZGVyLmFkZE1vZGVsKHJlc291cmNlLm1vZGVsSWQsIHJlc291cmNlLnZlcnNpb25JZClcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBidWlsZGVyLmFkZE9iamVjdChyZXNvdXJjZS5vYmplY3RJZClcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGZpbmFsU3RyaW5nID0gYnVpbGRlci50b1N0cmluZygpXHJcbiAgICByZXR1cm4gZmluYWxTdHJpbmcgfHwgcmVzb3VyY2VJZFN0cmluZy52YWx1ZVxyXG4gIH0pXHJcblxyXG4gIHJldHVybiB7XHJcbiAgICByZXNvdXJjZUl0ZW1zRXh0ZW5kZWQsXHJcbiAgICByZXNvdXJjZUl0ZW1zSWRzLFxyXG4gICAgcmVzb3VyY2VJdGVtcyxcclxuICAgIHJlc291cmNlSXRlbXNRdWVyeVZhcmlhYmxlczogY29tcHV0ZWQoKCkgPT4gcmVzb3VyY2VJdGVtc1F1ZXJ5VmFyaWFibGVzLnZhbHVlKSxcclxuICAgIHJlc291cmNlSXRlbXNMb2FkZWQsXHJcbiAgICBzYXZlZFZpZXcsXHJcbiAgICBpc0ZlZGVyYXRlZFZpZXcsXHJcbiAgICBjb25jcmV0ZVJlc291cmNlSWRTdHJpbmdcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldHVwUmVzcG9uc2VSZXNvdXJjZURhdGEoXHJcbiAgc3RhdGU6IEluaXRpYWxTdGF0ZVdpdGhSZXF1ZXN0LFxyXG4gIHJlc291cmNlSXRlbXNEYXRhOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXR1cFJlc3BvbnNlUmVzb3VyY2VJdGVtcz5cclxuKTogUGljazxcclxuICBJbmplY3RhYmxlVmlld2VyU3RhdGVbJ3Jlc291cmNlcyddWydyZXNwb25zZSddLFxyXG4gIHwgJ29iamVjdHMnXHJcbiAgfCAnY29tbWVudFRocmVhZHMnXHJcbiAgfCAnY29tbWVudFRocmVhZHNNZXRhZGF0YSdcclxuICB8ICdtb2RlbHNBbmRWZXJzaW9uSWRzJ1xyXG4gIHwgJ2F2YWlsYWJsZU1vZGVsc0FuZFZlcnNpb25zJ1xyXG4gIHwgJ3Byb2plY3QnXHJcbiAgfCAncmVzb3VyY2VRdWVyeVZhcmlhYmxlcydcclxuICB8ICd0aHJlYWRzUXVlcnlWYXJpYWJsZXMnXHJcbiAgfCAnbG9hZE1vcmVWZXJzaW9ucydcclxuICB8ICdyZXNvdXJjZXNMb2FkZWQnXHJcbiAgfCAncmVzb3VyY2VzTG9hZGluZydcclxuPiB7XHJcbiAgY29uc3QgYXBvbGxvID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgZ2xvYmFsRXJyb3IgPSB1c2VFcnJvcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgbG9nZ2VyID0gdXNlTG9nZ2VyKClcclxuXHJcbiAgY29uc3Qge1xyXG4gICAgcHJvamVjdElkLFxyXG4gICAgcmVzb3VyY2VzOiB7XHJcbiAgICAgIHJlcXVlc3Q6IHsgcmVzb3VyY2VJZFN0cmluZywgdGhyZWFkRmlsdGVycyB9XHJcbiAgICB9LFxyXG4gICAgdXJsSGFzaFN0YXRlOiB7IGRpZmYgfVxyXG4gIH0gPSBzdGF0ZVxyXG4gIGNvbnN0IHsgcmVzb3VyY2VJdGVtcywgcmVzb3VyY2VJdGVtc0xvYWRlZCB9ID0gcmVzb3VyY2VJdGVtc0RhdGFcclxuXHJcbiAgY29uc3QgaW5pdExvYWREb25lID0gcmVmKGltcG9ydC5tZXRhLnNlcnZlciA/IGZhbHNlIDogdHJ1ZSlcclxuICBjb25zdCBvYmplY3RzID0gY29tcHV0ZWQoKCkgPT5cclxuICAgIHJlc291cmNlSXRlbXMudmFsdWUuZmlsdGVyKChpKSA9PiAhaS5tb2RlbElkICYmICFpLnZlcnNpb25JZClcclxuICApXHJcblxyXG4gIGNvbnN0IG5vbk9iamVjdFJlc291cmNlSXRlbXMgPSBjb21wdXRlZCgoKSA9PlxyXG4gICAgcmVzb3VyY2VJdGVtcy52YWx1ZS5maWx0ZXIoXHJcbiAgICAgIChyKTogciBpcyBWaWV3ZXJSZXNvdXJjZUl0ZW0gJiB7IG1vZGVsSWQ6IHN0cmluZzsgdmVyc2lvbklkOiBzdHJpbmcgfSA9PlxyXG4gICAgICAgICEhci5tb2RlbElkXHJcbiAgICApXHJcbiAgKVxyXG5cclxuICBjb25zdCBkaWZmVmVyc2lvbklkcyA9IGNvbXB1dGVkKCgpID0+XHJcbiAgICBmbGF0dGVuKFxyXG4gICAgICAoZGlmZi52YWx1ZT8uZGlmZnMgfHwgW10pLm1hcCgoZCkgPT4gW2QudmVyc2lvbkEudmVyc2lvbklkLCBkLnZlcnNpb25CLnZlcnNpb25JZF0pXHJcbiAgICApXHJcbiAgKVxyXG5cclxuICAvLyBtb2RlbC5sb2FkZWRWZXJzaW9uIHdpbGwgYmUgdGhlIGFjdHVhbGx5IGN1cnJlbnRseSBsb2FkZWQgdmVyc2lvbiArXHJcbiAgLy8gYW55IGRpZmYgdmVyc2lvbnMsIGlmIHRoZXkncmUgcmVxdWVzdGVkLiB0aGUgbmFtaW5nIGlzIGNvbmZ1c2luZywgYnV0XHJcbiAgLy8gbW9kZWwubG9hZGVkVmVyc2lvbiA9IGFsbCBjdXJyZW50bHkgbG9hZGVkIHZlcnNpb25zIG9mIHRoYXQgbW9kZWwsIGFsdGhvIHRoZXJlJ3MgdXN1YWxseSBvbmx5IDFcclxuICBjb25zdCB2ZXJzaW9uSWRzID0gY29tcHV0ZWQoKCkgPT5cclxuICAgIFtcclxuICAgICAgLi4ubm9uT2JqZWN0UmVzb3VyY2VJdGVtcy52YWx1ZS5tYXAoKHIpID0+IHIudmVyc2lvbklkKSxcclxuICAgICAgLi4uZGlmZlZlcnNpb25JZHMudmFsdWVcclxuICAgIF0uc29ydCgpXHJcbiAgKVxyXG4gIGNvbnN0IHZlcnNpb25DdXJzb3JzID0gcmVmKHt9IGFzIFJlY29yZDxzdHJpbmcsIE51bGxhYmxlPHN0cmluZz4+KVxyXG5cclxuICBjb25zdCB2aWV3ZXJMb2FkZWRSZXNvdXJjZXNWYXJpYWJsZXNGdW5jID1cclxuICAgICgpOiBWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeVZhcmlhYmxlcyA9PiAoe1xyXG4gICAgICBwcm9qZWN0SWQ6IHByb2plY3RJZC52YWx1ZSxcclxuICAgICAgbW9kZWxJZHM6IG5vbk9iamVjdFJlc291cmNlSXRlbXMudmFsdWUubWFwKChyKSA9PiByLm1vZGVsSWQpLnNvcnQoKSxcclxuICAgICAgdmVyc2lvbklkczogdmVyc2lvbklkcy52YWx1ZVxyXG4gICAgfSlcclxuXHJcbiAgLy8gTU9ERUxTIEFORCBWRVJTSU9OU1xyXG4gIC8vIHNvcnRpbmcgdmFyaWFibGVzIHNvIHRoYXQgd2UgZG9uJ3QgcmVmZXRlY2gganVzdCBiZWNhdXNlIHRoZSBvcmRlciBjaGFuZ2VkXHJcbiAgY29uc3Qge1xyXG4gICAgcmVzdWx0OiB2aWV3ZXJMb2FkZWRSZXNvdXJjZXNSZXN1bHQsXHJcbiAgICBsb2FkaW5nOiB2aWV3ZXJMb2FkZWRSZXNvdXJjZXNMb2FkaW5nLFxyXG4gICAgdmFyaWFibGVzOiB2aWV3ZXJMb2FkZWRSZXNvdXJjZXNWYXJpYWJsZXMsXHJcbiAgICBvbkVycm9yOiBvblZpZXdlckxvYWRlZFJlc291cmNlc0Vycm9yLFxyXG4gICAgb25SZXN1bHQ6IG9uVmlld2VyTG9hZGVkUmVzb3VyY2VzUmVzdWx0LFxyXG4gICAgbG9hZDogbG9hZFZpZXdlckxvYWRlZFJlc291cmNlc1xyXG4gIH0gPSB1c2VMYXp5UXVlcnkodmlld2VyTG9hZGVkUmVzb3VyY2VzUXVlcnksIHZpZXdlckxvYWRlZFJlc291cmNlc1ZhcmlhYmxlc0Z1bmMsIHtcclxuICAgIGtlZXBQcmV2aW91c1Jlc3VsdDogdHJ1ZVxyXG4gIH0pXHJcblxyXG4gIGNvbnN0IHNlcnZlclJlc291cmNlc0xvYWRlZFByb21pc2UgPSBidWlsZE1hbnVhbFByb21pc2U8dm9pZD4oKVxyXG4gIGlmIChpbXBvcnQubWV0YS5zZXJ2ZXIpIHtcclxuICAgIHdhdGNoKFxyXG4gICAgICAoKSA9PiByZXNvdXJjZUl0ZW1zTG9hZGVkLnZhbHVlLFxyXG4gICAgICBhc3luYyAobmV3VmFsLCBvbGRWYWwpID0+IHtcclxuICAgICAgICBpZiAoIW5ld1ZhbCB8fCBvbGRWYWwpIHJldHVyblxyXG5cclxuICAgICAgICAvLyBMb2FkIG9ubHkgbm93IC0gb25jZSB0aGUgcHJldmlvdXMgcXVlcnkgaXMgZG9uZVxyXG4gICAgICAgIGF3YWl0IGxvYWRWaWV3ZXJMb2FkZWRSZXNvdXJjZXMoKVxyXG4gICAgICAgIHNlcnZlclJlc291cmNlc0xvYWRlZFByb21pc2UucmVzb2x2ZSgpXHJcbiAgICAgIH0sXHJcbiAgICAgIHsgZmx1c2g6ICdzeW5jJyB9XHJcbiAgICApXHJcbiAgfSBlbHNlIHtcclxuICAgIGxvYWRWaWV3ZXJMb2FkZWRSZXNvdXJjZXMoKVxyXG4gICAgc2VydmVyUmVzb3VyY2VzTG9hZGVkUHJvbWlzZS5yZXNvbHZlKClcclxuICB9XHJcblxyXG4gIGNvbnN0IHByb2plY3QgPSBjb21wdXRlZCgoKSA9PiB2aWV3ZXJMb2FkZWRSZXNvdXJjZXNSZXN1bHQudmFsdWU/LnByb2plY3QpXHJcbiAgY29uc3QgbW9kZWxzID0gY29tcHV0ZWQoKCkgPT4gcHJvamVjdC52YWx1ZT8ubW9kZWxzPy5pdGVtcyB8fCBbXSlcclxuXHJcbiAgY29uc3QgbW9kZWxzQW5kVmVyc2lvbklkcyA9IGNvbXB1dGVkKCgpID0+XHJcbiAgICBub25PYmplY3RSZXNvdXJjZUl0ZW1zLnZhbHVlXHJcbiAgICAgIC5tYXAoKHIpID0+ICh7XHJcbiAgICAgICAgdmVyc2lvbklkOiByLnZlcnNpb25JZCxcclxuICAgICAgICBtb2RlbDogbW9kZWxzLnZhbHVlLmZpbmQoKG0pID0+IG0uaWQgPT09IHIubW9kZWxJZClcclxuICAgICAgfSkpXHJcbiAgICAgIC5maWx0ZXIoKG8pOiBvIGlzIFNldE5vbk51bGxhYmxlPHR5cGVvZiBvLCAnbW9kZWwnPiA9PiAhIShvLnZlcnNpb25JZCAmJiBvLm1vZGVsKSlcclxuICApXHJcblxyXG4gIGNvbnN0IGF2YWlsYWJsZU1vZGVsc0FuZFZlcnNpb25zID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgbW9kZWxJdGVtcyA9IG1vZGVscy52YWx1ZVxyXG4gICAgcmV0dXJuIHJlZHVjZShcclxuICAgICAgbW9kZWxJdGVtcyxcclxuICAgICAgKHJlcywgZW50cnkpID0+IHtcclxuICAgICAgICByZXMucHVzaCh7XHJcbiAgICAgICAgICBtb2RlbDogZW50cnksXHJcbiAgICAgICAgICB2ZXJzaW9uczogWy4uLmVudHJ5LmxvYWRlZFZlcnNpb24uaXRlbXMsIC4uLmVudHJ5LnZlcnNpb25zLml0ZW1zXVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgcmV0dXJuIHJlc1xyXG4gICAgICB9LFxyXG4gICAgICBbXSBhcyBBcnJheTx7XHJcbiAgICAgICAgbW9kZWw6ICh0eXBlb2YgbW9kZWxJdGVtcylbMF1cclxuICAgICAgICB2ZXJzaW9uczogKHR5cGVvZiBtb2RlbEl0ZW1zKVswXVsndmVyc2lvbnMnXVsnaXRlbXMnXVxyXG4gICAgICB9PlxyXG4gICAgKVxyXG4gIH0pXHJcblxyXG4gIG9uVmlld2VyTG9hZGVkUmVzb3VyY2VzRXJyb3IoKGVycikgPT4ge1xyXG4gICAgLy8gU2hvdyBmdWxsIHBhZ2UgZXJyb3Igb25seSBpZiBzZXJpb3VzIGVycm9yIChjb3JlIGRhdGEgY291bGRuJ3QgYmUgbG9hZGVkKVxyXG4gICAgY29uc3QgaXNXb3JraW5nTG9hZCA9ICEhdmlld2VyTG9hZGVkUmVzb3VyY2VzUmVzdWx0LnZhbHVlPy5wcm9qZWN0Lm1vZGVscy5pdGVtc1xyXG4gICAgaWYgKGlzV29ya2luZ0xvYWQpIHtcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcblxyXG4gICAgZ2xvYmFsRXJyb3IudmFsdWUgPSBjcmVhdGVFcnJvcih7XHJcbiAgICAgIHN0YXR1c0NvZGU6IDUwMCxcclxuICAgICAgbWVzc2FnZTogYFZpZXdlciBsb2FkZWQgcmVzb3VyY2UgcmVzb2x1dGlvbiBmYWlsZWQ6ICR7ZXJyfWBcclxuICAgIH0pXHJcbiAgICBpbml0TG9hZERvbmUudmFsdWUgPSB0cnVlXHJcbiAgfSlcclxuXHJcbiAgLy8gTG9hZCBpbml0aWFsIGJhdGNoIG9mIGN1cnNvcnMgZm9yIGVhY2ggbW9kZWxcclxuICBvblZpZXdlckxvYWRlZFJlc291cmNlc1Jlc3VsdCgocmVzKSA9PiB7XHJcbiAgICBpbml0TG9hZERvbmUudmFsdWUgPSB0cnVlXHJcbiAgICBpZiAoIXJlcy5kYXRhPy5wcm9qZWN0Py5tb2RlbHMpIHJldHVyblxyXG5cclxuICAgIGZvciAoY29uc3QgbW9kZWwgb2YgcmVzLmRhdGEucHJvamVjdC5tb2RlbHMuaXRlbXMpIHtcclxuICAgICAgY29uc3QgbW9kZWxJZCA9IG1vZGVsLmlkXHJcbiAgICAgIGlmICh2ZXJzaW9uQ3Vyc29ycy52YWx1ZVttb2RlbElkXSkgY29udGludWVcclxuXHJcbiAgICAgIGNvbnN0IGN1cnNvciA9IG1vZGVsLnZlcnNpb25zLmN1cnNvclxyXG4gICAgICBpZiAoIWN1cnNvcikgY29udGludWVcclxuXHJcbiAgICAgIHZlcnNpb25DdXJzb3JzLnZhbHVlW21vZGVsSWRdID0gY3Vyc29yXHJcbiAgICB9XHJcbiAgfSlcclxuXHJcbiAgY29uc3QgbG9hZE1vcmVWZXJzaW9ucyA9IGFzeW5jIChtb2RlbElkOiBzdHJpbmcpID0+IHtcclxuICAgIGNvbnN0IGN1cnNvciA9IHZlcnNpb25DdXJzb3JzLnZhbHVlW21vZGVsSWRdXHJcbiAgICBjb25zdCBiYXNlVmFyaWFibGVzID0gdmlld2VyTG9hZGVkUmVzb3VyY2VzVmFyaWFibGVzRnVuYygpXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5xdWVyeSh7XHJcbiAgICAgICAgcXVlcnk6IHZpZXdlck1vZGVsVmVyc2lvbnNRdWVyeSxcclxuICAgICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICAgIHByb2plY3RJZDogYmFzZVZhcmlhYmxlcy5wcm9qZWN0SWQsXHJcbiAgICAgICAgICBtb2RlbElkLFxyXG4gICAgICAgICAgdmVyc2lvbnNDdXJzb3I6IGN1cnNvclxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZmV0Y2hQb2xpY3k6ICduZXR3b3JrLW9ubHknXHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgaWYgKCFkYXRhPy5wcm9qZWN0Py5tb2RlbD8udmVyc2lvbnMpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgICB0aXRsZTogXCJDYW4ndCBsb2FkIG1vcmUgdmVyc2lvbnNcIixcclxuICAgICAgICBkZXNjcmlwdGlvbjogZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB9KVxyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuXHJcbiAgICBpZiAoZGF0YS5wcm9qZWN0Lm1vZGVsLnZlcnNpb25zLmN1cnNvcikge1xyXG4gICAgICB2ZXJzaW9uQ3Vyc29ycy52YWx1ZVttb2RlbElkXSA9IGRhdGEucHJvamVjdC5tb2RlbC52ZXJzaW9ucy5jdXJzb3JcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIENPTU1FTlQgVEhSRUFEU1xyXG4gIGNvbnN0IHtcclxuICAgIHJlc3VsdDogdmlld2VyTG9hZGVkVGhyZWFkc1Jlc3VsdCxcclxuICAgIG9uRXJyb3I6IG9uVmlld2VyTG9hZGVkVGhyZWFkc0Vycm9yLFxyXG4gICAgdmFyaWFibGVzOiB0aHJlYWRzUXVlcnlWYXJpYWJsZXNcclxuICB9ID0gdXNlUXVlcnkoXHJcbiAgICB2aWV3ZXJMb2FkZWRUaHJlYWRzUXVlcnksXHJcbiAgICAoKSA9PiAoe1xyXG4gICAgICBwcm9qZWN0SWQ6IHByb2plY3RJZC52YWx1ZSxcclxuICAgICAgZmlsdGVyOiB7XHJcbiAgICAgICAgLi4udGhyZWFkRmlsdGVycy52YWx1ZSxcclxuICAgICAgICByZXNvdXJjZUlkU3RyaW5nOiByZXNvdXJjZUlkU3RyaW5nLnZhbHVlXHJcbiAgICAgIH1cclxuICAgIH0pLFxyXG4gICAgKCkgPT4gKHtcclxuICAgICAga2VlcFByZXZpb3VzUmVzdWx0OiB0cnVlLFxyXG4gICAgICAvLyBEb250IG5lZWQgdGhyZWFkcyB3aGVuIGluIHByZXNlbnRhdGlvbiBtb2RlXHJcbiAgICAgIGVuYWJsZWQ6IHN0YXRlLnBhZ2VUeXBlLnZhbHVlICE9PSBWaWV3ZXJSZW5kZXJQYWdlVHlwZS5QcmVzZW50YXRpb25cclxuICAgIH0pXHJcbiAgKVxyXG5cclxuICBjb25zdCBjb21tZW50VGhyZWFkc01ldGFkYXRhID0gY29tcHV0ZWQoXHJcbiAgICAoKSA9PiB2aWV3ZXJMb2FkZWRUaHJlYWRzUmVzdWx0LnZhbHVlPy5wcm9qZWN0Py5jb21tZW50VGhyZWFkc1xyXG4gIClcclxuICBjb25zdCBjb21tZW50VGhyZWFkcyA9IGNvbXB1dGVkKCgpID0+IGNvbW1lbnRUaHJlYWRzTWV0YWRhdGEudmFsdWU/Lml0ZW1zIHx8IFtdKVxyXG5cclxuICBvblZpZXdlckxvYWRlZFRocmVhZHNFcnJvcigoZXJyKSA9PiB7XHJcbiAgICAvLyBTaG93IGZ1bGwgcGFnZSBlcnJvciBvbmx5IGlmIHNlcmlvdXMgZXJyb3IgKGNvcmUgZGF0YSBjb3VsZG4ndCBiZSBsb2FkZWQpXHJcbiAgICBjb25zdCBpc1dvcmtpbmdMb2FkID1cclxuICAgICAgISF2aWV3ZXJMb2FkZWRUaHJlYWRzUmVzdWx0LnZhbHVlPy5wcm9qZWN0LmNvbW1lbnRUaHJlYWRzLml0ZW1zXHJcbiAgICBpZiAoaXNXb3JraW5nTG9hZCkge1xyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuXHJcbiAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgdGl0bGU6ICdDb21tZW50IGxvYWRpbmcgZmFpbGVkJyxcclxuICAgICAgZGVzY3JpcHRpb246IGAke2Vyci5tZXNzYWdlfWBcclxuICAgIH0pXHJcbiAgICBsb2dnZXIuZXJyb3IoZXJyKVxyXG4gIH0pXHJcblxyXG4gIG9uU2VydmVyUHJlZmV0Y2goYXN5bmMgKCkgPT4ge1xyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW3NlcnZlclJlc291cmNlc0xvYWRlZFByb21pc2UucHJvbWlzZV0pXHJcbiAgfSlcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIG9iamVjdHMsXHJcbiAgICBjb21tZW50VGhyZWFkcyxcclxuICAgIGNvbW1lbnRUaHJlYWRzTWV0YWRhdGEsXHJcbiAgICBtb2RlbHNBbmRWZXJzaW9uSWRzLFxyXG4gICAgYXZhaWxhYmxlTW9kZWxzQW5kVmVyc2lvbnMsXHJcbiAgICBwcm9qZWN0LFxyXG4gICAgcmVzb3VyY2VRdWVyeVZhcmlhYmxlczogY29tcHV0ZWQoKCkgPT4gdmlld2VyTG9hZGVkUmVzb3VyY2VzVmFyaWFibGVzLnZhbHVlKSxcclxuICAgIHRocmVhZHNRdWVyeVZhcmlhYmxlczogY29tcHV0ZWQoKCkgPT4gdGhyZWFkc1F1ZXJ5VmFyaWFibGVzLnZhbHVlKSxcclxuICAgIGxvYWRNb3JlVmVyc2lvbnMsXHJcbiAgICByZXNvdXJjZXNMb2FkZWQ6IGNvbXB1dGVkKCgpID0+IGluaXRMb2FkRG9uZS52YWx1ZSksXHJcbiAgICByZXNvdXJjZXNMb2FkaW5nOiBjb21wdXRlZCgoKSA9PiB2aWV3ZXJMb2FkZWRSZXNvdXJjZXNMb2FkaW5nLnZhbHVlKVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIExvYWQgcmVzb3VyY2UgcmVzcG9uc2VzIChhbGwgb2YgdGhlIHJlbGV2YW50IGRhdGEgZnJvbSBzZXJ2ZXIpXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXR1cFJlc291cmNlUmVzcG9uc2UoXHJcbiAgc3RhdGU6IEluaXRpYWxTdGF0ZVdpdGhSZXF1ZXN0XHJcbik6IEluaXRpYWxTdGF0ZVdpdGhSZXF1ZXN0QW5kUmVzcG9uc2Uge1xyXG4gIGNvbnN0IHJlc291cmNlSXRlbXNEYXRhID0gc2V0dXBSZXNwb25zZVJlc291cmNlSXRlbXMoc3RhdGUpXHJcbiAgY29uc3QgbG9hZGVkUmVzb3VyY2VEYXRhID0gc2V0dXBSZXNwb25zZVJlc291cmNlRGF0YShzdGF0ZSwgcmVzb3VyY2VJdGVtc0RhdGEpXHJcblxyXG4gIHJldHVybiB7XHJcbiAgICAuLi5zdGF0ZSxcclxuICAgIHJlc291cmNlczoge1xyXG4gICAgICByZXF1ZXN0OiB7XHJcbiAgICAgICAgLi4uc3RhdGUucmVzb3VyY2VzLnJlcXVlc3RcclxuICAgICAgfSxcclxuICAgICAgcmVzcG9uc2U6IHtcclxuICAgICAgICAuLi5yZXNvdXJjZUl0ZW1zRGF0YSxcclxuICAgICAgICAuLi5sb2FkZWRSZXNvdXJjZURhdGFcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gc2V0dXBJbnRlcmZhY2VTdGF0ZShcclxuICBzdGF0ZTogSW5pdGlhbFN0YXRlV2l0aFVybEhhc2hTdGF0ZVxyXG4pOiBJbml0aWFsU3RhdGVXaXRoSW50ZXJmYWNlIHtcclxuICAvLyBJcyB2aWV3ZXIgYnVzeSAtIFVzaW5nIHdyaXRhYmxlIGNvbXB1dGVkIHNvIHRoYXQgd2UgY2FuIGFsd2F5cyBpbnRlcmNlcHQgdGhlc2UgY2FsbHNcclxuICBjb25zdCBpc0xvYWRpbmcgPSByZWYoZmFsc2UpXHJcbiAgY29uc3QgbG9hZGluZyA9IGNvbXB1dGVkKHtcclxuICAgIGdldDogKCkgPT4gaXNMb2FkaW5nLnZhbHVlLFxyXG4gICAgc2V0OiAobmV3VmFsKSA9PiAoaXNMb2FkaW5nLnZhbHVlID0gISFuZXdWYWwpXHJcbiAgfSlcclxuXHJcbiAgY29uc3QgbG9hZFByb2dyZXNzID0gcmVmKDApXHJcbiAgY29uc3QgaGFzTG9hZGVkUXVldWVkVXBNb2RlbHMgPSByZWYoZmFsc2UpXHJcblxyXG4gIGNvbnN0IHsgZmlsdGVycyB9ID0gdXNlRmlsdGVyc1NldHVwKClcclxuICBjb25zdCB7IHZpZXdNb2RlIH0gPSB1c2VWaWV3TW9kZXNTZXR1cCgpXHJcblxyXG4gIGNvbnN0IGhpZ2hsaWdodGVkT2JqZWN0SWRzID0gcmVmKFtdIGFzIHN0cmluZ1tdKVxyXG4gIGNvbnN0IHNwb3RsaWdodFVzZXJTZXNzaW9uSWQgPSByZWYobnVsbCBhcyBOdWxsYWJsZTxzdHJpbmc+KVxyXG5cclxuICBjb25zdCBsaWdodENvbmZpZyA9IHJlZihEZWZhdWx0TGlnaHRDb25maWd1cmF0aW9uKVxyXG4gIGNvbnN0IGV4cGxvZGVGYWN0b3IgPSByZWYoMClcclxuICBjb25zdCBzZWxlY3Rpb24gPSByZWYobnVsbCBhcyBOdWxsYWJsZTxWZWN0b3IzPilcclxuXHJcbiAgY29uc3Qgc2VsZWN0ZWRPYmplY3RJZHMgPSBjb21wdXRlZChcbiAgICAoKSA9PlxuICAgICAgbmV3IFNldChcbiAgICAgICAgZmlsdGVycy5zZWxlY3RlZE9iamVjdHMudmFsdWUuZmxhdE1hcCgobzogU3BlY2tsZU9iamVjdCkgPT5cbiAgICAgICAgICBnZXRUYXJnZXRPYmplY3RJZHMobyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICAgICAgKVxuICAgICAgKVxuICApXG5cclxuICAvKipcclxuICAgKiBUSFJFQURTXHJcbiAgICovXHJcbiAgY29uc3QgeyBjb21tZW50VGhyZWFkcywgb3BlblRocmVhZCwgbmV3VGhyZWFkRWRpdG9yIH0gPSBzZXR1cFZpZXdlckNvbW1lbnRCdWJibGVzKHtcclxuICAgIHN0YXRlXHJcbiAgfSlcclxuICBjb25zdCBpc1R5cGluZyA9IHJlZihmYWxzZSlcclxuICBjb25zdCBoaWRlQnViYmxlcyA9IHJlZihmYWxzZSlcclxuXHJcbiAgLyoqXHJcbiAgICogRGlmZmluZ1xyXG4gICAqL1xyXG4gIGNvbnN0IGRpZmZTdGF0ZSA9IHNldHVwVWlEaWZmU3RhdGUoc3RhdGUpXHJcblxyXG4gIGNvbnN0IHBvc2l0aW9uID0gcmVmKG5ldyBWZWN0b3IzKCkpXHJcbiAgY29uc3QgdGFyZ2V0ID0gcmVmKG5ldyBWZWN0b3IzKCkpXHJcbiAgY29uc3QgaXNPcnRob1Byb2plY3Rpb24gPSByZWYoZmFsc2UgYXMgYm9vbGVhbilcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIC4uLnN0YXRlLFxyXG4gICAgdWk6IHtcclxuICAgICAgdmlld01vZGUsXHJcbiAgICAgIGRpZmY6IHtcclxuICAgICAgICAuLi5kaWZmU3RhdGVcclxuICAgICAgfSxcclxuICAgICAgc2VsZWN0aW9uLFxyXG4gICAgICBsaWdodENvbmZpZyxcclxuICAgICAgZXhwbG9kZUZhY3RvcixcclxuICAgICAgc3BvdGxpZ2h0VXNlclNlc3Npb25JZCxcclxuICAgICAgbG9hZGluZyxcclxuICAgICAgbG9hZFByb2dyZXNzLFxyXG4gICAgICB0aHJlYWRzOiB7XHJcbiAgICAgICAgaXRlbXM6IGNvbW1lbnRUaHJlYWRzLFxyXG4gICAgICAgIG9wZW5UaHJlYWQ6IHtcclxuICAgICAgICAgIHRocmVhZDogb3BlblRocmVhZCxcclxuICAgICAgICAgIGlzVHlwaW5nLFxyXG4gICAgICAgICAgbmV3VGhyZWFkRWRpdG9yXHJcbiAgICAgICAgfSxcclxuICAgICAgICBoaWRlQnViYmxlc1xyXG4gICAgICB9LFxyXG4gICAgICBjYW1lcmE6IHtcclxuICAgICAgICAvLyBwb3NpdGlvbjogd3JhcFJlZldpdGhUcmFja2luZyhwb3NpdGlvbiwgJ3Bvc2l0aW9uJyksXHJcbiAgICAgICAgLy8gdGFyZ2V0OiB3cmFwUmVmV2l0aFRyYWNraW5nKHRhcmdldCwgJ3RhcmdldCcpLFxyXG4gICAgICAgIHBvc2l0aW9uLFxyXG4gICAgICAgIHRhcmdldCxcclxuICAgICAgICBpc09ydGhvUHJvamVjdGlvblxyXG4gICAgICB9LFxyXG4gICAgICBzZWN0aW9uQm94OiByZWYobnVsbCBhcyBOdWxsYWJsZTxTZWN0aW9uQm94RGF0YT4pLFxyXG4gICAgICBzZWN0aW9uQm94Q29udGV4dDoge1xuICAgICAgICB2aXNpYmxlOiByZWYoZmFsc2UpLFxuICAgICAgICBlZGl0ZWQ6IHJlZihmYWxzZSlcbiAgICAgIH0sXG4gICAgICB3aW5kb3dTZWxlY3Rpb246IHtcbiAgICAgICAgZW5hYmxlZDogcmVmKGZhbHNlKVxuICAgICAgfSxcbiAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgLi4uZmlsdGVycyxcclxuICAgICAgICBzZWxlY3RlZE9iamVjdElkc1xyXG4gICAgICB9LFxyXG4gICAgICBoaWdobGlnaHRlZE9iamVjdElkcyxcclxuICAgICAgbWVhc3VyZW1lbnQ6IHVzZU1lYXN1cmVtZW50c1NldHVwKCksXHJcbiAgICAgIHNhdmVkVmlld3M6IHVzZUJ1aWxkU2F2ZWRWaWV3c1VJU3RhdGUoKSxcclxuICAgICAgcGFuZWxzOiB1c2VWaWV3ZXJQYW5lbHNTZXR1cCgpLFxyXG4gICAgICBoYXNMb2FkZWRRdWV1ZWRVcE1vZGVsc1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IHR5cGUgVXNlU2V0dXBWaWV3ZXJQYXJhbXMgPSB7XHJcbiAgcHJvamVjdElkOiBBc3luY1dyaXRhYmxlQ29tcHV0ZWRSZWY8c3RyaW5nPlxyXG4gIHJlc291cmNlSWRTdHJpbmc6IEFzeW5jV3JpdGFibGVDb21wdXRlZFJlZjxzdHJpbmc+XHJcbiAgcGFnZVR5cGU6IFZpZXdlclJlbmRlclBhZ2VUeXBlXHJcbiAgLyoqXHJcbiAgICogT3B0aW9uYWxseSBvdmVycmlkZSBzYXZlZFZpZXcgc291cmNlIG9mIHRydXRoXHJcbiAgICovXHJcbiAgc2F2ZWRWaWV3Pzoge1xyXG4gICAgaWQ6IEluamVjdGFibGVWaWV3ZXJTdGF0ZVsncmVzb3VyY2VzJ11bJ3JlcXVlc3QnXVsnc2F2ZWRWaWV3J11bJ2lkJ11cclxuICAgIGxvYWRPcmlnaW5hbDogSW5qZWN0YWJsZVZpZXdlclN0YXRlWydyZXNvdXJjZXMnXVsncmVxdWVzdCddWydzYXZlZFZpZXcnXVsnbG9hZE9yaWdpbmFsJ11cclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VTZXR1cFZpZXdlcihwYXJhbXM6IFVzZVNldHVwVmlld2VyUGFyYW1zKTogSW5qZWN0YWJsZVZpZXdlclN0YXRlIHtcclxuICAvLyBJbml0aWFsaXplIGZ1bGwgc3RhdGUgb2JqZWN0IC0gZWFjaCBzdWJzZXF1ZW50IHN0YXRlIGluaXRpYWxpemF0aW9uIGRlcGVuZHMgb25cclxuICAvLyB0aGUgcmVzdWx0cyBvZiB0aGUgcHJldmlvdXMgb25lcyB1bnRpbCB3ZSBoYXZlIHRoZSBmaW5hbCBmdWxsIG9iamVjdFxyXG4gIGNvbnN0IGluaXRTdGF0ZSA9IHNldHVwSW5pdGlhbFN0YXRlKHBhcmFtcylcclxuICBjb25zdCBpbml0aWFsU3RhdGVXaXRoUmVxdWVzdCA9IHNldHVwUmVzb3VyY2VSZXF1ZXN0KGluaXRTdGF0ZSwgcGFyYW1zKVxyXG4gIGNvbnN0IHN0YXRlV2l0aFJlc291cmNlcyA9IHNldHVwUmVzb3VyY2VSZXNwb25zZShpbml0aWFsU3RhdGVXaXRoUmVxdWVzdClcclxuICBjb25zdCBzdGF0ZTogSW5qZWN0YWJsZVZpZXdlclN0YXRlID0gc2V0dXBJbnRlcmZhY2VTdGF0ZShzdGF0ZVdpdGhSZXNvdXJjZXMpXHJcblxyXG4gIC8vIFdlIGRvbid0IHdhbnQgdGhlIHN0YXRlIHRvIGV2ZXIgYmUgcHJveGlmaWVkIChlLmcuIHdoZW4gcGFzc2VkIHRocm91Z2ggcHJvcHMpLFxyXG4gIC8vIGNhdXNlIHRoYXQgd2lsbCBicmVhayBjb21wb3NhYmxlcyAocmVmcyB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdW53cmFwcGVkIGFzIGlmXHJcbiAgLy8gdGhleSdyZSBhY2Nlc3NlZCBpbiBhIHRlbXBsYXRlKVxyXG4gIGNvbnN0IHJhd1N0YXRlID0gbWFya1JhdyhzdGF0ZSlcclxuXHJcbiAgLy8gSW5qZWN0IGl0IGludG8gZGVzY2VuZGFudCBjb21wb25lbnRzXHJcbiAgcHJvdmlkZShJbmplY3RhYmxlVmlld2VyU3RhdGVLZXksIHJhd1N0YXRlKVxyXG5cclxuICByZXR1cm4gcmF3U3RhdGVcclxufVxyXG5cclxuLy8gQ09NUE9TQUJMRVMgRk9SIFJFVFJJRVZJTkcgKFBBUlRTIE9GKSBJTkpFQ1RBQkxFIFNUQVRFXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlSW5qZWN0ZWRWaWV3ZXJTdGF0ZSgpOiBJbmplY3RhYmxlVmlld2VyU3RhdGUge1xyXG4gIC8vIHdlJ3JlIGZvcmNpbmcgVFMgdG8gaWdub3JlIHRoZSBzY2VuYXJpbyB3aGVyZSB0aGlzIGRhdGEgY2FuJ3QgYmUgZm91bmQgYW5kIHJldHVybnMgdW5kZWZpbmVkXHJcbiAgLy8gdG8gYXZvaWQgdW5uZWNlc3NhcnkgbnVsbCBjaGVja3MgZXZlcnl3aGVyZVxyXG4gIGNvbnN0IHN0YXRlID0gaW5qZWN0KEluamVjdGFibGVWaWV3ZXJTdGF0ZUtleSkgYXMgSW5qZWN0YWJsZVZpZXdlclN0YXRlXHJcbiAgcmV0dXJuIHN0YXRlXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VJbmplY3RlZFZpZXdlcigpOiBJbmplY3RhYmxlVmlld2VyU3RhdGVbJ3ZpZXdlciddIHtcclxuICBjb25zdCB7IHZpZXdlciB9ID0gdXNlSW5qZWN0ZWRWaWV3ZXJTdGF0ZSgpXHJcbiAgcmV0dXJuIHZpZXdlclxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlSW5qZWN0ZWRWaWV3ZXJMb2FkZWRSZXNvdXJjZXMoKTogSW5qZWN0YWJsZVZpZXdlclN0YXRlWydyZXNvdXJjZXMnXVsncmVzcG9uc2UnXSB7XHJcbiAgY29uc3QgeyByZXNvdXJjZXMgfSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG4gIHJldHVybiByZXNvdXJjZXMucmVzcG9uc2VcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZUluamVjdGVkVmlld2VyUmVxdWVzdGVkUmVzb3VyY2VzKCk6IEluamVjdGFibGVWaWV3ZXJTdGF0ZVsncmVzb3VyY2VzJ11bJ3JlcXVlc3QnXSB7XHJcbiAgY29uc3QgeyByZXNvdXJjZXMgfSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG4gIHJldHVybiByZXNvdXJjZXMucmVxdWVzdFxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlSW5qZWN0ZWRWaWV3ZXJJbnRlcmZhY2VTdGF0ZSgpOiBJbmplY3RhYmxlVmlld2VyU3RhdGVbJ3VpJ10ge1xyXG4gIGNvbnN0IHsgdWkgfSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG4gIHJldHVybiB1aVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlUmVzZXRVaVN0YXRlKCkge1xyXG4gIGNvbnN0IHtcclxuICAgIHVpOiB7IGNhbWVyYSwgc2VjdGlvbkJveCwgaGlnaGxpZ2h0ZWRPYmplY3RJZHMsIGxpZ2h0Q29uZmlnLCB2aWV3TW9kZSB9XHJcbiAgfSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG4gIGNvbnN0IHsgcmVzZXRGaWx0ZXJzIH0gPSB1c2VGaWx0ZXJVdGlsaXRpZXMoKVxyXG4gIGNvbnN0IHsgZW5kRGlmZiB9ID0gdXNlRGlmZlV0aWxpdGllcygpXHJcbiAgY29uc3QgeyByZXNldDogcmVzZXRNZWFzdXJlbWVudHMgfSA9IHVzZU1lYXN1cmVtZW50VXRpbGl0aWVzKClcclxuXHJcbiAgcmV0dXJuICgpID0+IHtcclxuICAgIGNhbWVyYS5pc09ydGhvUHJvamVjdGlvbi52YWx1ZSA9IGZhbHNlXHJcbiAgICBzZWN0aW9uQm94LnZhbHVlID0gbnVsbFxyXG4gICAgaGlnaGxpZ2h0ZWRPYmplY3RJZHMudmFsdWUgPSBbXVxyXG4gICAgbGlnaHRDb25maWcudmFsdWUgPSB7IC4uLkRlZmF1bHRMaWdodENvbmZpZ3VyYXRpb24gfVxyXG4gICAgdmlld01vZGUucmVzZXRWaWV3TW9kZSgpXHJcbiAgICByZXNldEZpbHRlcnMoKVxyXG4gICAgcmVzZXRNZWFzdXJlbWVudHMoKVxyXG4gICAgZW5kRGlmZigpXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgeyBJbmplY3RhYmxlVmlld2VyU3RhdGVLZXksIHVzZVNldHVwVmlld2VyU2NvcGUgfVxyXG4iXSwiZmlsZSI6IkQ6L3NwZWNrbGUtc2VydmVyL3BhY2thZ2VzL2Zyb250ZW5kLTIvbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC50cyJ9