264 lines
28 KiB
Plaintext
264 lines
28 KiB
Plaintext
import {
|
|
Automate,
|
|
ensureError
|
|
} from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/index.js";
|
|
import __vite__cjsImport1_dayjs from "/_nuxt/node_modules/.cache/vite/client/deps/dayjs.js?v=e4f18c29"; const dayjs = __vite__cjsImport1_dayjs.__esModule ? __vite__cjsImport1_dayjs.default : __vite__cjsImport1_dayjs;
|
|
import { orderBy } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
|
|
import { useAuthCookie } from "/_nuxt/lib/auth/composables/auth.ts";
|
|
import { useFunctionRunsStatusSummary } from "/_nuxt/lib/automate/composables/runStatus.ts";
|
|
import {
|
|
useFormatDuration,
|
|
useReactiveNowDate
|
|
} from "/_nuxt/lib/common/composables/datetime.ts";
|
|
import { graphql } from "/_nuxt/lib/common/generated/gql/index.ts";
|
|
import {
|
|
AutomateRunStatus
|
|
} from "/_nuxt/lib/common/generated/gql/graphql.ts";
|
|
import { abortControllerManager, isAbortError } from "/_nuxt/lib/common/utils/requests.ts";
|
|
import { useViewerRouteBuilder } from "/_nuxt/lib/projects/composables/models.ts";
|
|
|
|
import { computed, unref, ref, watch } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
|
|
import { useApiOrigin } from "/_nuxt/composables/env.ts";
|
|
import { useGlobalToast } from "/_nuxt/composables/globals.ts";
|
|
import { ToastNotificationType } from "/_nuxt/utils/globals.ts";
|
|
graphql(`
|
|
fragment AutomationRunDetails on AutomateRun {
|
|
id
|
|
status
|
|
functionRuns {
|
|
...FunctionRunStatusForSummary
|
|
statusMessage
|
|
}
|
|
trigger {
|
|
... on VersionCreatedTrigger {
|
|
version {
|
|
id
|
|
}
|
|
model {
|
|
id
|
|
}
|
|
}
|
|
}
|
|
createdAt
|
|
updatedAt
|
|
}
|
|
`);
|
|
export const useAutomationRunSummary = (params) => {
|
|
const { run } = params;
|
|
const fnRuns = computed(() => unref(run)?.functionRuns || []);
|
|
const { summary: coreSummary } = useFunctionRunsStatusSummary({
|
|
runs: fnRuns
|
|
});
|
|
const summary = computed(() => {
|
|
const errorMessages = unref(run)?.functionRuns.filter(
|
|
(r) => !!([
|
|
AutomateRunStatus.Failed,
|
|
AutomateRunStatus.Canceled,
|
|
AutomateRunStatus.Exception,
|
|
AutomateRunStatus.Timeout
|
|
].includes(r.status) && r.statusMessage?.length)
|
|
).map((r) => r.statusMessage) || [];
|
|
const errorMessage = errorMessages.length ? errorMessages.join(", ") : void 0;
|
|
return {
|
|
...coreSummary.value,
|
|
errorMessage
|
|
};
|
|
});
|
|
return { summary };
|
|
};
|
|
export const useAutomationRunDetailsFns = () => {
|
|
const formatDuration = useFormatDuration();
|
|
const now = useReactiveNowDate();
|
|
const { versionUrl } = useViewerRouteBuilder();
|
|
const runStatusClasses = (run) => {
|
|
const classParts = ["w-24 justify-center"];
|
|
const status = run.status;
|
|
switch (status) {
|
|
case AutomateRunStatus.Pending:
|
|
case AutomateRunStatus.Initializing:
|
|
classParts.push("bg-warning-lighter");
|
|
break;
|
|
case AutomateRunStatus.Running:
|
|
classParts.push("bg-info-lighter");
|
|
break;
|
|
case AutomateRunStatus.Failed:
|
|
case AutomateRunStatus.Exception:
|
|
case AutomateRunStatus.Canceled:
|
|
case AutomateRunStatus.Timeout:
|
|
classParts.push("bg-danger-lighter");
|
|
break;
|
|
case AutomateRunStatus.Succeeded:
|
|
classParts.push("bg-success-lighter");
|
|
break;
|
|
}
|
|
return classParts.join(" ");
|
|
};
|
|
const runModelVersionUrl = (params) => {
|
|
const {
|
|
run: {
|
|
trigger: { model, version }
|
|
},
|
|
projectId
|
|
} = params;
|
|
return model && version ? versionUrl({
|
|
projectId,
|
|
modelId: model.id,
|
|
versionId: version.id
|
|
}) : null;
|
|
};
|
|
const runDate = (run) => {
|
|
return dayjs(run.createdAt).fromNow();
|
|
};
|
|
const runDuration = (run) => {
|
|
const start = run.createdAt;
|
|
const end = run.status === AutomateRunStatus.Running ? now.value : [AutomateRunStatus.Initializing, AutomateRunStatus.Pending].includes(run.status) ? void 0 : run.updatedAt;
|
|
if (!end) return void 0;
|
|
const diff = dayjs(end).diff(dayjs(start));
|
|
const duration = dayjs.duration(diff);
|
|
const format = formatDuration(duration);
|
|
if (duration.days() > 0) return dayjs.duration(diff).humanize();
|
|
return dayjs.duration(diff).format(format);
|
|
};
|
|
return {
|
|
runStatusClasses,
|
|
runModelVersionUrl,
|
|
runDate,
|
|
runDuration
|
|
};
|
|
};
|
|
export const useAutomationRunLogs = (params) => {
|
|
const { projectId, automationId, runId } = params;
|
|
const apiOrigin = useApiOrigin();
|
|
const authToken = useAuthCookie();
|
|
const { triggerNotification } = useGlobalToast();
|
|
const loading = ref(false);
|
|
const results = ref("");
|
|
const isStreamFinished = ref(false);
|
|
const url = computed(
|
|
() => `/api/v1/projects/${unref(projectId)}/automations/${unref(
|
|
automationId
|
|
)}/runs/${unref(runId)}/logs`
|
|
);
|
|
const key = computed(() => {
|
|
if (!unref(automationId) || !unref(runId)) return null;
|
|
return `automation-run-logs-${unref(automationId)}-${unref(runId)}`;
|
|
});
|
|
const aborts = abortControllerManager();
|
|
const load = async () => {
|
|
results.value = "";
|
|
isStreamFinished.value = false;
|
|
if (!authToken.value) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Log retrieval failed",
|
|
description: "You need to be logged in to load the logs."
|
|
});
|
|
isStreamFinished.value = true;
|
|
return;
|
|
}
|
|
const res = await fetch(new URL(url.value, apiOrigin), {
|
|
signal: aborts.pop().signal,
|
|
headers: {
|
|
Authorization: `Bearer ${authToken.value}`
|
|
}
|
|
}).catch((e) => {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Log retrieval failed",
|
|
description: ensureError(e).message
|
|
});
|
|
throw e;
|
|
});
|
|
if (res.status !== 200) {
|
|
const json = await res.json();
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Couldn't load logs",
|
|
description: json.error?.message || "Something went wrong while loading the logs."
|
|
});
|
|
isStreamFinished.value = true;
|
|
return false;
|
|
}
|
|
const stream = res.body;
|
|
if (stream) {
|
|
const reader = stream.getReader();
|
|
const decoder = new TextDecoder();
|
|
const pump = async () => {
|
|
return reader.read().then(({ done, value }) => {
|
|
if (done) {
|
|
isStreamFinished.value = true;
|
|
return Promise.resolve();
|
|
}
|
|
results.value += decoder.decode(value);
|
|
return pump();
|
|
});
|
|
};
|
|
void pump().catch((e) => {
|
|
if (!isAbortError(e)) {
|
|
throw e;
|
|
}
|
|
});
|
|
}
|
|
return true;
|
|
};
|
|
const loadAndMarkLoading = async () => {
|
|
loading.value = true;
|
|
await load().finally(() => {
|
|
loading.value = false;
|
|
});
|
|
};
|
|
watch(
|
|
key,
|
|
(newKey, oldKey) => {
|
|
if (newKey && newKey !== oldKey) {
|
|
void loadAndMarkLoading();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
return {
|
|
data: computed(() => results.value),
|
|
isDataLoaded: computed(() => isStreamFinished.value),
|
|
loading: computed(() => loading.value)
|
|
};
|
|
};
|
|
export const useAutomationFunctionRunResults = (params) => {
|
|
const { results } = params;
|
|
const ret = computed(
|
|
() => {
|
|
const res = unref(results);
|
|
if (!res) return res;
|
|
if (!Automate.AutomateTypes.isResultsSchema(res)) return null;
|
|
return Automate.AutomateTypes.formatResultsSchema(res);
|
|
}
|
|
);
|
|
return ret;
|
|
};
|
|
graphql(`
|
|
fragment AutomationsStatusOrderedRuns_AutomationRun on AutomateRun {
|
|
id
|
|
automation {
|
|
id
|
|
name
|
|
}
|
|
functionRuns {
|
|
id
|
|
updatedAt
|
|
}
|
|
}
|
|
`);
|
|
export const useAutomationsStatusOrderedRuns = (params) => {
|
|
const { automationRuns } = params;
|
|
const runs = computed(() => {
|
|
const ret = [];
|
|
for (const automationRun of unref(automationRuns)) {
|
|
for (const run of automationRun.functionRuns) {
|
|
ret.push({ ...run, automationName: automationRun.automation.name });
|
|
}
|
|
}
|
|
return orderBy(ret, (r) => new Date(r.updatedAt).getTime(), "desc");
|
|
});
|
|
return { runs };
|
|
};
|
|
|
|
//# sourceMappingURL=data:application/json;base64,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RztBQUFBLElBQ3ZEO0FBQUEsRUFDRjtBQUVBLFNBQU87QUFDVDtBQUVBLFFBQVE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsQ0FZUDtBQUVNLGFBQU0sa0NBQWtDLENBRTdDLFdBRUk7QUFDSixRQUFNLEVBQUUsZUFBZSxJQUFJO0FBRTNCLFFBQU0sT0FBTyxTQUFTLE1BQU07QUFDMUIsVUFBTSxNQUlGLENBQUM7QUFFTCxlQUFXLGlCQUFpQixNQUFNLGNBQWMsR0FBRztBQUNqRCxpQkFBVyxPQUFPLGNBQWMsY0FBYztBQUM1QyxZQUFJLEtBQUssRUFBRSxHQUFHLEtBQUssZ0JBQWdCLGNBQWMsV0FBVyxLQUFLLENBQUM7QUFBQSxNQUNwRTtBQUFBLElBQ0Y7QUFFQSxXQUFPLFFBQVEsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLEVBQUUsU0FBUyxFQUFFLFFBQVEsR0FBRyxNQUFNO0FBQUEsRUFDcEUsQ0FBQztBQUVELFNBQU8sRUFBRSxLQUFLO0FBQ2hCIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJydW5zLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQXV0b21hdGUsXHJcbiAgZW5zdXJlRXJyb3IsXHJcbiAgdHlwZSBNYXliZU51bGxPclVuZGVmaW5lZCxcclxuICB0eXBlIE9wdGlvbmFsXHJcbn0gZnJvbSAnQHNwZWNrbGUvc2hhcmVkJ1xyXG5pbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnXHJcbmltcG9ydCB7IG9yZGVyQnkgfSBmcm9tICdsb2Rhc2gtZXMnXHJcbmltcG9ydCB7IHVzZUF1dGhDb29raWUgfSBmcm9tICd+L2xpYi9hdXRoL2NvbXBvc2FibGVzL2F1dGgnXHJcbmltcG9ydCB7IHVzZUZ1bmN0aW9uUnVuc1N0YXR1c1N1bW1hcnkgfSBmcm9tICd+L2xpYi9hdXRvbWF0ZS9jb21wb3NhYmxlcy9ydW5TdGF0dXMnXHJcbmltcG9ydCB7XHJcbiAgdXNlRm9ybWF0RHVyYXRpb24sXHJcbiAgdXNlUmVhY3RpdmVOb3dEYXRlXHJcbn0gZnJvbSAnfi9saWIvY29tbW9uL2NvbXBvc2FibGVzL2RhdGV0aW1lJ1xyXG5pbXBvcnQgeyBncmFwaHFsIH0gZnJvbSAnfi9saWIvY29tbW9uL2dlbmVyYXRlZC9ncWwnXHJcbmltcG9ydCB7XHJcbiAgQXV0b21hdGVSdW5TdGF0dXMsXHJcbiAgdHlwZSBBdXRvbWF0aW9uUnVuRGV0YWlsc0ZyYWdtZW50LFxyXG4gIHR5cGUgQXV0b21hdGlvbnNTdGF0dXNPcmRlcmVkUnVuc19BdXRvbWF0aW9uUnVuRnJhZ21lbnRcclxufSBmcm9tICd+L2xpYi9jb21tb24vZ2VuZXJhdGVkL2dxbC9ncmFwaHFsJ1xyXG5pbXBvcnQgdHlwZSB7IFNldEZ1bGx5UmVxdWlyZWQgfSBmcm9tICd+L2xpYi9jb21tb24vaGVscGVycy90eXBlJ1xyXG5pbXBvcnQgeyBhYm9ydENvbnRyb2xsZXJNYW5hZ2VyLCBpc0Fib3J0RXJyb3IgfSBmcm9tICd+L2xpYi9jb21tb24vdXRpbHMvcmVxdWVzdHMnXHJcbmltcG9ydCB7IHVzZVZpZXdlclJvdXRlQnVpbGRlciB9IGZyb20gJ34vbGliL3Byb2plY3RzL2NvbXBvc2FibGVzL21vZGVscydcclxuXHJcbmdyYXBocWwoYFxyXG4gIGZyYWdtZW50IEF1dG9tYXRpb25SdW5EZXRhaWxzIG9uIEF1dG9tYXRlUnVuIHtcclxuICAgIGlkXHJcbiAgICBzdGF0dXNcclxuICAgIGZ1bmN0aW9uUnVucyB7XHJcbiAgICAgIC4uLkZ1bmN0aW9uUnVuU3RhdHVzRm9yU3VtbWFyeVxyXG4gICAgICBzdGF0dXNNZXNzYWdlXHJcbiAgICB9XHJcbiAgICB0cmlnZ2VyIHtcclxuICAgICAgLi4uIG9uIFZlcnNpb25DcmVhdGVkVHJpZ2dlciB7XHJcbiAgICAgICAgdmVyc2lvbiB7XHJcbiAgICAgICAgICBpZFxyXG4gICAgICAgIH1cclxuICAgICAgICBtb2RlbCB7XHJcbiAgICAgICAgICBpZFxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgY3JlYXRlZEF0XHJcbiAgICB1cGRhdGVkQXRcclxuICB9XHJcbmApXHJcblxyXG5leHBvcnQgY29uc3QgdXNlQXV0b21hdGlvblJ1blN1bW1hcnkgPSAocGFyYW1zOiB7XHJcbiAgcnVuOiBNYXliZVJlZjxNYXliZU51bGxPclVuZGVmaW5lZDxBdXRvbWF0aW9uUnVuRGV0YWlsc0ZyYWdtZW50Pj5cclxufSkgPT4ge1xyXG4gIGNvbnN0IHsgcnVuIH0gPSBwYXJhbXNcclxuXHJcbiAgY29uc3QgZm5SdW5zID0gY29tcHV0ZWQoKCkgPT4gdW5yZWYocnVuKT8uZnVuY3Rpb25SdW5zIHx8IFtdKVxyXG5cclxuICBjb25zdCB7IHN1bW1hcnk6IGNvcmVTdW1tYXJ5IH0gPSB1c2VGdW5jdGlvblJ1bnNTdGF0dXNTdW1tYXJ5KHtcclxuICAgIHJ1bnM6IGZuUnVuc1xyXG4gIH0pXHJcblxyXG4gIGNvbnN0IHN1bW1hcnkgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICBjb25zdCBlcnJvck1lc3NhZ2VzID1cclxuICAgICAgdW5yZWYocnVuKVxyXG4gICAgICAgID8uZnVuY3Rpb25SdW5zLmZpbHRlcihcclxuICAgICAgICAgIChyKTogciBpcyBTZXRGdWxseVJlcXVpcmVkPHR5cGVvZiByLCAnc3RhdHVzTWVzc2FnZSc+ID0+XHJcbiAgICAgICAgICAgICEhKFxyXG4gICAgICAgICAgICAgIChcclxuICAgICAgICAgICAgICAgIFtcclxuICAgICAgICAgICAgICAgICAgQXV0b21hdGVSdW5TdGF0dXMuRmFpbGVkLFxyXG4gICAgICAgICAgICAgICAgICBBdXRvbWF0ZVJ1blN0YXR1cy5DYW5jZWxlZCxcclxuICAgICAgICAgICAgICAgICAgQXV0b21hdGVSdW5TdGF0dXMuRXhjZXB0aW9uLFxyXG4gICAgICAgICAgICAgICAgICBBdXRvbWF0ZVJ1blN0YXR1cy5UaW1lb3V0XHJcbiAgICAgICAgICAgICAgICBdIGFzIHN0cmluZ1tdXHJcbiAgICAgICAgICAgICAgKS5pbmNsdWRlcyhyLnN0YXR1cykgJiYgci5zdGF0dXNNZXNzYWdlPy5sZW5ndGhcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgIClcclxuICAgICAgICAubWFwKChyKSA9PiByLnN0YXR1c01lc3NhZ2UpIHx8IFtdXHJcbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvck1lc3NhZ2VzLmxlbmd0aCA/IGVycm9yTWVzc2FnZXMuam9pbignLCAnKSA6IHVuZGVmaW5lZFxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIC4uLmNvcmVTdW1tYXJ5LnZhbHVlLFxyXG4gICAgICBlcnJvck1lc3NhZ2VcclxuICAgIH1cclxuICB9KVxyXG5cclxuICByZXR1cm4geyBzdW1tYXJ5IH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHVzZUF1dG9tYXRpb25SdW5EZXRhaWxzRm5zID0gKCkgPT4ge1xyXG4gIGNvbnN0IGZvcm1hdER1cmF0aW9uID0gdXNlRm9ybWF0RHVyYXRpb24oKVxyXG4gIGNvbnN0IG5vdyA9IHVzZVJlYWN0aXZlTm93RGF0ZSgpXHJcbiAgY29uc3QgeyB2ZXJzaW9uVXJsIH0gPSB1c2VWaWV3ZXJSb3V0ZUJ1aWxkZXIoKVxyXG5cclxuICBjb25zdCBydW5TdGF0dXNDbGFzc2VzID0gKHJ1bjogQXV0b21hdGlvblJ1bkRldGFpbHNGcmFnbWVudCkgPT4ge1xyXG4gICAgY29uc3QgY2xhc3NQYXJ0cyA9IFsndy0yNCBqdXN0aWZ5LWNlbnRlciddXHJcbiAgICBjb25zdCBzdGF0dXMgPSBydW4uc3RhdHVzXHJcblxyXG4gICAgc3dpdGNoIChzdGF0dXMpIHtcclxuICAgICAgY2FzZSBBdXRvbWF0ZVJ1blN0YXR1cy5QZW5kaW5nOlxyXG4gICAgICBjYXNlIEF1dG9tYXRlUnVuU3RhdHVzLkluaXRpYWxpemluZzpcclxuICAgICAgICBjbGFzc1BhcnRzLnB1c2goJ2JnLXdhcm5pbmctbGlnaHRlcicpXHJcbiAgICAgICAgYnJlYWtcclxuICAgICAgY2FzZSBBdXRvbWF0ZVJ1blN0YXR1cy5SdW5uaW5nOlxyXG4gICAgICAgIGNsYXNzUGFydHMucHVzaCgnYmctaW5mby1saWdodGVyJylcclxuICAgICAgICBicmVha1xyXG4gICAgICBjYXNlIEF1dG9tYXRlUnVuU3RhdHVzLkZhaWxlZDpcclxuICAgICAgY2FzZSBBdXRvbWF0ZVJ1blN0YXR1cy5FeGNlcHRpb246XHJcbiAgICAgIGNhc2UgQXV0b21hdGVSdW5TdGF0dXMuQ2FuY2VsZWQ6XHJcbiAgICAgIGNhc2UgQXV0b21hdGVSdW5TdGF0dXMuVGltZW91dDpcclxuICAgICAgICBjbGFzc1BhcnRzLnB1c2goJ2JnLWRhbmdlci1saWdodGVyJylcclxuICAgICAgICBicmVha1xyXG4gICAgICBjYXNlIEF1dG9tYXRlUnVuU3RhdHVzLlN1Y2NlZWRlZDpcclxuICAgICAgICBjbGFzc1BhcnRzLnB1c2goJ2JnLXN1Y2Nlc3MtbGlnaHRlcicpXHJcbiAgICAgICAgYnJlYWtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY2xhc3NQYXJ0cy5qb2luKCcgJylcclxuICB9XHJcblxyXG4gIGNvbnN0IHJ1bk1vZGVsVmVyc2lvblVybCA9IChwYXJhbXM6IHtcclxuICAgIHJ1bjogQXV0b21hdGlvblJ1bkRldGFpbHNGcmFnbWVudFxyXG4gICAgcHJvamVjdElkOiBzdHJpbmdcclxuICB9KSA9PiB7XHJcbiAgICBjb25zdCB7XHJcbiAgICAgIHJ1bjoge1xyXG4gICAgICAgIHRyaWdnZXI6IHsgbW9kZWwsIHZlcnNpb24gfVxyXG4gICAgICB9LFxyXG4gICAgICBwcm9qZWN0SWRcclxuICAgIH0gPSBwYXJhbXNcclxuICAgIHJldHVybiBtb2RlbCAmJiB2ZXJzaW9uXHJcbiAgICAgID8gdmVyc2lvblVybCh7XHJcbiAgICAgICAgICBwcm9qZWN0SWQsXHJcbiAgICAgICAgICBtb2RlbElkOiBtb2RlbC5pZCxcclxuICAgICAgICAgIHZlcnNpb25JZDogdmVyc2lvbi5pZFxyXG4gICAgICAgIH0pXHJcbiAgICAgIDogbnVsbFxyXG4gIH1cclxuXHJcbiAgY29uc3QgcnVuRGF0ZSA9IChydW46IEF1dG9tYXRpb25SdW5EZXRhaWxzRnJhZ21lbnQpID0+IHtcclxuICAgIHJldHVybiBkYXlqcyhydW4uY3JlYXRlZEF0KS5mcm9tTm93KClcclxuICB9XHJcblxyXG4gIGNvbnN0IHJ1bkR1cmF0aW9uID0gKHJ1bjogQXV0b21hdGlvblJ1bkRldGFpbHNGcmFnbWVudCkgPT4ge1xyXG4gICAgY29uc3Qgc3RhcnQgPSBydW4uY3JlYXRlZEF0XHJcbiAgICBjb25zdCBlbmQgPVxyXG4gICAgICBydW4uc3RhdHVzID09PSBBdXRvbWF0ZVJ1blN0YXR1cy5SdW5uaW5nXHJcbiAgICAgICAgPyBub3cudmFsdWVcclxuICAgICAgICA6IChcclxuICAgICAgICAgICAgW0F1dG9tYXRlUnVuU3RhdHVzLkluaXRpYWxpemluZywgQXV0b21hdGVSdW5TdGF0dXMuUGVuZGluZ10gYXMgc3RyaW5nW11cclxuICAgICAgICAgICkuaW5jbHVkZXMocnVuLnN0YXR1cylcclxuICAgICAgICA/IHVuZGVmaW5lZFxyXG4gICAgICAgIDogcnVuLnVwZGF0ZWRBdFxyXG4gICAgaWYgKCFlbmQpIHJldHVybiB1bmRlZmluZWRcclxuXHJcbiAgICBjb25zdCBkaWZmID0gZGF5anMoZW5kKS5kaWZmKGRheWpzKHN0YXJ0KSlcclxuICAgIGNvbnN0IGR1cmF0aW9uID0gZGF5anMuZHVyYXRpb24oZGlmZilcclxuICAgIGNvbnN0IGZvcm1hdCA9IGZvcm1hdER1cmF0aW9uKGR1cmF0aW9uKVxyXG5cclxuICAgIGlmIChkdXJhdGlvbi5kYXlzKCkgPiAwKSByZXR1cm4gZGF5anMuZHVyYXRpb24oZGlmZikuaHVtYW5pemUoKVxyXG4gICAgcmV0dXJuIGRheWpzLmR1cmF0aW9uKGRpZmYpLmZvcm1hdChmb3JtYXQpXHJcbiAgfVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgcnVuU3RhdHVzQ2xhc3NlcyxcclxuICAgIHJ1bk1vZGVsVmVyc2lvblVybCxcclxuICAgIHJ1bkRhdGUsXHJcbiAgICBydW5EdXJhdGlvblxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHVzZUF1dG9tYXRpb25SdW5Mb2dzID0gKHBhcmFtczoge1xyXG4gIHByb2plY3RJZDogTWF5YmVSZWY8T3B0aW9uYWw8c3RyaW5nPj5cclxuICBhdXRvbWF0aW9uSWQ6IE1heWJlUmVmPE9wdGlvbmFsPHN0cmluZz4+XHJcbiAgcnVuSWQ6IE1heWJlUmVmPE9wdGlvbmFsPHN0cmluZz4+XHJcbn0pID0+IHtcclxuICBjb25zdCB7IHByb2plY3RJZCwgYXV0b21hdGlvbklkLCBydW5JZCB9ID0gcGFyYW1zXHJcbiAgY29uc3QgYXBpT3JpZ2luID0gdXNlQXBpT3JpZ2luKClcclxuXHJcbiAgY29uc3QgYXV0aFRva2VuID0gdXNlQXV0aENvb2tpZSgpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgbG9hZGluZyA9IHJlZihmYWxzZSlcclxuICBjb25zdCByZXN1bHRzID0gcmVmKCcnKVxyXG4gIGNvbnN0IGlzU3RyZWFtRmluaXNoZWQgPSByZWYoZmFsc2UpXHJcblxyXG4gIGNvbnN0IHVybCA9IGNvbXB1dGVkKFxyXG4gICAgKCkgPT5cclxuICAgICAgYC9hcGkvdjEvcHJvamVjdHMvJHt1bnJlZihwcm9qZWN0SWQpfS9hdXRvbWF0aW9ucy8ke3VucmVmKFxyXG4gICAgICAgIGF1dG9tYXRpb25JZFxyXG4gICAgICApfS9ydW5zLyR7dW5yZWYocnVuSWQpfS9sb2dzYFxyXG4gIClcclxuICBjb25zdCBrZXkgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICBpZiAoIXVucmVmKGF1dG9tYXRpb25JZCkgfHwgIXVucmVmKHJ1bklkKSkgcmV0dXJuIG51bGxcclxuICAgIHJldHVybiBgYXV0b21hdGlvbi1ydW4tbG9ncy0ke3VucmVmKGF1dG9tYXRpb25JZCl9LSR7dW5yZWYocnVuSWQpfWBcclxuICB9KVxyXG5cclxuICBjb25zdCBhYm9ydHMgPSBhYm9ydENvbnRyb2xsZXJNYW5hZ2VyKClcclxuICBjb25zdCBsb2FkID0gYXN5bmMgKCkgPT4ge1xyXG4gICAgcmVzdWx0cy52YWx1ZSA9ICcnXHJcbiAgICBpc1N0cmVhbUZpbmlzaGVkLnZhbHVlID0gZmFsc2VcclxuXHJcbiAgICBpZiAoIWF1dGhUb2tlbi52YWx1ZSkge1xyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnTG9nIHJldHJpZXZhbCBmYWlsZWQnLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWW91IG5lZWQgdG8gYmUgbG9nZ2VkIGluIHRvIGxvYWQgdGhlIGxvZ3MuJ1xyXG4gICAgICB9KVxyXG4gICAgICBpc1N0cmVhbUZpbmlzaGVkLnZhbHVlID0gdHJ1ZVxyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChuZXcgVVJMKHVybC52YWx1ZSwgYXBpT3JpZ2luKSwge1xyXG4gICAgICBzaWduYWw6IGFib3J0cy5wb3AoKS5zaWduYWwsXHJcbiAgICAgIGhlYWRlcnM6IHtcclxuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YXV0aFRva2VuLnZhbHVlfWBcclxuICAgICAgfVxyXG4gICAgfSkuY2F0Y2goKGUpID0+IHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgICB0aXRsZTogJ0xvZyByZXRyaWV2YWwgZmFpbGVkJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZW5zdXJlRXJyb3IoZSkubWVzc2FnZVxyXG4gICAgICB9KVxyXG5cclxuICAgICAgdGhyb3cgZVxyXG4gICAgfSlcclxuXHJcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB7XHJcbiAgICAgIC8vIFNvbWV0aGluZyBiYWQgaGFwcGVuZWRcclxuICAgICAgY29uc3QganNvbiA9IChhd2FpdCByZXMuanNvbigpKSBhcyB7IGVycm9yPzogeyBtZXNzYWdlOiBzdHJpbmcgfSB9XHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6IFwiQ291bGRuJ3QgbG9hZCBsb2dzXCIsXHJcbiAgICAgICAgZGVzY3JpcHRpb246XHJcbiAgICAgICAgICBqc29uLmVycm9yPy5tZXNzYWdlIHx8ICdTb21ldGhpbmcgd2VudCB3cm9uZyB3aGlsZSBsb2FkaW5nIHRoZSBsb2dzLidcclxuICAgICAgfSlcclxuICAgICAgaXNTdHJlYW1GaW5pc2hlZC52YWx1ZSA9IHRydWVcclxuXHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHN0cmVhbSA9IHJlcy5ib2R5XHJcblxyXG4gICAgLy8gUmVhZCBzdHJlYW0gaW50byByZXN1bHRzIHJlZlxyXG4gICAgaWYgKHN0cmVhbSkge1xyXG4gICAgICBjb25zdCByZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKClcclxuICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpXHJcbiAgICAgIGNvbnN0IHB1bXAgPSBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHJlYWRlci5yZWFkKCkudGhlbigoeyBkb25lLCB2YWx1ZSB9KTogUHJvbWlzZTx2b2lkPiA9PiB7XHJcbiAgICAgICAgICBpZiAoZG9uZSkge1xyXG4gICAgICAgICAgICBpc1N0cmVhbUZpbmlzaGVkLnZhbHVlID0gdHJ1ZVxyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHJlc3VsdHMudmFsdWUgKz0gZGVjb2Rlci5kZWNvZGUodmFsdWUpXHJcbiAgICAgICAgICByZXR1cm4gcHVtcCgpXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gSW50ZW50aW9uYWxseSBub3QgYXdhaXRpbmcgdGhpcyBzbyB0aGF0IHdlIGNhbiByZXR1cm4gdGhlIHJlZlxyXG4gICAgICB2b2lkIHB1bXAoKS5jYXRjaCgoZSkgPT4ge1xyXG4gICAgICAgIGlmICghaXNBYm9ydEVycm9yKGUpKSB7XHJcbiAgICAgICAgICB0aHJvdyBlXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICBjb25zdCBsb2FkQW5kTWFya0xvYWRpbmcgPSBhc3luYyAoKSA9PiB7XHJcbiAgICBsb2FkaW5nLnZhbHVlID0gdHJ1ZVxyXG4gICAgYXdhaXQgbG9hZCgpLmZpbmFsbHkoKCkgPT4ge1xyXG4gICAgICBsb2FkaW5nLnZhbHVlID0gZmFsc2VcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICB3YXRjaChcclxuICAgIGtleSxcclxuICAgIChuZXdLZXksIG9sZEtleSkgPT4ge1xyXG4gICAgICBpZiAobmV3S2V5ICYmIG5ld0tleSAhPT0gb2xkS2V5KSB7XHJcbiAgICAgICAgdm9pZCBsb2FkQW5kTWFya0xvYWRpbmcoKVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgeyBpbW1lZGlhdGU6IHRydWUgfVxyXG4gIClcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGRhdGE6IGNvbXB1dGVkKCgpID0+IHJlc3VsdHMudmFsdWUpLFxyXG4gICAgaXNEYXRhTG9hZGVkOiBjb21wdXRlZCgoKSA9PiBpc1N0cmVhbUZpbmlzaGVkLnZhbHVlKSxcclxuICAgIGxvYWRpbmc6IGNvbXB1dGVkKCgpID0+IGxvYWRpbmcudmFsdWUpXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgdXNlQXV0b21hdGlvbkZ1bmN0aW9uUnVuUmVzdWx0cyA9IChwYXJhbXM6IHtcclxuICByZXN1bHRzOiBNYXliZVJlZjxNYXliZU51bGxPclVuZGVmaW5lZDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+XHJcbn0pID0+IHtcclxuICBjb25zdCB7IHJlc3VsdHMgfSA9IHBhcmFtc1xyXG5cclxuICBjb25zdCByZXQgPSBjb21wdXRlZChcclxuICAgICgpOiBNYXliZU51bGxPclVuZGVmaW5lZDxBdXRvbWF0ZS5BdXRvbWF0ZVR5cGVzLlJlc3VsdHNTY2hlbWE+ID0+IHtcclxuICAgICAgY29uc3QgcmVzID0gdW5yZWYocmVzdWx0cylcclxuICAgICAgaWYgKCFyZXMpIHJldHVybiByZXNcclxuXHJcbiAgICAgIGlmICghQXV0b21hdGUuQXV0b21hdGVUeXBlcy5pc1Jlc3VsdHNTY2hlbWEocmVzKSkgcmV0dXJuIG51bGxcclxuICAgICAgcmV0dXJuIEF1dG9tYXRlLkF1dG9tYXRlVHlwZXMuZm9ybWF0UmVzdWx0c1NjaGVtYShyZXMpXHJcbiAgICB9XHJcbiAgKVxyXG5cclxuICByZXR1cm4gcmV0XHJcbn1cclxuXHJcbmdyYXBocWwoYFxyXG4gIGZyYWdtZW50IEF1dG9tYXRpb25zU3RhdHVzT3JkZXJlZFJ1bnNfQXV0b21hdGlvblJ1biBvbiBBdXRvbWF0ZVJ1biB7XHJcbiAgICBpZFxyXG4gICAgYXV0b21hdGlvbiB7XHJcbiAgICAgIGlkXHJcbiAgICAgIG5hbWVcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uUnVucyB7XHJcbiAgICAgIGlkXHJcbiAgICAgIHVwZGF0ZWRBdFxyXG4gICAgfVxyXG4gIH1cclxuYClcclxuXHJcbmV4cG9ydCBjb25zdCB1c2VBdXRvbWF0aW9uc1N0YXR1c09yZGVyZWRSdW5zID0gPFxyXG4gIFIgZXh0ZW5kcyBBdXRvbWF0aW9uc1N0YXR1c09yZGVyZWRSdW5zX0F1dG9tYXRpb25SdW5GcmFnbWVudCA9IEF1dG9tYXRpb25zU3RhdHVzT3JkZXJlZFJ1bnNfQXV0b21hdGlvblJ1bkZyYWdtZW50XHJcbj4ocGFyYW1zOiB7XHJcbiAgYXV0b21hdGlvblJ1bnM6IE1heWJlUmVmPFJbXT5cclxufSkgPT4ge1xyXG4gIGNvbnN0IHsgYXV0b21hdGlvblJ1bnMgfSA9IHBhcmFtc1xyXG5cclxuICBjb25zdCBydW5zID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgcmV0OiBBcnJheTxcclxuICAgICAgUlsnZnVuY3Rpb25SdW5zJ11bMF0gJiB7XHJcbiAgICAgICAgYXV0b21hdGlvbk5hbWU6IHN0cmluZ1xyXG4gICAgICB9XHJcbiAgICA+ID0gW11cclxuXHJcbiAgICBmb3IgKGNvbnN0IGF1dG9tYXRpb25SdW4gb2YgdW5yZWYoYXV0b21hdGlvblJ1bnMpKSB7XHJcbiAgICAgIGZvciAoY29uc3QgcnVuIG9mIGF1dG9tYXRpb25SdW4uZnVuY3Rpb25SdW5zKSB7XHJcbiAgICAgICAgcmV0LnB1c2goeyAuLi5ydW4sIGF1dG9tYXRpb25OYW1lOiBhdXRvbWF0aW9uUnVuLmF1dG9tYXRpb24ubmFtZSB9KVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG9yZGVyQnkocmV0LCAocikgPT4gbmV3IERhdGUoci51cGRhdGVkQXQpLmdldFRpbWUoKSwgJ2Rlc2MnKVxyXG4gIH0pXHJcblxyXG4gIHJldHVybiB7IHJ1bnMgfVxyXG59XHJcbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9saWIvYXV0b21hdGUvY29tcG9zYWJsZXMvcnVucy50cyJ9 |