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

195 lines
33 KiB
Plaintext

import { err, ok } from "/_nuxt/node_modules/.cache/vite/client/deps/true-myth_result.js?v=e4f18c29";
import { ProjectNoAccessError, ProjectNotEnoughPermissionsError, ProjectNotFoundError, WorkspaceNoAccessError } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/authz/domain/authErrors.js";
import { Roles } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/core/constants.js";
import { isMinimumProjectRole } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/authz/domain/logic/roles.js";
import { hasMinimumProjectRole, isPubliclyReadableProject } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/authz/checks/projects.js";
import { ensureCanUseWorkspacePlanFeatureFragment, ensureWorkspaceRoleAndSessionFragment } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/authz/fragments/workspaces.js";
import { checkIfAdminOverrideEnabledFragment, ensureMinimumServerRoleFragment } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/authz/fragments/server.js";
import { ProjectVisibility } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/authz/domain/projects/types.js";
const workspaceRoleImplicitProjectRoleMap = (projectVisibility) => {
const isFullyPrivate = projectVisibility === ProjectVisibility.Private;
return {
[Roles.Workspace.Admin]: Roles.Stream.Owner,
[Roles.Workspace.Member]: isFullyPrivate ? null : Roles.Stream.Reviewer,
[Roles.Workspace.Guest]: null
};
};
/**
* Ensure user has a minimum explicit or implicit project role
*/
export const ensureMinimumProjectRoleFragment = (loaders) => async ({ userId, projectId, role, explicit }) => {
const requiredProjectRole = role || Roles.Stream.Reviewer;
const isTestingForMinimumAccess = requiredProjectRole === Roles.Stream.Reviewer;
const env = await loaders.getEnv();
const project = await loaders.getProject({ projectId });
if (!project)
return err(new ProjectNotFoundError());
// Check for explicit project role first
const hasExplicitProjectRole = await hasMinimumProjectRole(loaders)({
userId,
projectId,
role: requiredProjectRole
});
if (hasExplicitProjectRole)
return ok();
// Now check if there's an implicit one
const { workspaceId } = project;
if (env.FF_WORKSPACES_MODULE_ENABLED && !!workspaceId) {
// Check for implicit workspace project role
const userWorkspaceRole = await loaders.getWorkspaceRole({ userId, workspaceId });
if (userWorkspaceRole) {
const implicitProjectRole = explicit
? null
: workspaceRoleImplicitProjectRoleMap(project.visibility)[userWorkspaceRole];
if (implicitProjectRole) {
// Does it fit minimum?
if (isMinimumProjectRole(implicitProjectRole, requiredProjectRole)) {
return ok();
}
else {
// Have some permissions, but not enough
return err(new ProjectNotEnoughPermissionsError());
}
}
}
}
// Do we have any role at all?
const anyRoleFound = await loaders.getProjectRole({ userId, projectId });
return err(isTestingForMinimumAccess || !anyRoleFound
? new ProjectNoAccessError()
: new ProjectNotEnoughPermissionsError());
};
/**
* Ensure user has access to the project's workspace (has role & SSO session, if any), if it has one
*/
export const ensureProjectWorkspaceAccessFragment = (loaders) => async ({ userId, projectId }) => {
const env = await loaders.getEnv();
const project = await loaders.getProject({ projectId });
if (!project)
return err(new ProjectNotFoundError());
const { workspaceId } = project;
if (!workspaceId || !env.FF_WORKSPACES_MODULE_ENABLED)
return ok();
const memberWithSsoSession = await ensureWorkspaceRoleAndSessionFragment(loaders)({
userId,
workspaceId
});
if (memberWithSsoSession.isErr) {
switch (memberWithSsoSession.error.code) {
case WorkspaceNoAccessError.code:
return err(new WorkspaceNoAccessError("You do not have access to this project's workspace"));
default:
return err(memberWithSsoSession.error);
}
}
return memberWithSsoSession;
};
/**
* Check if project is publicly readable or not
*/
export const checkIfPubliclyReadableProjectFragment = (loaders) => async ({ projectId }) => {
const project = await loaders.getProject({ projectId });
if (!project)
return err(new ProjectNotFoundError());
return ok(await isPubliclyReadableProject(loaders)({ projectId }));
};
/**
* Ensure user has implicit/explicit project membership and read access
*/
export const ensureImplicitProjectMemberWithReadAccessFragment = (loaders) => async ({ userId, projectId, role }) => {
// Ensure user is authed
const ensuredServerRole = await ensureMinimumServerRoleFragment(loaders)({
userId,
role: Roles.Server.Guest
});
if (ensuredServerRole.isErr) {
return err(ensuredServerRole.error);
}
// Check if user has admin override enabled
const isAdminOverrideEnabled = await checkIfAdminOverrideEnabledFragment(loaders)({
userId
});
if (isAdminOverrideEnabled.isErr) {
return err(isAdminOverrideEnabled.error);
}
if (isAdminOverrideEnabled.value)
return ok();
// And ensure (implicit/explicit) project role
const ensuredProjectRole = await ensureMinimumProjectRoleFragment(loaders)({
userId: userId,
projectId,
role
});
if (ensuredProjectRole.isErr) {
return err(ensuredProjectRole.error);
}
// No god mode, ensure workspace access
const ensuredWorkspaceAccess = await ensureProjectWorkspaceAccessFragment(loaders)({
userId: userId,
projectId
});
if (ensuredWorkspaceAccess.isErr) {
return err(ensuredWorkspaceAccess.error);
}
return ok();
};
/**
* Ensure user has implicit/explicit project membership and write access
*/
export const ensureImplicitProjectMemberWithWriteAccessFragment = (loaders) => async ({ userId, projectId, role }) => {
const requiredProjectRole = role || Roles.Stream.Contributor;
const requiredServerRole = requiredProjectRole === Roles.Stream.Owner
? Roles.Server.User
: Roles.Server.Guest;
// Ensure user is authed
const ensuredServerRole = await ensureMinimumServerRoleFragment(loaders)({
userId,
role: requiredServerRole
});
if (ensuredServerRole.isErr) {
return err(ensuredServerRole.error);
}
// And ensure (implicit/explicit) project role
const ensuredProjectRole = await ensureMinimumProjectRoleFragment(loaders)({
userId: userId,
projectId,
role: requiredProjectRole
});
if (ensuredProjectRole.isErr) {
return err(ensuredProjectRole.error);
}
// Ensure workspace access
const ensuredWorkspaceAccess = await ensureProjectWorkspaceAccessFragment(loaders)({
userId: userId,
projectId
});
if (ensuredWorkspaceAccess.isErr) {
return err(ensuredWorkspaceAccess.error);
}
return ok();
};
/**
* Ensure project is workspaced and has access to a specific plan feature
*/
export const ensureCanUseProjectWorkspacePlanFeatureFragment = (loaders) => async ({ projectId, feature, allowUnworkspaced = false }) => {
const project = await loaders.getProject({ projectId });
if (!project)
return err(new ProjectNotFoundError());
const workspaceId = project.workspaceId;
if (!workspaceId) {
if (allowUnworkspaced)
return ok();
return err(new WorkspaceNoAccessError({
message: 'The project must be in a workspace'
}));
}
const canUseFeature = await ensureCanUseWorkspacePlanFeatureFragment(loaders)({
workspaceId,
feature
});
if (canUseFeature.isErr)
return err(canUseFeature.error);
return ok();
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXV0aHovZnJhZ21lbnRzL3Byb2plY3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFPMUMsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixnQ0FBZ0MsRUFDaEMsb0JBQW9CLEVBSXBCLHNCQUFzQixFQU12QixNQUFNLHlCQUF5QixDQUFBO0FBQ2hDLE9BQU8sRUFBRSxLQUFLLEVBQWUsTUFBTSx5QkFBeUIsQ0FBQTtBQUM1RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUMvRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUN4RixPQUFPLEVBQ0wsd0NBQXdDLEVBQ3hDLHFDQUFxQyxFQUN0QyxNQUFNLGlCQUFpQixDQUFBO0FBQ3hCLE9BQU8sRUFDTCxtQ0FBbUMsRUFDbkMsK0JBQStCLEVBQ2hDLE1BQU0sYUFBYSxDQUFBO0FBQ3BCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFBO0FBRy9ELE1BQU0sbUNBQW1DLEdBQUcsQ0FBQyxpQkFBb0MsRUFBRSxFQUFFO0lBQ25GLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixLQUFLLGlCQUFpQixDQUFDLE9BQU8sQ0FBQTtJQUV0RSxPQUFjO1FBQ1osQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSztRQUMzQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUTtRQUN2RSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FB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LENBQUE7QUFDYixDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBlcnIsIG9rIH0gZnJvbSAndHJ1ZS1teXRoL3Jlc3VsdCdcclxuaW1wb3J0IHsgTWF5YmVVc2VyQ29udGV4dCwgUHJvamVjdENvbnRleHQsIFVzZXJDb250ZXh0IH0gZnJvbSAnLi4vZG9tYWluL2NvbnRleHQuanMnXHJcbmltcG9ydCB7IExvYWRlcnMgfSBmcm9tICcuLi9kb21haW4vbG9hZGVycy5qcydcclxuaW1wb3J0IHtcclxuICBBdXRoUG9saWN5Q2hlY2tGcmFnbWVudCxcclxuICBBdXRoUG9saWN5RW5zdXJlRnJhZ21lbnRcclxufSBmcm9tICcuLi9kb21haW4vcG9saWNpZXMuanMnXHJcbmltcG9ydCB7XHJcbiAgUHJvamVjdE5vQWNjZXNzRXJyb3IsXHJcbiAgUHJvamVjdE5vdEVub3VnaFBlcm1pc3Npb25zRXJyb3IsXHJcbiAgUHJvamVjdE5vdEZvdW5kRXJyb3IsXHJcbiAgU2VydmVyTm9BY2Nlc3NFcnJvcixcclxuICBTZXJ2ZXJOb1Nlc3Npb25FcnJvcixcclxuICBTZXJ2ZXJOb3RFbm91Z2hQZXJtaXNzaW9uc0Vycm9yLFxyXG4gIFdvcmtzcGFjZU5vQWNjZXNzRXJyb3IsXHJcbiAgV29ya3NwYWNlTm90RW5vdWdoUGVybWlzc2lvbnNFcnJvcixcclxuICBXb3Jrc3BhY2VQbGFuTm9GZWF0dXJlQWNjZXNzRXJyb3IsXHJcbiAgV29ya3NwYWNlUmVhZE9ubHlFcnJvcixcclxuICBXb3Jrc3BhY2VzTm90RW5hYmxlZEVycm9yLFxyXG4gIFdvcmtzcGFjZVNzb1Nlc3Npb25Ob0FjY2Vzc0Vycm9yXHJcbn0gZnJvbSAnLi4vZG9tYWluL2F1dGhFcnJvcnMuanMnXHJcbmltcG9ydCB7IFJvbGVzLCBTdHJlYW1Sb2xlcyB9IGZyb20gJy4uLy4uL2NvcmUvY29uc3RhbnRzLmpzJ1xyXG5pbXBvcnQgeyBpc01pbmltdW1Qcm9qZWN0Um9sZSB9IGZyb20gJy4uL2RvbWFpbi9sb2dpYy9yb2xlcy5qcydcclxuaW1wb3J0IHsgaGFzTWluaW11bVByb2plY3RSb2xlLCBpc1B1YmxpY2x5UmVhZGFibGVQcm9qZWN0IH0gZnJvbSAnLi4vY2hlY2tzL3Byb2plY3RzLmpzJ1xyXG5pbXBvcnQge1xyXG4gIGVuc3VyZUNhblVzZVdvcmtzcGFjZVBsYW5GZWF0dXJlRnJhZ21lbnQsXHJcbiAgZW5zdXJlV29ya3NwYWNlUm9sZUFuZFNlc3Npb25GcmFnbWVudFxyXG59IGZyb20gJy4vd29ya3NwYWNlcy5qcydcclxuaW1wb3J0IHtcclxuICBjaGVja0lmQWRtaW5PdmVycmlkZUVuYWJsZWRGcmFnbWVudCxcclxuICBlbnN1cmVNaW5pbXVtU2VydmVyUm9sZUZyYWdtZW50XHJcbn0gZnJvbSAnLi9zZXJ2ZXIuanMnXHJcbmltcG9ydCB7IFByb2plY3RWaXNpYmlsaXR5IH0gZnJvbSAnLi4vZG9tYWluL3Byb2plY3RzL3R5cGVzLmpzJ1xyXG5pbXBvcnQgeyBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMgfSBmcm9tICcuLi8uLi93b3Jrc3BhY2VzL2luZGV4LmpzJ1xyXG5cclxuY29uc3Qgd29ya3NwYWNlUm9sZUltcGxpY2l0UHJvamVjdFJvbGVNYXAgPSAocHJvamVjdFZpc2liaWxpdHk6IFByb2plY3RWaXNpYmlsaXR5KSA9PiB7XHJcbiAgY29uc3QgaXNGdWxseVByaXZhdGUgPSBwcm9qZWN0VmlzaWJpbGl0eSA9PT0gUHJvamVjdFZpc2liaWxpdHkuUHJpdmF0ZVxyXG5cclxuICByZXR1cm4gPGNvbnN0PntcclxuICAgIFtSb2xlcy5Xb3Jrc3BhY2UuQWRtaW5dOiBSb2xlcy5TdHJlYW0uT3duZXIsXHJcbiAgICBbUm9sZXMuV29ya3NwYWNlLk1lbWJlcl06IGlzRnVsbHlQcml2YXRlID8gbnVsbCA6IFJvbGVzLlN0cmVhbS5SZXZpZXdlcixcclxuICAgIFtSb2xlcy5Xb3Jrc3BhY2UuR3Vlc3RdOiBudWxsXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogRW5zdXJlIHVzZXIgaGFzIGEgbWluaW11bSBleHBsaWNpdCBvciBpbXBsaWNpdCBwcm9qZWN0IHJvbGVcclxuICovXHJcbmV4cG9ydCBjb25zdCBlbnN1cmVNaW5pbXVtUHJvamVjdFJvbGVGcmFnbWVudDogQXV0aFBvbGljeUVuc3VyZUZyYWdtZW50PFxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0UHJvamVjdFxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0U2VydmVyUm9sZVxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0RW52XHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VSb2xlXHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFdvcmtzcGFjZVNzb1Byb3ZpZGVyXHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VTc29TZXNzaW9uXHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRQcm9qZWN0Um9sZSxcclxuICBQcm9qZWN0Q29udGV4dCAmXHJcbiAgICBVc2VyQ29udGV4dCAmIHtcclxuICAgICAgLyoqXHJcbiAgICAgICAqIE9wdGlvbmFsbHkgc3BlY2lmeSByb2xlIHRoZSB1c2VyIHNob3VsZCBoYXZlXHJcbiAgICAgICAqL1xyXG4gICAgICByb2xlPzogU3RyZWFtUm9sZXNcclxuICAgICAgLyoqXHJcbiAgICAgICAqIE9wdGlvbmFsbHkgb25seSBhbGxvdyBleHBsaWNpdCBwcm9qZWN0IHJvbGVzXHJcbiAgICAgICAqL1xyXG4gICAgICBleHBsaWNpdD86IGJvb2xlYW5cclxuICAgIH0sXHJcbiAgSW5zdGFuY2VUeXBlPFxyXG4gICAgfCB0eXBlb2YgUHJvamVjdE5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFByb2plY3ROb3RGb3VuZEVycm9yXHJcbiAgICB8IHR5cGVvZiBQcm9qZWN0Tm90RW5vdWdoUGVybWlzc2lvbnNFcnJvclxyXG4gID5cclxuPiA9XHJcbiAgKGxvYWRlcnMpID0+XHJcbiAgYXN5bmMgKHsgdXNlcklkLCBwcm9qZWN0SWQsIHJvbGUsIGV4cGxpY2l0IH0pID0+IHtcclxuICAgIGNvbnN0IHJlcXVpcmVkUHJvamVjdFJvbGUgPSByb2xlIHx8IFJvbGVzLlN0cmVhbS5SZXZpZXdlclxyXG4gICAgY29uc3QgaXNUZXN0aW5nRm9yTWluaW11bUFjY2VzcyA9IHJlcXVpcmVkUHJvamVjdFJvbGUgPT09IFJvbGVzLlN0cmVhbS5SZXZpZXdlclxyXG5cclxuICAgIGNvbnN0IGVudiA9IGF3YWl0IGxvYWRlcnMuZ2V0RW52KClcclxuICAgIGNvbnN0IHByb2plY3QgPSBhd2FpdCBsb2FkZXJzLmdldFByb2plY3QoeyBwcm9qZWN0SWQgfSlcclxuICAgIGlmICghcHJvamVjdCkgcmV0dXJuIGVycihuZXcgUHJvamVjdE5vdEZvdW5kRXJyb3IoKSlcclxuXHJcbiAgICAvLyBDaGVjayBmb3IgZXhwbGljaXQgcHJvamVjdCByb2xlIGZpcnN0XHJcbiAgICBjb25zdCBoYXNFeHBsaWNpdFByb2plY3RSb2xlID0gYXdhaXQgaGFzTWluaW11bVByb2plY3RSb2xlKGxvYWRlcnMpKHtcclxuICAgICAgdXNlcklkLFxyXG4gICAgICBwcm9qZWN0SWQsXHJcbiAgICAgIHJvbGU6IHJlcXVpcmVkUHJvamVjdFJvbGVcclxuICAgIH0pXHJcbiAgICBpZiAoaGFzRXhwbGljaXRQcm9qZWN0Um9sZSkgcmV0dXJuIG9rKClcclxuXHJcbiAgICAvLyBOb3cgY2hlY2sgaWYgdGhlcmUncyBhbiBpbXBsaWNpdCBvbmVcclxuICAgIGNvbnN0IHsgd29ya3NwYWNlSWQgfSA9IHByb2plY3RcclxuXHJcbiAgICBpZiAoZW52LkZGX1dPUktTUEFDRVNfTU9EVUxFX0VOQUJMRUQgJiYgISF3b3Jrc3BhY2VJZCkge1xyXG4gICAgICAvLyBDaGVjayBmb3IgaW1wbGljaXQgd29ya3NwYWNlIHByb2plY3Qgcm9sZVxyXG4gICAgICBjb25zdCB1c2VyV29ya3NwYWNlUm9sZSA9IGF3YWl0IGxvYWRlcnMuZ2V0V29ya3NwYWNlUm9sZSh7IHVzZXJJZCwgd29ya3NwYWNlSWQgfSlcclxuICAgICAgaWYgKHVzZXJXb3Jrc3BhY2VSb2xlKSB7XHJcbiAgICAgICAgY29uc3QgaW1wbGljaXRQcm9qZWN0Um9sZSA9IGV4cGxpY2l0XHJcbiAgICAgICAgICA/IG51bGxcclxuICAgICAgICAgIDogd29ya3NwYWNlUm9sZUltcGxpY2l0UHJvamVjdFJvbGVNYXAocHJvamVjdC52aXNpYmlsaXR5KVt1c2VyV29ya3NwYWNlUm9sZV1cclxuICAgICAgICBpZiAoaW1wbGljaXRQcm9qZWN0Um9sZSkge1xyXG4gICAgICAgICAgLy8gRG9lcyBpdCBmaXQgbWluaW11bT9cclxuICAgICAgICAgIGlmIChpc01pbmltdW1Qcm9qZWN0Um9sZShpbXBsaWNpdFByb2plY3RSb2xlLCByZXF1aXJlZFByb2plY3RSb2xlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2soKVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gSGF2ZSBzb21lIHBlcm1pc3Npb25zLCBidXQgbm90IGVub3VnaFxyXG4gICAgICAgICAgICByZXR1cm4gZXJyKG5ldyBQcm9qZWN0Tm90RW5vdWdoUGVybWlzc2lvbnNFcnJvcigpKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIERvIHdlIGhhdmUgYW55IHJvbGUgYXQgYWxsP1xyXG4gICAgY29uc3QgYW55Um9sZUZvdW5kID0gYXdhaXQgbG9hZGVycy5nZXRQcm9qZWN0Um9sZSh7IHVzZXJJZCwgcHJvamVjdElkIH0pXHJcblxyXG4gICAgcmV0dXJuIGVycihcclxuICAgICAgaXNUZXN0aW5nRm9yTWluaW11bUFjY2VzcyB8fCAhYW55Um9sZUZvdW5kXHJcbiAgICAgICAgPyBuZXcgUHJvamVjdE5vQWNjZXNzRXJyb3IoKVxyXG4gICAgICAgIDogbmV3IFByb2plY3ROb3RFbm91Z2hQZXJtaXNzaW9uc0Vycm9yKClcclxuICAgIClcclxuICB9XHJcblxyXG4vKipcclxuICogRW5zdXJlIHVzZXIgaGFzIGFjY2VzcyB0byB0aGUgcHJvamVjdCdzIHdvcmtzcGFjZSAoaGFzIHJvbGUgJiBTU08gc2Vzc2lvbiwgaWYgYW55KSwgaWYgaXQgaGFzIG9uZVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGVuc3VyZVByb2plY3RXb3Jrc3BhY2VBY2Nlc3NGcmFnbWVudDogQXV0aFBvbGljeUVuc3VyZUZyYWdtZW50PFxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0UHJvamVjdFxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0RW52XHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VTc29Qcm92aWRlclxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0V29ya3NwYWNlU3NvU2Vzc2lvblxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0V29ya3NwYWNlXHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VSb2xlLFxyXG4gIHsgdXNlcklkOiBzdHJpbmc7IHByb2plY3RJZDogc3RyaW5nIH0sXHJcbiAgSW5zdGFuY2VUeXBlPFxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlU3NvU2Vzc2lvbk5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFdvcmtzcGFjZU5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFdvcmtzcGFjZU5vdEVub3VnaFBlcm1pc3Npb25zRXJyb3JcclxuICAgIHwgdHlwZW9mIFByb2plY3ROb3RGb3VuZEVycm9yXHJcbiAgPlxyXG4+ID1cclxuICAobG9hZGVycykgPT5cclxuICBhc3luYyAoeyB1c2VySWQsIHByb2plY3RJZCB9KSA9PiB7XHJcbiAgICBjb25zdCBlbnYgPSBhd2FpdCBsb2FkZXJzLmdldEVudigpXHJcbiAgICBjb25zdCBwcm9qZWN0ID0gYXdhaXQgbG9hZGVycy5nZXRQcm9qZWN0KHsgcHJvamVjdElkIH0pXHJcbiAgICBpZiAoIXByb2plY3QpIHJldHVybiBlcnIobmV3IFByb2plY3ROb3RGb3VuZEVycm9yKCkpXHJcblxyXG4gICAgY29uc3QgeyB3b3Jrc3BhY2VJZCB9ID0gcHJvamVjdFxyXG4gICAgaWYgKCF3b3Jrc3BhY2VJZCB8fCAhZW52LkZGX1dPUktTUEFDRVNfTU9EVUxFX0VOQUJMRUQpIHJldHVybiBvaygpXHJcblxyXG4gICAgY29uc3QgbWVtYmVyV2l0aFNzb1Nlc3Npb24gPSBhd2FpdCBlbnN1cmVXb3Jrc3BhY2VSb2xlQW5kU2Vzc2lvbkZyYWdtZW50KGxvYWRlcnMpKHtcclxuICAgICAgdXNlcklkLFxyXG4gICAgICB3b3Jrc3BhY2VJZFxyXG4gICAgfSlcclxuICAgIGlmIChtZW1iZXJXaXRoU3NvU2Vzc2lvbi5pc0Vycikge1xyXG4gICAgICBzd2l0Y2ggKG1lbWJlcldpdGhTc29TZXNzaW9uLmVycm9yLmNvZGUpIHtcclxuICAgICAgICBjYXNlIFdvcmtzcGFjZU5vQWNjZXNzRXJyb3IuY29kZTpcclxuICAgICAgICAgIHJldHVybiBlcnIoXHJcbiAgICAgICAgICAgIG5ldyBXb3Jrc3BhY2VOb0FjY2Vzc0Vycm9yKFxyXG4gICAgICAgICAgICAgIFwiWW91IGRvIG5vdCBoYXZlIGFjY2VzcyB0byB0aGlzIHByb2plY3QncyB3b3Jrc3BhY2VcIlxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgIHJldHVybiBlcnIobWVtYmVyV2l0aFNzb1Nlc3Npb24uZXJyb3IpXHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbWVtYmVyV2l0aFNzb1Nlc3Npb25cclxuICB9XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgcHJvamVjdCBpcyBwdWJsaWNseSByZWFkYWJsZSBvciBub3RcclxuICovXHJcbmV4cG9ydCBjb25zdCBjaGVja0lmUHVibGljbHlSZWFkYWJsZVByb2plY3RGcmFnbWVudDogQXV0aFBvbGljeUNoZWNrRnJhZ21lbnQ8XHJcbiAgdHlwZW9mIExvYWRlcnMuZ2V0UHJvamVjdCB8IHR5cGVvZiBMb2FkZXJzLmdldEVudixcclxuICBQcm9qZWN0Q29udGV4dCxcclxuICBJbnN0YW5jZVR5cGU8dHlwZW9mIFByb2plY3ROb3RGb3VuZEVycm9yPlxyXG4+ID1cclxuICAobG9hZGVycykgPT5cclxuICBhc3luYyAoeyBwcm9qZWN0SWQgfSkgPT4ge1xyXG4gICAgY29uc3QgcHJvamVjdCA9IGF3YWl0IGxvYWRlcnMuZ2V0UHJvamVjdCh7IHByb2plY3RJZCB9KVxyXG4gICAgaWYgKCFwcm9qZWN0KSByZXR1cm4gZXJyKG5ldyBQcm9qZWN0Tm90Rm91bmRFcnJvcigpKVxyXG5cclxuICAgIHJldHVybiBvayhhd2FpdCBpc1B1YmxpY2x5UmVhZGFibGVQcm9qZWN0KGxvYWRlcnMpKHsgcHJvamVjdElkIH0pKVxyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBFbnN1cmUgdXNlciBoYXMgaW1wbGljaXQvZXhwbGljaXQgcHJvamVjdCBtZW1iZXJzaGlwIGFuZCByZWFkIGFjY2Vzc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGVuc3VyZUltcGxpY2l0UHJvamVjdE1lbWJlcldpdGhSZWFkQWNjZXNzRnJhZ21lbnQ6IEF1dGhQb2xpY3lFbnN1cmVGcmFnbWVudDxcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFByb2plY3RcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldEVudlxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0U2VydmVyUm9sZVxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0V29ya3NwYWNlUm9sZVxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0V29ya3NwYWNlXHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VTc29Qcm92aWRlclxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0V29ya3NwYWNlU3NvU2Vzc2lvblxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0UHJvamVjdFJvbGVcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldEFkbWluT3ZlcnJpZGVFbmFibGVkLFxyXG4gIE1heWJlVXNlckNvbnRleHQgJlxyXG4gICAgUHJvamVjdENvbnRleHQgJiB7XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBPcHRpb25hbGx5IHNwZWNpZnkgcm9sZSB0aGUgdXNlciBzaG91bGQgaGF2ZVxyXG4gICAgICAgKi9cclxuICAgICAgcm9sZT86IFN0cmVhbVJvbGVzXHJcbiAgICB9LFxyXG4gIEluc3RhbmNlVHlwZTxcclxuICAgIHwgdHlwZW9mIFByb2plY3ROb3RGb3VuZEVycm9yXHJcbiAgICB8IHR5cGVvZiBTZXJ2ZXJOb0FjY2Vzc0Vycm9yXHJcbiAgICB8IHR5cGVvZiBTZXJ2ZXJOb1Nlc3Npb25FcnJvclxyXG4gICAgfCB0eXBlb2YgU2VydmVyTm90RW5vdWdoUGVybWlzc2lvbnNFcnJvclxyXG4gICAgfCB0eXBlb2YgUHJvamVjdE5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFdvcmtzcGFjZU5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFdvcmtzcGFjZVNzb1Nlc3Npb25Ob0FjY2Vzc0Vycm9yXHJcbiAgICB8IHR5cGVvZiBQcm9qZWN0Tm90RW5vdWdoUGVybWlzc2lvbnNFcnJvclxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlTm90RW5vdWdoUGVybWlzc2lvbnNFcnJvclxyXG4gID5cclxuPiA9XHJcbiAgKGxvYWRlcnMpID0+XHJcbiAgYXN5bmMgKHsgdXNlcklkLCBwcm9qZWN0SWQsIHJvbGUgfSkgPT4ge1xyXG4gICAgLy8gRW5zdXJlIHVzZXIgaXMgYXV0aGVkXHJcbiAgICBjb25zdCBlbnN1cmVkU2VydmVyUm9sZSA9IGF3YWl0IGVuc3VyZU1pbmltdW1TZXJ2ZXJSb2xlRnJhZ21lbnQobG9hZGVycykoe1xyXG4gICAgICB1c2VySWQsXHJcbiAgICAgIHJvbGU6IFJvbGVzLlNlcnZlci5HdWVzdFxyXG4gICAgfSlcclxuICAgIGlmIChlbnN1cmVkU2VydmVyUm9sZS5pc0Vycikge1xyXG4gICAgICByZXR1cm4gZXJyKGVuc3VyZWRTZXJ2ZXJSb2xlLmVycm9yKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGlmIHVzZXIgaGFzIGFkbWluIG92ZXJyaWRlIGVuYWJsZWRcclxuICAgIGNvbnN0IGlzQWRtaW5PdmVycmlkZUVuYWJsZWQgPSBhd2FpdCBjaGVja0lmQWRtaW5PdmVycmlkZUVuYWJsZWRGcmFnbWVudChsb2FkZXJzKSh7XHJcbiAgICAgIHVzZXJJZFxyXG4gICAgfSlcclxuICAgIGlmIChpc0FkbWluT3ZlcnJpZGVFbmFibGVkLmlzRXJyKSB7XHJcbiAgICAgIHJldHVybiBlcnIoaXNBZG1pbk92ZXJyaWRlRW5hYmxlZC5lcnJvcilcclxuICAgIH1cclxuICAgIGlmIChpc0FkbWluT3ZlcnJpZGVFbmFibGVkLnZhbHVlKSByZXR1cm4gb2soKVxyXG5cclxuICAgIC8vIEFuZCBlbnN1cmUgKGltcGxpY2l0L2V4cGxpY2l0KSBwcm9qZWN0IHJvbGVcclxuICAgIGNvbnN0IGVuc3VyZWRQcm9qZWN0Um9sZSA9IGF3YWl0IGVuc3VyZU1pbmltdW1Qcm9qZWN0Um9sZUZyYWdtZW50KGxvYWRlcnMpKHtcclxuICAgICAgdXNlcklkOiB1c2VySWQhLFxyXG4gICAgICBwcm9qZWN0SWQsXHJcbiAgICAgIHJvbGVcclxuICAgIH0pXHJcbiAgICBpZiAoZW5zdXJlZFByb2plY3RSb2xlLmlzRXJyKSB7XHJcbiAgICAgIHJldHVybiBlcnIoZW5zdXJlZFByb2plY3RSb2xlLmVycm9yKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIE5vIGdvZCBtb2RlLCBlbnN1cmUgd29ya3NwYWNlIGFjY2Vzc1xyXG4gICAgY29uc3QgZW5zdXJlZFdvcmtzcGFjZUFjY2VzcyA9IGF3YWl0IGVuc3VyZVByb2plY3RXb3Jrc3BhY2VBY2Nlc3NGcmFnbWVudChsb2FkZXJzKSh7XHJcbiAgICAgIHVzZXJJZDogdXNlcklkISxcclxuICAgICAgcHJvamVjdElkXHJcbiAgICB9KVxyXG4gICAgaWYgKGVuc3VyZWRXb3Jrc3BhY2VBY2Nlc3MuaXNFcnIpIHtcclxuICAgICAgcmV0dXJuIGVycihlbnN1cmVkV29ya3NwYWNlQWNjZXNzLmVycm9yKVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvaygpXHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEVuc3VyZSB1c2VyIGhhcyBpbXBsaWNpdC9leHBsaWNpdCBwcm9qZWN0IG1lbWJlcnNoaXAgYW5kIHdyaXRlIGFjY2Vzc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGVuc3VyZUltcGxpY2l0UHJvamVjdE1lbWJlcldpdGhXcml0ZUFjY2Vzc0ZyYWdtZW50OiBBdXRoUG9saWN5RW5zdXJlRnJhZ21lbnQ8XHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRQcm9qZWN0XHJcbiAgfCB0eXBlb2YgTG9hZGVycy5nZXRFbnZcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFNlcnZlclJvbGVcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFdvcmtzcGFjZVJvbGVcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFdvcmtzcGFjZVxyXG4gIHwgdHlwZW9mIExvYWRlcnMuZ2V0V29ya3NwYWNlU3NvUHJvdmlkZXJcclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFdvcmtzcGFjZVNzb1Nlc3Npb25cclxuICB8IHR5cGVvZiBMb2FkZXJzLmdldFByb2plY3RSb2xlLFxyXG4gIE1heWJlVXNlckNvbnRleHQgJlxyXG4gICAgUHJvamVjdENvbnRleHQgJiB7XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBCeSBkZWZhdWx0IGFzc3VtZXMgQ29udHJpYnV0b3IrIGZvciBhbnkgd3JpdGVzLCBidXQgc29tZSBvcGVyYXRpb25zXHJcbiAgICAgICAqIG1heSBhbGxvdyBmb3IgbG93ZXIgcm9sZXMgKGUuZy4gY29tbWVudHMpXHJcbiAgICAgICAqL1xyXG4gICAgICByb2xlPzogU3RyZWFtUm9sZXNcclxuICAgIH0sXHJcbiAgSW5zdGFuY2VUeXBlPFxyXG4gICAgfCB0eXBlb2YgUHJvamVjdE5vdEZvdW5kRXJyb3JcclxuICAgIHwgdHlwZW9mIFNlcnZlck5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFNlcnZlck5vU2Vzc2lvbkVycm9yXHJcbiAgICB8IHR5cGVvZiBQcm9qZWN0Tm9BY2Nlc3NFcnJvclxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlTm9BY2Nlc3NFcnJvclxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlU3NvU2Vzc2lvbk5vQWNjZXNzRXJyb3JcclxuICAgIHwgdHlwZW9mIFNlcnZlck5vdEVub3VnaFBlcm1pc3Npb25zRXJyb3JcclxuICAgIHwgdHlwZW9mIFByb2plY3ROb3RFbm91Z2hQZXJtaXNzaW9uc0Vycm9yXHJcbiAgICB8IHR5cGVvZiBXb3Jrc3BhY2VOb3RFbm91Z2hQZXJtaXNzaW9uc0Vycm9yXHJcbiAgPlxyXG4+ID1cclxuICAobG9hZGVycykgPT5cclxuICBhc3luYyAoeyB1c2VySWQsIHByb2plY3RJZCwgcm9sZSB9KSA9PiB7XHJcbiAgICBjb25zdCByZXF1aXJlZFByb2plY3RSb2xlID0gcm9sZSB8fCBSb2xlcy5TdHJlYW0uQ29udHJpYnV0b3JcclxuICAgIGNvbnN0IHJlcXVpcmVkU2VydmVyUm9sZSA9XHJcbiAgICAgIHJlcXVpcmVkUHJvamVjdFJvbGUgPT09IFJvbGVzLlN0cmVhbS5Pd25lclxyXG4gICAgICAgID8gUm9sZXMuU2VydmVyLlVzZXJcclxuICAgICAgICA6IFJvbGVzLlNlcnZlci5HdWVzdFxyXG5cclxuICAgIC8vIEVuc3VyZSB1c2VyIGlzIGF1dGhlZFxyXG4gICAgY29uc3QgZW5zdXJlZFNlcnZlclJvbGUgPSBhd2FpdCBlbnN1cmVNaW5pbXVtU2VydmVyUm9sZUZyYWdtZW50KGxvYWRlcnMpKHtcclxuICAgICAgdXNlcklkLFxyXG4gICAgICByb2xlOiByZXF1aXJlZFNlcnZlclJvbGVcclxuICAgIH0pXHJcbiAgICBpZiAoZW5zdXJlZFNlcnZlclJvbGUuaXNFcnIpIHtcclxuICAgICAgcmV0dXJuIGVycihlbnN1cmVkU2VydmVyUm9sZS5lcnJvcilcclxuICAgIH1cclxuXHJcbiAgICAvLyBBbmQgZW5zdXJlIChpbXBsaWNpdC9leHBsaWNpdCkgcHJvamVjdCByb2xlXHJcbiAgICBjb25zdCBlbnN1cmVkUHJvamVjdFJvbGUgPSBhd2FpdCBlbnN1cmVNaW5pbXVtUHJvamVjdFJvbGVGcmFnbWVudChsb2FkZXJzKSh7XHJcbiAgICAgIHVzZXJJZDogdXNlcklkISxcclxuICAgICAgcHJvamVjdElkLFxyXG4gICAgICByb2xlOiByZXF1aXJlZFByb2plY3RSb2xlXHJcbiAgICB9KVxyXG4gICAgaWYgKGVuc3VyZWRQcm9qZWN0Um9sZS5pc0Vycikge1xyXG4gICAgICByZXR1cm4gZXJyKGVuc3VyZWRQcm9qZWN0Um9sZS5lcnJvcilcclxuICAgIH1cclxuXHJcbiAgICAvLyBFbnN1cmUgd29ya3NwYWNlIGFjY2Vzc1xyXG4gICAgY29uc3QgZW5zdXJlZFdvcmtzcGFjZUFjY2VzcyA9IGF3YWl0IGVuc3VyZVByb2plY3RXb3Jrc3BhY2VBY2Nlc3NGcmFnbWVudChsb2FkZXJzKSh7XHJcbiAgICAgIHVzZXJJZDogdXNlcklkISxcclxuICAgICAgcHJvamVjdElkXHJcbiAgICB9KVxyXG4gICAgaWYgKGVuc3VyZWRXb3Jrc3BhY2VBY2Nlc3MuaXNFcnIpIHtcclxuICAgICAgcmV0dXJuIGVycihlbnN1cmVkV29ya3NwYWNlQWNjZXNzLmVycm9yKVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvaygpXHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEVuc3VyZSBwcm9qZWN0IGlzIHdvcmtzcGFjZWQgYW5kIGhhcyBhY2Nlc3MgdG8gYSBzcGVjaWZpYyBwbGFuIGZlYXR1cmVcclxuICovXHJcbmV4cG9ydCBjb25zdCBlbnN1cmVDYW5Vc2VQcm9qZWN0V29ya3NwYWNlUGxhbkZlYXR1cmVGcmFnbWVudDogQXV0aFBvbGljeUVuc3VyZUZyYWdtZW50PFxyXG4gIHR5cGVvZiBMb2FkZXJzLmdldEVudiB8IHR5cGVvZiBMb2FkZXJzLmdldFByb2plY3QgfCB0eXBlb2YgTG9hZGVycy5nZXRXb3Jrc3BhY2VQbGFuLFxyXG4gIFByb2plY3RDb250ZXh0ICYge1xyXG4gICAgZmVhdHVyZTogV29ya3NwYWNlUGxhbkZlYXR1cmVzXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgdG8gYWxzbyBhbGxvdyBpZiBwcm9qZWN0IGlzIG5vdCB3b3Jrc3BhY2VkIGF0IGFsbFxyXG4gICAgICogRGVmYXVsdDogZmFsc2VcclxuICAgICAqL1xyXG4gICAgYWxsb3dVbndvcmtzcGFjZWQ/OiBib29sZWFuXHJcbiAgfSxcclxuICBJbnN0YW5jZVR5cGU8XHJcbiAgICB8IHR5cGVvZiBXb3Jrc3BhY2VzTm90RW5hYmxlZEVycm9yXHJcbiAgICB8IHR5cGVvZiBQcm9qZWN0Tm90Rm91bmRFcnJvclxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlTm9BY2Nlc3NFcnJvclxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlUmVhZE9ubHlFcnJvclxyXG4gICAgfCB0eXBlb2YgV29ya3NwYWNlUGxhbk5vRmVhdHVyZUFjY2Vzc0Vycm9yXHJcbiAgPlxyXG4+ID1cclxuICAobG9hZGVycykgPT5cclxuICBhc3luYyAoeyBwcm9qZWN0SWQsIGZlYXR1cmUsIGFsbG93VW53b3Jrc3BhY2VkID0gZmFsc2UgfSkgPT4ge1xyXG4gICAgY29uc3QgcHJvamVjdCA9IGF3YWl0IGxvYWRlcnMuZ2V0UHJvamVjdCh7IHByb2plY3RJZCB9KVxyXG4gICAgaWYgKCFwcm9qZWN0KSByZXR1cm4gZXJyKG5ldyBQcm9qZWN0Tm90Rm91bmRFcnJvcigpKVxyXG5cclxuICAgIGNvbnN0IHdvcmtzcGFjZUlkID0gcHJvamVjdC53b3Jrc3BhY2VJZFxyXG4gICAgaWYgKCF3b3Jrc3BhY2VJZCkge1xyXG4gICAgICBpZiAoYWxsb3dVbndvcmtzcGFjZWQpIHJldHVybiBvaygpXHJcblxyXG4gICAgICByZXR1cm4gZXJyKFxyXG4gICAgICAgIG5ldyBXb3Jrc3BhY2VOb0FjY2Vzc0Vycm9yKHtcclxuICAgICAgICAgIG1lc3NhZ2U6ICdUaGUgcHJvamVjdCBtdXN0IGJlIGluIGEgd29ya3NwYWNlJ1xyXG4gICAgICAgIH0pXHJcbiAgICAgIClcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjYW5Vc2VGZWF0dXJlID0gYXdhaXQgZW5zdXJlQ2FuVXNlV29ya3NwYWNlUGxhbkZlYXR1cmVGcmFnbWVudChsb2FkZXJzKSh7XHJcbiAgICAgIHdvcmtzcGFjZUlkLFxyXG4gICAgICBmZWF0dXJlXHJcbiAgICB9KVxyXG4gICAgaWYgKGNhblVzZUZlYXR1cmUuaXNFcnIpIHJldHVybiBlcnIoY2FuVXNlRmVhdHVyZS5lcnJvcilcclxuICAgIHJldHVybiBvaygpXHJcbiAgfVxyXG4iXX0=