@sitblueprint/website-construct 0.1.5 → 0.1.6
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.
- package/README.md +83 -0
- package/docs/CHANGELOG.md +20 -0
- package/lambda/index.d.ts +11 -0
- package/lambda/index.js +238 -0
- package/lambda/index.ts +335 -0
- package/lib/index.d.ts +39 -0
- package/lib/index.js +139 -2
- package/lib/index.ts +214 -0
- package/package.json +3 -3
- package/test/website-construct.test.js +127 -1
- package/test/website-construct.test.ts +140 -0
package/lib/index.ts
CHANGED
|
@@ -6,6 +6,10 @@ import * as certificatemanager from "aws-cdk-lib/aws-certificatemanager";
|
|
|
6
6
|
import * as cdk from "aws-cdk-lib";
|
|
7
7
|
import * as iam from "aws-cdk-lib/aws-iam";
|
|
8
8
|
import * as route53 from "aws-cdk-lib/aws-route53";
|
|
9
|
+
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
|
|
10
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
11
|
+
import * as apigateway from "aws-cdk-lib/aws-apigateway";
|
|
12
|
+
import * as path from "path";
|
|
9
13
|
|
|
10
14
|
export interface DomainConfig {
|
|
11
15
|
/** The root domain name (e.g., example.com).
|
|
@@ -38,11 +42,43 @@ export interface WebsiteProps {
|
|
|
38
42
|
|
|
39
43
|
/** Optional path to a custom 404 page. If not specified, the error file will be used. */
|
|
40
44
|
notFoundResponsePagePath?: string;
|
|
45
|
+
|
|
46
|
+
/** Optional configuration for pull request preview environments. */
|
|
47
|
+
previewConfig?: PreviewConfig;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface PreviewConfig {
|
|
51
|
+
/** Prefix used to name preview buckets. Buckets are created as `${prefix}-0`, `${prefix}-1`, ... */
|
|
52
|
+
bucketPrefix: string;
|
|
53
|
+
|
|
54
|
+
/** Number of preview buckets to create.
|
|
55
|
+
* @default 2
|
|
56
|
+
*/
|
|
57
|
+
bucketCount?: number;
|
|
58
|
+
|
|
59
|
+
/** If true, creates one CloudFront distribution per preview bucket.
|
|
60
|
+
* @default true
|
|
61
|
+
*/
|
|
62
|
+
createDistributions?: boolean;
|
|
63
|
+
|
|
64
|
+
/** Maximum lease lifetime in hours before a slot is considered expired.
|
|
65
|
+
* @default 24
|
|
66
|
+
*/
|
|
67
|
+
maxLeaseHours?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface PreviewEnvironmentProps extends PreviewConfig {
|
|
71
|
+
/** Index document for preview buckets. */
|
|
72
|
+
indexFile: string;
|
|
73
|
+
|
|
74
|
+
/** Error document for preview buckets. */
|
|
75
|
+
errorFile: string;
|
|
41
76
|
}
|
|
42
77
|
|
|
43
78
|
export class Website extends Construct {
|
|
44
79
|
public readonly bucket: s3.Bucket;
|
|
45
80
|
public readonly distribution: cloudfont.Distribution;
|
|
81
|
+
public readonly previewEnvironment?: PreviewEnvironment;
|
|
46
82
|
|
|
47
83
|
constructor(scope: Construct, id: string, props: WebsiteProps) {
|
|
48
84
|
super(scope, id);
|
|
@@ -153,6 +189,18 @@ export class Website extends Construct {
|
|
|
153
189
|
description: "Website URL",
|
|
154
190
|
});
|
|
155
191
|
}
|
|
192
|
+
|
|
193
|
+
if (props.previewConfig) {
|
|
194
|
+
this.previewEnvironment = new PreviewEnvironment(
|
|
195
|
+
this,
|
|
196
|
+
"PreviewEnvironment",
|
|
197
|
+
{
|
|
198
|
+
...props.previewConfig,
|
|
199
|
+
indexFile: props.indexFile,
|
|
200
|
+
errorFile: props.errorFile,
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
}
|
|
156
204
|
}
|
|
157
205
|
|
|
158
206
|
private _getFullDomainName(domainConfig: DomainConfig): string {
|
|
@@ -169,3 +217,169 @@ export class Website extends Construct {
|
|
|
169
217
|
);
|
|
170
218
|
}
|
|
171
219
|
}
|
|
220
|
+
|
|
221
|
+
export class PreviewEnvironment extends Construct {
|
|
222
|
+
public readonly buckets: s3.Bucket[];
|
|
223
|
+
public readonly distributions: cloudfont.Distribution[];
|
|
224
|
+
public readonly leaseTable: dynamodb.Table;
|
|
225
|
+
public readonly api: apigateway.RestApi;
|
|
226
|
+
public readonly claimEndpoint: string;
|
|
227
|
+
public readonly heartbeatEndpoint: string;
|
|
228
|
+
public readonly releaseEndpoint: string;
|
|
229
|
+
|
|
230
|
+
constructor(scope: Construct, id: string, props: PreviewEnvironmentProps) {
|
|
231
|
+
super(scope, id);
|
|
232
|
+
|
|
233
|
+
const bucketCount = props.bucketCount ?? 2;
|
|
234
|
+
if (bucketCount < 1) {
|
|
235
|
+
throw new Error("bucketCount must be greater than or equal to 1");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const indexFile = props.indexFile;
|
|
239
|
+
const errorFile = props.errorFile;
|
|
240
|
+
const createDistributions = props.createDistributions ?? true;
|
|
241
|
+
const maxLeaseHours = props.maxLeaseHours ?? 24;
|
|
242
|
+
const maxLeaseMs = cdk.Duration.hours(maxLeaseHours).toMilliseconds();
|
|
243
|
+
|
|
244
|
+
this.buckets = Array.from({ length: bucketCount }, (_, slotId) => {
|
|
245
|
+
const bucketName = `${props.bucketPrefix}-${slotId}`;
|
|
246
|
+
return new s3.Bucket(this, `PreviewBucket${slotId}`, {
|
|
247
|
+
bucketName,
|
|
248
|
+
websiteIndexDocument: indexFile,
|
|
249
|
+
websiteErrorDocument: errorFile,
|
|
250
|
+
publicReadAccess: true,
|
|
251
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
252
|
+
autoDeleteObjects: true,
|
|
253
|
+
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS_ONLY,
|
|
254
|
+
accessControl: s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL,
|
|
255
|
+
encryption: s3.BucketEncryption.S3_MANAGED,
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
this.distributions = createDistributions
|
|
260
|
+
? this.buckets.map((bucket, slotId) => {
|
|
261
|
+
const oai = new cloudfont.OriginAccessIdentity(
|
|
262
|
+
this,
|
|
263
|
+
`PreviewOAI${slotId}`,
|
|
264
|
+
);
|
|
265
|
+
bucket.addToResourcePolicy(
|
|
266
|
+
new iam.PolicyStatement({
|
|
267
|
+
actions: ["s3:GetObject"],
|
|
268
|
+
resources: [bucket.arnForObjects("*")],
|
|
269
|
+
principals: [
|
|
270
|
+
new iam.CanonicalUserPrincipal(
|
|
271
|
+
oai.cloudFrontOriginAccessIdentityS3CanonicalUserId,
|
|
272
|
+
),
|
|
273
|
+
],
|
|
274
|
+
}),
|
|
275
|
+
);
|
|
276
|
+
return new cloudfont.Distribution(
|
|
277
|
+
this,
|
|
278
|
+
`PreviewDistribution${slotId}`,
|
|
279
|
+
{
|
|
280
|
+
defaultBehavior: {
|
|
281
|
+
origin: new origins.S3StaticWebsiteOrigin(bucket),
|
|
282
|
+
viewerProtocolPolicy:
|
|
283
|
+
cloudfont.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
284
|
+
},
|
|
285
|
+
priceClass: cloudfont.PriceClass.PRICE_CLASS_100,
|
|
286
|
+
},
|
|
287
|
+
);
|
|
288
|
+
})
|
|
289
|
+
: [];
|
|
290
|
+
|
|
291
|
+
this.leaseTable = new dynamodb.Table(this, "PreviewLeases", {
|
|
292
|
+
partitionKey: {
|
|
293
|
+
name: "slotId",
|
|
294
|
+
type: dynamodb.AttributeType.STRING,
|
|
295
|
+
},
|
|
296
|
+
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
|
|
297
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
298
|
+
timeToLiveAttribute: "ttlEpochSeconds",
|
|
299
|
+
});
|
|
300
|
+
this.leaseTable.addGlobalSecondaryIndex({
|
|
301
|
+
indexName: "RepoPrKeyIndex",
|
|
302
|
+
partitionKey: {
|
|
303
|
+
name: "repoPrKey",
|
|
304
|
+
type: dynamodb.AttributeType.STRING,
|
|
305
|
+
},
|
|
306
|
+
projectionType: dynamodb.ProjectionType.ALL,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const slotDefinitions = this.buckets.map((bucket, slotId) => ({
|
|
310
|
+
slotId,
|
|
311
|
+
bucketName: bucket.bucketName,
|
|
312
|
+
previewUrl: this.distributions[slotId]
|
|
313
|
+
? `https://${this.distributions[slotId].distributionDomainName}`
|
|
314
|
+
: bucket.bucketWebsiteUrl,
|
|
315
|
+
}));
|
|
316
|
+
|
|
317
|
+
const leaseApiHandler = new lambda.Function(
|
|
318
|
+
this,
|
|
319
|
+
"PreviewLeaseApiHandler",
|
|
320
|
+
{
|
|
321
|
+
runtime: lambda.Runtime.NODEJS_20_X,
|
|
322
|
+
handler: "index.handler",
|
|
323
|
+
timeout: cdk.Duration.seconds(15),
|
|
324
|
+
code: lambda.Code.fromAsset(path.join(__dirname, "..", "lambda")),
|
|
325
|
+
environment: {
|
|
326
|
+
TABLE_NAME: this.leaseTable.tableName,
|
|
327
|
+
SLOT_DEFINITIONS: JSON.stringify(slotDefinitions),
|
|
328
|
+
MAX_LEASE_MS: String(maxLeaseMs),
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
this.leaseTable.grantReadWriteData(leaseApiHandler);
|
|
334
|
+
|
|
335
|
+
this.api = new apigateway.RestApi(this, "PreviewLeaseApi", {
|
|
336
|
+
restApiName: `${cdk.Names.uniqueId(this)}-preview-lease-api`,
|
|
337
|
+
description: "API for claiming/releasing preview slots",
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
const claimResource = this.api.root.addResource("claim");
|
|
341
|
+
claimResource.addMethod(
|
|
342
|
+
"POST",
|
|
343
|
+
new apigateway.LambdaIntegration(leaseApiHandler),
|
|
344
|
+
);
|
|
345
|
+
const heartbeatResource = this.api.root.addResource("heartbeat");
|
|
346
|
+
heartbeatResource.addMethod(
|
|
347
|
+
"POST",
|
|
348
|
+
new apigateway.LambdaIntegration(leaseApiHandler),
|
|
349
|
+
);
|
|
350
|
+
const releaseResource = this.api.root.addResource("release");
|
|
351
|
+
releaseResource.addMethod(
|
|
352
|
+
"POST",
|
|
353
|
+
new apigateway.LambdaIntegration(leaseApiHandler),
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
this.claimEndpoint = `${this.api.url}claim`;
|
|
357
|
+
this.heartbeatEndpoint = `${this.api.url}heartbeat`;
|
|
358
|
+
this.releaseEndpoint = `${this.api.url}release`;
|
|
359
|
+
|
|
360
|
+
new cdk.CfnOutput(this, "preview-claim-endpoint", {
|
|
361
|
+
value: this.claimEndpoint,
|
|
362
|
+
description: "POST endpoint used to claim a preview slot",
|
|
363
|
+
});
|
|
364
|
+
new cdk.CfnOutput(this, "preview-heartbeat-endpoint", {
|
|
365
|
+
value: this.heartbeatEndpoint,
|
|
366
|
+
description: "POST endpoint used to refresh a preview slot lease",
|
|
367
|
+
});
|
|
368
|
+
new cdk.CfnOutput(this, "preview-release-endpoint", {
|
|
369
|
+
value: this.releaseEndpoint,
|
|
370
|
+
description: "POST endpoint used to release a preview slot",
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
public grantDeploymentAccess(grantee: iam.IGrantable): void {
|
|
375
|
+
this.buckets.forEach((bucket) => bucket.grantReadWrite(grantee));
|
|
376
|
+
this.distributions.forEach((distribution) => {
|
|
377
|
+
grantee.grantPrincipal.addToPrincipalPolicy(
|
|
378
|
+
new iam.PolicyStatement({
|
|
379
|
+
actions: ["cloudfront:CreateInvalidation"],
|
|
380
|
+
resources: [distribution.distributionArn],
|
|
381
|
+
}),
|
|
382
|
+
);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitblueprint/website-construct",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "A reusable AWS CDK construct for deploying static websites with optional custom domain support.",
|
|
5
5
|
"author": "Miguel Merlin <mmerlin@stevens.edu>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/jest": "^29.5.14",
|
|
34
34
|
"@types/node": "24.10.1",
|
|
35
|
-
"aws-cdk-lib": "2.
|
|
35
|
+
"aws-cdk-lib": "2.237.1",
|
|
36
36
|
"constructs": "^10.0.0",
|
|
37
37
|
"jest": "^29.7.0",
|
|
38
38
|
"prettier": "^3.6.2",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"typescript": "~5.9.3"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"aws-cdk-lib": "2.
|
|
43
|
+
"aws-cdk-lib": "2.237.1",
|
|
44
44
|
"constructs": "^10.0.0"
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -367,4 +367,130 @@ describe("Website", () => {
|
|
|
367
367
|
});
|
|
368
368
|
});
|
|
369
369
|
});
|
|
370
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic2l0ZS1jb25zdHJ1Y3QudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnNpdGUtY29uc3RydWN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1REFBeUQ7QUFDekQsaURBQW1DO0FBQ25DLGdDQUE2RDtBQUU3RCxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUN2QixJQUFJLEdBQVksQ0FBQztJQUNqQixJQUFJLEtBQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUU7WUFDdEMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO1NBQ3RELENBQUMsQ0FBQztRQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUNuQiwwRUFBMEUsRUFDMUU7WUFDRSxFQUFFLEVBQUUsMkJBQTJCO1lBQy9CLElBQUksRUFBRSxjQUFjO1NBQ3JCLENBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHFCQUFxQixFQUFFLEdBQUcsRUFBRTtRQUNuQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1lBQ3RELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsRUFBRTtnQkFDaEQsb0JBQW9CLEVBQUU7b0JBQ3BCLGFBQWEsRUFBRSxZQUFZO29CQUMzQixhQUFhLEVBQUUsWUFBWTtpQkFDNUI7Z0JBQ0QsZ0JBQWdCLEVBQUU7b0JBQ2hCLGlDQUFpQyxFQUFFO3dCQUNqQzs0QkFDRSw2QkFBNkIsRUFBRTtnQ0FDN0IsWUFBWSxFQUFFLFFBQVE7NkJBQ3ZCO3lCQUNGO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1lBQ3JELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FDNUIsaURBQWlELEVBQ2pEO2dCQUNFLG9DQUFvQyxFQUFFO29CQUNwQyxPQUFPLEVBQUUsa0JBQUssQ0FBQyxRQUFRLEVBQUU7aUJBQzFCO2FBQ0YsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsNERBQTRELEVBQUUsR0FBRyxFQUFFO1lBQ3RFLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLG9CQUFvQixFQUFFO3dCQUNwQixvQkFBb0IsRUFBRSxtQkFBbUI7cUJBQzFDO29CQUNELG9CQUFvQixFQUFFO3dCQUNwQjs0QkFDRSxTQUFTLEVBQUUsR0FBRzs0QkFDZCxZQUFZLEVBQUUsR0FBRzs0QkFDakIsZ0JBQWdCLEVBQUUsV0FBVzs0QkFDN0Isa0JBQWtCLEVBQUUsSUFBSTt5QkFDekI7cUJBQ0Y7b0JBQ0QsVUFBVSxFQUFFLGdCQUFnQjtvQkFDNUIsT0FBTyxFQUFFLElBQUk7aUJBQ2Q7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxHQUFHLEVBQUU7WUFDM0MsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUscUJBQXFCO2dCQUNqQyxTQUFTLEVBQUUsWUFBWTtnQkFDdkIsU0FBUyxFQUFFLFlBQVk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxJQUFJLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1lBQ3BELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2Qix3QkFBd0IsRUFBRSxrQkFBa0I7YUFDN0MsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLCtCQUErQixFQUFFO2dCQUM5RCxrQkFBa0IsRUFBRTtvQkFDbEIsb0JBQW9CLEVBQUU7d0JBQ3BCOzRCQUNFLFNBQVMsRUFBRSxHQUFHOzRCQUNkLFlBQVksRUFBRSxHQUFHOzRCQUNqQixnQkFBZ0IsRUFBRSxrQkFBa0I7NEJBQ3BDLGtCQUFrQixFQUFFLElBQUk7eUJBQ3pCO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUVBQXFFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLG9CQUFvQixFQUFFO3dCQUNwQjs0QkFDRSxTQUFTLEVBQUUsR0FBRzs0QkFDZCxZQUFZLEVBQUUsR0FBRzs0QkFDakIsZ0JBQWdCLEVBQUUsV0FBVzs0QkFDN0Isa0JBQWtCLEVBQUUsSUFBSTt5QkFDekI7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxNQUFNLFlBQVksR0FBaUI7WUFDakMsVUFBVSxFQUFFLGFBQWE7WUFDekIsYUFBYSxFQUFFLEtBQUs7WUFDcEIsY0FBYyxFQUNaLHFGQUFxRjtTQUN4RixDQUFDO1FBRUYsSUFBSSxDQUFDLHVEQUF1RCxFQUFFLEdBQUcsRUFBRTtZQUNqRSxNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxxQkFBcUI7Z0JBQ2pDLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsWUFBWTthQUNiLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDLGlCQUFpQixDQUFDO29CQUM1QixpQkFBaUIsRUFBRTt3QkFDakIsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLGNBQWM7d0JBQzlDLGdCQUFnQixFQUFFLFVBQVU7cUJBQzdCO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMseURBQXlELEVBQUUsR0FBRyxFQUFFO1lBQ25FLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZO2FBQ2IsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlCQUF5QixFQUFFO2dCQUN4RCxJQUFJLEVBQUUsR0FBRztnQkFDVCxJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixXQUFXLEVBQUU7b0JBQ1gsT0FBTyxFQUFFLGtCQUFLLENBQUMsUUFBUSxFQUFFO29CQUN6QixZQUFZLEVBQUUsa0JBQUssQ0FBQyxRQUFRLEVBQUU7aUJBQy9CO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1lBQzVDLE1BQU0sc0JBQXNCLEdBQWlCO2dCQUMzQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFDWixxRkFBcUY7YUFDeEYsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsc0JBQXNCO2FBQ3JDLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDLGFBQWEsQ0FBQztpQkFDekI7YUFDRixDQUFDLENBQUM7WUFFSCxRQUFRLENBQUMscUJBQXFCLENBQUMseUJBQXlCLEVBQUU7Z0JBQ3hELElBQUksRUFBRSxHQUFHO2dCQUNULElBQUksRUFBRSxjQUFjO2FBQ3JCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtHQUFrRyxFQUFFLEdBQUcsRUFBRTtZQUM1RyxNQUFNLGdCQUFnQixHQUFpQjtnQkFDckMsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLGFBQWEsRUFBRSxLQUFLO2dCQUNwQixjQUFjLEVBQ1oscUZBQXFGO2dCQUN2RixpQkFBaUIsRUFBRSxJQUFJO2FBQ3hCLENBQUM7WUFFRixNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxxQkFBcUI7Z0JBQ2pDLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsWUFBWSxFQUFFLGdCQUFnQjthQUMvQixDQUFDO1lBRUYsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUV6QyxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUUzQyxRQUFRLENBQUMscUJBQXFCLENBQUMsK0JBQStCLEVBQUU7Z0JBQzlELGtCQUFrQixFQUFFO29CQUNsQixPQUFPLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxhQUFhLENBQUM7aUJBQzVDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsOERBQThELEVBQUUsR0FBRyxFQUFFO1lBQ3hFLE1BQU0sZ0JBQWdCLEdBQWlCO2dCQUNyQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEtBQUs7Z0JBQ3BCLGNBQWMsRUFDWixxRkFBcUY7Z0JBQ3ZGLGlCQUFpQixFQUFFLElBQUk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsZ0JBQWdCO2FBQy9CLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdkQsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlCQUF5QixFQUFFO2dCQUN4RCxJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixJQUFJLEVBQUUsR0FBRzthQUNWLENBQUMsQ0FBQztZQUVILFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyx5QkFBeUIsRUFBRTtnQkFDeEQsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLElBQUksRUFBRSxHQUFHO2FBQ1YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUVBQXFFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLE1BQU0sc0JBQXNCLEdBQWlCO2dCQUMzQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFDWixxRkFBcUY7Z0JBQ3ZGLGlCQUFpQixFQUFFLElBQUk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsc0JBQXNCO2FBQ3JDLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdkQsUUFBUSxDQUFDLHFCQUFxQixDQUFDLCtCQUErQixFQUFFO2dCQUM5RCxrQkFBa0IsRUFBRTtvQkFDbEIsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDO2lCQUN6QjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1FBQy9CLElBQUksQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7WUFDcEUsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUsYUFBYTtnQkFDekIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixNQUFNLFNBQVMsR0FBRyxJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRTNELDZEQUE2RDtZQUM3RCxNQUFNLGlCQUFpQixHQUFJLFNBQWlCLENBQUMsa0JBQWtCLENBQUM7WUFFaEUsTUFBTSxZQUFZLEdBQWlCO2dCQUNqQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLE1BQU07Z0JBQ3JCLGNBQWMsRUFBRSxVQUFVO2FBQzNCLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFFO1lBQzFFLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTthQUN4QixDQUFDO1lBRUYsTUFBTSxTQUFTLEdBQUcsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUUzRCxNQUFNLGlCQUFpQixHQUFJLFNBQWlCLENBQUMsa0JBQWtCLENBQUM7WUFFaEUsTUFBTSxZQUFZLEdBQWlCO2dCQUNqQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFBRSxVQUFVO2FBQzNCLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtRQUMxQixJQUFJLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1lBQ3pDLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLGdCQUFnQjtnQkFDNUIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNWLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0MsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBRWpCLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0MsUUFBUSxDQUFDLGVBQWUsQ0FBQywrQkFBK0IsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM3RCxRQUFRLENBQUMsZUFBZSxDQUN0QixpREFBaUQsRUFDakQsQ0FBQyxDQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxzRUFBc0UsRUFBRSxHQUFHLEVBQUU7WUFDaEYsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUsYUFBYTtnQkFDekIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVtcGxhdGUsIE1hdGNoIH0gZnJvbSBcImF3cy1jZGstbGliL2Fzc2VydGlvbnNcIjtcbmltcG9ydCAqIGFzIGNkayBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IFdlYnNpdGUsIFdlYnNpdGVQcm9wcywgRG9tYWluQ29uZmlnIH0gZnJvbSBcIi4uL2xpYlwiO1xuXG5kZXNjcmliZShcIldlYnNpdGVcIiwgKCkgPT4ge1xuICBsZXQgYXBwOiBjZGsuQXBwO1xuICBsZXQgc3RhY2s6IGNkay5TdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBuZXcgY2RrLkFwcCgpO1xuICAgIHN0YWNrID0gbmV3IGNkay5TdGFjayhhcHAsIFwiVGVzdFN0YWNrXCIsIHtcbiAgICAgIGVudjogeyBhY2NvdW50OiBcIjEyMzQ1Njc4OTAxMlwiLCByZWdpb246IFwidXMtZWFzdC0xXCIgfSxcbiAgICB9KTtcbiAgICBzdGFjay5ub2RlLnNldENvbnRleHQoXG4gICAgICBcImhvc3RlZC16b25lOmFjY291bnQ9MTIzNDU2Nzg5MDEyOmRvbWFpbk5hbWU9ZXhhbXBsZS5jb206cmVnaW9uPXVzLWVhc3QtMVwiLFxuICAgICAge1xuICAgICAgICBJZDogXCIvaG9zdGVkem9uZS9aMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIE5hbWU6IFwiZXhhbXBsZS5jb20uXCIsXG4gICAgICB9LFxuICAgICk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgZnVuY3Rpb25hbGl0eVwiLCAoKSA9PiB7XG4gICAgdGVzdChcImNyZWF0ZXMgUzMgYnVja2V0IHdpdGggYmFzaWMgY29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgICAgICBXZWJzaXRlQ29uZmlndXJhdGlvbjoge1xuICAgICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICAgIEVycm9yRG9jdW1lbnQ6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICB9LFxuICAgICAgICBCdWNrZXRFbmNyeXB0aW9uOiB7XG4gICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQnlEZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgU1NFQWxnb3JpdGhtOiBcIkFFUzI1NlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyBDbG91ZEZyb250IE9yaWdpbiBBY2Nlc3MgSWRlbnRpdHlcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFxuICAgICAgICBcIkFXUzo6Q2xvdWRGcm9udDo6Q2xvdWRGcm9udE9yaWdpbkFjY2Vzc0lkZW50aXR5XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBDbG91ZEZyb250T3JpZ2luQWNjZXNzSWRlbnRpdHlDb25maWc6IHtcbiAgICAgICAgICAgIENvbW1lbnQ6IE1hdGNoLmFueVZhbHVlKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiB3aXRoIGNvcnJlY3QgY29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIERlZmF1bHRDYWNoZUJlaGF2aW9yOiB7XG4gICAgICAgICAgICBWaWV3ZXJQcm90b2NvbFBvbGljeTogXCJyZWRpcmVjdC10by1odHRwc1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgQ3VzdG9tRXJyb3JSZXNwb25zZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgRXJyb3JDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZVBhZ2VQYXRoOiBcIi80MDQuaHRtbFwiLFxuICAgICAgICAgICAgICBFcnJvckNhY2hpbmdNaW5UVEw6IDE4MDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgUHJpY2VDbGFzczogXCJQcmljZUNsYXNzXzEwMFwiLFxuICAgICAgICAgIEVuYWJsZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJleHBvc2VzIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2Vic2l0ZSA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KHdlYnNpdGUuZGlzdHJpYnV0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkN1c3RvbSBlcnJvciBwYWdlIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJ1c2VzIGN1c3RvbSBub3QgZm91bmQgcmVzcG9uc2UgcGFnZSBwYXRoXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBub3RGb3VuZFJlc3BvbnNlUGFnZVBhdGg6IFwiL2N1c3RvbS00MDQuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgQ3VzdG9tRXJyb3JSZXNwb25zZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgRXJyb3JDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZVBhZ2VQYXRoOiBcIi9jdXN0b20tNDA0Lmh0bWxcIixcbiAgICAgICAgICAgICAgRXJyb3JDYWNoaW5nTWluVFRMOiAxODAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwidXNlcyBkZWZhdWx0IDQwNC5odG1sIHdoZW4gbm90Rm91bmRSZXNwb25zZVBhZ2VQYXRoIGlzIG5vdCBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvNDA0Lmh0bWxcIixcbiAgICAgICAgICAgICAgRXJyb3JDYWNoaW5nTWluVFRMOiAxODAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiRG9tYWluIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgIGNvbnN0IGRvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgc3ViZG9tYWluTmFtZTogXCJ3d3dcIixcbiAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgfTtcblxuICAgIHRlc3QoXCJjb25maWd1cmVzIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIHdpdGggY3VzdG9tIGRvbWFpblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgQWxpYXNlczogW1wid3d3LmV4YW1wbGUuY29tXCJdLFxuICAgICAgICAgIFZpZXdlckNlcnRpZmljYXRlOiB7XG4gICAgICAgICAgICBBY21DZXJ0aWZpY2F0ZUFybjogZG9tYWluQ29uZmlnLmNlcnRpZmljYXRlQXJuLFxuICAgICAgICAgICAgU3NsU3VwcG9ydE1ldGhvZDogXCJzbmktb25seVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJjcmVhdGVzIFJvdXRlNTMgQSByZWNvcmQgd2hlbiBkb21haW4gY29uZmlnIGlzIHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBkb21haW5Db25maWcsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBUeXBlOiBcIkFcIixcbiAgICAgICAgTmFtZTogXCJ3d3cuZXhhbXBsZS5jb20uXCIsXG4gICAgICAgIEFsaWFzVGFyZ2V0OiB7XG4gICAgICAgICAgRE5TTmFtZTogTWF0Y2guYW55VmFsdWUoKSxcbiAgICAgICAgICBIb3N0ZWRab25lSWQ6IE1hdGNoLmFueVZhbHVlKCksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYW5kbGVzIGRvbWFpbiB3aXRob3V0IHN1YmRvbWFpblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBkb21haW5Db25maWdXaXRob3V0U3ViOiBEb21haW5Db25maWcgPSB7XG4gICAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgICAgc3ViZG9tYWluTmFtZTogXCJcIixcbiAgICAgICAgY2VydGlmaWNhdGVBcm46XG4gICAgICAgICAgXCJhcm46YXdzOmFjbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmNlcnRpZmljYXRlLzEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMlwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZG9tYWluQ29uZmlnV2l0aG91dFN1YixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIHtcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICAgIE5hbWU6IFwiZXhhbXBsZS5jb20uXCIsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJjb25maWd1cmVzIENsb3VkRnJvbnQgd2l0aCBib3RoIHN1YmRvbWFpbiBhbmQgcm9vdCBkb21haW4gYWxpYXNlcyB3aGVuIGluY2x1ZGVSb290RG9tYWluIGlzIHRydWVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZHVhbERvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwid3d3XCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgICAgaW5jbHVkZVJvb3REb21haW46IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnOiBkdWFsRG9tYWluQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgQWxpYXNlczogW1wid3d3LmV4YW1wbGUuY29tXCIsIFwiZXhhbXBsZS5jb21cIl0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJjcmVhdGVzIHR3byBSb3V0ZTUzIEEgcmVjb3JkcyB3aGVuIGluY2x1ZGVSb290RG9tYWluIGlzIHRydWVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZHVhbERvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwid3d3XCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgICAgaW5jbHVkZVJvb3REb21haW46IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnOiBkdWFsRG9tYWluQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIDIpO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCB7XG4gICAgICAgIE5hbWU6IFwid3d3LmV4YW1wbGUuY29tLlwiLFxuICAgICAgICBUeXBlOiBcIkFcIixcbiAgICAgIH0pO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCB7XG4gICAgICAgIE5hbWU6IFwiZXhhbXBsZS5jb20uXCIsXG4gICAgICAgIFR5cGU6IFwiQVwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaWdub3JlcyBpbmNsdWRlUm9vdERvbWFpbiBpZiBzdWJkb21haW4gaXMgZW1wdHkgdG8gYXZvaWQgZHVwbGljYXRlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBkb21haW5Db25maWdXaXRob3V0U3ViOiBEb21haW5Db25maWcgPSB7XG4gICAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgICAgc3ViZG9tYWluTmFtZTogXCJcIixcbiAgICAgICAgY2VydGlmaWNhdGVBcm46XG4gICAgICAgICAgXCJhcm46YXdzOmFjbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmNlcnRpZmljYXRlLzEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMlwiLFxuICAgICAgICBpbmNsdWRlUm9vdERvbWFpbjogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBkb21haW5Db25maWc6IGRvbWFpbkNvbmZpZ1dpdGhvdXRTdWIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwgMSk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgQWxpYXNlczogW1wiZXhhbXBsZS5jb21cIl0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQcml2YXRlIG1ldGhvZHNcIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJfZ2V0RnVsbERvbWFpbk5hbWUgcmV0dXJucyBjb3JyZWN0IGRvbWFpbiB3aXRoIHN1YmRvbWFpblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3QtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25zdHJ1Y3QgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIC8vIEFjY2VzcyBwcml2YXRlIG1ldGhvZCB0aHJvdWdoIGJyYWNrZXQgbm90YXRpb24gZm9yIHRlc3RpbmdcbiAgICAgIGNvbnN0IGdldEZ1bGxEb21haW5OYW1lID0gKGNvbnN0cnVjdCBhcyBhbnkpLl9nZXRGdWxsRG9tYWluTmFtZTtcblxuICAgICAgY29uc3QgZG9tYWluQ29uZmlnOiBEb21haW5Db25maWcgPSB7XG4gICAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgICAgc3ViZG9tYWluTmFtZTogXCJibG9nXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOiBcImFybjp0ZXN0XCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBnZXRGdWxsRG9tYWluTmFtZShkb21haW5Db25maWcpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZShcImJsb2cuZXhhbXBsZS5jb21cIik7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiX2dldEZ1bGxEb21haW5OYW1lIHJldHVybnMgcm9vdCBkb21haW4gd2hlbiBzdWJkb21haW4gaXMgZW1wdHlcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uc3RydWN0ID0gbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCBnZXRGdWxsRG9tYWluTmFtZSA9IChjb25zdHJ1Y3QgYXMgYW55KS5fZ2V0RnVsbERvbWFpbk5hbWU7XG5cbiAgICAgIGNvbnN0IGRvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOiBcImFybjp0ZXN0XCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBnZXRGdWxsRG9tYWluTmFtZShkb21haW5Db25maWcpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZShcImV4YW1wbGUuY29tXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkVkZ2UgY2FzZXNcIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJoYW5kbGVzIG1pbmltYWwgY29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcIm1pbmltYWwtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG4gICAgICB9KS5ub3QudG9UaHJvdygpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgMSk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCAxKTtcbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcbiAgICAgICAgXCJBV1M6OkNsb3VkRnJvbnQ6OkNsb3VkRnJvbnRPcmlnaW5BY2Nlc3NJZGVudGl0eVwiLFxuICAgICAgICAxLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJkb2VzIG5vdCBjcmVhdGUgUm91dGU1MyByZXNvdXJjZXMgd2hlbiBkb21haW4gY29uZmlnIGlzIG5vdCBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3QtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIDApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|
|
370
|
+
describe("Preview config on Website", () => {
|
|
371
|
+
let app;
|
|
372
|
+
let stack;
|
|
373
|
+
beforeEach(() => {
|
|
374
|
+
app = new cdk.App();
|
|
375
|
+
stack = new cdk.Stack(app, "PreviewTestStack", {
|
|
376
|
+
env: { account: "123456789012", region: "us-east-1" },
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
test("creates two preview buckets by default when previewConfig is enabled", () => {
|
|
380
|
+
const website = new lib_1.Website(stack, "PreviewEnabledWebsite", {
|
|
381
|
+
bucketName: "website-bucket",
|
|
382
|
+
indexFile: "index.html",
|
|
383
|
+
errorFile: "error.html",
|
|
384
|
+
previewConfig: {
|
|
385
|
+
bucketPrefix: "preview-bucket",
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
389
|
+
template.resourceCountIs("AWS::S3::Bucket", 3);
|
|
390
|
+
expect(website.previewEnvironment).toBeDefined();
|
|
391
|
+
});
|
|
392
|
+
test("creates requested number of preview buckets from previewConfig", () => {
|
|
393
|
+
new lib_1.Website(stack, "PreviewEnabledWebsite", {
|
|
394
|
+
bucketName: "website-bucket",
|
|
395
|
+
indexFile: "index.html",
|
|
396
|
+
errorFile: "error.html",
|
|
397
|
+
previewConfig: {
|
|
398
|
+
bucketPrefix: "preview-bucket",
|
|
399
|
+
bucketCount: 3,
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
403
|
+
template.resourceCountIs("AWS::S3::Bucket", 4);
|
|
404
|
+
});
|
|
405
|
+
test("reuses website index and error files for preview buckets", () => {
|
|
406
|
+
new lib_1.Website(stack, "PreviewEnabledWebsite", {
|
|
407
|
+
bucketName: "website-bucket",
|
|
408
|
+
indexFile: "app.html",
|
|
409
|
+
errorFile: "fallback.html",
|
|
410
|
+
previewConfig: {
|
|
411
|
+
bucketPrefix: "preview-bucket",
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
415
|
+
template.hasResourceProperties("AWS::S3::Bucket", {
|
|
416
|
+
BucketName: "preview-bucket-0",
|
|
417
|
+
WebsiteConfiguration: {
|
|
418
|
+
IndexDocument: "app.html",
|
|
419
|
+
ErrorDocument: "fallback.html",
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
template.hasResourceProperties("AWS::S3::Bucket", {
|
|
423
|
+
BucketName: "preview-bucket-1",
|
|
424
|
+
WebsiteConfiguration: {
|
|
425
|
+
IndexDocument: "app.html",
|
|
426
|
+
ErrorDocument: "fallback.html",
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
test("creates lease table with repo-pr lookup index when preview is enabled", () => {
|
|
431
|
+
new lib_1.Website(stack, "PreviewEnabledWebsite", {
|
|
432
|
+
bucketName: "website-bucket",
|
|
433
|
+
indexFile: "index.html",
|
|
434
|
+
errorFile: "error.html",
|
|
435
|
+
previewConfig: {
|
|
436
|
+
bucketPrefix: "preview-bucket",
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
440
|
+
template.hasResourceProperties("AWS::DynamoDB::Table", {
|
|
441
|
+
KeySchema: [
|
|
442
|
+
{
|
|
443
|
+
AttributeName: "slotId",
|
|
444
|
+
KeyType: "HASH",
|
|
445
|
+
},
|
|
446
|
+
],
|
|
447
|
+
GlobalSecondaryIndexes: [
|
|
448
|
+
{
|
|
449
|
+
IndexName: "RepoPrKeyIndex",
|
|
450
|
+
KeySchema: [
|
|
451
|
+
{
|
|
452
|
+
AttributeName: "repoPrKey",
|
|
453
|
+
KeyType: "HASH",
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
Projection: {
|
|
457
|
+
ProjectionType: "ALL",
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
],
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
test("creates lease API routes when preview is enabled", () => {
|
|
464
|
+
new lib_1.Website(stack, "PreviewEnabledWebsite", {
|
|
465
|
+
bucketName: "website-bucket",
|
|
466
|
+
indexFile: "index.html",
|
|
467
|
+
errorFile: "error.html",
|
|
468
|
+
previewConfig: {
|
|
469
|
+
bucketPrefix: "preview-bucket",
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
473
|
+
template.hasResourceProperties("AWS::ApiGateway::Resource", {
|
|
474
|
+
PathPart: "claim",
|
|
475
|
+
});
|
|
476
|
+
template.hasResourceProperties("AWS::ApiGateway::Resource", {
|
|
477
|
+
PathPart: "heartbeat",
|
|
478
|
+
});
|
|
479
|
+
template.hasResourceProperties("AWS::ApiGateway::Resource", {
|
|
480
|
+
PathPart: "release",
|
|
481
|
+
});
|
|
482
|
+
template.resourceCountIs("AWS::ApiGateway::Method", 3);
|
|
483
|
+
});
|
|
484
|
+
test("does not create preview resources when previewConfig is omitted", () => {
|
|
485
|
+
const website = new lib_1.Website(stack, "WebsiteWithoutPreview", {
|
|
486
|
+
bucketName: "website-bucket",
|
|
487
|
+
indexFile: "index.html",
|
|
488
|
+
errorFile: "error.html",
|
|
489
|
+
});
|
|
490
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
491
|
+
template.resourceCountIs("AWS::DynamoDB::Table", 0);
|
|
492
|
+
template.resourceCountIs("AWS::ApiGateway::RestApi", 0);
|
|
493
|
+
expect(website.previewEnvironment).toBeUndefined();
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic2l0ZS1jb25zdHJ1Y3QudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnNpdGUtY29uc3RydWN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1REFBeUQ7QUFDekQsaURBQW1DO0FBQ25DLGdDQUE2RDtBQUU3RCxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUN2QixJQUFJLEdBQVksQ0FBQztJQUNqQixJQUFJLEtBQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUU7WUFDdEMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO1NBQ3RELENBQUMsQ0FBQztRQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUNuQiwwRUFBMEUsRUFDMUU7WUFDRSxFQUFFLEVBQUUsMkJBQTJCO1lBQy9CLElBQUksRUFBRSxjQUFjO1NBQ3JCLENBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHFCQUFxQixFQUFFLEdBQUcsRUFBRTtRQUNuQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1lBQ3RELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsRUFBRTtnQkFDaEQsb0JBQW9CLEVBQUU7b0JBQ3BCLGFBQWEsRUFBRSxZQUFZO29CQUMzQixhQUFhLEVBQUUsWUFBWTtpQkFDNUI7Z0JBQ0QsZ0JBQWdCLEVBQUU7b0JBQ2hCLGlDQUFpQyxFQUFFO3dCQUNqQzs0QkFDRSw2QkFBNkIsRUFBRTtnQ0FDN0IsWUFBWSxFQUFFLFFBQVE7NkJBQ3ZCO3lCQUNGO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1lBQ3JELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FDNUIsaURBQWlELEVBQ2pEO2dCQUNFLG9DQUFvQyxFQUFFO29CQUNwQyxPQUFPLEVBQUUsa0JBQUssQ0FBQyxRQUFRLEVBQUU7aUJBQzFCO2FBQ0YsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsNERBQTRELEVBQUUsR0FBRyxFQUFFO1lBQ3RFLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLG9CQUFvQixFQUFFO3dCQUNwQixvQkFBb0IsRUFBRSxtQkFBbUI7cUJBQzFDO29CQUNELG9CQUFvQixFQUFFO3dCQUNwQjs0QkFDRSxTQUFTLEVBQUUsR0FBRzs0QkFDZCxZQUFZLEVBQUUsR0FBRzs0QkFDakIsZ0JBQWdCLEVBQUUsV0FBVzs0QkFDN0Isa0JBQWtCLEVBQUUsSUFBSTt5QkFDekI7cUJBQ0Y7b0JBQ0QsVUFBVSxFQUFFLGdCQUFnQjtvQkFDNUIsT0FBTyxFQUFFLElBQUk7aUJBQ2Q7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxHQUFHLEVBQUU7WUFDM0MsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUscUJBQXFCO2dCQUNqQyxTQUFTLEVBQUUsWUFBWTtnQkFDdkIsU0FBUyxFQUFFLFlBQVk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxJQUFJLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1lBQ3BELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2Qix3QkFBd0IsRUFBRSxrQkFBa0I7YUFDN0MsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLCtCQUErQixFQUFFO2dCQUM5RCxrQkFBa0IsRUFBRTtvQkFDbEIsb0JBQW9CLEVBQUU7d0JBQ3BCOzRCQUNFLFNBQVMsRUFBRSxHQUFHOzRCQUNkLFlBQVksRUFBRSxHQUFHOzRCQUNqQixnQkFBZ0IsRUFBRSxrQkFBa0I7NEJBQ3BDLGtCQUFrQixFQUFFLElBQUk7eUJBQ3pCO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUVBQXFFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLG9CQUFvQixFQUFFO3dCQUNwQjs0QkFDRSxTQUFTLEVBQUUsR0FBRzs0QkFDZCxZQUFZLEVBQUUsR0FBRzs0QkFDakIsZ0JBQWdCLEVBQUUsV0FBVzs0QkFDN0Isa0JBQWtCLEVBQUUsSUFBSTt5QkFDekI7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxNQUFNLFlBQVksR0FBaUI7WUFDakMsVUFBVSxFQUFFLGFBQWE7WUFDekIsYUFBYSxFQUFFLEtBQUs7WUFDcEIsY0FBYyxFQUNaLHFGQUFxRjtTQUN4RixDQUFDO1FBRUYsSUFBSSxDQUFDLHVEQUF1RCxFQUFFLEdBQUcsRUFBRTtZQUNqRSxNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxxQkFBcUI7Z0JBQ2pDLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsWUFBWTthQUNiLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDLGlCQUFpQixDQUFDO29CQUM1QixpQkFBaUIsRUFBRTt3QkFDakIsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLGNBQWM7d0JBQzlDLGdCQUFnQixFQUFFLFVBQVU7cUJBQzdCO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMseURBQXlELEVBQUUsR0FBRyxFQUFFO1lBQ25FLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZO2FBQ2IsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlCQUF5QixFQUFFO2dCQUN4RCxJQUFJLEVBQUUsR0FBRztnQkFDVCxJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixXQUFXLEVBQUU7b0JBQ1gsT0FBTyxFQUFFLGtCQUFLLENBQUMsUUFBUSxFQUFFO29CQUN6QixZQUFZLEVBQUUsa0JBQUssQ0FBQyxRQUFRLEVBQUU7aUJBQy9CO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1lBQzVDLE1BQU0sc0JBQXNCLEdBQWlCO2dCQUMzQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFDWixxRkFBcUY7YUFDeEYsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsc0JBQXNCO2FBQ3JDLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDLGFBQWEsQ0FBQztpQkFDekI7YUFDRixDQUFDLENBQUM7WUFFSCxRQUFRLENBQUMscUJBQXFCLENBQUMseUJBQXlCLEVBQUU7Z0JBQ3hELElBQUksRUFBRSxHQUFHO2dCQUNULElBQUksRUFBRSxjQUFjO2FBQ3JCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtHQUFrRyxFQUFFLEdBQUcsRUFBRTtZQUM1RyxNQUFNLGdCQUFnQixHQUFpQjtnQkFDckMsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLGFBQWEsRUFBRSxLQUFLO2dCQUNwQixjQUFjLEVBQ1oscUZBQXFGO2dCQUN2RixpQkFBaUIsRUFBRSxJQUFJO2FBQ3hCLENBQUM7WUFFRixNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxxQkFBcUI7Z0JBQ2pDLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsWUFBWSxFQUFFLGdCQUFnQjthQUMvQixDQUFDO1lBRUYsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUV6QyxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUUzQyxRQUFRLENBQUMscUJBQXFCLENBQUMsK0JBQStCLEVBQUU7Z0JBQzlELGtCQUFrQixFQUFFO29CQUNsQixPQUFPLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxhQUFhLENBQUM7aUJBQzVDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsOERBQThELEVBQUUsR0FBRyxFQUFFO1lBQ3hFLE1BQU0sZ0JBQWdCLEdBQWlCO2dCQUNyQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEtBQUs7Z0JBQ3BCLGNBQWMsRUFDWixxRkFBcUY7Z0JBQ3ZGLGlCQUFpQixFQUFFLElBQUk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsZ0JBQWdCO2FBQy9CLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdkQsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlCQUF5QixFQUFFO2dCQUN4RCxJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixJQUFJLEVBQUUsR0FBRzthQUNWLENBQUMsQ0FBQztZQUVILFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyx5QkFBeUIsRUFBRTtnQkFDeEQsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLElBQUksRUFBRSxHQUFHO2FBQ1YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUVBQXFFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLE1BQU0sc0JBQXNCLEdBQWlCO2dCQUMzQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFDWixxRkFBcUY7Z0JBQ3ZGLGlCQUFpQixFQUFFLElBQUk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsc0JBQXNCO2FBQ3JDLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdkQsUUFBUSxDQUFDLHFCQUFxQixDQUFDLCtCQUErQixFQUFFO2dCQUM5RCxrQkFBa0IsRUFBRTtvQkFDbEIsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDO2lCQUN6QjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1FBQy9CLElBQUksQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7WUFDcEUsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUsYUFBYTtnQkFDekIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixNQUFNLFNBQVMsR0FBRyxJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRTNELDZEQUE2RDtZQUM3RCxNQUFNLGlCQUFpQixHQUFJLFNBQWlCLENBQUMsa0JBQWtCLENBQUM7WUFFaEUsTUFBTSxZQUFZLEdBQWlCO2dCQUNqQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLE1BQU07Z0JBQ3JCLGNBQWMsRUFBRSxVQUFVO2FBQzNCLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFFO1lBQzFFLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTthQUN4QixDQUFDO1lBRUYsTUFBTSxTQUFTLEdBQUcsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUUzRCxNQUFNLGlCQUFpQixHQUFJLFNBQWlCLENBQUMsa0JBQWtCLENBQUM7WUFFaEUsTUFBTSxZQUFZLEdBQWlCO2dCQUNqQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFBRSxVQUFVO2FBQzNCLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtRQUMxQixJQUFJLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1lBQ3pDLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLGdCQUFnQjtnQkFDNUIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNWLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0MsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBRWpCLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0MsUUFBUSxDQUFDLGVBQWUsQ0FBQywrQkFBK0IsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM3RCxRQUFRLENBQUMsZUFBZSxDQUN0QixpREFBaUQsRUFDakQsQ0FBQyxDQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxzRUFBc0UsRUFBRSxHQUFHLEVBQUU7WUFDaEYsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUsYUFBYTtnQkFDekIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtJQUN6QyxJQUFJLEdBQVksQ0FBQztJQUNqQixJQUFJLEtBQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsRUFBRTtZQUM3QyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7U0FDdEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsc0VBQXNFLEVBQUUsR0FBRyxFQUFFO1FBQ2hGLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxRCxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLGFBQWEsRUFBRTtnQkFDYixZQUFZLEVBQUUsZ0JBQWdCO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsUUFBUSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQyxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFFO1FBQzFFLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxQyxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLGFBQWEsRUFBRTtnQkFDYixZQUFZLEVBQUUsZ0JBQWdCO2dCQUM5QixXQUFXLEVBQUUsQ0FBQzthQUNmO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsUUFBUSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7UUFDcEUsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLHVCQUF1QixFQUFFO1lBQzFDLFVBQVUsRUFBRSxnQkFBZ0I7WUFDNUIsU0FBUyxFQUFFLFVBQVU7WUFDckIsU0FBUyxFQUFFLGVBQWU7WUFDMUIsYUFBYSxFQUFFO2dCQUNiLFlBQVksRUFBRSxnQkFBZ0I7YUFDL0I7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxRQUFRLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUU7WUFDaEQsVUFBVSxFQUFFLGtCQUFrQjtZQUM5QixvQkFBb0IsRUFBRTtnQkFDcEIsYUFBYSxFQUFFLFVBQVU7Z0JBQ3pCLGFBQWEsRUFBRSxlQUFlO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLHFCQUFxQixDQUFDLGlCQUFpQixFQUFFO1lBQ2hELFVBQVUsRUFBRSxrQkFBa0I7WUFDOUIsb0JBQW9CLEVBQUU7Z0JBQ3BCLGFBQWEsRUFBRSxVQUFVO2dCQUN6QixhQUFhLEVBQUUsZUFBZTthQUMvQjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHVFQUF1RSxFQUFFLEdBQUcsRUFBRTtRQUNqRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7WUFDMUMsVUFBVSxFQUFFLGdCQUFnQjtZQUM1QixTQUFTLEVBQUUsWUFBWTtZQUN2QixTQUFTLEVBQUUsWUFBWTtZQUN2QixhQUFhLEVBQUU7Z0JBQ2IsWUFBWSxFQUFFLGdCQUFnQjthQUMvQjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxzQkFBc0IsRUFBRTtZQUNyRCxTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsYUFBYSxFQUFFLFFBQVE7b0JBQ3ZCLE9BQU8sRUFBRSxNQUFNO2lCQUNoQjthQUNGO1lBQ0Qsc0JBQXNCLEVBQUU7Z0JBQ3RCO29CQUNFLFNBQVMsRUFBRSxnQkFBZ0I7b0JBQzNCLFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxhQUFhLEVBQUUsV0FBVzs0QkFDMUIsT0FBTyxFQUFFLE1BQU07eUJBQ2hCO3FCQUNGO29CQUNELFVBQVUsRUFBRTt3QkFDVixjQUFjLEVBQUUsS0FBSztxQkFDdEI7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLGtEQUFrRCxFQUFFLEdBQUcsRUFBRTtRQUM1RCxJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7WUFDMUMsVUFBVSxFQUFFLGdCQUFnQjtZQUM1QixTQUFTLEVBQUUsWUFBWTtZQUN2QixTQUFTLEVBQUUsWUFBWTtZQUN2QixhQUFhLEVBQUU7Z0JBQ2IsWUFBWSxFQUFFLGdCQUFnQjthQUMvQjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywyQkFBMkIsRUFBRTtZQUMxRCxRQUFRLEVBQUUsT0FBTztTQUNsQixDQUFDLENBQUM7UUFDSCxRQUFRLENBQUMscUJBQXFCLENBQUMsMkJBQTJCLEVBQUU7WUFDMUQsUUFBUSxFQUFFLFdBQVc7U0FDdEIsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLHFCQUFxQixDQUFDLDJCQUEyQixFQUFFO1lBQzFELFFBQVEsRUFBRSxTQUFTO1NBQ3BCLENBQUMsQ0FBQztRQUNILFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsaUVBQWlFLEVBQUUsR0FBRyxFQUFFO1FBQzNFLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxRCxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1NBQ3hCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsUUFBUSxDQUFDLGVBQWUsQ0FBQywwQkFBMEIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RCxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlbXBsYXRlLCBNYXRjaCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hc3NlcnRpb25zXCI7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBXZWJzaXRlLCBXZWJzaXRlUHJvcHMsIERvbWFpbkNvbmZpZyB9IGZyb20gXCIuLi9saWJcIjtcblxuZGVzY3JpYmUoXCJXZWJzaXRlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGsuU3RhY2s7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gbmV3IGNkay5BcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiLCB7XG4gICAgICBlbnY6IHsgYWNjb3VudDogXCIxMjM0NTY3ODkwMTJcIiwgcmVnaW9uOiBcInVzLWVhc3QtMVwiIH0sXG4gICAgfSk7XG4gICAgc3RhY2subm9kZS5zZXRDb250ZXh0KFxuICAgICAgXCJob3N0ZWQtem9uZTphY2NvdW50PTEyMzQ1Njc4OTAxMjpkb21haW5OYW1lPWV4YW1wbGUuY29tOnJlZ2lvbj11cy1lYXN0LTFcIixcbiAgICAgIHtcbiAgICAgICAgSWQ6IFwiL2hvc3RlZHpvbmUvWjEyMzQ1Njc4OTAxMlwiLFxuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgfSxcbiAgICApO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIGZ1bmN0aW9uYWxpdHlcIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJjcmVhdGVzIFMzIGJ1Y2tldCB3aXRoIGJhc2ljIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0XCIsIHtcbiAgICAgICAgV2Vic2l0ZUNvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBJbmRleERvY3VtZW50OiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgICBFcnJvckRvY3VtZW50OiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgfSxcbiAgICAgICAgQnVja2V0RW5jcnlwdGlvbjoge1xuICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBTZXJ2ZXJTaWRlRW5jcnlwdGlvbkJ5RGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIFNTRUFsZ29yaXRobTogXCJBRVMyNTZcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgQ2xvdWRGcm9udCBPcmlnaW4gQWNjZXNzIElkZW50aXR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcbiAgICAgICAgXCJBV1M6OkNsb3VkRnJvbnQ6OkNsb3VkRnJvbnRPcmlnaW5BY2Nlc3NJZGVudGl0eVwiLFxuICAgICAgICB7XG4gICAgICAgICAgQ2xvdWRGcm9udE9yaWdpbkFjY2Vzc0lkZW50aXR5Q29uZmlnOiB7XG4gICAgICAgICAgICBDb21tZW50OiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gd2l0aCBjb3JyZWN0IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBEZWZhdWx0Q2FjaGVCZWhhdmlvcjoge1xuICAgICAgICAgICAgVmlld2VyUHJvdG9jb2xQb2xpY3k6IFwicmVkaXJlY3QtdG8taHR0cHNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvNDA0Lmh0bWxcIixcbiAgICAgICAgICAgICAgRXJyb3JDYWNoaW5nTWluVFRMOiAxODAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIFByaWNlQ2xhc3M6IFwiUHJpY2VDbGFzc18xMDBcIixcbiAgICAgICAgICBFbmFibGVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZXhwb3NlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdlYnNpdGUgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdCh3ZWJzaXRlLmRpc3RyaWJ1dGlvbikudG9CZURlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDdXN0b20gZXJyb3IgcGFnZSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICB0ZXN0KFwidXNlcyBjdXN0b20gbm90IGZvdW5kIHJlc3BvbnNlIHBhZ2UgcGF0aFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgbm90Rm91bmRSZXNwb25zZVBhZ2VQYXRoOiBcIi9jdXN0b20tNDA0Lmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvY3VzdG9tLTQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcInVzZXMgZGVmYXVsdCA0MDQuaHRtbCB3aGVuIG5vdEZvdW5kUmVzcG9uc2VQYWdlUGF0aCBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBDdXN0b21FcnJvclJlc3BvbnNlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBFcnJvckNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlUGFnZVBhdGg6IFwiLzQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkRvbWFpbiBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgIHN1YmRvbWFpbk5hbWU6IFwid3d3XCIsXG4gICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgXCJhcm46YXdzOmFjbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmNlcnRpZmljYXRlLzEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMlwiLFxuICAgIH07XG5cbiAgICB0ZXN0KFwiY29uZmlndXJlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiB3aXRoIGN1c3RvbSBkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcInd3dy5leGFtcGxlLmNvbVwiXSxcbiAgICAgICAgICBWaWV3ZXJDZXJ0aWZpY2F0ZToge1xuICAgICAgICAgICAgQWNtQ2VydGlmaWNhdGVBcm46IGRvbWFpbkNvbmZpZy5jZXJ0aWZpY2F0ZUFybixcbiAgICAgICAgICAgIFNzbFN1cHBvcnRNZXRob2Q6IFwic25pLW9ubHlcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyBSb3V0ZTUzIEEgcmVjb3JkIHdoZW4gZG9tYWluIGNvbmZpZyBpcyBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIHtcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICAgIE5hbWU6IFwid3d3LmV4YW1wbGUuY29tLlwiLFxuICAgICAgICBBbGlhc1RhcmdldDoge1xuICAgICAgICAgIEROU05hbWU6IE1hdGNoLmFueVZhbHVlKCksXG4gICAgICAgICAgSG9zdGVkWm9uZUlkOiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFuZGxlcyBkb21haW4gd2l0aG91dCBzdWJkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnV2l0aG91dFN1YjogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBkb21haW5Db25maWc6IGRvbWFpbkNvbmZpZ1dpdGhvdXRTdWIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBBbGlhc2VzOiBbXCJleGFtcGxlLmNvbVwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCB7XG4gICAgICAgIFR5cGU6IFwiQVwiLFxuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY29uZmlndXJlcyBDbG91ZEZyb250IHdpdGggYm90aCBzdWJkb21haW4gYW5kIHJvb3QgZG9tYWluIGFsaWFzZXMgd2hlbiBpbmNsdWRlUm9vdERvbWFpbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGR1YWxEb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIGluY2x1ZGVSb290RG9tYWluOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZHVhbERvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcInd3dy5leGFtcGxlLmNvbVwiLCBcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyB0d28gUm91dGU1MyBBIHJlY29yZHMgd2hlbiBpbmNsdWRlUm9vdERvbWFpbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGR1YWxEb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIGluY2x1ZGVSb290RG9tYWluOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZHVhbERvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCAyKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBOYW1lOiBcInd3dy5leGFtcGxlLmNvbS5cIixcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgICBUeXBlOiBcIkFcIixcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImlnbm9yZXMgaW5jbHVkZVJvb3REb21haW4gaWYgc3ViZG9tYWluIGlzIGVtcHR5IHRvIGF2b2lkIGR1cGxpY2F0ZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnV2l0aG91dFN1YjogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgICAgaW5jbHVkZVJvb3REb21haW46IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnOiBkb21haW5Db25maWdXaXRob3V0U3ViLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIDEpO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJpdmF0ZSBtZXRob2RzXCIsICgpID0+IHtcbiAgICB0ZXN0KFwiX2dldEZ1bGxEb21haW5OYW1lIHJldHVybnMgY29ycmVjdCBkb21haW4gd2l0aCBzdWJkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uc3RydWN0ID0gbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICAvLyBBY2Nlc3MgcHJpdmF0ZSBtZXRob2QgdGhyb3VnaCBicmFja2V0IG5vdGF0aW9uIGZvciB0ZXN0aW5nXG4gICAgICBjb25zdCBnZXRGdWxsRG9tYWluTmFtZSA9IChjb25zdHJ1Y3QgYXMgYW55KS5fZ2V0RnVsbERvbWFpbk5hbWU7XG5cbiAgICAgIGNvbnN0IGRvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiYmxvZ1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjogXCJhcm46dGVzdFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0RnVsbERvbWFpbk5hbWUoZG9tYWluQ29uZmlnKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJibG9nLmV4YW1wbGUuY29tXCIpO1xuICAgIH0pO1xuXG4gICAgdGVzdChcIl9nZXRGdWxsRG9tYWluTmFtZSByZXR1cm5zIHJvb3QgZG9tYWluIHdoZW4gc3ViZG9tYWluIGlzIGVtcHR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbnN0cnVjdCA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgZ2V0RnVsbERvbWFpbk5hbWUgPSAoY29uc3RydWN0IGFzIGFueSkuX2dldEZ1bGxEb21haW5OYW1lO1xuXG4gICAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcIlwiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjogXCJhcm46dGVzdFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0RnVsbERvbWFpbk5hbWUoZG9tYWluQ29uZmlnKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJleGFtcGxlLmNvbVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJFZGdlIGNhc2VzXCIsICgpID0+IHtcbiAgICB0ZXN0KFwiaGFuZGxlcyBtaW5pbWFsIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJtaW5pbWFsLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpTMzo6QnVja2V0XCIsIDEpO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwgMSk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXG4gICAgICAgIFwiQVdTOjpDbG91ZEZyb250OjpDbG91ZEZyb250T3JpZ2luQWNjZXNzSWRlbnRpdHlcIixcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZG9lcyBub3QgY3JlYXRlIFJvdXRlNTMgcmVzb3VyY2VzIHdoZW4gZG9tYWluIGNvbmZpZyBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCAwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJQcmV2aWV3IGNvbmZpZyBvbiBXZWJzaXRlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGsuU3RhY2s7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gbmV3IGNkay5BcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCBcIlByZXZpZXdUZXN0U3RhY2tcIiwge1xuICAgICAgZW52OiB7IGFjY291bnQ6IFwiMTIzNDU2Nzg5MDEyXCIsIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIiB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyB0d28gcHJldmlldyBidWNrZXRzIGJ5IGRlZmF1bHQgd2hlbiBwcmV2aWV3Q29uZmlnIGlzIGVuYWJsZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHdlYnNpdGUgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgMyk7XG4gICAgZXhwZWN0KHdlYnNpdGUucHJldmlld0Vudmlyb25tZW50KS50b0JlRGVmaW5lZCgpO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyByZXF1ZXN0ZWQgbnVtYmVyIG9mIHByZXZpZXcgYnVja2V0cyBmcm9tIHByZXZpZXdDb25maWdcIiwgKCkgPT4ge1xuICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlByZXZpZXdFbmFibGVkV2Vic2l0ZVwiLCB7XG4gICAgICBidWNrZXROYW1lOiBcIndlYnNpdGUtYnVja2V0XCIsXG4gICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIHByZXZpZXdDb25maWc6IHtcbiAgICAgICAgYnVja2V0UHJlZml4OiBcInByZXZpZXctYnVja2V0XCIsXG4gICAgICAgIGJ1Y2tldENvdW50OiAzLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgNCk7XG4gIH0pO1xuXG4gIHRlc3QoXCJyZXVzZXMgd2Vic2l0ZSBpbmRleCBhbmQgZXJyb3IgZmlsZXMgZm9yIHByZXZpZXcgYnVja2V0c1wiLCAoKSA9PiB7XG4gICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiUHJldmlld0VuYWJsZWRXZWJzaXRlXCIsIHtcbiAgICAgIGJ1Y2tldE5hbWU6IFwid2Vic2l0ZS1idWNrZXRcIixcbiAgICAgIGluZGV4RmlsZTogXCJhcHAuaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImZhbGxiYWNrLmh0bWxcIixcbiAgICAgIHByZXZpZXdDb25maWc6IHtcbiAgICAgICAgYnVja2V0UHJlZml4OiBcInByZXZpZXctYnVja2V0XCIsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICBCdWNrZXROYW1lOiBcInByZXZpZXctYnVja2V0LTBcIixcbiAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiYXBwLmh0bWxcIixcbiAgICAgICAgRXJyb3JEb2N1bWVudDogXCJmYWxsYmFjay5odG1sXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICBCdWNrZXROYW1lOiBcInByZXZpZXctYnVja2V0LTFcIixcbiAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiYXBwLmh0bWxcIixcbiAgICAgICAgRXJyb3JEb2N1bWVudDogXCJmYWxsYmFjay5odG1sXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyBsZWFzZSB0YWJsZSB3aXRoIHJlcG8tcHIgbG9va3VwIGluZGV4IHdoZW4gcHJldmlldyBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkR5bmFtb0RCOjpUYWJsZVwiLCB7XG4gICAgICBLZXlTY2hlbWE6IFtcbiAgICAgICAge1xuICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2xvdElkXCIsXG4gICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgR2xvYmFsU2Vjb25kYXJ5SW5kZXhlczogW1xuICAgICAgICB7XG4gICAgICAgICAgSW5kZXhOYW1lOiBcIlJlcG9QcktleUluZGV4XCIsXG4gICAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwicmVwb1ByS2V5XCIsXG4gICAgICAgICAgICAgIEtleVR5cGU6IFwiSEFTSFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIFByb2plY3Rpb246IHtcbiAgICAgICAgICAgIFByb2plY3Rpb25UeXBlOiBcIkFMTFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyBsZWFzZSBBUEkgcm91dGVzIHdoZW4gcHJldmlldyBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsIHtcbiAgICAgIFBhdGhQYXJ0OiBcImNsYWltXCIsXG4gICAgfSk7XG4gICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpBcGlHYXRld2F5OjpSZXNvdXJjZVwiLCB7XG4gICAgICBQYXRoUGFydDogXCJoZWFydGJlYXRcIixcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsIHtcbiAgICAgIFBhdGhQYXJ0OiBcInJlbGVhc2VcIixcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkFwaUdhdGV3YXk6Ok1ldGhvZFwiLCAzKTtcbiAgfSk7XG5cbiAgdGVzdChcImRvZXMgbm90IGNyZWF0ZSBwcmV2aWV3IHJlc291cmNlcyB3aGVuIHByZXZpZXdDb25maWcgaXMgb21pdHRlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgd2Vic2l0ZSA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIldlYnNpdGVXaXRob3V0UHJldmlld1wiLCB7XG4gICAgICBidWNrZXROYW1lOiBcIndlYnNpdGUtYnVja2V0XCIsXG4gICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkR5bmFtb0RCOjpUYWJsZVwiLCAwKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc3RBcGlcIiwgMCk7XG4gICAgZXhwZWN0KHdlYnNpdGUucHJldmlld0Vudmlyb25tZW50KS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xufSk7XG4iXX0=
|