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

376 lines
41 KiB
Plaintext

/* _processed_nuxt_unctx_transform */
import { executeAsync as __executeAsync } from "/_nuxt/node_modules/unctx/dist/index.mjs?v=e4f18c29";import { collectLongTrace, errorToString, getErrorMessage } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/index.js";
import __vite__cjsImport2_dayjs from "/_nuxt/node_modules/.cache/vite/client/deps/dayjs.js?v=e4f18c29"; const dayjs = __vite__cjsImport2_dayjs.__esModule ? __vite__cjsImport2_dayjs.default : __vite__cjsImport2_dayjs;
import { omit } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
import { useReadUserId } from "/_nuxt/lib/auth/composables/activeUser.ts";
import {
useCreateLoggingTransport,
useGetLoggingTransports,
useLogToLoggingTransports
} from "/_nuxt/lib/core/composables/error.ts";
import {
useRequestId,
useServerRequestId,
useUserCountry
} from "/_nuxt/lib/core/composables/server.ts";
import { isObjectLike } from "/_nuxt/lib/common/helpers/type.ts";
import {
buildFakePinoLogger,
enableCustomLoggerHandling
} from "/_nuxt/lib/core/helpers/observability.ts";
import { defineNuxtPlugin, useRuntimeConfig } from "/_nuxt/node_modules/nuxt/dist/app/nuxt.js?v=e4f18c29";
import { useRoute, useRouter } from "/_nuxt/node_modules/nuxt/dist/app/composables/router.js?v=e4f18c29";
import { createError } from "/_nuxt/node_modules/nuxt/dist/app/composables/error.js?v=e4f18c29";
const simpleStripHtml = (str) => str.replace(/<[^>]*>?/gm, "");
export default defineNuxtPlugin(async (nuxtApp) => {let __temp, __restore;
const runtimeConfig = useRuntimeConfig();
const {
public: {
logLevel: untypedLogLevel,
logPretty,
logClientApiToken,
speckleServerVersion,
logClientApiEndpoint,
serverName,
logCsrEmitProps
}
} = runtimeConfig;
const logLevel = untypedLogLevel;
const route = useRoute();
const router = useRouter();
const reqId = useRequestId();
const serverReqId = useServerRequestId();
const getUserId = useReadUserId();
const country = useUserCountry();
const registerErrorTransport = useCreateLoggingTransport();
const { invokeTransportsWithPayload } = useLogToLoggingTransports();
const profilerLogger = route.query.profilerLogger === "1";
const collectMainInfo = (params) => {
const info = {
browser: params.isBrowser,
speckleServerVersion,
serverName,
frontendType: "frontend-2",
route: route?.path,
routeDefinition: route.matched?.[route.matched.length - 1]?.path,
req: { id: reqId },
userId: getUserId(),
country: country.value,
serverReqId: serverReqId.value
};
return info;
};
let logger;
const logHandlers = [];
const unhandledErrorHandlers = [];
if (false) {
const {
buildLogger,
enableDynamicBindings,
serializeRequest,
prettifiedLoggerFactory,
initSsrDevLogs
} = (([__temp,__restore]=__executeAsync(()=>import("/_nuxt/server/lib/core/helpers/observability.ts"))),__temp=await __temp,__restore(),__temp);
logger = enableDynamicBindings(buildLogger(logLevel, logPretty).child({}), () => ({
...collectMainInfo({ isBrowser: false }),
...nuxtApp.ssrContext ? { req: serializeRequest(nuxtApp.ssrContext.event.node.req) } : {}
}));
nuxtApp.hook("app:rendered", () => {
if (!nuxtApp.ssrContext) return;
const bindings = collectMainInfo({ isBrowser: false });
nuxtApp.ssrContext.event.node.res.vueLoggerBindings = omit(bindings, [
"req",
"res"
]);
});
if (true) {
const ssrDevLogs = (([__temp,__restore]=__executeAsync(()=>initSsrDevLogs({ logLevel }))),__temp=await __temp,__restore(),__temp);
const consola = ssrDevLogs.consola;
if (consola) {
const unhandledHandler = ({
error,
message,
isUnhandledRejection
}) => {
consola.error({ err: error, isUnhandledRejection }, message);
};
unhandledErrorHandlers.push(unhandledHandler);
const errorHandler = ({ args, level }) => {
prettifiedLoggerFactory(consola[level])(args[0], ...args.slice(1), {
time: dayjs().format("HH:mm:ss.SSS"),
separator: "═══════════════════════════════════════════►"
});
};
logHandlers.push(errorHandler);
}
}
} else {
const localTimeFormat = new Intl.DateTimeFormat("en-GB", {
dateStyle: "full",
timeStyle: "long"
});
const collectBrowserInfo = () => {
const {
userAgent,
platform: navigatorPlatform,
vendor: navigatorVendor
} = navigator;
const url = window.location.href;
const localTime = localTimeFormat.format(/* @__PURE__ */ new Date());
const { innerWidth: browserWidth, innerHeight: browserHeight } = window;
const { width: screenWidth, height: screenHeight } = window.screen;
return {
userAgent,
navigatorPlatform,
navigatorVendor,
url,
localTime,
dimensions: {
browser: { width: browserWidth, height: browserHeight },
screen: { width: screenWidth, height: screenHeight }
}
};
};
const collectCoreInfo = () => ({
...collectBrowserInfo(),
...collectMainInfo({ isBrowser: true })
});
logger = buildFakePinoLogger({
consoleBindings: logCsrEmitProps ? collectCoreInfo : void 0,
time: profilerLogger
});
if (logClientApiToken?.length && logClientApiEndpoint?.length) {
const seq = (([__temp,__restore]=__executeAsync(()=>import('/_nuxt/node_modules/.cache/vite/client/deps/seq-logging_browser.js?v=e4f18c29').then(m => ((m$2) => m$2?.__esModule ? m$2 : { ...typeof m$2 === "object" && !Array.isArray(m$2) || typeof m$2 === "function" ? m$2 : {}, default: m$2})(m.default)))),__temp=await __temp,__restore(),__temp);
const seqLogger = new seq.Logger({
serverUrl: logClientApiEndpoint,
apiKey: logClientApiToken,
// eslint-disable-next-line no-console
onError: console.error
});
const unhandledErrorLogger = ({
error,
message,
isUnhandledRejection
}) => {
seqLogger.emit({
timestamp: /* @__PURE__ */ new Date(),
level: "error",
messageTemplate: "Client-side error: {mainSeqErrorMessage}",
properties: {
mainSeqErrorMessage: message,
isUnhandledRejection,
...collectCoreInfo()
},
exception: error instanceof Error ? error.stack : `${error}`
});
};
unhandledErrorHandlers.push(unhandledErrorLogger);
const mainSeqTransport = ({
args,
firstString,
firstError,
otherData,
nonObjectOtherData,
level
}) => {
if (!args.length) return;
const stack = collectLongTrace();
const isError = ["error", "fatal"].includes(level);
const isImportant = !!otherData?.important;
if (!isError && !isImportant) return;
if (isError) {
const errorMessage = firstError?.message ?? firstString ?? `Unknown error`;
const exception = firstError?.stack ?? new Error(
"No Error instance was thrown, thus the following stack trace is synthesized manually"
).stack;
seqLogger.emit({
timestamp: /* @__PURE__ */ new Date(),
level: "error",
messageTemplate: "Client-side error: {mainSeqErrorMessage}",
properties: {
mainSeqErrorMessage: errorMessage,
// weird name to avoid collision with otherData
extraData: nonObjectOtherData,
stack,
firstError,
firstString,
...otherData,
...collectCoreInfo()
},
exception
});
} else {
seqLogger.emit({
timestamp: /* @__PURE__ */ new Date(),
level,
messageTemplate: firstString,
properties: {
extraData: nonObjectOtherData,
firstError,
stack,
...otherData,
...collectCoreInfo()
}
});
}
};
logHandlers.push(mainSeqTransport);
logger.debug("Set up seq ingestion...");
}
}
if (logHandlers.length || unhandledErrorHandlers.length) {
registerErrorTransport({
onLog: (...params) => {
logHandlers.forEach((handler) => handler(...params));
},
onUnhandledError: (event) => {
unhandledErrorHandlers.forEach((handler) => handler(event));
}
});
}
const transports = useGetLoggingTransports();
logger = enableCustomLoggerHandling({
logger,
handler: (params, helpers) => {
transports.forEach((handler) => handler.onLog?.(params, helpers));
}
});
if (true && window) {
const unhandledHandler = (event) => {
const handlers = transports.filter(
(t) => !!t.onUnhandledError
);
const isUnhandledRejection = isObjectLike(event) && "reason" in event;
const error = "reason" in event ? event.reason : event.error;
const message = error instanceof Error ? error.message : `${error}`;
handlers.forEach(
(handler) => handler.onUnhandledError({ event, isUnhandledRejection, error, message })
);
};
window.addEventListener("error", unhandledHandler);
window.addEventListener("unhandledrejection", unhandledHandler);
}
const getErrorStatusCode = (err) => {
if (isObjectLike(err) && "statusCode" in err) {
const statusCode = err.statusCode;
if (typeof statusCode === "number" && !Number.isNaN(statusCode)) {
return statusCode;
}
}
return void 0;
};
const isIgnorableError = (err) => {
const statusCode = getErrorStatusCode(err);
if (typeof statusCode === "number") {
if ([404, 403, 401].includes(statusCode)) return true;
return false;
}
};
router.onError((err, to, from) => {
if (isIgnorableError(err)) return;
logger.error(
{
err,
to: to.path,
from: from?.path,
isAppError: !!false,
unhandledRoutingError: true,
statusCode: getErrorStatusCode(err)
},
getErrorMessage(err)
);
});
nuxtApp.vueApp.config.errorHandler = (error, _vm, info) => {
if (isIgnorableError(error)) return;
logger.error(
{
err: error,
info,
vm: _vm?.$options.name,
errString: errorToString(error),
vueErrorHandler: true,
statusCode: getErrorStatusCode(error)
},
getErrorMessage(error)
);
};
nuxtApp.hook("app:error", (error) => {
if (isIgnorableError(error)) return;
logger.error(
{
err: error,
isAppError: true,
errString: errorToString(error),
appErrorHook: true,
statusCode: getErrorStatusCode(error)
},
getErrorMessage(error)
);
});
nuxtApp.hook("vue:error", (error, _vm, info) => {
if (isIgnorableError(error)) return;
logger.error(
{
err: error,
info,
isAppError: true,
vm: _vm?.$options.name,
errString: errorToString(error),
vueErrorHook: true,
statusCode: getErrorStatusCode(error)
},
getErrorMessage(error)
);
});
if (!false) {
nuxtApp.hook("app:mounted", () => {
const serverFatalError = nuxtApp.payload.error;
if (serverFatalError && serverFatalError.statusCode >= 500) {
const msg = serverFatalError.message || "Fatal server error";
const stack = serverFatalError.stack ? simpleStripHtml(serverFatalError.stack) : void 0;
const finalStack = `${msg}${stack ? `
${stack}` : ""}`;
const nuxtError = createError({
...serverFatalError,
...finalStack ? { stack: finalStack } : {}
});
const payload = {
args: ["Fatal server error", serverFatalError],
firstError: nuxtError,
firstString: "Fatal server error",
otherData: { isAppError: true },
nonObjectOtherData: [],
level: "fatal"
};
invokeTransportsWithPayload(payload);
if (true) {
console.error("Fatal error occurred on server:", payload);
}
}
});
}
if (!false) {
nuxtApp.hook("app:mounted", () => {
logger.info("App mounted in the client", {
important: true,
speckleServerVersion,
runtimeConfig
});
});
} else {
nuxtApp.hook("app:rendered", () => {
logger.info("App SSR rendered", {
important: true,
speckleServerVersion
});
});
}
return {
provide: {
logger
}
};
},1);
//# sourceMappingURL=data:application/json;base64,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V0FBVztBQUFBLFFBQ1g7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNILENBQUM7QUFBQSxFQUNIO0FBRUEsU0FBTztBQUFBLElBQ0wsU0FBUztBQUFBLE1BQ1A7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLEdBQUMiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbIjAxMC1sb2dnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29sbGVjdExvbmdUcmFjZSwgZXJyb3JUb1N0cmluZywgZ2V0RXJyb3JNZXNzYWdlIH0gZnJvbSAnQHNwZWNrbGUvc2hhcmVkJ1xyXG5pbXBvcnQgdHlwZSB7IExvZ1R5cGUgfSBmcm9tICdjb25zb2xhJ1xyXG5pbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnXHJcbmltcG9ydCB7IG9taXQgfSBmcm9tICdsb2Rhc2gtZXMnXHJcbmltcG9ydCB0eXBlIHsgU2V0UmVxdWlyZWQgfSBmcm9tICd0eXBlLWZlc3QnXHJcbmltcG9ydCB7IHVzZVJlYWRVc2VySWQgfSBmcm9tICd+L2xpYi9hdXRoL2NvbXBvc2FibGVzL2FjdGl2ZVVzZXInXHJcbmltcG9ydCB7XHJcbiAgdXNlQ3JlYXRlTG9nZ2luZ1RyYW5zcG9ydCxcclxuICB1c2VHZXRMb2dnaW5nVHJhbnNwb3J0cyxcclxuICB1c2VMb2dUb0xvZ2dpbmdUcmFuc3BvcnRzXHJcbn0gZnJvbSAnfi9saWIvY29yZS9jb21wb3NhYmxlcy9lcnJvcidcclxuaW1wb3J0IHtcclxuICB1c2VSZXF1ZXN0SWQsXHJcbiAgdXNlU2VydmVyUmVxdWVzdElkLFxyXG4gIHVzZVVzZXJDb3VudHJ5XHJcbn0gZnJvbSAnfi9saWIvY29yZS9jb21wb3NhYmxlcy9zZXJ2ZXInXHJcbmltcG9ydCB7IGlzT2JqZWN0TGlrZSB9IGZyb20gJ35+L2xpYi9jb21tb24vaGVscGVycy90eXBlJ1xyXG5pbXBvcnQge1xyXG4gIGJ1aWxkRmFrZVBpbm9Mb2dnZXIsXHJcbiAgZW5hYmxlQ3VzdG9tTG9nZ2VySGFuZGxpbmcsXHJcbiAgdHlwZSBBYnN0cmFjdExvZ2dlckhhbmRsZXIsXHJcbiAgdHlwZSBBYnN0cmFjdExvZ2dlckhhbmRsZXJQYXJhbXMsXHJcbiAgdHlwZSBBYnN0cmFjdFVuaGFuZGxlZEVycm9ySGFuZGxlclxyXG59IGZyb20gJ35+L2xpYi9jb3JlL2hlbHBlcnMvb2JzZXJ2YWJpbGl0eSdcclxuXHJcbmNvbnN0IHNpbXBsZVN0cmlwSHRtbCA9IChzdHI6IHN0cmluZykgPT4gc3RyLnJlcGxhY2UoLzxbXj5dKj4/L2dtLCAnJylcclxuXHJcbi8qKlxyXG4gKiAtIFNldHRpbmcgdXAgUGlubyBsb2dnZXIgaW4gU1NSLCBiYXNpYyBjb25zb2xlLmxvZyBmYWxsYmFjayBpbiBDU1JcclxuICogLSBBbHNvIHNldHMgdXAgYWJpbGl0eSB0byBhZGQgZXh0cmEgdHJhbnNwb3J0IGZvciBvdGhlciBvYnNlcnZhYmlsaXR5IHRvb2xzXHJcbiAqL1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lTnV4dFBsdWdpbihhc3luYyAobnV4dEFwcCkgPT4ge1xyXG4gIGNvbnN0IHJ1bnRpbWVDb25maWcgPSB1c2VSdW50aW1lQ29uZmlnKClcclxuICBjb25zdCB7XHJcbiAgICBwdWJsaWM6IHtcclxuICAgICAgbG9nTGV2ZWw6IHVudHlwZWRMb2dMZXZlbCxcclxuICAgICAgbG9nUHJldHR5LFxyXG4gICAgICBsb2dDbGllbnRBcGlUb2tlbixcclxuICAgICAgc3BlY2tsZVNlcnZlclZlcnNpb24sXHJcbiAgICAgIGxvZ0NsaWVudEFwaUVuZHBvaW50LFxyXG4gICAgICBzZXJ2ZXJOYW1lLFxyXG4gICAgICBsb2dDc3JFbWl0UHJvcHNcclxuICAgIH1cclxuICB9ID0gcnVudGltZUNvbmZpZ1xyXG5cclxuICBjb25zdCBsb2dMZXZlbCA9IHVudHlwZWRMb2dMZXZlbCBhcyBMb2dUeXBlXHJcbiAgY29uc3Qgcm91dGUgPSB1c2VSb3V0ZSgpXHJcbiAgY29uc3Qgcm91dGVyID0gdXNlUm91dGVyKClcclxuICBjb25zdCByZXFJZCA9IHVzZVJlcXVlc3RJZCgpXHJcbiAgY29uc3Qgc2VydmVyUmVxSWQgPSB1c2VTZXJ2ZXJSZXF1ZXN0SWQoKVxyXG4gIGNvbnN0IGdldFVzZXJJZCA9IHVzZVJlYWRVc2VySWQoKVxyXG4gIGNvbnN0IGNvdW50cnkgPSB1c2VVc2VyQ291bnRyeSgpXHJcbiAgY29uc3QgcmVnaXN0ZXJFcnJvclRyYW5zcG9ydCA9IHVzZUNyZWF0ZUxvZ2dpbmdUcmFuc3BvcnQoKVxyXG4gIGNvbnN0IHsgaW52b2tlVHJhbnNwb3J0c1dpdGhQYXlsb2FkIH0gPSB1c2VMb2dUb0xvZ2dpbmdUcmFuc3BvcnRzKClcclxuXHJcbiAgY29uc3QgcHJvZmlsZXJMb2dnZXIgPSByb3V0ZS5xdWVyeS5wcm9maWxlckxvZ2dlciA9PT0gJzEnXHJcblxyXG4gIGNvbnN0IGNvbGxlY3RNYWluSW5mbyA9IChwYXJhbXM6IHsgaXNCcm93c2VyOiBib29sZWFuIH0pID0+IHtcclxuICAgIGNvbnN0IGluZm8gPSB7XHJcbiAgICAgIGJyb3dzZXI6IHBhcmFtcy5pc0Jyb3dzZXIsXHJcbiAgICAgIHNwZWNrbGVTZXJ2ZXJWZXJzaW9uLFxyXG4gICAgICBzZXJ2ZXJOYW1lLFxyXG4gICAgICBmcm9udGVuZFR5cGU6ICdmcm9udGVuZC0yJyxcclxuICAgICAgcm91dGU6IHJvdXRlPy5wYXRoLFxyXG4gICAgICByb3V0ZURlZmluaXRpb246IHJvdXRlLm1hdGNoZWQ/Lltyb3V0ZS5tYXRjaGVkLmxlbmd0aCAtIDFdPy5wYXRoLFxyXG4gICAgICByZXE6IHsgaWQ6IHJlcUlkIH0sXHJcbiAgICAgIHVzZXJJZDogZ2V0VXNlcklkKCksXHJcbiAgICAgIGNvdW50cnk6IGNvdW50cnkudmFsdWUsXHJcbiAgICAgIHNlcnZlclJlcUlkOiBzZXJ2ZXJSZXFJZC52YWx1ZVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGluZm9cclxuICB9XHJcblxyXG4gIC8vIFNldCB1cCBsb2dnZXJcclxuICBsZXQgbG9nZ2VyOiBSZXR1cm5UeXBlPHR5cGVvZiBpbXBvcnQoJ0BzcGVja2xlL3NoYXJlZC9vYnNlcnZhYmlsaXR5JykuZ2V0TG9nZ2VyPlxyXG4gIGNvbnN0IGxvZ0hhbmRsZXJzOiBBYnN0cmFjdExvZ2dlckhhbmRsZXJbXSA9IFtdXHJcbiAgY29uc3QgdW5oYW5kbGVkRXJyb3JIYW5kbGVyczogQWJzdHJhY3RVbmhhbmRsZWRFcnJvckhhbmRsZXJbXSA9IFtdXHJcblxyXG4gIGlmIChpbXBvcnQubWV0YS5zZXJ2ZXIpIHtcclxuICAgIGNvbnN0IHtcclxuICAgICAgYnVpbGRMb2dnZXIsXHJcbiAgICAgIGVuYWJsZUR5bmFtaWNCaW5kaW5ncyxcclxuICAgICAgc2VyaWFsaXplUmVxdWVzdCxcclxuICAgICAgcHJldHRpZmllZExvZ2dlckZhY3RvcnksXHJcbiAgICAgIGluaXRTc3JEZXZMb2dzXHJcbiAgICB9ID0gYXdhaXQgaW1wb3J0KCd+L3NlcnZlci9saWIvY29yZS9oZWxwZXJzL29ic2VydmFiaWxpdHknKVxyXG4gICAgbG9nZ2VyID0gZW5hYmxlRHluYW1pY0JpbmRpbmdzKGJ1aWxkTG9nZ2VyKGxvZ0xldmVsLCBsb2dQcmV0dHkpLmNoaWxkKHt9KSwgKCkgPT4gKHtcclxuICAgICAgLi4uY29sbGVjdE1haW5JbmZvKHsgaXNCcm93c2VyOiBmYWxzZSB9KSxcclxuICAgICAgLi4uKG51eHRBcHAuc3NyQ29udGV4dFxyXG4gICAgICAgID8geyByZXE6IHNlcmlhbGl6ZVJlcXVlc3QobnV4dEFwcC5zc3JDb250ZXh0LmV2ZW50Lm5vZGUucmVxKSB9XHJcbiAgICAgICAgOiB7fSlcclxuICAgIH0pKVxyXG5cclxuICAgIC8vIENvbGxlY3QgYmluZGluZ3MgZm9yIHBpbm8taHR0cCBsb2dnZXJcclxuICAgIG51eHRBcHAuaG9vaygnYXBwOnJlbmRlcmVkJywgKCkgPT4ge1xyXG4gICAgICBpZiAoIW51eHRBcHAuc3NyQ29udGV4dCkgcmV0dXJuXHJcbiAgICAgIGNvbnN0IGJpbmRpbmdzID0gY29sbGVjdE1haW5JbmZvKHsgaXNCcm93c2VyOiBmYWxzZSB9KVxyXG4gICAgICBudXh0QXBwLnNzckNvbnRleHQuZXZlbnQubm9kZS5yZXMudnVlTG9nZ2VyQmluZGluZ3MgPSBvbWl0KGJpbmRpbmdzLCBbXHJcbiAgICAgICAgJ3JlcScsXHJcbiAgICAgICAgJ3JlcydcclxuICAgICAgXSlcclxuICAgIH0pXHJcblxyXG4gICAgLy8gU2VuZCB0byBjb25zb2xhIGZvciBTU1IgbG9nIHN0cmVhbWluZyBpbiBkZXYgbW9kZVxyXG4gICAgaWYgKGltcG9ydC5tZXRhLmRldikge1xyXG4gICAgICBjb25zdCBzc3JEZXZMb2dzID0gYXdhaXQgaW5pdFNzckRldkxvZ3MoeyBsb2dMZXZlbCB9KVxyXG4gICAgICBjb25zdCBjb25zb2xhID0gc3NyRGV2TG9ncy5jb25zb2xhXHJcblxyXG4gICAgICBpZiAoY29uc29sYSkge1xyXG4gICAgICAgIGNvbnN0IHVuaGFuZGxlZEhhbmRsZXI6IEFic3RyYWN0VW5oYW5kbGVkRXJyb3JIYW5kbGVyID0gKHtcclxuICAgICAgICAgIGVycm9yLFxyXG4gICAgICAgICAgbWVzc2FnZSxcclxuICAgICAgICAgIGlzVW5oYW5kbGVkUmVqZWN0aW9uXHJcbiAgICAgICAgfSkgPT4ge1xyXG4gICAgICAgICAgY29uc29sYS5lcnJvcih7IGVycjogZXJyb3IsIGlzVW5oYW5kbGVkUmVqZWN0aW9uIH0sIG1lc3NhZ2UpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHVuaGFuZGxlZEVycm9ySGFuZGxlcnMucHVzaCh1bmhhbmRsZWRIYW5kbGVyKVxyXG5cclxuICAgICAgICBjb25zdCBlcnJvckhhbmRsZXI6IEFic3RyYWN0TG9nZ2VySGFuZGxlciA9ICh7IGFyZ3MsIGxldmVsIH0pID0+IHtcclxuICAgICAgICAgIC8vIGFwcGx5aW5nIHBpbm8tbGlrZSBtZXNzYWdlIHRlbXBsYXRpbmcsIGNhdXNlIGNvbnNvbGEgZG9lc250IGhhdmUgaXRcclxuICAgICAgICAgIC8vIHRoZSBhcmcgc2xpY2UgaXMgVFMgYXBwZWFzZW1lbnRcclxuICAgICAgICAgIHByZXR0aWZpZWRMb2dnZXJGYWN0b3J5KGNvbnNvbGFbbGV2ZWxdKShhcmdzWzBdLCAuLi5hcmdzLnNsaWNlKDEpLCB7XHJcbiAgICAgICAgICAgIHRpbWU6IGRheWpzKCkuZm9ybWF0KCdISDptbTpzcy5TU1MnKSxcclxuICAgICAgICAgICAgc2VwYXJhdG9yOiAn4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pa6J1xyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgICAgbG9nSGFuZGxlcnMucHVzaChlcnJvckhhbmRsZXIpXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgY29uc3QgbG9jYWxUaW1lRm9ybWF0ID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoJ2VuLUdCJywge1xyXG4gICAgICBkYXRlU3R5bGU6ICdmdWxsJyxcclxuICAgICAgdGltZVN0eWxlOiAnbG9uZydcclxuICAgIH0pXHJcbiAgICBjb25zdCBjb2xsZWN0QnJvd3NlckluZm8gPSAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IHtcclxuICAgICAgICB1c2VyQWdlbnQsXHJcbiAgICAgICAgcGxhdGZvcm06IG5hdmlnYXRvclBsYXRmb3JtLFxyXG4gICAgICAgIHZlbmRvcjogbmF2aWdhdG9yVmVuZG9yXHJcbiAgICAgIH0gPSBuYXZpZ2F0b3JcclxuICAgICAgY29uc3QgdXJsID0gd2luZG93LmxvY2F0aW9uLmhyZWZcclxuICAgICAgY29uc3QgbG9jYWxUaW1lID0gbG9jYWxUaW1lRm9ybWF0LmZvcm1hdChuZXcgRGF0ZSgpKVxyXG5cclxuICAgICAgLy8gR2V0IGJyb3dzZXIgZGltZW5zaW9ucyAmIHNjcmVlbiBkaW1lbnNpb25zXHJcbiAgICAgIGNvbnN0IHsgaW5uZXJXaWR0aDogYnJvd3NlcldpZHRoLCBpbm5lckhlaWdodDogYnJvd3NlckhlaWdodCB9ID0gd2luZG93XHJcbiAgICAgIGNvbnN0IHsgd2lkdGg6IHNjcmVlbldpZHRoLCBoZWlnaHQ6IHNjcmVlbkhlaWdodCB9ID0gd2luZG93LnNjcmVlblxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB1c2VyQWdlbnQsXHJcbiAgICAgICAgbmF2aWdhdG9yUGxhdGZvcm0sXHJcbiAgICAgICAgbmF2aWdhdG9yVmVuZG9yLFxyXG4gICAgICAgIHVybCxcclxuICAgICAgICBsb2NhbFRpbWUsXHJcbiAgICAgICAgZGltZW5zaW9uczoge1xyXG4gICAgICAgICAgYnJvd3NlcjogeyB3aWR0aDogYnJvd3NlcldpZHRoLCBoZWlnaHQ6IGJyb3dzZXJIZWlnaHQgfSxcclxuICAgICAgICAgIHNjcmVlbjogeyB3aWR0aDogc2NyZWVuV2lkdGgsIGhlaWdodDogc2NyZWVuSGVpZ2h0IH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjb2xsZWN0Q29yZUluZm8gPSAoKSA9PiAoe1xyXG4gICAgICAuLi5jb2xsZWN0QnJvd3NlckluZm8oKSxcclxuICAgICAgLi4uY29sbGVjdE1haW5JbmZvKHsgaXNCcm93c2VyOiB0cnVlIH0pXHJcbiAgICB9KVxyXG5cclxuICAgIGxvZ2dlciA9IGJ1aWxkRmFrZVBpbm9Mb2dnZXIoe1xyXG4gICAgICBjb25zb2xlQmluZGluZ3M6IGxvZ0NzckVtaXRQcm9wcyA/IGNvbGxlY3RDb3JlSW5mbyA6IHVuZGVmaW5lZCxcclxuICAgICAgdGltZTogcHJvZmlsZXJMb2dnZXJcclxuICAgIH0pXHJcblxyXG4gICAgLy8gU0VRIEJyb3dzZXIgaW50ZWdyYXRpb25cclxuICAgIGlmIChsb2dDbGllbnRBcGlUb2tlbj8ubGVuZ3RoICYmIGxvZ0NsaWVudEFwaUVuZHBvaW50Py5sZW5ndGgpIHtcclxuICAgICAgY29uc3Qgc2VxID0gYXdhaXQgaW1wb3J0KCdzZXEtbG9nZ2luZy9icm93c2VyJylcclxuICAgICAgY29uc3Qgc2VxTG9nZ2VyID0gbmV3IHNlcS5Mb2dnZXIoe1xyXG4gICAgICAgIHNlcnZlclVybDogbG9nQ2xpZW50QXBpRW5kcG9pbnQsXHJcbiAgICAgICAgYXBpS2V5OiBsb2dDbGllbnRBcGlUb2tlbixcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxyXG4gICAgICAgIG9uRXJyb3I6IGNvbnNvbGUuZXJyb3JcclxuICAgICAgfSlcclxuXHJcbiAgICAgIGNvbnN0IHVuaGFuZGxlZEVycm9yTG9nZ2VyOiBBYnN0cmFjdFVuaGFuZGxlZEVycm9ySGFuZGxlciA9ICh7XHJcbiAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgbWVzc2FnZSxcclxuICAgICAgICBpc1VuaGFuZGxlZFJlamVjdGlvblxyXG4gICAgICB9KSA9PiB7XHJcbiAgICAgICAgc2VxTG9nZ2VyLmVtaXQoe1xyXG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgICAgbGV2ZWw6ICdlcnJvcicsXHJcbiAgICAgICAgICBtZXNzYWdlVGVtcGxhdGU6ICdDbGllbnQtc2lkZSBlcnJvcjoge21haW5TZXFFcnJvck1lc3NhZ2V9JyxcclxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcclxuICAgICAgICAgICAgbWFpblNlcUVycm9yTWVzc2FnZTogbWVzc2FnZSxcclxuICAgICAgICAgICAgaXNVbmhhbmRsZWRSZWplY3Rpb24sXHJcbiAgICAgICAgICAgIC4uLmNvbGxlY3RDb3JlSW5mbygpXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgZXhjZXB0aW9uOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3Iuc3RhY2sgOiBgJHtlcnJvcn1gXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgICB1bmhhbmRsZWRFcnJvckhhbmRsZXJzLnB1c2godW5oYW5kbGVkRXJyb3JMb2dnZXIpXHJcblxyXG4gICAgICBjb25zdCBtYWluU2VxVHJhbnNwb3J0OiBBYnN0cmFjdExvZ2dlckhhbmRsZXIgPSAoe1xyXG4gICAgICAgIGFyZ3MsXHJcbiAgICAgICAgZmlyc3RTdHJpbmcsXHJcbiAgICAgICAgZmlyc3RFcnJvcixcclxuICAgICAgICBvdGhlckRhdGEsXHJcbiAgICAgICAgbm9uT2JqZWN0T3RoZXJEYXRhLFxyXG4gICAgICAgIGxldmVsXHJcbiAgICAgIH0pID0+IHtcclxuICAgICAgICBpZiAoIWFyZ3MubGVuZ3RoKSByZXR1cm5cclxuXHJcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBjb2xsZWN0TG9uZ1RyYWNlKClcclxuICAgICAgICBjb25zdCBpc0Vycm9yID0gWydlcnJvcicsICdmYXRhbCddLmluY2x1ZGVzKGxldmVsKVxyXG4gICAgICAgIGNvbnN0IGlzSW1wb3J0YW50ID0gISFvdGhlckRhdGE/LmltcG9ydGFudFxyXG4gICAgICAgIGlmICghaXNFcnJvciAmJiAhaXNJbXBvcnRhbnQpIHJldHVyblxyXG5cclxuICAgICAgICBpZiAoaXNFcnJvcikge1xyXG4gICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZmlyc3RFcnJvcj8ubWVzc2FnZSA/PyBmaXJzdFN0cmluZyA/PyBgVW5rbm93biBlcnJvcmBcclxuICAgICAgICAgIGNvbnN0IGV4Y2VwdGlvbiA9XHJcbiAgICAgICAgICAgIGZpcnN0RXJyb3I/LnN0YWNrID8/XHJcbiAgICAgICAgICAgIG5ldyBFcnJvcihcclxuICAgICAgICAgICAgICAnTm8gRXJyb3IgaW5zdGFuY2Ugd2FzIHRocm93biwgdGh1cyB0aGUgZm9sbG93aW5nIHN0YWNrIHRyYWNlIGlzIHN5bnRoZXNpemVkIG1hbnVhbGx5J1xyXG4gICAgICAgICAgICApLnN0YWNrXHJcblxyXG4gICAgICAgICAgc2VxTG9nZ2VyLmVtaXQoe1xyXG4gICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxyXG4gICAgICAgICAgICBtZXNzYWdlVGVtcGxhdGU6ICdDbGllbnQtc2lkZSBlcnJvcjoge21haW5TZXFFcnJvck1lc3NhZ2V9JyxcclxuICAgICAgICAgICAgcHJvcGVydGllczoge1xyXG4gICAgICAgICAgICAgIG1haW5TZXFFcnJvck1lc3NhZ2U6IGVycm9yTWVzc2FnZSwgLy8gd2VpcmQgbmFtZSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBvdGhlckRhdGFcclxuICAgICAgICAgICAgICBleHRyYURhdGE6IG5vbk9iamVjdE90aGVyRGF0YSxcclxuICAgICAgICAgICAgICBzdGFjayxcclxuICAgICAgICAgICAgICBmaXJzdEVycm9yLFxyXG4gICAgICAgICAgICAgIGZpcnN0U3RyaW5nLFxyXG4gICAgICAgICAgICAgIC4uLm90aGVyRGF0YSxcclxuICAgICAgICAgICAgICAuLi5jb2xsZWN0Q29yZUluZm8oKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBleGNlcHRpb25cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHNlcUxvZ2dlci5lbWl0KHtcclxuICAgICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgICAgICBsZXZlbCxcclxuICAgICAgICAgICAgbWVzc2FnZVRlbXBsYXRlOiBmaXJzdFN0cmluZyxcclxuICAgICAgICAgICAgcHJvcGVydGllczoge1xyXG4gICAgICAgICAgICAgIGV4dHJhRGF0YTogbm9uT2JqZWN0T3RoZXJEYXRhLFxyXG4gICAgICAgICAgICAgIGZpcnN0RXJyb3IsXHJcbiAgICAgICAgICAgICAgc3RhY2ssXHJcbiAgICAgICAgICAgICAgLi4ub3RoZXJEYXRhLFxyXG4gICAgICAgICAgICAgIC4uLmNvbGxlY3RDb3JlSW5mbygpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGxvZ0hhbmRsZXJzLnB1c2gobWFpblNlcVRyYW5zcG9ydClcclxuXHJcbiAgICAgIGxvZ2dlci5kZWJ1ZygnU2V0IHVwIHNlcSBpbmdlc3Rpb24uLi4nKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gUmVnaXN0ZXIgc2VxIHRyYW5zcG9ydHMsIGlmIGFueVxyXG4gIGlmIChsb2dIYW5kbGVycy5sZW5ndGggfHwgdW5oYW5kbGVkRXJyb3JIYW5kbGVycy5sZW5ndGgpIHtcclxuICAgIHJlZ2lzdGVyRXJyb3JUcmFuc3BvcnQoe1xyXG4gICAgICBvbkxvZzogKC4uLnBhcmFtcykgPT4ge1xyXG4gICAgICAgIGxvZ0hhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IGhhbmRsZXIoLi4ucGFyYW1zKSlcclxuICAgICAgfSxcclxuICAgICAgb25VbmhhbmRsZWRFcnJvcjogKGV2ZW50KSA9PiB7XHJcbiAgICAgICAgdW5oYW5kbGVkRXJyb3JIYW5kbGVycy5mb3JFYWNoKChoYW5kbGVyKSA9PiBoYW5kbGVyKGV2ZW50KSlcclxuICAgICAgfVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIC8vIEdsb2JhbCBsb2dnZXIgaGFuZGxlciAtIGhhbmRsZSBhbGwgdHJhbnNwb3J0cyBiZXNpZGVzIHRoZSBjb3JlIHBpbm8vY29uc29sZS5sb2cgbG9nZ2VyXHJcbiAgY29uc3QgdHJhbnNwb3J0cyA9IHVzZUdldExvZ2dpbmdUcmFuc3BvcnRzKClcclxuICBsb2dnZXIgPSBlbmFibGVDdXN0b21Mb2dnZXJIYW5kbGluZyh7XHJcbiAgICBsb2dnZXIsXHJcbiAgICBoYW5kbGVyOiAocGFyYW1zLCBoZWxwZXJzKSA9PiB7XHJcbiAgICAgIHRyYW5zcG9ydHMuZm9yRWFjaCgoaGFuZGxlcikgPT4gaGFuZGxlci5vbkxvZz8uKHBhcmFtcywgaGVscGVycykpXHJcbiAgICB9XHJcbiAgfSlcclxuXHJcbiAgLy8gVW5oYW5kbGVkIGVycm9yIGhhbmRsZXJcclxuICBpZiAoaW1wb3J0Lm1ldGEuY2xpZW50ICYmIHdpbmRvdykge1xyXG4gICAgY29uc3QgdW5oYW5kbGVkSGFuZGxlciA9IChldmVudDogRXJyb3JFdmVudCB8IFByb21pc2VSZWplY3Rpb25FdmVudCkgPT4ge1xyXG4gICAgICBjb25zdCBoYW5kbGVycyA9IHRyYW5zcG9ydHMuZmlsdGVyKFxyXG4gICAgICAgICh0KTogdCBpcyBTZXRSZXF1aXJlZDx0eXBlb2YgdCwgJ29uVW5oYW5kbGVkRXJyb3InPiA9PiAhIXQub25VbmhhbmRsZWRFcnJvclxyXG4gICAgICApXHJcblxyXG4gICAgICBjb25zdCBpc1VuaGFuZGxlZFJlamVjdGlvbiA9IGlzT2JqZWN0TGlrZShldmVudCkgJiYgJ3JlYXNvbicgaW4gZXZlbnRcclxuICAgICAgY29uc3QgZXJyb3IgPSAoJ3JlYXNvbicgaW4gZXZlbnQgPyBldmVudC5yZWFzb24gOiBldmVudC5lcnJvcikgYXMgdW5rbm93blxyXG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBgJHtlcnJvcn1gXHJcblxyXG4gICAgICBoYW5kbGVycy5mb3JFYWNoKChoYW5kbGVyKSA9PlxyXG4gICAgICAgIGhhbmRsZXIub25VbmhhbmRsZWRFcnJvcih7IGV2ZW50LCBpc1VuaGFuZGxlZFJlamVjdGlvbiwgZXJyb3IsIG1lc3NhZ2UgfSlcclxuICAgICAgKVxyXG4gICAgfVxyXG5cclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIHVuaGFuZGxlZEhhbmRsZXIpXHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndW5oYW5kbGVkcmVqZWN0aW9uJywgdW5oYW5kbGVkSGFuZGxlcilcclxuICB9XHJcblxyXG4gIGNvbnN0IGdldEVycm9yU3RhdHVzQ29kZSA9IChlcnI6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQgPT4ge1xyXG4gICAgaWYgKGlzT2JqZWN0TGlrZShlcnIpICYmICdzdGF0dXNDb2RlJyBpbiBlcnIpIHtcclxuICAgICAgY29uc3Qgc3RhdHVzQ29kZSA9IGVyci5zdGF0dXNDb2RlXHJcbiAgICAgIGlmICh0eXBlb2Ygc3RhdHVzQ29kZSA9PT0gJ251bWJlcicgJiYgIU51bWJlci5pc05hTihzdGF0dXNDb2RlKSkge1xyXG4gICAgICAgIHJldHVybiBzdGF0dXNDb2RlXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB1bmRlZmluZWRcclxuICB9XHJcblxyXG4gIGNvbnN0IGlzSWdub3JhYmxlRXJyb3IgPSAoZXJyOiB1bmtub3duKSA9PiB7XHJcbiAgICAvLyBza2lwIDQwNCwgNDAzLCA0MDFcclxuICAgIGNvbnN0IHN0YXR1c0NvZGUgPSBnZXRFcnJvclN0YXR1c0NvZGUoZXJyKVxyXG4gICAgaWYgKHR5cGVvZiBzdGF0dXNDb2RlID09PSAnbnVtYmVyJykge1xyXG4gICAgICBpZiAoWzQwNCwgNDAzLCA0MDFdLmluY2x1ZGVzKHN0YXR1c0NvZGUpKSByZXR1cm4gdHJ1ZVxyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFVuY2F1Z2h0IHJvdXRpbmcgZXJyb3IgaGFuZGxlclxyXG4gIHJvdXRlci5vbkVycm9yKChlcnIsIHRvLCBmcm9tKSA9PiB7XHJcbiAgICBpZiAoaXNJZ25vcmFibGVFcnJvcihlcnIpKSByZXR1cm5cclxuXHJcbiAgICBsb2dnZXIuZXJyb3IoXHJcbiAgICAgIHtcclxuICAgICAgICBlcnIsXHJcbiAgICAgICAgdG86IHRvLnBhdGgsXHJcbiAgICAgICAgZnJvbTogZnJvbT8ucGF0aCxcclxuICAgICAgICBpc0FwcEVycm9yOiAhIWltcG9ydC5tZXRhLnNlcnZlcixcclxuICAgICAgICB1bmhhbmRsZWRSb3V0aW5nRXJyb3I6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogZ2V0RXJyb3JTdGF0dXNDb2RlKGVycilcclxuICAgICAgfSxcclxuICAgICAgZ2V0RXJyb3JNZXNzYWdlKGVycilcclxuICAgIClcclxuICB9KVxyXG5cclxuICAvLyBNb3JlIGVycm9yIGxvZ2dpbmcgaG9va3NcclxuICBudXh0QXBwLnZ1ZUFwcC5jb25maWcuZXJyb3JIYW5kbGVyID0gKGVycm9yLCBfdm0sIGluZm8pID0+IHtcclxuICAgIGlmIChpc0lnbm9yYWJsZUVycm9yKGVycm9yKSkgcmV0dXJuXHJcblxyXG4gICAgbG9nZ2VyLmVycm9yKFxyXG4gICAgICB7XHJcbiAgICAgICAgZXJyOiBlcnJvcixcclxuICAgICAgICBpbmZvLFxyXG4gICAgICAgIHZtOiBfdm0/LiRvcHRpb25zLm5hbWUsXHJcbiAgICAgICAgZXJyU3RyaW5nOiBlcnJvclRvU3RyaW5nKGVycm9yKSxcclxuICAgICAgICB2dWVFcnJvckhhbmRsZXI6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogZ2V0RXJyb3JTdGF0dXNDb2RlKGVycm9yKVxyXG4gICAgICB9LFxyXG4gICAgICBnZXRFcnJvck1lc3NhZ2UoZXJyb3IpXHJcbiAgICApXHJcbiAgfVxyXG4gIG51eHRBcHAuaG9vaygnYXBwOmVycm9yJywgKGVycm9yKSA9PiB7XHJcbiAgICBpZiAoaXNJZ25vcmFibGVFcnJvcihlcnJvcikpIHJldHVyblxyXG5cclxuICAgIGxvZ2dlci5lcnJvcihcclxuICAgICAge1xyXG4gICAgICAgIGVycjogZXJyb3IsXHJcbiAgICAgICAgaXNBcHBFcnJvcjogdHJ1ZSxcclxuICAgICAgICBlcnJTdHJpbmc6IGVycm9yVG9TdHJpbmcoZXJyb3IpLFxyXG4gICAgICAgIGFwcEVycm9ySG9vazogdHJ1ZSxcclxuICAgICAgICBzdGF0dXNDb2RlOiBnZXRFcnJvclN0YXR1c0NvZGUoZXJyb3IpXHJcbiAgICAgIH0sXHJcbiAgICAgIGdldEVycm9yTWVzc2FnZShlcnJvcilcclxuICAgIClcclxuICB9KVxyXG5cclxuICBudXh0QXBwLmhvb2soJ3Z1ZTplcnJvcicsIChlcnJvciwgX3ZtLCBpbmZvKSA9PiB7XHJcbiAgICBpZiAoaXNJZ25vcmFibGVFcnJvcihlcnJvcikpIHJldHVyblxyXG5cclxuICAgIGxvZ2dlci5lcnJvcihcclxuICAgICAge1xyXG4gICAgICAgIGVycjogZXJyb3IsXHJcbiAgICAgICAgaW5mbyxcclxuICAgICAgICBpc0FwcEVycm9yOiB0cnVlLFxyXG4gICAgICAgIHZtOiBfdm0/LiRvcHRpb25zLm5hbWUsXHJcbiAgICAgICAgZXJyU3RyaW5nOiBlcnJvclRvU3RyaW5nKGVycm9yKSxcclxuICAgICAgICB2dWVFcnJvckhvb2s6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogZ2V0RXJyb3JTdGF0dXNDb2RlKGVycm9yKVxyXG4gICAgICB9LFxyXG4gICAgICBnZXRFcnJvck1lc3NhZ2UoZXJyb3IpXHJcbiAgICApXHJcbiAgfSlcclxuXHJcbiAgLy8gSHlkcmF0ZSBzZXJ2ZXIgZmF0YWwgZXJyb3IgdG8gQ1NSXHJcbiAgaWYgKCFpbXBvcnQubWV0YS5zZXJ2ZXIpIHtcclxuICAgIG51eHRBcHAuaG9vaygnYXBwOm1vdW50ZWQnLCAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IHNlcnZlckZhdGFsRXJyb3IgPSBudXh0QXBwLnBheWxvYWQuZXJyb3JcclxuICAgICAgaWYgKHNlcnZlckZhdGFsRXJyb3IgJiYgc2VydmVyRmF0YWxFcnJvci5zdGF0dXNDb2RlID49IDUwMCkge1xyXG4gICAgICAgIGNvbnN0IG1zZyA9IHNlcnZlckZhdGFsRXJyb3IubWVzc2FnZSB8fCAnRmF0YWwgc2VydmVyIGVycm9yJ1xyXG4gICAgICAgIGNvbnN0IHN0YWNrID0gc2VydmVyRmF0YWxFcnJvci5zdGFja1xyXG4gICAgICAgICAgPyBzaW1wbGVTdHJpcEh0bWwoc2VydmVyRmF0YWxFcnJvci5zdGFjaylcclxuICAgICAgICAgIDogdW5kZWZpbmVkXHJcbiAgICAgICAgY29uc3QgZmluYWxTdGFjayA9IGAke21zZ30ke3N0YWNrID8gYFxcbiR7c3RhY2t9YCA6ICcnfWBcclxuXHJcbiAgICAgICAgY29uc3QgbnV4dEVycm9yID0gY3JlYXRlRXJyb3Ioe1xyXG4gICAgICAgICAgLi4uc2VydmVyRmF0YWxFcnJvcixcclxuICAgICAgICAgIC4uLihmaW5hbFN0YWNrID8geyBzdGFjazogZmluYWxTdGFjayB9IDoge30pXHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICAgY29uc3QgcGF5bG9hZDogQWJzdHJhY3RMb2dnZXJIYW5kbGVyUGFyYW1zID0ge1xyXG4gICAgICAgICAgYXJnczogWydGYXRhbCBzZXJ2ZXIgZXJyb3InLCBzZXJ2ZXJGYXRhbEVycm9yXSxcclxuICAgICAgICAgIGZpcnN0RXJyb3I6IG51eHRFcnJvcixcclxuICAgICAgICAgIGZpcnN0U3RyaW5nOiAnRmF0YWwgc2VydmVyIGVycm9yJyxcclxuICAgICAgICAgIG90aGVyRGF0YTogeyBpc0FwcEVycm9yOiB0cnVlIH0sXHJcbiAgICAgICAgICBub25PYmplY3RPdGhlckRhdGE6IFtdLFxyXG4gICAgICAgICAgbGV2ZWw6ICdmYXRhbCdcclxuICAgICAgICB9XHJcbiAgICAgICAgaW52b2tlVHJhbnNwb3J0c1dpdGhQYXlsb2FkKHBheWxvYWQpXHJcblxyXG4gICAgICAgIGlmIChpbXBvcnQubWV0YS5kZXYpIHtcclxuICAgICAgICAgIC8vIGludGVudGlvbmFsbHkgc2tpcHBpbmcgZXJyb3IgcGlwZWxpbmU6XHJcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxyXG4gICAgICAgICAgY29uc29sZS5lcnJvcignRmF0YWwgZXJyb3Igb2NjdXJyZWQgb24gc2VydmVyOicsIHBheWxvYWQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgLy8gTG9nIGltcG9ydGFudCB0aWVyIGFwcCBtb3VudGVkIG1zZyBmb3Igc2VxXHJcbiAgaWYgKCFpbXBvcnQubWV0YS5zZXJ2ZXIpIHtcclxuICAgIG51eHRBcHAuaG9vaygnYXBwOm1vdW50ZWQnLCAoKSA9PiB7XHJcbiAgICAgIGxvZ2dlci5pbmZvKCdBcHAgbW91bnRlZCBpbiB0aGUgY2xpZW50Jywge1xyXG4gICAgICAgIGltcG9ydGFudDogdHJ1ZSxcclxuICAgICAgICBzcGVja2xlU2VydmVyVmVyc2lvbixcclxuICAgICAgICBydW50aW1lQ29uZmlnXHJcbiAgICAgIH0pXHJcbiAgICB9KVxyXG4gIH0gZWxzZSB7XHJcbiAgICBudXh0QXBwLmhvb2soJ2FwcDpyZW5kZXJlZCcsICgpID0+IHtcclxuICAgICAgbG9nZ2VyLmluZm8oJ0FwcCBTU1IgcmVuZGVyZWQnLCB7XHJcbiAgICAgICAgaW1wb3J0YW50OiB0cnVlLFxyXG4gICAgICAgIHNwZWNrbGVTZXJ2ZXJWZXJzaW9uXHJcbiAgICAgIH0pXHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIHByb3ZpZGU6IHtcclxuICAgICAgbG9nZ2VyXHJcbiAgICB9XHJcbiAgfVxyXG59KVxyXG4iXSwiZmlsZSI6IkQ6L3NwZWNrbGUtc2VydmVyL3BhY2thZ2VzL2Zyb250ZW5kLTIvcGx1Z2lucy8wMTAtbG9nZ2VyLnRzIn0=