cdk-monitoring-constructs
Version:
[](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs) [](https://badge
449 lines • 63.7 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MonitoringFacade = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const common_1 = require("../common");
const dashboard_1 = require("../dashboard");
const monitoring_1 = require("../monitoring");
const MonitoringAspect_1 = require("./MonitoringAspect");
/**
* Main entry point to create your monitoring.
*/
class MonitoringFacade extends common_1.MonitoringScope {
constructor(scope, id, props) {
super(scope, id);
this.metricFactoryDefaults =
props?.metricFactoryDefaults ??
MonitoringFacade.getDefaultMetricFactoryDefaults();
this.alarmFactoryDefaults =
props?.alarmFactoryDefaults ??
MonitoringFacade.getDefaultAlarmFactoryDefaults(id);
this.dashboardFactory =
props?.dashboardFactory ??
MonitoringFacade.getDefaultDashboardFactory(this, id);
this.createdSegments = [];
}
static getDefaultMetricFactoryDefaults() {
return {};
}
static getDefaultAlarmFactoryDefaults(defaultName) {
return {
alarmNamePrefix: defaultName,
actionsEnabled: true,
};
}
static getDefaultDashboardFactory(scope, defaultName) {
return new dashboard_1.DefaultDashboardFactory(scope, `${defaultName}-Dashboards`, {
dashboardNamePrefix: defaultName,
});
}
// FACTORIES
// =========
createAlarmFactory(alarmNamePrefix) {
return new common_1.AlarmFactory(this, {
globalAlarmDefaults: this.alarmFactoryDefaults,
globalMetricDefaults: this.metricFactoryDefaults,
localAlarmNamePrefix: alarmNamePrefix,
});
}
createAwsConsoleUrlFactory() {
const stack = aws_cdk_lib_1.Stack.of(this);
const awsAccountId = stack.account;
const awsAccountRegion = stack.region;
return new common_1.AwsConsoleUrlFactory({ awsAccountRegion, awsAccountId });
}
createMetricFactory() {
return new common_1.MetricFactory({ globalDefaults: this.metricFactoryDefaults });
}
createWidgetFactory() {
return new dashboard_1.DefaultWidgetFactory();
}
// GENERIC
// =======
createdDashboard() {
return this.dashboardFactory?.createdDashboard();
}
createdSummaryDashboard() {
return this.dashboardFactory?.createdSummaryDashboard();
}
createdAlarmDashboard() {
return this.dashboardFactory?.createdAlarmDashboard();
}
/**
* Returns the created alarms across all the monitorings added up until now.
*/
createdAlarms() {
const alarms = [];
this.createdSegments.forEach((monitoring) => {
if (monitoring instanceof common_1.Monitoring) {
alarms.push(...monitoring.createdAlarms());
}
});
return alarms;
}
/**
* Returns a subset of created alarms that are marked by a specific custom tag.
* @param customTag tag to filter alarms by
*/
createdAlarmsWithTag(customTag) {
return this.createdAlarms().filter((alarm) => alarm.customTags?.includes(customTag));
}
/**
* Returns a subset of created alarms that are marked by a specific disambiguator.
* @param disambiguator disambiguator to filter alarms by
*/
createdAlarmsWithDisambiguator(disambiguator) {
return this.createdAlarms().filter((alarm) => alarm.disambiguator === disambiguator);
}
/**
* Finds a subset of created alarms that are marked by a specific custom tag and creates a composite alarm.
* This composite alarm is created with an 'OR' condition, so it triggers with any child alarm.
* NOTE: This composite alarm is not added among other alarms, so it is not returned by createdAlarms() calls.
*
* @param customTag tag to filter alarms by
* @param props customization options
*/
createCompositeAlarmUsingTag(customTag, props) {
const alarms = this.createdAlarmsWithTag(customTag);
if (alarms.length > 0) {
const disambiguator = props?.disambiguator ?? customTag;
const alarmFactory = this.createAlarmFactory("Composite");
return alarmFactory.addCompositeAlarm(alarms, {
...(props ?? {}),
disambiguator,
});
}
return undefined;
}
/**
* Finds a subset of created alarms that are marked by a specific disambiguator and creates a composite alarm.
* This composite alarm is created with an 'OR' condition, so it triggers with any child alarm.
* NOTE: This composite alarm is not added among other alarms, so it is not returned by createdAlarms() calls.
*
* @param alarmDisambiguator disambiguator to filter alarms by
* @param props customization options
*/
createCompositeAlarmUsingDisambiguator(alarmDisambiguator, props) {
const alarms = this.createdAlarmsWithDisambiguator(alarmDisambiguator);
if (alarms.length > 0) {
const disambiguator = props?.disambiguator ?? alarmDisambiguator;
const alarmFactory = this.createAlarmFactory("Composite");
return alarmFactory.addCompositeAlarm(alarms, {
...(props ?? {}),
disambiguator,
});
}
return undefined;
}
/**
* Returns the created monitorings added up until now.
*/
createdMonitorings() {
return this.createdSegments
.filter((s) => s instanceof common_1.Monitoring)
.map((s) => s);
}
addSegment(segment, overrideProps) {
this.dashboardFactory?.addSegment({ segment, overrideProps });
this.createdSegments.push(segment);
return this;
}
addLargeHeader(text, addToSummary, addToAlarm) {
this.addWidget(new dashboard_1.HeaderWidget(text, dashboard_1.HeaderLevel.LARGE), addToSummary ?? false, addToAlarm ?? false);
return this;
}
addMediumHeader(text, addToSummary, addToAlarm) {
this.addWidget(new dashboard_1.HeaderWidget(text, dashboard_1.HeaderLevel.MEDIUM), addToSummary ?? false, addToAlarm ?? false);
return this;
}
addSmallHeader(text, addToSummary, addToAlarm) {
this.addWidget(new dashboard_1.HeaderWidget(text, dashboard_1.HeaderLevel.SMALL), addToSummary ?? false, addToAlarm ?? false);
return this;
}
addWidget(widget, addToSummary, addToAlarm) {
this.addSegment(new dashboard_1.SingleWidgetDashboardSegment(widget, addToSummary, addToAlarm));
return this;
}
// MONITORING
// ==========
monitorApiGateway(props) {
const segment = new monitoring_1.ApiGatewayMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorApiGatewayV2HttpApi(props) {
const segment = new monitoring_1.ApiGatewayV2HttpApiMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorAppSyncApi(props) {
const segment = new monitoring_1.AppSyncMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorCertificate(props) {
const segment = new monitoring_1.CertificateManagerMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorCloudFrontDistribution(props) {
const segment = new monitoring_1.CloudFrontDistributionMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorCodeBuildProject(props) {
const segment = new monitoring_1.CodeBuildProjectMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorDocumentDbCluster(props) {
const segment = new monitoring_1.DocumentDbMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorDynamoTable(props) {
const segment = new monitoring_1.DynamoTableMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorDynamoTableGlobalSecondaryIndex(props) {
const segment = new monitoring_1.DynamoTableGlobalSecondaryIndexMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorEC2Instances(props) {
const segment = new monitoring_1.EC2Monitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorElasticsearchCluster(props) {
const segment = new monitoring_1.OpenSearchClusterMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorOpenSearchCluster(props) {
const segment = new monitoring_1.OpenSearchClusterMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorElastiCacheCluster(props) {
const segment = new monitoring_1.ElastiCacheClusterMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorGlueJob(props) {
const segment = new monitoring_1.GlueJobMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorFargateService(props) {
const segment = new monitoring_1.FargateServiceMonitoring(this, {
...props,
fargateService: props.fargateService.service,
loadBalancer: props.fargateService.loadBalancer,
targetGroup: props.fargateService.targetGroup,
});
this.addSegment(segment, props);
return this;
}
monitorSimpleFargateService(props) {
const segment = new monitoring_1.FargateServiceMonitoring(this, {
...props,
fargateService: props.fargateService,
});
this.addSegment(segment, props);
return this;
}
monitorFargateNetworkLoadBalancer(props) {
const segment = new monitoring_1.FargateServiceMonitoring(this, {
...props,
fargateService: props.fargateService,
loadBalancer: props.networkLoadBalancer,
targetGroup: props.networkTargetGroup,
});
this.addSegment(segment, props);
return this;
}
monitorFargateApplicationLoadBalancer(props) {
const segment = new monitoring_1.FargateServiceMonitoring(this, {
...props,
fargateService: props.fargateService,
loadBalancer: props.applicationLoadBalancer,
targetGroup: props.applicationTargetGroup,
});
this.addSegment(segment, props);
return this;
}
monitorEc2Service(props) {
const segment = new monitoring_1.Ec2ServiceMonitoring(this, {
...props,
ec2Service: props.ec2Service.service,
loadBalancer: props.ec2Service.loadBalancer,
targetGroup: props.ec2Service.targetGroup,
});
this.addSegment(segment, props);
return this;
}
monitorSimpleEc2Service(props) {
const segment = new monitoring_1.Ec2ServiceMonitoring(this, {
...props,
ec2Service: props.ec2Service,
});
this.addSegment(segment, props);
return this;
}
monitorEc2NetworkLoadBalancer(props) {
const segment = new monitoring_1.Ec2ServiceMonitoring(this, {
...props,
ec2Service: props.ec2Service,
loadBalancer: props.networkLoadBalancer,
targetGroup: props.networkTargetGroup,
});
this.addSegment(segment, props);
return this;
}
monitorEc2ApplicationLoadBalancer(props) {
const segment = new monitoring_1.Ec2ServiceMonitoring(this, {
...props,
ec2Service: props.ec2Service,
loadBalancer: props.applicationLoadBalancer,
targetGroup: props.applicationTargetGroup,
});
this.addSegment(segment, props);
return this;
}
monitorQueueProcessingFargateService(props) {
monitoring_1.getQueueProcessingFargateServiceMonitoring(this, props).forEach((segment) => this.addSegment(segment));
return this;
}
monitorQueueProcessingEc2Service(props) {
monitoring_1.getQueueProcessingEc2ServiceMonitoring(this, props).forEach((segment) => this.addSegment(segment));
return this;
}
monitorAutoScalingGroup(props) {
const segment = new monitoring_1.AutoScalingGroupMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorKinesisFirehose(props) {
const segment = new monitoring_1.KinesisFirehoseMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorKinesisDataStream(props) {
const segment = new monitoring_1.KinesisDataStreamMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorKinesisDataAnalytics(props) {
const segment = new monitoring_1.KinesisDataAnalyticsMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorLambdaFunction(props) {
const segment = new monitoring_1.LambdaFunctionMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorNetworkLoadBalancer(props) {
const segment = new monitoring_1.NetworkLoadBalancerMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorRdsCluster(props) {
const segment = new monitoring_1.RdsClusterMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorRedshiftCluster(props) {
const segment = new monitoring_1.RedshiftClusterMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorSecretsManagerSecret(props) {
const segment = new monitoring_1.SecretsManagerSecretMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorSnsTopic(props) {
const segment = new monitoring_1.SnsTopicMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorSqsQueue(props) {
const segment = new monitoring_1.SqsQueueMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorSqsQueueWithDlq(props) {
const segment = new monitoring_1.SqsQueueMonitoringWithDlq(this, props);
this.addSegment(segment, props);
return this;
}
monitorStepFunction(props) {
const segment = new monitoring_1.StepFunctionMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorStepFunctionActivity(props) {
const segment = new monitoring_1.StepFunctionActivityMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorStepFunctionLambdaIntegration(props) {
const segment = new monitoring_1.StepFunctionLambdaIntegrationMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorStepFunctionServiceIntegration(props) {
const segment = new monitoring_1.StepFunctionServiceIntegrationMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorS3Bucket(props) {
const segment = new monitoring_1.S3BucketMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorLog(props) {
const segment = new monitoring_1.LogMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorSyntheticsCanary(props) {
const segment = new monitoring_1.SyntheticsCanaryMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorWebApplicationFirewallAclV2(props) {
const segment = new monitoring_1.WafV2Monitoring(this, props);
this.addSegment(segment, props);
return this;
}
monitorBilling(props) {
const segment = new monitoring_1.BillingMonitoring(this, props ?? {});
this.addSegment(segment, props);
return this;
}
monitorCustom(props) {
const segment = new monitoring_1.CustomMonitoring(this, props);
this.addSegment(segment, props);
return this;
}
/**
* Monitor all the resources in the given scope.
* @param scope
* @param aspectProps
* @experimental
*/
monitorScope(scope, aspectProps) {
const aspect = new MonitoringAspect_1.MonitoringAspect(this, aspectProps);
aws_cdk_lib_1.Aspects.of(scope).add(aspect);
}
}
exports.MonitoringFacade = MonitoringFacade;
_a = JSII_RTTI_SYMBOL_1;
MonitoringFacade[_a] = { fqn: "cdk-monitoring-constructs.MonitoringFacade", version: "1.21.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9uaXRvcmluZ0ZhY2FkZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIk1vbml0b3JpbmdGYWNhZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNkM7QUFJN0Msc0NBVW1CO0FBQ25CLDRDQVVzQjtBQUN0Qiw4Q0FxRnVCO0FBQ3ZCLHlEQUE2RTtBQXNCN0U7O0dBRUc7QUFDSCxNQUFhLGdCQUFpQixTQUFRLHdCQUFlO0lBTW5ELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBNkI7UUFDckUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLENBQUMscUJBQXFCO1lBQ3hCLEtBQUssRUFBRSxxQkFBcUI7Z0JBQzVCLGdCQUFnQixDQUFDLCtCQUErQixFQUFFLENBQUM7UUFDckQsSUFBSSxDQUFDLG9CQUFvQjtZQUN2QixLQUFLLEVBQUUsb0JBQW9CO2dCQUMzQixnQkFBZ0IsQ0FBQyw4QkFBOEIsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsZ0JBQWdCO1lBQ25CLEtBQUssRUFBRSxnQkFBZ0I7Z0JBQ3ZCLGdCQUFnQixDQUFDLDBCQUEwQixDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUV4RCxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU8sTUFBTSxDQUFDLCtCQUErQjtRQUM1QyxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTyxNQUFNLENBQUMsOEJBQThCLENBQzNDLFdBQW1CO1FBRW5CLE9BQU87WUFDTCxlQUFlLEVBQUUsV0FBVztZQUM1QixjQUFjLEVBQUUsSUFBSTtTQUNyQixDQUFDO0lBQ0osQ0FBQztJQUVPLE1BQU0sQ0FBQywwQkFBMEIsQ0FDdkMsS0FBZ0IsRUFDaEIsV0FBbUI7UUFFbkIsT0FBTyxJQUFJLG1DQUF1QixDQUFDLEtBQUssRUFBRSxHQUFHLFdBQVcsYUFBYSxFQUFFO1lBQ3JFLG1C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SUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQTRCO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLElBQUksNkJBQWdCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsWUFBWSxDQUFDLEtBQWdCLEVBQUUsV0FBbUM7UUFDaEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxtQ0FBZ0IsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDdkQscUJBQU8sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2hDLENBQUM7O0FBaGpCSCw0Q0FpakJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXNwZWN0cywgU3RhY2sgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IENvbXBvc2l0ZUFsYXJtLCBEYXNoYm9hcmQsIElXaWRnZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbmltcG9ydCB7XG4gIEFkZENvbXBvc2l0ZUFsYXJtUHJvcHMsXG4gIEFsYXJtRmFjdG9yeSxcbiAgQWxhcm1GYWN0b3J5RGVmYXVsdHMsXG4gIEFsYXJtV2l0aEFubm90YXRpb24sXG4gIEF3c0NvbnNvbGVVcmxGYWN0b3J5LFxuICBNZXRyaWNGYWN0b3J5LFxuICBNZXRyaWNGYWN0b3J5RGVmYXVsdHMsXG4gIE1vbml0b3JpbmcsXG4gIE1vbml0b3JpbmdTY29wZSxcbn0gZnJvbSBcIi4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgRGVmYXVsdERhc2hib2FyZEZhY3RvcnksXG4gIERlZmF1bHRXaWRnZXRGYWN0b3J5LFxuICBIZWFkZXJMZXZlbCxcbiAgSGVhZGVyV2lkZ2V0LFxuICBJRGFzaGJvYXJkRmFjdG9yeSxcbiAgSURhc2hib2FyZFNlZ21lbnQsXG4gIElXaWRnZXRGYWN0b3J5LFxuICBNb25pdG9yaW5nRGFzaGJvYXJkc092ZXJyaWRlUHJvcHMsXG4gIFNpbmdsZVdpZGdldERhc2hib2FyZFNlZ21lbnQsXG59IGZyb20gXCIuLi9kYXNoYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFwaUdhdGV3YXlNb25pdG9yaW5nLFxuICBBcGlHYXRld2F5TW9uaXRvcmluZ1Byb3BzLFxuICBBcGlHYXRld2F5VjJIdHRwQXBpTW9uaXRvcmluZyxcbiAgQXBpR2F0ZXdheVYySHR0cEFwaU1vbml0b3JpbmdQcm9wcyxcbiAgQXBwU3luY01vbml0b3JpbmcsXG4gIEFwcFN5bmNNb25pdG9yaW5nUHJvcHMsXG4gIEF1dG9TY2FsaW5nR3JvdXBNb25pdG9yaW5nLFxuICBBdXRvU2NhbGluZ0dyb3VwTW9uaXRvcmluZ1Byb3BzLFxuICBCaWxsaW5nTW9uaXRvcmluZyxcbiAgQmlsbGluZ01vbml0b3JpbmdQcm9wcyxcbiAgQ2VydGlmaWNhdGVNYW5hZ2VyTW9uaXRvcmluZyxcbiAgQ2VydGlmaWNhdGVNYW5hZ2VyTW9uaXRvcmluZ1Byb3BzLFxuICBDbG91ZEZyb250RGlzdHJpYnV0aW9uTW9uaXRvcmluZyxcbiAgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbk1vbml0b3JpbmdQcm9wcyxcbiAgQ29kZUJ1aWxkUHJvamVjdE1vbml0b3JpbmcsXG4gIENvZGVCdWlsZFByb2plY3RNb25pdG9yaW5nUHJvcHMsXG4gIEN1c3RvbU1vbml0b3JpbmcsXG4gIEN1c3RvbU1vbml0b3JpbmdQcm9wcyxcbiAgRG9jdW1lbnREYk1vbml0b3JpbmcsXG4gIERvY3VtZW50RGJNb25pdG9yaW5nUHJvcHMsXG4gIER5bmFtb1RhYmxlR2xvYmFsU2Vjb25kYXJ5SW5kZXhNb25pdG9yaW5nLFxuICBEeW5hbW9UYWJsZUdsb2JhbFNlY29uZGFyeUluZGV4TW9uaXRvcmluZ1Byb3BzLFxuICBEeW5hbW9UYWJsZU1vbml0b3JpbmcsXG4gIER5bmFtb1RhYmxlTW9uaXRvcmluZ1Byb3BzLFxuICBFYzJBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1vbml0b3JpbmdQcm9wcyxcbiAgRUMyTW9uaXRvcmluZyxcbiAgRUMyTW9uaXRvcmluZ1Byb3BzLFxuICBFYzJOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzLFxuICBFYzJTZXJ2aWNlTW9uaXRvcmluZyxcbiAgRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyxcbiAgRWxhc3RpQ2FjaGVDbHVzdGVyTW9uaXRvcmluZyxcbiAgRWxhc3RpQ2FjaGVDbHVzdGVyTW9uaXRvcmluZ1Byb3BzLFxuICBGYXJnYXRlQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHMsXG4gIEZhcmdhdGVOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzLFxuICBGYXJnYXRlU2VydmljZU1vbml0b3JpbmcsXG4gIEZhcmdhdGVTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzLFxuICBnZXRRdWV1ZVByb2Nlc3NpbmdFYzJTZXJ2aWNlTW9uaXRvcmluZyxcbiAgZ2V0UXVldWVQcm9jZXNzaW5nRmFyZ2F0ZVNlcnZpY2VNb25pdG9yaW5nLFxuICBHbHVlSm9iTW9uaXRvcmluZyxcbiAgR2x1ZUpvYk1vbml0b3JpbmdQcm9wcyxcbiAgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLFxuICBLaW5lc2lzRGF0YUFuYWx5dGljc01vbml0b3JpbmdQcm9wcyxcbiAgS2luZXNpc0RhdGFTdHJlYW1Nb25pdG9yaW5nLFxuICBLaW5lc2lzRGF0YVN0cmVhbU1vbml0b3JpbmdQcm9wcyxcbiAgS2luZXNpc0ZpcmVob3NlTW9uaXRvcmluZyxcbiAgS2luZXNpc0ZpcmVob3NlTW9uaXRvcmluZ1Byb3BzLFxuICBMYW1iZGFGdW5jdGlvbk1vbml0b3JpbmcsXG4gIExhbWJkYUZ1bmN0aW9uTW9uaXRvcmluZ1Byb3BzLFxuICBMb2dNb25pdG9yaW5nLFxuICBMb2dNb25pdG9yaW5nUHJvcHMsXG4gIE5ldHdvcmtMb2FkQmFsYW5jZXJNb25pdG9yaW5nLFxuICBOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzLFxuICBPcGVuU2VhcmNoQ2x1c3Rlck1vbml0b3JpbmcsXG4gIE9wZW5TZWFyY2hDbHVzdGVyTW9uaXRvcmluZ1Byb3BzLFxuICBRdWV1ZVByb2Nlc3NpbmdFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzLFxuICBRdWV1ZVByb2Nlc3NpbmdGYXJnYXRlU2VydmljZU1vbml0b3JpbmdQcm9wcyxcbiAgUmRzQ2x1c3Rlck1vbml0b3JpbmcsXG4gIFJkc0NsdXN0ZXJNb25pdG9yaW5nUHJvcHMsXG4gIFJlZHNoaWZ0Q2x1c3Rlck1vbml0b3JpbmcsXG4gIFJlZHNoaWZ0Q2x1c3Rlck1vbml0b3JpbmdQcm9wcyxcbiAgUzNCdWNrZXRNb25pdG9yaW5nLFxuICBTM0J1Y2tldE1vbml0b3JpbmdQcm9wcyxcbiAgU2VjcmV0c01hbmFnZXJTZWNyZXRNb25pdG9yaW5nLFxuICBTZWNyZXRzTWFuYWdlclNlY3JldE1vbml0b3JpbmdQcm9wcyxcbiAgU2ltcGxlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyxcbiAgU2ltcGxlRmFyZ2F0ZVNlcnZpY2VNb25pdG9yaW5nUHJvcHMsXG4gIFNuc1RvcGljTW9uaXRvcmluZyxcbiAgU25zVG9waWNNb25pdG9yaW5nUHJvcHMsXG4gIFNxc1F1ZXVlTW9uaXRvcmluZyxcbiAgU3FzUXVldWVNb25pdG9yaW5nUHJvcHMsXG4gIFNxc1F1ZXVlTW9uaXRvcmluZ1dpdGhEbHEsXG4gIFNxc1F1ZXVlTW9uaXRvcmluZ1dpdGhEbHFQcm9wcyxcbiAgU3RlcEZ1bmN0aW9uQWN0aXZpdHlNb25pdG9yaW5nLFxuICBTdGVwRnVuY3Rpb25BY3Rpdml0eU1vbml0b3JpbmdQcm9wcyxcbiAgU3RlcEZ1bmN0aW9uTGFtYmRhSW50ZWdyYXRpb25Nb25pdG9yaW5nLFxuICBTdGVwRnVuY3Rpb25MYW1iZGFJbnRlZ3JhdGlvbk1vbml0b3JpbmdQcm9wcyxcbiAgU3RlcEZ1bmN0aW9uTW9uaXRvcmluZyxcbiAgU3RlcEZ1bmN0aW9uTW9uaXRvcmluZ1Byb3BzLFxuICBTdGVwRnVuY3Rpb25TZXJ2aWNlSW50ZWdyYXRpb25Nb25pdG9yaW5nLFxuICBTdGVwRnVuY3Rpb25TZXJ2aWNlSW50ZWdyYXRpb25Nb25pdG9yaW5nUHJvcHMsXG4gIFN5bnRoZXRpY3NDYW5hcnlNb25pdG9yaW5nLFxuICBTeW50aGV0aWNzQ2FuYXJ5TW9uaXRvcmluZ1Byb3BzLFxuICBXYWZWMk1vbml0b3JpbmcsXG4gIFdhZlYyTW9uaXRvcmluZ1Byb3BzLFxufSBmcm9tIFwiLi4vbW9uaXRvcmluZ1wiO1xuaW1wb3J0IHsgTW9uaXRvcmluZ0FzcGVjdCwgTW9uaXRvcmluZ0FzcGVjdFByb3BzIH0gZnJvbSBcIi4vTW9uaXRvcmluZ0FzcGVjdFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1vbml0b3JpbmdGYWNhZGVQcm9wcyB7XG4gIC8qKlxuICAgKiBEZWZhdWx0cyBmb3IgbWV0cmljIGZhY3RvcnkuXG4gICAqIEBkZWZhdWx0IC0gZW1wdHkgKG5vIHByZWZlcmVuY2VzKVxuICAgKi9cbiAgcmVhZG9ubHkgbWV0cmljRmFjdG9yeURlZmF1bHRzPzogTWV0cmljRmFjdG9yeURlZmF1bHRzO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0cyBmb3IgYWxhcm0gZmFjdG9yeS5cbiAgICogQGRlZmF1bHQgLSBhY3Rpb25zIGVuYWJsZWQsIGZhY2FkZSBsb2dpY2FsIElEIHVzZWQgYXMgZGVmYXVsdCBhbGFybSBuYW1lIHByZWZpeFxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1GYWN0b3J5RGVmYXVsdHM/OiBBbGFybUZhY3RvcnlEZWZhdWx0cztcblxuICAvKipcbiAgICogRGVmYXVsdHMgZm9yIGRhc2hib2FyZCBmYWN0b3J5LlxuICAgKiBAZGVmYXVsdCAtIGBEZWZhdWx0RGFzaGJvYXJkRmFjdG9yeWA7IGZhY2FkZSBsb2dpY2FsIElEIHVzZWQgYXMgZGVmYXVsdCBuYW1lXG4gICAqL1xuICByZWFkb25seSBkYXNoYm9hcmRGYWN0b3J5PzogSURhc2hib2FyZEZhY3Rvcnk7XG59XG5cbi8qKlxuICogTWFpbiBlbnRyeSBwb2ludCB0byBjcmVhdGUgeW91ciBtb25pdG9yaW5nLlxuICovXG5leHBvcnQgY2xhc3MgTW9uaXRvcmluZ0ZhY2FkZSBleHRlbmRzIE1vbml0b3JpbmdTY29wZSB7XG4gIHByb3RlY3RlZCByZWFkb25seSBtZXRyaWNGYWN0b3J5RGVmYXVsdHM6IE1ldHJpY0ZhY3RvcnlEZWZhdWx0cztcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFsYXJtRmFjdG9yeURlZmF1bHRzOiBBbGFybUZhY3RvcnlEZWZhdWx0cztcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRhc2hib2FyZEZhY3Rvcnk/OiBJRGFzaGJvYXJkRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNyZWF0ZWRTZWdtZW50czogSURhc2hib2FyZFNlZ21lbnRbXTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IE1vbml0b3JpbmdGYWNhZGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLm1ldHJpY0ZhY3RvcnlEZWZhdWx0cyA9XG4gICAgICBwcm9wcz8ubWV0cmljRmFjdG9yeURlZmF1bHRzID8/XG4gICAgICBNb25pdG9yaW5nRmFjYWRlLmdldERlZmF1bHRNZXRyaWNGYWN0b3J5RGVmYXVsdHMoKTtcbiAgICB0aGlzLmFsYXJtRmFjdG9yeURlZmF1bHRzID1cbiAgICAgIHByb3BzPy5hbGFybUZhY3RvcnlEZWZhdWx0cyA/P1xuICAgICAgTW9uaXRvcmluZ0ZhY2FkZS5nZXREZWZhdWx0QWxhcm1GYWN0b3J5RGVmYXVsdHMoaWQpO1xuICAgIHRoaXMuZGFzaGJvYXJkRmFjdG9yeSA9XG4gICAgICBwcm9wcz8uZGFzaGJvYXJkRmFjdG9yeSA/P1xuICAgICAgTW9uaXRvcmluZ0ZhY2FkZS5nZXREZWZhdWx0RGFzaGJvYXJkRmFjdG9yeSh0aGlzLCBpZCk7XG5cbiAgICB0aGlzLmNyZWF0ZWRTZWdtZW50cyA9IFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0RGVmYXVsdE1ldHJpY0ZhY3RvcnlEZWZhdWx0cygpOiBNZXRyaWNGYWN0b3J5RGVmYXVsdHMge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldERlZmF1bHRBbGFybUZhY3RvcnlEZWZhdWx0cyhcbiAgICBkZWZhdWx0TmFtZTogc3RyaW5nXG4gICk6IEFsYXJtRmFjdG9yeURlZmF1bHRzIHtcbiAgICByZXR1cm4ge1xuICAgICAgYWxhcm1OYW1lUHJlZml4OiBkZWZhdWx0TmFtZSxcbiAgICAgIGFjdGlvbnNFbmFibGVkOiB0cnVlLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXREZWZhdWx0RGFzaGJvYXJkRmFjdG9yeShcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGRlZmF1bHROYW1lOiBzdHJpbmdcbiAgKTogSURhc2hib2FyZEZhY3Rvcnkge1xuICAgIHJldHVybiBuZXcgRGVmYXVsdERhc2hib2FyZEZhY3Rvcnkoc2NvcGUsIGAke2RlZmF1bHROYW1lfS1EYXNoYm9hcmRzYCwge1xuICAgICAgZGFzaGJvYXJkTmFtZVByZWZpeDogZGVmYXVsdE5hbWUsXG4gICAgfSk7XG4gIH1cblxuICAvLyBGQUNUT1JJRVNcbiAgLy8gPT09PT09PT09XG5cbiAgY3JlYXRlQWxhcm1GYWN0b3J5KGFsYXJtTmFtZVByZWZpeDogc3RyaW5nKTogQWxhcm1GYWN0b3J5IHtcbiAgICByZXR1cm4gbmV3IEFsYXJtRmFjdG9yeSh0aGlzLCB7XG4gICAgICBnbG9iYWxBbGFybURlZmF1bHRzOiB0aGlzLmFsYXJtRmFjdG9yeURlZmF1bHRzLFxuICAgICAgZ2xvYmFsTWV0cmljRGVmYXVsdHM6IHRoaXMubWV0cmljRmFjdG9yeURlZmF1bHRzLFxuICAgICAgbG9jYWxBbGFybU5hbWVQcmVmaXg6IGFsYXJtTmFtZVByZWZpeCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUF3c0NvbnNvbGVVcmxGYWN0b3J5KCk6IEF3c0NvbnNvbGVVcmxGYWN0b3J5IHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IGF3c0FjY291bnRJZCA9IHN0YWNrLmFjY291bnQ7XG4gICAgY29uc3QgYXdzQWNjb3VudFJlZ2lvbiA9IHN0YWNrLnJlZ2lvbjtcbiAgICByZXR1cm4gbmV3IEF3c0NvbnNvbGVVcmxGYWN0b3J5KHsgYXdzQWNjb3VudFJlZ2lvbiwgYXdzQWNjb3VudElkIH0pO1xuICB9XG5cbiAgY3JlYXRlTWV0cmljRmFjdG9yeSgpOiBNZXRyaWNGYWN0b3J5IHtcbiAgICByZXR1cm4gbmV3IE1ldHJpY0ZhY3RvcnkoeyBnbG9iYWxEZWZhdWx0czogdGhpcy5tZXRyaWNGYWN0b3J5RGVmYXVsdHMgfSk7XG4gIH1cblxuICBjcmVhdGVXaWRnZXRGYWN0b3J5KCk6IElXaWRnZXRGYWN0b3J5IHtcbiAgICByZXR1cm4gbmV3IERlZmF1bHRXaWRnZXRGYWN0b3J5KCk7XG4gIH1cblxuICAvLyBHRU5FUklDXG4gIC8vID09PT09PT1cblxuICBjcmVhdGVkRGFzaGJvYXJkKCk6IERhc2hib2FyZCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZGFzaGJvYXJkRmFjdG9yeT8uY3JlYXRlZERhc2hib2FyZCgpO1xuICB9XG5cbiAgY3JlYXRlZFN1bW1hcnlEYXNoYm9hcmQoKTogRGFzaGJvYXJkIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5kYXNoYm9hcmRGYWN0b3J5Py5jcmVhdGVkU3VtbWFyeURhc2hib2FyZCgpO1xuICB9XG5cbiAgY3JlYXRlZEFsYXJtRGFzaGJvYXJkKCk6IERhc2hib2FyZCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZGFzaGJvYXJkRmFjdG9yeT8uY3JlYXRlZEFsYXJtRGFzaGJvYXJkKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3JlYXRlZCBhbGFybXMgYWNyb3NzIGFsbCB0aGUgbW9uaXRvcmluZ3MgYWRkZWQgdXAgdW50aWwgbm93LlxuICAgKi9cbiAgY3JlYXRlZEFsYXJtcygpOiBBbGFybVdpdGhBbm5vdGF0aW9uW10ge1xuICAgIGNvbnN0IGFsYXJtczogQWxhcm1XaXRoQW5ub3RhdGlvbltdID0gW107XG4gICAgdGhpcy5jcmVhdGVkU2VnbWVudHMuZm9yRWFjaCgobW9uaXRvcmluZykgPT4ge1xuICAgICAgaWYgKG1vbml0b3JpbmcgaW5zdGFuY2VvZiBNb25pdG9yaW5nKSB7XG4gICAgICAgIGFsYXJtcy5wdXNoKC4uLm1vbml0b3JpbmcuY3JlYXRlZEFsYXJtcygpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYWxhcm1zO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdWJzZXQgb2YgY3JlYXRlZCBhbGFybXMgdGhhdCBhcmUgbWFya2VkIGJ5IGEgc3BlY2lmaWMgY3VzdG9tIHRhZy5cbiAgICogQHBhcmFtIGN1c3RvbVRhZyB0YWcgdG8gZmlsdGVyIGFsYXJtcyBieVxuICAgKi9cbiAgY3JlYXRlZEFsYXJtc1dpdGhUYWcoY3VzdG9tVGFnOiBzdHJpbmcpOiBBbGFybVdpdGhBbm5vdGF0aW9uW10ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZWRBbGFybXMoKS5maWx0ZXIoKGFsYXJtKSA9PlxuICAgICAgYWxhcm0uY3VzdG9tVGFncz8uaW5jbHVkZXMoY3VzdG9tVGFnKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN1YnNldCBvZiBjcmVhdGVkIGFsYXJtcyB0aGF0IGFyZSBtYXJrZWQgYnkgYSBzcGVjaWZpYyBkaXNhbWJpZ3VhdG9yLlxuICAgKiBAcGFyYW0gZGlzYW1iaWd1YXRvciBkaXNhbWJpZ3VhdG9yIHRvIGZpbHRlciBhbGFybXMgYnlcbiAgICovXG4gIGNyZWF0ZWRBbGFybXNXaXRoRGlzYW1iaWd1YXRvcihkaXNhbWJpZ3VhdG9yOiBzdHJpbmcpOiBBbGFybVdpdGhBbm5vdGF0aW9uW10ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZWRBbGFybXMoKS5maWx0ZXIoXG4gICAgICAoYWxhcm0pID0+IGFsYXJtLmRpc2FtYmlndWF0b3IgPT09IGRpc2FtYmlndWF0b3JcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIGEgc3Vic2V0IG9mIGNyZWF0ZWQgYWxhcm1zIHRoYXQgYXJlIG1hcmtlZCBieSBhIHNwZWNpZmljIGN1c3RvbSB0YWcgYW5kIGNyZWF0ZXMgYSBjb21wb3NpdGUgYWxhcm0uXG4gICAqIFRoaXMgY29tcG9zaXRlIGFsYXJtIGlzIGNyZWF0ZWQgd2l0aCBhbiAnT1InIGNvbmRpdGlvbiwgc28gaXQgdHJpZ2dlcnMgd2l0aCBhbnkgY2hpbGQgYWxhcm0uXG4gICAqIE5PVEU6IFRoaXMgY29tcG9zaXRlIGFsYXJtIGlzIG5vdCBhZGRlZCBhbW9uZyBvdGhlciBhbGFybXMsIHNvIGl0IGlzIG5vdCByZXR1cm5lZCBieSBjcmVhdGVkQWxhcm1zKCkgY2FsbHMuXG4gICAqXG4gICAqIEBwYXJhbSBjdXN0b21UYWcgdGFnIHRvIGZpbHRlciBhbGFybXMgYnlcbiAgICogQHBhcmFtIHByb3BzIGN1c3RvbWl6YXRpb24gb3B0aW9uc1xuICAgKi9cbiAgY3JlYXRlQ29tcG9zaXRlQWxhcm1Vc2luZ1RhZyhcbiAgICBjdXN0b21UYWc6IHN0cmluZyxcbiAgICBwcm9wcz86IEFkZENvbXBvc2l0ZUFsYXJtUHJvcHNcbiAgKTogQ29tcG9zaXRlQWxhcm0gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFsYXJtcyA9IHRoaXMuY3JlYXRlZEFsYXJtc1dpdGhUYWcoY3VzdG9tVGFnKTtcbiAgICBpZiAoYWxhcm1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGRpc2FtYmlndWF0b3IgPSBwcm9wcz8uZGlzYW1iaWd1YXRvciA/PyBjdXN0b21UYWc7XG4gICAgICBjb25zdCBhbGFybUZhY3RvcnkgPSB0aGlzLmNyZWF0ZUFsYXJtRmFjdG9yeShcIkNvbXBvc2l0ZVwiKTtcbiAgICAgIHJldHVybiBhbGFybUZhY3RvcnkuYWRkQ29tcG9zaXRlQWxhcm0oYWxhcm1zLCB7XG4gICAgICAgIC4uLihwcm9wcyA/PyB7fSksXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBhIHN1YnNldCBvZiBjcmVhdGVkIGFsYXJtcyB0aGF0IGFyZSBtYXJrZWQgYnkgYSBzcGVjaWZpYyBkaXNhbWJpZ3VhdG9yIGFuZCBjcmVhdGVzIGEgY29tcG9zaXRlIGFsYXJtLlxuICAgKiBUaGlzIGNvbXBvc2l0ZSBhbGFybSBpcyBjcmVhdGVkIHdpdGggYW4gJ09SJyBjb25kaXRpb24sIHNvIGl0IHRyaWdnZXJzIHdpdGggYW55IGNoaWxkIGFsYXJtLlxuICAgKiBOT1RFOiBUaGlzIGNvbXBvc2l0ZSBhbGFybSBpcyBub3QgYWRkZWQgYW1vbmcgb3RoZXIgYWxhcm1zLCBzbyBpdCBpcyBub3QgcmV0dXJuZWQgYnkgY3JlYXRlZEFsYXJtcygpIGNhbGxzLlxuICAgKlxuICAgKiBAcGFyYW0gYWxhcm1EaXNhbWJpZ3VhdG9yIGRpc2FtYmlndWF0b3IgdG8gZmlsdGVyIGFsYXJtcyBieVxuICAgKiBAcGFyYW0gcHJvcHMgY3VzdG9taXphdGlvbiBvcHRpb25zXG4gICAqL1xuICBjcmVhdGVDb21wb3NpdGVBbGFybVVzaW5nRGlzYW1iaWd1YXRvcihcbiAgICBhbGFybURpc2FtYmlndWF0b3I6IHN0cmluZyxcbiAgICBwcm9wcz86IEFkZENvbXBvc2l0ZUFsYXJtUHJvcHNcbiAgKTogQ29tcG9zaXRlQWxhcm0gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFsYXJtcyA9IHRoaXMuY3JlYXRlZEFsYXJtc1dpdGhEaXNhbWJpZ3VhdG9yKGFsYXJtRGlzYW1iaWd1YXRvcik7XG4gICAgaWYgKGFsYXJtcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBkaXNhbWJpZ3VhdG9yID0gcHJvcHM/LmRpc2FtYmlndWF0b3IgPz8gYWxhcm1EaXNhbWJpZ3VhdG9yO1xuICAgICAgY29uc3QgYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXCJDb21wb3NpdGVcIik7XG4gICAgICByZXR1cm4gYWxhcm1GYWN0b3J5LmFkZENvbXBvc2l0ZUFsYXJtKGFsYXJtcywge1xuICAgICAgICAuLi4ocHJvcHMgPz8ge30pLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3JlYXRlZCBtb25pdG9yaW5ncyBhZGRlZCB1cCB1bnRpbCBub3cuXG4gICAqL1xuICBjcmVhdGVkTW9uaXRvcmluZ3MoKTogTW9uaXRvcmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVkU2VnbWVudHNcbiAgICAgIC5maWx0ZXIoKHMpID0+IHMgaW5zdGFuY2VvZiBNb25pdG9yaW5nKVxuICAgICAgLm1hcCgocykgPT4gcyBhcyBNb25pdG9yaW5nKTtcbiAgfVxuXG4gIGFkZFNlZ21lbnQoXG4gICAgc2VnbWVudDogSURhc2hib2FyZFNlZ21lbnQsXG4gICAgb3ZlcnJpZGVQcm9wcz86IE1vbml0b3JpbmdEYXNoYm9hcmRzT3ZlcnJpZGVQcm9wc1xuICApIHtcbiAgICB0aGlzLmRhc2hib2FyZEZhY3Rvcnk/LmFkZFNlZ21lbnQoeyBzZWdtZW50LCBvdmVycmlkZVByb3BzIH0pO1xuICAgIHRoaXMuY3JlYXRlZFNlZ21lbnRzLnB1c2goc2VnbWVudCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBhZGRMYXJnZUhlYWRlcih0ZXh0OiBzdHJpbmcsIGFkZFRvU3VtbWFyeT86IGJvb2xlYW4sIGFkZFRvQWxhcm0/OiBib29sZWFuKSB7XG4gICAgdGhpcy5hZGRXaWRnZXQoXG4gICAgICBuZXcgSGVhZGVyV2lkZ2V0KHRleHQsIEhlYWRlckxldmVsLkxBUkdFKSxcbiAgICAgIGFkZFRvU3VtbWFyeSA/PyBmYWxzZSxcbiAgICAgIGFkZFRvQWxhcm0gPz8gZmFsc2VcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkTWVkaXVtSGVhZGVyKHRleHQ6IHN0cmluZywgYWRkVG9TdW1tYXJ5PzogYm9vbGVhbiwgYWRkVG9BbGFybT86IGJvb2xlYW4pIHtcbiAgICB0aGlzLmFkZFdpZGdldChcbiAgICAgIG5ldyBIZWFkZXJXaWRnZXQodGV4dCwgSGVhZGVyTGV2ZWwuTUVESVVNKSxcbiAgICAgIGFkZFRvU3VtbWFyeSA/PyBmYWxzZSxcbiAgICAgIGFkZFRvQWxhcm0gPz8gZmFsc2VcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkU21hbGxIZWFkZXIodGV4dDogc3RyaW5nLCBhZGRUb1N1bW1hcnk/OiBib29sZWFuLCBhZGRUb0FsYXJtPzogYm9vbGVhbikge1xuICAgIHRoaXMuYWRkV2lkZ2V0KFxuICAgICAgbmV3IEhlYWRlcldpZGdldCh0ZXh0LCBIZWFkZXJMZXZlbC5TTUFMTCksXG4gICAgICBhZGRUb1N1bW1hcnkgPz8gZmFsc2UsXG4gICAgICBhZGRUb0FsYXJtID8/IGZhbHNlXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZFdpZGdldCh3aWRnZXQ6IElXaWRnZXQsIGFkZFRvU3VtbWFyeT86IGJvb2xlYW4sIGFkZFRvQWxhcm0/OiBib29sZWFuKSB7XG4gICAgdGhpcy5hZGRTZWdtZW50KFxuICAgICAgbmV3IFNpbmdsZVdpZGdldERhc2hib2FyZFNlZ21lbnQod2lkZ2V0LCBhZGRUb1N1bW1hcnksIGFkZFRvQWxhcm0pXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIE1PTklUT1JJTkdcbiAgLy8gPT09PT09PT09PVxuXG4gIG1vbml0b3JBcGlHYXRld2F5KHByb3BzOiBBcGlHYXRld2F5TW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBBcGlHYXRld2F5TW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JBcGlHYXRld2F5VjJIdHRwQXBpKHByb3BzOiBBcGlHYXRld2F5VjJIdHRwQXBpTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBBcGlHYXRld2F5VjJIdHRwQXBpTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JBcHBTeW5jQXBpKHByb3BzOiBBcHBTeW5jTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBBcHBTeW5jTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JDZXJ0aWZpY2F0ZShwcm9wczogQ2VydGlmaWNhdGVNYW5hZ2VyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBDZXJ0aWZpY2F0ZU1hbmFnZXJNb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvckNsb3VkRnJvbnREaXN0cmlidXRpb24ocHJvcHM6IENsb3VkRnJvbnREaXN0cmlidXRpb25Nb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IENsb3VkRnJvbnREaXN0cmlidXRpb25Nb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvckNvZGVCdWlsZFByb2plY3QocHJvcHM6IENvZGVCdWlsZFByb2plY3RNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IENvZGVCdWlsZFByb2plY3RNb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvckRvY3VtZW50RGJDbHVzdGVyKHByb3BzOiBEb2N1bWVudERiTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBEb2N1bWVudERiTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JEeW5hbW9UYWJsZShwcm9wczogRHluYW1vVGFibGVNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IER5bmFtb1RhYmxlTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JEeW5hbW9UYWJsZUdsb2JhbFNlY29uZGFyeUluZGV4KFxuICAgIHByb3BzOiBEeW5hbW9UYWJsZUdsb2JhbFNlY29uZGFyeUluZGV4TW9uaXRvcmluZ1Byb3BzXG4gICkge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgRHluYW1vVGFibGVHbG9iYWxTZWNvbmRhcnlJbmRleE1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yRUMySW5zdGFuY2VzKHByb3BzOiBFQzJNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEVDMk1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yRWxhc3RpY3NlYXJjaENsdXN0ZXIocHJvcHM6IE9wZW5TZWFyY2hDbHVzdGVyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBPcGVuU2VhcmNoQ2x1c3Rlck1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yT3BlblNlYXJjaENsdXN0ZXIocHJvcHM6IE9wZW5TZWFyY2hDbHVzdGVyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBPcGVuU2VhcmNoQ2x1c3Rlck1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yRWxhc3RpQ2FjaGVDbHVzdGVyKHByb3BzOiBFbGFzdGlDYWNoZUNsdXN0ZXJNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEVsYXN0aUNhY2hlQ2x1c3Rlck1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yR2x1ZUpvYihwcm9wczogR2x1ZUpvYk1vbml0b3JpbmdQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgR2x1ZUpvYk1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yRmFyZ2F0ZVNlcnZpY2UocHJvcHM6IEZhcmdhdGVTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBGYXJnYXRlU2VydmljZU1vbml0b3JpbmcodGhpcywge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYXJnYXRlU2VydmljZTogcHJvcHMuZmFyZ2F0ZVNlcnZpY2Uuc2VydmljZSxcbiAgICAgIGxvYWRCYWxhbmNlcjogcHJvcHMuZmFyZ2F0ZVNlcnZpY2UubG9hZEJhbGFuY2VyLFxuICAgICAgdGFyZ2V0R3JvdXA6IHByb3BzLmZhcmdhdGVTZXJ2aWNlLnRhcmdldEdyb3VwLFxuICAgIH0pO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yU2ltcGxlRmFyZ2F0ZVNlcnZpY2UocHJvcHM6IFNpbXBsZUZhcmdhdGVTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBGYXJnYXRlU2VydmljZU1vbml0b3JpbmcodGhpcywge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYXJnYXRlU2VydmljZTogcHJvcHMuZmFyZ2F0ZVNlcnZpY2UsXG4gICAgfSk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JGYXJnYXRlTmV0d29ya0xvYWRCYWxhbmNlcihcbiAgICBwcm9wczogRmFyZ2F0ZU5ldHdvcmtMb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBGYXJnYXRlU2VydmljZU1vbml0b3JpbmcodGhpcywge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYXJnYXRlU2VydmljZTogcHJvcHMuZmFyZ2F0ZVNlcnZpY2UsXG4gICAgICBsb2FkQmFsYW5jZXI6IHByb3BzLm5ldHdvcmtMb2FkQmFsYW5jZXIsXG4gICAgICB0YXJnZXRHcm91cDogcHJvcHMubmV0d29ya1RhcmdldEdyb3VwLFxuICAgIH0pO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yRmFyZ2F0ZUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKFxuICAgIHByb3BzOiBGYXJnYXRlQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBGYXJnYXRlU2VydmljZU1vbml0b3JpbmcodGhpcywge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYXJnYXRlU2VydmljZTogcHJvcHMuZmFyZ2F0ZVNlcnZpY2UsXG4gICAgICBsb2FkQmFsYW5jZXI6IHByb3BzLmFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLFxuICAgICAgdGFyZ2V0R3JvdXA6IHByb3BzLmFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gICAgfSk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JFYzJTZXJ2aWNlKHByb3BzOiBFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBFYzJTZXJ2aWNlTW9uaXRvcmluZyh0aGlzLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGVjMlNlcnZpY2U6IHByb3BzLmVjMlNlcnZpY2Uuc2VydmljZSxcbiAgICAgIGxvYWRCYWxhbmNlcjogcHJvcHMuZWMyU2VydmljZS5sb2FkQmFsYW5jZXIsXG4gICAgICB0YXJnZXRHcm91cDogcHJvcHMuZWMyU2VydmljZS50YXJnZXRHcm91cCxcbiAgICB9KTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvclNpbXBsZUVjMlNlcnZpY2UocHJvcHM6IFNpbXBsZUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEVjMlNlcnZpY2VNb25pdG9yaW5nKHRoaXMsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZWMyU2VydmljZTogcHJvcHMuZWMyU2VydmljZSxcbiAgICB9KTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvckVjMk5ldHdvcmtMb2FkQmFsYW5jZXIocHJvcHM6IEVjMk5ldHdvcmtMb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEVjMlNlcnZpY2VNb25pdG9yaW5nKHRoaXMsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZWMyU2VydmljZTogcHJvcHMuZWMyU2VydmljZSxcbiAgICAgIGxvYWRCYWxhbmNlcjogcHJvcHMubmV0d29ya0xvYWRCYWxhbmNlcixcbiAgICAgIHRhcmdldEdyb3VwOiBwcm9wcy5uZXR3b3JrVGFyZ2V0R3JvdXAsXG4gICAgfSk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JFYzJBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcihcbiAgICBwcm9wczogRWMyQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBFYzJTZXJ2aWNlTW9uaXRvcmluZyh0aGlzLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGVjMlNlcnZpY2U6IHByb3BzLmVjMlNlcnZpY2UsXG4gICAgICBsb2FkQmFsYW5jZXI6IHByb3BzLmFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLFxuICAgICAgdGFyZ2V0R3JvdXA6IHByb3BzLmFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gICAgfSk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JRdWV1ZVByb2Nlc3NpbmdGYXJnYXRlU2VydmljZShcbiAgICBwcm9wczogUXVldWVQcm9jZXNzaW5nRmFyZ2F0ZVNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgZ2V0UXVldWVQcm9jZXNzaW5nRmFyZ2F0ZVNlcnZpY2VNb25pdG9yaW5nKHRoaXMsIHByb3BzKS5mb3JFYWNoKChzZWdtZW50KSA9PlxuICAgICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQpXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JRdWV1ZVByb2Nlc3NpbmdFYzJTZXJ2aWNlKFxuICAgIHByb3BzOiBRdWV1ZVByb2Nlc3NpbmdFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzXG4gICkge1xuICAgIGdldFF1ZXVlUHJvY2Vzc2luZ0VjMlNlcnZpY2VNb25pdG9yaW5nKHRoaXMsIHByb3BzKS5mb3JFYWNoKChzZWdtZW50KSA9PlxuICAgICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQpXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JBdXRvU2NhbGluZ0dyb3VwKHByb3BzOiBBdXRvU2NhbGluZ0dyb3VwTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBBdXRvU2NhbGluZ0dyb3VwTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JLaW5lc2lzRmlyZWhvc2UocHJvcHM6IEtpbmVzaXNGaXJlaG9zZU1vbml0b3JpbmdQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgS2luZXNpc0ZpcmVob3NlTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JLaW5lc2lzRGF0YVN0cmVhbShwcm9wczogS2luZXNpc0RhdGFTdHJlYW1Nb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEtpbmVzaXNEYXRhU3RyZWFtTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JLaW5lc2lzRGF0YUFuYWx5dGljcyhwcm9wczogS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEtpbmVzaXNEYXRhQW5hbHl0aWNzTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JMYW1iZGFGdW5jdGlvbihwcm9wczogTGFtYmRhRnVuY3Rpb25Nb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IExhbWJkYUZ1bmN0aW9uTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JOZXR3b3JrTG9hZEJhbGFuY2VyKHByb3BzOiBOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JSZHNDbHVzdGVyKHByb3BzOiBSZHNDbHVzdGVyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBSZHNDbHVzdGVyTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JSZWRzaGlmdENsdXN0ZXIocHJvcHM6IFJlZHNoaWZ0Q2x1c3Rlck1vbml0b3JpbmdQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgUmVkc2hpZnRDbHVzdGVyTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTZWNyZXRzTWFuYWdlclNlY3JldChwcm9wczogU2VjcmV0c01hbmFnZXJTZWNyZXRNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IFNlY3JldHNNYW5hZ2VyU2VjcmV0TW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTbnNUb3BpYyhwcm9wczogU25zVG9waWNNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IFNuc1RvcGljTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTcXNRdWV1ZShwcm9wczogU3FzUXVldWVNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IFNxc1F1ZXVlTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTcXNRdWV1ZVdpdGhEbHEocHJvcHM6IFNxc1F1ZXVlTW9uaXRvcmluZ1dpdGhEbHFQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgU3FzUXVldWVNb25pdG9yaW5nV2l0aERscSh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTdGVwRnVuY3Rpb24ocHJvcHM6IFN0ZXBGdW5jdGlvbk1vbml0b3JpbmdQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgU3RlcEZ1bmN0aW9uTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTdGVwRnVuY3Rpb25BY3Rpdml0eShwcm9wczogU3RlcEZ1bmN0aW9uQWN0aXZpdHlNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IFN0ZXBGdW5jdGlvbkFjdGl2aXR5TW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JTdGVwRnVuY3Rpb25MYW1iZGFJbnRlZ3JhdGlvbihcbiAgICBwcm9wczogU3RlcEZ1bmN0aW9uTGFtYmRhSW50ZWdyYXRpb25Nb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBTdGVwRnVuY3Rpb25MYW1iZGFJbnRlZ3JhdGlvbk1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yU3RlcEZ1bmN0aW9uU2VydmljZUludGVncmF0aW9uKFxuICAgIHByb3BzOiBTdGVwRnVuY3Rpb25TZXJ2aWNlSW50ZWdyYXRpb25Nb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBTdGVwRnVuY3Rpb25TZXJ2aWNlSW50ZWdyYXRpb25Nb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvclMzQnVja2V0KHByb3BzOiBTM0J1Y2tldE1vbml0b3JpbmdQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgUzNCdWNrZXRNb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvckxvZyhwcm9wczogTG9nTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IG5ldyBMb2dNb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvclN5bnRoZXRpY3NDYW5hcnkocHJvcHM6IFN5bnRoZXRpY3NDYW5hcnlNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IFN5bnRoZXRpY3NDYW5hcnlNb25pdG9yaW5nKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLmFkZFNlZ21lbnQoc2VnbWVudCwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbW9uaXRvcldlYkFwcGxpY2F0aW9uRmlyZXdhbGxBY2xWMihwcm9wczogV2FmVjJNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IFdhZlYyTW9uaXRvcmluZyh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRTZWdtZW50KHNlZ21lbnQsIHByb3BzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIG1vbml0b3JCaWxsaW5nKHByb3BzPzogQmlsbGluZ01vbml0b3JpbmdQcm9wcykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBuZXcgQmlsbGluZ01vbml0b3JpbmcodGhpcywgcHJvcHMgPz8ge30pO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBtb25pdG9yQ3VzdG9tKHByb3BzOiBDdXN0b21Nb25pdG9yaW5nUHJvcHMpIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbmV3IEN1c3RvbU1vbml0b3JpbmcodGhpcywgcHJvcHMpO1xuICAgIHRoaXMuYWRkU2VnbWVudChzZWdtZW50LCBwcm9wcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogTW9uaXRvciBhbGwgdGhlIHJlc291cmNlcyBpbiB0aGUgZ2l2ZW4gc2NvcGUuXG4gICAqIEBwYXJhbSBzY29wZVxuICAgKiBAcGFyYW0gYXNwZWN0UHJvcHNcbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKi9cbiAgbW9uaXRvclNjb3BlKHNjb3BlOiBDb25zdHJ1Y3QsIGFzcGVjdFByb3BzPzogTW9uaXRvcmluZ0FzcGVjdFByb3BzKSB7XG4gICAgY29uc3QgYXNwZWN0ID0gbmV3IE1vbml0b3JpbmdBc3BlY3QodGhpcywgYXNwZWN0UHJvcHMpO1xuICAgIEFzcGVjdHMub2Yoc2NvcGUpLmFkZChhc3BlY3QpO1xuICB9XG59XG4iXX0=