@gammarers/aws-rds-database-running-schedule-stack
Version:
AWS RDS Database Running Scheduler
233 lines • 52.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RunningControlStateMachine = void 0;
const aws_cdk_lib_1 = require("aws-cdk-lib");
const sfn = require("aws-cdk-lib/aws-stepfunctions");
const tasks = require("aws-cdk-lib/aws-stepfunctions-tasks");
class RunningControlStateMachine extends sfn.StateMachine {
constructor(scope, id, props) {
super(scope, id, {
...props,
definitionBody: (() => {
// 👇 Get account
const account = aws_cdk_lib_1.Stack.of(scope).account;
const initStateListDefinition = new sfn.Pass(scope, 'InitStateListDefinition', {
result: sfn.Result.fromObject([
{ name: 'AVAILABLE', emoji: '🤩', state: 'available' },
{ name: 'STOPPED', emoji: '😴', state: 'stopped' },
]),
resultPath: '$.definition.stateList',
});
// 👇 Succeed
const stateChangeSucceed = new sfn.Succeed(scope, 'StateChangeSucceed');
const prepareTopicValue = new sfn.Pass(scope, 'PrepareTopicValue', {
resultPath: '$.prepare.topic.values',
parameters: {
emoji: sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringAt('$.definition.stateList[?(@.state == $.Result.status.current)].emoji'), 0),
status: sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringAt('$.definition.stateList[?(@.state == $.Result.status.current)].name'), 0),
account: sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringSplit(sfn.JsonPath.stringAt('$.TargetResource'), ':'), 4), // account
region: sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringSplit(sfn.JsonPath.stringAt('$.TargetResource'), ':'), 3), // region
},
}).next(new sfn.Pass(scope, 'GenerateTopic', {
resultPath: '$.Generate.Topic',
parameters: {
Subject: sfn.JsonPath.format('{} [{}] AWS RDS DB {} Running Notification [{}][{}]', sfn.JsonPath.stringAt('$.prepare.topic.values.emoji'), sfn.JsonPath.stringAt('$.prepare.topic.values.status'), sfn.JsonPath.stringAt('$.params.Mode'), sfn.JsonPath.stringAt('$.prepare.topic.values.account'), sfn.JsonPath.stringAt('$.prepare.topic.values.region')),
TextMessage: sfn.JsonPath.format('{}\n\nAccount : {}\nRegion : {}\nType : {}\nIdentifier : {}\nStatus : {}', sfn.JsonPath.format('The status of the RDS {} changed to {} due to the schedule.', sfn.JsonPath.stringAt('$.Result.target.type'), sfn.JsonPath.stringAt('$.prepare.topic.values.status')), sfn.JsonPath.stringAt('$.prepare.topic.values.account'), sfn.JsonPath.stringAt('$.prepare.topic.values.region'), sfn.JsonPath.stringAt('$.Result.target.type'), sfn.JsonPath.stringAt('$.Result.target.identifier'), sfn.JsonPath.stringAt('$.prepare.topic.values.status')),
SlackJsonMessage: {
attachments: [
{
color: '#36a64f',
pretext: sfn.JsonPath.format('{} The status of the RDS {} changed to {} due to the schedule.', sfn.JsonPath.stringAt('$.prepare.topic.values.emoji'), sfn.JsonPath.stringAt('$.Result.target.type'), sfn.JsonPath.stringAt('$.prepare.topic.values.status')),
fields: [
{
title: 'Account',
value: sfn.JsonPath.stringAt('$.prepare.topic.values.account'),
short: true,
},
{
title: 'Region',
value: sfn.JsonPath.stringAt('$.prepare.topic.values.region'),
short: true,
},
{
title: 'Type',
value: sfn.JsonPath.stringAt('$.Result.target.type'),
short: true,
},
{
title: 'Identifier',
value: sfn.JsonPath.stringAt('$.Result.target.identifier'),
short: true,
},
{
title: 'Status',
value: sfn.JsonPath.stringAt('$.prepare.topic.values.status'),
short: true,
},
],
},
],
},
},
}).next(new tasks.SnsPublish(scope, 'SendNotification', {
topic: props.notificationTopic,
subject: sfn.JsonPath.stringAt('$.Generate.Topic.Subject'),
message: sfn.TaskInput.fromObject({
default: sfn.JsonPath.stringAt('$.Generate.Topic.TextMessage'),
email: sfn.JsonPath.stringAt('$.Generate.Topic.TextMessage'),
lambda: sfn.JsonPath.jsonToString(sfn.JsonPath.objectAt('$.Generate.Topic.SlackJsonMessage')),
}),
messagePerSubscriptionType: true,
resultPath: '$.snsResult',
}).next(stateChangeSucceed)));
// 👇 Get DB Instance Resources (Filter by Tag)
const getResources = new tasks.CallAwsService(scope, 'GetResources', {
iamResources: ['*'],
iamAction: 'tag:GetResources',
service: 'resourcegroupstaggingapi',
action: 'getResources',
parameters: {
ResourceTypeFilters: [
'rds:db',
'rds:cluster',
],
TagFilters: [
{
Key: sfn.JsonPath.stringAt('$.Params.TagKey'),
Values: sfn.JsonPath.stringAt('$.Params.TagValues'),
},
],
},
resultPath: '$.Result',
resultSelector: {
TargetResources: sfn.JsonPath.stringAt('$..ResourceTagMappingList[*].ResourceARN'),
},
});
initStateListDefinition.next(getResources);
// 👇 Describe DB Instance Task
const describeDBInstancesTask = new tasks.CallAwsService(scope, 'DescribeDBInstances', {
iamResources: [`arn:aws:rds:*:${account}:db:*`],
service: 'rds',
action: 'describeDBInstances',
parameters: {
DbInstanceIdentifier: sfn.JsonPath.stringAt('$.Result.target.identifier'),
},
resultPath: '$.Result.status',
resultSelector: {
current: sfn.JsonPath.stringAt('$.DbInstances[0].DbInstanceStatus'),
},
});
// 👇 Stop DB Instance Task
const stopDBInstanceTask = new tasks.CallAwsService(scope, 'StopDBInstance', {
iamResources: [`arn:aws:rds:*:${account}:db:*`],
service: 'rds',
action: 'stopDBInstance',
parameters: {
DbInstanceIdentifier: sfn.JsonPath.stringAt('$.Result.target.identifier'),
},
resultPath: '$.Result.StopDBInstance',
});
// 👇 Start DB Instance Task
const startDBInstanceTask = new tasks.CallAwsService(scope, 'StartDBInstance', {
iamResources: [`arn:aws:rds:*:${account}:db:*`],
service: 'rds',
action: 'startDBInstance',
parameters: {
DbInstanceIdentifier: sfn.JsonPath.stringAt('$.Result.target.identifier'),
},
resultPath: '$.Result.StartDBInstance',
});
// 👇 Describe DB Cluster Task
const describeDBClustersTask = new tasks.CallAwsService(scope, 'DescribeDBClusters', {
iamResources: [`arn:aws:rds:*:${account}:cluster:*`],
service: 'rds',
action: 'describeDBClusters',
parameters: {
DbClusterIdentifier: sfn.JsonPath.stringAt('$.Result.target.identifier'),
},
resultPath: '$.Result.status',
resultSelector: {
current: sfn.JsonPath.stringAt('$.DbClusters[0].Status'),
},
});
const handleDbClusterNotFound = new sfn.Pass(scope, 'HandleDbClusterNotFound', {
result: sfn.Result.fromObject({
message: 'DB Cluster not found, but continuing...',
}),
});
describeDBClustersTask.addCatch(handleDbClusterNotFound, {
errors: ['Rds.DbClusterNotFoundException'],
});
// 👇 Stop DB Cluster Task
const stopDBClusterTask = new tasks.CallAwsService(scope, 'StopDBCluster', {
iamResources: [`arn:aws:rds:*:${account}:cluster:*`],
service: 'rds',
action: 'stopDBCluster',
parameters: {
DbClusterIdentifier: sfn.JsonPath.stringAt('$.Result.target.identifier'),
},
resultPath: '$.Result.StopDBCluster',
});
// 👇 Stop DB Cluster Task
const startDBClusterTask = new tasks.CallAwsService(scope, 'StartDBCluster', {
iamResources: [`arn:aws:rds:*:${account}:cluster:*`],
service: 'rds',
action: 'startDBCluster',
parameters: {
DbClusterIdentifier: sfn.JsonPath.stringAt('$.Result.target.identifier'),
},
resultPath: '$.Result.StartDBCluster',
});
const describeTypeChoice = new sfn.Choice(scope, 'DescribeTypeChoice')
.when(sfn.Condition.stringEquals('$.Result.target.type', 'db'), describeDBInstancesTask)
.when(sfn.Condition.stringEquals('$.Result.target.type', 'cluster'), describeDBClustersTask)
.otherwise(new sfn.Fail(scope, 'UnknownType'));
const statusChangeWait = new sfn.Wait(scope, 'StatusChangeWait', {
time: sfn.WaitTime.duration(aws_cdk_lib_1.Duration.minutes(1)),
});
statusChangeWait.next(describeTypeChoice);
startDBInstanceTask.next(statusChangeWait);
stopDBInstanceTask.next(statusChangeWait);
startDBClusterTask.next(statusChangeWait);
stopDBClusterTask.next(statusChangeWait);
const statusChoice = new sfn.Choice(scope, 'StatusChoice')
// db instance start on status.stopped
.when(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Start'), sfn.Condition.stringEquals('$.Result.target.type', 'db'), sfn.Condition.stringEquals('$.Result.status.current', 'stopped')), startDBInstanceTask)
// db instance stop on status.available
.when(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Stop'), sfn.Condition.stringEquals('$.Result.target.type', 'db'), sfn.Condition.stringEquals('$.Result.status.current', 'available')), stopDBInstanceTask)
// start on status.stopped
.when(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Start'), sfn.Condition.stringEquals('$.Result.target.type', 'cluster'), sfn.Condition.stringEquals('$.Result.status.current', 'stopped')), startDBClusterTask)
// stop on status.available
.when(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Stop'), sfn.Condition.stringEquals('$.Result.target.type', 'cluster'), sfn.Condition.stringEquals('$.Result.status.current', 'available')), stopDBClusterTask)
// status change succeed, generate topic
.when(sfn.Condition.or(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Start'), sfn.Condition.or(sfn.Condition.stringEquals('$.Result.target.type', 'db'), sfn.Condition.stringEquals('$.Result.target.type', 'cluster')), sfn.Condition.stringEquals('$.Result.status.current', 'available')), sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Stop'), sfn.Condition.or(sfn.Condition.stringEquals('$.Result.target.type', 'db'), sfn.Condition.stringEquals('$.Result.target.type', 'cluster')), sfn.Condition.stringEquals('$.Result.status.current', 'stopped'))), prepareTopicValue)
.when(
// start & starting/configuring-enhanced-monitoring/backing-up or stop modifying/stopping
sfn.Condition.or(sfn.Condition.and(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Start'), sfn.Condition.or(sfn.Condition.stringEquals('$.Result.target.type', 'db'), sfn.Condition.stringEquals('$.Result.target.type', 'cluster')), sfn.Condition.or(sfn.Condition.stringEquals('$.Result.status.current', 'starting'), sfn.Condition.stringEquals('$.Result.status.current', 'configuring-enhanced-monitoring'), sfn.Condition.stringEquals('$.Result.status.current', 'backing-up'), sfn.Condition.stringEquals('$.Result.status.current', 'modifying')))), sfn.Condition.and(sfn.Condition.and(sfn.Condition.stringEquals('$.params.Mode', 'Stop'), sfn.Condition.or(sfn.Condition.stringEquals('$.Result.target.type', 'db'), sfn.Condition.stringEquals('$.Result.target.type', 'cluster')), sfn.Condition.or(sfn.Condition.stringEquals('$.Result.status.current', 'modifying'), sfn.Condition.stringEquals('$.Result.status.current', 'stopping'))))), statusChangeWait)
.otherwise(new sfn.Fail(scope, 'StatusFail', {
cause: 'db instance or cluster status fail.',
}));
getResources.next(new sfn.Map(scope, 'ResourceProcessingMap', {
itemsPath: sfn.JsonPath.stringAt('$.Result.TargetResources'),
parameters: {
TargetResource: sfn.JsonPath.stringAt('$$.Map.Item.Value'),
params: sfn.JsonPath.stringAt('$.Params'),
definition: sfn.JsonPath.stringAt('$.definition'),
},
maxConcurrency: 10,
}).itemProcessor(new sfn.Pass(scope, 'GetIdentifier', {
resultPath: '$.Result.target',
parameters: {
identifier: sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringSplit(sfn.JsonPath.stringAt('$.TargetResource'), ':'), 6),
type: sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringSplit(sfn.JsonPath.stringAt('$.TargetResource'), ':'), 5), // db or cluster
},
}).next(describeTypeChoice)));
describeDBInstancesTask.next(statusChoice);
describeDBClustersTask.next(statusChoice);
return sfn.DefinitionBody.fromChainable(initStateListDefinition);
})(),
});
}
}
exports.RunningControlStateMachine = RunningControlStateMachine;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVubmluZy1jb250cm9sLXN0YXRlLW1hY2hpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVzb3VyY2VzL3J1bm5pbmctY29udHJvbC1zdGF0ZS1tYWNoaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUE4QztBQUU5QyxxREFBcUQ7QUFDckQsNkRBQTZEO0FBTzdELE1BQWEsMEJBQTJCLFNBQVEsR0FBRyxDQUFDLFlBQVk7SUFDOUQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFzQztRQUM5RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLEdBQUcsS0FBSztZQUNSLGNBQWMsRUFBRSxDQUFDLEdBQUcsRUFBRTtnQkFFcEIsaUJBQWlCO2dCQUNqQixNQUFNLE9BQU8sR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBRXhDLE1BQU0sdUJBQXVCLEdBQWEsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSx5QkFBeUIsRUFBRTtvQkFDdkYsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO3dCQUM1QixFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFO3dCQUN0RCxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFO3FCQUNuRCxDQUFDO29CQUNGLFVBQVUsRUFBRSx3QkFBd0I7aUJBQ3JDLENBQUMsQ0FBQztnQkFFSCxhQUFhO2dCQUNiLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO2dCQUV4RSxNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUs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QUFHLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLGdCQUFnQjtxQkFDL0g7aUJBQ0YsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFbEMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUMzQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBRTFDLE9BQU8sR0FBRyxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUNuRSxDQUFDLENBQUMsRUFBRTtTQUNMLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQWpXRCxnRUFpV0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiwgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBzbnMgZnJvbSAnYXdzLWNkay1saWIvYXdzLXNucyc7XG5pbXBvcnQgKiBhcyBzZm4gZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMnO1xuaW1wb3J0ICogYXMgdGFza3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMtdGFza3MnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVubmluZ0NvbnRyb2xTdGF0ZU1hY2hpbmVQcm9wcyBleHRlbmRzIHNmbi5TdGF0ZU1hY2hpbmVQcm9wcyB7XG4gIG5vdGlmaWNhdGlvblRvcGljOiBzbnMuSVRvcGljO1xufVxuXG5leHBvcnQgY2xhc3MgUnVubmluZ0NvbnRyb2xTdGF0ZU1hY2hpbmUgZXh0ZW5kcyBzZm4uU3RhdGVNYWNoaW5lIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFJ1bm5pbmdDb250cm9sU3RhdGVNYWNoaW5lUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZGVmaW5pdGlvbkJvZHk6ICgoKSA9PiB7XG5cbiAgICAgICAgLy8g8J+RhyBHZXQgYWNjb3VudFxuICAgICAgICBjb25zdCBhY2NvdW50ID0gU3RhY2sub2Yoc2NvcGUpLmFjY291bnQ7XG5cbiAgICAgICAgY29uc3QgaW5pdFN0YXRlTGlzdERlZmluaXRpb246IHNmbi5QYXNzID0gbmV3IHNmbi5QYXNzKHNjb3BlLCAnSW5pdFN0YXRlTGlzdERlZmluaXRpb24nLCB7XG4gICAgICAgICAgcmVzdWx0OiBzZm4uUmVzdWx0LmZyb21PYmplY3QoW1xuICAgICAgICAgICAgeyBuYW1lOiAnQVZBSUxBQkxFJywgZW1vamk6ICfwn6SpJywgc3RhdGU6ICdhdmFpbGFibGUnIH0sXG4gICAgICAgICAgICB7IG5hbWU6ICdTVE9QUEVEJywgZW1vamk6ICfwn5i0Jywgc3RhdGU6ICdzdG9wcGVkJyB9LFxuICAgICAgICAgIF0pLFxuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLmRlZmluaXRpb24uc3RhdGVMaXN0JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8g8J+RhyBTdWNjZWVkXG4gICAgICAgIGNvbnN0IHN0YXRlQ2hhbmdlU3VjY2VlZCA9IG5ldyBzZm4uU3VjY2VlZChzY29wZSwgJ1N0YXRlQ2hhbmdlU3VjY2VlZCcpO1xuXG4gICAgICAgIGNvbnN0IHByZXBhcmVUb3BpY1ZhbHVlID0gbmV3IHNmbi5QYXNzKHNjb3BlLCAnUHJlcGFyZVRvcGljVmFsdWUnLCB7XG4gICAgICAgICAgcmVzdWx0UGF0aDogJyQucHJlcGFyZS50b3BpYy52YWx1ZXMnLFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGVtb2ppOiBzZm4uSnNvblBhdGguYXJyYXlHZXRJdGVtKHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5kZWZpbml0aW9uLnN0YXRlTGlzdFs/KEAuc3RhdGUgPT0gJC5SZXN1bHQuc3RhdHVzLmN1cnJlbnQpXS5lbW9qaScpLCAwKSxcbiAgICAgICAgICAgIHN0YXR1czogc2ZuLkpzb25QYXRoLmFycmF5R2V0SXRlbShzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuZGVmaW5pdGlvbi5zdGF0ZUxpc3RbPyhALnN0YXRlID09ICQuUmVzdWx0LnN0YXR1cy5jdXJyZW50KV0ubmFtZScpLCAwKSxcbiAgICAgICAgICAgIGFjY291bnQ6IHNmbi5Kc29uUGF0aC5hcnJheUdldEl0ZW0oc2ZuLkpzb25QYXRoLnN0cmluZ1NwbGl0KHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5UYXJnZXRSZXNvdXJjZScpLCAnOicpLCA0KSwgLy8gYWNjb3VudFxuICAgICAgICAgICAgcmVnaW9uOiBzZm4uSnNvblBhdGguYXJyYXlHZXRJdGVtKHNmbi5Kc29uUGF0aC5zdHJpbmdTcGxpdChzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuVGFyZ2V0UmVzb3VyY2UnKSwgJzonKSwgMyksIC8vIHJlZ2lvblxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLm5leHQobmV3IHNmbi5QYXNzKHNjb3BlLCAnR2VuZXJhdGVUb3BpYycsIHtcbiAgICAgICAgICByZXN1bHRQYXRoOiAnJC5HZW5lcmF0ZS5Ub3BpYycsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgU3ViamVjdDogc2ZuLkpzb25QYXRoLmZvcm1hdCgne30gW3t9XSBBV1MgUkRTIERCIHt9IFJ1bm5pbmcgTm90aWZpY2F0aW9uIFt7fV1be31dJyxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLnByZXBhcmUudG9waWMudmFsdWVzLmVtb2ppJyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwYXJlLnRvcGljLnZhbHVlcy5zdGF0dXMnKSxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLnBhcmFtcy5Nb2RlJyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwYXJlLnRvcGljLnZhbHVlcy5hY2NvdW50JyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwYXJlLnRvcGljLnZhbHVlcy5yZWdpb24nKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBUZXh0TWVzc2FnZTogc2ZuLkpzb25QYXRoLmZvcm1hdCgne31cXG5cXG5BY2NvdW50IDoge31cXG5SZWdpb24gOiB7fVxcblR5cGUgOiB7fVxcbklkZW50aWZpZXIgOiB7fVxcblN0YXR1cyA6IHt9JyxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLmZvcm1hdCgnVGhlIHN0YXR1cyBvZiB0aGUgUkRTIHt9IGNoYW5nZWQgdG8ge30gZHVlIHRvIHRoZSBzY2hlZHVsZS4nLFxuICAgICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5SZXN1bHQudGFyZ2V0LnR5cGUnKSxcbiAgICAgICAgICAgICAgICBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQucHJlcGFyZS50b3BpYy52YWx1ZXMuc3RhdHVzJyksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwYXJlLnRvcGljLnZhbHVlcy5hY2NvdW50JyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwYXJlLnRvcGljLnZhbHVlcy5yZWdpb24nKSxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC50YXJnZXQudHlwZScpLFxuICAgICAgICAgICAgICBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuUmVzdWx0LnRhcmdldC5pZGVudGlmaWVyJyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwYXJlLnRvcGljLnZhbHVlcy5zdGF0dXMnKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBTbGFja0pzb25NZXNzYWdlOiB7XG4gICAgICAgICAgICAgIGF0dGFjaG1lbnRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgY29sb3I6ICcjMzZhNjRmJyxcbiAgICAgICAgICAgICAgICAgIHByZXRleHQ6IHNmbi5Kc29uUGF0aC5mb3JtYXQoJ3t9IFRoZSBzdGF0dXMgb2YgdGhlIFJEUyB7fSBjaGFuZ2VkIHRvIHt9IGR1ZSB0byB0aGUgc2NoZWR1bGUuJyxcbiAgICAgICAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLnByZXBhcmUudG9waWMudmFsdWVzLmVtb2ppJyksXG4gICAgICAgICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5SZXN1bHQudGFyZ2V0LnR5cGUnKSxcbiAgICAgICAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLnByZXBhcmUudG9waWMudmFsdWVzLnN0YXR1cycpLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgIGZpZWxkczogW1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdBY2NvdW50JyxcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLnByZXBhcmUudG9waWMudmFsdWVzLmFjY291bnQnKSxcbiAgICAgICAgICAgICAgICAgICAgICBzaG9ydDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnUmVnaW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLnByZXBhcmUudG9waWMudmFsdWVzLnJlZ2lvbicpLFxuICAgICAgICAgICAgICAgICAgICAgIHNob3J0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdUeXBlJyxcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC50YXJnZXQudHlwZScpLFxuICAgICAgICAgICAgICAgICAgICAgIHNob3J0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdJZGVudGlmaWVyJyxcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC50YXJnZXQuaWRlbnRpZmllcicpLFxuICAgICAgICAgICAgICAgICAgICAgIHNob3J0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdTdGF0dXMnLFxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQucHJlcGFyZS50b3BpYy52YWx1ZXMuc3RhdHVzJyksXG4gICAgICAgICAgICAgICAgICAgICAgc2hvcnQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLm5leHQobmV3IHRhc2tzLlNuc1B1Ymxpc2goc2NvcGUsICdTZW5kTm90aWZpY2F0aW9uJywge1xuICAgICAgICAgIHRvcGljOiBwcm9wcy5ub3RpZmljYXRpb25Ub3BpYyxcbiAgICAgICAgICBzdWJqZWN0OiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuR2VuZXJhdGUuVG9waWMuU3ViamVjdCcpLFxuICAgICAgICAgIG1lc3NhZ2U6IHNmbi5UYXNrSW5wdXQuZnJvbU9iamVjdCh7XG4gICAgICAgICAgICBkZWZhdWx0OiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuR2VuZXJhdGUuVG9waWMuVGV4dE1lc3NhZ2UnKSxcbiAgICAgICAgICAgIGVtYWlsOiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuR2VuZXJhdGUuVG9waWMuVGV4dE1lc3NhZ2UnKSxcbiAgICAgICAgICAgIGxhbWJkYTogc2ZuLkpzb25QYXRoLmpzb25Ub1N0cmluZyhzZm4uSnNvblBhdGgub2JqZWN0QXQoJyQuR2VuZXJhdGUuVG9waWMuU2xhY2tKc29uTWVzc2FnZScpKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBtZXNzYWdlUGVyU3Vic2NyaXB0aW9uVHlwZTogdHJ1ZSxcbiAgICAgICAgICByZXN1bHRQYXRoOiAnJC5zbnNSZXN1bHQnLFxuICAgICAgICB9KS5uZXh0KHN0YXRlQ2hhbmdlU3VjY2VlZCkpKTtcblxuICAgICAgICAvLyDwn5GHIEdldCBEQiBJbnN0YW5jZSBSZXNvdXJjZXMgKEZpbHRlciBieSBUYWcpXG4gICAgICAgIGNvbnN0IGdldFJlc291cmNlcyA9IG5ldyB0YXNrcy5DYWxsQXdzU2VydmljZShzY29wZSwgJ0dldFJlc291cmNlcycsIHtcbiAgICAgICAgICBpYW1SZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIGlhbUFjdGlvbjogJ3RhZzpHZXRSZXNvdXJjZXMnLFxuICAgICAgICAgIHNlcnZpY2U6ICdyZXNvdXJjZWdyb3Vwc3RhZ2dpbmdhcGknLFxuICAgICAgICAgIGFjdGlvbjogJ2dldFJlc291cmNlcycsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgUmVzb3VyY2VUeXBlRmlsdGVyczogW1xuICAgICAgICAgICAgICAncmRzOmRiJyxcbiAgICAgICAgICAgICAgJ3JkczpjbHVzdGVyJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBUYWdGaWx0ZXJzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBLZXk6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5QYXJhbXMuVGFnS2V5JyksXG4gICAgICAgICAgICAgICAgVmFsdWVzOiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuUGFyYW1zLlRhZ1ZhbHVlcycpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLlJlc3VsdCcsXG4gICAgICAgICAgcmVzdWx0U2VsZWN0b3I6IHtcbiAgICAgICAgICAgIFRhcmdldFJlc291cmNlczogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLi5SZXNvdXJjZVRhZ01hcHBpbmdMaXN0WypdLlJlc291cmNlQVJOJyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaW5pdFN0YXRlTGlzdERlZmluaXRpb24ubmV4dChnZXRSZXNvdXJjZXMpO1xuXG4gICAgICAgIC8vIPCfkYcgRGVzY3JpYmUgREIgSW5zdGFuY2UgVGFza1xuICAgICAgICBjb25zdCBkZXNjcmliZURCSW5zdGFuY2VzVGFzayA9IG5ldyB0YXNrcy5DYWxsQXdzU2VydmljZShzY29wZSwgJ0Rlc2NyaWJlREJJbnN0YW5jZXMnLCB7XG4gICAgICAgICAgaWFtUmVzb3VyY2VzOiBbYGFybjphd3M6cmRzOio6JHthY2NvdW50fTpkYjoqYF0sXG4gICAgICAgICAgc2VydmljZTogJ3JkcycsXG4gICAgICAgICAgYWN0aW9uOiAnZGVzY3JpYmVEQkluc3RhbmNlcycsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgRGJJbnN0YW5jZUlkZW50aWZpZXI6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5SZXN1bHQudGFyZ2V0LmlkZW50aWZpZXInKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLlJlc3VsdC5zdGF0dXMnLFxuICAgICAgICAgIHJlc3VsdFNlbGVjdG9yOiB7XG4gICAgICAgICAgICBjdXJyZW50OiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuRGJJbnN0YW5jZXNbMF0uRGJJbnN0YW5jZVN0YXR1cycpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIPCfkYcgU3RvcCBEQiBJbnN0YW5jZSBUYXNrXG4gICAgICAgIGNvbnN0IHN0b3BEQkluc3RhbmNlVGFzayA9IG5ldyB0YXNrcy5DYWxsQXdzU2VydmljZShzY29wZSwgJ1N0b3BEQkluc3RhbmNlJywge1xuICAgICAgICAgIGlhbVJlc291cmNlczogW2Bhcm46YXdzOnJkczoqOiR7YWNjb3VudH06ZGI6KmBdLFxuICAgICAgICAgIHNlcnZpY2U6ICdyZHMnLFxuICAgICAgICAgIGFjdGlvbjogJ3N0b3BEQkluc3RhbmNlJyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBEYkluc3RhbmNlSWRlbnRpZmllcjogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC50YXJnZXQuaWRlbnRpZmllcicpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzdWx0UGF0aDogJyQuUmVzdWx0LlN0b3BEQkluc3RhbmNlJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8g8J+RhyBTdGFydCBEQiBJbnN0YW5jZSBUYXNrXG4gICAgICAgIGNvbnN0IHN0YXJ0REJJbnN0YW5jZVRhc2sgPSBuZXcgdGFza3MuQ2FsbEF3c1NlcnZpY2Uoc2NvcGUsICdTdGFydERCSW5zdGFuY2UnLCB7XG4gICAgICAgICAgaWFtUmVzb3VyY2VzOiBbYGFybjphd3M6cmRzOio6JHthY2NvdW50fTpkYjoqYF0sXG4gICAgICAgICAgc2VydmljZTogJ3JkcycsXG4gICAgICAgICAgYWN0aW9uOiAnc3RhcnREQkluc3RhbmNlJyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBEYkluc3RhbmNlSWRlbnRpZmllcjogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC50YXJnZXQuaWRlbnRpZmllcicpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzdWx0UGF0aDogJyQuUmVzdWx0LlN0YXJ0REJJbnN0YW5jZScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIPCfkYcgRGVzY3JpYmUgREIgQ2x1c3RlciBUYXNrXG4gICAgICAgIGNvbnN0IGRlc2NyaWJlREJDbHVzdGVyc1Rhc2sgPSBuZXcgdGFza3MuQ2FsbEF3c1NlcnZpY2Uoc2NvcGUsICdEZXNjcmliZURCQ2x1c3RlcnMnLCB7XG4gICAgICAgICAgaWFtUmVzb3VyY2VzOiBbYGFybjphd3M6cmRzOio6JHthY2NvdW50fTpjbHVzdGVyOipgXSxcbiAgICAgICAgICBzZXJ2aWNlOiAncmRzJyxcbiAgICAgICAgICBhY3Rpb246ICdkZXNjcmliZURCQ2x1c3RlcnMnLFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIERiQ2x1c3RlcklkZW50aWZpZXI6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5SZXN1bHQudGFyZ2V0LmlkZW50aWZpZXInKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLlJlc3VsdC5zdGF0dXMnLFxuICAgICAgICAgIHJlc3VsdFNlbGVjdG9yOiB7XG4gICAgICAgICAgICBjdXJyZW50OiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuRGJDbHVzdGVyc1swXS5TdGF0dXMnKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBoYW5kbGVEYkNsdXN0ZXJOb3RGb3VuZCA9IG5ldyBzZm4uUGFzcyhzY29wZSwgJ0hhbmRsZURiQ2x1c3Rlck5vdEZvdW5kJywge1xuICAgICAgICAgIHJlc3VsdDogc2ZuLlJlc3VsdC5mcm9tT2JqZWN0KHtcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdEQiBDbHVzdGVyIG5vdCBmb3VuZCwgYnV0IGNvbnRpbnVpbmcuLi4nLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZURCQ2x1c3RlcnNUYXNrLmFkZENhdGNoKGhhbmRsZURiQ2x1c3Rlck5vdEZvdW5kLCB7XG4gICAgICAgICAgZXJyb3JzOiBbJ1Jkcy5EYkNsdXN0ZXJOb3RGb3VuZEV4Y2VwdGlvbiddLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyDwn5GHIFN0b3AgREIgQ2x1c3RlciBUYXNrXG4gICAgICAgIGNvbnN0IHN0b3BEQkNsdXN0ZXJUYXNrID0gbmV3IHRhc2tzLkNhbGxBd3NTZXJ2aWNlKHNjb3BlLCAnU3RvcERCQ2x1c3RlcicsIHtcbiAgICAgICAgICBpYW1SZXNvdXJjZXM6IFtgYXJuOmF3czpyZHM6Kjoke2FjY291bnR9OmNsdXN0ZXI6KmBdLFxuICAgICAgICAgIHNlcnZpY2U6ICdyZHMnLFxuICAgICAgICAgIGFjdGlvbjogJ3N0b3BEQkNsdXN0ZXInLFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIERiQ2x1c3RlcklkZW50aWZpZXI6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5SZXN1bHQudGFyZ2V0LmlkZW50aWZpZXInKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLlJlc3VsdC5TdG9wREJDbHVzdGVyJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8g8J+RhyBTdG9wIERCIENsdXN0ZXIgVGFza1xuICAgICAgICBjb25zdCBzdGFydERCQ2x1c3RlclRhc2sgPSBuZXcgdGFza3MuQ2FsbEF3c1NlcnZpY2Uoc2NvcGUsICdTdGFydERCQ2x1c3RlcicsIHtcbiAgICAgICAgICBpYW1SZXNvdXJjZXM6IFtgYXJuOmF3czpyZHM6Kjoke2FjY291bnR9OmNsdXN0ZXI6KmBdLFxuICAgICAgICAgIHNlcnZpY2U6ICdyZHMnLFxuICAgICAgICAgIGFjdGlvbjogJ3N0YXJ0REJDbHVzdGVyJyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBEYkNsdXN0ZXJJZGVudGlmaWVyOiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuUmVzdWx0LnRhcmdldC5pZGVudGlmaWVyJyksXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXN1bHRQYXRoOiAnJC5SZXN1bHQuU3RhcnREQkNsdXN0ZXInLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBkZXNjcmliZVR5cGVDaG9pY2UgPSBuZXcgc2ZuLkNob2ljZShzY29wZSwgJ0Rlc2NyaWJlVHlwZUNob2ljZScpXG4gICAgICAgICAgLndoZW4oXG4gICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQudGFyZ2V0LnR5cGUnLCAnZGInKSxcbiAgICAgICAgICAgIGRlc2NyaWJlREJJbnN0YW5jZXNUYXNrLFxuICAgICAgICAgIClcbiAgICAgICAgICAud2hlbihcbiAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLlJlc3VsdC50YXJnZXQudHlwZScsICdjbHVzdGVyJyksXG4gICAgICAgICAgICBkZXNjcmliZURCQ2x1c3RlcnNUYXNrLFxuICAgICAgICAgIClcbiAgICAgICAgICAub3RoZXJ3aXNlKG5ldyBzZm4uRmFpbChzY29wZSwgJ1Vua25vd25UeXBlJykpO1xuXG4gICAgICAgIGNvbnN0IHN0YXR1c0NoYW5nZVdhaXQgPSBuZXcgc2ZuLldhaXQoc2NvcGUsICdTdGF0dXNDaGFuZ2VXYWl0Jywge1xuICAgICAgICAgIHRpbWU6IHNmbi5XYWl0VGltZS5kdXJhdGlvbihEdXJhdGlvbi5taW51dGVzKDEpKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHN0YXR1c0NoYW5nZVdhaXQubmV4dChkZXNjcmliZVR5cGVDaG9pY2UpO1xuXG4gICAgICAgIHN0YXJ0REJJbnN0YW5jZVRhc2submV4dChzdGF0dXNDaGFuZ2VXYWl0KTtcbiAgICAgICAgc3RvcERCSW5zdGFuY2VUYXNrLm5leHQoc3RhdHVzQ2hhbmdlV2FpdCk7XG5cbiAgICAgICAgc3RhcnREQkNsdXN0ZXJUYXNrLm5leHQoc3RhdHVzQ2hhbmdlV2FpdCk7XG4gICAgICAgIHN0b3BEQkNsdXN0ZXJUYXNrLm5leHQoc3RhdHVzQ2hhbmdlV2FpdCk7XG5cbiAgICAgICAgY29uc3Qgc3RhdHVzQ2hvaWNlID0gbmV3IHNmbi5DaG9pY2Uoc2NvcGUsICdTdGF0dXNDaG9pY2UnKVxuICAgICAgICAgIC8vIGRiIGluc3RhbmNlIHN0YXJ0IG9uIHN0YXR1cy5zdG9wcGVkXG4gICAgICAgICAgLndoZW4oXG4gICAgICAgICAgICBzZm4uQ29uZGl0aW9uLmFuZChcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQucGFyYW1zLk1vZGUnLCAnU3RhcnQnKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuUmVzdWx0LnRhcmdldC50eXBlJywgJ2RiJyksXG4gICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLlJlc3VsdC5zdGF0dXMuY3VycmVudCcsICdzdG9wcGVkJyksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgc3RhcnREQkluc3RhbmNlVGFzayxcbiAgICAgICAgICApXG4gICAgICAgICAgLy8gZGIgaW5zdGFuY2Ugc3RvcCBvbiBzdGF0dXMuYXZhaWxhYmxlXG4gICAgICAgICAgLndoZW4oXG4gICAgICAgICAgICBzZm4uQ29uZGl0aW9uLmFuZChcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQucGFyYW1zLk1vZGUnLCAnU3RvcCcpLFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQudGFyZ2V0LnR5cGUnLCAnZGInKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuUmVzdWx0LnN0YXR1cy5jdXJyZW50JywgJ2F2YWlsYWJsZScpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHN0b3BEQkluc3RhbmNlVGFzayxcbiAgICAgICAgICApXG4gICAgICAgICAgLy8gc3RhcnQgb24gc3RhdHVzLnN0b3BwZWRcbiAgICAgICAgICAud2hlbihcbiAgICAgICAgICAgIHNmbi5Db25kaXRpb24uYW5kKFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5wYXJhbXMuTW9kZScsICdTdGFydCcpLFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQudGFyZ2V0LnR5cGUnLCAnY2x1c3RlcicpLFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQuc3RhdHVzLmN1cnJlbnQnLCAnc3RvcHBlZCcpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHN0YXJ0REJDbHVzdGVyVGFzayxcbiAgICAgICAgICApXG4gICAgICAgICAgLy8gc3RvcCBvbiBzdGF0dXMuYXZhaWxhYmxlXG4gICAgICAgICAgLndoZW4oXG4gICAgICAgICAgICBzZm4uQ29uZGl0aW9uLmFuZChcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQucGFyYW1zLk1vZGUnLCAnU3RvcCcpLFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQudGFyZ2V0LnR5cGUnLCAnY2x1c3RlcicpLFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQuc3RhdHVzLmN1cnJlbnQnLCAnYXZhaWxhYmxlJyksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgc3RvcERCQ2x1c3RlclRhc2ssXG4gICAgICAgICAgKVxuICAgICAgICAgIC8vIHN0YXR1cyBjaGFuZ2Ugc3VjY2VlZCwgZ2VuZXJhdGUgdG9waWNcbiAgICAgICAgICAud2hlbihcbiAgICAgICAgICAgIHNmbi5Db25kaXRpb24ub3IoXG4gICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uYW5kKFxuICAgICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLnBhcmFtcy5Nb2RlJywgJ1N0YXJ0JyksXG4gICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5vcihcbiAgICAgICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLlJlc3VsdC50YXJnZXQudHlwZScsICdkYicpLFxuICAgICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuUmVzdWx0LnRhcmdldC50eXBlJywgJ2NsdXN0ZXInKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLlJlc3VsdC5zdGF0dXMuY3VycmVudCcsICdhdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5hbmQoXG4gICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQucGFyYW1zLk1vZGUnLCAnU3RvcCcpLFxuICAgICAgICAgICAgICAgIHNmbi5Db25kaXRpb24ub3IoXG4gICAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQudGFyZ2V0LnR5cGUnLCAnZGInKSxcbiAgICAgICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLlJlc3VsdC50YXJnZXQudHlwZScsICdjbHVzdGVyJyksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQuc3RhdHVzLmN1cnJlbnQnLCAnc3RvcHBlZCcpLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHByZXBhcmVUb3BpY1ZhbHVlLFxuICAgICAgICAgIClcbiAgICAgICAgICAud2hlbihcbiAgICAgICAgICAgIC8vIHN0YXJ0ICYgc3RhcnRpbmcvY29uZmlndXJpbmctZW5oYW5jZWQtbW9uaXRvcmluZy9iYWNraW5nLXVwIG9yIHN0b3AgbW9kaWZ5aW5nL3N0b3BwaW5nXG4gICAgICAgICAgICBzZm4uQ29uZGl0aW9uLm9yKFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLmFuZChcbiAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLmFuZChcbiAgICAgICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLnBhcmFtcy5Nb2RlJywgJ1N0YXJ0JyksXG4gICAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLm9yKFxuICAgICAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQudGFyZ2V0LnR5cGUnLCAnZGInKSxcbiAgICAgICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuUmVzdWx0LnRhcmdldC50eXBlJywgJ2NsdXN0ZXInKSxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLm9yKFxuICAgICAgICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5SZXN1bHQuc3RhdHVzLmN1cnJlbnQnLCAnc3RhcnRpbmcnKSxcbiAgICAgICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuUmVzdWx0LnN0YXR1cy5jdXJyZW50JywgJ2NvbmZpZ3VyaW5nLWVuaGFuY2VkLW1vbml0b3JpbmcnKSxcbiAgICAgICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuUmVzdWx0LnN0YXR1cy5jdXJyZW50JywgJ2JhY2tpbmctdXAnKSxcbiAgICAgICAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcX