cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
378 lines • 48.5 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MonitoringAspect = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const apigw = require("aws-cdk-lib/aws-apigateway");
const apigwv2 = require("aws-cdk-lib/aws-apigatewayv2");
const appsync = require("aws-cdk-lib/aws-appsync");
const autoscaling = require("aws-cdk-lib/aws-autoscaling");
const acm = require("aws-cdk-lib/aws-certificatemanager");
const cloudfront = require("aws-cdk-lib/aws-cloudfront");
const codebuild = require("aws-cdk-lib/aws-codebuild");
const docdb = require("aws-cdk-lib/aws-docdb");
const dynamodb = require("aws-cdk-lib/aws-dynamodb");
const elasticsearch = require("aws-cdk-lib/aws-elasticsearch");
const glue = require("aws-cdk-lib/aws-glue");
const kinesis = require("aws-cdk-lib/aws-kinesis");
const kinesisanalytics = require("aws-cdk-lib/aws-kinesisanalytics");
const kinesisfirehose = require("aws-cdk-lib/aws-kinesisfirehose");
const lambda = require("aws-cdk-lib/aws-lambda");
const opensearch = require("aws-cdk-lib/aws-opensearchservice");
const rds = require("aws-cdk-lib/aws-rds");
const aws_redshift_1 = require("aws-cdk-lib/aws-redshift");
const s3 = require("aws-cdk-lib/aws-s3");
const secretsmanager = require("aws-cdk-lib/aws-secretsmanager");
const sns = require("aws-cdk-lib/aws-sns");
const sqs = require("aws-cdk-lib/aws-sqs");
const stepfunctions = require("aws-cdk-lib/aws-stepfunctions");
const synthetics = require("aws-cdk-lib/aws-synthetics");
const wafv2 = require("aws-cdk-lib/aws-wafv2");
const monitoring_1 = require("../monitoring");
/**
* A CDK aspect that adds support for monitoring all resources within scope.
*/
class MonitoringAspect {
constructor(monitoringFacade, props = {}) {
this.monitoringFacade = monitoringFacade;
this.props = props;
/**
* Whether or not we've added a monitoring to the scope for node independent monitorings.
*/
this.addedNodeIndependentMonitoringToScope = false;
}
visit(node) {
this.monitorAcm(node);
this.monitorApiGateway(node);
this.monitorApiGatewayV2(node);
this.monitorAppSync(node);
this.monitorAuroraCluster(node);
this.monitorAutoScalingGroup(node);
this.monitorCloudFront(node);
this.monitorCodeBuild(node);
this.monitorDocumentDb(node);
this.monitorDynamoDb(node);
this.monitorGlue(node);
this.monitorKinesisAnalytics(node);
this.monitorKinesisDataStream(node);
this.monitorKinesisFirehose(node);
this.monitorLambda(node);
this.monitorOpenSearch(node);
this.monitorRdsCluster(node);
this.monitorRdsInstance(node);
this.monitorRedshift(node);
this.monitorS3(node);
this.monitorSecretsManager(node);
this.monitorSns(node);
this.monitorSqs(node);
this.monitorStepFunctions(node);
this.monitorSyntheticsCanaries(node);
this.monitorWebApplicationFirewallV2Acls(node);
if (!this.addedNodeIndependentMonitoringToScope) {
this.addedNodeIndependentMonitoringToScope = true;
this.monitorEc2();
this.monitorBilling();
this.monitorElasticCache();
}
}
getMonitoringDetails(aspectOptions) {
const isEnabled = aspectOptions?.enabled ?? true;
const props = aspectOptions?.props;
return [isEnabled, props];
}
monitorAcm(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.acm);
if (isEnabled && node instanceof acm.Certificate) {
this.monitoringFacade.monitorCertificate({
certificate: node,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorApiGateway(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.apiGateway);
if (isEnabled && node instanceof apigw.RestApi) {
this.monitoringFacade.monitorApiGateway({
api: node,
apiStage: node.deploymentStage.stageName,
...props,
});
}
}
monitorApiGatewayV2(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.apiGatewayV2);
if (isEnabled && node instanceof apigwv2.HttpApi) {
this.monitoringFacade.monitorApiGatewayV2HttpApi({
api: node,
...props,
});
}
}
monitorAppSync(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.appSync);
if (isEnabled && node instanceof appsync.GraphqlApi) {
this.monitoringFacade.monitorAppSyncApi({
api: node,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorAuroraCluster(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.auroraCluster);
if (isEnabled && node instanceof rds.ServerlessCluster) {
this.monitoringFacade.monitorAuroraCluster({
cluster: node,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorAutoScalingGroup(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.autoScalingGroup);
if (isEnabled && node instanceof autoscaling.AutoScalingGroup) {
this.monitoringFacade.monitorAutoScalingGroup({
autoScalingGroup: node,
...props,
});
}
}
monitorBilling() {
const [isEnabled, props] = this.getMonitoringDetails(this.props.billing);
if (isEnabled) {
this.monitoringFacade.monitorBilling({
...props,
alarmFriendlyName: "Billing",
});
}
}
monitorCloudFront(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.cloudFront);
if (isEnabled && node instanceof cloudfront.Distribution) {
this.monitoringFacade.monitorCloudFrontDistribution({
distribution: node,
...props,
});
}
}
monitorCodeBuild(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.codeBuild);
if (isEnabled && node instanceof codebuild.Project) {
this.monitoringFacade.monitorCodeBuildProject({
project: node,
...props,
});
}
}
monitorDocumentDb(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.documentDb);
if (isEnabled && node instanceof docdb.DatabaseCluster) {
this.monitoringFacade.monitorDocumentDbCluster({
cluster: node,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorDynamoDb(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.dynamoDB);
if (isEnabled && node instanceof dynamodb.Table) {
this.monitoringFacade.monitorDynamoTable({
table: node,
...props,
});
}
}
monitorEc2() {
const [isEnabled, props] = this.getMonitoringDetails(this.props.ec2);
if (isEnabled) {
this.monitoringFacade.monitorEC2Instances({
...props,
});
}
}
monitorElasticCache() {
const [isEnabled, props] = this.getMonitoringDetails(this.props.elasticCache);
if (isEnabled) {
this.monitoringFacade.monitorElastiCacheCluster({
clusterType: monitoring_1.ElastiCacheClusterType.MEMCACHED,
...props,
});
this.monitoringFacade.monitorElastiCacheCluster({
clusterType: monitoring_1.ElastiCacheClusterType.REDIS,
...props,
});
}
}
monitorGlue(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.glue);
if (isEnabled && node instanceof glue.CfnJob) {
this.monitoringFacade.monitorGlueJob({
jobName: node.name,
...props,
});
}
}
monitorKinesisAnalytics(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.kinesisDataAnalytics);
if (isEnabled && node instanceof kinesisanalytics.CfnApplication) {
this.monitoringFacade.monitorKinesisDataAnalytics({
application: node.applicationName,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorKinesisDataStream(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.kinesisDataStream);
if (isEnabled && node instanceof kinesis.CfnStream) {
this.monitoringFacade.monitorKinesisDataStream({
streamName: node.name,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorKinesisFirehose(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.kinesisFirehose);
if (isEnabled && node instanceof kinesisfirehose.CfnDeliveryStream) {
this.monitoringFacade.monitorKinesisFirehose({
deliveryStreamName: node.deliveryStreamName,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorLambda(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.lambda);
if (isEnabled && node instanceof lambda.Function) {
this.monitoringFacade.monitorLambdaFunction({
lambdaFunction: node,
...props,
});
}
}
monitorOpenSearch(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.openSearch);
if (isEnabled &&
(node instanceof elasticsearch.Domain ||
node instanceof elasticsearch.CfnDomain ||
node instanceof opensearch.Domain ||
node instanceof opensearch.CfnDomain)) {
this.monitoringFacade.monitorOpenSearchCluster({
domain: node,
...props,
});
}
}
monitorRdsCluster(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.rdsCluster ?? this.props.rds);
if (isEnabled && node instanceof rds.DatabaseCluster) {
this.monitoringFacade.monitorRdsCluster({
cluster: node,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorRdsInstance(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.rdsInstance);
if (isEnabled && node instanceof rds.DatabaseInstance) {
this.monitoringFacade.monitorRdsInstance({
instance: node,
alarmFriendlyName: node.node.path,
...props,
});
}
}
monitorRedshift(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.redshift);
if (isEnabled && this.isProbablyL2RedshiftCluster(node)) {
const cfnCluster = node.cluster;
this.monitoringFacade.monitorRedshiftCluster({
clusterIdentifier: cfnCluster.ref,
alarmFriendlyName: cfnCluster.node.path,
...props,
});
}
}
isProbablyL2RedshiftCluster(node) {
return (node.cluster instanceof aws_redshift_1.CfnCluster &&
!!node.clusterName &&
!!node.node?.path);
}
monitorS3(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.s3);
if (isEnabled && node instanceof s3.Bucket) {
this.monitoringFacade.monitorS3Bucket({
bucket: node,
...props,
});
}
}
monitorSecretsManager(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.secretsManager);
if (isEnabled && node instanceof secretsmanager.Secret) {
this.monitoringFacade.monitorSecretsManagerSecret({
secret: node,
...props,
});
}
}
monitorSns(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.sns);
if (isEnabled && node instanceof sns.Topic) {
this.monitoringFacade.monitorSnsTopic({
topic: node,
...props,
});
}
}
monitorSqs(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.sqs);
if (isEnabled && node instanceof sqs.Queue) {
this.monitoringFacade.monitorSqsQueue({
queue: node,
...props,
});
}
}
monitorStepFunctions(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.stepFunctions);
if (isEnabled && node instanceof stepfunctions.StateMachine) {
this.monitoringFacade.monitorStepFunction({
stateMachine: node,
...props,
});
}
}
monitorSyntheticsCanaries(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.syntheticsCanaries);
if (isEnabled && node instanceof synthetics.Canary) {
this.monitoringFacade.monitorSyntheticsCanary({
canary: node,
...props,
});
}
}
monitorWebApplicationFirewallV2Acls(node) {
const [isEnabled, props] = this.getMonitoringDetails(this.props.webApplicationFirewallAclV2);
if (isEnabled && node instanceof wafv2.CfnWebACL) {
const regionProps = {};
if (node.scope === "REGIONAL") {
regionProps.region = aws_cdk_lib_1.Stack.of(node).region;
}
this.monitoringFacade.monitorWebApplicationFirewallAclV2({
acl: node,
...regionProps,
...props,
});
}
}
}
exports.MonitoringAspect = MonitoringAspect;
_a = JSII_RTTI_SYMBOL_1;
MonitoringAspect[_a] = { fqn: "cdk-monitoring-constructs.MonitoringAspect", version: "9.15.2" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9uaXRvcmluZ0FzcGVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIk1vbml0b3JpbmdBc3BlY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNkM7QUFDN0Msb0RBQW9EO0FBQ3BELHdEQUF3RDtBQUN4RCxtREFBbUQ7QUFDbkQsMkRBQTJEO0FBQzNELDBEQUEwRDtBQUMxRCx5REFBeUQ7QUFDekQsdURBQXVEO0FBQ3ZELCtDQUErQztBQUMvQyxxREFBcUQ7QUFDckQsK0RBQStEO0FBQy9ELDZDQUE2QztBQUM3QyxtREFBbUQ7QUFDbkQscUVBQXFFO0FBQ3JFLG1FQUFtRTtBQUNuRSxpREFBaUQ7QUFDakQsZ0VBQWdFO0FBQ2hFLDJDQUEyQztBQUMzQywyREFBc0Q7QUFDdEQseUNBQXlDO0FBQ3pDLGlFQUFpRTtBQUNqRSwyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBQzNDLCtEQUErRDtBQUMvRCx5REFBeUQ7QUFDekQsK0NBQStDO0FBUS9DLDhDQUF1RDtBQUV2RDs7R0FFRztBQUNILE1BQWEsZ0JBQWdCO0lBTTNCLFlBQ21CLGdCQUFrQyxFQUNsQyxRQUErQixFQUFFO1FBRGpDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsVUFBSyxHQUFMLEtBQUssQ0FBNEI7UUFQcEQ7O1dBRUc7UUFDSywwQ0FBcUMsR0FBRyxLQUFLLENBQUM7SUFLbkQsQ0FBQztJQUVHLEtBQUssQ0FBQyxJQUFnQjtRQUMzQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLHVCQUF1QixD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LENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQztJQUVPLG1DQUFtQyxDQUFDLElBQWdCO1FBQzFELE1BQU0sQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUNsRCxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixDQUN2QyxDQUFDO1FBQ0YsSUFBSSxTQUFTLElBQUksSUFBSSxZQUFZLEtBQUssQ0FBQyxTQUFTLEVBQUU7WUFDaEQsTUFBTSxXQUFXLEdBQTJCLEVBQUUsQ0FBQztZQUMvQyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssVUFBVSxFQUFFO2dCQUM3QixXQUFXLENBQUMsTUFBTSxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQzthQUM1QztZQUVELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQ0FBa0MsQ0FBQztnQkFDdkQsR0FBRyxFQUFFLElBQUk7Z0JBQ1QsR0FBRyxXQUFXO2dCQUNkLEdBQUcsS0FBSzthQUNULENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQzs7QUFyWkgsNENBc1pDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUFzcGVjdCwgU3RhY2sgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCAqIGFzIGFwaWd3IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtYXBpZ2F0ZXdheVwiO1xuaW1wb3J0ICogYXMgYXBpZ3d2MiBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWFwaWdhdGV3YXl2MlwiO1xuaW1wb3J0ICogYXMgYXBwc3luYyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWFwcHN5bmNcIjtcbmltcG9ydCAqIGFzIGF1dG9zY2FsaW5nIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtYXV0b3NjYWxpbmdcIjtcbmltcG9ydCAqIGFzIGFjbSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNlcnRpZmljYXRlbWFuYWdlclwiO1xuaW1wb3J0ICogYXMgY2xvdWRmcm9udCBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnRcIjtcbmltcG9ydCAqIGFzIGNvZGVidWlsZCBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNvZGVidWlsZFwiO1xuaW1wb3J0ICogYXMgZG9jZGIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1kb2NkYlwiO1xuaW1wb3J0ICogYXMgZHluYW1vZGIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1keW5hbW9kYlwiO1xuaW1wb3J0ICogYXMgZWxhc3RpY3NlYXJjaCBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVsYXN0aWNzZWFyY2hcIjtcbmltcG9ydCAqIGFzIGdsdWUgZnJvbSBcImF3cy1jZGstbGliL2F3cy1nbHVlXCI7XG5pbXBvcnQgKiBhcyBraW5lc2lzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mta2luZXNpc1wiO1xuaW1wb3J0ICogYXMga2luZXNpc2FuYWx5dGljcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWtpbmVzaXNhbmFseXRpY3NcIjtcbmltcG9ydCAqIGFzIGtpbmVzaXNmaXJlaG9zZSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWtpbmVzaXNmaXJlaG9zZVwiO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgKiBhcyBvcGVuc2VhcmNoIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtb3BlbnNlYXJjaHNlcnZpY2VcIjtcbmltcG9ydCAqIGFzIHJkcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXJkc1wiO1xuaW1wb3J0IHsgQ2ZuQ2x1c3RlciB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtcmVkc2hpZnRcIjtcbmltcG9ydCAqIGFzIHMzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCAqIGFzIHNlY3JldHNtYW5hZ2VyIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXJcIjtcbmltcG9ydCAqIGFzIHNucyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNuc1wiO1xuaW1wb3J0ICogYXMgc3FzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc3FzXCI7XG5pbXBvcnQgKiBhcyBzdGVwZnVuY3Rpb25zIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9uc1wiO1xuaW1wb3J0ICogYXMgc3ludGhldGljcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXN5bnRoZXRpY3NcIjtcbmltcG9ydCAqIGFzIHdhZnYyIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtd2FmdjJcIjtcbmltcG9ydCB7IElDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG5pbXBvcnQge1xuICBNb25pdG9yaW5nQXNwZWN0UHJvcHMsXG4gIE1vbml0b3JpbmdBc3BlY3RUeXBlLFxufSBmcm9tIFwiLi9JTW9uaXRvcmluZ0FzcGVjdFwiO1xuaW1wb3J0IHsgTW9uaXRvcmluZ0ZhY2FkZSB9IGZyb20gXCIuL01vbml0b3JpbmdGYWNhZGVcIjtcbmltcG9ydCB7IEVsYXN0aUNhY2hlQ2x1c3RlclR5cGUgfSBmcm9tIFwiLi4vbW9uaXRvcmluZ1wiO1xuXG4vKipcbiAqIEEgQ0RLIGFzcGVjdCB0aGF0IGFkZHMgc3VwcG9ydCBmb3IgbW9uaXRvcmluZyBhbGwgcmVzb3VyY2VzIHdpdGhpbiBzY29wZS5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vbml0b3JpbmdBc3BlY3QgaW1wbGVtZW50cyBJQXNwZWN0IHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHdlJ3ZlIGFkZGVkIGEgbW9uaXRvcmluZyB0byB0aGUgc2NvcGUgZm9yIG5vZGUgaW5kZXBlbmRlbnQgbW9uaXRvcmluZ3MuXG4gICAqL1xuICBwcml2YXRlIGFkZGVkTm9kZUluZGVwZW5kZW50TW9uaXRvcmluZ1RvU2NvcGUgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1vbml0b3JpbmdGYWNhZGU6IE1vbml0b3JpbmdGYWNhZGUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogTW9uaXRvcmluZ0FzcGVjdFByb3BzID0ge30sXG4gICkge31cblxuICBwdWJsaWMgdmlzaXQobm9kZTogSUNvbnN0cnVjdCk6IHZvaWQge1xuICAgIHRoaXMubW9uaXRvckFjbShub2RlKTtcbiAgICB0aGlzLm1vbml0b3JBcGlHYXRld2F5KG5vZGUpO1xuICAgIHRoaXMubW9uaXRvckFwaUdhdGV3YXlWMihub2RlKTtcbiAgICB0aGlzLm1vbml0b3JBcHBTeW5jKG5vZGUpO1xuICAgIHRoaXMubW9uaXRvckF1cm9yYUNsdXN0ZXIobm9kZSk7XG4gICAgdGhpcy5tb25pdG9yQXV0b1NjYWxpbmdHcm91cChub2RlKTtcbiAgICB0aGlzLm1vbml0b3JDbG91ZEZyb250KG5vZGUpO1xuICAgIHRoaXMubW9uaXRvckNvZGVCdWlsZChub2RlKTtcbiAgICB0aGlzLm1vbml0b3JEb2N1bWVudERiKG5vZGUpO1xuICAgIHRoaXMubW9uaXRvckR5bmFtb0RiKG5vZGUpO1xuICAgIHRoaXMubW9uaXRvckdsdWUobm9kZSk7XG4gICAgdGhpcy5tb25pdG9yS2luZXNpc0FuYWx5dGljcyhub2RlKTtcbiAgICB0aGlzLm1vbml0b3JLaW5lc2lzRGF0YVN0cmVhbShub2RlKTtcbiAgICB0aGlzLm1vbml0b3JLaW5lc2lzRmlyZWhvc2Uobm9kZSk7XG4gICAgdGhpcy5tb25pdG9yTGFtYmRhKG5vZGUpO1xuICAgIHRoaXMubW9uaXRvck9wZW5TZWFyY2gobm9kZSk7XG4gICAgdGhpcy5tb25pdG9yUmRzQ2x1c3Rlcihub2RlKTtcbiAgICB0aGlzLm1vbml0b3JSZHNJbnN0YW5jZShub2RlKTtcbiAgICB0aGlzLm1vbml0b3JSZWRzaGlmdChub2RlKTtcbiAgICB0aGlzLm1vbml0b3JTMyhub2RlKTtcbiAgICB0aGlzLm1vbml0b3JTZWNyZXRzTWFuYWdlcihub2RlKTtcbiAgICB0aGlzLm1vbml0b3JTbnMobm9kZSk7XG4gICAgdGhpcy5tb25pdG9yU3FzKG5vZGUpO1xuICAgIHRoaXMubW9uaXRvclN0ZXBGdW5jdGlvbnMobm9kZSk7XG4gICAgdGhpcy5tb25pdG9yU3ludGhldGljc0NhbmFyaWVzKG5vZGUpO1xuICAgIHRoaXMubW9uaXRvcldlYkFwcGxpY2F0aW9uRmlyZXdhbGxWMkFjbHMobm9kZSk7XG5cbiAgICBpZiAoIXRoaXMuYWRkZWROb2RlSW5kZXBlbmRlbnRNb25pdG9yaW5nVG9TY29wZSkge1xuICAgICAgdGhpcy5hZGRlZE5vZGVJbmRlcGVuZGVudE1vbml0b3JpbmdUb1Njb3BlID0gdHJ1ZTtcblxuICAgICAgdGhpcy5tb25pdG9yRWMyKCk7XG4gICAgICB0aGlzLm1vbml0b3JCaWxsaW5nKCk7XG4gICAgICB0aGlzLm1vbml0b3JFbGFzdGljQ2FjaGUoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldE1vbml0b3JpbmdEZXRhaWxzPFQ+KFxuICAgIGFzcGVjdE9wdGlvbnM/OiBNb25pdG9yaW5nQXNwZWN0VHlwZTxUPixcbiAgKTogW2Jvb2xlYW4sIFQ/XSB7XG4gICAgY29uc3QgaXNFbmFibGVkID0gYXNwZWN0T3B0aW9ucz8uZW5hYmxlZCA/PyB0cnVlO1xuICAgIGNvbnN0IHByb3BzID0gYXNwZWN0T3B0aW9ucz8ucHJvcHM7XG4gICAgcmV0dXJuIFtpc0VuYWJsZWQsIHByb3BzXTtcbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckFjbShub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLmFjbSk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgYWNtLkNlcnRpZmljYXRlKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckNlcnRpZmljYXRlKHtcbiAgICAgICAgY2VydGlmaWNhdGU6IG5vZGUsXG4gICAgICAgIGFsYXJtRnJpZW5kbHlOYW1lOiBub2RlLm5vZGUucGF0aCxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JBcGlHYXRld2F5KG5vZGU6IElDb25zdHJ1Y3QpIHtcbiAgICBjb25zdCBbaXNFbmFibGVkLCBwcm9wc10gPSB0aGlzLmdldE1vbml0b3JpbmdEZXRhaWxzKHRoaXMucHJvcHMuYXBpR2F0ZXdheSk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgYXBpZ3cuUmVzdEFwaSkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JBcGlHYXRld2F5KHtcbiAgICAgICAgYXBpOiBub2RlLFxuICAgICAgICBhcGlTdGFnZTogbm9kZS5kZXBsb3ltZW50U3RhZ2Uuc3RhZ2VOYW1lLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckFwaUdhdGV3YXlWMihub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMuYXBpR2F0ZXdheVYyLFxuICAgICk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgYXBpZ3d2Mi5IdHRwQXBpKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckFwaUdhdGV3YXlWMkh0dHBBcGkoe1xuICAgICAgICBhcGk6IG5vZGUsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yQXBwU3luYyhub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLmFwcFN5bmMpO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIGFwcHN5bmMuR3JhcGhxbEFwaSkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JBcHBTeW5jQXBpKHtcbiAgICAgICAgYXBpOiBub2RlLFxuICAgICAgICBhbGFybUZyaWVuZGx5TmFtZTogbm9kZS5ub2RlLnBhdGgsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yQXVyb3JhQ2x1c3Rlcihub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMuYXVyb3JhQ2x1c3RlcixcbiAgICApO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIHJkcy5TZXJ2ZXJsZXNzQ2x1c3Rlcikge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JBdXJvcmFDbHVzdGVyKHtcbiAgICAgICAgY2x1c3Rlcjogbm9kZSxcbiAgICAgICAgYWxhcm1GcmllbmRseU5hbWU6IG5vZGUubm9kZS5wYXRoLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckF1dG9TY2FsaW5nR3JvdXAobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHMoXG4gICAgICB0aGlzLnByb3BzLmF1dG9TY2FsaW5nR3JvdXAsXG4gICAgKTtcbiAgICBpZiAoaXNFbmFibGVkICYmIG5vZGUgaW5zdGFuY2VvZiBhdXRvc2NhbGluZy5BdXRvU2NhbGluZ0dyb3VwKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckF1dG9TY2FsaW5nR3JvdXAoe1xuICAgICAgICBhdXRvU2NhbGluZ0dyb3VwOiBub2RlLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckJpbGxpbmcoKSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLmJpbGxpbmcpO1xuICAgIGlmIChpc0VuYWJsZWQpIHtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yQmlsbGluZyh7XG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgICBhbGFybUZyaWVuZGx5TmFtZTogXCJCaWxsaW5nXCIsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JDbG91ZEZyb250KG5vZGU6IElDb25zdHJ1Y3QpIHtcbiAgICBjb25zdCBbaXNFbmFibGVkLCBwcm9wc10gPSB0aGlzLmdldE1vbml0b3JpbmdEZXRhaWxzKHRoaXMucHJvcHMuY2xvdWRGcm9udCk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgY2xvdWRmcm9udC5EaXN0cmlidXRpb24pIHtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yQ2xvdWRGcm9udERpc3RyaWJ1dGlvbih7XG4gICAgICAgIGRpc3RyaWJ1dGlvbjogbm9kZSxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JDb2RlQnVpbGQobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHModGhpcy5wcm9wcy5jb2RlQnVpbGQpO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIGNvZGVidWlsZC5Qcm9qZWN0KSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckNvZGVCdWlsZFByb2plY3Qoe1xuICAgICAgICBwcm9qZWN0OiBub2RlLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckRvY3VtZW50RGIobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHModGhpcy5wcm9wcy5kb2N1bWVudERiKTtcbiAgICBpZiAoaXNFbmFibGVkICYmIG5vZGUgaW5zdGFuY2VvZiBkb2NkYi5EYXRhYmFzZUNsdXN0ZXIpIHtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yRG9jdW1lbnREYkNsdXN0ZXIoe1xuICAgICAgICBjbHVzdGVyOiBub2RlLFxuICAgICAgICBhbGFybUZyaWVuZGx5TmFtZTogbm9kZS5ub2RlLnBhdGgsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yRHluYW1vRGIobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHModGhpcy5wcm9wcy5keW5hbW9EQik7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgZHluYW1vZGIuVGFibGUpIHtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yRHluYW1vVGFibGUoe1xuICAgICAgICB0YWJsZTogbm9kZSxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JFYzIoKSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLmVjMik7XG4gICAgaWYgKGlzRW5hYmxlZCkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JFQzJJbnN0YW5jZXMoe1xuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckVsYXN0aWNDYWNoZSgpIHtcbiAgICBjb25zdCBbaXNFbmFibGVkLCBwcm9wc10gPSB0aGlzLmdldE1vbml0b3JpbmdEZXRhaWxzKFxuICAgICAgdGhpcy5wcm9wcy5lbGFzdGljQ2FjaGUsXG4gICAgKTtcbiAgICBpZiAoaXNFbmFibGVkKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckVsYXN0aUNhY2hlQ2x1c3Rlcih7XG4gICAgICAgIGNsdXN0ZXJUeXBlOiBFbGFzdGlDYWNoZUNsdXN0ZXJUeXBlLk1FTUNBQ0hFRCxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yRWxhc3RpQ2FjaGVDbHVzdGVyKHtcbiAgICAgICAgY2x1c3RlclR5cGU6IEVsYXN0aUNhY2hlQ2x1c3RlclR5cGUuUkVESVMsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yR2x1ZShub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLmdsdWUpO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIGdsdWUuQ2ZuSm9iKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckdsdWVKb2Ioe1xuICAgICAgICBqb2JOYW1lOiBub2RlLm5hbWUhLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvcktpbmVzaXNBbmFseXRpY3Mobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHMoXG4gICAgICB0aGlzLnByb3BzLmtpbmVzaXNEYXRhQW5hbHl0aWNzLFxuICAgICk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2Yga2luZXNpc2FuYWx5dGljcy5DZm5BcHBsaWNhdGlvbikge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JLaW5lc2lzRGF0YUFuYWx5dGljcyh7XG4gICAgICAgIGFwcGxpY2F0aW9uOiBub2RlLmFwcGxpY2F0aW9uTmFtZSEsXG4gICAgICAgIGFsYXJtRnJpZW5kbHlOYW1lOiBub2RlLm5vZGUucGF0aCxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JLaW5lc2lzRGF0YVN0cmVhbShub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMua2luZXNpc0RhdGFTdHJlYW0sXG4gICAgKTtcbiAgICBpZiAoaXNFbmFibGVkICYmIG5vZGUgaW5zdGFuY2VvZiBraW5lc2lzLkNmblN0cmVhbSkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JLaW5lc2lzRGF0YVN0cmVhbSh7XG4gICAgICAgIHN0cmVhbU5hbWU6IG5vZGUubmFtZSEsXG4gICAgICAgIGFsYXJtRnJpZW5kbHlOYW1lOiBub2RlLm5vZGUucGF0aCxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JLaW5lc2lzRmlyZWhvc2Uobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHMoXG4gICAgICB0aGlzLnByb3BzLmtpbmVzaXNGaXJlaG9zZSxcbiAgICApO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIGtpbmVzaXNmaXJlaG9zZS5DZm5EZWxpdmVyeVN0cmVhbSkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JLaW5lc2lzRmlyZWhvc2Uoe1xuICAgICAgICBkZWxpdmVyeVN0cmVhbU5hbWU6IG5vZGUuZGVsaXZlcnlTdHJlYW1OYW1lISxcbiAgICAgICAgYWxhcm1GcmllbmRseU5hbWU6IG5vZGUubm9kZS5wYXRoLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvckxhbWJkYShub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLmxhbWJkYSk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgbGFtYmRhLkZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvckxhbWJkYUZ1bmN0aW9uKHtcbiAgICAgICAgbGFtYmRhRnVuY3Rpb246IG5vZGUsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yT3BlblNlYXJjaChub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLm9wZW5TZWFyY2gpO1xuICAgIGlmIChcbiAgICAgIGlzRW5hYmxlZCAmJlxuICAgICAgKG5vZGUgaW5zdGFuY2VvZiBlbGFzdGljc2VhcmNoLkRvbWFpbiB8fFxuICAgICAgICBub2RlIGluc3RhbmNlb2YgZWxhc3RpY3NlYXJjaC5DZm5Eb21haW4gfHxcbiAgICAgICAgbm9kZSBpbnN0YW5jZW9mIG9wZW5zZWFyY2guRG9tYWluIHx8XG4gICAgICAgIG5vZGUgaW5zdGFuY2VvZiBvcGVuc2VhcmNoLkNmbkRvbWFpbilcbiAgICApIHtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yT3BlblNlYXJjaENsdXN0ZXIoe1xuICAgICAgICBkb21haW46IG5vZGUsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yUmRzQ2x1c3Rlcihub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMucmRzQ2x1c3RlciA/PyB0aGlzLnByb3BzLnJkcyxcbiAgICApO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIHJkcy5EYXRhYmFzZUNsdXN0ZXIpIHtcbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yUmRzQ2x1c3Rlcih7XG4gICAgICAgIGNsdXN0ZXI6IG5vZGUsXG4gICAgICAgIGFsYXJtRnJpZW5kbHlOYW1lOiBub2RlLm5vZGUucGF0aCxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JSZHNJbnN0YW5jZShub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMucmRzSW5zdGFuY2UsXG4gICAgKTtcbiAgICBpZiAoaXNFbmFibGVkICYmIG5vZGUgaW5zdGFuY2VvZiByZHMuRGF0YWJhc2VJbnN0YW5jZSkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JSZHNJbnN0YW5jZSh7XG4gICAgICAgIGluc3RhbmNlOiBub2RlLFxuICAgICAgICBhbGFybUZyaWVuZGx5TmFtZTogbm9kZS5ub2RlLnBhdGgsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yUmVkc2hpZnQobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHModGhpcy5wcm9wcy5yZWRzaGlmdCk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiB0aGlzLmlzUHJvYmFibHlMMlJlZHNoaWZ0Q2x1c3Rlcihub2RlKSkge1xuICAgICAgY29uc3QgY2ZuQ2x1c3RlciA9IChub2RlIGFzIGFueSkuY2x1c3RlciBhcyBDZm5DbHVzdGVyO1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JSZWRzaGlmdENsdXN0ZXIoe1xuICAgICAgICBjbHVzdGVySWRlbnRpZmllcjogY2ZuQ2x1c3Rlci5yZWYsXG4gICAgICAgIGFsYXJtRnJpZW5kbHlOYW1lOiBjZm5DbHVzdGVyLm5vZGUucGF0aCxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzUHJvYmFibHlMMlJlZHNoaWZ0Q2x1c3Rlcihub2RlOiBJQ29uc3RydWN0KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIChub2RlIGFzIGFueSkuY2x1c3RlciBpbnN0YW5jZW9mIENmbkNsdXN0ZXIgJiZcbiAgICAgICEhKG5vZGUgYXMgYW55KS5jbHVzdGVyTmFtZSAmJlxuICAgICAgISEobm9kZSBhcyBhbnkpLm5vZGU/LnBhdGhcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yUzMobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHModGhpcy5wcm9wcy5zMyk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2YgczMuQnVja2V0KSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvclMzQnVja2V0KHtcbiAgICAgICAgYnVja2V0OiBub2RlLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvclNlY3JldHNNYW5hZ2VyKG5vZGU6IElDb25zdHJ1Y3QpIHtcbiAgICBjb25zdCBbaXNFbmFibGVkLCBwcm9wc10gPSB0aGlzLmdldE1vbml0b3JpbmdEZXRhaWxzKFxuICAgICAgdGhpcy5wcm9wcy5zZWNyZXRzTWFuYWdlcixcbiAgICApO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIHNlY3JldHNtYW5hZ2VyLlNlY3JldCkge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JTZWNyZXRzTWFuYWdlclNlY3JldCh7XG4gICAgICAgIHNlY3JldDogbm9kZSxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JTbnMobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHModGhpcy5wcm9wcy5zbnMpO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIHNucy5Ub3BpYykge1xuICAgICAgdGhpcy5tb25pdG9yaW5nRmFjYWRlLm1vbml0b3JTbnNUb3BpYyh7XG4gICAgICAgIHRvcGljOiBub2RlLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbW9uaXRvclNxcyhub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyh0aGlzLnByb3BzLnNxcyk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2Ygc3FzLlF1ZXVlKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvclNxc1F1ZXVlKHtcbiAgICAgICAgcXVldWU6IG5vZGUsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yU3RlcEZ1bmN0aW9ucyhub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMuc3RlcEZ1bmN0aW9ucyxcbiAgICApO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIHN0ZXBmdW5jdGlvbnMuU3RhdGVNYWNoaW5lKSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvclN0ZXBGdW5jdGlvbih7XG4gICAgICAgIHN0YXRlTWFjaGluZTogbm9kZSxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JTeW50aGV0aWNzQ2FuYXJpZXMobm9kZTogSUNvbnN0cnVjdCkge1xuICAgIGNvbnN0IFtpc0VuYWJsZWQsIHByb3BzXSA9IHRoaXMuZ2V0TW9uaXRvcmluZ0RldGFpbHMoXG4gICAgICB0aGlzLnByb3BzLnN5bnRoZXRpY3NDYW5hcmllcyxcbiAgICApO1xuICAgIGlmIChpc0VuYWJsZWQgJiYgbm9kZSBpbnN0YW5jZW9mIHN5bnRoZXRpY3MuQ2FuYXJ5KSB7XG4gICAgICB0aGlzLm1vbml0b3JpbmdGYWNhZGUubW9uaXRvclN5bnRoZXRpY3NDYW5hcnkoe1xuICAgICAgICBjYW5hcnk6IG5vZGUsXG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtb25pdG9yV2ViQXBwbGljYXRpb25GaXJld2FsbFYyQWNscyhub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgY29uc3QgW2lzRW5hYmxlZCwgcHJvcHNdID0gdGhpcy5nZXRNb25pdG9yaW5nRGV0YWlscyhcbiAgICAgIHRoaXMucHJvcHMud2ViQXBwbGljYXRpb25GaXJld2FsbEFjbFYyLFxuICAgICk7XG4gICAgaWYgKGlzRW5hYmxlZCAmJiBub2RlIGluc3RhbmNlb2Ygd2FmdjIuQ2ZuV2ViQUNMKSB7XG4gICAgICBjb25zdCByZWdpb25Qcm9wczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgICAgaWYgKG5vZGUuc2NvcGUgPT09IFwiUkVHSU9OQUxcIikge1xuICAgICAgICByZWdpb25Qcm9wcy5yZWdpb24gPSBTdGFjay5vZihub2RlKS5yZWdpb247XG4gICAgICB9XG5cbiAgICAgIHRoaXMubW9uaXRvcmluZ0ZhY2FkZS5tb25pdG9yV2ViQXBwbGljYXRpb25GaXJld2FsbEFjbFYyKHtcbiAgICAgICAgYWNsOiBub2RlLFxuICAgICAgICAuLi5yZWdpb25Qcm9wcyxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==