1 | ;
|
2 | var _a;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.Alarm = exports.TreatMissingData = exports.ComparisonOperator = void 0;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const core_1 = require("@aws-cdk/core");
|
8 | const alarm_base_1 = require("./alarm-base");
|
9 | const cloudwatch_generated_1 = require("./cloudwatch.generated");
|
10 | const metric_util_1 = require("./private/metric-util");
|
11 | const object_1 = require("./private/object");
|
12 | const rendering_1 = require("./private/rendering");
|
13 | const statistic_1 = require("./private/statistic");
|
14 | /**
|
15 | * Comparison operator for evaluating alarms
|
16 | */
|
17 | var ComparisonOperator;
|
18 | (function (ComparisonOperator) {
|
19 | /**
|
20 | * Specified statistic is greater than or equal to the threshold
|
21 | */
|
22 | ComparisonOperator["GREATER_THAN_OR_EQUAL_TO_THRESHOLD"] = "GreaterThanOrEqualToThreshold";
|
23 | /**
|
24 | * Specified statistic is strictly greater than the threshold
|
25 | */
|
26 | ComparisonOperator["GREATER_THAN_THRESHOLD"] = "GreaterThanThreshold";
|
27 | /**
|
28 | * Specified statistic is strictly less than the threshold
|
29 | */
|
30 | ComparisonOperator["LESS_THAN_THRESHOLD"] = "LessThanThreshold";
|
31 | /**
|
32 | * Specified statistic is less than or equal to the threshold.
|
33 | */
|
34 | ComparisonOperator["LESS_THAN_OR_EQUAL_TO_THRESHOLD"] = "LessThanOrEqualToThreshold";
|
35 | /**
|
36 | * Specified statistic is lower than or greater than the anomaly model band.
|
37 | * Used only for alarms based on anomaly detection models
|
38 | */
|
39 | ComparisonOperator["LESS_THAN_LOWER_OR_GREATER_THAN_UPPER_THRESHOLD"] = "LessThanLowerOrGreaterThanUpperThreshold";
|
40 | /**
|
41 | * Specified statistic is greater than the anomaly model band.
|
42 | * Used only for alarms based on anomaly detection models
|
43 | */
|
44 | ComparisonOperator["GREATER_THAN_UPPER_THRESHOLD"] = "GreaterThanUpperThreshold";
|
45 | /**
|
46 | * Specified statistic is lower than the anomaly model band.
|
47 | * Used only for alarms based on anomaly detection models
|
48 | */
|
49 | ComparisonOperator["LESS_THAN_LOWER_THRESHOLD"] = "LessThanLowerThreshold";
|
50 | })(ComparisonOperator = exports.ComparisonOperator || (exports.ComparisonOperator = {}));
|
51 | const OPERATOR_SYMBOLS = {
|
52 | GreaterThanOrEqualToThreshold: '>=',
|
53 | GreaterThanThreshold: '>',
|
54 | LessThanThreshold: '<',
|
55 | LessThanOrEqualToThreshold: '<=',
|
56 | };
|
57 | /**
|
58 | * Specify how missing data points are treated during alarm evaluation
|
59 | */
|
60 | var TreatMissingData;
|
61 | (function (TreatMissingData) {
|
62 | /**
|
63 | * Missing data points are treated as breaching the threshold
|
64 | */
|
65 | TreatMissingData["BREACHING"] = "breaching";
|
66 | /**
|
67 | * Missing data points are treated as being within the threshold
|
68 | */
|
69 | TreatMissingData["NOT_BREACHING"] = "notBreaching";
|
70 | /**
|
71 | * The current alarm state is maintained
|
72 | */
|
73 | TreatMissingData["IGNORE"] = "ignore";
|
74 | /**
|
75 | * The alarm does not consider missing data points when evaluating whether to change state
|
76 | */
|
77 | TreatMissingData["MISSING"] = "missing";
|
78 | })(TreatMissingData = exports.TreatMissingData || (exports.TreatMissingData = {}));
|
79 | /**
|
80 | * An alarm on a CloudWatch metric
|
81 | */
|
82 | class Alarm extends alarm_base_1.AlarmBase {
|
83 | constructor(scope, id, props) {
|
84 | super(scope, id, {
|
85 | physicalName: props.alarmName,
|
86 | });
|
87 | try {
|
88 | jsiiDeprecationWarnings._aws_cdk_aws_cloudwatch_AlarmProps(props);
|
89 | }
|
90 | catch (error) {
|
91 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
92 | Error.captureStackTrace(error, Alarm);
|
93 | }
|
94 | throw error;
|
95 | }
|
96 | const comparisonOperator = props.comparisonOperator || ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD;
|
97 | // Render metric, process potential overrides from the alarm
|
98 | // (It would be preferable if the statistic etc. was worked into the metric,
|
99 | // but hey we're allowing overrides...)
|
100 | const metricProps = this.renderMetric(props.metric);
|
101 | if (props.period) {
|
102 | metricProps.period = props.period.toSeconds();
|
103 | }
|
104 | if (props.statistic) {
|
105 | // Will overwrite both fields if present
|
106 | Object.assign(metricProps, {
|
107 | statistic: renderIfSimpleStatistic(props.statistic),
|
108 | extendedStatistic: renderIfExtendedStatistic(props.statistic),
|
109 | });
|
110 | }
|
111 | const alarm = new cloudwatch_generated_1.CfnAlarm(this, 'Resource', {
|
112 | // Meta
|
113 | alarmDescription: props.alarmDescription,
|
114 | alarmName: this.physicalName,
|
115 | // Evaluation
|
116 | comparisonOperator,
|
117 | threshold: props.threshold,
|
118 | datapointsToAlarm: props.datapointsToAlarm,
|
119 | evaluateLowSampleCountPercentile: props.evaluateLowSampleCountPercentile,
|
120 | evaluationPeriods: props.evaluationPeriods,
|
121 | treatMissingData: props.treatMissingData,
|
122 | // Actions
|
123 | actionsEnabled: props.actionsEnabled,
|
124 | alarmActions: core_1.Lazy.list({ produce: () => this.alarmActionArns }),
|
125 | insufficientDataActions: core_1.Lazy.list({ produce: (() => this.insufficientDataActionArns) }),
|
126 | okActions: core_1.Lazy.list({ produce: () => this.okActionArns }),
|
127 | // Metric
|
128 | ...metricProps,
|
129 | });
|
130 | this.alarmArn = this.getResourceArnAttribute(alarm.attrArn, {
|
131 | service: 'cloudwatch',
|
132 | resource: 'alarm',
|
133 | resourceName: this.physicalName,
|
134 | arnFormat: core_1.ArnFormat.COLON_RESOURCE_NAME,
|
135 | });
|
136 | this.alarmName = this.getResourceNameAttribute(alarm.ref);
|
137 | this.metric = props.metric;
|
138 | const datapoints = props.datapointsToAlarm || props.evaluationPeriods;
|
139 | this.annotation = {
|
140 | // eslint-disable-next-line max-len
|
141 | label: `${this.metric} ${OPERATOR_SYMBOLS[comparisonOperator]} ${props.threshold} for ${datapoints} datapoints within ${describePeriod(props.evaluationPeriods * metric_util_1.metricPeriod(props.metric).toSeconds())}`,
|
142 | value: props.threshold,
|
143 | };
|
144 | for (const w of this.metric.warnings ?? []) {
|
145 | core_1.Annotations.of(this).addWarning(w);
|
146 | }
|
147 | }
|
148 | /**
|
149 | * Import an existing CloudWatch alarm provided an ARN
|
150 | *
|
151 | * @param scope The parent creating construct (usually `this`).
|
152 | * @param id The construct's name
|
153 | * @param alarmArn Alarm ARN (i.e. arn:aws:cloudwatch:<region>:<account-id>:alarm:Foo)
|
154 | */
|
155 | static fromAlarmArn(scope, id, alarmArn) {
|
156 | class Import extends alarm_base_1.AlarmBase {
|
157 | constructor() {
|
158 | super(...arguments);
|
159 | this.alarmArn = alarmArn;
|
160 | this.alarmName = core_1.Stack.of(scope).splitArn(alarmArn, core_1.ArnFormat.COLON_RESOURCE_NAME).resourceName;
|
161 | }
|
162 | }
|
163 | return new Import(scope, id);
|
164 | }
|
165 | /**
|
166 | * Turn this alarm into a horizontal annotation
|
167 | *
|
168 | * This is useful if you want to represent an Alarm in a non-AlarmWidget.
|
169 | * An `AlarmWidget` can directly show an alarm, but it can only show a
|
170 | * single alarm and no other metrics. Instead, you can convert the alarm to
|
171 | * a HorizontalAnnotation and add it as an annotation to another graph.
|
172 | *
|
173 | * This might be useful if:
|
174 | *
|
175 | * - You want to show multiple alarms inside a single graph, for example if
|
176 | * you have both a "small margin/long period" alarm as well as a
|
177 | * "large margin/short period" alarm.
|
178 | *
|
179 | * - You want to show an Alarm line in a graph with multiple metrics in it.
|
180 | */
|
181 | toAnnotation() {
|
182 | return this.annotation;
|
183 | }
|
184 | /**
|
185 | * Trigger this action if the alarm fires
|
186 | *
|
187 | * Typically the ARN of an SNS topic or ARN of an AutoScaling policy.
|
188 | */
|
189 | addAlarmAction(...actions) {
|
190 | try {
|
191 | jsiiDeprecationWarnings._aws_cdk_aws_cloudwatch_IAlarmAction(actions);
|
192 | }
|
193 | catch (error) {
|
194 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
195 | Error.captureStackTrace(error, this.addAlarmAction);
|
196 | }
|
197 | throw error;
|
198 | }
|
199 | if (this.alarmActionArns === undefined) {
|
200 | this.alarmActionArns = [];
|
201 | }
|
202 | this.alarmActionArns.push(...actions.map(a => this.validateActionArn(a.bind(this, this).alarmActionArn)));
|
203 | }
|
204 | validateActionArn(actionArn) {
|
205 | const ec2ActionsRegexp = /arn:aws[a-z0-9-]*:automate:[a-z|\d|-]+:ec2:[a-z]+/;
|
206 | if (ec2ActionsRegexp.test(actionArn)) {
|
207 | // Check per-instance metric
|
208 | const metricConfig = this.metric.toMetricConfig();
|
209 | if (metricConfig.metricStat?.dimensions?.length != 1 || metricConfig.metricStat?.dimensions[0].name != 'InstanceId') {
|
210 | throw new Error(`EC2 alarm actions requires an EC2 Per-Instance Metric. (${JSON.stringify(metricConfig)} does not have an 'InstanceId' dimension)`);
|
211 | }
|
212 | }
|
213 | return actionArn;
|
214 | }
|
215 | renderMetric(metric) {
|
216 | const self = this;
|
217 | return metric_util_1.dispatchMetric(metric, {
|
218 | withStat(stat, conf) {
|
219 | self.validateMetricStat(stat, metric);
|
220 | const canRenderAsLegacyMetric = conf.renderingProperties?.label == undefined && !self.requiresAccountId(stat);
|
221 | // Do this to disturb existing templates as little as possible
|
222 | if (canRenderAsLegacyMetric) {
|
223 | return object_1.dropUndefined({
|
224 | dimensions: stat.dimensions,
|
225 | namespace: stat.namespace,
|
226 | metricName: stat.metricName,
|
227 | period: stat.period?.toSeconds(),
|
228 | statistic: renderIfSimpleStatistic(stat.statistic),
|
229 | extendedStatistic: renderIfExtendedStatistic(stat.statistic),
|
230 | unit: stat.unitFilter,
|
231 | });
|
232 | }
|
233 | return {
|
234 | metrics: [
|
235 | {
|
236 | metricStat: {
|
237 | metric: {
|
238 | metricName: stat.metricName,
|
239 | namespace: stat.namespace,
|
240 | dimensions: stat.dimensions,
|
241 | },
|
242 | period: stat.period.toSeconds(),
|
243 | stat: stat.statistic,
|
244 | unit: stat.unitFilter,
|
245 | },
|
246 | id: 'm1',
|
247 | accountId: self.requiresAccountId(stat) ? stat.account : undefined,
|
248 | label: conf.renderingProperties?.label,
|
249 | returnData: true,
|
250 | },
|
251 | ],
|
252 | };
|
253 | },
|
254 | withExpression() {
|
255 | // Expand the math expression metric into a set
|
256 | const mset = new rendering_1.MetricSet();
|
257 | mset.addTopLevel(true, metric);
|
258 | let eid = 0;
|
259 | function uniqueMetricId() {
|
260 | return `expr_${++eid}`;
|
261 | }
|
262 | return {
|
263 | metrics: mset.entries.map(entry => metric_util_1.dispatchMetric(entry.metric, {
|
264 | withStat(stat, conf) {
|
265 | self.validateMetricStat(stat, entry.metric);
|
266 | return {
|
267 | metricStat: {
|
268 | metric: {
|
269 | metricName: stat.metricName,
|
270 | namespace: stat.namespace,
|
271 | dimensions: stat.dimensions,
|
272 | },
|
273 | period: stat.period.toSeconds(),
|
274 | stat: stat.statistic,
|
275 | unit: stat.unitFilter,
|
276 | },
|
277 | id: entry.id || uniqueMetricId(),
|
278 | accountId: self.requiresAccountId(stat) ? stat.account : undefined,
|
279 | label: conf.renderingProperties?.label,
|
280 | returnData: entry.tag ? undefined : false,
|
281 | };
|
282 | },
|
283 | withExpression(expr, conf) {
|
284 | const hasSubmetrics = mathExprHasSubmetrics(expr);
|
285 | if (hasSubmetrics) {
|
286 | assertSubmetricsCount(expr);
|
287 | }
|
288 | self.validateMetricExpression(expr);
|
289 | return {
|
290 | expression: expr.expression,
|
291 | id: entry.id || uniqueMetricId(),
|
292 | label: conf.renderingProperties?.label,
|
293 | period: hasSubmetrics ? undefined : expr.period,
|
294 | returnData: entry.tag ? undefined : false,
|
295 | };
|
296 | },
|
297 | })),
|
298 | };
|
299 | },
|
300 | });
|
301 | }
|
302 | /**
|
303 | * Validate that if a region is in the given stat config, they match the Alarm
|
304 | */
|
305 | validateMetricStat(stat, metric) {
|
306 | const stack = core_1.Stack.of(this);
|
307 | if (definitelyDifferent(stat.region, stack.region)) {
|
308 | throw new Error(`Cannot create an Alarm in region '${stack.region}' based on metric '${metric}' in '${stat.region}'`);
|
309 | }
|
310 | }
|
311 | /**
|
312 | * Validates that the expression config does not specify searchAccount or searchRegion props
|
313 | * as search expressions are not supported by Alarms.
|
314 | */
|
315 | validateMetricExpression(expr) {
|
316 | if (expr.searchAccount !== undefined || expr.searchRegion !== undefined) {
|
317 | throw new Error('Cannot create an Alarm based on a MathExpression which specifies a searchAccount or searchRegion');
|
318 | }
|
319 | }
|
320 | /**
|
321 | * Determine if the accountId property should be included in the metric.
|
322 | */
|
323 | requiresAccountId(stat) {
|
324 | const stackAccount = core_1.Stack.of(this).account;
|
325 | // if stat.account is undefined, it's by definition in the same account
|
326 | if (stat.account === undefined) {
|
327 | return false;
|
328 | }
|
329 | // Return true if they're different. The ACCOUNT_ID token is interned
|
330 | // so will always have the same string value (and even if we guess wrong
|
331 | // it will still work).
|
332 | return stackAccount !== stat.account;
|
333 | }
|
334 | }
|
335 | exports.Alarm = Alarm;
|
336 | _a = JSII_RTTI_SYMBOL_1;
|
337 | Alarm[_a] = { fqn: "@aws-cdk/aws-cloudwatch.Alarm", version: "1.161.0" };
|
338 | function definitelyDifferent(x, y) {
|
339 | return x && !core_1.Token.isUnresolved(y) && x !== y;
|
340 | }
|
341 | /**
|
342 | * Return a human readable string for this period
|
343 | *
|
344 | * We know the seconds are always one of a handful of allowed values.
|
345 | */
|
346 | function describePeriod(seconds) {
|
347 | if (seconds === 60) {
|
348 | return '1 minute';
|
349 | }
|
350 | if (seconds === 1) {
|
351 | return '1 second';
|
352 | }
|
353 | if (seconds > 60) {
|
354 | return (seconds / 60) + ' minutes';
|
355 | }
|
356 | return seconds + ' seconds';
|
357 | }
|
358 | function renderIfSimpleStatistic(statistic) {
|
359 | if (statistic === undefined) {
|
360 | return undefined;
|
361 | }
|
362 | const parsed = statistic_1.parseStatistic(statistic);
|
363 | if (parsed.type === 'simple') {
|
364 | return parsed.statistic;
|
365 | }
|
366 | return undefined;
|
367 | }
|
368 | function renderIfExtendedStatistic(statistic) {
|
369 | if (statistic === undefined) {
|
370 | return undefined;
|
371 | }
|
372 | const parsed = statistic_1.parseStatistic(statistic);
|
373 | if (parsed.type === 'percentile') {
|
374 | // Already percentile. Avoid parsing because we might get into
|
375 | // floating point rounding issues, return as-is but lowercase the p.
|
376 | return statistic.toLowerCase();
|
377 | }
|
378 | else if (parsed.type === 'generic') {
|
379 | return statistic;
|
380 | }
|
381 | return undefined;
|
382 | }
|
383 | function mathExprHasSubmetrics(expr) {
|
384 | return Object.keys(expr.usingMetrics).length > 0;
|
385 | }
|
386 | function assertSubmetricsCount(expr) {
|
387 | if (Object.keys(expr.usingMetrics).length > 10) {
|
388 | // https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-on-metric-math-expressions
|
389 | throw new Error('Alarms on math expressions cannot contain more than 10 individual metrics');
|
390 | }
|
391 | ;
|
392 | }
|
393 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxhcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhbGFybS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3Q0FBMkU7QUFHM0UsNkNBQWlEO0FBQ2pELGlFQUFpRTtBQUlqRSx1REFBcUU7QUFDckUsNkNBQWlEO0FBQ2pELG1EQUFnRDtBQUNoRCxtREFBcUQ7QUFlckQ7O0dBRUc7QUFDSCxJQUFZLGtCQXNDWDtBQXRDRCxXQUFZLGtCQUFrQjtJQUM1Qjs7T0FFRztJQUNILDBGQUFvRSxDQUFBO0lBRXBFOztPQUVHO0lBQ0gscUVBQStDLENBQUE7SUFFL0M7O09BRUc7SUFDSCwrREFBeUMsQ0FBQTtJQUV6Qzs7T0FFRztJQUNILG9GQUE4RCxDQUFBO0lBRTlEOzs7T0FHRztJQUNILGtIQUE0RixDQUFBO0lBRTVGOzs7T0FHRztJQUNILGdGQUEwRCxDQUFBO0lBRTFEOzs7T0FHRztJQUNILDBFQUFvRCxDQUFBO0FBQ3RELENBQUMsRUF0Q1csa0JBQWtCLEdBQWxCLDBCQUFrQixLQUFsQiwwQkFBa0IsUUFzQzdCO0FBRUQsTUFBTSxnQkFBZ0IsR0FBNEI7SUFDaEQsNkJBQTZCLEVBQUUsSUFBSTtJQUNuQyxvQkFBb0IsRUFBRSxHQUFHO0lBQ3pCLGlCQUFpQixFQUFFLEdBQUc7SUFDdEIsMEJBQTBCLEVBQUUsSUFBSTtDQUNqQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxJQUFZLGdCQW9CWDtBQXBCRCxXQUFZLGdCQUFnQjtJQUMxQjs7T0FFRztJQUNILDJDQUF1QixDQUFBO0lBRXZCOztPQUVHO0lBQ0gsa0RBQThCLENBQUE7SUFFOUI7O09BRUc7SUFDSCxxQ0FBaUIsQ0FBQTtJQUVqQjs7T0FFRztJQUNILHVDQUFtQixDQUFBO0FBQ3JCLENBQUMsRUFwQlcsZ0JBQWdCLEdBQWhCLHdCQUFnQixLQUFoQix3QkFBZ0IsUUFvQjNCO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLEtBQU0sU0FBUSxzQkFBUztJQXlDbEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFpQjtRQUN6RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFlBQVksRUFBRSxLQUFLLENBQUMsU0FBUztTQUM5QixDQUFDLENBQUM7Ozs7OzsrQ0E1Q00sS0FBSzs7OztRQThDZCxNQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxrQkFBa0IsQ0FBQyxrQ0FBa0MsQ0FBQztRQUU3Ryw0REFBNEQ7UUFDNUQsNEVBQTRFO1FBQzVFLHVDQUF1QztRQUN2QyxNQUFNLFdBQVcsR0FBc0MsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkYsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFO1lBQ2hCLFdBQVcsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUMvQztRQUNELElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtZQUNuQix3Q0FBd0M7WUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUU7Z0JBQ3pCLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO2dCQUNuRCxpQkFBaUIsRUFBRSx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO2FBQzlELENBQUMsQ0FBQztTQUNKO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSwrQkFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDM0MsT0FBTztZQUNQLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7WUFDeEMsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZO1lBRTVCLGFBQWE7WUFDYixrQkFBa0I7WUFDbEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1lBQzFCLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUI7WUFDMUMsZ0NBQWdDLEVBQUUsS0FBSyxDQUFDLGdDQUFnQztZQUN4RSxpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQzFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7WUFFeEMsVUFBVTtZQUNWLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYztZQUNwQyxZQUFZLEVBQUUsV0FBSSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDaEUsdUJBQXVCLEVBQUUsV0FBSSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLENBQUM7WUFDeEYsU0FBUyxFQUFFLFdBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRTFELFNBQVM7WUFDVCxHQUFHLFdBQVc7U0FDZixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFO1lBQzFELE9BQU8sRUFBRSxZQUFZO1lBQ3JCLFFBQVEsRUFBRSxPQUFPO1lBQ2pCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtZQUMvQixTQUFTLEVBQUUsZ0JBQVMsQ0FBQyxtQkFBbUI7U0FDekMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTFELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUMzQixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsaUJBQWlCLElBQUksS0FBSyxDQUFDLGlCQUFpQixDQUFDO1FBQ3RFLElBQUksQ0FBQyxVQUFVLEdBQUc7WUFDaEIsbUNBQW1DO1lBQ25DLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsSUFBSSxLQUFLLENBQUMsU0FBUyxRQUFRLFVBQVUsc0JBQXNCLGNBQWMsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEdBQUcsMEJBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRTtZQUMxTSxLQUFLLEVBQUUsS0FBSyxDQUFDLFNBQVM7U0FDdkIsQ0FBQztRQUVGLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksRUFBRSxFQUFFO1lBQzFDLGtCQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNwQztLQUNGO0lBdkdEOzs7Ozs7T0FNRztJQUNJLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBZ0I7UUFDdkUsTUFBTSxNQUFPLFNBQVEsc0JBQVM7WUFBOUI7O2dCQUNrQixhQUFRLEdBQUcsUUFBUSxDQUFDO2dCQUNwQixjQUFTLEdBQUcsWUFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLGdCQUFTLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxZQUFhLENBQUM7WUFDOUcsQ0FBQztTQUFBO1FBQ0QsT0FBTyxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDOUI7SUE0RkQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0ksWUFBWTtRQUNqQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7S0FDeEI7SUFFRDs7OztPQUlHO0lBQ0ksY0FBYyxDQUFDLEdBQUcsT0FBdUI7Ozs7Ozs7Ozs7UUFDOUMsSUFBSSxJQUFJLENBQUMsZUFBZSxLQUFLLFNBQVMsRUFBRTtZQUN0QyxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztTQUMzQjtRQUVELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUMzQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsY0FBYyxDQUFDLENBQzFELENBQUMsQ0FBQztLQUNKO0lBRU8saUJBQWlCLENBQUMsU0FBaUI7UUFDekMsTUFBTSxnQkFBZ0IsR0FBVyxtREFBbUQsQ0FBQztRQUNyRixJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUNwQyw0QkFBNEI7WUFDNUIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNsRCxJQUFJLFlBQVksQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sSUFBSSxDQUFDLElBQUksWUFBWSxDQUFDLFVBQVUsRUFBRSxVQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLFlBQVksRUFBRTtnQkFDcEgsTUFBTSxJQUFJLEtBQUssQ0FBQywyREFBMkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsMkNBQTJDLENBQUMsQ0FBQzthQUNySjtTQUNGO1FBQ0QsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFFTyxZQUFZLENBQUMsTUFBZTtRQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUM7UUFDbEIsT0FBTyw0QkFBYyxDQUFDLE1BQU0sRUFBRTtZQUM1QixRQUFRLENBQUMsSUFBSSxFQUFFLElBQUk7Z0JBQ2pCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3RDLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUssSUFBSSxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzlHLDhEQUE4RDtnQkFDOUQsSUFBSSx1QkFBdUIsRUFBRTtvQkFDM0IsT0FBTyxzQkFBYSxDQUFDO3dCQUNuQixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7d0JBQzNCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUzt3QkFDekIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO3dCQUMzQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUU7d0JBQ2hDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO3dCQUNsRCxpQkFBaUIsRUFBRSx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO3dCQUM1RCxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVU7cUJBQ3RCLENBQUMsQ0FBQztpQkFDSjtnQkFFRCxPQUFPO29CQUNMLE9BQU8sRUFBRTt3QkFDUDs0QkFDRSxVQUFVLEVBQUU7Z0NBQ1YsTUFBTSxFQUFFO29DQUNOLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtvQ0FDM0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO29DQUN6QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7aUNBQzVCO2dDQUNELE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTtnQ0FDL0IsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTO2dDQUNwQixJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVU7NkJBQ3RCOzRCQUNELEVBQUUsRUFBRSxJQUFJOzRCQUNSLFNBQVMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVM7NEJBQ2xFLEtBQUssRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsS0FBSzs0QkFDdEMsVUFBVSxFQUFFLElBQUk7eUJBQ21CO3FCQUN0QztpQkFDRixDQUFDO1lBQ0osQ0FBQztZQUVELGNBQWM7Z0JBQ1osK0NBQStDO2dCQUMvQyxNQUFNLElBQUksR0FBRyxJQUFJLHFCQUFTLEVBQVcsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBRS9CLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztnQkFDWixTQUFTLGNBQWM7b0JBQ3JCLE9BQU8sUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUN6QixDQUFDO2dCQUVELE9BQU87b0JBQ0wsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsNEJBQWMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO3dCQUM5RCxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUk7NEJBQ2pCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDOzRCQUU1QyxPQUFPO2dDQUNMLFVBQVUsRUFBRTtvQ0FDVixNQUFNLEVBQUU7d0NBQ04sVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO3dDQUMzQixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7d0NBQ3pCLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtxQ0FDNUI7b0NBQ0QsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO29DQUMvQixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVM7b0NBQ3BCLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVTtpQ0FDdEI7Z0NBQ0QsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFLElBQUksY0FBYyxFQUFFO2dDQUNoQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTO2dDQUNsRSxLQUFLLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUs7Z0NBQ3RDLFVBQVUsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUs7NkJBQzFDLENBQUM7d0JBQ0osQ0FBQzt3QkFDRCxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUk7NEJBRXZCLE1BQU0sYUFBYSxHQUFHLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDOzRCQUVsRCxJQUFJLGFBQWEsRUFBRTtnQ0FDakIscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7NkJBQzdCOzRCQUVELElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFFcEMsT0FBTztnQ0FDTCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0NBQzNCLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRSxJQUFJLGNBQWMsRUFBRTtnQ0FDaEMsS0FBSyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxLQUFLO2dDQUN0QyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNO2dDQUMvQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLOzZCQUMxQyxDQUFDO3dCQUNKLENBQUM7cUJBQ0YsQ0FBcUMsQ0FBQztpQkFDeEMsQ0FBQztZQUNKLENBQUM7U0FDRixDQUFDLENBQUM7S0FDSjtJQUVEOztPQUVHO0lBQ0ssa0JBQWtCLENBQUMsSUFBc0IsRUFBRSxNQUFlO1FBQ2hFLE1BQU0sS0FBSyxHQUFHLFlBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0IsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxLQUFLLENBQUMsTUFBTSxzQkFBc0IsTUFBTSxTQUFTLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1NBQ3ZIO0tBQ0Y7SUFFRDs7O09BR0c7SUFDSyx3QkFBd0IsQ0FBQyxJQUE0QjtRQUMzRCxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFO1lBQ3ZFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0dBQWtHLENBQUMsQ0FBQztTQUNySDtLQUNGO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxJQUFzQjtRQUM5QyxNQUFNLFlBQVksR0FBRyxZQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUU1Qyx1RUFBdUU7UUFDdkUsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRTtZQUM5QixPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQscUVBQXFFO1FBQ3JFLHdFQUF3RTtRQUN4RSx1QkFBdUI7UUFDdkIsT0FBTyxZQUFZLEtBQUssSUFBSSxDQUFDLE9BQU8sQ0FBQztLQUN0Qzs7QUEvUkgsc0JBZ1NDOzs7QUFFRCxTQUFTLG1CQUFtQixDQUFDLENBQXFCLEVBQUUsQ0FBUztJQUMzRCxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsY0FBYyxDQUFDLE9BQWU7SUFDckMsSUFBSSxPQUFPLEtBQUssRUFBRSxFQUFFO1FBQUUsT0FBTyxVQUFVLENBQUM7S0FBRTtJQUMxQyxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUU7UUFBRSxPQUFPLFVBQVUsQ0FBQztLQUFFO0lBQ3pDLElBQUksT0FBTyxHQUFHLEVBQUUsRUFBRTtRQUFFLE9BQU8sQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDO0tBQUU7SUFDekQsT0FBTyxPQUFPLEdBQUcsVUFBVSxDQUFDO0FBQzlCLENBQUM7QUFFRCxTQUFTLHVCQUF1QixDQUFDLFNBQWtCO0lBQ2pELElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0tBQUU7SUFFbEQsTUFBTSxNQUFNLEdBQUcsMEJBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6QyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1FBQzVCLE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQztLQUN6QjtJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLHlCQUF5QixDQUFDLFNBQWtCO0lBQ25ELElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0tBQUU7SUFFbEQsTUFBTSxNQUFNLEdBQUcsMEJBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6QyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFO1FBQ2hDLDhEQUE4RDtRQUM5RCxvRUFBb0U7UUFDcEUsT0FBTyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDaEM7U0FBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFO1FBQ3BDLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsSUFBNEI7SUFDekQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLElBQTRCO0lBQ3pELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRTtRQUM5Qyw0SEFBNEg7UUFDNUgsTUFBTSxJQUFJLEtBQUssQ0FBQywyRUFBMkUsQ0FBQyxDQUFDO0tBQzlGO0lBQUEsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcm5Gb3JtYXQsIExhenksIFN0YWNrLCBUb2tlbiwgQW5ub3RhdGlvbnMgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSUFsYXJtQWN0aW9uIH0gZnJvbSAnLi9hbGFybS1hY3Rpb24nO1xuaW1wb3J0IHsgQWxhcm1CYXNlLCBJQWxhcm0gfSBmcm9tICcuL2FsYXJtLWJhc2UnO1xuaW1wb3J0IHsgQ2ZuQWxhcm0sIENmbkFsYXJtUHJvcHMgfSBmcm9tICcuL2Nsb3Vkd2F0Y2guZ2VuZXJhdGVkJztcbmltcG9ydCB7IEhvcml6b250YWxBbm5vdGF0aW9uIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBDcmVhdGVBbGFybU9wdGlvbnMgfSBmcm9tICcuL21ldHJpYyc7XG5pbXBvcnQgeyBJTWV0cmljLCBNZXRyaWNFeHByZXNzaW9uQ29uZmlnLCBNZXRyaWNTdGF0Q29uZmlnIH0gZnJvbSAnLi9tZXRyaWMtdHlwZXMnO1xuaW1wb3J0IHsgZGlzcGF0Y2hNZXRyaWMsIG1ldHJpY1BlcmlvZCB9IGZyb20gJy4vcHJpdmF0ZS9tZXRyaWMtdXRpbCc7XG5pbXBvcnQgeyBkcm9wVW5kZWZpbmVkIH0gZnJvbSAnLi9wcml2YXRlL29iamVjdCc7XG5pbXBvcnQgeyBNZXRyaWNTZXQgfSBmcm9tICcuL3ByaXZhdGUvcmVuZGVyaW5nJztcbmltcG9ydCB7IHBhcnNlU3RhdGlzdGljIH0gZnJvbSAnLi9wcml2YXRlL3N0YXRpc3RpYyc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgQWxhcm1zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxhcm1Qcm9wcyBleHRlbmRzIENyZWF0ZUFsYXJtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbWV0cmljIHRvIGFkZCB0aGUgYWxhcm0gb25cbiAgICpcbiAgICogTWV0cmljIG9iamVjdHMgY2FuIGJlIG9idGFpbmVkIGZyb20gbW9zdCByZXNvdXJjZXMsIG9yIHlvdSBjYW4gY29uc3RydWN0XG4gICAqIGN1c3RvbSBNZXRyaWMgb2JqZWN0cyBieSBpbnN0YW50aWF0aW5nIG9uZS5cbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpYzogSU1ldHJpYztcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uIG9wZXJhdG9yIGZvciBldmFsdWF0aW5nIGFsYXJtc1xuICovXG5leHBvcnQgZW51bSBDb21wYXJpc29uT3BlcmF0b3Ige1xuICAvKipcbiAgICogU3BlY2lmaWVkIHN0YXRpc3RpYyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHRocmVzaG9sZFxuICAgKi9cbiAgR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCA9ICdHcmVhdGVyVGhhbk9yRXF1YWxUb1RocmVzaG9sZCcsXG5cbiAgLyoqXG4gICAqIFNwZWNpZmllZCBzdGF0aXN0aWMgaXMgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZSB0aHJlc2hvbGRcbiAgICovXG4gIEdSRUFURVJfVEhBTl9USFJFU0hPTEQgPSAnR3JlYXRlclRoYW5UaHJlc2hvbGQnLFxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZWQgc3RhdGlzdGljIGlzIHN0cmljdGx5IGxlc3MgdGhhbiB0aGUgdGhyZXNob2xkXG4gICAqL1xuICBMRVNTX1RIQU5fVEhSRVNIT0xEID0gJ0xlc3NUaGFuVGhyZXNob2xkJyxcblxuICAvKipcbiAgICogU3BlY2lmaWVkIHN0YXRpc3RpYyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHRocmVzaG9sZC5cbiAgICovXG4gIExFU1NfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQgPSAnTGVzc1RoYW5PckVxdWFsVG9UaHJlc2hvbGQnLFxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZWQgc3RhdGlzdGljIGlzIGxvd2VyIHRoYW4gb3IgZ3JlYXRlciB0aGFuIHRoZSBhbm9tYWx5IG1vZGVsIGJhbmQuXG4gICAqIFVzZWQgb25seSBmb3IgYWxhcm1zIGJhc2VkIG9uIGFub21hbHkgZGV0ZWN0aW9uIG1vZGVsc1xuICAgKi9cbiAgTEVTU19USEFOX0xPV0VSX09SX0dSRUFURVJfVEhBTl9VUFBFUl9USFJFU0hPTEQgPSAnTGVzc1RoYW5Mb3dlck9yR3JlYXRlclRoYW5VcHBlclRocmVzaG9sZCcsXG5cbiAgLyoqXG4gICAqIFNwZWNpZmllZCBzdGF0aXN0aWMgaXMgZ3JlYXRlciB0aGFuIHRoZSBhbm9tYWx5IG1vZGVsIGJhbmQuXG4gICAqIFVzZWQgb25seSBmb3IgYWxhcm1zIGJhc2VkIG9uIGFub21hbHkgZGV0ZWN0aW9uIG1vZGVsc1xuICAgKi9cbiAgR1JFQVRFUl9USEFOX1VQUEVSX1RIUkVTSE9MRCA9ICdHcmVhdGVyVGhhblVwcGVyVGhyZXNob2xkJyxcblxuICAvKipcbiAgICogU3BlY2lmaWVkIHN0YXRpc3RpYyBpcyBsb3dlciB0aGFuIHRoZSBhbm9tYWx5IG1vZGVsIGJhbmQuXG4gICAqIFVzZWQgb25seSBmb3IgYWxhcm1zIGJhc2VkIG9uIGFub21hbHkgZGV0ZWN0aW9uIG1vZGVsc1xuICAgKi9cbiAgTEVTU19USEFOX0xPV0VSX1RIUkVTSE9MRCA9ICdMZXNzVGhhbkxvd2VyVGhyZXNob2xkJyxcbn1cblxuY29uc3QgT1BFUkFUT1JfU1lNQk9MUzoge1trZXk6IHN0cmluZ106IHN0cmluZ30gPSB7XG4gIEdyZWF0ZXJUaGFuT3JFcXVhbFRvVGhyZXNob2xkOiAnPj0nLFxuICBHcmVhdGVyVGhhblRocmVzaG9sZDogJz4nLFxuICBMZXNzVGhhblRocmVzaG9sZDogJzwnLFxuICBMZXNzVGhhbk9yRXF1YWxUb1RocmVzaG9sZDogJzw9Jyxcbn07XG5cbi8qKlxuICogU3BlY2lmeSBob3cgbWlzc2luZyBkYXRhIHBvaW50cyBhcmUgdHJlYXRlZCBkdXJpbmcgYWxhcm0gZXZhbHVhdGlvblxuICovXG5leHBvcnQgZW51bSBUcmVhdE1pc3NpbmdEYXRhIHtcbiAgLyoqXG4gICAqIE1pc3NpbmcgZGF0YSBwb2ludHMgYXJlIHRyZWF0ZWQgYXMgYnJlYWNoaW5nIHRoZSB0aHJlc2hvbGRcbiAgICovXG4gIEJSRUFDSElORyA9ICdicmVhY2hpbmcnLFxuXG4gIC8qKlxuICAgKiBNaXNzaW5nIGRhdGEgcG9pbnRzIGFyZSB0cmVhdGVkIGFzIGJlaW5nIHdpdGhpbiB0aGUgdGhyZXNob2xkXG4gICAqL1xuICBOT1RfQlJFQUNISU5HID0gJ25vdEJyZWFjaGluZycsXG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IGFsYXJtIHN0YXRlIGlzIG1haW50YWluZWRcbiAgICovXG4gIElHTk9SRSA9ICdpZ25vcmUnLFxuXG4gIC8qKlxuICAgKiBUaGUgYWxhcm0gZG9lcyBub3QgY29uc2lkZXIgbWlzc2luZyBkYXRhIHBvaW50cyB3aGVuIGV2YWx1YXRpbmcgd2hldGhlciB0byBjaGFuZ2Ugc3RhdGVcbiAgICovXG4gIE1JU1NJTkcgPSAnbWlzc2luZydcbn1cblxuLyoqXG4gKiBBbiBhbGFybSBvbiBhIENsb3VkV2F0Y2ggbWV0cmljXG4gKi9cbmV4cG9ydCBjbGFzcyBBbGFybSBleHRlbmRzIEFsYXJtQmFzZSB7XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhbiBleGlzdGluZyBDbG91ZFdhdGNoIGFsYXJtIHByb3ZpZGVkIGFuIEFSTlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgVGhlIHBhcmVudCBjcmVhdGluZyBjb25zdHJ1Y3QgKHVzdWFsbHkgYHRoaXNgKS5cbiAgICogQHBhcmFtIGlkIFRoZSBjb25zdHJ1Y3QncyBuYW1lXG4gICAqIEBwYXJhbSBhbGFybUFybiBBbGFybSBBUk4gKGkuZS4gYXJuOmF3czpjbG91ZHdhdGNoOjxyZWdpb24+OjxhY2NvdW50LWlkPjphbGFybTpGb28pXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21BbGFybUFybihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBhbGFybUFybjogc3RyaW5nKTogSUFsYXJtIHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBBbGFybUJhc2UgaW1wbGVtZW50cyBJQWxhcm0ge1xuICAgICAgcHVibGljIHJlYWRvbmx5IGFsYXJtQXJuID0gYWxhcm1Bcm47XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYWxhcm1OYW1lID0gU3RhY2sub2Yoc2NvcGUpLnNwbGl0QXJuKGFsYXJtQXJuLCBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSkucmVzb3VyY2VOYW1lITtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBUk4gb2YgdGhpcyBhbGFybVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWxhcm1Bcm46IHN0cmluZztcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGlzIGFsYXJtLlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWxhcm1OYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBtZXRyaWMgb2JqZWN0IHRoaXMgYWxhcm0gd2FzIGJhc2VkIG9uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWV0cmljOiBJTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGlzIG1ldHJpYyBhcyBhbiBhbm5vdGF0aW9uXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGFubm90YXRpb246IEhvcml6b250YWxBbm5vdGF0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBBbGFybVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLmFsYXJtTmFtZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvbXBhcmlzb25PcGVyYXRvciA9IHByb3BzLmNvbXBhcmlzb25PcGVyYXRvciB8fCBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRDtcblxuICAgIC8vIFJlbmRlciBtZXRyaWMsIHByb2Nlc3MgcG90ZW50aWFsIG92ZXJyaWRlcyBmcm9tIHRoZSBhbGFybVxuICAgIC8vIChJdCB3b3VsZCBiZSBwcmVmZXJhYmxlIGlmIHRoZSBzdGF0aXN0aWMgZXRjLiB3YXMgd29ya2VkIGludG8gdGhlIG1ldHJpYyxcbiAgICAvLyBidXQgaGV5IHdlJ3JlIGFsbG93aW5nIG92ZXJyaWRlcy4uLilcbiAgICBjb25zdCBtZXRyaWNQcm9wczogV3JpdGVhYmxlPFBhcnRpYWw8Q2ZuQWxhcm1Qcm9wcz4+ID0gdGhpcy5yZW5kZXJNZXRyaWMocHJvcHMubWV0cmljKTtcbiAgICBpZiAocHJvcHMucGVyaW9kKSB7XG4gICAgICBtZXRyaWNQcm9wcy5wZXJpb2QgPSBwcm9wcy5wZXJpb2QudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5zdGF0aXN0aWMpIHtcbiAgICAgIC8vIFdpbGwgb3ZlcndyaXRlIGJvdGggZmllbGRzIGlmIHByZXNlbnRcbiAgICAgIE9iamVjdC5hc3NpZ24obWV0cmljUHJvcHMsIHtcbiAgICAgICAgc3RhdGlzdGljOiByZW5kZXJJZlNpbXBsZVN0YXRpc3RpYyhwcm9wcy5zdGF0aXN0aWMpLFxuICAgICAgICBleHRlbmRlZFN0YXRpc3RpYzogcmVuZGVySWZFeHRlbmRlZFN0YXRpc3RpYyhwcm9wcy5zdGF0aXN0aWMpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYWxhcm0gPSBuZXcgQ2ZuQWxhcm0odGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgLy8gTWV0YVxuICAgICAgYWxhcm1EZXNjcmlwdGlvbjogcHJvcHMuYWxhcm1EZXNjcmlwdGlvbixcbiAgICAgIGFsYXJtTmFtZTogdGhpcy5waHlzaWNhbE5hbWUsXG5cbiAgICAgIC8vIEV2YWx1YXRpb25cbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcixcbiAgICAgIHRocmVzaG9sZDogcHJvcHMudGhyZXNob2xkLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm06IHByb3BzLmRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgZXZhbHVhdGVMb3dTYW1wbGVDb3VudFBlcmNlbnRpbGU6IHByb3BzLmV2YWx1YXRlTG93U2FtcGxlQ291bnRQZXJjZW50aWxlLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YTogcHJvcHMudHJlYXRNaXNzaW5nRGF0YSxcblxuICAgICAgLy8gQWN0aW9uc1xuICAgICAgYWN0aW9uc0VuYWJsZWQ6IHByb3BzLmFjdGlvbnNFbmFibGVkLFxuICAgICAgYWxhcm1BY3Rpb25zOiBMYXp5Lmxpc3QoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLmFsYXJtQWN0aW9uQXJucyB9KSxcbiAgICAgIGluc3VmZmljaWVudERhdGFBY3Rpb25zOiBMYXp5Lmxpc3QoeyBwcm9kdWNlOiAoKCkgPT4gdGhpcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uQXJucykgfSksXG4gICAgICBva0FjdGlvbnM6IExhenkubGlzdCh7IHByb2R1Y2U6ICgpID0+IHRoaXMub2tBY3Rpb25Bcm5zIH0pLFxuXG4gICAgICAvLyBNZXRyaWNcbiAgICAgIC4uLm1ldHJpY1Byb3BzLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hbGFybUFybiA9IHRoaXMuZ2V0UmVzb3VyY2VBcm5BdHRyaWJ1dGUoYWxhcm0uYXR0ckFybiwge1xuICAgICAgc2VydmljZTogJ2Nsb3Vkd2F0Y2gnLFxuICAgICAgcmVzb3VyY2U6ICdhbGFybScsXG4gICAgICByZXNvdXJjZU5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgYXJuRm9ybWF0OiBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSxcbiAgICB9KTtcbiAgICB0aGlzLmFsYXJtTmFtZSA9IHRoaXMuZ2V0UmVzb3VyY2VOYW1lQXR0cmlidXRlKGFsYXJtLnJlZik7XG5cbiAgICB0aGlzLm1ldHJpYyA9IHByb3BzLm1ldHJpYztcbiAgICBjb25zdCBkYXRhcG9pbnRzID0gcHJvcHMuZGF0YXBvaW50c1RvQWxhcm0gfHwgcHJvcHMuZXZhbHVhdGlvblBlcmlvZHM7XG4gICAgdGhpcy5hbm5vdGF0aW9uID0ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgIGxhYmVsOiBgJHt0aGlzLm1ldHJpY30gJHtPUEVSQVRPUl9TWU1CT0xTW2NvbXBhcmlzb25PcGVyYXRvcl19ICR7cHJvcHMudGhyZXNob2xkfSBmb3IgJHtkYXRhcG9pbnRzfSBkYXRhcG9pbnRzIHdpdGhpbiAke2Rlc2NyaWJlUGVyaW9kKHByb3BzLmV2YWx1YXRpb25QZXJpb2RzICogbWV0cmljUGVyaW9kKHByb3BzLm1ldHJpYykudG9TZWNvbmRzKCkpfWAsXG4gICAgICB2YWx1ZTogcHJvcHMudGhyZXNob2xkLFxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IHcgb2YgdGhpcy5tZXRyaWMud2FybmluZ3MgPz8gW10pIHtcbiAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmcodyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFR1cm4gdGhpcyBhbGFybSBpbnRvIGEgaG9yaXpvbnRhbCBhbm5vdGF0aW9uXG4gICAqXG4gICAqIFRoaXMgaXMgdXNlZnVsIGlmIHlvdSB3YW50IHRvIHJlcHJlc2VudCBhbiBBbGFybSBpbiBhIG5vbi1BbGFybVdpZGdldC5cbiAgICogQW4gYEFsYXJtV2lkZ2V0YCBjYW4gZGlyZWN0bHkgc2hvdyBhbiBhbGFybSwgYnV0IGl0IGNhbiBvbmx5IHNob3cgYVxuICAgKiBzaW5nbGUgYWxhcm0gYW5kIG5vIG90aGVyIG1ldHJpY3MuIEluc3RlYWQsIHlvdSBjYW4gY29udmVydCB0aGUgYWxhcm0gdG9cbiAgICogYSBIb3Jpem9udGFsQW5ub3RhdGlvbiBhbmQgYWRkIGl0IGFzIGFuIGFubm90YXRpb24gdG8gYW5vdGhlciBncmFwaC5cbiAgICpcbiAgICogVGhpcyBtaWdodCBiZSB1c2VmdWwgaWY6XG4gICAqXG4gICAqIC0gWW91IHdhbnQgdG8gc2hvdyBtdWx0aXBsZSBhbGFybXMgaW5zaWRlIGEgc2luZ2xlIGdyYXBoLCBmb3IgZXhhbXBsZSBpZlxuICAgKiAgIHlvdSBoYXZlIGJvdGggYSBcInNtYWxsIG1hcmdpbi9sb25nIHBlcmlvZFwiIGFsYXJtIGFzIHdlbGwgYXMgYVxuICAgKiAgIFwibGFyZ2UgbWFyZ2luL3Nob3J0IHBlcmlvZFwiIGFsYXJtLlxuICAgKlxuICAgKiAtIFlvdSB3YW50IHRvIHNob3cgYW4gQWxhcm0gbGluZSBpbiBhIGdyYXBoIHdpdGggbXVsdGlwbGUgbWV0cmljcyBpbiBpdC5cbiAgICovXG4gIHB1YmxpYyB0b0Fubm90YXRpb24oKTogSG9yaXpvbnRhbEFubm90YXRpb24ge1xuICAgIHJldHVybiB0aGlzLmFubm90YXRpb247XG4gIH1cblxuICAvKipcbiAgICogVHJpZ2dlciB0aGlzIGFjdGlvbiBpZiB0aGUgYWxhcm0gZmlyZXNcbiAgICpcbiAgICogVHlwaWNhbGx5IHRoZSBBUk4gb2YgYW4gU05TIHRvcGljIG9yIEFSTiBvZiBhbiBBdXRvU2NhbGluZyBwb2xpY3kuXG4gICAqL1xuICBwdWJsaWMgYWRkQWxhcm1BY3Rpb24oLi4uYWN0aW9uczogSUFsYXJtQWN0aW9uW10pIHtcbiAgICBpZiAodGhpcy5hbGFybUFjdGlvbkFybnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5hbGFybUFjdGlvbkFybnMgPSBbXTtcbiAgICB9XG5cbiAgICB0aGlzLmFsYXJtQWN0aW9uQXJucy5wdXNoKC4uLmFjdGlvbnMubWFwKGEgPT5cbiAgICAgIHRoaXMudmFsaWRhdGVBY3Rpb25Bcm4oYS5iaW5kKHRoaXMsIHRoaXMpLmFsYXJtQWN0aW9uQXJuKSxcbiAgICApKTtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVBY3Rpb25Bcm4oYWN0aW9uQXJuOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGVjMkFjdGlvbnNSZWdleHA6IFJlZ0V4cCA9IC9hcm46YXdzW2EtejAtOS1dKjphdXRvbWF0ZTpbYS16fFxcZHwtXSs6ZWMyOlthLXpdKy87XG4gICAgaWYgKGVjMkFjdGlvbnNSZWdleHAudGVzdChhY3Rpb25Bcm4pKSB7XG4gICAgICAvLyBDaGVjayBwZXItaW5zdGFuY2UgbWV0cmljXG4gICAgICBjb25zdCBtZXRyaWNDb25maWcgPSB0aGlzLm1ldHJpYy50b01ldHJpY0NvbmZpZygpO1xuICAgICAgaWYgKG1ldHJpY0NvbmZpZy5tZXRyaWNTdGF0Py5kaW1lbnNpb25zPy5sZW5ndGggIT0gMSB8fCBtZXRyaWNDb25maWcubWV0cmljU3RhdD8uZGltZW5zaW9ucyFbMF0ubmFtZSAhPSAnSW5zdGFuY2VJZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFQzIgYWxhcm0gYWN0aW9ucyByZXF1aXJlcyBhbiBFQzIgUGVyLUluc3RhbmNlIE1ldHJpYy4gKCR7SlNPTi5zdHJpbmdpZnkobWV0cmljQ29uZmlnKX0gZG9lcyBub3QgaGF2ZSBhbiAnSW5zdGFuY2VJZCcgZGltZW5zaW9uKWApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYWN0aW9uQXJuO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJNZXRyaWMobWV0cmljOiBJTWV0cmljKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIGRpc3BhdGNoTWV0cmljKG1ldHJpYywge1xuICAgICAgd2l0aFN0YXQoc3RhdCwgY29uZikge1xuICAgICAgICBzZWxmLnZhbGlkYXRlTWV0cmljU3RhdChzdGF0LCBtZXRyaWMpO1xuICAgICAgICBjb25zdCBjYW5SZW5kZXJBc0xlZ2FjeU1ldHJpYyA9IGNvbmYucmVuZGVyaW5nUHJvcGVydGllcz8ubGFiZWwgPT0gdW5kZWZpbmVkICYmICFzZWxmLnJlcXVpcmVzQWNjb3VudElkKHN0YXQpO1xuICAgICAgICAvLyBEbyB0aGlzIHRvIGRpc3R1cmIgZXhpc3RpbmcgdGVtcGxhdGVzIGFzIGxpdHRsZSBhcyBwb3NzaWJsZVxuICAgICAgICBpZiAoY2FuUmVuZGVyQXNMZWdhY3lNZXRyaWMpIHtcbiAgICAgICAgICByZXR1cm4gZHJvcFVuZGVmaW5lZCh7XG4gICAgICAgICAgICBkaW1lbnNpb25zOiBzdGF0LmRpbWVuc2lvbnMsXG4gICAgICAgICAgICBuYW1lc3BhY2U6IHN0YXQubmFtZXNwYWNlLFxuICAgICAgICAgICAgbWV0cmljTmFtZTogc3RhdC5tZXRyaWNOYW1lLFxuICAgICAgICAgICAgcGVyaW9kOiBzdGF0LnBlcmlvZD8udG9TZWNvbmRzKCksXG4gICAgICAgICAgICBzdGF0aXN0aWM6IHJlbmRlcklmU2ltcGxlU3RhdGlzdGljKHN0YXQuc3RhdGlzdGljKSxcbiAgICAgICAgICAgIGV4dGVuZGVkU3RhdGlzdGljOiByZW5kZXJJZkV4dGVuZGVkU3RhdGlzdGljKHN0YXQuc3RhdGlzdGljKSxcbiAgICAgICAgICAgIHVuaXQ6IHN0YXQudW5pdEZpbHRlcixcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbWV0cmljczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXRyaWNTdGF0OiB7XG4gICAgICAgICAgICAgICAgbWV0cmljOiB7XG4gICAgICAgICAgICAgICAgICBtZXRyaWNOYW1lOiBzdGF0Lm1ldHJpY05hbWUsXG4gICAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHN0YXQubmFtZXNwYWNlLFxuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uczogc3RhdC5kaW1lbnNpb25zLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcGVyaW9kOiBzdGF0LnBlcmlvZC50b1NlY29uZHMoKSxcbiAgICAgICAgICAgICAgICBzdGF0OiBzdGF0LnN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgICB1bml0OiBzdGF0LnVuaXRGaWx0ZXIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGlkOiAnbTEnLFxuICAgICAgICAgICAgICBhY2NvdW50SWQ6IHNlbGYucmVxdWlyZXNBY2NvdW50SWQoc3RhdCkgPyBzdGF0LmFjY291bnQgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGxhYmVsOiBjb25mLnJlbmRlcmluZ1Byb3BlcnRpZXM/LmxhYmVsLFxuICAgICAgICAgICAgICByZXR1cm5EYXRhOiB0cnVlLFxuICAgICAgICAgICAgfSBhcyBDZm5BbGFybS5NZXRyaWNEYXRhUXVlcnlQcm9wZXJ0eSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuICAgICAgfSxcblxuICAgICAgd2l0aEV4cHJlc3Npb24oKSB7XG4gICAgICAgIC8vIEV4cGFuZCB0aGUgbWF0aCBleHByZXNzaW9uIG1ldHJpYyBpbnRvIGEgc2V0XG4gICAgICAgIGNvbnN0IG1zZXQgPSBuZXcgTWV0cmljU2V0PGJvb2xlYW4+KCk7XG4gICAgICAgIG1zZXQuYWRkVG9wTGV2ZWwodHJ1ZSwgbWV0cmljKTtcblxuICAgICAgICBsZXQgZWlkID0gMDtcbiAgICAgICAgZnVuY3Rpb24gdW5pcXVlTWV0cmljSWQoKSB7XG4gICAgICAgICAgcmV0dXJuIGBleHByXyR7KytlaWR9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbWV0cmljczogbXNldC5lbnRyaWVzLm1hcChlbnRyeSA9PiBkaXNwYXRjaE1ldHJpYyhlbnRyeS5tZXRyaWMsIHtcbiAgICAgICAgICAgIHdpdGhTdGF0KHN0YXQsIGNvbmYpIHtcbiAgICAgICAgICAgICAgc2VsZi52YWxpZGF0ZU1ldHJpY1N0YXQoc3RhdCwgZW50cnkubWV0cmljKTtcblxuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG1ldHJpY1N0YXQ6IHtcbiAgICAgICAgICAgICAgICAgIG1ldHJpYzoge1xuICAgICAgICAgICAgICAgICAgICBtZXRyaWNOYW1lOiBzdGF0Lm1ldHJpY05hbWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogc3RhdC5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnM6IHN0YXQuZGltZW5zaW9ucyxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHN0YXQucGVyaW9kLnRvU2Vjb25kcygpLFxuICAgICAgICAgICAgICAgICAgc3RhdDogc3RhdC5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgICAgICB1bml0OiBzdGF0LnVuaXRGaWx0ZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpZDogZW50cnkuaWQgfHwgdW5pcXVlTWV0cmljSWQoKSxcbiAgICAgICAgICAgICAgICBhY2NvdW50SWQ6IHNlbGYucmVxdWlyZXNBY2NvdW50SWQoc3RhdCkgPyBzdGF0LmFjY291bnQgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGNvbmYucmVuZGVyaW5nUHJvcGVydGllcz8ubGFiZWwsXG4gICAgICAgICAgICAgICAgcmV0dXJuRGF0YTogZW50cnkudGFnID8gdW5kZWZpbmVkIDogZmFsc2UsIC8vIGVudHJ5LnRhZyBldmFsdWF0ZXMgdG8gdHJ1ZSBpZiB0aGUgbWV0cmljIGlzIHRoZSBtYXRoIGV4cHJlc3Npb24gdGhlIGFsYXJtIGlzIGJhc2VkIG9uLlxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdpdGhFeHByZXNzaW9uKGV4cHIsIGNvbmYpIHtcblxuICAgICAgICAgICAgICBjb25zdCBoYXNTdWJtZXRyaWNzID0gbWF0aEV4cHJIYXNTdWJtZXRyaWNzKGV4cHIpO1xuXG4gICAgICAgICAgICAgIGlmIChoYXNTdWJtZXRyaWNzKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0U3VibWV0cmljc0NvdW50KGV4cHIpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgc2VsZi52YWxpZGF0ZU1ldHJpY0V4cHJlc3Npb24oZXhwcik7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBleHByLmV4cHJlc3Npb24sXG4gICAgICAgICAgICAgICAgaWQ6IGVudHJ5LmlkIHx8IHVuaXF1ZU1ldHJpY0lkKCksXG4gICAgICAgICAgICAgICAgbGFiZWw6IGNvbmYucmVuZGVyaW5nUHJvcGVydGllcz8ubGFiZWwsXG4gICAgICAgICAgICAgICAgcGVyaW9kOiBoYXNTdWJtZXRyaWNzID8gdW5kZWZpbmVkIDogZXhwci5wZXJpb2QsXG4gICAgICAgICAgICAgICAgcmV0dXJuRGF0YTogZW50cnkudGFnID8gdW5kZWZpbmVkIDogZmFsc2UsIC8vIGVudHJ5LnRhZyBldmFsdWF0ZXMgdG8gdHJ1ZSBpZiB0aGUgbWV0cmljIGlzIHRoZSBtYXRoIGV4cHJlc3Npb24gdGhlIGFsYXJtIGlzIGJhc2VkIG9uLlxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSBhcyBDZm5BbGFybS5NZXRyaWNEYXRhUXVlcnlQcm9wZXJ0eSksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgaWYgYSByZWdpb24gaXMgaW4gdGhlIGdpdmVuIHN0YXQgY29uZmlnLCB0aGV5IG1hdGNoIHRoZSBBbGFybVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZU1ldHJpY1N0YXQoc3RhdDogTWV0cmljU3RhdENvbmZpZywgbWV0cmljOiBJTWV0cmljKSB7XG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcblxuICAgIGlmIChkZWZpbml0ZWx5RGlmZmVyZW50KHN0YXQucmVnaW9uLCBzdGFjay5yZWdpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjcmVhdGUgYW4gQWxhcm0gaW4gcmVnaW9uICcke3N0YWNrLnJlZ2lvbn0nIGJhc2VkIG9uIG1ldHJpYyAnJHttZXRyaWN9JyBpbiAnJHtzdGF0LnJlZ2lvbn0nYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGF0IHRoZSBleHByZXNzaW9uIGNvbmZpZyBkb2VzIG5vdCBzcGVjaWZ5IHNlYXJjaEFjY291bnQgb3Igc2VhcmNoUmVnaW9uIHByb3BzXG4gICAqIGFzIHNlYXJjaCBleHByZXNzaW9ucyBhcmUgbm90IHN1cHBvcnRlZCBieSBBbGFybXMuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlTWV0cmljRXhwcmVzc2lvbihleHByOiBNZXRyaWNFeHByZXNzaW9uQ29uZmlnKSB7XG4gICAgaWYgKGV4cHIuc2VhcmNoQWNjb3VudCAhPT0gdW5kZWZpbmVkIHx8IGV4cHIuc2VhcmNoUmVnaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNyZWF0ZSBhbiBBbGFybSBiYXNlZCBvbiBhIE1hdGhFeHByZXNzaW9uIHdoaWNoIHNwZWNpZmllcyBhIHNlYXJjaEFjY291bnQgb3Igc2VhcmNoUmVnaW9uJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgYWNjb3VudElkIHByb3BlcnR5IHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgbWV0cmljLlxuICAgKi9cbiAgcHJpdmF0ZSByZXF1aXJlc0FjY291bnRJZChzdGF0OiBNZXRyaWNTdGF0Q29uZmlnKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc3RhY2tBY2NvdW50ID0gU3RhY2sub2YodGhpcykuYWNjb3VudDtcblxuICAgIC8vIGlmIHN0YXQuYWNjb3VudCBpcyB1bmRlZmluZWQsIGl0J3MgYnkgZGVmaW5pdGlvbiBpbiB0aGUgc2FtZSBhY2NvdW50XG4gICAgaWYgKHN0YXQuYWNjb3VudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHRydWUgaWYgdGhleSdyZSBkaWZmZXJlbnQuIFRoZSBBQ0NPVU5UX0lEIHRva2VuIGlzIGludGVybmVkXG4gICAgLy8gc28gd2lsbCBhbHdheXMgaGF2ZSB0aGUgc2FtZSBzdHJpbmcgdmFsdWUgKGFuZCBldmVuIGlmIHdlIGd1ZXNzIHdyb25nXG4gICAgLy8gaXQgd2lsbCBzdGlsbCB3b3JrKS5cbiAgICByZXR1cm4gc3RhY2tBY2NvdW50ICE9PSBzdGF0LmFjY291bnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVmaW5pdGVseURpZmZlcmVudCh4OiBzdHJpbmcgfCB1bmRlZmluZWQsIHk6IHN0cmluZykge1xuICByZXR1cm4geCAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKHkpICYmIHggIT09IHk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgaHVtYW4gcmVhZGFibGUgc3RyaW5nIGZvciB0aGlzIHBlcmlvZFxuICpcbiAqIFdlIGtub3cgdGhlIHNlY29uZHMgYXJlIGFsd2F5cyBvbmUgb2YgYSBoYW5kZnVsIG9mIGFsbG93ZWQgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBkZXNjcmliZVBlcmlvZChzZWNvbmRzOiBudW1iZXIpIHtcbiAgaWYgKHNlY29uZHMgPT09IDYwKSB7IHJldHVybiAnMSBtaW51dGUnOyB9XG4gIGlmIChzZWNvbmRzID09PSAxKSB7IHJldHVybiAnMSBzZWNvbmQnOyB9XG4gIGlmIChzZWNvbmRzID4gNjApIHsgcmV0dXJuIChzZWNvbmRzIC8gNjApICsgJyBtaW51dGVzJzsgfVxuICByZXR1cm4gc2Vjb25kcyArICcgc2Vjb25kcyc7XG59XG5cbmZ1bmN0aW9uIHJlbmRlcklmU2ltcGxlU3RhdGlzdGljKHN0YXRpc3RpYz86IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChzdGF0aXN0aWMgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG5cbiAgY29uc3QgcGFyc2VkID0gcGFyc2VTdGF0aXN0aWMoc3RhdGlzdGljKTtcbiAgaWYgKHBhcnNlZC50eXBlID09PSAnc2ltcGxlJykge1xuICAgIHJldHVybiBwYXJzZWQuc3RhdGlzdGljO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHJlbmRlcklmRXh0ZW5kZWRTdGF0aXN0aWMoc3RhdGlzdGljPzogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHN0YXRpc3RpYyA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cblxuICBjb25zdCBwYXJzZWQgPSBwYXJzZVN0YXRpc3RpYyhzdGF0aXN0aWMpO1xuICBpZiAocGFyc2VkLnR5cGUgPT09ICdwZXJjZW50aWxlJykge1xuICAgIC8vIEFscmVhZHkgcGVyY2VudGlsZS4gQXZvaWQgcGFyc2luZyBiZWNhdXNlIHdlIG1pZ2h0IGdldCBpbnRvXG4gICAgLy8gZmxvYXRpbmcgcG9pbnQgcm91bmRpbmcgaXNzdWVzLCByZXR1cm4gYXMtaXMgYnV0IGxvd2VyY2FzZSB0aGUgcC5cbiAgICByZXR1cm4gc3RhdGlzdGljLnRvTG93ZXJDYXNlKCk7XG4gIH0gZWxzZSBpZiAocGFyc2VkLnR5cGUgPT09ICdnZW5lcmljJykge1xuICAgIHJldHVybiBzdGF0aXN0aWM7XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYXRoRXhwckhhc1N1Ym1ldHJpY3MoZXhwcjogTWV0cmljRXhwcmVzc2lvbkNvbmZpZykge1xuICByZXR1cm4gT2JqZWN0LmtleXMoZXhwci51c2luZ01ldHJpY3MpLmxlbmd0aCA+IDA7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFN1Ym1ldHJpY3NDb3VudChleHByOiBNZXRyaWNFeHByZXNzaW9uQ29uZmlnKSB7XG4gIGlmIChPYmplY3Qua2V5cyhleHByLnVzaW5nTWV0cmljcykubGVuZ3RoID4gMTApIHtcbiAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbW9uaXRvcmluZy9BbGFybVRoYXRTZW5kc0VtYWlsLmh0bWwjYWxhcm1zLW9uLW1ldHJpYy1tYXRoLWV4cHJlc3Npb25zXG4gICAgdGhyb3cgbmV3IEVycm9yKCdBbGFybXMgb24gbWF0aCBleHByZXNzaW9ucyBjYW5ub3QgY29udGFpbiBtb3JlIHRoYW4gMTAgaW5kaXZpZHVhbCBtZXRyaWNzJyk7XG4gIH07XG59XG5cbnR5cGUgV3JpdGVhYmxlPFQ+ID0geyAtcmVhZG9ubHkgW1AgaW4ga2V5b2YgVF06IFRbUF0gfTtcbiJdfQ== |
\ | No newline at end of file |