253 lines
33 KiB
Plaintext
253 lines
33 KiB
Plaintext
import { PaidWorkspacePlans, UnpaidWorkspacePlans } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/workspaces/helpers/plans.js";
|
|
/**
|
|
* WORKSPACE FEATURES
|
|
*/
|
|
export const WorkspacePlanFeatures = {
|
|
// Core features pretty much available to everyone
|
|
AutomateBeta: 'automateBeta',
|
|
DomainDiscoverability: 'domainDiscoverability',
|
|
// Optional/plan specific
|
|
DomainSecurity: 'domainBasedSecurityPolicies',
|
|
SSO: 'oidcSso',
|
|
CustomDataRegion: 'workspaceDataRegionSpecificity',
|
|
HideSpeckleBranding: 'hideSpeckleBranding',
|
|
ExclusiveMembership: 'exclusiveMembership',
|
|
EmbedPrivateProjects: 'embedPrivateProjects',
|
|
SavedViews: 'savedViews'
|
|
};
|
|
// this const will be used as a bitwise flag for a per workspace feature access controller
|
|
// IMPORTANT: always use powers of 2 as the value of the object
|
|
// read more https://www.hendrik-erz.de/post/bitwise-flags-are-beautiful-and-heres-why
|
|
// this will make its way to the pricing plan and info setup at some point
|
|
// but for now its an internal only control
|
|
export const WorkspaceFeatureFlags = {
|
|
none: 0,
|
|
dashboards: 1,
|
|
accIntegration: 2,
|
|
// High numbers for internal features
|
|
presentations: 64
|
|
};
|
|
export const isWorkspaceFeatureFlagOn = ({ workspaceFeatureFlags, feature }) => (workspaceFeatureFlags & feature) === feature;
|
|
export const WorkspacePlanFeaturesMetadata = {
|
|
[WorkspacePlanFeatures.AutomateBeta]: {
|
|
displayName: 'Automate beta access',
|
|
description: 'Run custom automations on every new model version'
|
|
},
|
|
[WorkspacePlanFeatures.DomainDiscoverability]: {
|
|
displayName: 'Domain discoverability',
|
|
description: 'Allow people to discover your workspace if they use a verified company email'
|
|
},
|
|
[WorkspacePlanFeatures.DomainSecurity]: {
|
|
displayName: 'Domain protection',
|
|
description: 'Require workspace members to use a verified company email'
|
|
},
|
|
[WorkspacePlanFeatures.SSO]: {
|
|
displayName: 'Single Sign-On (SSO)',
|
|
description: 'Require workspace members to authenticate with your SSO provider'
|
|
},
|
|
[WorkspacePlanFeatures.CustomDataRegion]: {
|
|
displayName: 'Custom data residency',
|
|
description: 'Store your data in EU, UK, North America, or Asia Pacific'
|
|
},
|
|
[WorkspacePlanFeatures.HideSpeckleBranding]: {
|
|
displayName: 'Customised viewer',
|
|
description: 'Hide the Speckle branding in embedded viewer'
|
|
},
|
|
[WorkspacePlanFeatures.ExclusiveMembership]: {
|
|
displayName: 'Exclusive workspace membership',
|
|
description: 'Members of exclusive workspaces cannot join or create other workspaces'
|
|
},
|
|
[WorkspacePlanFeatures.EmbedPrivateProjects]: {
|
|
displayName: 'Embed private projects',
|
|
description: 'Embed projects with visibility set to private or workspace'
|
|
},
|
|
[WorkspacePlanFeatures.SavedViews]: {
|
|
displayName: 'Saved views',
|
|
description: 'Create and share saved views of your models'
|
|
}
|
|
};
|
|
const unlimited = {
|
|
projectCount: null,
|
|
modelCount: null,
|
|
versionsHistory: null,
|
|
commentHistory: null
|
|
};
|
|
const baseFeatures = [
|
|
WorkspacePlanFeatures.AutomateBeta,
|
|
WorkspacePlanFeatures.DomainDiscoverability,
|
|
WorkspacePlanFeatures.EmbedPrivateProjects
|
|
];
|
|
export const WorkspacePaidPlanConfigs = (params) => {
|
|
const finalBaseFeatures = [
|
|
...baseFeatures,
|
|
...(params.featureFlags?.FF_SAVED_VIEWS_ENABLED
|
|
? [WorkspacePlanFeatures.SavedViews]
|
|
: [])
|
|
];
|
|
return {
|
|
[PaidWorkspacePlans.Team]: {
|
|
plan: PaidWorkspacePlans.Team,
|
|
features: [...finalBaseFeatures],
|
|
limits: {
|
|
projectCount: 5,
|
|
modelCount: 25,
|
|
versionsHistory: { value: 30, unit: 'day' },
|
|
commentHistory: { value: 30, unit: 'day' }
|
|
}
|
|
},
|
|
[PaidWorkspacePlans.TeamUnlimited]: {
|
|
plan: PaidWorkspacePlans.TeamUnlimited,
|
|
features: [...finalBaseFeatures],
|
|
limits: {
|
|
projectCount: null,
|
|
modelCount: null,
|
|
versionsHistory: { value: 30, unit: 'day' },
|
|
commentHistory: { value: 30, unit: 'day' }
|
|
}
|
|
},
|
|
[PaidWorkspacePlans.Pro]: {
|
|
plan: PaidWorkspacePlans.Pro,
|
|
features: [
|
|
...finalBaseFeatures,
|
|
WorkspacePlanFeatures.DomainSecurity,
|
|
WorkspacePlanFeatures.SSO,
|
|
WorkspacePlanFeatures.CustomDataRegion,
|
|
WorkspacePlanFeatures.HideSpeckleBranding
|
|
],
|
|
limits: {
|
|
projectCount: 10,
|
|
modelCount: 50,
|
|
versionsHistory: null,
|
|
commentHistory: null
|
|
}
|
|
},
|
|
[PaidWorkspacePlans.ProUnlimited]: {
|
|
plan: PaidWorkspacePlans.ProUnlimited,
|
|
features: [
|
|
...finalBaseFeatures,
|
|
WorkspacePlanFeatures.DomainSecurity,
|
|
WorkspacePlanFeatures.SSO,
|
|
WorkspacePlanFeatures.CustomDataRegion,
|
|
WorkspacePlanFeatures.HideSpeckleBranding
|
|
],
|
|
limits: {
|
|
projectCount: null,
|
|
modelCount: null,
|
|
versionsHistory: null,
|
|
commentHistory: null
|
|
}
|
|
}
|
|
};
|
|
};
|
|
export const WorkspaceUnpaidPlanConfigs = (params) => {
|
|
const finalBaseFeatures = [
|
|
...baseFeatures,
|
|
...(params.featureFlags?.FF_SAVED_VIEWS_ENABLED
|
|
? [WorkspacePlanFeatures.SavedViews]
|
|
: [])
|
|
];
|
|
return {
|
|
[UnpaidWorkspacePlans.Enterprise]: {
|
|
plan: UnpaidWorkspacePlans.Enterprise,
|
|
features: [
|
|
...finalBaseFeatures,
|
|
WorkspacePlanFeatures.DomainSecurity,
|
|
WorkspacePlanFeatures.SSO,
|
|
WorkspacePlanFeatures.CustomDataRegion,
|
|
WorkspacePlanFeatures.HideSpeckleBranding,
|
|
WorkspacePlanFeatures.ExclusiveMembership
|
|
],
|
|
limits: unlimited
|
|
},
|
|
[UnpaidWorkspacePlans.Unlimited]: {
|
|
plan: UnpaidWorkspacePlans.Unlimited,
|
|
features: [
|
|
...finalBaseFeatures,
|
|
WorkspacePlanFeatures.DomainSecurity,
|
|
WorkspacePlanFeatures.SSO,
|
|
WorkspacePlanFeatures.CustomDataRegion,
|
|
WorkspacePlanFeatures.HideSpeckleBranding,
|
|
WorkspacePlanFeatures.ExclusiveMembership
|
|
],
|
|
limits: unlimited
|
|
},
|
|
[UnpaidWorkspacePlans.Academia]: {
|
|
plan: UnpaidWorkspacePlans.Academia,
|
|
features: [
|
|
...finalBaseFeatures,
|
|
WorkspacePlanFeatures.DomainSecurity,
|
|
WorkspacePlanFeatures.SSO,
|
|
WorkspacePlanFeatures.CustomDataRegion,
|
|
WorkspacePlanFeatures.HideSpeckleBranding
|
|
],
|
|
limits: unlimited
|
|
},
|
|
[UnpaidWorkspacePlans.TeamUnlimitedInvoiced]: {
|
|
...WorkspacePaidPlanConfigs(params).teamUnlimited,
|
|
plan: UnpaidWorkspacePlans.TeamUnlimitedInvoiced
|
|
},
|
|
[UnpaidWorkspacePlans.ProUnlimitedInvoiced]: {
|
|
...WorkspacePaidPlanConfigs(params).proUnlimited,
|
|
plan: UnpaidWorkspacePlans.ProUnlimitedInvoiced
|
|
},
|
|
[UnpaidWorkspacePlans.Free]: {
|
|
plan: UnpaidWorkspacePlans.Free,
|
|
features: finalBaseFeatures,
|
|
limits: {
|
|
projectCount: 1,
|
|
modelCount: 5,
|
|
versionsHistory: { value: 7, unit: 'day' },
|
|
commentHistory: { value: 7, unit: 'day' }
|
|
}
|
|
}
|
|
};
|
|
};
|
|
export const WorkspacePlanConfigs = (params) => ({
|
|
...WorkspacePaidPlanConfigs(params),
|
|
...WorkspaceUnpaidPlanConfigs(params)
|
|
});
|
|
/**
|
|
* Checks if a workspace exceeds its plan limits for projects and models
|
|
*/
|
|
export const workspaceExceedsPlanLimit = (params) => {
|
|
const { plan, projectCount, modelCount, featureFlags } = params;
|
|
if (!plan)
|
|
return false;
|
|
const planConfig = WorkspacePlanConfigs({ featureFlags })[plan];
|
|
if (!planConfig)
|
|
return false;
|
|
const limits = planConfig.limits;
|
|
if (!limits.projectCount || !limits.modelCount)
|
|
return false;
|
|
if (!projectCount || !modelCount)
|
|
return false;
|
|
return projectCount > limits.projectCount || modelCount > limits.modelCount;
|
|
};
|
|
/**
|
|
* Checks if a workspace reached its plan limits for projects and models
|
|
*/
|
|
export const workspaceReachedPlanLimit = (params) => {
|
|
const { plan, projectCount, modelCount, featureFlags } = params;
|
|
if (!plan)
|
|
return false;
|
|
const planConfig = WorkspacePlanConfigs({ featureFlags })[plan];
|
|
if (!planConfig)
|
|
return false;
|
|
const limits = planConfig.limits;
|
|
if (!limits.projectCount || !limits.modelCount)
|
|
return false;
|
|
return projectCount === limits.projectCount || modelCount === limits.modelCount;
|
|
};
|
|
export const workspacePlanHasAccessToFeature = ({ plan, feature, featureFlags }) => {
|
|
const planConfig = WorkspacePlanConfigs({ featureFlags })[plan];
|
|
const hasAccess = planConfig.features.includes(feature);
|
|
return hasAccess;
|
|
};
|
|
export const isPlanFeature = (feature) => {
|
|
if (typeof feature === 'number') {
|
|
return false;
|
|
}
|
|
return Object.values(WorkspacePlanFeatures).includes(feature);
|
|
};
|
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd29ya3NwYWNlcy9oZWxwZXJzL2ZlYXR1cmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFDTCxrQkFBa0IsRUFDbEIsb0JBQW9CLEVBR3JCLE1BQU0sWUFBWSxDQUFBO0FBSW5COztHQUVHO0FBRUgsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQVU7SUFDMUMsa0RBQWtEO0lBQ2xELFlBQVksRUFBRSxjQUFjO0lBQzVCLHFCQUFxQixFQUFFLHVCQUF1QjtJQUM5Qyx5QkFBeUI7SUFDekIsY0FBYyxFQUFFLDZCQUE2QjtJQUM3QyxHQUFHLEVBQUUsU0FBUztJQUNkLGdCQUFnQixFQUFFLGdDQUFnQztJQUNsRCxtQkFBbUIsRUFBRSxxQkFBcUI7SUFDMUMsbUJBQW1CLEVBQUUscUJBQXFCO0lBQzFDLG9CQUFvQixFQUFFLHNCQUFzQjtJQUM1QyxVQUFVLEVBQUUsWUFBWTtDQUN6QixDQUFBO0FBS0QsMEZBQTBGO0FBQzFGLCtEQUErRDtBQUMvRCxzRkFBc0Y7QUFDdEYsMEVBQTBFO0FBQzFFLDJDQUEyQztBQUMzQyxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBVTtJQUMxQyxJQUFJLEVBQUUsQ0FBQztJQUNQLFVBQVUsRUFBRSxDQUFDO0lBQ2IsY0FBYyxFQUFFLENBQUM7SUFDakIscUNBQXFDO0lBQ3JDLGFBQWEsRUFBRSxFQUFFO0NBQ2xCLENBQUE7QUFLRCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLEVBQ3ZDLHFCQUFxQixFQUNyQixPQUFPLEVBSVIsRUFBVyxFQUFFLENBQUMsQ0FBQyxxQkFBcUIsR0FBRyxPQUFPLENBQUMsS0FBSyxPQUFPLENBQUE7QUFJNUQsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQVc7SUFDbkQsQ0FBQyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsRUFBRTtRQUNwQyxXQUFXLEVBQUUsc0JBQXNC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QUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3ZELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxDQUMzQixPQUEwQixFQUNRLEVBQUU7SUFDcEMsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNoQyxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7QUFDL0QsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV29ya3NwYWNlUm9sZXMgfSBmcm9tICcuLi8uLi9jb3JlL2NvbnN0YW50cy5qcydcclxuaW1wb3J0IHsgV29ya3NwYWNlTGltaXRzIH0gZnJvbSAnLi9saW1pdHMuanMnXHJcbmltcG9ydCB7XHJcbiAgUGFpZFdvcmtzcGFjZVBsYW5zLFxyXG4gIFVucGFpZFdvcmtzcGFjZVBsYW5zLFxyXG4gIFdvcmtzcGFjZVBsYW5CaWxsaW5nSW50ZXJ2YWxzLFxyXG4gIFdvcmtzcGFjZVBsYW5zXHJcbn0gZnJvbSAnLi9wbGFucy5qcydcclxuaW1wb3J0IHR5cGUgeyBNYXliZU51bGxPclVuZGVmaW5lZCB9IGZyb20gJy4uLy4uL2NvcmUvaGVscGVycy91dGlsaXR5VHlwZXMuanMnXHJcbmltcG9ydCB7IEZlYXR1cmVGbGFncyB9IGZyb20gJy4uLy4uL2Vudmlyb25tZW50L2ZlYXR1cmVGbGFncy5qcydcclxuXHJcbi8qKlxyXG4gKiBXT1JLU1BBQ0UgRkVBVFVSRVNcclxuICovXHJcblxyXG5leHBvcnQgY29uc3QgV29ya3NwYWNlUGxhbkZlYXR1cmVzID0gPGNvbnN0PntcclxuICAvLyBDb3JlIGZlYXR1cmVzIHByZXR0eSBtdWNoIGF2YWlsYWJsZSB0byBldmVyeW9uZVxyXG4gIEF1dG9tYXRlQmV0YTogJ2F1dG9tYXRlQmV0YScsXHJcbiAgRG9tYWluRGlzY292ZXJhYmlsaXR5OiAnZG9tYWluRGlzY292ZXJhYmlsaXR5JyxcclxuICAvLyBPcHRpb25hbC9wbGFuIHNwZWNpZmljXHJcbiAgRG9tYWluU2VjdXJpdHk6ICdkb21haW5CYXNlZFNlY3VyaXR5UG9saWNpZXMnLFxyXG4gIFNTTzogJ29pZGNTc28nLFxyXG4gIEN1c3RvbURhdGFSZWdpb246ICd3b3Jrc3BhY2VEYXRhUmVnaW9uU3BlY2lmaWNpdHknLFxyXG4gIEhpZGVTcGVja2xlQnJhbmRpbmc6ICdoaWRlU3BlY2tsZUJyYW5kaW5nJyxcclxuICBFeGNsdXNpdmVNZW1iZXJzaGlwOiAnZXhjbHVzaXZlTWVtYmVyc2hpcCcsXHJcbiAgRW1iZWRQcml2YXRlUHJvamVjdHM6ICdlbWJlZFByaXZhdGVQcm9qZWN0cycsXHJcbiAgU2F2ZWRWaWV3czogJ3NhdmVkVmlld3MnXHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFdvcmtzcGFjZVBsYW5GZWF0dXJlcyA9XHJcbiAgKHR5cGVvZiBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMpW2tleW9mIHR5cGVvZiBXb3Jrc3BhY2VQbGFuRmVhdHVyZXNdXHJcblxyXG4vLyB0aGlzIGNvbnN0IHdpbGwgYmUgdXNlZCBhcyBhIGJpdHdpc2UgZmxhZyBmb3IgYSBwZXIgd29ya3NwYWNlIGZlYXR1cmUgYWNjZXNzIGNvbnRyb2xsZXJcclxuLy8gSU1QT1JUQU5UOiBhbHdheXMgdXNlIHBvd2VycyBvZiAyIGFzIHRoZSB2YWx1ZSBvZiB0aGUgb2JqZWN0XHJcbi8vIHJlYWQgbW9yZSBodHRwczovL3d3dy5oZW5kcmlrLWVyei5kZS9wb3N0L2JpdHdpc2UtZmxhZ3MtYXJlLWJlYXV0aWZ1bC1hbmQtaGVyZXMtd2h5XHJcbi8vIHRoaXMgd2lsbCBtYWtlIGl0cyB3YXkgdG8gdGhlIHByaWNpbmcgcGxhbiBhbmQgaW5mbyBzZXR1cCBhdCBzb21lIHBvaW50XHJcbi8vIGJ1dCBmb3Igbm93IGl0cyBhbiBpbnRlcm5hbCBvbmx5IGNvbnRyb2xcclxuZXhwb3J0IGNvbnN0IFdvcmtzcGFjZUZlYXR1cmVGbGFncyA9IDxjb25zdD57XHJcbiAgbm9uZTogMCxcclxuICBkYXNoYm9hcmRzOiAxLFxyXG4gIGFjY0ludGVncmF0aW9uOiAyLFxyXG4gIC8vIEhpZ2ggbnVtYmVycyBmb3IgaW50ZXJuYWwgZmVhdHVyZXNcclxuICBwcmVzZW50YXRpb25zOiA2NFxyXG59XHJcblxyXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VGZWF0dXJlRmxhZ3MgPVxyXG4gICh0eXBlb2YgV29ya3NwYWNlRmVhdHVyZUZsYWdzKVtrZXlvZiB0eXBlb2YgV29ya3NwYWNlRmVhdHVyZUZsYWdzXVxyXG5cclxuZXhwb3J0IGNvbnN0IGlzV29ya3NwYWNlRmVhdHVyZUZsYWdPbiA9ICh7XHJcbiAgd29ya3NwYWNlRmVhdHVyZUZsYWdzLFxyXG4gIGZlYXR1cmVcclxufToge1xyXG4gIHdvcmtzcGFjZUZlYXR1cmVGbGFnczogbnVtYmVyXHJcbiAgZmVhdHVyZTogV29ya3NwYWNlRmVhdHVyZUZsYWdzXHJcbn0pOiBib29sZWFuID0+ICh3b3Jrc3BhY2VGZWF0dXJlRmxhZ3MgJiBmZWF0dXJlKSA9PT0gZmVhdHVyZVxyXG5cclxuZXhwb3J0IHR5cGUgV29ya3NwYWNlRmVhdHVyZXMgPSBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMgfCBXb3Jrc3BhY2VGZWF0dXJlRmxhZ3NcclxuXHJcbmV4cG9ydCBjb25zdCBXb3Jrc3BhY2VQbGFuRmVhdHVyZXNNZXRhZGF0YSA9ICg8Y29uc3Q+e1xyXG4gIFtXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuQXV0b21hdGVCZXRhXToge1xyXG4gICAgZGlzcGxheU5hbWU6ICdBdXRvbWF0ZSBiZXRhIGFjY2VzcycsXHJcbiAgICBkZXNjcmlwdGlvbjogJ1J1biBjdXN0b20gYXV0b21hdGlvbnMgb24gZXZlcnkgbmV3IG1vZGVsIHZlcnNpb24nXHJcbiAgfSxcclxuICBbV29ya3NwYWNlUGxhbkZlYXR1cmVzLkRvbWFpbkRpc2NvdmVyYWJpbGl0eV06IHtcclxuICAgIGRpc3BsYXlOYW1lOiAnRG9tYWluIGRpc2NvdmVyYWJpbGl0eScsXHJcbiAgICBkZXNjcmlwdGlvbjpcclxuICAgICAgJ0FsbG93IHBlb3BsZSB0byBkaXNjb3ZlciB5b3VyIHdvcmtzcGFjZSBpZiB0aGV5IHVzZSBhIHZlcmlmaWVkIGNvbXBhbnkgZW1haWwnXHJcbiAgfSxcclxuICBbV29ya3NwYWNlUGxhbkZlYXR1cmVzLkRvbWFpblNlY3VyaXR5XToge1xyXG4gICAgZGlzcGxheU5hbWU6ICdEb21haW4gcHJvdGVjdGlvbicsXHJcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVpcmUgd29ya3NwYWNlIG1lbWJlcnMgdG8gdXNlIGEgdmVyaWZpZWQgY29tcGFueSBlbWFpbCdcclxuICB9LFxyXG4gIFtXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuU1NPXToge1xyXG4gICAgZGlzcGxheU5hbWU6ICdTaW5nbGUgU2lnbi1PbiAoU1NPKScsXHJcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVpcmUgd29ya3NwYWNlIG1lbWJlcnMgdG8gYXV0aGVudGljYXRlIHdpdGggeW91ciBTU08gcHJvdmlkZXInXHJcbiAgfSxcclxuICBbV29ya3NwYWNlUGxhbkZlYXR1cmVzLkN1c3RvbURhdGFSZWdpb25dOiB7XHJcbiAgICBkaXNwbGF5TmFtZTogJ0N1c3RvbSBkYXRhIHJlc2lkZW5jeScsXHJcbiAgICBkZXNjcmlwdGlvbjogJ1N0b3JlIHlvdXIgZGF0YSBpbiBFVSwgVUssIE5vcnRoIEFtZXJpY2EsIG9yIEFzaWEgUGFjaWZpYydcclxuICB9LFxyXG4gIFtXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuSGlkZVNwZWNrbGVCcmFuZGluZ106IHtcclxuICAgIGRpc3BsYXlOYW1lOiAnQ3VzdG9taXNlZCB2aWV3ZXInLFxyXG4gICAgZGVzY3JpcHRpb246ICdIaWRlIHRoZSBTcGVja2xlIGJyYW5kaW5nIGluIGVtYmVkZGVkIHZpZXdlcidcclxuICB9LFxyXG4gIFtXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuRXhjbHVzaXZlTWVtYmVyc2hpcF06IHtcclxuICAgIGRpc3BsYXlOYW1lOiAnRXhjbHVzaXZlIHdvcmtzcGFjZSBtZW1iZXJzaGlwJyxcclxuICAgIGRlc2NyaXB0aW9uOlxyXG4gICAgICAnTWVtYmVycyBvZiBleGNsdXNpdmUgd29ya3NwYWNlcyBjYW5ub3Qgam9pbiBvciBjcmVhdGUgb3RoZXIgd29ya3NwYWNlcydcclxuICB9LFxyXG4gIFtXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuRW1iZWRQcml2YXRlUHJvamVjdHNdOiB7XHJcbiAgICBkaXNwbGF5TmFtZTogJ0VtYmVkIHByaXZhdGUgcHJvamVjdHMnLFxyXG4gICAgZGVzY3JpcHRpb246ICdFbWJlZCBwcm9qZWN0cyB3aXRoIHZpc2liaWxpdHkgc2V0IHRvIHByaXZhdGUgb3Igd29ya3NwYWNlJ1xyXG4gIH0sXHJcbiAgW1dvcmtzcGFjZVBsYW5GZWF0dXJlcy5TYXZlZFZpZXdzXToge1xyXG4gICAgZGlzcGxheU5hbWU6ICdTYXZlZCB2aWV3cycsXHJcbiAgICBkZXNjcmlwdGlvbjogJ0NyZWF0ZSBhbmQgc2hhcmUgc2F2ZWQgdmlld3Mgb2YgeW91ciBtb2RlbHMnXHJcbiAgfVxyXG59KSBzYXRpc2ZpZXMgUmVjb3JkPFxyXG4gIFdvcmtzcGFjZVBsYW5GZWF0dXJlcyxcclxuICB7XHJcbiAgICBkaXNwbGF5TmFtZTogc3RyaW5nXHJcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nXHJcbiAgfVxyXG4+XHJcblxyXG4vKipcclxuICogUExBTiBDT05GSUcgLSBQUklDRVMgJiBGRUFUVVJFU1xyXG4gKi9cclxuXHJcbmV4cG9ydCB0eXBlIFdvcmtzcGFjZVBsYW5QcmljZVN0cnVjdHVyZSA9IHtcclxuICBbaW50ZXJ2YWwgaW4gV29ya3NwYWNlUGxhbkJpbGxpbmdJbnRlcnZhbHNdOiB7XHJcbiAgICBbcm9sZSBpbiBXb3Jrc3BhY2VSb2xlc106IG51bWJlclxyXG4gIH1cclxufVxyXG5cclxuY29uc3QgdW5saW1pdGVkOiBXb3Jrc3BhY2VMaW1pdHMgPSB7XHJcbiAgcHJvamVjdENvdW50OiBudWxsLFxyXG4gIG1vZGVsQ291bnQ6IG51bGwsXHJcbiAgdmVyc2lvbnNIaXN0b3J5OiBudWxsLFxyXG4gIGNvbW1lbnRIaXN0b3J5OiBudWxsXHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFdvcmtzcGFjZVBsYW5Db25maWc8UGxhbiBleHRlbmRzIFdvcmtzcGFjZVBsYW5zID0gV29ya3NwYWNlUGxhbnM+ID0ge1xyXG4gIHBsYW46IFBsYW5cclxuICBmZWF0dXJlczogcmVhZG9ubHkgV29ya3NwYWNlUGxhbkZlYXR1cmVzW11cclxuICBsaW1pdHM6IFdvcmtzcGFjZUxpbWl0c1xyXG59XHJcblxyXG5jb25zdCBiYXNlRmVhdHVyZXMgPSBbXHJcbiAgV29ya3NwYWNlUGxhbkZlYXR1cmVzLkF1dG9tYXRlQmV0YSxcclxuICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuRG9tYWluRGlzY292ZXJhYmlsaXR5LFxyXG4gIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5FbWJlZFByaXZhdGVQcm9qZWN0c1xyXG5dIGFzIGNvbnN0XHJcblxyXG5leHBvcnQgY29uc3QgV29ya3NwYWNlUGFpZFBsYW5Db25maWdzOiAocGFyYW1zOiB7XHJcbiAgZmVhdHVyZUZsYWdzOiBQYXJ0aWFsPEZlYXR1cmVGbGFncz4gfCB1bmRlZmluZWRcclxufSkgPT4ge1xyXG4gIFtwbGFuIGluIFBhaWRXb3Jrc3BhY2VQbGFuc106IFdvcmtzcGFjZVBsYW5Db25maWc8cGxhbj5cclxufSA9IChwYXJhbXMpID0+IHtcclxuICBjb25zdCBmaW5hbEJhc2VGZWF0dXJlcyA9IFtcclxuICAgIC4uLmJhc2VGZWF0dXJlcyxcclxuICAgIC4uLihwYXJhbXMuZmVhdHVyZUZsYWdzPy5GRl9TQVZFRF9WSUVXU19FTkFCTEVEXHJcbiAgICAgID8gW1dvcmtzcGFjZVBsYW5GZWF0dXJlcy5TYXZlZFZpZXdzXVxyXG4gICAgICA6IFtdKVxyXG4gIF1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIFtQYWlkV29ya3NwYWNlUGxhbnMuVGVhbV06IHtcclxuICAgICAgcGxhbjogUGFpZFdvcmtzcGFjZVBsYW5zLlRlYW0sXHJcbiAgICAgIGZlYXR1cmVzOiBbLi4uZmluYWxCYXNlRmVhdHVyZXNdLFxyXG4gICAgICBsaW1pdHM6IHtcclxuICAgICAgICBwcm9qZWN0Q291bnQ6IDUsXHJcbiAgICAgICAgbW9kZWxDb3VudDogMjUsXHJcbiAgICAgICAgdmVyc2lvbnNIaXN0b3J5OiB7IHZhbHVlOiAzMCwgdW5pdDogJ2RheScgfSxcclxuICAgICAgICBjb21tZW50SGlzdG9yeTogeyB2YWx1ZTogMzAsIHVuaXQ6ICdkYXknIH1cclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIFtQYWlkV29ya3NwYWNlUGxhbnMuVGVhbVVubGltaXRlZF06IHtcclxuICAgICAgcGxhbjogUGFpZFdvcmtzcGFjZVBsYW5zLlRlYW1VbmxpbWl0ZWQsXHJcbiAgICAgIGZlYXR1cmVzOiBbLi4uZmluYWxCYXNlRmVhdHVyZXNdLFxyXG4gICAgICBsaW1pdHM6IHtcclxuICAgICAgICBwcm9qZWN0Q291bnQ6IG51bGwsXHJcbiAgICAgICAgbW9kZWxDb3VudDogbnVsbCxcclxuICAgICAgICB2ZXJzaW9uc0hpc3Rvcnk6IHsgdmFsdWU6IDMwLCB1bml0OiAnZGF5JyB9LFxyXG4gICAgICAgIGNvbW1lbnRIaXN0b3J5OiB7IHZhbHVlOiAzMCwgdW5pdDogJ2RheScgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgW1BhaWRXb3Jrc3BhY2VQbGFucy5Qcm9dOiB7XHJcbiAgICAgIHBsYW46IFBhaWRXb3Jrc3BhY2VQbGFucy5Qcm8sXHJcbiAgICAgIGZlYXR1cmVzOiBbXHJcbiAgICAgICAgLi4uZmluYWxCYXNlRmVhdHVyZXMsXHJcbiAgICAgICAgV29ya3NwYWNlUGxhbkZlYXR1cmVzLkRvbWFpblNlY3VyaXR5LFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5TU08sXHJcbiAgICAgICAgV29ya3NwYWNlUGxhbkZlYXR1cmVzLkN1c3RvbURhdGFSZWdpb24sXHJcbiAgICAgICAgV29ya3NwYWNlUGxhbkZlYXR1cmVzLkhpZGVTcGVja2xlQnJhbmRpbmdcclxuICAgICAgXSxcclxuICAgICAgbGltaXRzOiB7XHJcbiAgICAgICAgcHJvamVjdENvdW50OiAxMCxcclxuICAgICAgICBtb2RlbENvdW50OiA1MCxcclxuICAgICAgICB2ZXJzaW9uc0hpc3Rvcnk6IG51bGwsXHJcbiAgICAgICAgY29tbWVudEhpc3Rvcnk6IG51bGxcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIFtQYWlkV29ya3NwYWNlUGxhbnMuUHJvVW5saW1pdGVkXToge1xyXG4gICAgICBwbGFuOiBQYWlkV29ya3NwYWNlUGxhbnMuUHJvVW5saW1pdGVkLFxyXG4gICAgICBmZWF0dXJlczogW1xyXG4gICAgICAgIC4uLmZpbmFsQmFzZUZlYXR1cmVzLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5Eb21haW5TZWN1cml0eSxcclxuICAgICAgICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuU1NPLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5DdXN0b21EYXRhUmVnaW9uLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5IaWRlU3BlY2tsZUJyYW5kaW5nXHJcbiAgICAgIF0sXHJcbiAgICAgIGxpbWl0czoge1xyXG4gICAgICAgIHByb2plY3RDb3VudDogbnVsbCxcclxuICAgICAgICBtb2RlbENvdW50OiBudWxsLFxyXG4gICAgICAgIHZlcnNpb25zSGlzdG9yeTogbnVsbCxcclxuICAgICAgICBjb21tZW50SGlzdG9yeTogbnVsbFxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgV29ya3NwYWNlVW5wYWlkUGxhbkNvbmZpZ3M6IChwYXJhbXM6IHtcclxuICBmZWF0dXJlRmxhZ3M6IFBhcnRpYWw8RmVhdHVyZUZsYWdzPiB8IHVuZGVmaW5lZFxyXG59KSA9PiB7XHJcbiAgW3BsYW4gaW4gVW5wYWlkV29ya3NwYWNlUGxhbnNdOiBXb3Jrc3BhY2VQbGFuQ29uZmlnPHBsYW4+XHJcbn0gPSAocGFyYW1zKSA9PiB7XHJcbiAgY29uc3QgZmluYWxCYXNlRmVhdHVyZXMgPSBbXHJcbiAgICAuLi5iYXNlRmVhdHVyZXMsXHJcbiAgICAuLi4ocGFyYW1zLmZlYXR1cmVGbGFncz8uRkZfU0FWRURfVklFV1NfRU5BQkxFRFxyXG4gICAgICA/IFtXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuU2F2ZWRWaWV3c11cclxuICAgICAgOiBbXSlcclxuICBdXHJcbiAgcmV0dXJuIHtcclxuICAgIFtVbnBhaWRXb3Jrc3BhY2VQbGFucy5FbnRlcnByaXNlXToge1xyXG4gICAgICBwbGFuOiBVbnBhaWRXb3Jrc3BhY2VQbGFucy5FbnRlcnByaXNlLFxyXG4gICAgICBmZWF0dXJlczogW1xyXG4gICAgICAgIC4uLmZpbmFsQmFzZUZlYXR1cmVzLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5Eb21haW5TZWN1cml0eSxcclxuICAgICAgICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuU1NPLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5DdXN0b21EYXRhUmVnaW9uLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5IaWRlU3BlY2tsZUJyYW5kaW5nLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5FeGNsdXNpdmVNZW1iZXJzaGlwXHJcbiAgICAgIF0sXHJcbiAgICAgIGxpbWl0czogdW5saW1pdGVkXHJcbiAgICB9LFxyXG4gICAgW1VucGFpZFdvcmtzcGFjZVBsYW5zLlVubGltaXRlZF06IHtcclxuICAgICAgcGxhbjogVW5wYWlkV29ya3NwYWNlUGxhbnMuVW5saW1pdGVkLFxyXG4gICAgICBmZWF0dXJlczogW1xyXG4gICAgICAgIC4uLmZpbmFsQmFzZUZlYXR1cmVzLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5Eb21haW5TZWN1cml0eSxcclxuICAgICAgICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuU1NPLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5DdXN0b21EYXRhUmVnaW9uLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5IaWRlU3BlY2tsZUJyYW5kaW5nLFxyXG4gICAgICAgIFdvcmtzcGFjZVBsYW5GZWF0dXJlcy5FeGNsdXNpdmVNZW1iZXJzaGlwXHJcbiAgICAgIF0sXHJcbiAgICAgIGxpbWl0czogdW5saW1pdGVkXHJcbiAgICB9LFxyXG4gICAgW1VucGFpZFdvcmtzcGFjZVBsYW5zLkFjYWRlbWlhXToge1xyXG4gICAgICBwbGFuOiBVbnBhaWRXb3Jrc3BhY2VQbGFucy5BY2FkZW1pYSxcclxuICAgICAgZmVhdHVyZXM6IFtcclxuICAgICAgICAuLi5maW5hbEJhc2VGZWF0dXJlcyxcclxuICAgICAgICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuRG9tYWluU2VjdXJpdHksXHJcbiAgICAgICAgV29ya3NwYWNlUGxhbkZlYXR1cmVzLlNTTyxcclxuICAgICAgICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuQ3VzdG9tRGF0YVJlZ2lvbixcclxuICAgICAgICBXb3Jrc3BhY2VQbGFuRmVhdHVyZXMuSGlkZVNwZWNrbGVCcmFuZGluZ1xyXG4gICAgICBdLFxyXG4gICAgICBsaW1pdHM6IHVubGltaXRlZFxyXG4gICAgfSxcclxuICAgIFtVbnBhaWRXb3Jrc3BhY2VQbGFucy5UZWFtVW5saW1pdGVkSW52b2ljZWRdOiB7XHJcbiAgICAgIC4uLldvcmtzcGFjZVBhaWRQbGFuQ29uZmlncyhwYXJhbXMpLnRlYW1VbmxpbWl0ZWQsXHJcbiAgICAgIHBsYW46IFVucGFpZFdvcmtzcGFjZVBsYW5zLlRlYW1VbmxpbWl0ZWRJbnZvaWNlZFxyXG4gICAgfSxcclxuICAgIFtVbnBhaWRXb3Jrc3BhY2VQbGFucy5Qcm9VbmxpbWl0ZWRJbnZvaWNlZF06IHtcclxuICAgICAgLi4uV29ya3NwYWNlUGFpZFBsYW5Db25maWdzKHBhcmFtcykucHJvVW5saW1pdGVkLFxyXG4gICAgICBwbGFuOiBVbnBhaWRXb3Jrc3BhY2VQbGFucy5Qcm9VbmxpbWl0ZWRJbnZvaWNlZFxyXG4gICAgfSxcclxuICAgIFtVbnBhaWRXb3Jrc3BhY2VQbGFucy5GcmVlXToge1xyXG4gICAgICBwbGFuOiBVbnBhaWRXb3Jrc3BhY2VQbGFucy5GcmVlLFxyXG4gICAgICBmZWF0dXJlczogZmluYWxCYXNlRmVhdHVyZXMsXHJcbiAgICAgIGxpbWl0czoge1xyXG4gICAgICAgIHByb2plY3RDb3VudDogMSxcclxuICAgICAgICBtb2RlbENvdW50OiA1LFxyXG4gICAgICAgIHZlcnNpb25zSGlzdG9yeTogeyB2YWx1ZTogNywgdW5pdDogJ2RheScgfSxcclxuICAgICAgICBjb21tZW50SGlzdG9yeTogeyB2YWx1ZTogNywgdW5pdDogJ2RheScgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgV29ya3NwYWNlUGxhbkNvbmZpZ3MgPSAocGFyYW1zOiB7XHJcbiAgZmVhdHVyZUZsYWdzOiBQYXJ0aWFsPEZlYXR1cmVGbGFncz4gfCB1bmRlZmluZWRcclxufSkgPT4gKHtcclxuICAuLi5Xb3Jrc3BhY2VQYWlkUGxhbkNvbmZpZ3MocGFyYW1zKSxcclxuICAuLi5Xb3Jrc3BhY2VVbnBhaWRQbGFuQ29uZmlncyhwYXJhbXMpXHJcbn0pXHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIGEgd29ya3NwYWNlIGV4Y2VlZHMgaXRzIHBsYW4gbGltaXRzIGZvciBwcm9qZWN0cyBhbmQgbW9kZWxzXHJcbiAqL1xyXG5leHBvcnQgY29uc3Qgd29ya3NwYWNlRXhjZWVkc1BsYW5MaW1pdCA9IChwYXJhbXM6IHtcclxuICBwbGFuOiBNYXliZU51bGxPclVuZGVmaW5lZDxXb3Jrc3BhY2VQbGFucz5cclxuICBwcm9qZWN0Q291bnQ6IE1heWJlTnVsbE9yVW5kZWZpbmVkPG51bWJlcj5cclxuICBtb2RlbENvdW50OiBNYXliZU51bGxPclVuZGVmaW5lZDxudW1iZXI+XHJcbiAgZmVhdHVyZUZsYWdzOiBQYXJ0aWFsPEZlYXR1cmVGbGFncz4gfCB1bmRlZmluZWRcclxufSk6IGJvb2xlYW4gPT4ge1xyXG4gIGNvbnN0IHsgcGxhbiwgcHJvamVjdENvdW50LCBtb2RlbENvdW50LCBmZWF0dXJlRmxhZ3MgfSA9IHBhcmFtc1xyXG4gIGlmICghcGxhbikgcmV0dXJuIGZhbHNlXHJcblxyXG4gIGNvbnN0IHBsYW5Db25maWcgPSBXb3Jrc3BhY2VQbGFuQ29uZmlncyh7IGZlYXR1cmVGbGFncyB9KVtwbGFuXVxyXG4gIGlmICghcGxhbkNvbmZpZykgcmV0dXJuIGZhbHNlXHJcblxyXG4gIGNvbnN0IGxpbWl0cyA9IHBsYW5Db25maWcubGltaXRzXHJcbiAgaWYgKCFsaW1pdHMucHJvamVjdENvdW50IHx8ICFsaW1pdHMubW9kZWxDb3VudCkgcmV0dXJuIGZhbHNlXHJcbiAgaWYgKCFwcm9qZWN0Q291bnQgfHwgIW1vZGVsQ291bnQpIHJldHVybiBmYWxzZVxyXG5cclxuICByZXR1cm4gcHJvamVjdENvdW50ID4gbGltaXRzLnByb2plY3RDb3VudCB8fCBtb2RlbENvdW50ID4gbGltaXRzLm1vZGVsQ291bnRcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBpZiBhIHdvcmtzcGFjZSByZWFjaGVkIGl0cyBwbGFuIGxpbWl0cyBmb3IgcHJvamVjdHMgYW5kIG1vZGVsc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHdvcmtzcGFjZVJlYWNoZWRQbGFuTGltaXQgPSAocGFyYW1zOiB7XHJcbiAgcGxhbjogTWF5YmVOdWxsT3JVbmRlZmluZWQ8V29ya3NwYWNlUGxhbnM+XHJcbiAgcHJvamVjdENvdW50OiBNYXliZU51bGxPclVuZGVmaW5lZDxudW1iZXI+XHJcbiAgbW9kZWxDb3VudDogTWF5YmVOdWxsT3JVbmRlZmluZWQ8bnVtYmVyPlxyXG4gIGZlYXR1cmVGbGFnczogUGFydGlhbDxGZWF0dXJlRmxhZ3M+IHwgdW5kZWZpbmVkXHJcbn0pOiBib29sZWFuID0+IHtcclxuICBjb25zdCB7IHBsYW4sIHByb2plY3RDb3VudCwgbW9kZWxDb3VudCwgZmVhdHVyZUZsYWdzIH0gPSBwYXJhbXNcclxuICBpZiAoIXBsYW4pIHJldHVybiBmYWxzZVxyXG5cclxuICBjb25zdCBwbGFuQ29uZmlnID0gV29ya3NwYWNlUGxhbkNvbmZpZ3MoeyBmZWF0dXJlRmxhZ3MgfSlbcGxhbl1cclxuICBpZiAoIXBsYW5Db25maWcpIHJldHVybiBmYWxzZVxyXG5cclxuICBjb25zdCBsaW1pdHMgPSBwbGFuQ29uZmlnLmxpbWl0c1xyXG4gIGlmICghbGltaXRzLnByb2plY3RDb3VudCB8fCAhbGltaXRzLm1vZGVsQ291bnQpIHJldHVybiBmYWxzZVxyXG5cclxuICByZXR1cm4gcHJvamVjdENvdW50ID09PSBsaW1pdHMucHJvamVjdENvdW50IHx8IG1vZGVsQ291bnQgPT09IGxpbWl0cy5tb2RlbENvdW50XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCB3b3Jrc3BhY2VQbGFuSGFzQWNjZXNzVG9GZWF0dXJlID0gKHtcclxuICBwbGFuLFxyXG4gIGZlYXR1cmUsXHJcbiAgZmVhdHVyZUZsYWdzXHJcbn06IHtcclxuICBwbGFuOiBXb3Jrc3BhY2VQbGFuc1xyXG4gIGZlYXR1cmU6IFdvcmtzcGFjZVBsYW5GZWF0dXJlc1xyXG4gIGZlYXR1cmVGbGFnczogUGFydGlhbDxGZWF0dXJlRmxhZ3M+IHwgdW5kZWZpbmVkXHJcbn0pOiBib29sZWFuID0+IHtcclxuICBjb25zdCBwbGFuQ29uZmlnID0gV29ya3NwYWNlUGxhbkNvbmZpZ3MoeyBmZWF0dXJlRmxhZ3MgfSlbcGxhbl1cclxuICBjb25zdCBoYXNBY2Nlc3MgPSBwbGFuQ29uZmlnLmZlYXR1cmVzLmluY2x1ZGVzKGZlYXR1cmUpXHJcbiAgcmV0dXJuIGhhc0FjY2Vzc1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgaXNQbGFuRmVhdHVyZSA9IChcclxuICBmZWF0dXJlOiBXb3Jrc3BhY2VGZWF0dXJlc1xyXG4pOiBmZWF0dXJlIGlzIFdvcmtzcGFjZVBsYW5GZWF0dXJlcyA9PiB7XHJcbiAgaWYgKHR5cGVvZiBmZWF0dXJlID09PSAnbnVtYmVyJykge1xyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG4gIHJldHVybiBPYmplY3QudmFsdWVzKFdvcmtzcGFjZVBsYW5GZWF0dXJlcykuaW5jbHVkZXMoZmVhdHVyZSlcclxufVxyXG4iXX0= |