@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/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.5",
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.235.0",
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.235.0",
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic2l0ZS1jb25zdHJ1Y3QudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnNpdGUtY29uc3RydWN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1REFBeUQ7QUFDekQsaURBQW1DO0FBQ25DLGdDQUE2RDtBQUU3RCxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUN2QixJQUFJLEdBQVksQ0FBQztJQUNqQixJQUFJLEtBQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUU7WUFDdEMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO1NBQ3RELENBQUMsQ0FBQztRQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUNuQiwwRUFBMEUsRUFDMUU7WUFDRSxFQUFFLEVBQUUsMkJBQTJCO1lBQy9CLElBQUksRUFBRSxjQUFjO1NBQ3JCLENBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHFCQUFxQixFQUFFLEdBQUcsRUFBRTtRQUNuQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1lBQ3RELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxD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QUM7SUFDekQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsaUVBQWlFLEVBQUUsR0FBRyxFQUFFO1FBQzNFLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxRCxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1NBQ3hCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsUUFBUSxDQUFDLGVBQWUsQ0FBQywwQkFBMEIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RCxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlbXBsYXRlLCBNYXRjaCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hc3NlcnRpb25zXCI7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBXZWJzaXRlLCBXZWJzaXRlUHJvcHMsIERvbWFpbkNvbmZpZyB9IGZyb20gXCIuLi9saWJcIjtcblxuZGVzY3JpYmUoXCJXZWJzaXRlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGsuU3RhY2s7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gbmV3IGNkay5BcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiLCB7XG4gICAgICBlbnY6IHsgYWNjb3VudDogXCIxMjM0NTY3ODkwMTJcIiwgcmVnaW9uOiBcInVzLWVhc3QtMVwiIH0sXG4gICAgfSk7XG4gICAgc3RhY2subm9kZS5zZXRDb250ZXh0KFxuICAgICAgXCJob3N0ZWQtem9uZTphY2NvdW50PTEyMzQ1Njc4OTAxMjpkb21haW5OYW1lPWV4YW1wbGUuY29tOnJlZ2lvbj11cy1lYXN0LTFcIixcbiAgICAgIHtcbiAgICAgICAgSWQ6IFwiL2hvc3RlZHpvbmUvWjEyMzQ1Njc4OTAxMlwiLFxuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgfSxcbiAgICApO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIGZ1bmN0aW9uYWxpdHlcIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJjcmVhdGVzIFMzIGJ1Y2tldCB3aXRoIGJhc2ljIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0XCIsIHtcbiAgICAgICAgV2Vic2l0ZUNvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBJbmRleERvY3VtZW50OiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgICBFcnJvckRvY3VtZW50OiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgfSxcbiAgICAgICAgQnVja2V0RW5jcnlwdGlvbjoge1xuICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBTZXJ2ZXJTaWRlRW5jcnlwdGlvbkJ5RGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIFNTRUFsZ29yaXRobTogXCJBRVMyNTZcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgQ2xvdWRGcm9udCBPcmlnaW4gQWNjZXNzIElkZW50aXR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcbiAgICAgICAgXCJBV1M6OkNsb3VkRnJvbnQ6OkNsb3VkRnJvbnRPcmlnaW5BY2Nlc3NJZGVudGl0eVwiLFxuICAgICAgICB7XG4gICAgICAgICAgQ2xvdWRGcm9udE9yaWdpbkFjY2Vzc0lkZW50aXR5Q29uZmlnOiB7XG4gICAgICAgICAgICBDb21tZW50OiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gd2l0aCBjb3JyZWN0IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBEZWZhdWx0Q2FjaGVCZWhhdmlvcjoge1xuICAgICAgICAgICAgVmlld2VyUHJvdG9jb2xQb2xpY3k6IFwicmVkaXJlY3QtdG8taHR0cHNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvNDA0Lmh0bWxcIixcbiAgICAgICAgICAgICAgRXJyb3JDYWNoaW5nTWluVFRMOiAxODAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIFByaWNlQ2xhc3M6IFwiUHJpY2VDbGFzc18xMDBcIixcbiAgICAgICAgICBFbmFibGVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZXhwb3NlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdlYnNpdGUgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdCh3ZWJzaXRlLmRpc3RyaWJ1dGlvbikudG9CZURlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDdXN0b20gZXJyb3IgcGFnZSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICB0ZXN0KFwidXNlcyBjdXN0b20gbm90IGZvdW5kIHJlc3BvbnNlIHBhZ2UgcGF0aFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgbm90Rm91bmRSZXNwb25zZVBhZ2VQYXRoOiBcIi9jdXN0b20tNDA0Lmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvY3VzdG9tLTQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcInVzZXMgZGVmYXVsdCA0MDQuaHRtbCB3aGVuIG5vdEZvdW5kUmVzcG9uc2VQYWdlUGF0aCBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBDdXN0b21FcnJvclJlc3BvbnNlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBFcnJvckNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlUGFnZVBhdGg6IFwiLzQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkRvbWFpbiBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgIHN1YmRvbWFpbk5hbWU6IFwid3d3XCIsXG4gICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgXCJhcm46YXdzOmFjbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmNlcnRpZmljYXRlLzEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMlwiLFxuICAgIH07XG5cbiAgICB0ZXN0KFwiY29uZmlndXJlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiB3aXRoIGN1c3RvbSBkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcInd3dy5leGFtcGxlLmNvbVwiXSxcbiAgICAgICAgICBWaWV3ZXJDZXJ0aWZpY2F0ZToge1xuICAgICAgICAgICAgQWNtQ2VydGlmaWNhdGVBcm46IGRvbWFpbkNvbmZpZy5jZXJ0aWZpY2F0ZUFybixcbiAgICAgICAgICAgIFNzbFN1cHBvcnRNZXRob2Q6IFwic25pLW9ubHlcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyBSb3V0ZTUzIEEgcmVjb3JkIHdoZW4gZG9tYWluIGNvbmZpZyBpcyBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIHtcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICAgIE5hbWU6IFwid3d3LmV4YW1wbGUuY29tLlwiLFxuICAgICAgICBBbGlhc1RhcmdldDoge1xuICAgICAgICAgIEROU05hbWU6IE1hdGNoLmFueVZhbHVlKCksXG4gICAgICAgICAgSG9zdGVkWm9uZUlkOiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFuZGxlcyBkb21haW4gd2l0aG91dCBzdWJkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnV2l0aG91dFN1YjogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBkb21haW5Db25maWc6IGRvbWFpbkNvbmZpZ1dpdGhvdXRTdWIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBBbGlhc2VzOiBbXCJleGFtcGxlLmNvbVwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCB7XG4gICAgICAgIFR5cGU6IFwiQVwiLFxuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY29uZmlndXJlcyBDbG91ZEZyb250IHdpdGggYm90aCBzdWJkb21haW4gYW5kIHJvb3QgZG9tYWluIGFsaWFzZXMgd2hlbiBpbmNsdWRlUm9vdERvbWFpbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGR1YWxEb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIGluY2x1ZGVSb290RG9tYWluOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZHVhbERvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcInd3dy5leGFtcGxlLmNvbVwiLCBcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyB0d28gUm91dGU1MyBBIHJlY29yZHMgd2hlbiBpbmNsdWRlUm9vdERvbWFpbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGR1YWxEb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIGluY2x1ZGVSb290RG9tYWluOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZHVhbERvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCAyKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBOYW1lOiBcInd3dy5leGFtcGxlLmNvbS5cIixcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgICBUeXBlOiBcIkFcIixcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImlnbm9yZXMgaW5jbHVkZVJvb3REb21haW4gaWYgc3ViZG9tYWluIGlzIGVtcHR5IHRvIGF2b2lkIGR1cGxpY2F0ZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnV2l0aG91dFN1YjogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgICAgaW5jbHVkZVJvb3REb21haW46IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnOiBkb21haW5Db25maWdXaXRob3V0U3ViLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIDEpO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJpdmF0ZSBtZXRob2RzXCIsICgpID0+IHtcbiAgICB0ZXN0KFwiX2dldEZ1bGxEb21haW5OYW1lIHJldHVybnMgY29ycmVjdCBkb21haW4gd2l0aCBzdWJkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uc3RydWN0ID0gbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICAvLyBBY2Nlc3MgcHJpdmF0ZSBtZXRob2QgdGhyb3VnaCBicmFja2V0IG5vdGF0aW9uIGZvciB0ZXN0aW5nXG4gICAgICBjb25zdCBnZXRGdWxsRG9tYWluTmFtZSA9IChjb25zdHJ1Y3QgYXMgYW55KS5fZ2V0RnVsbERvbWFpbk5hbWU7XG5cbiAgICAgIGNvbnN0IGRvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiYmxvZ1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjogXCJhcm46dGVzdFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0RnVsbERvbWFpbk5hbWUoZG9tYWluQ29uZmlnKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJibG9nLmV4YW1wbGUuY29tXCIpO1xuICAgIH0pO1xuXG4gICAgdGVzdChcIl9nZXRGdWxsRG9tYWluTmFtZSByZXR1cm5zIHJvb3QgZG9tYWluIHdoZW4gc3ViZG9tYWluIGlzIGVtcHR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbnN0cnVjdCA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgZ2V0RnVsbERvbWFpbk5hbWUgPSAoY29uc3RydWN0IGFzIGFueSkuX2dldEZ1bGxEb21haW5OYW1lO1xuXG4gICAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcIlwiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjogXCJhcm46dGVzdFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0RnVsbERvbWFpbk5hbWUoZG9tYWluQ29uZmlnKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJleGFtcGxlLmNvbVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJFZGdlIGNhc2VzXCIsICgpID0+IHtcbiAgICB0ZXN0KFwiaGFuZGxlcyBtaW5pbWFsIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJtaW5pbWFsLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpTMzo6QnVja2V0XCIsIDEpO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwgMSk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXG4gICAgICAgIFwiQVdTOjpDbG91ZEZyb250OjpDbG91ZEZyb250T3JpZ2luQWNjZXNzSWRlbnRpdHlcIixcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZG9lcyBub3QgY3JlYXRlIFJvdXRlNTMgcmVzb3VyY2VzIHdoZW4gZG9tYWluIGNvbmZpZyBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCAwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJQcmV2aWV3IGNvbmZpZyBvbiBXZWJzaXRlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGsuU3RhY2s7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gbmV3IGNkay5BcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCBcIlByZXZpZXdUZXN0U3RhY2tcIiwge1xuICAgICAgZW52OiB7IGFjY291bnQ6IFwiMTIzNDU2Nzg5MDEyXCIsIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIiB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyB0d28gcHJldmlldyBidWNrZXRzIGJ5IGRlZmF1bHQgd2hlbiBwcmV2aWV3Q29uZmlnIGlzIGVuYWJsZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHdlYnNpdGUgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgMyk7XG4gICAgZXhwZWN0KHdlYnNpdGUucHJldmlld0Vudmlyb25tZW50KS50b0JlRGVmaW5lZCgpO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyByZXF1ZXN0ZWQgbnVtYmVyIG9mIHByZXZpZXcgYnVja2V0cyBmcm9tIHByZXZpZXdDb25maWdcIiwgKCkgPT4ge1xuICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlByZXZpZXdFbmFibGVkV2Vic2l0ZVwiLCB7XG4gICAgICBidWNrZXROYW1lOiBcIndlYnNpdGUtYnVja2V0XCIsXG4gICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIHByZXZpZXdDb25maWc6IHtcbiAgICAgICAgYnVja2V0UHJlZml4OiBcInByZXZpZXctYnVja2V0XCIsXG4gICAgICAgIGJ1Y2tldENvdW50OiAzLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgNCk7XG4gIH0pO1xuXG4gIHRlc3QoXCJyZXVzZXMgd2Vic2l0ZSBpbmRleCBhbmQgZXJyb3IgZmlsZXMgZm9yIHByZXZpZXcgYnVja2V0c1wiLCAoKSA9PiB7XG4gICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiUHJldmlld0VuYWJsZWRXZWJzaXRlXCIsIHtcbiAgICAgIGJ1Y2tldE5hbWU6IFwid2Vic2l0ZS1idWNrZXRcIixcbiAgICAgIGluZGV4RmlsZTogXCJhcHAuaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImZhbGxiYWNrLmh0bWxcIixcbiAgICAgIHByZXZpZXdDb25maWc6IHtcbiAgICAgICAgYnVja2V0UHJlZml4OiBcInByZXZpZXctYnVja2V0XCIsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICBCdWNrZXROYW1lOiBcInByZXZpZXctYnVja2V0LTBcIixcbiAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiYXBwLmh0bWxcIixcbiAgICAgICAgRXJyb3JEb2N1bWVudDogXCJmYWxsYmFjay5odG1sXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICBCdWNrZXROYW1lOiBcInByZXZpZXctYnVja2V0LTFcIixcbiAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiYXBwLmh0bWxcIixcbiAgICAgICAgRXJyb3JEb2N1bWVudDogXCJmYWxsYmFjay5odG1sXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyBsZWFzZSB0YWJsZSB3aXRoIHJlcG8tcHIgbG9va3VwIGluZGV4IHdoZW4gcHJldmlldyBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkR5bmFtb0RCOjpUYWJsZVwiLCB7XG4gICAgICBLZXlTY2hlbWE6IFtcbiAgICAgICAge1xuICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2xvdElkXCIsXG4gICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgR2xvYmFsU2Vjb25kYXJ5SW5kZXhlczogW1xuICAgICAgICB7XG4gICAgICAgICAgSW5kZXhOYW1lOiBcIlJlcG9QcktleUluZGV4XCIsXG4gICAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwicmVwb1ByS2V5XCIsXG4gICAgICAgICAgICAgIEtleVR5cGU6IFwiSEFTSFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIFByb2plY3Rpb246IHtcbiAgICAgICAgICAgIFByb2plY3Rpb25UeXBlOiBcIkFMTFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyBsZWFzZSBBUEkgcm91dGVzIHdoZW4gcHJldmlldyBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsIHtcbiAgICAgIFBhdGhQYXJ0OiBcImNsYWltXCIsXG4gICAgfSk7XG4gICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpBcGlHYXRld2F5OjpSZXNvdXJjZVwiLCB7XG4gICAgICBQYXRoUGFydDogXCJoZWFydGJlYXRcIixcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsIHtcbiAgICAgIFBhdGhQYXJ0OiBcInJlbGVhc2VcIixcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkFwaUdhdGV3YXk6Ok1ldGhvZFwiLCAzKTtcbiAgfSk7XG5cbiAgdGVzdChcImRvZXMgbm90IGNyZWF0ZSBwcmV2aWV3IHJlc291cmNlcyB3aGVuIHByZXZpZXdDb25maWcgaXMgb21pdHRlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgd2Vic2l0ZSA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIldlYnNpdGVXaXRob3V0UHJldmlld1wiLCB7XG4gICAgICBidWNrZXROYW1lOiBcIndlYnNpdGUtYnVja2V0XCIsXG4gICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkR5bmFtb0RCOjpUYWJsZVwiLCAwKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc3RBcGlcIiwgMCk7XG4gICAgZXhwZWN0KHdlYnNpdGUucHJldmlld0Vudmlyb25tZW50KS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xufSk7XG4iXX0=