Files
speckle-server/scratch/edge-debug-selection/Default/Cache/Cache_Data/f_000103
T

701 lines
100 KiB
Plaintext

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