333 lines
42 KiB
Plaintext
333 lines
42 KiB
Plaintext
import { useApolloClient, useSubscription } from "/_nuxt/node_modules/@vue/apollo-composable/dist/index.mjs?v=e4f18c29";
|
|
import { useClipboard } from "/_nuxt/node_modules/@vueuse/core/index.mjs?v=e4f18c29";
|
|
import { ToastNotificationType, useGlobalToast } from "/_nuxt/lib/common/composables/toast.ts";
|
|
import {
|
|
ProjectModelsUpdatedMessageType,
|
|
ProjectPendingModelsUpdatedMessageType
|
|
} from "/_nuxt/lib/common/generated/gql/graphql.ts";
|
|
import {
|
|
convertThrowIntoFetchResult,
|
|
evictObjectFields,
|
|
getCacheId,
|
|
getFirstErrorMessage,
|
|
modifyObjectFields
|
|
} from "/_nuxt/lib/common/helpers/graphql.ts";
|
|
import { isRequired, isStringOfLength } from "/_nuxt/lib/common/helpers/validation.ts";
|
|
import {
|
|
createModelMutation,
|
|
deleteModelMutation,
|
|
updateModelMutation
|
|
} from "/_nuxt/lib/projects/graphql/mutations.ts";
|
|
import {
|
|
onProjectModelsUpdateSubscription,
|
|
onProjectPendingModelsUpdatedSubscription
|
|
} from "/_nuxt/lib/projects/graphql/subscriptions.ts";
|
|
import { useNavigateToProject } from "/_nuxt/lib/common/helpers/route.ts";
|
|
import { FileUploadConvertedStatus } from "/_nuxt/lib/core/api/fileImport.ts";
|
|
import { useLock } from "/_nuxt/lib/common/composables/singleton.ts";
|
|
import { isUndefined } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
|
|
import {
|
|
useFailedFileImportJobUtils,
|
|
useGlobalFileImportManager
|
|
} from "/_nuxt/lib/core/composables/fileImport.ts";
|
|
import { graphql } from "/_nuxt/lib/common/generated/gql/index.ts";
|
|
import { getModelItemRoute } from "/_nuxt/lib/projects/helpers/models.ts";
|
|
|
|
import { computed, unref, ref } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
|
|
import { useActiveUser } from "/_nuxt/composables/globals.ts";
|
|
const isValidModelName = (name) => {
|
|
name = name.trim();
|
|
if (name.startsWith("/") || name.endsWith("/") || name.startsWith("#") || name.startsWith("$") || name.indexOf("//") !== -1 || name.indexOf(",") !== -1)
|
|
return 'Value should not start with "#", "$", start or end with "/", have multiple slashes next to each other or contain commas';
|
|
if (["globals", "main"].includes(name))
|
|
return `'main' and 'globals' are reserved names`;
|
|
return true;
|
|
};
|
|
export function useModelNameValidationRules() {
|
|
return computed(() => [
|
|
isRequired,
|
|
isStringOfLength({ maxLength: 512 }),
|
|
isValidModelName
|
|
]);
|
|
}
|
|
export function useEvictProjectModelFields() {
|
|
const apollo = useApolloClient().client;
|
|
const cache = apollo.cache;
|
|
return (projectId) => {
|
|
evictObjectFields(cache, getCacheId("Project", projectId), (field) => {
|
|
return [
|
|
"models",
|
|
"modelsTree",
|
|
"model",
|
|
"modelChildrenTree",
|
|
"viewerResources",
|
|
"viewerResourcesExtended"
|
|
].includes(field);
|
|
});
|
|
};
|
|
}
|
|
export function useCreateNewModel() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const evictProjectModels = useEvictProjectModelFields();
|
|
return async (values) => {
|
|
const { name, description, projectId } = values;
|
|
const { data, errors } = await apollo.mutate({
|
|
mutation: createModelMutation,
|
|
variables: {
|
|
input: {
|
|
name,
|
|
description,
|
|
projectId
|
|
}
|
|
},
|
|
update: (_cache, { data: data2 }) => {
|
|
if (!data2?.modelMutations?.create?.id) return;
|
|
evictProjectModels(projectId);
|
|
}
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (data?.modelMutations?.create?.id) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "New model created"
|
|
});
|
|
} else {
|
|
const errMsg = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Model creation failed",
|
|
description: errMsg
|
|
});
|
|
}
|
|
return data?.modelMutations?.create;
|
|
};
|
|
}
|
|
export function useUpdateModel() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
return async (input) => {
|
|
const { data, errors } = await apollo.mutate({
|
|
mutation: updateModelMutation,
|
|
variables: {
|
|
input
|
|
}
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (data?.modelMutations.update.id) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "Model updated"
|
|
});
|
|
} else {
|
|
const errMsg = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Model update failed",
|
|
description: errMsg
|
|
});
|
|
}
|
|
return data?.modelMutations.update;
|
|
};
|
|
}
|
|
export function useDeleteModel() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const evictProjectModels = useEvictProjectModelFields();
|
|
return async (input) => {
|
|
const { data, errors } = await apollo.mutate({
|
|
mutation: deleteModelMutation,
|
|
variables: {
|
|
input
|
|
},
|
|
update: (cache, res) => {
|
|
if (!res.data?.modelMutations.delete) return;
|
|
cache.evict({
|
|
id: getCacheId("Model", input.id)
|
|
});
|
|
evictProjectModels(input.projectId);
|
|
}
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (data?.modelMutations.delete) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "Model deleted"
|
|
});
|
|
} else {
|
|
const errMsg = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Model delete failed",
|
|
description: errMsg
|
|
});
|
|
}
|
|
return !!data?.modelMutations.delete;
|
|
};
|
|
}
|
|
export function useProjectModelUpdateTracking(projectId, handler, options) {
|
|
const { hasLock } = useLock(
|
|
computed(() => `useProjectModelUpdateTracking-${unref(projectId)}`)
|
|
);
|
|
const isEnabled = computed(() => !!(hasLock.value || handler));
|
|
const { onResult: onProjectModelUpdate } = useSubscription(
|
|
onProjectModelsUpdateSubscription,
|
|
() => ({
|
|
id: unref(projectId)
|
|
}),
|
|
{ enabled: isEnabled, errorPolicy: "all" }
|
|
);
|
|
const apollo = useApolloClient().client;
|
|
const evictProjectModels = useEvictProjectModelFields();
|
|
const goToProject = useNavigateToProject();
|
|
const { triggerNotification } = useGlobalToast();
|
|
onProjectModelUpdate((res) => {
|
|
if (!res.data?.projectModelsUpdated || !hasLock.value) return;
|
|
const event = res.data.projectModelsUpdated;
|
|
const isDelete = event.type === ProjectModelsUpdatedMessageType.Deleted;
|
|
const model = event.model;
|
|
if (isDelete) {
|
|
apollo.cache.evict({
|
|
id: getCacheId("Model", event.id)
|
|
});
|
|
if (options?.redirectToProjectOnModelDeletion?.(event.id)) {
|
|
goToProject({ id: unref(projectId) });
|
|
triggerNotification({
|
|
type: ToastNotificationType.Info,
|
|
title: "Model has been deleted",
|
|
description: "Redirecting to project page home"
|
|
});
|
|
}
|
|
}
|
|
if (event.type === ProjectModelsUpdatedMessageType.Created || isDelete) {
|
|
evictProjectModels(unref(projectId));
|
|
} else if (event.type === ProjectModelsUpdatedMessageType.Updated && model?.versionCount.totalCount) {
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(_fieldName, variables, value, { ref }) => {
|
|
if (variables.filter?.search) return;
|
|
if (variables.filter?.sourceApps?.length) return;
|
|
if (variables.filter?.contributors?.length) return;
|
|
if (!variables.filter?.onlyWithVersions) return;
|
|
const limit = variables.limit;
|
|
const newModelRef = ref("Model", model.id);
|
|
const newItems = (value?.items || []).slice();
|
|
if (!newItems.find((i) => i.__ref === newModelRef.__ref) && (isUndefined(limit) || newItems.length < limit)) {
|
|
newItems.unshift(newModelRef);
|
|
}
|
|
return {
|
|
...value || {},
|
|
items: newItems,
|
|
totalCount: (value.totalCount || 0) + 1
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["models"] }
|
|
);
|
|
evictObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(fieldName, variables, value, { readField }) => {
|
|
if (fieldName !== "modelsTree") return false;
|
|
if (variables.filter?.search) return false;
|
|
if (variables.filter?.contributors?.length) return false;
|
|
if (variables.filter?.sourceApps?.length) return false;
|
|
const items = value?.items || [];
|
|
for (const item of items) {
|
|
const fullName = readField("fullName", item);
|
|
if (fullName === model.name) return false;
|
|
}
|
|
return true;
|
|
}
|
|
);
|
|
}
|
|
});
|
|
onProjectModelUpdate((res) => {
|
|
if (!res.data?.projectModelsUpdated) return;
|
|
const event = res.data.projectModelsUpdated;
|
|
handler?.(event, apollo.cache);
|
|
});
|
|
}
|
|
export function useProjectPendingModelUpdateTracking(projectId, handler) {
|
|
const { hasLock } = useLock(
|
|
computed(() => `useProjectPendingModelUpdateTracking-${unref(projectId)}`)
|
|
);
|
|
const isEnabled = computed(() => !!(hasLock.value || handler));
|
|
const { onResult: onProjectPendingModelUpdate } = useSubscription(
|
|
onProjectPendingModelsUpdatedSubscription,
|
|
() => ({
|
|
id: unref(projectId)
|
|
}),
|
|
{ enabled: isEnabled, errorPolicy: "all" }
|
|
);
|
|
const apollo = useApolloClient().client;
|
|
const { addFailedJob } = useGlobalFileImportManager();
|
|
const { convertUploadToFailedJob } = useFailedFileImportJobUtils();
|
|
const { userId } = useActiveUser();
|
|
onProjectPendingModelUpdate((res) => {
|
|
if (!res.data?.projectPendingModelsUpdated.id || !hasLock.value) return;
|
|
const event = res.data.projectPendingModelsUpdated;
|
|
if (event.type === ProjectPendingModelsUpdatedMessageType.Created) {
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(_fieldName, _variables, value, { ref }) => {
|
|
const currentModels = (value || []).slice();
|
|
currentModels.push(ref("FileUpload", event.id));
|
|
return currentModels;
|
|
},
|
|
{ fieldNameWhitelist: ["pendingImportedModels"] }
|
|
);
|
|
} else if (event.type === ProjectPendingModelsUpdatedMessageType.Updated) {
|
|
const success = event.model.convertedStatus === FileUploadConvertedStatus.Completed;
|
|
const failure = event.model.convertedStatus === FileUploadConvertedStatus.Error;
|
|
const newModel = event.model.model;
|
|
if (success && newModel) {
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(_fieldName, _variables, value, { ref }) => {
|
|
if (!value?.length) return;
|
|
const currentModels = (value || []).filter(
|
|
(i) => i.__ref !== ref("FileUpload", event.id).__ref
|
|
);
|
|
return currentModels;
|
|
},
|
|
{ fieldNameWhitelist: ["pendingImportedModels"] }
|
|
);
|
|
} else if (failure) {
|
|
if (event.model.userId === userId.value) {
|
|
addFailedJob(convertUploadToFailedJob(event.model));
|
|
}
|
|
}
|
|
}
|
|
});
|
|
onProjectPendingModelUpdate((res) => {
|
|
if (!res.data?.projectPendingModelsUpdated.id) return;
|
|
const event = res.data.projectPendingModelsUpdated;
|
|
handler?.(event, apollo.cache);
|
|
});
|
|
}
|
|
graphql(`
|
|
fragment UseCopyModelLink_Model on Model {
|
|
id
|
|
projectId
|
|
...GetModelItemRoute_Model
|
|
}
|
|
`);
|
|
export function useCopyModelLink() {
|
|
const { copy } = useClipboard();
|
|
const { triggerNotification } = useGlobalToast();
|
|
return async (params) => {
|
|
const { model, versionId } = params;
|
|
if (false) {
|
|
throw new Error("Not supported in SSR");
|
|
}
|
|
const path = getModelItemRoute(model, versionId);
|
|
const url = new URL(path, window.location.toString()).toString();
|
|
await copy(url);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Info,
|
|
title: `Copied ${versionId ? "version" : "model"} link to clipboard`
|
|
});
|
|
};
|
|
}
|
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQ0EsU0FBUyxpQkFBaUIsdUJBQXVCO0FBQ2pELFNBQVMsb0JBQW9CO0FBSTdCLFNBQVMsdUJBQXVCLHNCQUFzQjtBQVl0RDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyxZQUFZLHdCQUF3QjtBQUM3QztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsNEJBQTRCO0FBQ3JDLFNBQVMsaUNBQWlDO0FBQzFDLFNBQVMsZUFBZTtBQUN4QixTQUFTLG1CQUFtQjtBQUM1QjtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsZUFBZTtBQUN4QixTQUFTLHlCQUF5Qjs7OztBQUVsQyxNQUFNLG1CQUFvRCxDQUFDLFNBQVM7QUFDbEUsU0FBTyxLQUFLLEtBQUs7QUFDakIsTUFDRSxLQUFLLFdBQVcsR0FBRyxLQUNuQixLQUFLLFNBQVMsR0FBRyxLQUNqQixLQUFLLFdBQVcsR0FBRyxLQUNuQixLQUFLLFdBQVcsR0FBRyxLQUNuQixLQUFLLFFBQVEsSUFBSSxNQUFNLE1BQ3ZCLEtBQUssUUFBUSxHQUFHLE1BQU07QUFFdEIsV0FBTztBQUVULE1BQUksQ0FBQyxXQUFXLE1BQU0sRUFBRSxTQUFTLElBQUk7QUFDbkMsV0FBTztBQUVULFNBQU87QUFDVDtBQUVPLGdCQUFTLDhCQUE4QjtBQUM1QyxTQUFPLFNBQVMsTUFBTTtBQUFBLElBQ3BCO0FBQUEsSUFDQSxpQkFBaUIsRUFBRSxXQUFXLElBQUksQ0FBQztBQUFBLElBQ25DO0FBQUEsRUFDRixDQUFDO0FBQ0g7QUFFTyxnQkFBUyw2QkFBNkI7QUFDM0MsUUFBTSxTQUFTLGdCQUFnQixFQUFFO0FBQ2pDLFFBQU0sUUFBUSxPQUFPO0FBQ3JCLFNBQU8sQ0FBQyxjQUFzQjtBQUk1QixzQkFBa0IsT0FBTyxXQUFXLFdBQVcsU0FBUyxHQUFHLENBQUMsVUFBVTtBQUNwRSxhQUFPO0FBQUEsUUFDTDtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsTUFDRixFQUFFLFNBQVMsS0FBSztBQUFBLElBQ2xCLENBQUM7QUFBQSxFQUNIO0FBQ0Y7QUFFTyxnQkFBUyxvQkFBb0I7QUFDbEMsUUFBTSxTQUFTLGdCQUFnQixFQUFFO0FBQ2pDLFFBQU0sRUFBRSxvQkFBb0IsSUFBSSxlQUFlO0FBQy9DLFFBQU0scUJBQXFCLDJCQUEyQjtBQUV0RCxTQUFPLE9BQU8sV0FBcUU7QUFDakYsVUFBTSxFQUFFLE1BQU0sYUFBYSxVQUFVLElBQUk7QUFFekMsVUFBTSxFQUFFLE1BQU0sT0FBTyxJQUFJLE1BQU0sT0FDNUIsT0FBTztBQUFBLE1BQ04sVUFBVTtBQUFBLE1BQ1YsV0FBVztBQUFBLFFBQ1QsT0FBTztBQUFBLFVBQ0w7QUFBQSxVQUNBO0FBQUEsVUFDQTtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsTUFDQSxRQUFRLENBQUMsUUFBUSxFQUFFLE1BQUFBLE1BQUssTUFBTTtBQUM1QixZQUFJLENBQUNBLE9BQU0sZ0JBQWdCLFFBQVEsR0FBSTtBQUN2QywyQkFBbUIsU0FBUztBQUFBLE1BQzlCO0FBQUEsSUFDRixDQUFDLEVBQ0EsTUFBTSwyQkFBMkI7QUFFcEMsUUFBSSxNQUFNLGdCQUFnQixRQUFRLElBQUk7QUFDcEMsMEJBQW9CO0FBQUEsUUFDbEIsTUFBTSxzQkFBc0I7QUFBQSxRQUM1QixPQUFPO0FBQUEsTUFDVCxDQUFDO0FBQUEsSUFDSCxPQUFPO0FBQ0wsWUFBTSxTQUFTLHFCQUFxQixNQUFNO0FBQzFDLDBCQUFvQjtBQUFBLFFBQ2xCLE1BQU0sc0JBQXNCO0FBQUEsUUFDNUIsT0FBTztBQUFBLFFBQ1AsYUFBYTtBQUFBLE1BQ2YsQ0FBQztBQUFBLElBQ0g7QUFFQSxXQUFPLE1BQU0sZ0JBQWdCO0FBQUEsRUFDL0I7QUFDRjtBQUVPLGdCQUFTLGlCQUFpQjtBQUMvQixRQUFNLFNBQVMsZ0JBQWdCLEVBQUU7QUFDakMsUUFBTSxFQUFFLG9CQUFvQixJQUFJLGVBQWU7QUFFL0MsU0FBTyxPQUFPLFVBQTRCO0FBQ3hDLFVBQU0sRUFBRSxNQUFNLE9BQU8sSUFBSSxNQUFNLE9BQzVCLE9BQU87QUFBQSxNQUNOLFVBQVU7QUFBQSxNQUNWLFdBQVc7QUFBQSxRQUNUO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQyxFQUNBLE1BQU0sMkJBQTJCO0FBRXBDLFFBQUksTUFBTSxlQUFlLE9BQU8sSUFBSTtBQUNsQywwQkFBb0I7QUFBQSxRQUNsQixNQUFNLHNCQUFzQjtBQUFBLFFBQzVCLE9BQU87QUFBQSxNQUNULENBQUM7QUFBQSxJQUNILE9BQU87QUFDTCxZQUFNLFNBQVMscUJBQXFCLE1BQU07QUFDMUMsMEJBQW9CO0FBQUEsUUFDbEIsTUFBTSxzQkFBc0I7QUFBQSxRQUM1QixPQUFPO0FBQUEsUUFDUCxhQUFhO0FBQUEsTUFDZixDQUFDO0FBQUEsSUFDSDtBQUVBLFdBQU8sTUFBTSxlQUFlO0FBQUEsRUFDOUI7QUFDRjtBQUVPLGdCQUFTLGlCQUFpQjtBQUMvQixRQUFNLFNBQVMsZ0JBQWdCLEVBQUU7QUFDakMsUUFBTSxFQUFFLG9CQUFvQixJQUFJLGVBQWU7QUFDL0MsUUFBTSxxQkFBcUIsMkJBQTJCO0FBRXRELFNBQU8sT0FBTyxVQUE0QjtBQUN4QyxVQUFNLEVBQUUsTUFBTSxPQUFPLElBQUksTUFBTSxPQUM1QixPQUFPO0FBQUEsTUFDTixVQUFVO0FBQUEsTUFDVixXQUFXO0FBQUEsUUFDVDtBQUFBLE1BQ0Y7QUFBQSxNQUNBLFFBQVEsQ0FBQyxPQUFPLFFBQVE7QUFDdEIsWUFBSSxDQUFDLElBQUksTUFBTSxlQUFlLE9BQVE7QUFFdEMsY0FBTSxNQUFNO0FBQUEsVUFDVixJQUFJLFdBQVcsU0FBUyxNQUFNLEVBQUU7QUFBQSxRQUNsQyxDQUFDO0FBQ0QsMkJBQW1CLE1BQU0sU0FBUztBQUFBLE1BQ3BDO0FBQUEsSUFDRixDQUFDLEVBQ0EsTUFBTSwyQkFBMkI7QUFFcEMsUUFBSSxNQUFNLGVBQWUsUUFBUTtBQUMvQiwwQkFBb0I7QUFBQSxRQUNsQixNQUFNLHNCQUFzQjtBQUFBLFFBQzVCLE9BQU87QUFBQSxNQUNULENBQUM7QUFBQSxJQUNILE9BQU87QUFDTCxZQUFNLFNBQVMscUJBQXFCLE1BQU07QUFDMUMsMEJBQW9CO0FBQUEsUUFDbEIsTUFBTSxzQkFBc0I7QUFBQSxRQUM1QixPQUFPO0FBQUEsUUFDUCxhQUFhO0FBQUEsTUFDZixDQUFDO0FBQUEsSUFDSDtBQUVBLFdBQU8sQ0FBQyxDQUFDLE1BQU0sZUFBZTtBQUFBLEVBQ2hDO0FBQ0Y7QUFNTyxnQkFBUyw4QkFDZCxXQUNBLFNBSUEsU0FDQTtBQUNBLFFBQU0sRUFBRSxRQUFRLElBQUk7QUFBQSxJQUNsQixTQUFTLE1BQU0saUNBQWlDLE1BQU0sU0FBUyxDQUFDLEVBQUU7QUFBQSxFQUNwRTtBQUNBLFFBQU0sWUFBWSxTQUFTLE1BQU0sQ0FBQyxFQUFFLFFBQVEsU0FBUyxRQUFRO0FBQzdELFFBQU0sRUFBRSxVQUFVLHFCQUFxQixJQUFJO0FBQUEsSUFDekM7QUFBQSxJQUNBLE9BQU87QUFBQSxNQUNMLElBQUksTUFBTSxTQUFTO0FBQUEsSUFDckI7QUFBQSxJQUNBLEVBQUUsU0FBUyxXQUFXLGFBQWEsTUFBTTtBQUFBLEVBQzNDO0FBRUEsUUFBTSxTQUFTLGdCQUFnQixFQUFFO0FBQ2pDLFFBQU0scUJBQXFCLDJCQUEyQjtBQUN0RCxRQUFNLGNBQWMscUJBQXFCO0FBQ3pDLFFBQU0sRUFBRSxvQkFBb0IsSUFBSSxlQUFlO0FBRS9DLHVCQUFxQixDQUFDLFFBQVE7QUFDNUIsUUFBSSxDQUFDLElBQUksTUFBTSx3QkFBd0IsQ0FBQyxRQUFRLE1BQU87QUFHdkQsVUFBTSxRQUFRLElBQUksS0FBSztBQUN2QixVQUFNLFdBQVcsTUFBTSxTQUFTLGdDQUFnQztBQUNoRSxVQUFNLFFBQVEsTUFBTTtBQUVwQixRQUFJLFVBQVU7QUFFWixhQUFPLE1BQU0sTUFBTTtBQUFBLFFBQ2pCLElBQUksV0FBVyxTQUFTLE1BQU0sRUFBRTtBQUFBLE1BQ2xDLENBQUM7QUFFRCxVQUFJLFNBQVMsbUNBQW1DLE1BQU0sRUFBRSxHQUFHO0FBQ3pELG9CQUFZLEVBQUUsSUFBSSxNQUFNLFNBQVMsRUFBRSxDQUFDO0FBRXBDLDRCQUFvQjtBQUFBLFVBQ2xCLE1BQU0sc0JBQXNCO0FBQUEsVUFDNUIsT0FBTztBQUFBLFVBQ1AsYUFBYTtBQUFBLFFBQ2YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxJQUNGO0FBR0EsUUFBSSxNQUFNLFNBQVMsZ0NBQWdDLFdBQVcsVUFBVTtBQUN0RSx5QkFBbUIsTUFBTSxTQUFTLENBQUM7QUFBQSxJQUNyQyxXQUNFLE1BQU0sU0FBUyxnQ0FBZ0MsV0FDL0MsT0FBTyxhQUFhLFlBQ3BCO0FBR0E7QUFBQSxRQUNFLE9BQU87QUFBQSxRQUNQLFdBQVcsV0FBVyxNQUFNLFNBQVMsQ0FBQztBQUFBLFFBQ3RDLENBQUMsWUFBWSxXQUFXLE9BQU8sRUFBRSxJQUFJLE1BQU07QUFDekMsY0FBSSxVQUFVLFFBQVEsT0FBUTtBQUM5QixjQUFJLFVBQVUsUUFBUSxZQUFZLE9BQVE7QUFDMUMsY0FBSSxVQUFVLFFBQVEsY0FBYyxPQUFRO0FBQzVDLGNBQUksQ0FBQyxVQUFVLFFBQVEsaUJBQWtCO0FBRXpDLGdCQUFNLFFBQVEsVUFBVTtBQUN4QixnQkFBTSxjQUFjLElBQUksU0FBUyxNQUFNLEVBQUU7QUFDekMsZ0JBQU0sWUFBWSxPQUFPLFNBQVMsQ0FBQyxHQUFHLE1BQU07QUFFNUMsY0FDRSxDQUFDLFNBQVMsS0FBSyxDQUFDLE1BQU0sRUFBRSxVQUFVLFlBQVksS0FBSyxNQUNsRCxZQUFZLEtBQUssS0FBSyxTQUFTLFNBQVMsUUFDekM7QUFDQSxxQkFBUyxRQUFRLFdBQVc7QUFBQSxVQUM5QjtBQUVBLGlCQUFPO0FBQUEsWUFDTCxHQUFJLFNBQVMsQ0FBQztBQUFBLFlBQ2QsT0FBTztBQUFBLFlBQ1AsYUFBYSxNQUFNLGNBQWMsS0FBSztBQUFBLFVBQ3hDO0FBQUEsUUFDRjtBQUFBLFFBQ0EsRUFBRSxvQkFBb0IsQ0FBQyxRQUFRLEVBQUU7QUFBQSxNQUNuQztBQUdBO0FBQUEsUUFDRSxPQUFPO0FBQUEsUUFDUCxXQUFXLFdBQVcsTUFBTSxTQUFTLENBQUM7QUFBQSxRQUN0QyxDQUFDLFdBQVcsV0FBVyxPQUFPLEVBQUUsVUFBVSxNQUFNO0FBQzlDLGNBQUksY0FBYyxhQUFjLFFBQU87QUFDdkMsY0FBSSxVQUFVLFFBQVEsT0FBUSxRQUFPO0FBQ3JDLGNBQUksVUFBVSxRQUFRLGNBQWMsT0FBUSxRQUFPO0FBQ25ELGNBQUksVUFBVSxRQUFRLFlBQVksT0FBUSxRQUFPO0FBRWpELGdCQUFNLFFBQVEsT0FBTyxTQUFTLENBQUM7QUFDL0IscUJBQVcsUUFBUSxPQUFPO0FBQ3hCLGtCQUFNLFdBQVcsVUFBVSxZQUFZLElBQUk7QUFDM0MsZ0JBQUksYUFBYSxNQUFNLEtBQU0sUUFBTztBQUFBLFVBQ3RDO0FBRUEsaUJBQU87QUFBQSxRQUNUO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGLENBQUM7QUFFRCx1QkFBcUIsQ0FBQyxRQUFRO0FBQzVCLFFBQUksQ0FBQyxJQUFJLE1BQU0scUJBQXNCO0FBQ3JDLFVBQU0sUUFBUSxJQUFJLEtBQUs7QUFDdkIsY0FBVSxPQUFPLE9BQU8sS0FBSztBQUFBLEVBQy9CLENBQUM7QUFDSDtBQUVPLGdCQUFTLHFDQUNkLFdBQ0EsU0FNQTtBQUNBLFFBQU0sRUFBRSxRQUFRLElBQUk7QUFBQSxJQUNsQixTQUFTLE1BQU0sd0NBQXdDLE1BQU0sU0FBUyxDQUFDLEVBQUU7QUFBQSxFQUMzRTtBQUNBLFFBQU0sWUFBWSxTQUFTLE1BQU0sQ0FBQyxFQUFFLFFBQVEsU0FBUyxRQUFRO0FBRTdELFFBQU0sRUFBRSxVQUFVLDRCQUE0QixJQUFJO0FBQUEsSUFDaEQ7QUFBQSxJQUNBLE9BQU87QUFBQSxNQUNMLElBQUksTUFBTSxTQUFTO0FBQUEsSUFDckI7QUFBQSxJQUNBLEVBQUUsU0FBUyxXQUFXLGFBQWEsTUFBTTtBQUFBLEVBQzNDO0FBQ0EsUUFBTSxTQUFTLGdCQUFnQixFQUFFO0FBQ2pDLFFBQU0sRUFBRSxhQUFhLElBQUksMkJBQTJCO0FBQ3BELFFBQU0sRUFBRSx5QkFBeUIsSUFBSSw0QkFBNEI7QUFDakUsUUFBTSxFQUFFLE9BQU8sSUFBSSxjQUFjO0FBRWpDLDhCQUE0QixDQUFDLFFBQVE7QUFDbkMsUUFBSSxDQUFDLElBQUksTUFBTSw0QkFBNEIsTUFBTSxDQUFDLFFBQVEsTUFBTztBQUNqRSxVQUFNLFFBQVEsSUFBSSxLQUFLO0FBRXZCLFFBQUksTUFBTSxTQUFTLHVDQUF1QyxTQUFTO0FBRWpFO0FBQUEsUUFJRSxPQUFPO0FBQUEsUUFDUCxXQUFXLFdBQVcsTUFBTSxTQUFTLENBQUM7QUFBQSxRQUN0QyxDQUFDLFlBQVksWUFBWSxPQUFPLEVBQUUsSUFBSSxNQUFNO0FBQzFDLGdCQUFNLGlCQUFpQixTQUFTLENBQUMsR0FBRyxNQUFNO0FBQzFDLHdCQUFjLEtBQUssSUFBSSxjQUFjLE1BQU0sRUFBRSxDQUFDO0FBQzlDLGlCQUFPO0FBQUEsUUFDVDtBQUFBLFFBQ0EsRUFBRSxvQkFBb0IsQ0FBQyx1QkFBdUIsRUFBRTtBQUFBLE1BQ2xEO0FBQUEsSUFDRixXQUFXLE1BQU0sU0FBUyx1Q0FBdUMsU0FBUztBQUd4RSxZQUFNLFVBQ0osTUFBTSxNQUFNLG9CQUFvQiwwQkFBMEI7QUFDNUQsWUFBTSxVQUFVLE1BQU0sTUFBTSxvQkFBb0IsMEJBQTBCO0FBQzFFLFlBQU0sV0FBVyxNQUFNLE1BQU07QUFFN0IsVUFBSSxXQUFXLFVBQVU7QUFDdkI7QUFBQSxVQUlFLE9BQU87QUFBQSxVQUNQLFdBQVcsV0FBVyxNQUFNLFNBQVMsQ0FBQztBQUFBLFVBQ3RDLENBQUMsWUFBWSxZQUFZLE9BQU8sRUFBRSxJQUFJLE1BQU07QUFDMUMsZ0JBQUksQ0FBQyxPQUFPLE9BQVE7QUFFcEIsa0JBQU0saUJBQWlCLFNBQVMsQ0FBQyxHQUFHO0FBQUEsY0FDbEMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxJQUFJLGNBQWMsTUFBTSxFQUFFLEVBQUU7QUFBQSxZQUNqRDtBQUNBLG1CQUFPO0FBQUEsVUFDVDtBQUFBLFVBQ0EsRUFBRSxvQkFBb0IsQ0FBQyx1QkFBdUIsRUFBRTtBQUFBLFFBQ2xEO0FBQUEsTUFDRixXQUFXLFNBQVM7QUFFbEIsWUFBSSxNQUFNLE1BQU0sV0FBVyxPQUFPLE9BQU87QUFDdkMsdUJBQWEseUJBQXlCLE1BQU0sS0FBSyxDQUFDO0FBQUEsUUFDcEQ7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0YsQ0FBQztBQUVELDhCQUE0QixDQUFDLFFBQVE7QUFDbkMsUUFBSSxDQUFDLElBQUksTUFBTSw0QkFBNEIsR0FBSTtBQUMvQyxVQUFNLFFBQVEsSUFBSSxLQUFLO0FBQ3ZCLGNBQVUsT0FBTyxPQUFPLEtBQUs7QUFBQSxFQUMvQixDQUFDO0FBQ0g7QUFFQSxRQUFRO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLENBTVA7QUFFTSxnQkFBUyxtQkFBbUI7QUFDakMsUUFBTSxFQUFFLEtBQUssSUFBSSxhQUFhO0FBQzlCLFFBQU0sRUFBRSxvQkFBb0IsSUFBSSxlQUFlO0FBRS9DLFNBQU8sT0FBTyxXQUdSO0FBQ0osVUFBTSxFQUFFLE9BQU8sVUFBVSxJQUFJO0FBRTdCLFFBQUksS0FBWSxFQUFRO0FBQ3RCLFlBQU0sSUFBSSxNQUFNLHNCQUFzQjtBQUFBLElBQ3hDO0FBRUEsVUFBTSxPQUFPLGtCQUFrQixPQUFPLFNBQVM7QUFDL0MsVUFBTSxNQUFNLElBQUksSUFBSSxNQUFNLE9BQU8sU0FBUyxTQUFTLENBQUMsRUFBRSxTQUFTO0FBRS9ELFVBQU0sS0FBSyxHQUFHO0FBQ2Qsd0JBQW9CO0FBQUEsTUFDbEIsTUFBTSxzQkFBc0I7QUFBQSxNQUM1QixPQUFPLFVBQVUsWUFBWSxZQUFZLE9BQU87QUFBQSxJQUNsRCxDQUFDO0FBQUEsRUFDSDtBQUNGIiwibmFtZXMiOlsiZGF0YSJdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtb2RlbE1hbmFnZW1lbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBcG9sbG9DYWNoZSB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2NvcmUnXHJcbmltcG9ydCB7IHVzZUFwb2xsb0NsaWVudCwgdXNlU3Vic2NyaXB0aW9uIH0gZnJvbSAnQHZ1ZS9hcG9sbG8tY29tcG9zYWJsZSdcclxuaW1wb3J0IHsgdXNlQ2xpcGJvYXJkIH0gZnJvbSAnQHZ1ZXVzZS9jb3JlJ1xyXG5pbXBvcnQgdHlwZSB7IE1heWJlUmVmIH0gZnJvbSAnQHZ1ZXVzZS9jb3JlJ1xyXG5pbXBvcnQgdHlwZSB7IEdldCB9IGZyb20gJ3R5cGUtZmVzdCdcclxuaW1wb3J0IHR5cGUgeyBHZW5lcmljVmFsaWRhdGVGdW5jdGlvbiB9IGZyb20gJ3ZlZS12YWxpZGF0ZSdcclxuaW1wb3J0IHsgVG9hc3ROb3RpZmljYXRpb25UeXBlLCB1c2VHbG9iYWxUb2FzdCB9IGZyb20gJ35+L2xpYi9jb21tb24vY29tcG9zYWJsZXMvdG9hc3QnXHJcbmltcG9ydCB0eXBlIHtcclxuICBEZWxldGVNb2RlbElucHV0LFxyXG4gIE9uUHJvamVjdE1vZGVsc1VwZGF0ZVN1YnNjcmlwdGlvbixcclxuICBPblByb2plY3RQZW5kaW5nTW9kZWxzVXBkYXRlZFN1YnNjcmlwdGlvbixcclxuICBQcm9qZWN0LFxyXG4gIFByb2plY3RNb2RlbHNBcmdzLFxyXG4gIFByb2plY3RNb2RlbHNUcmVlQXJncyxcclxuICBQcm9qZWN0UGVuZGluZ0ltcG9ydGVkTW9kZWxzQXJncyxcclxuICBVcGRhdGVNb2RlbElucHV0LFxyXG4gIFVzZUNvcHlNb2RlbExpbmtfTW9kZWxGcmFnbWVudFxyXG59IGZyb20gJ35+L2xpYi9jb21tb24vZ2VuZXJhdGVkL2dxbC9ncmFwaHFsJ1xyXG5pbXBvcnQge1xyXG4gIFByb2plY3RNb2RlbHNVcGRhdGVkTWVzc2FnZVR5cGUsXHJcbiAgUHJvamVjdFBlbmRpbmdNb2RlbHNVcGRhdGVkTWVzc2FnZVR5cGVcclxufSBmcm9tICd+fi9saWIvY29tbW9uL2dlbmVyYXRlZC9ncWwvZ3JhcGhxbCdcclxuaW1wb3J0IHtcclxuICBjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQsXHJcbiAgZXZpY3RPYmplY3RGaWVsZHMsXHJcbiAgZ2V0Q2FjaGVJZCxcclxuICBnZXRGaXJzdEVycm9yTWVzc2FnZSxcclxuICBtb2RpZnlPYmplY3RGaWVsZHNcclxufSBmcm9tICd+fi9saWIvY29tbW9uL2hlbHBlcnMvZ3JhcGhxbCdcclxuaW1wb3J0IHsgaXNSZXF1aXJlZCwgaXNTdHJpbmdPZkxlbmd0aCB9IGZyb20gJ35+L2xpYi9jb21tb24vaGVscGVycy92YWxpZGF0aW9uJ1xyXG5pbXBvcnQge1xyXG4gIGNyZWF0ZU1vZGVsTXV0YXRpb24sXHJcbiAgZGVsZXRlTW9kZWxNdXRhdGlvbixcclxuICB1cGRhdGVNb2RlbE11dGF0aW9uXHJcbn0gZnJvbSAnfn4vbGliL3Byb2plY3RzL2dyYXBocWwvbXV0YXRpb25zJ1xyXG5pbXBvcnQge1xyXG4gIG9uUHJvamVjdE1vZGVsc1VwZGF0ZVN1YnNjcmlwdGlvbixcclxuICBvblByb2plY3RQZW5kaW5nTW9kZWxzVXBkYXRlZFN1YnNjcmlwdGlvblxyXG59IGZyb20gJ35+L2xpYi9wcm9qZWN0cy9ncmFwaHFsL3N1YnNjcmlwdGlvbnMnXHJcbmltcG9ydCB7IHVzZU5hdmlnYXRlVG9Qcm9qZWN0IH0gZnJvbSAnfn4vbGliL2NvbW1vbi9oZWxwZXJzL3JvdXRlJ1xyXG5pbXBvcnQgeyBGaWxlVXBsb2FkQ29udmVydGVkU3RhdHVzIH0gZnJvbSAnfn4vbGliL2NvcmUvYXBpL2ZpbGVJbXBvcnQnXHJcbmltcG9ydCB7IHVzZUxvY2sgfSBmcm9tICd+fi9saWIvY29tbW9uL2NvbXBvc2FibGVzL3NpbmdsZXRvbidcclxuaW1wb3J0IHsgaXNVbmRlZmluZWQgfSBmcm9tICdsb2Rhc2gtZXMnXHJcbmltcG9ydCB7XHJcbiAgdXNlRmFpbGVkRmlsZUltcG9ydEpvYlV0aWxzLFxyXG4gIHVzZUdsb2JhbEZpbGVJbXBvcnRNYW5hZ2VyXHJcbn0gZnJvbSAnfi9saWIvY29yZS9jb21wb3NhYmxlcy9maWxlSW1wb3J0J1xyXG5pbXBvcnQgeyBncmFwaHFsIH0gZnJvbSAnfi9saWIvY29tbW9uL2dlbmVyYXRlZC9ncWwnXHJcbmltcG9ydCB7IGdldE1vZGVsSXRlbVJvdXRlIH0gZnJvbSAnfi9saWIvcHJvamVjdHMvaGVscGVycy9tb2RlbHMnXHJcblxyXG5jb25zdCBpc1ZhbGlkTW9kZWxOYW1lOiBHZW5lcmljVmFsaWRhdGVGdW5jdGlvbjxzdHJpbmc+ID0gKG5hbWUpID0+IHtcclxuICBuYW1lID0gbmFtZS50cmltKClcclxuICBpZiAoXHJcbiAgICBuYW1lLnN0YXJ0c1dpdGgoJy8nKSB8fFxyXG4gICAgbmFtZS5lbmRzV2l0aCgnLycpIHx8XHJcbiAgICBuYW1lLnN0YXJ0c1dpdGgoJyMnKSB8fFxyXG4gICAgbmFtZS5zdGFydHNXaXRoKCckJykgfHxcclxuICAgIG5hbWUuaW5kZXhPZignLy8nKSAhPT0gLTEgfHxcclxuICAgIG5hbWUuaW5kZXhPZignLCcpICE9PSAtMVxyXG4gIClcclxuICAgIHJldHVybiAnVmFsdWUgc2hvdWxkIG5vdCBzdGFydCB3aXRoIFwiI1wiLCBcIiRcIiwgc3RhcnQgb3IgZW5kIHdpdGggXCIvXCIsIGhhdmUgbXVsdGlwbGUgc2xhc2hlcyBuZXh0IHRvIGVhY2ggb3RoZXIgb3IgY29udGFpbiBjb21tYXMnXHJcblxyXG4gIGlmIChbJ2dsb2JhbHMnLCAnbWFpbiddLmluY2x1ZGVzKG5hbWUpKVxyXG4gICAgcmV0dXJuIGAnbWFpbicgYW5kICdnbG9iYWxzJyBhcmUgcmVzZXJ2ZWQgbmFtZXNgXHJcblxyXG4gIHJldHVybiB0cnVlXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VNb2RlbE5hbWVWYWxpZGF0aW9uUnVsZXMoKSB7XHJcbiAgcmV0dXJuIGNvbXB1dGVkKCgpID0+IFtcclxuICAgIGlzUmVxdWlyZWQsXHJcbiAgICBpc1N0cmluZ09mTGVuZ3RoKHsgbWF4TGVuZ3RoOiA1MTIgfSksXHJcbiAgICBpc1ZhbGlkTW9kZWxOYW1lXHJcbiAgXSlcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZUV2aWN0UHJvamVjdE1vZGVsRmllbGRzKCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IGNhY2hlID0gYXBvbGxvLmNhY2hlXHJcbiAgcmV0dXJuIChwcm9qZWN0SWQ6IHN0cmluZykgPT4ge1xyXG4gICAgLy8gTWFudWFsIGNhY2hlIHVwZGF0ZXMgd2hlbiBuZXcgbW9kZWxzIGFyZSBjcmVhdGVkIGFyZSB0b28gb3ZlcndoZWxtaW5nLCB0aGVyZSdzIG11bHRpcGxlIHBsYWNlcyBpbiB0aGUgZ3JhcGhcclxuICAgIC8vIHdoZXJlIHlvdSBjYW4gZmluZCBhIG1vZGVsLCBzb21lIG9mIHdoaWNoIG9yZGVyIG1vZGVscyBpbiBhIHRyZWUgc3RydWN0dXJlXHJcbiAgICAvLyBzbyB3ZSdyZSBqdXN0IGV2aWN0aW5nIGFsbCBQcm9qZWN0IG1vZGVsIHJlbGF0ZWQgZmllbGRzXHJcbiAgICBldmljdE9iamVjdEZpZWxkcyhjYWNoZSwgZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHByb2plY3RJZCksIChmaWVsZCkgPT4ge1xyXG4gICAgICByZXR1cm4gW1xuICAgICAgICAnbW9kZWxzJyxcbiAgICAgICAgJ21vZGVsc1RyZWUnLFxuICAgICAgICAnbW9kZWwnLFxuICAgICAgICAnbW9kZWxDaGlsZHJlblRyZWUnLFxuICAgICAgICAndmlld2VyUmVzb3VyY2VzJyxcbiAgICAgICAgJ3ZpZXdlclJlc291cmNlc0V4dGVuZGVkJ1xuICAgICAgXS5pbmNsdWRlcyhmaWVsZClcbiAgICB9KVxuICB9XG59XG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZUNyZWF0ZU5ld01vZGVsKCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG4gIGNvbnN0IGV2aWN0UHJvamVjdE1vZGVscyA9IHVzZUV2aWN0UHJvamVjdE1vZGVsRmllbGRzKClcclxuXHJcbiAgcmV0dXJuIGFzeW5jICh2YWx1ZXM6IHsgbmFtZTogc3RyaW5nOyBkZXNjcmlwdGlvbjogc3RyaW5nOyBwcm9qZWN0SWQ6IHN0cmluZyB9KSA9PiB7XHJcbiAgICBjb25zdCB7IG5hbWUsIGRlc2NyaXB0aW9uLCBwcm9qZWN0SWQgfSA9IHZhbHVlc1xyXG5cclxuICAgIGNvbnN0IHsgZGF0YSwgZXJyb3JzIH0gPSBhd2FpdCBhcG9sbG9cclxuICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgbXV0YXRpb246IGNyZWF0ZU1vZGVsTXV0YXRpb24sXHJcbiAgICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAgICBuYW1lLFxyXG4gICAgICAgICAgICBkZXNjcmlwdGlvbixcclxuICAgICAgICAgICAgcHJvamVjdElkXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICB1cGRhdGU6IChfY2FjaGUsIHsgZGF0YSB9KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIWRhdGE/Lm1vZGVsTXV0YXRpb25zPy5jcmVhdGU/LmlkKSByZXR1cm5cclxuICAgICAgICAgIGV2aWN0UHJvamVjdE1vZGVscyhwcm9qZWN0SWQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChkYXRhPy5tb2RlbE11dGF0aW9ucz8uY3JlYXRlPy5pZCkge1xyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuU3VjY2VzcyxcclxuICAgICAgICB0aXRsZTogJ05ldyBtb2RlbCBjcmVhdGVkJ1xyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnTW9kZWwgY3JlYXRpb24gZmFpbGVkJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyTXNnXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRhdGE/Lm1vZGVsTXV0YXRpb25zPy5jcmVhdGVcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VVcGRhdGVNb2RlbCgpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuXHJcbiAgcmV0dXJuIGFzeW5jIChpbnB1dDogVXBkYXRlTW9kZWxJbnB1dCkgPT4ge1xyXG4gICAgY29uc3QgeyBkYXRhLCBlcnJvcnMgfSA9IGF3YWl0IGFwb2xsb1xyXG4gICAgICAubXV0YXRlKHtcclxuICAgICAgICBtdXRhdGlvbjogdXBkYXRlTW9kZWxNdXRhdGlvbixcclxuICAgICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICAgIGlucHV0XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChkYXRhPy5tb2RlbE11dGF0aW9ucy51cGRhdGUuaWQpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6ICdNb2RlbCB1cGRhdGVkJ1xyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnTW9kZWwgdXBkYXRlIGZhaWxlZCcsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGVyck1zZ1xyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkYXRhPy5tb2RlbE11dGF0aW9ucy51cGRhdGVcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VEZWxldGVNb2RlbCgpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuICBjb25zdCBldmljdFByb2plY3RNb2RlbHMgPSB1c2VFdmljdFByb2plY3RNb2RlbEZpZWxkcygpXHJcblxyXG4gIHJldHVybiBhc3luYyAoaW5wdXQ6IERlbGV0ZU1vZGVsSW5wdXQpID0+IHtcclxuICAgIGNvbnN0IHsgZGF0YSwgZXJyb3JzIH0gPSBhd2FpdCBhcG9sbG9cclxuICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgbXV0YXRpb246IGRlbGV0ZU1vZGVsTXV0YXRpb24sXHJcbiAgICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgICBpbnB1dFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdXBkYXRlOiAoY2FjaGUsIHJlcykgPT4ge1xyXG4gICAgICAgICAgaWYgKCFyZXMuZGF0YT8ubW9kZWxNdXRhdGlvbnMuZGVsZXRlKSByZXR1cm5cclxuXHJcbiAgICAgICAgICBjYWNoZS5ldmljdCh7XHJcbiAgICAgICAgICAgIGlkOiBnZXRDYWNoZUlkKCdNb2RlbCcsIGlucHV0LmlkKVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICAgIGV2aWN0UHJvamVjdE1vZGVscyhpbnB1dC5wcm9qZWN0SWQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChkYXRhPy5tb2RlbE11dGF0aW9ucy5kZWxldGUpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6ICdNb2RlbCBkZWxldGVkJ1xyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnTW9kZWwgZGVsZXRlIGZhaWxlZCcsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGVyck1zZ1xyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAhIWRhdGE/Lm1vZGVsTXV0YXRpb25zLmRlbGV0ZVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFRyYWNrIHByb2plY3QgbW9kZWwgdXBkYXRlcy9kZWxldGVzIGFuZCBtYWtlIGNhY2hlIHVwZGF0ZXMgYWNjb3JkaW5nbHkuIE9wdGlvbmFsbHlcclxuICogcHJvdmlkZSBhbiBleHRyYSBoYW5kbGVyIHRoYXQgeW91IGNhbiB1c2UgdG8gcmVhY3QgdG8gYWxsIG1vZGVsIHVwZGF0ZSBldmVudHMgKGNyZWF0ZS91cGRhdGUvZGVsZXRlKVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZVByb2plY3RNb2RlbFVwZGF0ZVRyYWNraW5nKFxyXG4gIHByb2plY3RJZDogTWF5YmVSZWY8c3RyaW5nPixcclxuICBoYW5kbGVyPzogKFxyXG4gICAgZGF0YTogTm9uTnVsbGFibGU8R2V0PE9uUHJvamVjdE1vZGVsc1VwZGF0ZVN1YnNjcmlwdGlvbiwgJ3Byb2plY3RNb2RlbHNVcGRhdGVkJz4+LFxyXG4gICAgY2FjaGU6IEFwb2xsb0NhY2hlPHVua25vd24+XHJcbiAgKSA9PiB2b2lkLFxyXG4gIG9wdGlvbnM/OiBQYXJ0aWFsPHsgcmVkaXJlY3RUb1Byb2plY3RPbk1vZGVsRGVsZXRpb246IChtb2RlbElkOiBzdHJpbmcpID0+IGJvb2xlYW4gfT5cclxuKSB7XHJcbiAgY29uc3QgeyBoYXNMb2NrIH0gPSB1c2VMb2NrKFxyXG4gICAgY29tcHV0ZWQoKCkgPT4gYHVzZVByb2plY3RNb2RlbFVwZGF0ZVRyYWNraW5nLSR7dW5yZWYocHJvamVjdElkKX1gKVxyXG4gIClcclxuICBjb25zdCBpc0VuYWJsZWQgPSBjb21wdXRlZCgoKSA9PiAhIShoYXNMb2NrLnZhbHVlIHx8IGhhbmRsZXIpKVxyXG4gIGNvbnN0IHsgb25SZXN1bHQ6IG9uUHJvamVjdE1vZGVsVXBkYXRlIH0gPSB1c2VTdWJzY3JpcHRpb24oXHJcbiAgICBvblByb2plY3RNb2RlbHNVcGRhdGVTdWJzY3JpcHRpb24sXHJcbiAgICAoKSA9PiAoe1xyXG4gICAgICBpZDogdW5yZWYocHJvamVjdElkKVxyXG4gICAgfSksXHJcbiAgICB7IGVuYWJsZWQ6IGlzRW5hYmxlZCwgZXJyb3JQb2xpY3k6ICdhbGwnIH1cclxuICApXHJcblxyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IGV2aWN0UHJvamVjdE1vZGVscyA9IHVzZUV2aWN0UHJvamVjdE1vZGVsRmllbGRzKClcclxuICBjb25zdCBnb1RvUHJvamVjdCA9IHVzZU5hdmlnYXRlVG9Qcm9qZWN0KClcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuXHJcbiAgb25Qcm9qZWN0TW9kZWxVcGRhdGUoKHJlcykgPT4ge1xyXG4gICAgaWYgKCFyZXMuZGF0YT8ucHJvamVjdE1vZGVsc1VwZGF0ZWQgfHwgIWhhc0xvY2sudmFsdWUpIHJldHVyblxyXG5cclxuICAgIC8vIElmIG1vZGVsIHdhcyB1cGRhdGVkLCBhcG9sbG8gYWxyZWFkeSB1cGRhdGVkIGl0XHJcbiAgICBjb25zdCBldmVudCA9IHJlcy5kYXRhLnByb2plY3RNb2RlbHNVcGRhdGVkXHJcbiAgICBjb25zdCBpc0RlbGV0ZSA9IGV2ZW50LnR5cGUgPT09IFByb2plY3RNb2RlbHNVcGRhdGVkTWVzc2FnZVR5cGUuRGVsZXRlZFxyXG4gICAgY29uc3QgbW9kZWwgPSBldmVudC5tb2RlbFxyXG5cclxuICAgIGlmIChpc0RlbGV0ZSkge1xyXG4gICAgICAvLyBFdmljdCBmcm9tIGNhY2hlXHJcbiAgICAgIGFwb2xsby5jYWNoZS5ldmljdCh7XHJcbiAgICAgICAgaWQ6IGdldENhY2hlSWQoJ01vZGVsJywgZXZlbnQuaWQpXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICBpZiAob3B0aW9ucz8ucmVkaXJlY3RUb1Byb2plY3RPbk1vZGVsRGVsZXRpb24/LihldmVudC5pZCkpIHtcclxuICAgICAgICBnb1RvUHJvamVjdCh7IGlkOiB1bnJlZihwcm9qZWN0SWQpIH0pXHJcblxyXG4gICAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkluZm8sXHJcbiAgICAgICAgICB0aXRsZTogJ01vZGVsIGhhcyBiZWVuIGRlbGV0ZWQnLFxyXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdSZWRpcmVjdGluZyB0byBwcm9qZWN0IHBhZ2UgaG9tZSdcclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgY3JlYXRpb24gb3IgZGVsZXRpb24sIHJlZnJlc2ggYWxsIHByb2plY3QncyBtb2RlbCBmaWVsZHNcclxuICAgIGlmIChldmVudC50eXBlID09PSBQcm9qZWN0TW9kZWxzVXBkYXRlZE1lc3NhZ2VUeXBlLkNyZWF0ZWQgfHwgaXNEZWxldGUpIHtcclxuICAgICAgZXZpY3RQcm9qZWN0TW9kZWxzKHVucmVmKHByb2plY3RJZCkpXHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICBldmVudC50eXBlID09PSBQcm9qZWN0TW9kZWxzVXBkYXRlZE1lc3NhZ2VUeXBlLlVwZGF0ZWQgJiZcclxuICAgICAgbW9kZWw/LnZlcnNpb25Db3VudC50b3RhbENvdW50XHJcbiAgICApIHtcclxuICAgICAgLy8gVXBkYXRlZCBtb2RlbCB0aGF0IGhhcyB2ZXJzaW9ucyAtIGl0IG1pZ2h0IG5vdCBoYXZlIGhhZCB0aGVtIHByZXZpb3VzbHksXHJcbiAgICAgIC8vIHNvIGFkZCBpdCB0byB0aGUgcmVsZXZhbnQgbW9kZWwgbGlzdFxyXG4gICAgICBtb2RpZnlPYmplY3RGaWVsZHM8UHJvamVjdE1vZGVsc0FyZ3MsIFByb2plY3RbJ21vZGVscyddPihcclxuICAgICAgICBhcG9sbG8uY2FjaGUsXHJcbiAgICAgICAgZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHVucmVmKHByb2plY3RJZCkpLFxyXG4gICAgICAgIChfZmllbGROYW1lLCB2YXJpYWJsZXMsIHZhbHVlLCB7IHJlZiB9KSA9PiB7XHJcbiAgICAgICAgICBpZiAodmFyaWFibGVzLmZpbHRlcj8uc2VhcmNoKSByZXR1cm5cclxuICAgICAgICAgIGlmICh2YXJpYWJsZXMuZmlsdGVyPy5zb3VyY2VBcHBzPy5sZW5ndGgpIHJldHVyblxyXG4gICAgICAgICAgaWYgKHZhcmlhYmxlcy5maWx0ZXI/LmNvbnRyaWJ1dG9ycz8ubGVuZ3RoKSByZXR1cm5cclxuICAgICAgICAgIGlmICghdmFyaWFibGVzLmZpbHRlcj8ub25seVdpdGhWZXJzaW9ucykgcmV0dXJuXHJcblxyXG4gICAgICAgICAgY29uc3QgbGltaXQgPSB2YXJpYWJsZXMubGltaXRcclxuICAgICAgICAgIGNvbnN0IG5ld01vZGVsUmVmID0gcmVmKCdNb2RlbCcsIG1vZGVsLmlkKVxyXG4gICAgICAgICAgY29uc3QgbmV3SXRlbXMgPSAodmFsdWU/Lml0ZW1zIHx8IFtdKS5zbGljZSgpXHJcblxyXG4gICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAhbmV3SXRlbXMuZmluZCgoaSkgPT4gaS5fX3JlZiA9PT0gbmV3TW9kZWxSZWYuX19yZWYpICYmXHJcbiAgICAgICAgICAgIChpc1VuZGVmaW5lZChsaW1pdCkgfHwgbmV3SXRlbXMubGVuZ3RoIDwgbGltaXQpXHJcbiAgICAgICAgICApIHtcclxuICAgICAgICAgICAgbmV3SXRlbXMudW5zaGlmdChuZXdNb2RlbFJlZilcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi4odmFsdWUgfHwge30pLFxyXG4gICAgICAgICAgICBpdGVtczogbmV3SXRlbXMsXHJcbiAgICAgICAgICAgIHRvdGFsQ291bnQ6ICh2YWx1ZS50b3RhbENvdW50IHx8IDApICsgMVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgeyBmaWVsZE5hbWVXaGl0ZWxpc3Q6IFsnbW9kZWxzJ10gfVxyXG4gICAgICApXHJcblxyXG4gICAgICAvLyArIEV2aWN0IG1vZGVsc1RyZWUsIGlmIGl0IGRvZXNudCBoYXZlIHRoaXMgbW9kZWxcclxuICAgICAgZXZpY3RPYmplY3RGaWVsZHM8UHJvamVjdE1vZGVsc1RyZWVBcmdzLCBQcm9qZWN0Wydtb2RlbHNUcmVlJ10+KFxyXG4gICAgICAgIGFwb2xsby5jYWNoZSxcclxuICAgICAgICBnZXRDYWNoZUlkKCdQcm9qZWN0JywgdW5yZWYocHJvamVjdElkKSksXHJcbiAgICAgICAgKGZpZWxkTmFtZSwgdmFyaWFibGVzLCB2YWx1ZSwgeyByZWFkRmllbGQgfSkgPT4ge1xyXG4gICAgICAgICAgaWYgKGZpZWxkTmFtZSAhPT0gJ21vZGVsc1RyZWUnKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgIGlmICh2YXJpYWJsZXMuZmlsdGVyPy5zZWFyY2gpIHJldHVybiBmYWxzZVxyXG4gICAgICAgICAgaWYgKHZhcmlhYmxlcy5maWx0ZXI/LmNvbnRyaWJ1dG9ycz8ubGVuZ3RoKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgIGlmICh2YXJpYWJsZXMuZmlsdGVyPy5zb3VyY2VBcHBzPy5sZW5ndGgpIHJldHVybiBmYWxzZVxyXG5cclxuICAgICAgICAgIGNvbnN0IGl0ZW1zID0gdmFsdWU/Lml0ZW1zIHx8IFtdXHJcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcclxuICAgICAgICAgICAgY29uc3QgZnVsbE5hbWUgPSByZWFkRmllbGQoJ2Z1bGxOYW1lJywgaXRlbSlcclxuICAgICAgICAgICAgaWYgKGZ1bGxOYW1lID09PSBtb2RlbC5uYW1lKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgKVxyXG4gICAgfVxyXG4gIH0pXHJcblxyXG4gIG9uUHJvamVjdE1vZGVsVXBkYXRlKChyZXMpID0+IHtcclxuICAgIGlmICghcmVzLmRhdGE/LnByb2plY3RNb2RlbHNVcGRhdGVkKSByZXR1cm5cclxuICAgIGNvbnN0IGV2ZW50ID0gcmVzLmRhdGEucHJvamVjdE1vZGVsc1VwZGF0ZWRcclxuICAgIGhhbmRsZXI/LihldmVudCwgYXBvbGxvLmNhY2hlKVxyXG4gIH0pXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VQcm9qZWN0UGVuZGluZ01vZGVsVXBkYXRlVHJhY2tpbmcoXHJcbiAgcHJvamVjdElkOiBNYXliZVJlZjxzdHJpbmc+LFxyXG4gIGhhbmRsZXI/OiAoXHJcbiAgICBkYXRhOiBOb25OdWxsYWJsZTxcclxuICAgICAgR2V0PE9uUHJvamVjdFBlbmRpbmdNb2RlbHNVcGRhdGVkU3Vic2NyaXB0aW9uLCAncHJvamVjdFBlbmRpbmdNb2RlbHNVcGRhdGVkJz5cclxuICAgID4sXHJcbiAgICBjYWNoZTogQXBvbGxvQ2FjaGU8dW5rbm93bj5cclxuICApID0+IHZvaWRcclxuKSB7XHJcbiAgY29uc3QgeyBoYXNMb2NrIH0gPSB1c2VMb2NrKFxyXG4gICAgY29tcHV0ZWQoKCkgPT4gYHVzZVByb2plY3RQZW5kaW5nTW9kZWxVcGRhdGVUcmFja2luZy0ke3VucmVmKHByb2plY3RJZCl9YClcclxuICApXHJcbiAgY29uc3QgaXNFbmFibGVkID0gY29tcHV0ZWQoKCkgPT4gISEoaGFzTG9jay52YWx1ZSB8fCBoYW5kbGVyKSlcclxuXHJcbiAgY29uc3QgeyBvblJlc3VsdDogb25Qcm9qZWN0UGVuZGluZ01vZGVsVXBkYXRlIH0gPSB1c2VTdWJzY3JpcHRpb24oXHJcbiAgICBvblByb2plY3RQZW5kaW5nTW9kZWxzVXBkYXRlZFN1YnNjcmlwdGlvbixcclxuICAgICgpID0+ICh7XHJcbiAgICAgIGlkOiB1bnJlZihwcm9qZWN0SWQpXHJcbiAgICB9KSxcclxuICAgIHsgZW5hYmxlZDogaXNFbmFibGVkLCBlcnJvclBvbGljeTogJ2FsbCcgfVxyXG4gIClcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IGFkZEZhaWxlZEpvYiB9ID0gdXNlR2xvYmFsRmlsZUltcG9ydE1hbmFnZXIoKVxyXG4gIGNvbnN0IHsgY29udmVydFVwbG9hZFRvRmFpbGVkSm9iIH0gPSB1c2VGYWlsZWRGaWxlSW1wb3J0Sm9iVXRpbHMoKVxyXG4gIGNvbnN0IHsgdXNlcklkIH0gPSB1c2VBY3RpdmVVc2VyKClcclxuXHJcbiAgb25Qcm9qZWN0UGVuZGluZ01vZGVsVXBkYXRlKChyZXMpID0+IHtcclxuICAgIGlmICghcmVzLmRhdGE/LnByb2plY3RQZW5kaW5nTW9kZWxzVXBkYXRlZC5pZCB8fCAhaGFzTG9jay52YWx1ZSkgcmV0dXJuXHJcbiAgICBjb25zdCBldmVudCA9IHJlcy5kYXRhLnByb2plY3RQZW5kaW5nTW9kZWxzVXBkYXRlZFxyXG5cclxuICAgIGlmIChldmVudC50eXBlID09PSBQcm9qZWN0UGVuZGluZ01vZGVsc1VwZGF0ZWRNZXNzYWdlVHlwZS5DcmVhdGVkKSB7XHJcbiAgICAgIC8vIEluc2VydCBpbnRvIHByb2plY3QucGVuZGluZ01vZGVsc1xyXG4gICAgICBtb2RpZnlPYmplY3RGaWVsZHM8XHJcbiAgICAgICAgUHJvamVjdFBlbmRpbmdJbXBvcnRlZE1vZGVsc0FyZ3MsXHJcbiAgICAgICAgUHJvamVjdFsncGVuZGluZ0ltcG9ydGVkTW9kZWxzJ11cclxuICAgICAgPihcclxuICAgICAgICBhcG9sbG8uY2FjaGUsXHJcbiAgICAgICAgZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHVucmVmKHByb2plY3RJZCkpLFxyXG4gICAgICAgIChfZmllbGROYW1lLCBfdmFyaWFibGVzLCB2YWx1ZSwgeyByZWYgfSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgY3VycmVudE1vZGVscyA9ICh2YWx1ZSB8fCBbXSkuc2xpY2UoKVxyXG4gICAgICAgICAgY3VycmVudE1vZGVscy5wdXNoKHJlZignRmlsZVVwbG9hZCcsIGV2ZW50LmlkKSlcclxuICAgICAgICAgIHJldHVybiBjdXJyZW50TW9kZWxzXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWydwZW5kaW5nSW1wb3J0ZWRNb2RlbHMnXSB9XHJcbiAgICAgIClcclxuICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gUHJvamVjdFBlbmRpbmdNb2RlbHNVcGRhdGVkTWVzc2FnZVR5cGUuVXBkYXRlZCkge1xyXG4gICAgICAvLyBJZiBjb252ZXJ0ZWQgZW1pdCB0b2FzdCBub3RpZmljYXRpb24gJiByZW1vdmUgZnJvbSBwZW5kaW5nIG1vZGVsc1xyXG4gICAgICAvLyAoaWYgaXQgc3RpbGwgZXhpc3RzIHRoZXJlLCBjYXVzZSBcInZlcnNpb24gY3JlYXRlXCIgc3Vic2NyaXB0aW9uIG1pZ2h0J3ZlIGFscmVhZHkgcmVtb3ZlZCBpdClcclxuICAgICAgY29uc3Qgc3VjY2VzcyA9XHJcbiAgICAgICAgZXZlbnQubW9kZWwuY29udmVydGVkU3RhdHVzID09PSBGaWxlVXBsb2FkQ29udmVydGVkU3RhdHVzLkNvbXBsZXRlZFxyXG4gICAgICBjb25zdCBmYWlsdXJlID0gZXZlbnQubW9kZWwuY29udmVydGVkU3RhdHVzID09PSBGaWxlVXBsb2FkQ29udmVydGVkU3RhdHVzLkVycm9yXHJcbiAgICAgIGNvbnN0IG5ld01vZGVsID0gZXZlbnQubW9kZWwubW9kZWxcclxuXHJcbiAgICAgIGlmIChzdWNjZXNzICYmIG5ld01vZGVsKSB7XHJcbiAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPFxyXG4gICAgICAgICAgUHJvamVjdFBlbmRpbmdJbXBvcnRlZE1vZGVsc0FyZ3MsXHJcbiAgICAgICAgICBQcm9qZWN0WydwZW5kaW5nSW1wb3J0ZWRNb2RlbHMnXVxyXG4gICAgICAgID4oXHJcbiAgICAgICAgICBhcG9sbG8uY2FjaGUsXHJcbiAgICAgICAgICBnZXRDYWNoZUlkKCdQcm9qZWN0JywgdW5yZWYocHJvamVjdElkKSksXHJcbiAgICAgICAgICAoX2ZpZWxkTmFtZSwgX3ZhcmlhYmxlcywgdmFsdWUsIHsgcmVmIH0pID0+IHtcclxuICAgICAgICAgICAgaWYgKCF2YWx1ZT8ubGVuZ3RoKSByZXR1cm5cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRNb2RlbHMgPSAodmFsdWUgfHwgW10pLmZpbHRlcihcclxuICAgICAgICAgICAgICAoaSkgPT4gaS5fX3JlZiAhPT0gcmVmKCdGaWxlVXBsb2FkJywgZXZlbnQuaWQpLl9fcmVmXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRNb2RlbHNcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWydwZW5kaW5nSW1wb3J0ZWRNb2RlbHMnXSB9XHJcbiAgICAgICAgKVxyXG4gICAgICB9IGVsc2UgaWYgKGZhaWx1cmUpIHtcclxuICAgICAgICAvLyBSZXBvcnQgdy8gZGlhbG9nIHRvIHVwbG9hZGVyIHVzZXJcclxuICAgICAgICBpZiAoZXZlbnQubW9kZWwudXNlcklkID09PSB1c2VySWQudmFsdWUpIHtcclxuICAgICAgICAgIGFkZEZhaWxlZEpvYihjb252ZXJ0VXBsb2FkVG9GYWlsZWRKb2IoZXZlbnQubW9kZWwpKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pXHJcblxyXG4gIG9uUHJvamVjdFBlbmRpbmdNb2RlbFVwZGF0ZSgocmVzKSA9PiB7XHJcbiAgICBpZiAoIXJlcy5kYXRhPy5wcm9qZWN0UGVuZGluZ01vZGVsc1VwZGF0ZWQuaWQpIHJldHVyblxyXG4gICAgY29uc3QgZXZlbnQgPSByZXMuZGF0YS5wcm9qZWN0UGVuZGluZ01vZGVsc1VwZGF0ZWRcclxuICAgIGhhbmRsZXI/LihldmVudCwgYXBvbGxvLmNhY2hlKVxyXG4gIH0pXHJcbn1cclxuXHJcbmdyYXBocWwoYFxyXG4gIGZyYWdtZW50IFVzZUNvcHlNb2RlbExpbmtfTW9kZWwgb24gTW9kZWwge1xyXG4gICAgaWRcclxuICAgIHByb2plY3RJZFxyXG4gICAgLi4uR2V0TW9kZWxJdGVtUm91dGVfTW9kZWxcclxuICB9XHJcbmApXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlQ29weU1vZGVsTGluaygpIHtcclxuICBjb25zdCB7IGNvcHkgfSA9IHVzZUNsaXBib2FyZCgpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcblxyXG4gIHJldHVybiBhc3luYyAocGFyYW1zOiB7XHJcbiAgICBtb2RlbDogVXNlQ29weU1vZGVsTGlua19Nb2RlbEZyYWdtZW50IHwgeyBwcm9qZWN0SWQ6IHN0cmluZzsgaWQ6IHN0cmluZyB9XHJcbiAgICB2ZXJzaW9uSWQ/OiBzdHJpbmdcclxuICB9KSA9PiB7XHJcbiAgICBjb25zdCB7IG1vZGVsLCB2ZXJzaW9uSWQgfSA9IHBhcmFtc1xyXG5cclxuICAgIGlmIChpbXBvcnQubWV0YS5zZXJ2ZXIpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3Qgc3VwcG9ydGVkIGluIFNTUicpXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcGF0aCA9IGdldE1vZGVsSXRlbVJvdXRlKG1vZGVsLCB2ZXJzaW9uSWQpXHJcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHBhdGgsIHdpbmRvdy5sb2NhdGlvbi50b1N0cmluZygpKS50b1N0cmluZygpXHJcblxyXG4gICAgYXdhaXQgY29weSh1cmwpXHJcbiAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkluZm8sXHJcbiAgICAgIHRpdGxlOiBgQ29waWVkICR7dmVyc2lvbklkID8gJ3ZlcnNpb24nIDogJ21vZGVsJ30gbGluayB0byBjbGlwYm9hcmRgXHJcbiAgICB9KVxyXG4gIH1cclxufVxyXG4iXSwiZmlsZSI6IkQ6L3NwZWNrbGUtc2VydmVyL3BhY2thZ2VzL2Zyb250ZW5kLTIvbGliL3Byb2plY3RzL2NvbXBvc2FibGVzL21vZGVsTWFuYWdlbWVudC50cyJ9 |