ec2-instance-running-scheduler 0.2.7 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  import { TimeZone } from 'aws-cdk-lib';
2
2
  import { Construct } from 'constructs';
3
+ import { type FailureDetectionAlarms, type RunningSchedulerFailureDetection } from './running-scheduler-failure-detection';
4
+ export type { FailureDetectionAlarms, RunningSchedulerFailureDetection, RunningSchedulerFailureDetectionProps, } from './running-scheduler-failure-detection';
3
5
  /**
4
6
  * Cron-style schedule configuration for start/stop actions.
5
7
  */
@@ -30,23 +32,25 @@ export interface Secrets {
30
32
  readonly slackSecretName: string;
31
33
  }
32
34
  /**
33
- * CDK-side limits for per-instance stable-state polling in the Durable Lambda handler.
35
+ * CDK-side limits for per-instance stable-state waiting in the Durable Lambda handler.
34
36
  *
35
- * Values are written to {@link PROCESS_RESOURCE_MAX_LOOP_COUNT_ENV} and
37
+ * Optional fields map to {@link PROCESS_RESOURCE_MAX_LOOP_COUNT_ENV} and
36
38
  * {@link PROCESS_RESOURCE_MAX_ELAPSED_SECONDS_ENV} on the running scheduler function.
37
39
  * Prevents abnormal or stuck transitions from running until the Durable execution timeout.
40
+ *
41
+ * @see {@link ResourceWaitLimits} in `running-scheduler-predicates.ts` for the handler-side required shape.
38
42
  */
39
- export interface ResourcePollingLimits {
43
+ export interface ResourceWaitLimits {
40
44
  /**
41
- * Maximum describe/poll loop iterations per instance.
45
+ * Maximum describe/wait loop iterations per instance.
42
46
  *
43
- * @default {@link DEFAULT_RESOURCE_POLLING_LIMITS.maxLoopCount} (90)
47
+ * @default {@link DEFAULT_RESOURCE_WAIT_LIMITS.maxLoopCount} (90)
44
48
  */
45
49
  readonly maxLoopCount?: number;
46
50
  /**
47
- * Maximum wall-clock seconds spent polling a single instance.
51
+ * Maximum wall-clock seconds spent waiting for a single instance to stabilize.
48
52
  *
49
- * @default {@link DEFAULT_RESOURCE_POLLING_LIMITS.maxElapsedSeconds} (1800, 30 minutes)
53
+ * @default {@link DEFAULT_RESOURCE_WAIT_LIMITS.maxElapsedSeconds} (1800, 30 minutes)
50
54
  */
51
55
  readonly maxElapsedSeconds?: number;
52
56
  }
@@ -65,11 +69,19 @@ export interface EC2InstanceRunningSchedulerProps {
65
69
  /** Cron schedule for starting instances. */
66
70
  readonly startSchedule?: Schedule;
67
71
  /**
68
- * Per-instance polling limits for the running scheduler Lambda.
72
+ * Per-instance wait limits for the running scheduler Lambda.
73
+ *
74
+ * @default {@link DEFAULT_RESOURCE_WAIT_LIMITS}
75
+ */
76
+ readonly resourceWait?: ResourceWaitLimits;
77
+ /**
78
+ * Optional CloudWatch alarms and log-based metrics for failure detection.
79
+ *
80
+ * Set `enabled: true` to create alarms; optionally pass `alarmTopic` for SNS notifications.
69
81
  *
70
- * @default {@link DEFAULT_RESOURCE_POLLING_LIMITS}
82
+ * @default disabled when omitted
71
83
  */
72
- readonly resourcePolling?: ResourcePollingLimits;
84
+ readonly failureDetection?: FailureDetectionAlarms;
73
85
  }
74
86
  /**
75
87
  * Provisions EventBridge Scheduler rules and a Durable Execution Lambda that start/stop tagged EC2 instances.
@@ -77,16 +89,21 @@ export interface EC2InstanceRunningSchedulerProps {
77
89
  * Each schedule invokes the function with `Params` (`TagKey`, `TagValues`, `Mode`). The function uses
78
90
  * the Resource Groups Tagging API and EC2 APIs; Slack notifications use the secret named in {@link Secrets.slackSecretName}.
79
91
  *
80
- * Per-instance polling timeouts are configured via {@link EC2InstanceRunningSchedulerProps.resourcePolling}
81
- * and enforced in the handler before the Durable execution timeout.
92
+ * Per-instance wait timeouts are configured via {@link EC2InstanceRunningSchedulerProps.resourceWait}
93
+ * and enforced in the handler before the Durable execution timeout. Optional CloudWatch failure
94
+ * detection is available via {@link EC2InstanceRunningSchedulerProps.failureDetection}.
82
95
  */
83
96
  export declare class EC2InstanceRunningScheduler extends Construct {
97
+ /** Failure detection alarms, when {@link EC2InstanceRunningSchedulerProps.failureDetection} is enabled. */
98
+ readonly failureDetection?: RunningSchedulerFailureDetection;
84
99
  /**
85
- * Defines IAM, logging, two cron schedules (start/stop), and the bundled running-scheduler Lambda (Node.js, Durable Execution).
100
+ * Defines IAM, logging, optional failure detection alarms, two cron schedules (start/stop),
101
+ * and the bundled running-scheduler Lambda (Node.js, Durable Execution).
86
102
  *
87
103
  * @param scope - Parent construct.
88
104
  * @param id - Construct id.
89
- * @param props - Target tags, schedules, Slack secret, schedule enable flag, and optional {@link ResourcePollingLimits}.
105
+ * @param props - Target tags, schedules, Slack secret, schedule enable flag, optional
106
+ * {@link ResourceWaitLimits}, and optional {@link FailureDetectionAlarms}.
90
107
  */
91
108
  constructor(scope: Construct, id: string, props: EC2InstanceRunningSchedulerProps);
92
109
  }
@@ -43,32 +43,42 @@ const scheduler = __importStar(require("aws-cdk-lib/aws-scheduler"));
43
43
  const targets = __importStar(require("aws-cdk-lib/aws-scheduler-targets"));
44
44
  const aws_secretsmanager_1 = require("aws-cdk-lib/aws-secretsmanager");
45
45
  const constructs_1 = require("constructs");
46
+ const running_scheduler_failure_detection_1 = require("./running-scheduler-failure-detection");
46
47
  const running_scheduler_function_1 = require("../funcs/running-scheduler-function");
47
- const running_scheduler_polling_config_1 = require("../funcs/running-scheduler-polling-config");
48
48
  const running_scheduler_predicates_1 = require("../funcs/running-scheduler-predicates");
49
+ const running_scheduler_wait_config_1 = require("../funcs/running-scheduler-wait-config");
49
50
  /**
50
51
  * Provisions EventBridge Scheduler rules and a Durable Execution Lambda that start/stop tagged EC2 instances.
51
52
  *
52
53
  * Each schedule invokes the function with `Params` (`TagKey`, `TagValues`, `Mode`). The function uses
53
54
  * the Resource Groups Tagging API and EC2 APIs; Slack notifications use the secret named in {@link Secrets.slackSecretName}.
54
55
  *
55
- * Per-instance polling timeouts are configured via {@link EC2InstanceRunningSchedulerProps.resourcePolling}
56
- * and enforced in the handler before the Durable execution timeout.
56
+ * Per-instance wait timeouts are configured via {@link EC2InstanceRunningSchedulerProps.resourceWait}
57
+ * and enforced in the handler before the Durable execution timeout. Optional CloudWatch failure
58
+ * detection is available via {@link EC2InstanceRunningSchedulerProps.failureDetection}.
57
59
  */
58
60
  class EC2InstanceRunningScheduler extends constructs_1.Construct {
59
- static [JSII_RTTI_SYMBOL_1] = { fqn: "ec2-instance-running-scheduler.EC2InstanceRunningScheduler", version: "0.2.7" };
61
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "ec2-instance-running-scheduler.EC2InstanceRunningScheduler", version: "0.3.1" };
62
+ /** Failure detection alarms, when {@link EC2InstanceRunningSchedulerProps.failureDetection} is enabled. */
63
+ failureDetection;
60
64
  /**
61
- * Defines IAM, logging, two cron schedules (start/stop), and the bundled running-scheduler Lambda (Node.js, Durable Execution).
65
+ * Defines IAM, logging, optional failure detection alarms, two cron schedules (start/stop),
66
+ * and the bundled running-scheduler Lambda (Node.js, Durable Execution).
62
67
  *
63
68
  * @param scope - Parent construct.
64
69
  * @param id - Construct id.
65
- * @param props - Target tags, schedules, Slack secret, schedule enable flag, and optional {@link ResourcePollingLimits}.
70
+ * @param props - Target tags, schedules, Slack secret, schedule enable flag, optional
71
+ * {@link ResourceWaitLimits}, and optional {@link FailureDetectionAlarms}.
66
72
  */
67
73
  constructor(scope, id, props) {
68
74
  super(scope, id);
69
75
  const slackSecret = aws_secretsmanager_1.Secret.fromSecretNameV2(this, 'SlackSecret', props.secrets.slackSecretName);
70
76
  // Durable Functions-based Running Scheduler (previous Step Functions logic implemented in Lambda).
71
77
  // Durable Execution requires Node.js 22+.
78
+ const runningScheduleFunctionLogGroup = new logs.LogGroup(this, 'RunningSchedulerFunctionLogGroup', {
79
+ retention: logs.RetentionDays.THREE_MONTHS,
80
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
81
+ });
72
82
  const runningScheduleFunction = new running_scheduler_function_1.RunningSchedulerFunction(this, 'RunningSchedulerFunction', {
73
83
  description: 'Starts and stops tagged EC2 instances on EventBridge Scheduler schedules.',
74
84
  architecture: lambda.Architecture.ARM_64,
@@ -81,10 +91,11 @@ class EC2InstanceRunningScheduler extends constructs_1.Construct {
81
91
  },
82
92
  environment: {
83
93
  SLACK_SECRET_NAME: props.secrets.slackSecretName,
84
- [running_scheduler_polling_config_1.PROCESS_RESOURCE_MAX_LOOP_COUNT_ENV]: String(props.resourcePolling?.maxLoopCount ?? running_scheduler_predicates_1.DEFAULT_RESOURCE_POLLING_LIMITS.maxLoopCount),
85
- [running_scheduler_polling_config_1.PROCESS_RESOURCE_MAX_ELAPSED_SECONDS_ENV]: String(props.resourcePolling?.maxElapsedSeconds ?? running_scheduler_predicates_1.DEFAULT_RESOURCE_POLLING_LIMITS.maxElapsedSeconds),
94
+ [running_scheduler_wait_config_1.PROCESS_RESOURCE_MAX_LOOP_COUNT_ENV]: String(props.resourceWait?.maxLoopCount ?? running_scheduler_predicates_1.DEFAULT_RESOURCE_WAIT_LIMITS.maxLoopCount),
95
+ [running_scheduler_wait_config_1.PROCESS_RESOURCE_MAX_ELAPSED_SECONDS_ENV]: String(props.resourceWait?.maxElapsedSeconds ?? running_scheduler_predicates_1.DEFAULT_RESOURCE_WAIT_LIMITS.maxElapsedSeconds),
86
96
  },
87
97
  paramsAndSecrets: lambda.ParamsAndSecretsLayerVersion.fromVersion(lambda.ParamsAndSecretsVersions.V1_0_103, {
98
+ // Required by aws-lambda-secret-fetcher (extension HTTP API on localhost; port from PARAMETERS_SECRETS_EXTENSION_HTTP_PORT).
88
99
  cacheSize: 500,
89
100
  logLevel: lambda.ParamsAndSecretsLogLevel.INFO,
90
101
  }),
@@ -96,10 +107,7 @@ class EC2InstanceRunningScheduler extends constructs_1.Construct {
96
107
  iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicDurableExecutionRolePolicy'),
97
108
  ],
98
109
  }),
99
- logGroup: new logs.LogGroup(this, 'RunningSchedulerFunctionLogGroup', {
100
- retention: logs.RetentionDays.THREE_MONTHS,
101
- removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
102
- }),
110
+ logGroup: runningScheduleFunctionLogGroup,
103
111
  loggingFormat: lambda.LoggingFormat.JSON,
104
112
  systemLogLevelV2: lambda.SystemLogLevel.INFO,
105
113
  applicationLogLevelV2: lambda.ApplicationLogLevel.INFO,
@@ -125,6 +133,11 @@ class EC2InstanceRunningScheduler extends constructs_1.Construct {
125
133
  }));
126
134
  // Grant read access to the Slack secret
127
135
  slackSecret.grantRead(runningScheduleFunction);
136
+ this.failureDetection = (0, running_scheduler_failure_detection_1.createRunningSchedulerFailureDetection)(this, 'FailureDetection', {
137
+ failureDetection: props.failureDetection,
138
+ runningScheduleFunction,
139
+ logGroup: runningScheduleFunctionLogGroup,
140
+ });
128
141
  // See: https://docs.aws.amazon.com/lambda/latest/dg/durable-getting-started-iac.html
129
142
  const runningScheduleFunctionAlias = runningScheduleFunction.addAlias('live');
130
143
  // Whether schedules are enabled (default true unless explicitly disabled).
@@ -178,4 +191,4 @@ class EC2InstanceRunningScheduler extends constructs_1.Construct {
178
191
  }
179
192
  }
180
193
  exports.EC2InstanceRunningScheduler = EC2InstanceRunningScheduler;
181
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyLWluc3RhbmNlLXJ1bm5pbmctc2NoZWR1bGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnN0cnVjdHMvZWMyLWluc3RhbmNlLXJ1bm5pbmctc2NoZWR1bGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2Q0FBZ0U7QUFDaEUseURBQTJDO0FBQzNDLCtEQUFpRDtBQUNqRCwyREFBNkM7QUFDN0MscUVBQXVEO0FBQ3ZELDJFQUE2RDtBQUM3RCx1RUFBd0Q7QUFDeEQsMkNBQXVDO0FBQ3ZDLG9GQUErRTtBQUMvRSxnR0FHbUQ7QUFDbkQsd0ZBQXdGO0FBOEV4Rjs7Ozs7Ozs7R0FRRztBQUNILE1BQWEsMkJBQTRCLFNBQVEsc0JBQVM7O0lBQ3hEOzs7Ozs7T0FNRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUM7UUFDL0UsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLFdBQVcsR0FBRywyQkFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUVoRyxtR0FBbUc7UUFDbkcsMENBQTBDO1FBQzFDLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxxREFBd0IsQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLEVBQUU7WUFDN0YsV0FBVyxFQUFFLDJFQUEyRTtZQUN4RixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNO1lBQ3hDLE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDN0IsVUFBVSxFQUFFLEdBQUc7WUFDZixhQUFhLEVBQUUsQ0FBQztZQUNoQixhQUFhLEVBQUU7Z0JBQ2IsZ0JBQWdCLEVBQUUsc0JBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxlQUFl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SUFBSSxJQUFJO2dCQUN0QyxPQUFPLEVBQUUsS0FBSyxDQUFDLFlBQVksRUFBRSxJQUFJLElBQUksU0FBUztnQkFDOUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxZQUFZLEVBQUUsUUFBUSxJQUFJLHNCQUFRLENBQUMsT0FBTzthQUMzRCxDQUFDO1lBQ0YsTUFBTSxFQUFFLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyw0QkFBNEIsRUFBRTtnQkFDN0QsS0FBSyxFQUFFLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLENBQUM7b0JBQzlDLE1BQU0sRUFBRTt3QkFDTixNQUFNLEVBQUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNO3dCQUNuQyxTQUFTLEVBQUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxTQUFTO3dCQUN6QyxJQUFJLEVBQUUsTUFBTTtxQkFDYjtpQkFDRixDQUFDO2FBQ0gsQ0FBQztTQUNILENBQUMsQ0FBQztJQUNMLENBQUM7O0FBaElILGtFQWlJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uLCBSZW1vdmFsUG9saWN5LCBUaW1lWm9uZSB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0ICogYXMgc2NoZWR1bGVyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zY2hlZHVsZXInO1xuaW1wb3J0ICogYXMgdGFyZ2V0cyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc2NoZWR1bGVyLXRhcmdldHMnO1xuaW1wb3J0IHsgU2VjcmV0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNlY3JldHNtYW5hZ2VyJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgUnVubmluZ1NjaGVkdWxlckZ1bmN0aW9uIH0gZnJvbSAnLi4vZnVuY3MvcnVubmluZy1zY2hlZHVsZXItZnVuY3Rpb24nO1xuaW1wb3J0IHtcbiAgUFJPQ0VTU19SRVNPVVJDRV9NQVhfRUxBUFNFRF9TRUNPTkRTX0VOVixcbiAgUFJPQ0VTU19SRVNPVVJDRV9NQVhfTE9PUF9DT1VOVF9FTlYsXG59IGZyb20gJy4uL2Z1bmNzL3J1bm5pbmctc2NoZWR1bGVyLXBvbGxpbmctY29uZmlnJztcbmltcG9ydCB7IERFRkFVTFRfUkVTT1VSQ0VfUE9MTElOR19MSU1JVFMgfSBmcm9tICcuLi9mdW5jcy9ydW5uaW5nLXNjaGVkdWxlci1wcmVkaWNhdGVzJztcblxuLyoqXG4gKiBDcm9uLXN0eWxlIHNjaGVkdWxlIGNvbmZpZ3VyYXRpb24gZm9yIHN0YXJ0L3N0b3AgYWN0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY2hlZHVsZSB7XG4gIC8qKiBUaW1lIHpvbmUgZm9yIHRoZSBzY2hlZHVsZSAoZS5nLiBFVENfVVRDKS4gKi9cbiAgcmVhZG9ubHkgdGltZXpvbmU6IFRpbWVab25lO1xuICAvKiogQ3JvbiBtaW51dGUgKDDigJM1OSkuICovXG4gIHJlYWRvbmx5IG1pbnV0ZT86IHN0cmluZztcbiAgLyoqIENyb24gaG91ciAoMOKAkzIzKS4gKi9cbiAgcmVhZG9ubHkgaG91cj86IHN0cmluZztcbiAgLyoqIENyb24gZGF5IG9mIHdlZWsgKGUuZy4gTU9OLUZSSSkuICovXG4gIHJlYWRvbmx5IHdlZWs/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGVmaW5lcyB3aGljaCBFQzIgaW5zdGFuY2VzIGFyZSB0YXJnZXRlZCBieSB0YWcga2V5IGFuZCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFyZ2V0UmVzb3VyY2Uge1xuICAvKiogVGFnIGtleSB1c2VkIHRvIHNlbGVjdCBpbnN0YW5jZXMgKGUuZy4gU2NoZWR1bGUpLiAqL1xuICByZWFkb25seSB0YWdLZXk6IHN0cmluZztcbiAgLyoqIFRhZyB2YWx1ZXMgdGhhdCBtYXRjaCBpbnN0YW5jZXMgdG8gaW5jbHVkZS4gKi9cbiAgcmVhZG9ubHkgdGFnVmFsdWVzOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBTZWNyZXQgaWRlbnRpZmllcnMgcmVxdWlyZWQgYnkgdGhlIHNjaGVkdWxlciAoZS5nLiBTbGFjaykuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VjcmV0cyB7XG4gIC8qKiBOYW1lIG9mIHRoZSBTZWNyZXRzIE1hbmFnZXIgc2VjcmV0IGNvbnRhaW5pbmcgU2xhY2sgdG9rZW4gYW5kIGNoYW5uZWwuICovXG4gIHJlYWRvbmx5IHNsYWNrU2VjcmV0TmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIENESy1zaWRlIGxpbWl0cyBmb3IgcGVyLWluc3RhbmNlIHN0YWJsZS1zdGF0ZSBwb2xsaW5nIGluIHRoZSBEdXJhYmxlIExhbWJkYSBoYW5kbGVyLlxuICpcbiAqIFZhbHVlcyBhcmUgd3JpdHRlbiB0byB7QGxpbmsgUFJPQ0VTU19SRVNPVVJDRV9NQVhfTE9PUF9DT1VOVF9FTlZ9IGFuZFxuICoge0BsaW5rIFBST0NFU1NfUkVTT1VSQ0VfTUFYX0VMQVBTRURfU0VDT05EU19FTlZ9IG9uIHRoZSBydW5uaW5nIHNjaGVkdWxlciBmdW5jdGlvbi5cbiAqIFByZXZlbnRzIGFibm9ybWFsIG9yIHN0dWNrIHRyYW5zaXRpb25zIGZyb20gcnVubmluZyB1bnRpbCB0aGUgRHVyYWJsZSBleGVjdXRpb24gdGltZW91dC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZVBvbGxpbmdMaW1pdHMge1xuICAvKipcbiAgICogTWF4aW11bSBkZXNjcmliZS9wb2xsIGxvb3AgaXRlcmF0aW9ucyBwZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IHtAbGluayBERUZBVUxUX1JFU09VUkNFX1BPTExJTkdfTElNSVRTLm1heExvb3BDb3VudH0gKDkwKVxuICAgKi9cbiAgcmVhZG9ubHkgbWF4TG9vcENvdW50PzogbnVtYmVyO1xuICAvKipcbiAgICogTWF4aW11bSB3YWxsLWNsb2NrIHNlY29uZHMgc3BlbnQgcG9sbGluZyBhIHNpbmdsZSBpbnN0YW5jZS5cbiAgICpcbiAgICogQGRlZmF1bHQge0BsaW5rIERFRkFVTFRfUkVTT1VSQ0VfUE9MTElOR19MSU1JVFMubWF4RWxhcHNlZFNlY29uZHN9ICgxODAwLCAzMCBtaW51dGVzKVxuICAgKi9cbiAgcmVhZG9ubHkgbWF4RWxhcHNlZFNlY29uZHM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgYW4gRUMyIGluc3RhbmNlIHJ1bm5pbmcgc2NoZWR1bGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlclByb3BzIHtcbiAgLyoqIFRhZy1iYXNlZCB0YXJnZXRpbmcgZm9yIEVDMiBpbnN0YW5jZXMgdG8gc3RhcnQvc3RvcC4gKi9cbiAgcmVhZG9ubHkgdGFyZ2V0UmVzb3VyY2U6IFRhcmdldFJlc291cmNlO1xuICAvKiogV2hldGhlciBFdmVudEJyaWRnZSBTY2hlZHVsZXIgcnVsZXMgYXJlIGVuYWJsZWQuIERlZmF1bHRzIHRvIHRydWUgaWYgb21pdHRlZC4gKi9cbiAgcmVhZG9ubHkgZW5hYmxlU2NoZWR1bGluZz86IGJvb2xlYW47XG4gIC8qKiBTZWNyZXRzIChlLmcuIFNsYWNrKSB1c2VkIGZvciBub3RpZmljYXRpb25zLiAqL1xuICByZWFkb25seSBzZWNyZXRzOiBTZWNyZXRzO1xuICAvKiogQ3JvbiBzY2hlZHVsZSBmb3Igc3RvcHBpbmcgaW5zdGFuY2VzLiAqL1xuICByZWFkb25seSBzdG9wU2NoZWR1bGU/OiBTY2hlZHVsZTtcbiAgLyoqIENyb24gc2NoZWR1bGUgZm9yIHN0YXJ0aW5nIGluc3RhbmNlcy4gKi9cbiAgcmVhZG9ubHkgc3RhcnRTY2hlZHVsZT86IFNjaGVkdWxlO1xuICAvKipcbiAgICogUGVyLWluc3RhbmNlIHBvbGxpbmcgbGltaXRzIGZvciB0aGUgcnVubmluZyBzY2hlZHVsZXIgTGFtYmRhLlxuICAgKlxuICAgKiBAZGVmYXVsdCB7QGxpbmsgREVGQVVMVF9SRVNPVVJDRV9QT0xMSU5HX0xJTUlUU31cbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlUG9sbGluZz86IFJlc291cmNlUG9sbGluZ0xpbWl0cztcbn1cblxuLyoqXG4gKiBQcm92aXNpb25zIEV2ZW50QnJpZGdlIFNjaGVkdWxlciBydWxlcyBhbmQgYSBEdXJhYmxlIEV4ZWN1dGlvbiBMYW1iZGEgdGhhdCBzdGFydC9zdG9wIHRhZ2dlZCBFQzIgaW5zdGFuY2VzLlxuICpcbiAqIEVhY2ggc2NoZWR1bGUgaW52b2tlcyB0aGUgZnVuY3Rpb24gd2l0aCBgUGFyYW1zYCAoYFRhZ0tleWAsIGBUYWdWYWx1ZXNgLCBgTW9kZWApLiBUaGUgZnVuY3Rpb24gdXNlc1xuICogdGhlIFJlc291cmNlIEdyb3VwcyBUYWdnaW5nIEFQSSBhbmQgRUMyIEFQSXM7IFNsYWNrIG5vdGlmaWNhdGlvbnMgdXNlIHRoZSBzZWNyZXQgbmFtZWQgaW4ge0BsaW5rIFNlY3JldHMuc2xhY2tTZWNyZXROYW1lfS5cbiAqXG4gKiBQZXItaW5zdGFuY2UgcG9sbGluZyB0aW1lb3V0cyBhcmUgY29uZmlndXJlZCB2aWEge0BsaW5rIEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlclByb3BzLnJlc291cmNlUG9sbGluZ31cbiAqIGFuZCBlbmZvcmNlZCBpbiB0aGUgaGFuZGxlciBiZWZvcmUgdGhlIER1cmFibGUgZXhlY3V0aW9uIHRpbWVvdXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFQzJJbnN0YW5jZVJ1bm5pbmdTY2hlZHVsZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogRGVmaW5lcyBJQU0sIGxvZ2dpbmcsIHR3byBjcm9uIHNjaGVkdWxlcyAoc3RhcnQvc3RvcCksIGFuZCB0aGUgYnVuZGxlZCBydW5uaW5nLXNjaGVkdWxlciBMYW1iZGEgKE5vZGUuanMsIER1cmFibGUgRXhlY3V0aW9uKS5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIC0gUGFyZW50IGNvbnN0cnVjdC5cbiAgICogQHBhcmFtIGlkIC0gQ29uc3RydWN0IGlkLlxuICAgKiBAcGFyYW0gcHJvcHMgLSBUYXJnZXQgdGFncywgc2NoZWR1bGVzLCBTbGFjayBzZWNyZXQsIHNjaGVkdWxlIGVuYWJsZSBmbGFnLCBhbmQgb3B0aW9uYWwge0BsaW5rIFJlc291cmNlUG9sbGluZ0xpbWl0c30uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qgc2xhY2tTZWNyZXQgPSBTZWNyZXQuZnJvbVNlY3JldE5hbWVWMih0aGlzLCAnU2xhY2tTZWNyZXQnLCBwcm9wcy5zZWNyZXRzLnNsYWNrU2VjcmV0TmFtZSk7XG5cbiAgICAvLyBEdXJhYmxlIEZ1bmN0aW9ucy1iYXNlZCBSdW5uaW5nIFNjaGVkdWxlciAocHJldmlvdXMgU3RlcCBGdW5jdGlvbnMgbG9naWMgaW1wbGVtZW50ZWQgaW4gTGFtYmRhKS5cbiAgICAvLyBEdXJhYmxlIEV4ZWN1dGlvbiByZXF1aXJlcyBOb2RlLmpzIDIyKy5cbiAgICBjb25zdCBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbiA9IG5ldyBSdW5uaW5nU2NoZWR1bGVyRnVuY3Rpb24odGhpcywgJ1J1bm5pbmdTY2hlZHVsZXJGdW5jdGlvbicsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnU3RhcnRzIGFuZCBzdG9wcyB0YWdnZWQgRUMyIGluc3RhbmNlcyBvbiBFdmVudEJyaWRnZSBTY2hlZHVsZXIgc2NoZWR1bGVzLicsXG4gICAgICBhcmNoaXRlY3R1cmU6IGxhbWJkYS5BcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgICBtZW1vcnlTaXplOiA1MTIsXG4gICAgICByZXRyeUF0dGVtcHRzOiAyLFxuICAgICAgZHVyYWJsZUNvbmZpZzoge1xuICAgICAgICBleGVjdXRpb25UaW1lb3V0OiBEdXJhdGlvbi5ob3VycygyKSxcbiAgICAgICAgcmV0ZW50aW9uUGVyaW9kOiBEdXJhdGlvbi5kYXlzKDEpLFxuICAgICAgfSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIFNMQUNLX1NFQ1JFVF9OQU1FOiBwcm9wcy5zZWNyZXRzLnNsYWNrU2VjcmV0TmFtZSxcbiAgICAgICAgW1BST0NFU1NfUkVTT1VSQ0VfTUFYX0xPT1BfQ09VTlRfRU5WXTogU3RyaW5nKFxuICAgICAgICAgIHByb3BzLnJlc291cmNlUG9sbGluZz8ubWF4TG9vcENvdW50ID8/IERFRkFVTFRfUkVTT1VSQ0VfUE9MTElOR19MSU1JVFMubWF4TG9vcENvdW50LFxuICAgICAgICApLFxuICAgICAgICBbUFJPQ0VTU19SRVNPVVJDRV9NQVhfRUxBUFNFRF9TRUNPTkRTX0VOVl06IFN0cmluZyhcbiAgICAgICAgICBwcm9wcy5yZXNvdXJjZVBvbGxpbmc/Lm1heEVsYXBzZWRTZWNvbmRzID8/IERFRkFVTFRfUkVTT1VSQ0VfUE9MTElOR19MSU1JVFMubWF4RWxhcHNlZFNlY29uZHMsXG4gICAgICAgICksXG4gICAgICB9LFxuICAgICAgcGFyYW1zQW5kU2VjcmV0czogbGFtYmRhLlBhcmFtc0FuZFNlY3JldHNMYXllclZlcnNpb24uZnJvbVZlcnNpb24obGFtYmRhLlBhcmFtc0FuZFNlY3JldHNWZXJzaW9ucy5WMV8wXzEwMywge1xuICAgICAgICBjYWNoZVNpemU6IDUwMCxcbiAgICAgICAgbG9nTGV2ZWw6IGxhbWJkYS5QYXJhbXNBbmRTZWNyZXRzTG9nTGV2ZWwuSU5GTyxcbiAgICAgIH0pLFxuICAgICAgcm9sZTogbmV3IGlhbS5Sb2xlKHRoaXMsICdSdW5uaW5nU2NoZWR1bGVyRnVuY3Rpb25Sb2xlJywge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0FsbG93cyB0aGUgcnVubmluZyBzY2hlZHVsZXIgdG8gZGVzY3JpYmUsIHN0YXJ0LCBhbmQgc3RvcCBFQzIgaW5zdGFuY2VzIGFuZCByZWFkIFNsYWNrIHNlY3JldHMuJyxcbiAgICAgICAgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2xhbWJkYS5hbWF6b25hd3MuY29tJyksXG4gICAgICAgIG1hbmFnZWRQb2xpY2llczogW1xuICAgICAgICAgIGlhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZSgnc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZScpLFxuICAgICAgICAgIGlhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZSgnc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRHVyYWJsZUV4ZWN1dGlvblJvbGVQb2xpY3knKSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICAgbG9nR3JvdXA6IG5ldyBsb2dzLkxvZ0dyb3VwKHRoaXMsICdSdW5uaW5nU2NoZWR1bGVyRnVuY3Rpb25Mb2dHcm91cCcsIHtcbiAgICAgICAgcmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuVEhSRUVfTU9OVEhTLFxuICAgICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICB9KSxcbiAgICAgIGxvZ2dpbmdGb3JtYXQ6IGxhbWJkYS5Mb2dnaW5nRm9ybWF0LkpTT04sXG4gICAgICBzeXN0ZW1Mb2dMZXZlbFYyOiBsYW1iZGEuU3lzdGVtTG9nTGV2ZWwuSU5GTyxcbiAgICAgIGFwcGxpY2F0aW9uTG9nTGV2ZWxWMjogbGFtYmRhLkFwcGxpY2F0aW9uTG9nTGV2ZWwuSU5GTyxcbiAgICB9KTtcbiAgICBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiAnR2V0UmVzb3VyY2VzJyxcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3RhZzpHZXRSZXNvdXJjZXMnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuICAgIC8vIEVDMjogZGVzY3JpYmUgaW5zdGFuY2VzIGFuZCBzdGFydC9zdG9wIGJ5IGluc3RhbmNlIGlkXG4gICAgcnVubmluZ1NjaGVkdWxlRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIHNpZDogJ0VjMlJ1bm5pbmdDb250cm9sJyxcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ2VjMjpEZXNjcmliZUluc3RhbmNlcycsXG4gICAgICAgICdlYzI6U3RhcnRJbnN0YW5jZXMnLFxuICAgICAgICAnZWMyOlN0b3BJbnN0YW5jZXMnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuICAgIC8vIEdyYW50IHJlYWQgYWNjZXNzIHRvIHRoZSBTbGFjayBzZWNyZXRcbiAgICBzbGFja1NlY3JldC5ncmFudFJlYWQocnVubmluZ1NjaGVkdWxlRnVuY3Rpb24pO1xuXG4gICAgLy8gU2VlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGFtYmRhL2xhdGVzdC9kZy9kdXJhYmxlLWdldHRpbmctc3RhcnRlZC1pYWMuaHRtbFxuICAgIGNvbnN0IHJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uQWxpYXMgPSBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbi5hZGRBbGlhcygnbGl2ZScpO1xuXG4gICAgLy8gV2hldGhlciBzY2hlZHVsZXMgYXJlIGVuYWJsZWQgKGRlZmF1bHQgdHJ1ZSB1bmxlc3MgZXhwbGljaXRseSBkaXNhYmxlZCkuXG4gICAgY29uc3Qgc2NoZWR1bGVFbmFibGVkOiBib29sZWFuID0gKCgpID0+IHtcbiAgICAgIGlmIChwcm9wcy5lbmFibGVTY2hlZHVsaW5nID09PSB1bmRlZmluZWQgfHwgcHJvcHMuZW5hYmxlU2NoZWR1bGluZykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgLy8gRHVyYWJsZSBGdW5jdGlvbnM6IExhbWJkYSBwZXJmb3JtcyB0YWcgbG9va3VwIGFuZCBpbnN0YW5jZSBzdGFydC9zdG9wIGluIGEgc2luZ2xlIHJ1bi5cbiAgICBuZXcgc2NoZWR1bGVyLlNjaGVkdWxlKHRoaXMsICdSdW5uaW5nU3RhcnRTY2hlZHVsZScsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAncnVubmluZyBzdGFydCBzY2hlZHVsZScsXG4gICAgICBlbmFibGVkOiBzY2hlZHVsZUVuYWJsZWQsXG4gICAgICBzY2hlZHVsZTogc2NoZWR1bGVyLlNjaGVkdWxlRXhwcmVzc2lvbi5jcm9uKHtcbiAgICAgICAgbWludXRlOiBwcm9wcy5zdGFydFNjaGVkdWxlPy5taW51dGUgPz8gJzUwJyxcbiAgICAgICAgaG91cjogcHJvcHMuc3RhcnRTY2hlZHVsZT8uaG91ciA/PyAnNycsXG4gICAgICAgIHdlZWtEYXk6IHByb3BzLnN0YXJ0U2NoZWR1bGU/LndlZWsgPz8gJ01PTi1GUkknLFxuICAgICAgICB0aW1lWm9uZTogcHJvcHMuc3RhcnRTY2hlZHVsZT8udGltZXpvbmUgPz8gVGltZVpvbmUuRVRDX1VUQyxcbiAgICAgIH0pLFxuICAgICAgdGFyZ2V0OiBuZXcgdGFyZ2V0cy5MYW1iZGFJbnZva2UocnVubmluZ1NjaGVkdWxlRnVuY3Rpb25BbGlhcywge1xuICAgICAgICBpbnB1dDogc2NoZWR1bGVyLlNjaGVkdWxlVGFyZ2V0SW5wdXQuZnJvbU9iamVjdCh7XG4gICAgICAgICAgUGFyYW1zOiB7XG4gICAgICAgICAgICBUYWdLZXk6IHByb3BzLnRhcmdldFJlc291cmNlLnRhZ0tleSxcbiAgICAgICAgICAgIFRhZ1ZhbHVlczogcHJvcHMudGFyZ2V0UmVzb3VyY2UudGFnVmFsdWVzLFxuICAgICAgICAgICAgTW9kZTogJ1N0YXJ0JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgbmV3IHNjaGVkdWxlci5TY2hlZHVsZSh0aGlzLCAnUnVubmluZ1N0b3BTY2hlZHVsZScsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAncnVubmluZyBzdG9wIHNjaGVkdWxlJyxcbiAgICAgIGVuYWJsZWQ6IHNjaGVkdWxlRW5hYmxlZCxcbiAgICAgIHNjaGVkdWxlOiBzY2hlZHVsZXIuU2NoZWR1bGVFeHByZXNzaW9uLmNyb24oe1xuICAgICAgICBtaW51dGU6IHByb3BzLnN0b3BTY2hlZHVsZT8ubWludXRlID8/ICc1JyxcbiAgICAgICAgaG91cjogcHJvcHMuc3RvcFNjaGVkdWxlPy5ob3VyID8/ICcxOScsXG4gICAgICAgIHdlZWtEYXk6IHByb3BzLnN0b3BTY2hlZHVsZT8ud2VlayA/PyAnTU9OLUZSSScsXG4gICAgICAgIHRpbWVab25lOiBwcm9wcy5zdG9wU2NoZWR1bGU/LnRpbWV6b25lID8/IFRpbWVab25lLkVUQ19VVEMsXG4gICAgICB9KSxcbiAgICAgIHRhcmdldDogbmV3IHRhcmdldHMuTGFtYmRhSW52b2tlKHJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uQWxpYXMsIHtcbiAgICAgICAgaW5wdXQ6IHNjaGVkdWxlci5TY2hlZHVsZVRhcmdldElucHV0LmZyb21PYmplY3Qoe1xuICAgICAgICAgIFBhcmFtczoge1xuICAgICAgICAgICAgVGFnS2V5OiBwcm9wcy50YXJnZXRSZXNvdXJjZS50YWdLZXksXG4gICAgICAgICAgICBUYWdWYWx1ZXM6IHByb3BzLnRhcmdldFJlc291cmNlLnRhZ1ZhbHVlcyxcbiAgICAgICAgICAgIE1vZGU6ICdTdG9wJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
194
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyLWluc3RhbmNlLXJ1bm5pbmctc2NoZWR1bGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnN0cnVjdHMvZWMyLWluc3RhbmNlLXJ1bm5pbmctc2NoZWR1bGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2Q0FBZ0U7QUFDaEUseURBQTJDO0FBQzNDLCtEQUFpRDtBQUNqRCwyREFBNkM7QUFDN0MscUVBQXVEO0FBQ3ZELDJFQUE2RDtBQUM3RCx1RUFBd0Q7QUFDeEQsMkNBQXVDO0FBQ3ZDLCtGQUkrQztBQUMvQyxvRkFBK0U7QUFDL0Usd0ZBQXFGO0FBQ3JGLDBGQUdnRDtBQThGaEQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBYSwyQkFBNEIsU0FBUSxzQkFBUzs7SUFDeEQsMkdBQTJHO0lBQzNGLGdCQUFnQixDQUFvQztJQUVwRTs7Ozs7Ozs7T0FRRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUM7UUFDL0UsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLFdBQVcsR0FBRywyQkFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUVoRyxtR0FBbUc7UUFDbkcsMENBQTBDO1FBQzFDLE1BQU0sK0JBQStCLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxrQ0FBa0MsRUFBRTtZQUNsRyxTQUFTLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZO1lBQzFDLGFBQWEsRUFBRSwyQkFBYSxDQUFDLE9BQU87U0FDckMsQ0FBQyxDQUFDO1FBRUgsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLHFEQUF3QixDQUFDLElBQUksRUFBRSwwQkFBMEIsRUFBRTtZQUM3RixXQUFXLEVBQUUsMkVBQTJF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Q0FBQyxDQUFDO1FBRUgsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxxQkFBcUIsRUFBRTtZQUNsRCxXQUFXLEVBQUUsdUJBQXVCO1lBQ3BDLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLFFBQVEsRUFBRSxTQUFTLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDO2dCQUMxQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFlBQVksRUFBRSxNQUFNLElBQUksR0FBRztnQkFDekMsSUFBSSxFQUFFLEtBQUssQ0FBQyxZQUFZLEVBQUUsSUFBSSxJQUFJLElBQUk7Z0JBQ3RDLE9BQU8sRUFBRSxLQUFLLENBQUMsWUFBWSxFQUFFLElBQUksSUFBSSxTQUFTO2dCQUM5QyxRQUFRLEVBQUUsS0FBSyxDQUFDLFlBQVksRUFBRSxRQUFRLElBQUksc0JBQVEsQ0FBQyxPQUFPO2FBQzNELENBQUM7WUFDRixNQUFNLEVBQUUsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLDRCQUE0QixFQUFFO2dCQUM3RCxLQUFLLEVBQUUsU0FBUyxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQztvQkFDOUMsTUFBTSxFQUFFO3dCQUNOLE1BQU0sRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU07d0JBQ25DLFNBQVMsRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLFNBQVM7d0JBQ3pDLElBQUksRUFBRSxNQUFNO3FCQUNiO2lCQUNGLENBQUM7YUFDSCxDQUFDO1NBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUE5SUgsa0VBK0lDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHVyYXRpb24sIFJlbW92YWxQb2xpY3ksIFRpbWVab25lIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzY2hlZHVsZXIgZnJvbSAnYXdzLWNkay1saWIvYXdzLXNjaGVkdWxlcic7XG5pbXBvcnQgKiBhcyB0YXJnZXRzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zY2hlZHVsZXItdGFyZ2V0cyc7XG5pbXBvcnQgeyBTZWNyZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQge1xuICBjcmVhdGVSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvbixcbiAgdHlwZSBGYWlsdXJlRGV0ZWN0aW9uQWxhcm1zLFxuICB0eXBlIFJ1bm5pbmdTY2hlZHVsZXJGYWlsdXJlRGV0ZWN0aW9uLFxufSBmcm9tICcuL3J1bm5pbmctc2NoZWR1bGVyLWZhaWx1cmUtZGV0ZWN0aW9uJztcbmltcG9ydCB7IFJ1bm5pbmdTY2hlZHVsZXJGdW5jdGlvbiB9IGZyb20gJy4uL2Z1bmNzL3J1bm5pbmctc2NoZWR1bGVyLWZ1bmN0aW9uJztcbmltcG9ydCB7IERFRkFVTFRfUkVTT1VSQ0VfV0FJVF9MSU1JVFMgfSBmcm9tICcuLi9mdW5jcy9ydW5uaW5nLXNjaGVkdWxlci1wcmVkaWNhdGVzJztcbmltcG9ydCB7XG4gIFBST0NFU1NfUkVTT1VSQ0VfTUFYX0VMQVBTRURfU0VDT05EU19FTlYsXG4gIFBST0NFU1NfUkVTT1VSQ0VfTUFYX0xPT1BfQ09VTlRfRU5WLFxufSBmcm9tICcuLi9mdW5jcy9ydW5uaW5nLXNjaGVkdWxlci13YWl0LWNvbmZpZyc7XG5cbmV4cG9ydCB0eXBlIHtcbiAgRmFpbHVyZURldGVjdGlvbkFsYXJtcyxcbiAgUnVubmluZ1NjaGVkdWxlckZhaWx1cmVEZXRlY3Rpb24sXG4gIFJ1bm5pbmdTY2hlZHVsZXJGYWlsdXJlRGV0ZWN0aW9uUHJvcHMsXG59IGZyb20gJy4vcnVubmluZy1zY2hlZHVsZXItZmFpbHVyZS1kZXRlY3Rpb24nO1xuXG4vKipcbiAqIENyb24tc3R5bGUgc2NoZWR1bGUgY29uZmlndXJhdGlvbiBmb3Igc3RhcnQvc3RvcCBhY3Rpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjaGVkdWxlIHtcbiAgLyoqIFRpbWUgem9uZSBmb3IgdGhlIHNjaGVkdWxlIChlLmcuIEVUQ19VVEMpLiAqL1xuICByZWFkb25seSB0aW1lem9uZTogVGltZVpvbmU7XG4gIC8qKiBDcm9uIG1pbnV0ZSAoMOKAkzU5KS4gKi9cbiAgcmVhZG9ubHkgbWludXRlPzogc3RyaW5nO1xuICAvKiogQ3JvbiBob3VyICgw4oCTMjMpLiAqL1xuICByZWFkb25seSBob3VyPzogc3RyaW5nO1xuICAvKiogQ3JvbiBkYXkgb2Ygd2VlayAoZS5nLiBNT04tRlJJKS4gKi9cbiAgcmVhZG9ubHkgd2Vlaz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZWZpbmVzIHdoaWNoIEVDMiBpbnN0YW5jZXMgYXJlIHRhcmdldGVkIGJ5IHRhZyBrZXkgYW5kIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUYXJnZXRSZXNvdXJjZSB7XG4gIC8qKiBUYWcga2V5IHVzZWQgdG8gc2VsZWN0IGluc3RhbmNlcyAoZS5nLiBTY2hlZHVsZSkuICovXG4gIHJlYWRvbmx5IHRhZ0tleTogc3RyaW5nO1xuICAvKiogVGFnIHZhbHVlcyB0aGF0IG1hdGNoIGluc3RhbmNlcyB0byBpbmNsdWRlLiAqL1xuICByZWFkb25seSB0YWdWYWx1ZXM6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFNlY3JldCBpZGVudGlmaWVycyByZXF1aXJlZCBieSB0aGUgc2NoZWR1bGVyIChlLmcuIFNsYWNrKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWNyZXRzIHtcbiAgLyoqIE5hbWUgb2YgdGhlIFNlY3JldHMgTWFuYWdlciBzZWNyZXQgY29udGFpbmluZyBTbGFjayB0b2tlbiBhbmQgY2hhbm5lbC4gKi9cbiAgcmVhZG9ubHkgc2xhY2tTZWNyZXROYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ0RLLXNpZGUgbGltaXRzIGZvciBwZXItaW5zdGFuY2Ugc3RhYmxlLXN0YXRlIHdhaXRpbmcgaW4gdGhlIER1cmFibGUgTGFtYmRhIGhhbmRsZXIuXG4gKlxuICogT3B0aW9uYWwgZmllbGRzIG1hcCB0byB7QGxpbmsgUFJPQ0VTU19SRVNPVVJDRV9NQVhfTE9PUF9DT1VOVF9FTlZ9IGFuZFxuICoge0BsaW5rIFBST0NFU1NfUkVTT1VSQ0VfTUFYX0VMQVBTRURfU0VDT05EU19FTlZ9IG9uIHRoZSBydW5uaW5nIHNjaGVkdWxlciBmdW5jdGlvbi5cbiAqIFByZXZlbnRzIGFibm9ybWFsIG9yIHN0dWNrIHRyYW5zaXRpb25zIGZyb20gcnVubmluZyB1bnRpbCB0aGUgRHVyYWJsZSBleGVjdXRpb24gdGltZW91dC5cbiAqXG4gKiBAc2VlIHtAbGluayBSZXNvdXJjZVdhaXRMaW1pdHN9IGluIGBydW5uaW5nLXNjaGVkdWxlci1wcmVkaWNhdGVzLnRzYCBmb3IgdGhlIGhhbmRsZXItc2lkZSByZXF1aXJlZCBzaGFwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZVdhaXRMaW1pdHMge1xuICAvKipcbiAgICogTWF4aW11bSBkZXNjcmliZS93YWl0IGxvb3AgaXRlcmF0aW9ucyBwZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IHtAbGluayBERUZBVUxUX1JFU09VUkNFX1dBSVRfTElNSVRTLm1heExvb3BDb3VudH0gKDkwKVxuICAgKi9cbiAgcmVhZG9ubHkgbWF4TG9vcENvdW50PzogbnVtYmVyO1xuICAvKipcbiAgICogTWF4aW11bSB3YWxsLWNsb2NrIHNlY29uZHMgc3BlbnQgd2FpdGluZyBmb3IgYSBzaW5nbGUgaW5zdGFuY2UgdG8gc3RhYmlsaXplLlxuICAgKlxuICAgKiBAZGVmYXVsdCB7QGxpbmsgREVGQVVMVF9SRVNPVVJDRV9XQUlUX0xJTUlUUy5tYXhFbGFwc2VkU2Vjb25kc30gKDE4MDAsIDMwIG1pbnV0ZXMpXG4gICAqL1xuICByZWFkb25seSBtYXhFbGFwc2VkU2Vjb25kcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBjcmVhdGluZyBhbiBFQzIgaW5zdGFuY2UgcnVubmluZyBzY2hlZHVsZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyUHJvcHMge1xuICAvKiogVGFnLWJhc2VkIHRhcmdldGluZyBmb3IgRUMyIGluc3RhbmNlcyB0byBzdGFydC9zdG9wLiAqL1xuICByZWFkb25seSB0YXJnZXRSZXNvdXJjZTogVGFyZ2V0UmVzb3VyY2U7XG4gIC8qKiBXaGV0aGVyIEV2ZW50QnJpZGdlIFNjaGVkdWxlciBydWxlcyBhcmUgZW5hYmxlZC4gRGVmYXVsdHMgdG8gdHJ1ZSBpZiBvbWl0dGVkLiAqL1xuICByZWFkb25seSBlbmFibGVTY2hlZHVsaW5nPzogYm9vbGVhbjtcbiAgLyoqIFNlY3JldHMgKGUuZy4gU2xhY2spIHVzZWQgZm9yIG5vdGlmaWNhdGlvbnMuICovXG4gIHJlYWRvbmx5IHNlY3JldHM6IFNlY3JldHM7XG4gIC8qKiBDcm9uIHNjaGVkdWxlIGZvciBzdG9wcGluZyBpbnN0YW5jZXMuICovXG4gIHJlYWRvbmx5IHN0b3BTY2hlZHVsZT86IFNjaGVkdWxlO1xuICAvKiogQ3JvbiBzY2hlZHVsZSBmb3Igc3RhcnRpbmcgaW5zdGFuY2VzLiAqL1xuICByZWFkb25seSBzdGFydFNjaGVkdWxlPzogU2NoZWR1bGU7XG4gIC8qKlxuICAgKiBQZXItaW5zdGFuY2Ugd2FpdCBsaW1pdHMgZm9yIHRoZSBydW5uaW5nIHNjaGVkdWxlciBMYW1iZGEuXG4gICAqXG4gICAqIEBkZWZhdWx0IHtAbGluayBERUZBVUxUX1JFU09VUkNFX1dBSVRfTElNSVRTfVxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VXYWl0PzogUmVzb3VyY2VXYWl0TGltaXRzO1xuICAvKipcbiAgICogT3B0aW9uYWwgQ2xvdWRXYXRjaCBhbGFybXMgYW5kIGxvZy1iYXNlZCBtZXRyaWNzIGZvciBmYWlsdXJlIGRldGVjdGlvbi5cbiAgICpcbiAgICogU2V0IGBlbmFibGVkOiB0cnVlYCB0byBjcmVhdGUgYWxhcm1zOyBvcHRpb25hbGx5IHBhc3MgYGFsYXJtVG9waWNgIGZvciBTTlMgbm90aWZpY2F0aW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgZGlzYWJsZWQgd2hlbiBvbWl0dGVkXG4gICAqL1xuICByZWFkb25seSBmYWlsdXJlRGV0ZWN0aW9uPzogRmFpbHVyZURldGVjdGlvbkFsYXJtcztcbn1cblxuLyoqXG4gKiBQcm92aXNpb25zIEV2ZW50QnJpZGdlIFNjaGVkdWxlciBydWxlcyBhbmQgYSBEdXJhYmxlIEV4ZWN1dGlvbiBMYW1iZGEgdGhhdCBzdGFydC9zdG9wIHRhZ2dlZCBFQzIgaW5zdGFuY2VzLlxuICpcbiAqIEVhY2ggc2NoZWR1bGUgaW52b2tlcyB0aGUgZnVuY3Rpb24gd2l0aCBgUGFyYW1zYCAoYFRhZ0tleWAsIGBUYWdWYWx1ZXNgLCBgTW9kZWApLiBUaGUgZnVuY3Rpb24gdXNlc1xuICogdGhlIFJlc291cmNlIEdyb3VwcyBUYWdnaW5nIEFQSSBhbmQgRUMyIEFQSXM7IFNsYWNrIG5vdGlmaWNhdGlvbnMgdXNlIHRoZSBzZWNyZXQgbmFtZWQgaW4ge0BsaW5rIFNlY3JldHMuc2xhY2tTZWNyZXROYW1lfS5cbiAqXG4gKiBQZXItaW5zdGFuY2Ugd2FpdCB0aW1lb3V0cyBhcmUgY29uZmlndXJlZCB2aWEge0BsaW5rIEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlclByb3BzLnJlc291cmNlV2FpdH1cbiAqIGFuZCBlbmZvcmNlZCBpbiB0aGUgaGFuZGxlciBiZWZvcmUgdGhlIER1cmFibGUgZXhlY3V0aW9uIHRpbWVvdXQuIE9wdGlvbmFsIENsb3VkV2F0Y2ggZmFpbHVyZVxuICogZGV0ZWN0aW9uIGlzIGF2YWlsYWJsZSB2aWEge0BsaW5rIEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlclByb3BzLmZhaWx1cmVEZXRlY3Rpb259LlxuICovXG5leHBvcnQgY2xhc3MgRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqIEZhaWx1cmUgZGV0ZWN0aW9uIGFsYXJtcywgd2hlbiB7QGxpbmsgRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyUHJvcHMuZmFpbHVyZURldGVjdGlvbn0gaXMgZW5hYmxlZC4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGZhaWx1cmVEZXRlY3Rpb24/OiBSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvbjtcblxuICAvKipcbiAgICogRGVmaW5lcyBJQU0sIGxvZ2dpbmcsIG9wdGlvbmFsIGZhaWx1cmUgZGV0ZWN0aW9uIGFsYXJtcywgdHdvIGNyb24gc2NoZWR1bGVzIChzdGFydC9zdG9wKSxcbiAgICogYW5kIHRoZSBidW5kbGVkIHJ1bm5pbmctc2NoZWR1bGVyIExhbWJkYSAoTm9kZS5qcywgRHVyYWJsZSBFeGVjdXRpb24pLlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgLSBQYXJlbnQgY29uc3RydWN0LlxuICAgKiBAcGFyYW0gaWQgLSBDb25zdHJ1Y3QgaWQuXG4gICAqIEBwYXJhbSBwcm9wcyAtIFRhcmdldCB0YWdzLCBzY2hlZHVsZXMsIFNsYWNrIHNlY3JldCwgc2NoZWR1bGUgZW5hYmxlIGZsYWcsIG9wdGlvbmFsXG4gICAqICAge0BsaW5rIFJlc291cmNlV2FpdExpbWl0c30sIGFuZCBvcHRpb25hbCB7QGxpbmsgRmFpbHVyZURldGVjdGlvbkFsYXJtc30uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qgc2xhY2tTZWNyZXQgPSBTZWNyZXQuZnJvbVNlY3JldE5hbWVWMih0aGlzLCAnU2xhY2tTZWNyZXQnLCBwcm9wcy5zZWNyZXRzLnNsYWNrU2VjcmV0TmFtZSk7XG5cbiAgICAvLyBEdXJhYmxlIEZ1bmN0aW9ucy1iYXNlZCBSdW5uaW5nIFNjaGVkdWxlciAocHJldmlvdXMgU3RlcCBGdW5jdGlvbnMgbG9naWMgaW1wbGVtZW50ZWQgaW4gTGFtYmRhKS5cbiAgICAvLyBEdXJhYmxlIEV4ZWN1dGlvbiByZXF1aXJlcyBOb2RlLmpzIDIyKy5cbiAgICBjb25zdCBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbkxvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcywgJ1J1bm5pbmdTY2hlZHVsZXJGdW5jdGlvbkxvZ0dyb3VwJywge1xuICAgICAgcmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuVEhSRUVfTU9OVEhTLFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcnVubmluZ1NjaGVkdWxlRnVuY3Rpb24gPSBuZXcgUnVubmluZ1NjaGVkdWxlckZ1bmN0aW9uKHRoaXMsICdSdW5uaW5nU2NoZWR1bGVyRnVuY3Rpb24nLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1N0YXJ0cyBhbmQgc3RvcHMgdGFnZ2VkIEVDMiBpbnN0YW5jZXMgb24gRXZlbnRCcmlkZ2UgU2NoZWR1bGVyIHNjaGVkdWxlcy4nLFxuICAgICAgYXJjaGl0ZWN0dXJlOiBsYW1iZGEuQXJjaGl0ZWN0dXJlLkFSTV82NCxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMTUpLFxuICAgICAgbWVtb3J5U2l6ZTogNTEyLFxuICAgICAgcmV0cnlBdHRlbXB0czogMixcbiAgICAgIGR1cmFibGVDb25maWc6IHtcbiAgICAgICAgZXhlY3V0aW9uVGltZW91dDogRHVyYXRpb24uaG91cnMoMiksXG4gICAgICAgIHJldGVudGlvblBlcmlvZDogRHVyYXRpb24uZGF5cygxKSxcbiAgICAgIH0sXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBTTEFDS19TRUNSRVRfTkFNRTogcHJvcHMuc2VjcmV0cy5zbGFja1NlY3JldE5hbWUsXG4gICAgICAgIFtQUk9DRVNTX1JFU09VUkNFX01BWF9MT09QX0NPVU5UX0VOVl06IFN0cmluZyhcbiAgICAgICAgICBwcm9wcy5yZXNvdXJjZVdhaXQ/Lm1heExvb3BDb3VudCA/PyBERUZBVUxUX1JFU09VUkNFX1dBSVRfTElNSVRTLm1heExvb3BDb3VudCxcbiAgICAgICAgKSxcbiAgICAgICAgW1BST0NFU1NfUkVTT1VSQ0VfTUFYX0VMQVBTRURfU0VDT05EU19FTlZdOiBTdHJpbmcoXG4gICAgICAgICAgcHJvcHMucmVzb3VyY2VXYWl0Py5tYXhFbGFwc2VkU2Vjb25kcyA/PyBERUZBVUxUX1JFU09VUkNFX1dBSVRfTElNSVRTLm1heEVsYXBzZWRTZWNvbmRzLFxuICAgICAgICApLFxuICAgICAgfSxcbiAgICAgIHBhcmFtc0FuZFNlY3JldHM6IGxhbWJkYS5QYXJhbXNBbmRTZWNyZXRzTGF5ZXJWZXJzaW9uLmZyb21WZXJzaW9uKGxhbWJkYS5QYXJhbXNBbmRTZWNyZXRzVmVyc2lvbnMuVjFfMF8xMDMsIHtcbiAgICAgICAgLy8gUmVxdWlyZWQgYnkgYXdzLWxhbWJkYS1zZWNyZXQtZmV0Y2hlciAoZXh0ZW5zaW9uIEhUVFAgQVBJIG9uIGxvY2FsaG9zdDsgcG9ydCBmcm9tIFBBUkFNRVRFUlNfU0VDUkVUU19FWFRFTlNJT05fSFRUUF9QT1JUKS5cbiAgICAgICAgY2FjaGVTaXplOiA1MDAsXG4gICAgICAgIGxvZ0xldmVsOiBsYW1iZGEuUGFyYW1zQW5kU2VjcmV0c0xvZ0xldmVsLklORk8sXG4gICAgICB9KSxcbiAgICAgIHJvbGU6IG5ldyBpYW0uUm9sZSh0aGlzLCAnUnVubmluZ1NjaGVkdWxlckZ1bmN0aW9uUm9sZScsIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdBbGxvd3MgdGhlIHJ1bm5pbmcgc2NoZWR1bGVyIHRvIGRlc2NyaWJlLCBzdGFydCwgYW5kIHN0b3AgRUMyIGluc3RhbmNlcyBhbmQgcmVhZCBTbGFjayBzZWNyZXRzLicsXG4gICAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdsYW1iZGEuYW1hem9uYXdzLmNvbScpLFxuICAgICAgICBtYW5hZ2VkUG9saWNpZXM6IFtcbiAgICAgICAgICBpYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoJ3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUnKSxcbiAgICAgICAgICBpYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoJ3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0R1cmFibGVFeGVjdXRpb25Sb2xlUG9saWN5JyksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICAgIGxvZ0dyb3VwOiBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbkxvZ0dyb3VwLFxuICAgICAgbG9nZ2luZ0Zvcm1hdDogbGFtYmRhLkxvZ2dpbmdGb3JtYXQuSlNPTixcbiAgICAgIHN5c3RlbUxvZ0xldmVsVjI6IGxhbWJkYS5TeXN0ZW1Mb2dMZXZlbC5JTkZPLFxuICAgICAgYXBwbGljYXRpb25Mb2dMZXZlbFYyOiBsYW1iZGEuQXBwbGljYXRpb25Mb2dMZXZlbC5JTkZPLFxuICAgIH0pO1xuICAgIHJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6ICdHZXRSZXNvdXJjZXMnLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogW1xuICAgICAgICAndGFnOkdldFJlc291cmNlcycsXG4gICAgICBdLFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICB9KSk7XG4gICAgLy8gRUMyOiBkZXNjcmliZSBpbnN0YW5jZXMgYW5kIHN0YXJ0L3N0b3AgYnkgaW5zdGFuY2UgaWRcbiAgICBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiAnRWMyUnVubmluZ0NvbnRyb2wnLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogW1xuICAgICAgICAnZWMyOkRlc2NyaWJlSW5zdGFuY2VzJyxcbiAgICAgICAgJ2VjMjpTdGFydEluc3RhbmNlcycsXG4gICAgICAgICdlYzI6U3RvcEluc3RhbmNlcycsXG4gICAgICBdLFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICB9KSk7XG4gICAgLy8gR3JhbnQgcmVhZCBhY2Nlc3MgdG8gdGhlIFNsYWNrIHNlY3JldFxuICAgIHNsYWNrU2VjcmV0LmdyYW50UmVhZChydW5uaW5nU2NoZWR1bGVGdW5jdGlvbik7XG5cbiAgICB0aGlzLmZhaWx1cmVEZXRlY3Rpb24gPSBjcmVhdGVSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvbih0aGlzLCAnRmFpbHVyZURldGVjdGlvbicsIHtcbiAgICAgIGZhaWx1cmVEZXRlY3Rpb246IHByb3BzLmZhaWx1cmVEZXRlY3Rpb24sXG4gICAgICBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbixcbiAgICAgIGxvZ0dyb3VwOiBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbkxvZ0dyb3VwLFxuICAgIH0pO1xuXG4gICAgLy8gU2VlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGFtYmRhL2xhdGVzdC9kZy9kdXJhYmxlLWdldHRpbmctc3RhcnRlZC1pYWMuaHRtbFxuICAgIGNvbnN0IHJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uQWxpYXMgPSBydW5uaW5nU2NoZWR1bGVGdW5jdGlvbi5hZGRBbGlhcygnbGl2ZScpO1xuXG4gICAgLy8gV2hldGhlciBzY2hlZHVsZXMgYXJlIGVuYWJsZWQgKGRlZmF1bHQgdHJ1ZSB1bmxlc3MgZXhwbGljaXRseSBkaXNhYmxlZCkuXG4gICAgY29uc3Qgc2NoZWR1bGVFbmFibGVkOiBib29sZWFuID0gKCgpID0+IHtcbiAgICAgIGlmIChwcm9wcy5lbmFibGVTY2hlZHVsaW5nID09PSB1bmRlZmluZWQgfHwgcHJvcHMuZW5hYmxlU2NoZWR1bGluZykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgLy8gRHVyYWJsZSBGdW5jdGlvbnM6IExhbWJkYSBwZXJmb3JtcyB0YWcgbG9va3VwIGFuZCBpbnN0YW5jZSBzdGFydC9zdG9wIGluIGEgc2luZ2xlIHJ1bi5cbiAgICBuZXcgc2NoZWR1bGVyLlNjaGVkdWxlKHRoaXMsICdSdW5uaW5nU3RhcnRTY2hlZHVsZScsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAncnVubmluZyBzdGFydCBzY2hlZHVsZScsXG4gICAgICBlbmFibGVkOiBzY2hlZHVsZUVuYWJsZWQsXG4gICAgICBzY2hlZHVsZTogc2NoZWR1bGVyLlNjaGVkdWxlRXhwcmVzc2lvbi5jcm9uKHtcbiAgICAgICAgbWludXRlOiBwcm9wcy5zdGFydFNjaGVkdWxlPy5taW51dGUgPz8gJzUwJyxcbiAgICAgICAgaG91cjogcHJvcHMuc3RhcnRTY2hlZHVsZT8uaG91ciA/PyAnNycsXG4gICAgICAgIHdlZWtEYXk6IHByb3BzLnN0YXJ0U2NoZWR1bGU/LndlZWsgPz8gJ01PTi1GUkknLFxuICAgICAgICB0aW1lWm9uZTogcHJvcHMuc3RhcnRTY2hlZHVsZT8udGltZXpvbmUgPz8gVGltZVpvbmUuRVRDX1VUQyxcbiAgICAgIH0pLFxuICAgICAgdGFyZ2V0OiBuZXcgdGFyZ2V0cy5MYW1iZGFJbnZva2UocnVubmluZ1NjaGVkdWxlRnVuY3Rpb25BbGlhcywge1xuICAgICAgICBpbnB1dDogc2NoZWR1bGVyLlNjaGVkdWxlVGFyZ2V0SW5wdXQuZnJvbU9iamVjdCh7XG4gICAgICAgICAgUGFyYW1zOiB7XG4gICAgICAgICAgICBUYWdLZXk6IHByb3BzLnRhcmdldFJlc291cmNlLnRhZ0tleSxcbiAgICAgICAgICAgIFRhZ1ZhbHVlczogcHJvcHMudGFyZ2V0UmVzb3VyY2UudGFnVmFsdWVzLFxuICAgICAgICAgICAgTW9kZTogJ1N0YXJ0JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgbmV3IHNjaGVkdWxlci5TY2hlZHVsZSh0aGlzLCAnUnVubmluZ1N0b3BTY2hlZHVsZScsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAncnVubmluZyBzdG9wIHNjaGVkdWxlJyxcbiAgICAgIGVuYWJsZWQ6IHNjaGVkdWxlRW5hYmxlZCxcbiAgICAgIHNjaGVkdWxlOiBzY2hlZHVsZXIuU2NoZWR1bGVFeHByZXNzaW9uLmNyb24oe1xuICAgICAgICBtaW51dGU6IHByb3BzLnN0b3BTY2hlZHVsZT8ubWludXRlID8/ICc1JyxcbiAgICAgICAgaG91cjogcHJvcHMuc3RvcFNjaGVkdWxlPy5ob3VyID8/ICcxOScsXG4gICAgICAgIHdlZWtEYXk6IHByb3BzLnN0b3BTY2hlZHVsZT8ud2VlayA/PyAnTU9OLUZSSScsXG4gICAgICAgIHRpbWVab25lOiBwcm9wcy5zdG9wU2NoZWR1bGU/LnRpbWV6b25lID8/IFRpbWVab25lLkVUQ19VVEMsXG4gICAgICB9KSxcbiAgICAgIHRhcmdldDogbmV3IHRhcmdldHMuTGFtYmRhSW52b2tlKHJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uQWxpYXMsIHtcbiAgICAgICAgaW5wdXQ6IHNjaGVkdWxlci5TY2hlZHVsZVRhcmdldElucHV0LmZyb21PYmplY3Qoe1xuICAgICAgICAgIFBhcmFtczoge1xuICAgICAgICAgICAgVGFnS2V5OiBwcm9wcy50YXJnZXRSZXNvdXJjZS50YWdLZXksXG4gICAgICAgICAgICBUYWdWYWx1ZXM6IHByb3BzLnRhcmdldFJlc291cmNlLnRhZ1ZhbHVlcyxcbiAgICAgICAgICAgIE1vZGU6ICdTdG9wJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,87 @@
1
+ import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
2
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
3
+ import * as logs from 'aws-cdk-lib/aws-logs';
4
+ import * as sns from 'aws-cdk-lib/aws-sns';
5
+ import { Construct } from 'constructs';
6
+ /**
7
+ * Props accepted by {@link createRunningSchedulerFailureDetection}.
8
+ */
9
+ interface CreateRunningSchedulerFailureDetectionProps {
10
+ /** Failure detection options; alarms are created only when {@link FailureDetectionAlarms.enabled} is true. */
11
+ readonly failureDetection?: FailureDetectionAlarms;
12
+ /** Running scheduler Lambda to monitor. */
13
+ readonly runningScheduleFunction: lambda.IFunction;
14
+ /** Application log group for the running scheduler Lambda. */
15
+ readonly logGroup: logs.ILogGroup;
16
+ }
17
+ /**
18
+ * Optional CloudWatch alarms and log-based metrics for operational failure detection.
19
+ *
20
+ * When {@link FailureDetectionAlarms.enabled} is true, the construct creates alarms for Lambda
21
+ * errors, Durable handler failures, EC2 instance status wait failures, and Slack post failures.
22
+ * Alarms can optionally notify an SNS topic supplied by the caller.
23
+ */
24
+ export interface FailureDetectionAlarms {
25
+ /**
26
+ * When true, creates failure detection alarms and log-based metrics.
27
+ *
28
+ * @default false when omitted
29
+ */
30
+ readonly enabled?: boolean;
31
+ /**
32
+ * SNS topic for alarm notifications.
33
+ *
34
+ * When omitted, alarms are created without SNS actions.
35
+ */
36
+ readonly alarmTopic?: sns.ITopic;
37
+ }
38
+ /**
39
+ * Props for {@link RunningSchedulerFailureDetection}.
40
+ */
41
+ export interface RunningSchedulerFailureDetectionProps {
42
+ /** Alarm configuration (must have {@link FailureDetectionAlarms.enabled} true). */
43
+ readonly failureDetection: FailureDetectionAlarms;
44
+ /** Running scheduler Lambda to monitor. */
45
+ readonly runningScheduleFunction: lambda.IFunction;
46
+ /** Application log group for the running scheduler Lambda. */
47
+ readonly logGroup: logs.ILogGroup;
48
+ }
49
+ /**
50
+ * CloudWatch alarms and log-based metrics for the running scheduler Lambda.
51
+ *
52
+ * When enabled, creates four alarms:
53
+ * - `lambdaErrorsAlarm` – `AWS/Lambda` `Errors` metric.
54
+ * - `instanceStatusFailureAlarm` – log filter for `ResourceWaitFailed:*`.
55
+ * - `slackPostFailureAlarm` – log filter for `running-scheduler: Slack post failed`.
56
+ * - `durableExecutionFailureAlarm` – other handler-level `ERROR` logs (excluding the above).
57
+ *
58
+ * Custom metrics are published under the `EC2InstanceRunningScheduler` namespace.
59
+ */
60
+ export declare class RunningSchedulerFailureDetection extends Construct {
61
+ /** SNS topic used for alarm actions, when configured. */
62
+ readonly alarmTopic?: sns.ITopic;
63
+ /** Fires when the Lambda `Errors` metric is non-zero. */
64
+ readonly lambdaErrorsAlarm: cloudwatch.Alarm;
65
+ /** Fires on handler-level ERROR logs outside instance waiting and Slack post failures. */
66
+ readonly durableExecutionFailureAlarm: cloudwatch.Alarm;
67
+ /** Fires when instance stable-state waiting fails (`ResourceWaitFailed:*`). */
68
+ readonly instanceStatusFailureAlarm: cloudwatch.Alarm;
69
+ /** Fires when Slack `chat.postMessage` fails. */
70
+ readonly slackPostFailureAlarm: cloudwatch.Alarm;
71
+ /**
72
+ * @param scope - Parent construct.
73
+ * @param id - Construct id.
74
+ * @param props - Lambda, log group, and {@link FailureDetectionAlarms} (must have `enabled: true`).
75
+ */
76
+ constructor(scope: Construct, id: string, props: RunningSchedulerFailureDetectionProps);
77
+ }
78
+ /**
79
+ * Creates failure detection alarms when enabled in props.
80
+ *
81
+ * @param scope - Parent construct.
82
+ * @param id - Construct id.
83
+ * @param props - Lambda, log group, and optional alarm configuration.
84
+ * @returns Failure detection construct, or undefined when disabled.
85
+ */
86
+ export declare const createRunningSchedulerFailureDetection: (scope: Construct, id: string, props: CreateRunningSchedulerFailureDetectionProps) => RunningSchedulerFailureDetection | undefined;
87
+ export {};
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createRunningSchedulerFailureDetection = exports.RunningSchedulerFailureDetection = void 0;
37
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
38
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
39
+ const cloudwatch = __importStar(require("aws-cdk-lib/aws-cloudwatch"));
40
+ const cloudwatch_actions = __importStar(require("aws-cdk-lib/aws-cloudwatch-actions"));
41
+ const logs = __importStar(require("aws-cdk-lib/aws-logs"));
42
+ const constructs_1 = require("constructs");
43
+ /** CloudWatch custom metric namespace for log-based failure detection metrics. */
44
+ const METRIC_NAMESPACE = 'EC2InstanceRunningScheduler';
45
+ const isFailureDetectionEnabled = (failureDetection) => failureDetection.enabled === true;
46
+ /**
47
+ * Registers an SNS alarm action when a topic is configured.
48
+ *
49
+ * @param alarm - CloudWatch alarm to notify.
50
+ * @param alarmTopic - Optional SNS topic from {@link FailureDetectionAlarms.alarmTopic}.
51
+ */
52
+ const attachAlarmActions = (alarm, alarmTopic) => {
53
+ if (!alarmTopic) {
54
+ return;
55
+ }
56
+ alarm.addAlarmAction(new cloudwatch_actions.SnsAction(alarmTopic));
57
+ };
58
+ /**
59
+ * Creates a CloudWatch alarm that fires when a sum metric is greater than or equal to 1.
60
+ *
61
+ * Uses `treatMissingData: notBreaching` so scheduled invocations do not alarm between runs.
62
+ *
63
+ * @param scope - Parent construct.
64
+ * @param id - Alarm construct id.
65
+ * @param props - Metric to alarm on and optional SNS topic.
66
+ * @returns Configured CloudWatch alarm.
67
+ */
68
+ const createLogSumAlarm = (scope, id, props) => {
69
+ const alarm = new cloudwatch.Alarm(scope, id, {
70
+ metric: props.metric,
71
+ threshold: 1,
72
+ comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
73
+ evaluationPeriods: 1,
74
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
75
+ });
76
+ attachAlarmActions(alarm, props.alarmTopic);
77
+ return alarm;
78
+ };
79
+ /**
80
+ * CloudWatch alarms and log-based metrics for the running scheduler Lambda.
81
+ *
82
+ * When enabled, creates four alarms:
83
+ * - `lambdaErrorsAlarm` – `AWS/Lambda` `Errors` metric.
84
+ * - `instanceStatusFailureAlarm` – log filter for `ResourceWaitFailed:*`.
85
+ * - `slackPostFailureAlarm` – log filter for `running-scheduler: Slack post failed`.
86
+ * - `durableExecutionFailureAlarm` – other handler-level `ERROR` logs (excluding the above).
87
+ *
88
+ * Custom metrics are published under the `EC2InstanceRunningScheduler` namespace.
89
+ */
90
+ class RunningSchedulerFailureDetection extends constructs_1.Construct {
91
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "ec2-instance-running-scheduler.RunningSchedulerFailureDetection", version: "0.3.1" };
92
+ /** SNS topic used for alarm actions, when configured. */
93
+ alarmTopic;
94
+ /** Fires when the Lambda `Errors` metric is non-zero. */
95
+ lambdaErrorsAlarm;
96
+ /** Fires on handler-level ERROR logs outside instance waiting and Slack post failures. */
97
+ durableExecutionFailureAlarm;
98
+ /** Fires when instance stable-state waiting fails (`ResourceWaitFailed:*`). */
99
+ instanceStatusFailureAlarm;
100
+ /** Fires when Slack `chat.postMessage` fails. */
101
+ slackPostFailureAlarm;
102
+ /**
103
+ * @param scope - Parent construct.
104
+ * @param id - Construct id.
105
+ * @param props - Lambda, log group, and {@link FailureDetectionAlarms} (must have `enabled: true`).
106
+ */
107
+ constructor(scope, id, props) {
108
+ super(scope, id);
109
+ const alarmTopic = props.failureDetection.alarmTopic;
110
+ this.alarmTopic = alarmTopic;
111
+ this.lambdaErrorsAlarm = createLogSumAlarm(this, 'LambdaErrorsAlarm', {
112
+ metric: props.runningScheduleFunction.metricErrors({
113
+ period: aws_cdk_lib_1.Duration.minutes(5),
114
+ statistic: 'Sum',
115
+ }),
116
+ alarmTopic,
117
+ });
118
+ const instanceStatusFailureMetric = new logs.MetricFilter(this, 'InstanceStatusFailureMetric', {
119
+ logGroup: props.logGroup,
120
+ filterPattern: logs.FilterPattern.literal('"ResourceWaitFailed"'),
121
+ metricNamespace: METRIC_NAMESPACE,
122
+ metricName: 'InstanceStatusFailure',
123
+ metricValue: '1',
124
+ defaultValue: 0,
125
+ });
126
+ this.instanceStatusFailureAlarm = createLogSumAlarm(this, 'InstanceStatusFailureAlarm', {
127
+ metric: instanceStatusFailureMetric.metric({
128
+ period: aws_cdk_lib_1.Duration.minutes(5),
129
+ statistic: 'Sum',
130
+ }),
131
+ alarmTopic,
132
+ });
133
+ const slackPostFailureMetric = new logs.MetricFilter(this, 'SlackPostFailureMetric', {
134
+ logGroup: props.logGroup,
135
+ filterPattern: logs.FilterPattern.literal('"running-scheduler: Slack post failed"'),
136
+ metricNamespace: METRIC_NAMESPACE,
137
+ metricName: 'SlackPostFailure',
138
+ metricValue: '1',
139
+ defaultValue: 0,
140
+ });
141
+ this.slackPostFailureAlarm = createLogSumAlarm(this, 'SlackPostFailureAlarm', {
142
+ metric: slackPostFailureMetric.metric({
143
+ period: aws_cdk_lib_1.Duration.minutes(5),
144
+ statistic: 'Sum',
145
+ }),
146
+ alarmTopic,
147
+ });
148
+ const durableExecutionFailureMetric = new logs.MetricFilter(this, 'DurableExecutionFailureMetric', {
149
+ logGroup: props.logGroup,
150
+ filterPattern: logs.FilterPattern.literal('"ERROR" - "processOneResource" - "ResourceWaitFailed" - "running-scheduler: Slack post failed"'),
151
+ metricNamespace: METRIC_NAMESPACE,
152
+ metricName: 'DurableExecutionFailure',
153
+ metricValue: '1',
154
+ defaultValue: 0,
155
+ });
156
+ this.durableExecutionFailureAlarm = createLogSumAlarm(this, 'DurableExecutionFailureAlarm', {
157
+ metric: durableExecutionFailureMetric.metric({
158
+ period: aws_cdk_lib_1.Duration.minutes(5),
159
+ statistic: 'Sum',
160
+ }),
161
+ alarmTopic,
162
+ });
163
+ }
164
+ }
165
+ exports.RunningSchedulerFailureDetection = RunningSchedulerFailureDetection;
166
+ /**
167
+ * Creates failure detection alarms when enabled in props.
168
+ *
169
+ * @param scope - Parent construct.
170
+ * @param id - Construct id.
171
+ * @param props - Lambda, log group, and optional alarm configuration.
172
+ * @returns Failure detection construct, or undefined when disabled.
173
+ */
174
+ const createRunningSchedulerFailureDetection = (scope, id, props) => {
175
+ if (!props.failureDetection || !isFailureDetectionEnabled(props.failureDetection)) {
176
+ return undefined;
177
+ }
178
+ return new RunningSchedulerFailureDetection(scope, id, {
179
+ failureDetection: props.failureDetection,
180
+ runningScheduleFunction: props.runningScheduleFunction,
181
+ logGroup: props.logGroup,
182
+ });
183
+ };
184
+ exports.createRunningSchedulerFailureDetection = createRunningSchedulerFailureDetection;
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVubmluZy1zY2hlZHVsZXItZmFpbHVyZS1kZXRlY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9ydW5uaW5nLXNjaGVkdWxlci1mYWlsdXJlLWRldGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQXVDO0FBQ3ZDLHVFQUF5RDtBQUN6RCx1RkFBeUU7QUFFekUsMkRBQTZDO0FBRTdDLDJDQUF1QztBQUV2QyxrRkFBa0Y7QUFDbEYsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQztBQWdEdkQsTUFBTSx5QkFBeUIsR0FBRyxDQUFDLGdCQUF3QyxFQUFXLEVBQUUsQ0FDdEYsZ0JBQWdCLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQztBQUVwQzs7Ozs7R0FLRztBQUNILE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxLQUF1QixFQUFFLFVBQXVCLEVBQVEsRUFBRTtJQUNwRixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsT0FBTztJQUNULENBQUM7SUFFRCxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFDckUsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUN4QixLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FHQyxFQUNpQixFQUFFO0lBQ3BCLE1BQU0sS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1FBQzVDLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtRQUNwQixTQUFTLEVBQUUsQ0FBQztRQUNaLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxrQ0FBa0M7UUFDcEYsaUJBQWlCLEVBQUUsQ0FBQztRQUNwQixnQkFBZ0IsRUFBRSxVQUFVLENBQUMsZ0JBQWdCLENBQUMsYUFBYTtLQUNuQyxDQUFDLENBQUM7SUFDNUIsa0JBQWtCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM1QyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFhLGdDQUFpQyxTQUFRLHNCQUFTOztJQUM3RCx5REFBeUQ7SUFDekMsVUFBVSxDQUFjO0lBQ3hDLHlEQUF5RDtJQUN6QyxpQkFBaUIsQ0FBbUI7SUFDcEQsMEZBQTBGO0lBQzFFLDRCQUE0QixDQUFtQjtJQUMvRCwrRUFBK0U7SUFDL0QsMEJBQTBCLENBQW1CO0lBQzdELGlEQUFpRDtJQUNqQyxxQkFBcUIsQ0FBbUI7SUFFeEQ7Ozs7T0FJRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBNEM7UUFDcEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDO1FBQ3JELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBRTdCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDcEUsTUFBTSxFQUFFLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxZQUFZLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLFNBQVMsRUFBRSxLQUFLO2FBQ2pCLENBQUM7WUFDRixVQUFVO1NBQ1gsQ0FBQyxDQUFDO1FBRUgsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLDZCQUE2QixFQUFFO1lBQzdGLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtZQUN4QixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUM7WUFDakUsZUFBZSxFQUFFLGdCQUFnQjtZQUNqQyxVQUFVLEVBQUUsdUJBQXVCO1lBQ25DLFdBQVcsRUFBRSxHQUFHO1lBQ2hCLFlBQVksRUFBRSxDQUFDO1NBQ2hCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQywwQkFBMEIsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLEVBQUU7WUFDdEYsTUFBTSxFQUFFLDJCQUEyQixDQUFDLE1BQU0sQ0FBQztnQkFDekMsTUFBTSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDM0IsU0FBUyxFQUFFLEtBQUs7YUFDakIsQ0FBQztZQUNGLFVBQVU7U0FDWCxDQUFDLENBQUM7UUFFSCxNQUFNLHNCQUFzQixHQUFHLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUU7WUFDbkYsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyx3Q0FBd0MsQ0FBQztZQUNuRixlQUFlLEVBQUUsZ0JBQWdCO1lBQ2pDLFVBQVUsRUFBRSxrQkFBa0I7WUFDOUIsV0FBVyxFQUFFLEdBQUc7WUFDaEIsWUFBWSxFQUFFLENBQUM7U0FDaEIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLHFCQUFxQixHQUFHLGlCQUFpQixDQUFDLElBQUksRUFBRSx1QkFBdUIsRUFBRTtZQUM1RSxNQUFNLEVBQUUsc0JBQXNCLENBQUMsTUFBTSxDQUFDO2dCQUNwQyxNQUFNLEVBQUUsc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUMzQixTQUFTLEVBQUUsS0FBSzthQUNqQixDQUFDO1lBQ0YsVUFBVTtTQUNYLENBQUMsQ0FBQztRQUVILE1BQU0sNkJBQTZCLEdBQUcsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSwrQkFBK0IsRUFBRTtZQUNqRyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7WUFDeEIsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLGdHQUFnRyxDQUFDO1lBQzNJLGVBQWUsRUFBRSxnQkFBZ0I7WUFDakMsVUFBVSxFQUFFLHlCQUF5QjtZQUNyQyxXQUFXLEVBQUUsR0FBRztZQUNoQixZQUFZLEVBQUUsQ0FBQztTQUNoQixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsNEJBQTRCLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxFQUFFLDhCQUE4QixFQUFFO1lBQzFGLE1BQU0sRUFBRSw2QkFBNkIsQ0FBQyxNQUFNLENBQUM7Z0JBQzNDLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLFNBQVMsRUFBRSxLQUFLO2FBQ2pCLENBQUM7WUFDRixVQUFVO1NBQ1gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUE5RUgsNEVBK0VDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNJLE1BQU0sc0NBQXNDLEdBQUcsQ0FDcEQsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEtBQWtELEVBQ0osRUFBRTtJQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUMseUJBQXlCLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztRQUNsRixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsT0FBTyxJQUFJLGdDQUFnQyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7UUFDckQsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtRQUN4Qyx1QkFBdUIsRUFBRSxLQUFLLENBQUMsdUJBQXVCO1FBQ3RELFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtLQUN6QixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUM7QUFkVyxRQUFBLHNDQUFzQywwQ0FjakQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0ICogYXMgY2xvdWR3YXRjaF9hY3Rpb25zIGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoLWFjdGlvbnMnO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzbnMgZnJvbSAnYXdzLWNkay1saWIvYXdzLXNucyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqIENsb3VkV2F0Y2ggY3VzdG9tIG1ldHJpYyBuYW1lc3BhY2UgZm9yIGxvZy1iYXNlZCBmYWlsdXJlIGRldGVjdGlvbiBtZXRyaWNzLiAqL1xuY29uc3QgTUVUUklDX05BTUVTUEFDRSA9ICdFQzJJbnN0YW5jZVJ1bm5pbmdTY2hlZHVsZXInO1xuXG4vKipcbiAqIFByb3BzIGFjY2VwdGVkIGJ5IHtAbGluayBjcmVhdGVSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvbn0uXG4gKi9cbmludGVyZmFjZSBDcmVhdGVSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvblByb3BzIHtcbiAgLyoqIEZhaWx1cmUgZGV0ZWN0aW9uIG9wdGlvbnM7IGFsYXJtcyBhcmUgY3JlYXRlZCBvbmx5IHdoZW4ge0BsaW5rIEZhaWx1cmVEZXRlY3Rpb25BbGFybXMuZW5hYmxlZH0gaXMgdHJ1ZS4gKi9cbiAgcmVhZG9ubHkgZmFpbHVyZURldGVjdGlvbj86IEZhaWx1cmVEZXRlY3Rpb25BbGFybXM7XG4gIC8qKiBSdW5uaW5nIHNjaGVkdWxlciBMYW1iZGEgdG8gbW9uaXRvci4gKi9cbiAgcmVhZG9ubHkgcnVubmluZ1NjaGVkdWxlRnVuY3Rpb246IGxhbWJkYS5JRnVuY3Rpb247XG4gIC8qKiBBcHBsaWNhdGlvbiBsb2cgZ3JvdXAgZm9yIHRoZSBydW5uaW5nIHNjaGVkdWxlciBMYW1iZGEuICovXG4gIHJlYWRvbmx5IGxvZ0dyb3VwOiBsb2dzLklMb2dHcm91cDtcbn1cblxuLyoqXG4gKiBPcHRpb25hbCBDbG91ZFdhdGNoIGFsYXJtcyBhbmQgbG9nLWJhc2VkIG1ldHJpY3MgZm9yIG9wZXJhdGlvbmFsIGZhaWx1cmUgZGV0ZWN0aW9uLlxuICpcbiAqIFdoZW4ge0BsaW5rIEZhaWx1cmVEZXRlY3Rpb25BbGFybXMuZW5hYmxlZH0gaXMgdHJ1ZSwgdGhlIGNvbnN0cnVjdCBjcmVhdGVzIGFsYXJtcyBmb3IgTGFtYmRhXG4gKiBlcnJvcnMsIER1cmFibGUgaGFuZGxlciBmYWlsdXJlcywgRUMyIGluc3RhbmNlIHN0YXR1cyB3YWl0IGZhaWx1cmVzLCBhbmQgU2xhY2sgcG9zdCBmYWlsdXJlcy5cbiAqIEFsYXJtcyBjYW4gb3B0aW9uYWxseSBub3RpZnkgYW4gU05TIHRvcGljIHN1cHBsaWVkIGJ5IHRoZSBjYWxsZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmFpbHVyZURldGVjdGlvbkFsYXJtcyB7XG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIGNyZWF0ZXMgZmFpbHVyZSBkZXRlY3Rpb24gYWxhcm1zIGFuZCBsb2ctYmFzZWQgbWV0cmljcy5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2Ugd2hlbiBvbWl0dGVkXG4gICAqL1xuICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFNOUyB0b3BpYyBmb3IgYWxhcm0gbm90aWZpY2F0aW9ucy5cbiAgICpcbiAgICogV2hlbiBvbWl0dGVkLCBhbGFybXMgYXJlIGNyZWF0ZWQgd2l0aG91dCBTTlMgYWN0aW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtVG9waWM/OiBzbnMuSVRvcGljO1xufVxuXG4vKipcbiAqIFByb3BzIGZvciB7QGxpbmsgUnVubmluZ1NjaGVkdWxlckZhaWx1cmVEZXRlY3Rpb259LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJ1bm5pbmdTY2hlZHVsZXJGYWlsdXJlRGV0ZWN0aW9uUHJvcHMge1xuICAvKiogQWxhcm0gY29uZmlndXJhdGlvbiAobXVzdCBoYXZlIHtAbGluayBGYWlsdXJlRGV0ZWN0aW9uQWxhcm1zLmVuYWJsZWR9IHRydWUpLiAqL1xuICByZWFkb25seSBmYWlsdXJlRGV0ZWN0aW9uOiBGYWlsdXJlRGV0ZWN0aW9uQWxhcm1zO1xuICAvKiogUnVubmluZyBzY2hlZHVsZXIgTGFtYmRhIHRvIG1vbml0b3IuICovXG4gIHJlYWRvbmx5IHJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uOiBsYW1iZGEuSUZ1bmN0aW9uO1xuICAvKiogQXBwbGljYXRpb24gbG9nIGdyb3VwIGZvciB0aGUgcnVubmluZyBzY2hlZHVsZXIgTGFtYmRhLiAqL1xuICByZWFkb25seSBsb2dHcm91cDogbG9ncy5JTG9nR3JvdXA7XG59XG5cbmNvbnN0IGlzRmFpbHVyZURldGVjdGlvbkVuYWJsZWQgPSAoZmFpbHVyZURldGVjdGlvbjogRmFpbHVyZURldGVjdGlvbkFsYXJtcyk6IGJvb2xlYW4gPT5cbiAgZmFpbHVyZURldGVjdGlvbi5lbmFibGVkID09PSB0cnVlO1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBTTlMgYWxhcm0gYWN0aW9uIHdoZW4gYSB0b3BpYyBpcyBjb25maWd1cmVkLlxuICpcbiAqIEBwYXJhbSBhbGFybSAtIENsb3VkV2F0Y2ggYWxhcm0gdG8gbm90aWZ5LlxuICogQHBhcmFtIGFsYXJtVG9waWMgLSBPcHRpb25hbCBTTlMgdG9waWMgZnJvbSB7QGxpbmsgRmFpbHVyZURldGVjdGlvbkFsYXJtcy5hbGFybVRvcGljfS5cbiAqL1xuY29uc3QgYXR0YWNoQWxhcm1BY3Rpb25zID0gKGFsYXJtOiBjbG91ZHdhdGNoLkFsYXJtLCBhbGFybVRvcGljPzogc25zLklUb3BpYyk6IHZvaWQgPT4ge1xuICBpZiAoIWFsYXJtVG9waWMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBhbGFybS5hZGRBbGFybUFjdGlvbihuZXcgY2xvdWR3YXRjaF9hY3Rpb25zLlNuc0FjdGlvbihhbGFybVRvcGljKSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBDbG91ZFdhdGNoIGFsYXJtIHRoYXQgZmlyZXMgd2hlbiBhIHN1bSBtZXRyaWMgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEuXG4gKlxuICogVXNlcyBgdHJlYXRNaXNzaW5nRGF0YTogbm90QnJlYWNoaW5nYCBzbyBzY2hlZHVsZWQgaW52b2NhdGlvbnMgZG8gbm90IGFsYXJtIGJldHdlZW4gcnVucy5cbiAqXG4gKiBAcGFyYW0gc2NvcGUgLSBQYXJlbnQgY29uc3RydWN0LlxuICogQHBhcmFtIGlkIC0gQWxhcm0gY29uc3RydWN0IGlkLlxuICogQHBhcmFtIHByb3BzIC0gTWV0cmljIHRvIGFsYXJtIG9uIGFuZCBvcHRpb25hbCBTTlMgdG9waWMuXG4gKiBAcmV0dXJucyBDb25maWd1cmVkIENsb3VkV2F0Y2ggYWxhcm0uXG4gKi9cbmNvbnN0IGNyZWF0ZUxvZ1N1bUFsYXJtID0gKFxuICBzY29wZTogQ29uc3RydWN0LFxuICBpZDogc3RyaW5nLFxuICBwcm9wczoge1xuICAgIG1ldHJpYzogY2xvdWR3YXRjaC5JTWV0cmljO1xuICAgIGFsYXJtVG9waWM/OiBzbnMuSVRvcGljO1xuICB9LFxuKTogY2xvdWR3YXRjaC5BbGFybSA9PiB7XG4gIGNvbnN0IGFsYXJtID0gbmV3IGNsb3Vkd2F0Y2guQWxhcm0oc2NvcGUsIGlkLCB7XG4gICAgbWV0cmljOiBwcm9wcy5tZXRyaWMsXG4gICAgdGhyZXNob2xkOiAxLFxuICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTk9UX0JSRUFDSElORyxcbiAgfSBhcyBjbG91ZHdhdGNoLkFsYXJtUHJvcHMpO1xuICBhdHRhY2hBbGFybUFjdGlvbnMoYWxhcm0sIHByb3BzLmFsYXJtVG9waWMpO1xuICByZXR1cm4gYWxhcm07XG59O1xuXG4vKipcbiAqIENsb3VkV2F0Y2ggYWxhcm1zIGFuZCBsb2ctYmFzZWQgbWV0cmljcyBmb3IgdGhlIHJ1bm5pbmcgc2NoZWR1bGVyIExhbWJkYS5cbiAqXG4gKiBXaGVuIGVuYWJsZWQsIGNyZWF0ZXMgZm91ciBhbGFybXM6XG4gKiAtIGBsYW1iZGFFcnJvcnNBbGFybWAg4oCTIGBBV1MvTGFtYmRhYCBgRXJyb3JzYCBtZXRyaWMuXG4gKiAtIGBpbnN0YW5jZVN0YXR1c0ZhaWx1cmVBbGFybWAg4oCTIGxvZyBmaWx0ZXIgZm9yIGBSZXNvdXJjZVdhaXRGYWlsZWQ6KmAuXG4gKiAtIGBzbGFja1Bvc3RGYWlsdXJlQWxhcm1gIOKAkyBsb2cgZmlsdGVyIGZvciBgcnVubmluZy1zY2hlZHVsZXI6IFNsYWNrIHBvc3QgZmFpbGVkYC5cbiAqIC0gYGR1cmFibGVFeGVjdXRpb25GYWlsdXJlQWxhcm1gIOKAkyBvdGhlciBoYW5kbGVyLWxldmVsIGBFUlJPUmAgbG9ncyAoZXhjbHVkaW5nIHRoZSBhYm92ZSkuXG4gKlxuICogQ3VzdG9tIG1ldHJpY3MgYXJlIHB1Ymxpc2hlZCB1bmRlciB0aGUgYEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlcmAgbmFtZXNwYWNlLlxuICovXG5leHBvcnQgY2xhc3MgUnVubmluZ1NjaGVkdWxlckZhaWx1cmVEZXRlY3Rpb24gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKiogU05TIHRvcGljIHVzZWQgZm9yIGFsYXJtIGFjdGlvbnMsIHdoZW4gY29uZmlndXJlZC4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGFsYXJtVG9waWM/OiBzbnMuSVRvcGljO1xuICAvKiogRmlyZXMgd2hlbiB0aGUgTGFtYmRhIGBFcnJvcnNgIG1ldHJpYyBpcyBub24temVyby4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYUVycm9yc0FsYXJtOiBjbG91ZHdhdGNoLkFsYXJtO1xuICAvKiogRmlyZXMgb24gaGFuZGxlci1sZXZlbCBFUlJPUiBsb2dzIG91dHNpZGUgaW5zdGFuY2Ugd2FpdGluZyBhbmQgU2xhY2sgcG9zdCBmYWlsdXJlcy4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGR1cmFibGVFeGVjdXRpb25GYWlsdXJlQWxhcm06IGNsb3Vkd2F0Y2guQWxhcm07XG4gIC8qKiBGaXJlcyB3aGVuIGluc3RhbmNlIHN0YWJsZS1zdGF0ZSB3YWl0aW5nIGZhaWxzIChgUmVzb3VyY2VXYWl0RmFpbGVkOipgKS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbmNlU3RhdHVzRmFpbHVyZUFsYXJtOiBjbG91ZHdhdGNoLkFsYXJtO1xuICAvKiogRmlyZXMgd2hlbiBTbGFjayBgY2hhdC5wb3N0TWVzc2FnZWAgZmFpbHMuICovXG4gIHB1YmxpYyByZWFkb25seSBzbGFja1Bvc3RGYWlsdXJlQWxhcm06IGNsb3Vkd2F0Y2guQWxhcm07XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBzY29wZSAtIFBhcmVudCBjb25zdHJ1Y3QuXG4gICAqIEBwYXJhbSBpZCAtIENvbnN0cnVjdCBpZC5cbiAgICogQHBhcmFtIHByb3BzIC0gTGFtYmRhLCBsb2cgZ3JvdXAsIGFuZCB7QGxpbmsgRmFpbHVyZURldGVjdGlvbkFsYXJtc30gKG11c3QgaGF2ZSBgZW5hYmxlZDogdHJ1ZWApLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFJ1bm5pbmdTY2hlZHVsZXJGYWlsdXJlRGV0ZWN0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgYWxhcm1Ub3BpYyA9IHByb3BzLmZhaWx1cmVEZXRlY3Rpb24uYWxhcm1Ub3BpYztcbiAgICB0aGlzLmFsYXJtVG9waWMgPSBhbGFybVRvcGljO1xuXG4gICAgdGhpcy5sYW1iZGFFcnJvcnNBbGFybSA9IGNyZWF0ZUxvZ1N1bUFsYXJtKHRoaXMsICdMYW1iZGFFcnJvcnNBbGFybScsIHtcbiAgICAgIG1ldHJpYzogcHJvcHMucnVubmluZ1NjaGVkdWxlRnVuY3Rpb24ubWV0cmljRXJyb3JzKHtcbiAgICAgICAgcGVyaW9kOiBEdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgfSksXG4gICAgICBhbGFybVRvcGljLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW5zdGFuY2VTdGF0dXNGYWlsdXJlTWV0cmljID0gbmV3IGxvZ3MuTWV0cmljRmlsdGVyKHRoaXMsICdJbnN0YW5jZVN0YXR1c0ZhaWx1cmVNZXRyaWMnLCB7XG4gICAgICBsb2dHcm91cDogcHJvcHMubG9nR3JvdXAsXG4gICAgICBmaWx0ZXJQYXR0ZXJuOiBsb2dzLkZpbHRlclBhdHRlcm4ubGl0ZXJhbCgnXCJSZXNvdXJjZVdhaXRGYWlsZWRcIicpLFxuICAgICAgbWV0cmljTmFtZXNwYWNlOiBNRVRSSUNfTkFNRVNQQUNFLFxuICAgICAgbWV0cmljTmFtZTogJ0luc3RhbmNlU3RhdHVzRmFpbHVyZScsXG4gICAgICBtZXRyaWNWYWx1ZTogJzEnLFxuICAgICAgZGVmYXVsdFZhbHVlOiAwLFxuICAgIH0pO1xuICAgIHRoaXMuaW5zdGFuY2VTdGF0dXNGYWlsdXJlQWxhcm0gPSBjcmVhdGVMb2dTdW1BbGFybSh0aGlzLCAnSW5zdGFuY2VTdGF0dXNGYWlsdXJlQWxhcm0nLCB7XG4gICAgICBtZXRyaWM6IGluc3RhbmNlU3RhdHVzRmFpbHVyZU1ldHJpYy5tZXRyaWMoe1xuICAgICAgICBwZXJpb2Q6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICB9KSxcbiAgICAgIGFsYXJtVG9waWMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzbGFja1Bvc3RGYWlsdXJlTWV0cmljID0gbmV3IGxvZ3MuTWV0cmljRmlsdGVyKHRoaXMsICdTbGFja1Bvc3RGYWlsdXJlTWV0cmljJywge1xuICAgICAgbG9nR3JvdXA6IHByb3BzLmxvZ0dyb3VwLFxuICAgICAgZmlsdGVyUGF0dGVybjogbG9ncy5GaWx0ZXJQYXR0ZXJuLmxpdGVyYWwoJ1wicnVubmluZy1zY2hlZHVsZXI6IFNsYWNrIHBvc3QgZmFpbGVkXCInKSxcbiAgICAgIG1ldHJpY05hbWVzcGFjZTogTUVUUklDX05BTUVTUEFDRSxcbiAgICAgIG1ldHJpY05hbWU6ICdTbGFja1Bvc3RGYWlsdXJlJyxcbiAgICAgIG1ldHJpY1ZhbHVlOiAnMScsXG4gICAgICBkZWZhdWx0VmFsdWU6IDAsXG4gICAgfSk7XG4gICAgdGhpcy5zbGFja1Bvc3RGYWlsdXJlQWxhcm0gPSBjcmVhdGVMb2dTdW1BbGFybSh0aGlzLCAnU2xhY2tQb3N0RmFpbHVyZUFsYXJtJywge1xuICAgICAgbWV0cmljOiBzbGFja1Bvc3RGYWlsdXJlTWV0cmljLm1ldHJpYyh7XG4gICAgICAgIHBlcmlvZDogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgIH0pLFxuICAgICAgYWxhcm1Ub3BpYyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGR1cmFibGVFeGVjdXRpb25GYWlsdXJlTWV0cmljID0gbmV3IGxvZ3MuTWV0cmljRmlsdGVyKHRoaXMsICdEdXJhYmxlRXhlY3V0aW9uRmFpbHVyZU1ldHJpYycsIHtcbiAgICAgIGxvZ0dyb3VwOiBwcm9wcy5sb2dHcm91cCxcbiAgICAgIGZpbHRlclBhdHRlcm46IGxvZ3MuRmlsdGVyUGF0dGVybi5saXRlcmFsKCdcIkVSUk9SXCIgLSBcInByb2Nlc3NPbmVSZXNvdXJjZVwiIC0gXCJSZXNvdXJjZVdhaXRGYWlsZWRcIiAtIFwicnVubmluZy1zY2hlZHVsZXI6IFNsYWNrIHBvc3QgZmFpbGVkXCInKSxcbiAgICAgIG1ldHJpY05hbWVzcGFjZTogTUVUUklDX05BTUVTUEFDRSxcbiAgICAgIG1ldHJpY05hbWU6ICdEdXJhYmxlRXhlY3V0aW9uRmFpbHVyZScsXG4gICAgICBtZXRyaWNWYWx1ZTogJzEnLFxuICAgICAgZGVmYXVsdFZhbHVlOiAwLFxuICAgIH0pO1xuICAgIHRoaXMuZHVyYWJsZUV4ZWN1dGlvbkZhaWx1cmVBbGFybSA9IGNyZWF0ZUxvZ1N1bUFsYXJtKHRoaXMsICdEdXJhYmxlRXhlY3V0aW9uRmFpbHVyZUFsYXJtJywge1xuICAgICAgbWV0cmljOiBkdXJhYmxlRXhlY3V0aW9uRmFpbHVyZU1ldHJpYy5tZXRyaWMoe1xuICAgICAgICBwZXJpb2Q6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICB9KSxcbiAgICAgIGFsYXJtVG9waWMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGZhaWx1cmUgZGV0ZWN0aW9uIGFsYXJtcyB3aGVuIGVuYWJsZWQgaW4gcHJvcHMuXG4gKlxuICogQHBhcmFtIHNjb3BlIC0gUGFyZW50IGNvbnN0cnVjdC5cbiAqIEBwYXJhbSBpZCAtIENvbnN0cnVjdCBpZC5cbiAqIEBwYXJhbSBwcm9wcyAtIExhbWJkYSwgbG9nIGdyb3VwLCBhbmQgb3B0aW9uYWwgYWxhcm0gY29uZmlndXJhdGlvbi5cbiAqIEByZXR1cm5zIEZhaWx1cmUgZGV0ZWN0aW9uIGNvbnN0cnVjdCwgb3IgdW5kZWZpbmVkIHdoZW4gZGlzYWJsZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvbiA9IChcbiAgc2NvcGU6IENvbnN0cnVjdCxcbiAgaWQ6IHN0cmluZyxcbiAgcHJvcHM6IENyZWF0ZVJ1bm5pbmdTY2hlZHVsZXJGYWlsdXJlRGV0ZWN0aW9uUHJvcHMsXG4pOiBSdW5uaW5nU2NoZWR1bGVyRmFpbHVyZURldGVjdGlvbiB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmICghcHJvcHMuZmFpbHVyZURldGVjdGlvbiB8fCAhaXNGYWlsdXJlRGV0ZWN0aW9uRW5hYmxlZChwcm9wcy5mYWlsdXJlRGV0ZWN0aW9uKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gbmV3IFJ1bm5pbmdTY2hlZHVsZXJGYWlsdXJlRGV0ZWN0aW9uKHNjb3BlLCBpZCwge1xuICAgIGZhaWx1cmVEZXRlY3Rpb246IHByb3BzLmZhaWx1cmVEZXRlY3Rpb24sXG4gICAgcnVubmluZ1NjaGVkdWxlRnVuY3Rpb246IHByb3BzLnJ1bm5pbmdTY2hlZHVsZUZ1bmN0aW9uLFxuICAgIGxvZ0dyb3VwOiBwcm9wcy5sb2dHcm91cCxcbiAgfSk7XG59O1xuIl19