cdk-nuxt 0.4.1 → 0.4.2
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 +2 -2
- package/lib/stack/nuxt-app-stack.d.ts +17 -24
- package/lib/stack/nuxt-app-stack.js +15 -25
- package/lib/stack/nuxt-app-stack.ts +25 -36
- package/lib/templates/stack-index.ts +10 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ Easily deploy a dynamic universal Nuxt application via CDK on AWS including the
|
|
|
28
28
|
```bash
|
|
29
29
|
yarn add cdk-nuxt --dev # The package itself
|
|
30
30
|
yarn add ts-node typescript --dev # To compile the CDK stacks via typescript
|
|
31
|
-
yarn add aws-cdk@2.
|
|
31
|
+
yarn add aws-cdk@2.15.0 --dev # CDK cli with this exact version for the deployment
|
|
32
32
|
yarn add nuxt-aws-lambda nuxt-start # To make the Nuxt app renderable via AWS Lambda
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -42,7 +42,7 @@ After the installation steps the `package.json` file should look something like
|
|
|
42
42
|
{
|
|
43
43
|
"name": "nuxt-app",
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"aws-cdk": "2.
|
|
45
|
+
"aws-cdk": "2.15.0",
|
|
46
46
|
"cdk-nuxt": "^X.X.X",
|
|
47
47
|
"nuxt": "^X.X.X",
|
|
48
48
|
"ts-node": "^X.X.X",
|
|
@@ -19,11 +19,17 @@ export interface NuxtAppStackProps extends AppStackProps {
|
|
|
19
19
|
*/
|
|
20
20
|
readonly hostedZoneId: string;
|
|
21
21
|
/**
|
|
22
|
-
* The ARN of the certificate to use for the Nuxt app to make it accessible via HTTPS.
|
|
22
|
+
* The ARN of the certificate to use on CloudFront for the Nuxt app to make it accessible via HTTPS.
|
|
23
23
|
* The certificate must be issued for the specified domain in us-east-1 (global) regardless of the
|
|
24
|
-
* region
|
|
24
|
+
* region specified via 'env.region' as CloudFront only works globally.
|
|
25
25
|
*/
|
|
26
26
|
readonly globalTlsCertificateArn: string;
|
|
27
|
+
/**
|
|
28
|
+
* The ARN of the certificate to use at the ApiGateway for the Nuxt app to make it accessible via the custom domain
|
|
29
|
+
* and to provide the custom domain to the Nuxt app on server side rendering.
|
|
30
|
+
* The certificate must be issued in the same region as specified via 'env.region' as ApiGateway works regionally.
|
|
31
|
+
*/
|
|
32
|
+
readonly regionalTlsCertificateArn: string;
|
|
27
33
|
/**
|
|
28
34
|
* The nuxt.config.js of the Nuxt app.
|
|
29
35
|
*/
|
|
@@ -46,12 +52,6 @@ export declare class NuxtAppStack extends Stack {
|
|
|
46
52
|
* @private
|
|
47
53
|
*/
|
|
48
54
|
private readonly deploymentRevision;
|
|
49
|
-
/**
|
|
50
|
-
* The certificate to use for the Nuxt app to make it accessible via HTTPS.
|
|
51
|
-
*
|
|
52
|
-
* @private
|
|
53
|
-
*/
|
|
54
|
-
private readonly tlsCertificate;
|
|
55
55
|
/**
|
|
56
56
|
* The identity to use for accessing the deployment assets on S3.
|
|
57
57
|
*
|
|
@@ -81,7 +81,7 @@ export declare class NuxtAppStack extends Stack {
|
|
|
81
81
|
*/
|
|
82
82
|
private staticAssetConfigs;
|
|
83
83
|
/**
|
|
84
|
-
* The
|
|
84
|
+
* The CloudFront distribution to route incoming requests to the Nuxt lambda function (via the API gateway)
|
|
85
85
|
* or the S3 assets folder (with caching).
|
|
86
86
|
*
|
|
87
87
|
* @private
|
|
@@ -89,14 +89,7 @@ export declare class NuxtAppStack extends Stack {
|
|
|
89
89
|
private readonly cdn;
|
|
90
90
|
constructor(scope: Construct, id: string, props: NuxtAppStackProps);
|
|
91
91
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* @param props
|
|
95
|
-
* @private
|
|
96
|
-
*/
|
|
97
|
-
private findTlsCertificate;
|
|
98
|
-
/**
|
|
99
|
-
* Creates the identity to access our S3 deployment asset files via the cloudfront distribution.
|
|
92
|
+
* Creates the identity to access the S3 deployment asset files via the CloudFront distribution.
|
|
100
93
|
*
|
|
101
94
|
* @private
|
|
102
95
|
*/
|
|
@@ -126,7 +119,7 @@ export declare class NuxtAppStack extends Stack {
|
|
|
126
119
|
*/
|
|
127
120
|
private createApiGateway;
|
|
128
121
|
/**
|
|
129
|
-
* Creates the
|
|
122
|
+
* Creates the CloudFront distribution that routes incoming requests to the Nuxt lambda function (via the API gateway)
|
|
130
123
|
* or the S3 assets folder (with caching).
|
|
131
124
|
*
|
|
132
125
|
* @param props
|
|
@@ -134,21 +127,21 @@ export declare class NuxtAppStack extends Stack {
|
|
|
134
127
|
*/
|
|
135
128
|
private createCloudFrontDistribution;
|
|
136
129
|
/**
|
|
137
|
-
* Creates a behavior for the
|
|
130
|
+
* Creates a behavior for the CloudFront distribution to route incoming requests to the Nuxt render lambda function (via API gateway).
|
|
138
131
|
* Additionally, this automatically redirects HTTP requests to HTTPS.
|
|
139
132
|
*
|
|
140
133
|
* @private
|
|
141
134
|
*/
|
|
142
135
|
private createNuxtAppRouteBehavior;
|
|
143
136
|
/**
|
|
144
|
-
* Creates a cache policy for the Nuxt app route behavior of
|
|
137
|
+
* Creates a cache policy for the Nuxt app route behavior of the CloudFront distribution.
|
|
145
138
|
* Eventhough we don't want to cache SSR requests, we still have to create this cache policy in order to
|
|
146
139
|
* forward required cookies, query params and headers. This doesn't make any sense, because if nothing
|
|
147
140
|
* is cached, one would expect, that anything would/could be forwarded, but anyway...
|
|
148
141
|
*/
|
|
149
142
|
private createSsrCachePolicy;
|
|
150
143
|
/**
|
|
151
|
-
* Creates a behavior for the
|
|
144
|
+
* Creates a behavior for the CloudFront distribution to route matching incoming requests for the static assets
|
|
152
145
|
* to the S3 bucket that holds these static assets.
|
|
153
146
|
*
|
|
154
147
|
* @private
|
|
@@ -162,21 +155,21 @@ export declare class NuxtAppStack extends Stack {
|
|
|
162
155
|
*/
|
|
163
156
|
private configureDeployments;
|
|
164
157
|
/**
|
|
165
|
-
* Resolves the hosted zone at which the DNS records shall be created to access
|
|
158
|
+
* Resolves the hosted zone at which the DNS records shall be created to access the Nuxt app on the internet.
|
|
166
159
|
*
|
|
167
160
|
* @param props
|
|
168
161
|
* @private
|
|
169
162
|
*/
|
|
170
163
|
private findHostedZone;
|
|
171
164
|
/**
|
|
172
|
-
* Creates the DNS records to access
|
|
165
|
+
* Creates the DNS records to access the Nuxt app on the internet via the custom domain.
|
|
173
166
|
*
|
|
174
167
|
* @param props
|
|
175
168
|
* @private
|
|
176
169
|
*/
|
|
177
170
|
private createDnsRecords;
|
|
178
171
|
/**
|
|
179
|
-
* Creates a scheduled rule to ping
|
|
172
|
+
* Creates a scheduled rule to ping the Nuxt app lambda function every 5 minutes in order to keep it warm
|
|
180
173
|
* and speed up initial SSR requests.
|
|
181
174
|
*
|
|
182
175
|
* @private
|
|
@@ -27,7 +27,6 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
27
27
|
this.resourceIdPrefix = `${props.project}-${props.service}-${props.environment}`;
|
|
28
28
|
this.deploymentRevision = new Date().toISOString();
|
|
29
29
|
this.staticAssetConfigs = (0, nuxt_app_static_assets_1.getNuxtAppStaticAssetConfigs)(props.nuxtConfig);
|
|
30
|
-
this.tlsCertificate = this.findTlsCertificate(props);
|
|
31
30
|
this.cdnAccessIdentity = this.createCdnAccessIdentity();
|
|
32
31
|
this.staticAssetsBucket = this.createStaticAssetsBucket();
|
|
33
32
|
this.lambdaFunction = this.createLambdaFunction();
|
|
@@ -38,16 +37,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
38
37
|
this.createPingRule();
|
|
39
38
|
}
|
|
40
39
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* @param props
|
|
44
|
-
* @private
|
|
45
|
-
*/
|
|
46
|
-
findTlsCertificate(props) {
|
|
47
|
-
return aws_certificatemanager_1.Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-tls-certificate`, props.globalTlsCertificateArn);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Creates the identity to access our S3 deployment asset files via the cloudfront distribution.
|
|
40
|
+
* Creates the identity to access the S3 deployment asset files via the CloudFront distribution.
|
|
51
41
|
*
|
|
52
42
|
* @private
|
|
53
43
|
*/
|
|
@@ -119,17 +109,17 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
119
109
|
const apiName = `${this.resourceIdPrefix}-api`;
|
|
120
110
|
const lambdaIntegration = new aws_apigatewayv2_integrations_alpha_1.HttpLambdaIntegration(`${this.resourceIdPrefix}-lambda-integration`, this.lambdaFunction);
|
|
121
111
|
// We want the API gateway to be accessible by the custom domain name.
|
|
122
|
-
// Even though we access the gateway via
|
|
123
|
-
// to be able to redirect the original 'Host' header to
|
|
112
|
+
// Even though we access the gateway via CloudFront (for auto http to https redirects), this is required
|
|
113
|
+
// to be able to redirect the original 'Host' header to the Nuxt application, if requested.
|
|
124
114
|
const domainName = new aws_apigatewayv2_alpha_1.DomainName(this, `${this.resourceIdPrefix}-api-domain`, {
|
|
125
115
|
domainName: props.domain,
|
|
126
|
-
certificate: this.
|
|
116
|
+
certificate: aws_certificatemanager_1.Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-regional-certificate`, props.regionalTlsCertificateArn),
|
|
127
117
|
endpointType: aws_apigatewayv2_alpha_1.EndpointType.REGIONAL,
|
|
128
118
|
securityPolicy: aws_apigatewayv2_alpha_1.SecurityPolicy.TLS_1_2
|
|
129
119
|
});
|
|
130
120
|
const apiGateway = new aws_apigatewayv2_alpha_1.HttpApi(this, apiName, {
|
|
131
121
|
apiName,
|
|
132
|
-
description: `Connects the ${this.resourceIdPrefix}
|
|
122
|
+
description: `Connects the ${this.resourceIdPrefix} CloudFront distribution with the ${this.resourceIdPrefix} lambda function to make it publicly available.`,
|
|
133
123
|
// The app does not allow any cross-origin access by purpose: the app should not be embeddable anywhere
|
|
134
124
|
corsPreflight: undefined,
|
|
135
125
|
defaultIntegration: lambdaIntegration,
|
|
@@ -145,7 +135,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
145
135
|
return apiGateway;
|
|
146
136
|
}
|
|
147
137
|
/**
|
|
148
|
-
* Creates the
|
|
138
|
+
* Creates the CloudFront distribution that routes incoming requests to the Nuxt lambda function (via the API gateway)
|
|
149
139
|
* or the S3 assets folder (with caching).
|
|
150
140
|
*
|
|
151
141
|
* @param props
|
|
@@ -157,14 +147,14 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
157
147
|
domainNames: [props.domain],
|
|
158
148
|
comment: `${this.resourceIdPrefix}-redirect`,
|
|
159
149
|
minimumProtocolVersion: aws_cloudfront_1.SecurityPolicyProtocol.TLS_V1_2_2018,
|
|
160
|
-
certificate: this.
|
|
150
|
+
certificate: aws_certificatemanager_1.Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-global-certificate`, props.globalTlsCertificateArn),
|
|
161
151
|
defaultBehavior: this.createNuxtAppRouteBehavior(),
|
|
162
152
|
additionalBehaviors: this.createStaticAssetsRouteBehavior(),
|
|
163
153
|
priceClass: aws_cloudfront_1.PriceClass.PRICE_CLASS_100, // Use only North America and Europe
|
|
164
154
|
});
|
|
165
155
|
}
|
|
166
156
|
/**
|
|
167
|
-
* Creates a behavior for the
|
|
157
|
+
* Creates a behavior for the CloudFront distribution to route incoming requests to the Nuxt render lambda function (via API gateway).
|
|
168
158
|
* Additionally, this automatically redirects HTTP requests to HTTPS.
|
|
169
159
|
*
|
|
170
160
|
* @private
|
|
@@ -185,13 +175,13 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
185
175
|
};
|
|
186
176
|
}
|
|
187
177
|
/**
|
|
188
|
-
* Creates a cache policy for the Nuxt app route behavior of
|
|
178
|
+
* Creates a cache policy for the Nuxt app route behavior of the CloudFront distribution.
|
|
189
179
|
* Eventhough we don't want to cache SSR requests, we still have to create this cache policy in order to
|
|
190
180
|
* forward required cookies, query params and headers. This doesn't make any sense, because if nothing
|
|
191
181
|
* is cached, one would expect, that anything would/could be forwarded, but anyway...
|
|
192
182
|
*/
|
|
193
183
|
createSsrCachePolicy() {
|
|
194
|
-
// The headers to make accessible in
|
|
184
|
+
// The headers to make accessible in the Nuxt app code.
|
|
195
185
|
// There is no 'CacheHeaderBehavior.all()' option, so we have to explicitly define them.
|
|
196
186
|
const headers = [
|
|
197
187
|
'User-Agent',
|
|
@@ -212,7 +202,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
212
202
|
});
|
|
213
203
|
}
|
|
214
204
|
/**
|
|
215
|
-
* Creates a behavior for the
|
|
205
|
+
* Creates a behavior for the CloudFront distribution to route matching incoming requests for the static assets
|
|
216
206
|
* to the S3 bucket that holds these static assets.
|
|
217
207
|
*
|
|
218
208
|
* @private
|
|
@@ -268,7 +258,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
268
258
|
});
|
|
269
259
|
}
|
|
270
260
|
/**
|
|
271
|
-
* Resolves the hosted zone at which the DNS records shall be created to access
|
|
261
|
+
* Resolves the hosted zone at which the DNS records shall be created to access the Nuxt app on the internet.
|
|
272
262
|
*
|
|
273
263
|
* @param props
|
|
274
264
|
* @private
|
|
@@ -281,7 +271,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
281
271
|
});
|
|
282
272
|
}
|
|
283
273
|
/**
|
|
284
|
-
* Creates the DNS records to access
|
|
274
|
+
* Creates the DNS records to access the Nuxt app on the internet via the custom domain.
|
|
285
275
|
*
|
|
286
276
|
* @param props
|
|
287
277
|
* @private
|
|
@@ -303,7 +293,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
303
293
|
});
|
|
304
294
|
}
|
|
305
295
|
/**
|
|
306
|
-
* Creates a scheduled rule to ping
|
|
296
|
+
* Creates a scheduled rule to ping the Nuxt app lambda function every 5 minutes in order to keep it warm
|
|
307
297
|
* and speed up initial SSR requests.
|
|
308
298
|
*
|
|
309
299
|
* @private
|
|
@@ -319,4 +309,4 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
|
|
|
319
309
|
}
|
|
320
310
|
}
|
|
321
311
|
exports.NuxtAppStack = NuxtAppStack;
|
|
322
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJudXh0LWFwcC1zdGFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBMkQ7QUFFM0QsK0VBQTZFO0FBQzdFLCtEQWdCb0M7QUFDcEMsdURBQTJGO0FBQzNGLCtDQUEyRjtBQUMzRix5REFBbUc7QUFDbkcscUVBQW1HO0FBQ25HLCtFQUF3RTtBQUN4RSx5RUFBaUU7QUFDakUsaUZBQStEO0FBQy9ELG1EQUFtRDtBQUNuRCxzR0FBbUY7QUFDbkYsNEVBQWtHO0FBQ2xHLHFFQUF5RjtBQUV6Rix5QkFBeUI7QUFDekIsdURBQXNEO0FBQ3RELHVFQUE4RDtBQWlDOUQ7O0dBRUc7QUFDSCxNQUFhLFlBQWEsU0FBUSxtQkFBSztJQWlFbkMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUM5RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV4QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pGLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFBLHFEQUE0QixFQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDeEQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxD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LENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUV6RSwyQkFBMkI7UUFDM0IsSUFBSSxxQkFBTyxDQUFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsY0FBYyxFQUFFO1lBQ3RELFVBQVUsRUFBRSxLQUFLLENBQUMsTUFBTTtZQUN4QixJQUFJLEVBQUUsVUFBVTtZQUNoQixNQUFNLEVBQUUsU0FBUztTQUNwQixDQUFDLENBQUM7UUFFSCwyQkFBMkI7UUFDM0IsSUFBSSx3QkFBVSxDQUFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsY0FBYyxFQUFFO1lBQ3pELFVBQVUsRUFBRSxLQUFLLENBQUMsTUFBTTtZQUN4QixJQUFJLEVBQUUsVUFBVTtZQUNoQixNQUFNLEVBQUUsU0FBUztTQUNwQixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxjQUFjO1FBQ2xCLElBQUksaUJBQUksQ0FBQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLGNBQWMsRUFBRTtZQUNuRCxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLFNBQVM7WUFDM0MsV0FBVyxFQUFFLG9DQUFvQyxJQUFJLENBQUMsZ0JBQWdCLHVDQUF1QztZQUM3RyxPQUFPLEVBQUUsSUFBSTtZQUNiLFFBQVEsRUFBRSxxQkFBUSxDQUFDLElBQUksQ0FBQyxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1QyxPQUFPLEVBQUUsQ0FBQyxJQUFJLG1DQUFjLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQ3JELENBQUMsQ0FBQztJQUNQLENBQUM7Q0FDSjtBQXRZRCxvQ0FzWUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0R1cmF0aW9uLCBSZW1vdmFsUG9saWN5LCBTdGFja30gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHtDb25zdHJ1Y3R9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHtDZXJ0aWZpY2F0ZSwgSUNlcnRpZmljYXRlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNlcnRpZmljYXRlbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgICBBbGxvd2VkTWV0aG9kcyxcbiAgICBCZWhhdmlvck9wdGlvbnMsXG4gICAgQ2FjaGVDb29raWVCZWhhdmlvcixcbiAgICBDYWNoZWRNZXRob2RzLFxuICAgIENhY2hlSGVhZGVyQmVoYXZpb3IsXG4gICAgQ2FjaGVQb2xpY3ksXG4gICAgQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLFxuICAgIERpc3RyaWJ1dGlvbixcbiAgICBJQ2FjaGVQb2xpY3ksXG4gICAgSU9yaWdpbkFjY2Vzc0lkZW50aXR5LFxuICAgIE9yaWdpbkFjY2Vzc0lkZW50aXR5LFxuICAgIE9yaWdpblByb3RvY29sUG9saWN5LFxuICAgIFByaWNlQ2xhc3MsXG4gICAgU2VjdXJpdHlQb2xpY3lQcm90b2NvbCxcbiAgICBWaWV3ZXJQcm90b2NvbFBvbGljeVxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnRcIjtcbmltcG9ydCB7QXJjaGl0ZWN0dXJlLCBDb2RlLCBGdW5jdGlvbiwgTGF5ZXJWZXJzaW9uLCBSdW50aW1lfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHtCbG9ja1B1YmxpY0FjY2VzcywgQnVja2V0LCBCdWNrZXRBY2Nlc3NDb250cm9sLCBJQnVja2V0fSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQge0FhYWFSZWNvcmQsIEFSZWNvcmQsIEhvc3RlZFpvbmUsIElIb3N0ZWRab25lLCBSZWNvcmRUYXJnZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1M1wiO1xuaW1wb3J0IHtCdWNrZXREZXBsb3ltZW50LCBDYWNoZUNvbnRyb2wsIFNvdXJjZSwgU3RvcmFnZUNsYXNzfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCB7SHR0cE9yaWdpbiwgUzNPcmlnaW59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udC1vcmlnaW5zXCI7XG5pbXBvcnQge0Nsb3VkRnJvbnRUYXJnZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzXCI7XG5pbXBvcnQge0h0dHBNZXRob2R9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9ucy10YXNrc1wiO1xuaW1wb3J0IHtSZXRlbnRpb25EYXlzfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxvZ3NcIjtcbmltcG9ydCB7SHR0cExhbWJkYUludGVncmF0aW9ufSBmcm9tICdAYXdzLWNkay9hd3MtYXBpZ2F0ZXdheXYyLWludGVncmF0aW9ucy1hbHBoYSc7XG5pbXBvcnQge0RvbWFpbk5hbWUsIEVuZHBvaW50VHlwZSwgSHR0cEFwaSwgU2VjdXJpdHlQb2xpY3l9IGZyb20gXCJAYXdzLWNkay9hd3MtYXBpZ2F0ZXdheXYyLWFscGhhXCI7XG5pbXBvcnQge2dldE51eHRBcHBTdGF0aWNBc3NldENvbmZpZ3MsIFN0YXRpY0Fzc2V0Q29uZmlnfSBmcm9tIFwiLi9udXh0LWFwcC1zdGF0aWMtYXNzZXRzXCI7XG5pbXBvcnQge0FwcFN0YWNrUHJvcHN9IGZyb20gXCIuL2FwcC1zdGFjay1wcm9wc1wiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQge1J1bGUsIFNjaGVkdWxlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50c1wiO1xuaW1wb3J0IHtMYW1iZGFGdW5jdGlvbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHMtdGFyZ2V0c1wiO1xuaW1wb3J0IHtOdXh0Q29uZmlnfSBmcm9tIFwiLi9udXh0LWNvbmZpZ1wiO1xuXG4vKipcbiAqIERlZmluZXMgdGhlIHByb3BzIHJlcXVpcmVkIGZvciB0aGUge0BzZWUgTnV4dEFwcFN0YWNrfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOdXh0QXBwU3RhY2tQcm9wcyBleHRlbmRzIEFwcFN0YWNrUHJvcHMge1xuICAgIC8qKlxuICAgICAqIFRoZSBkb21haW4gKHdpdGhvdXQgdGhlIHByb3RvY29sKSBhdCB3aGljaCB0aGUgTnV4dCBhcHAgc2hhbGwgYmUgcHVibGljbHkgYXZhaWxhYmxlLlxuICAgICAqIEEgRE5TIHJlY29yZCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY3JlYXRlZCBpbiBSb3V0ZTUzIGZvciB0aGUgZG9tYWluLlxuICAgICAqIFRoaXMgYWxzbyBzdXBwb3J0cyBzdWJkb21haW5zLlxuICAgICAqIEV4YW1wbGVzOiBcImV4YW1wbGUuY29tXCIsIFwic3ViLmV4YW1wbGUuY29tXCJcbiAgICAgKi9cbiAgICByZWFkb25seSBkb21haW46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBpZCBvZiB0aGUgaG9zdGVkIHpvbmUgdG8gY3JlYXRlIGEgRE5TIHJlY29yZCBmb3IgdGhlIHNwZWNpZmllZCBkb21haW4uXG4gICAgICovXG4gICAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIHRoZSBjZXJ0aWZpY2F0ZSB0byB1c2UgZm9yIHRoZSBOdXh0IGFwcCB0byBtYWtlIGl0IGFjY2Vzc2libGUgdmlhIEhUVFBTLlxuICAgICAqIFRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGlzc3VlZCBmb3IgdGhlIHNwZWNpZmllZCBkb21haW4gaW4gdXMtZWFzdC0xIChnbG9iYWwpIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gICAgICogcmVnaW9uIHVzZWQgZm9yIHRoZSBOdXh0IGFwcCBpdHNlbGYuXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ2xvYmFsVGxzQ2VydGlmaWNhdGVBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBudXh0LmNvbmZpZy5qcyBvZiB0aGUgTnV4dCBhcHAuXG4gICAgICovXG4gICAgcmVhZG9ubHkgbnV4dENvbmZpZzogTnV4dENvbmZpZztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGFtYmRhIGZ1bmN0aW9uIHRoYXQgcmVuZGVycyB0aGUgTnV4dCBhcHAgYW5kIGlzIHB1YmxpY2x5IHJlYWNoYWJsZSB2aWEgYSBzcGVjaWZpZWQgZG9tYWluLlxuICovXG5leHBvcnQgY2xhc3MgTnV4dEFwcFN0YWNrIGV4dGVuZHMgU3RhY2sge1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkZW50aWZpZXIgcHJlZml4IG9mIHRoZSByZXNvdXJjZXMgY3JlYXRlZCBieSB0aGUgc3RhY2suXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VJZFByZWZpeDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRlcGxveW1lbnQgdGhhdCBpcyB1c2VkIGFzIFMzIGZvbGRlciBuYW1lXG4gICAgICogdG8gc3RvcmUgdGhlIHN0YXRpYyBhc3NldHMgb2YgdGhlIE51eHQgYXBwLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlcGxveW1lbnRSZXZpc2lvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNlcnRpZmljYXRlIHRvIHVzZSBmb3IgdGhlIE51eHQgYXBwIHRvIG1ha2UgaXQgYWNjZXNzaWJsZSB2aWEgSFRUUFMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgdGxzQ2VydGlmaWNhdGU6IElDZXJ0aWZpY2F0ZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpZGVudGl0eSB0byB1c2UgZm9yIGFjY2Vzc2luZyB0aGUgZGVwbG95bWVudCBhc3NldHMgb24gUzMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RuQWNjZXNzSWRlbnRpdHk6IElPcmlnaW5BY2Nlc3NJZGVudGl0eTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBTMyBidWNrZXQgd2hlcmUgdGhlIGRlcGxveW1lbnQgYXNzZXRzIGdldHMgc3RvcmVkLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWNBc3NldHNCdWNrZXQ6IElCdWNrZXQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGFtYmRhIGZ1bmN0aW9uIHRvIHJlbmRlciB0aGUgTnV4dCBhcHAgb24gdGhlIHNlcnZlciBzaWRlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGxhbWJkYUZ1bmN0aW9uOiBGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUEkgZ2F0ZXdheSB0byBtYWtlIHRoZSBsYW1iZGEgZnVuY3Rpb24gdG8gcmVuZGVyIHRoZSBOdXh0IGFwcCBwdWJsaWNseSBhdmFpbGFibGUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgYXBpR2F0ZXdheTogSHR0cEFwaTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb25maWdzIGZvciB0aGUgc3RhdGljIGFzc2V0cyBvZiB0aGUgTnV4dCBhcHAgdGhhdCBzaGFsbCBiZSBwdWJsaWNseSBhdmFpbGFibGUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgc3RhdGljQXNzZXRDb25maWdzOiBTdGF0aWNBc3NldENvbmZpZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIHRvIHJvdXRlIGluY29taW5nIHJlcXVlc3RzIHRvIHRoZSBOdXh0IGxhbWJkYSBmdW5jdGlvbiAodmlhIHRoZSBBUEkgZ2F0ZXdheSlcbiAgICAgKiBvciB0aGUgUzMgYXNzZXRzIGZvbGRlciAod2l0aCBjYWNoaW5nKS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZG46IERpc3RyaWJ1dGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgICAgICB0aGlzLnJlc291cmNlSWRQcmVmaXggPSBgJHtwcm9wcy5wcm9qZWN0fS0ke3Byb3BzLnNlcnZpY2V9LSR7cHJvcHMuZW52aXJvbm1lbnR9YDtcbiAgICAgICAgdGhpcy5kZXBsb3ltZW50UmV2aXNpb24gPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIHRoaXMuc3RhdGljQXNzZXRDb25maWdzID0gZ2V0TnV4dEFwcFN0YXRpY0Fzc2V0Q29uZmlncyhwcm9wcy5udXh0Q29uZmlnKTtcbiAgICAgICAgdGhpcy50bHNDZXJ0aWZpY2F0ZSA9IHRoaXMuZmluZFRsc0NlcnRpZmljYXRlKHByb3BzKTtcbiAgICAgICAgdGhpcy5jZG5BY2Nlc3NJZGVudGl0eSA9IHRoaXMuY3JlYXRlQ2RuQWNjZXNzSWRlbnRpdHkoKTtcbiAgICAgICAgdGhpcy5zdGF0aWNBc3NldHNCdWNrZXQgPSB0aGlzLmNyZWF0ZVN0YXRpY0Fzc2V0c0J1Y2tldCgpO1xuICAgICAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uID0gdGhpcy5jcmVhdGVMYW1iZGFGdW5jdGlvbigpO1xuICAgICAgICB0aGlzLmFwaUdhdGV3YXkgPSB0aGlzLmNyZWF0ZUFwaUdhdGV3YXkocHJvcHMpO1xuICAgICAgICB0aGlzLmNkbiA9IHRoaXMuY3JlYXRlQ2xvdWRGcm9udERpc3RyaWJ1dGlvbihwcm9wcyk7XG4gICAgICAgIHRoaXMuY29uZmlndXJlRGVwbG95bWVudHMoKTtcbiAgICAgICAgdGhpcy5jcmVhdGVEbnNSZWNvcmRzKHByb3BzKTtcbiAgICAgICAgdGhpcy5jcmVhdGVQaW5nUnVsZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBjZXJ0aWZpY2F0ZSB0byB1c2UgZm9yIHByb3ZpZGluZyBIVFRQUyByZXF1ZXN0cyB0byBvdXIgTnV4dCBhcHAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcHJvcHNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgZmluZFRsc0NlcnRpZmljYXRlKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IElDZXJ0aWZpY2F0ZSB7XG4gICAgICAgIHJldHVybiBDZXJ0aWZpY2F0ZS5mcm9tQ2VydGlmaWNhdGVBcm4odGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS10bHMtY2VydGlmaWNhdGVgLCBwcm9wcy5nbG9iYWxUbHNDZXJ0aWZpY2F0ZUFybik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgaWRlbnRpdHkgdG8gYWNjZXNzIG91ciBTMyBkZXBsb3ltZW50IGFzc2V0IGZpbGVzIHZpYSB0aGUgY2xvdWRmcm9udCBkaXN0cmlidXRpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlQ2RuQWNjZXNzSWRlbnRpdHkoKTogSU9yaWdpbkFjY2Vzc0lkZW50aXR5IHtcbiAgICAgICAgY29uc3Qgb3JpZ2luQWNjZXNzSWRlbnRpdHlOYW1lID0gYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1jZG4tczMtYWNjZXNzYDtcbiAgICAgICAgcmV0dXJuIG5ldyBPcmlnaW5BY2Nlc3NJZGVudGl0eSh0aGlzLCBvcmlnaW5BY2Nlc3NJZGVudGl0eU5hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIGJ1Y2tldCB0byBzdG9yZSB0aGUgc3RhdGljIGRlcGxveW1lbnQgYXNzZXQgZmlsZXMgb2YgdGhlIE51eHQgYXBwLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZVN0YXRpY0Fzc2V0c0J1Y2tldCgpOiBJQnVja2V0IHtcbiAgICAgICAgY29uc3QgYnVja2V0TmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tYXNzZXRzYDtcbiAgICAgICAgY29uc3QgYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCBidWNrZXROYW1lLCB7XG4gICAgICAgICAgICBhY2Nlc3NDb250cm9sOiBCdWNrZXRBY2Nlc3NDb250cm9sLkFVVEhFTlRJQ0FURURfUkVBRCxcbiAgICAgICAgICAgIGJsb2NrUHVibGljQWNjZXNzOiBCbG9ja1B1YmxpY0FjY2Vzcy5CTE9DS19BTEwsXG4gICAgICAgICAgICBidWNrZXROYW1lLFxuICAgICAgICAgICAgLy8gVGhlIGJ1Y2tldCBhbmQgYWxsIG9mIGl0cyBvYmplY3RzIGNhbiBiZSBkZWxldGVkLCBiZWNhdXNlIGFsbCB0aGUgY29udGVudCBpcyBtYW5hZ2VkIGluIHRoaXMgcHJvamVjdFxuICAgICAgICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJ1Y2tldC5ncmFudFJlYWRXcml0ZSh0aGlzLmNkbkFjY2Vzc0lkZW50aXR5KTtcblxuICAgICAgICByZXR1cm4gYnVja2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBsYW1iZGEgbGF5ZXIgd2l0aCB0aGUgbm9kZV9tb2R1bGVzIHJlcXVpcmVkIHRvIHJlbmRlciB0aGUgTnV4dCBhcHAgb24gdGhlIHNlcnZlciBzaWRlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZVNzckxhbWJkYUxheWVyKCk6IExheWVyVmVyc2lvbiB7XG4gICAgICAgIGNvbnN0IGxheWVyTmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tc3NyLWxheWVyYDtcbiAgICAgICAgcmV0dXJuIG5ldyBMYXllclZlcnNpb24odGhpcywgbGF5ZXJOYW1lLCB7XG4gICAgICAgICAgICBsYXllclZlcnNpb25OYW1lOiBsYXllck5hbWUsXG4gICAgICAgICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldCgnLm51eHQvY2RrLWRlcGxveW1lbnQvbGF5ZXInKSxcbiAgICAgICAgICAgIGNvbXBhdGlibGVSdW50aW1lczogW1J1bnRpbWUuTk9ERUpTXzEyX1hdLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBQcm92aWRlcyB0aGUgbm9kZV9tb2R1bGVzIHJlcXVpcmVkIGZvciBTU1Igb2YgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LmAsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIGxhbWJkYSBmdW5jdGlvbiB0byByZW5kZXIgdGhlIE51eHQgYXBwLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZUxhbWJkYUZ1bmN0aW9uKCk6IEZ1bmN0aW9uIHtcbiAgICAgICAgY29uc3QgZnVuY05hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWZ1bmN0aW9uYDtcblxuICAgICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKHRoaXMsIGZ1bmNOYW1lLCB7XG4gICAgICAgICAgICBmdW5jdGlvbk5hbWU6IGZ1bmNOYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBSZW5kZXJzIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gTnV4dCBhcHAuYCxcbiAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzEyX1gsXG4gICAgICAgICAgICBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICAgICAgICBsYXllcnM6IFt0aGlzLmNyZWF0ZVNzckxhbWJkYUxheWVyKCldLFxuICAgICAgICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoJy5udXh0L2Nkay1kZXBsb3ltZW50L3NyYycsIHtcbiAgICAgICAgICAgICAgICBleGNsdWRlOiBbJyoqLnN2ZycsICcqKi5pY28nLCAnKioucG5nJywgJyoqLmpwZycsICcqKi5qcy5tYXAnXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGltZW91dDogRHVyYXRpb24uc2Vjb25kcygxMCksXG4gICAgICAgICAgICBtZW1vcnlTaXplOiA1MTIsXG4gICAgICAgICAgICBsb2dSZXRlbnRpb246IFJldGVudGlvbkRheXMuT05FX01PTlRILFxuICAgICAgICAgICAgYWxsb3dQdWJsaWNTdWJuZXQ6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIEFQSSBnYXRld2F5IHRvIG1ha2UgdGhlIE51eHQgYXBwIHJlbmRlciBsYW1iZGEgZnVuY3Rpb24gcHVibGljbHkgYXZhaWxhYmxlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZUFwaUdhdGV3YXkocHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKTogSHR0cEFwaSB7XG4gICAgICAgIGNvbnN0IGFwaU5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWFwaWA7XG4gICAgICAgIGNvbnN0IGxhbWJkYUludGVncmF0aW9uID0gbmV3IEh0dHBMYW1iZGFJbnRlZ3JhdGlvbihgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWxhbWJkYS1pbnRlZ3JhdGlvbmAsIHRoaXMubGFtYmRhRnVuY3Rpb24pO1xuXG4gICAgICAgIC8vIFdlIHdhbnQgdGhlIEFQSSBnYXRld2F5IHRvIGJlIGFjY2Vzc2libGUgYnkgdGhlIGN1c3RvbSBkb21haW4gbmFtZS5cbiAgICAgICAgLy8gRXZlbiB0aG91Z2ggd2UgYWNjZXNzIHRoZSBnYXRld2F5IHZpYSBDbG91ZGZyb250IChmb3IgYXV0byBodHRwIHRvIGh0dHBzIHJlZGlyZWN0cyksIHRoaXMgaXMgcmVxdWlyZWRcbiAgICAgICAgLy8gdG8gYmUgYWJsZSB0byByZWRpcmVjdCB0aGUgb3JpZ2luYWwgJ0hvc3QnIGhlYWRlciB0byBvdXIgTnV4dCBhcHBsaWNhdGlvbiwgaWYgcmVxdWVzdGVkLlxuICAgICAgICBjb25zdCBkb21haW5OYW1lID0gbmV3IERvbWFpbk5hbWUodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1hcGktZG9tYWluYCwge1xuICAgICAgICAgICAgZG9tYWluTmFtZTogcHJvcHMuZG9tYWluLFxuICAgICAgICAgICAgY2VydGlmaWNhdGU6IHRoaXMudGxzQ2VydGlmaWNhdGUsXG4gICAgICAgICAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZS5SRUdJT05BTCxcbiAgICAgICAgICAgIHNlY3VyaXR5UG9saWN5OiBTZWN1cml0eVBvbGljeS5UTFNfMV8yXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFwaUdhdGV3YXkgPSBuZXcgSHR0cEFwaSh0aGlzLCBhcGlOYW1lLCB7XG4gICAgICAgICAgICBhcGlOYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBDb25uZWN0cyB0aGUgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9IGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIHdpdGggdGhlICR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fSBsYW1iZGEgZnVuY3Rpb24gdG8gbWFrZSBpdCBwdWJsaWNseSBhdmFpbGFibGUuYCxcbiAgICAgICAgICAgIC8vIFRoZSBhcHAgZG9lcyBub3QgYWxsb3cgYW55IGNyb3NzLW9yaWdpbiBhY2Nlc3MgYnkgcHVycG9zZTogdGhlIGFwcCBzaG91bGQgbm90IGJlIGVtYmVkZGFibGUgYW55d2hlcmVcbiAgICAgICAgICAgIGNvcnNQcmVmbGlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGRlZmF1bHRJbnRlZ3JhdGlvbjogbGFtYmRhSW50ZWdyYXRpb24sXG4gICAgICAgICAgICBkZWZhdWx0RG9tYWluTWFwcGluZzoge1xuICAgICAgICAgICAgICAgIGRvbWFpbk5hbWU6IGRvbWFpbk5hbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXBpR2F0ZXdheS5hZGRSb3V0ZXMoe1xuICAgICAgICAgICAgaW50ZWdyYXRpb246IGxhbWJkYUludGVncmF0aW9uLFxuICAgICAgICAgICAgcGF0aDogJy97cHJveHkrfScsXG4gICAgICAgICAgICBtZXRob2RzOiBbSHR0cE1ldGhvZC5HRVQsIEh0dHBNZXRob2QuSEVBRF0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBhcGlHYXRld2F5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIHRoYXQgcm91dGVzIGluY29taW5nIHJlcXVlc3RzIHRvIHRoZSBOdXh0IGxhbWJkYSBmdW5jdGlvbiAodmlhIHRoZSBBUEkgZ2F0ZXdheSlcbiAgICAgKiBvciB0aGUgUzMgYXNzZXRzIGZvbGRlciAod2l0aCBjYWNoaW5nKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9wc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVDbG91ZEZyb250RGlzdHJpYnV0aW9uKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IERpc3RyaWJ1dGlvbiB7XG4gICAgICAgIGNvbnN0IGNkbk5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbmA7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBEaXN0cmlidXRpb24odGhpcywgY2RuTmFtZSwge1xuICAgICAgICAgICAgZG9tYWluTmFtZXM6IFtwcm9wcy5kb21haW5dLFxuICAgICAgICAgICAgY29tbWVudDogYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1yZWRpcmVjdGAsXG4gICAgICAgICAgICBtaW5pbXVtUHJvdG9jb2xWZXJzaW9uOiBTZWN1cml0eVBvbGljeVByb3RvY29sLlRMU19WMV8yXzIwMTgsXG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZTogdGhpcy50bHNDZXJ0aWZpY2F0ZSxcbiAgICAgICAgICAgIGRlZmF1bHRCZWhhdmlvcjogdGhpcy5jcmVhdGVOdXh0QXBwUm91dGVCZWhhdmlvcigpLFxuICAgICAgICAgICAgYWRkaXRpb25hbEJlaGF2aW9yczogdGhpcy5jcmVhdGVTdGF0aWNBc3NldHNSb3V0ZUJlaGF2aW9yKCksXG4gICAgICAgICAgICBwcmljZUNsYXNzOiBQcmljZUNsYXNzLlBSSUNFX0NMQVNTXzEwMCwgLy8gVXNlIG9ubHkgTm9ydGggQW1lcmljYSBhbmQgRXVyb3BlXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBiZWhhdmlvciBmb3IgdGhlIGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIHRvIHJvdXRlIGluY29taW5nIHJlcXVlc3RzIHRvIHRoZSBOdXh0IHJlbmRlciBsYW1iZGEgZnVuY3Rpb24gKHZpYSBBUEkgZ2F0ZXdheSkuXG4gICAgICogQWRkaXRpb25hbGx5LCB0aGlzIGF1dG9tYXRpY2FsbHkgcmVkaXJlY3RzIEhUVFAgcmVxdWVzdHMgdG8gSFRUUFMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlTnV4dEFwcFJvdXRlQmVoYXZpb3IoKTogQmVoYXZpb3JPcHRpb25zIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9yaWdpbjogbmV3IEh0dHBPcmlnaW4oYCR7dGhpcy5hcGlHYXRld2F5Lmh0dHBBcGlJZH0uZXhlY3V0ZS1hcGkuJHt0aGlzLnJlZ2lvbn0uYW1hem9uYXdzLmNvbWAsIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uQXR0ZW1wdHM6IDIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvblRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMiksXG4gICAgICAgICAgICAgICAgcmVhZFRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMTApLFxuICAgICAgICAgICAgICAgIHByb3RvY29sUG9saWN5OiBPcmlnaW5Qcm90b2NvbFBvbGljeS5IVFRQU19PTkxZLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfR0VUX0hFQUQsXG4gICAgICAgICAgICBjb21wcmVzczogdHJ1ZSxcbiAgICAgICAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgICAgICAgIG9yaWdpblJlcXVlc3RQb2xpY3k6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGNhY2hlUG9saWN5OiB0aGlzLmNyZWF0ZVNzckNhY2hlUG9saWN5KCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNhY2hlIHBvbGljeSBmb3IgdGhlIE51eHQgYXBwIHJvdXRlIGJlaGF2aW9yIG9mIG91ciBjbG91ZGZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgKiBFdmVudGhvdWdoIHdlIGRvbid0IHdhbnQgdG8gY2FjaGUgU1NSIHJlcXVlc3RzLCB3ZSBzdGlsbCBoYXZlIHRvIGNyZWF0ZSB0aGlzIGNhY2hlIHBvbGljeSBpbiBvcmRlciB0b1xuICAgICAqIGZvcndhcmQgcmVxdWlyZWQgY29va2llcywgcXVlcnkgcGFyYW1zIGFuZCBoZWFkZXJzLiBUaGlzIGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UsIGJlY2F1c2UgaWYgbm90aGluZ1xuICAgICAqIGlzIGNhY2hlZCwgb25lIHdvdWxkIGV4cGVjdCwgdGhhdCBhbnl0aGluZyB3b3VsZC9jb3VsZCBiZSBmb3J3YXJkZWQsIGJ1dCBhbnl3YXkuLi5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZVNzckNhY2hlUG9saWN5KCk6IElDYWNoZVBvbGljeSB7XG5cbiAgICAgICAgLy8gVGhlIGhlYWRlcnMgdG8gbWFrZSBhY2Nlc3NpYmxlIGluIG91ciBOdXh0IGFwcCBjb2RlLlxuICAgICAgICAvLyBUaGVyZSBpcyBubyAnQ2FjaGVIZWFkZXJCZWhhdmlvci5hbGwoKScgb3B0aW9uLCBzbyB3ZSBoYXZlIHRvIGV4cGxpY2l0bHkgZGVmaW5lIHRoZW0uXG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBbXG4gICAgICAgICAgICAnVXNlci1BZ2VudCcsIC8vIFJlcXVpcmVkIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gbW9iaWxlIGFuZCBkZXNrdG9wIHRlbXBsYXRlXG4gICAgICAgICAgICAnQXV0aG9yaXphdGlvbicsIC8vIEZvciBhdXRob3JpemF0aW9uXG4gICAgICAgICAgICAnSG9zdCcgLy8gVG8gYWNjZXNzIHRoZSBkb21haW4gbmFtZSBvbiBTU1IgcmVxdWVzdHNcbiAgICAgICAgXTtcblxuICAgICAgICByZXR1cm4gbmV3IENhY2hlUG9saWN5KHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tY2FjaGUtcG9saWN5YCwge1xuICAgICAgICAgICAgY2FjaGVQb2xpY3lOYW1lOiBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbi1jYWNoZS1wb2xpY3lgLFxuICAgICAgICAgICAgY29tbWVudDogYFBhc3NlcyBhbGwgcmVxdWlyZWQgcmVxdWVzdCBkYXRhIHRvIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gb3JpZ2luLmAsXG4gICAgICAgICAgICBkZWZhdWx0VHRsOiBEdXJhdGlvbi5zZWNvbmRzKDApLFxuICAgICAgICAgICAgbWluVHRsOiBEdXJhdGlvbi5zZWNvbmRzKDApLFxuICAgICAgICAgICAgbWF4VHRsOiBEdXJhdGlvbi5zZWNvbmRzKDEpLCAvLyBUaGUgbWF4IFRUTCBtdXN0IG5vdCBiZSAwIGZvciBhIGNhY2hlIHBvbGljeVxuICAgICAgICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLmFsbCgpLFxuICAgICAgICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KC4uLmhlYWRlcnMpLFxuICAgICAgICAgICAgY29va2llQmVoYXZpb3I6IENhY2hlQ29va2llQmVoYXZpb3IuYWxsKCksXG4gICAgICAgICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0Jyb3RsaTogdHJ1ZSxcbiAgICAgICAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nR3ppcDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGJlaGF2aW9yIGZvciB0aGUgY2xvdWRmcm9udCBkaXN0cmlidXRpb24gdG8gcm91dGUgbWF0Y2hpbmcgaW5jb21pbmcgcmVxdWVzdHMgZm9yIG91ciBzdGF0aWMgYXNzZXRzXG4gICAgICogdG8gdGhlIFMzIGJ1Y2tldCB0aGF0IGhvbGRzIHRoZXNlIHN0YXRpYyBhc3NldHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlU3RhdGljQXNzZXRzUm91dGVCZWhhdmlvcigpOiBSZWNvcmQ8c3RyaW5nLCBCZWhhdmlvck9wdGlvbnM+IHtcbiAgICAgICAgY29uc3Qgc3RhdGljQXNzZXRzQ2FjaGVDb25maWc6IEJlaGF2aW9yT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIG9yaWdpbjogbmV3IFMzT3JpZ2luKHRoaXMuc3RhdGljQXNzZXRzQnVja2V0LCB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbkF0dGVtcHRzOiAyLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25UaW1lb3V0OiBEdXJhdGlvbi5zZWNvbmRzKDMpLFxuICAgICAgICAgICAgICAgIG9yaWdpbkFjY2Vzc0lkZW50aXR5OiB0aGlzLmNkbkFjY2Vzc0lkZW50aXR5LFxuICAgICAgICAgICAgICAgIG9yaWdpblBhdGg6IHRoaXMuZGVwbG95bWVudFJldmlzaW9uLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjb21wcmVzczogdHJ1ZSxcbiAgICAgICAgICAgIGFsbG93ZWRNZXRob2RzOiBBbGxvd2VkTWV0aG9kcy5BTExPV19HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgICAgICAgY2FjaGVkTWV0aG9kczogQ2FjaGVkTWV0aG9kcy5DQUNIRV9HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgICAgICAgY2FjaGVQb2xpY3k6IENhY2hlUG9saWN5LkNBQ0hJTkdfT1BUSU1JWkVELFxuICAgICAgICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IFZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJ1bGVzOiBSZWNvcmQ8c3RyaW5nLCBCZWhhdmlvck9wdGlvbnM+ID0ge307XG4gICAgICAgIHRoaXMuc3RhdGljQXNzZXRDb25maWdzLmZvckVhY2goYXNzZXQgPT4ge1xuICAgICAgICAgICAgcnVsZXNbYCR7YXNzZXQudGFyZ2V0fSR7YXNzZXQucGF0dGVybn1gXSA9IHN0YXRpY0Fzc2V0c0NhY2hlQ29uZmlnXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmV0dXJuIHJ1bGVzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBsb2FkcyB0aGUgc3RhdGljIGFzc2V0cyBvZiB0aGUgTnV4dCBhcHAgYXMgZGVmaW5lZCBpbiB7QHNlZSBnZXROdXh0QXBwU3RhdGljQXNzZXRDb25maWdzfSB0byB0aGUgc3RhdGljIGFzc2V0cyBTMyBidWNrZXQuXG4gICAgICogSW4gb3JkZXIgdG8gZW5hYmxlIGEgemVyby1kb3dudGltZSBkZXBsb3ltZW50LCB3ZSB1c2UgYSBuZXcgc3ViZGlyZWN0b3J5IChyZXZpc2lvbikgZm9yIGV2ZXJ5IGRlcGxveW1lbnQuXG4gICAgICogVGhlIHByZXZpb3VzIHZlcnNpb25zIGFyZSByZXRhaW5lZCB0byBhbGxvdyBjbGllbnRzIHRvIGNvbnRpbnVlIHRvIHdvcmsgd2l0aCBhbiBvbGRlciByZXZpc2lvbiBidXQgZ2V0cyBjbGVhbmVkIHVwXG4gICAgICogYWZ0ZXIgYSBzcGVjaWZpZWQgcGVyaW9kIG9mIHRpbWUgdmlhIHRoZSBsYW1iZGEgZnVuY3Rpb24gaW4gdGhlIHtAc2VlIE51eHRBcHBBc3NldHNDbGVhbnVwU3RhY2t9LlxuICAgICAqL1xuICAgIHByaXZhdGUgY29uZmlndXJlRGVwbG95bWVudHMoKTogQnVja2V0RGVwbG95bWVudFtdIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdENhY2hlQ29uZmlnID0gW1xuICAgICAgICAgICAgQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLFxuICAgICAgICAgICAgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5kYXlzKDM2NSkpLFxuICAgICAgICAgICAgQ2FjaGVDb250cm9sLmZyb21TdHJpbmcoJ2ltbXV0YWJsZScpLFxuICAgICAgICBdO1xuXG4gICAgICAgIC8vIFJldHVybnMgYSBkZXBsb3ltZW50IGZvciBldmVyeSBjb25maWd1cmVkIHN0YXRpYyBhc3NldCB0eXBlIHRvIHJlc3BlY3QgdGhlIGRpZmZlcmVudCBjYWNoZSBzZXR0aW5nc1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0aWNBc3NldENvbmZpZ3MuZmlsdGVyKGFzc2V0ID0+IGZzLmV4aXN0c1N5bmMoYXNzZXQuc291cmNlKSkubWFwKChhc3NldCwgYXNzZXRJbmRleCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tYXNzZXRzLWRlcGxveW1lbnQtJHthc3NldEluZGV4fWAsIHtcbiAgICAgICAgICAgICAgICBzb3VyY2VzOiBbU291cmNlLmFzc2V0KGFzc2V0LnNvdXJjZSldLFxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiB0aGlzLnN0YXRpY0Fzc2V0c0J1Y2tldCxcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbktleVByZWZpeDogdGhpcy5kZXBsb3ltZW50UmV2aXNpb24gKyBhc3NldC50YXJnZXQsXG4gICAgICAgICAgICAgICAgcHJ1bmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHN0b3JhZ2VDbGFzczogU3RvcmFnZUNsYXNzLlNUQU5EQVJELFxuICAgICAgICAgICAgICAgIGV4Y2x1ZGU6IFsnKiddLFxuICAgICAgICAgICAgICAgIGluY2x1ZGU6IFthc3NldC5wYXR0ZXJuXSxcbiAgICAgICAgICAgICAgICBjYWNoZUNvbnRyb2w6IGFzc2V0LmNhY2hlQ29udHJvbCA/PyBkZWZhdWx0Q2FjaGVDb25maWcsXG4gICAgICAgICAgICAgICAgY29udGVudFR5cGU6IGFzc2V0LmNvbnRlbnRUeXBlLFxuICAgICAgICAgICAgICAgIGxvZ1JldGVudGlvbjogUmV0ZW50aW9uRGF5cy5PTkVfREFZLFxuICAgICAgICAgICAgICAgIG1lbW9yeUxpbWl0OiAyNTYgLy8gU29tZSBOdXh0IGFwcGxpY2F0aW9ucyBoYXZlIGEgbG90IG9mIGFzc2V0cyB0byBkZXBsb3kgd2hlcmVieSB0aGUgZnVuY3Rpb24gbWlnaHQgcnVuIG91dCBvZiBtZW1vcnlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSBob3N0ZWQgem9uZSBhdCB3aGljaCB0aGUgRE5TIHJlY29yZHMgc2hhbGwgYmUgY3JlYXRlZCB0byBhY2Nlc3Mgb3VyIE51eHQgYXBwIG9uIHRoZSBpbnRlcm5ldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9wc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBmaW5kSG9zdGVkWm9uZShwcm9wczogTnV4dEFwcFN0YWNrUHJvcHMpOiBJSG9zdGVkWm9uZSB7XG4gICAgICAgIGNvbnN0IGRvbWFpblBhcnRzID0gcHJvcHMuZG9tYWluLnNwbGl0KCcuJyk7XG5cbiAgICAgICAgcmV0dXJuIEhvc3RlZFpvbmUuZnJvbUhvc3RlZFpvbmVBdHRyaWJ1dGVzKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0taG9zdGVkLXpvbmVgLCB7XG4gICAgICAgICAgICBob3N0ZWRab25lSWQ6IHByb3BzLmhvc3RlZFpvbmVJZCxcbiAgICAgICAgICAgIHpvbmVOYW1lOiBkb21haW5QYXJ0c1tkb21haW5QYXJ0cy5sZW5ndGggLSAxXSwgLy8gU3VwcG9ydCBzdWJkb21haW5zXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIEROUyByZWNvcmRzIHRvIGFjY2VzcyBvdXIgTnV4dCBhcHAgb24gdGhlIGludGVybmV0IHZpYSBvdXIgY3VzdG9tIGRvbWFpbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9wc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVEbnNSZWNvcmRzKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IHZvaWQge1xuICAgICAgICBjb25zdCBob3N0ZWRab25lID0gdGhpcy5maW5kSG9zdGVkWm9uZShwcm9wcyk7XG4gICAgICAgIGNvbnN0IGRuc1RhcmdldCA9IFJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IENsb3VkRnJvbnRUYXJnZXQodGhpcy5jZG4pKTtcblxuICAgICAgICAvLyBDcmVhdGUgYSByZWNvcmQgZm9yIElQdjRcbiAgICAgICAgbmV3IEFSZWNvcmQodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1pcHY0LXJlY29yZGAsIHtcbiAgICAgICAgICAgIHJlY29yZE5hbWU6IHByb3BzLmRvbWFpbixcbiAgICAgICAgICAgIHpvbmU6IGhvc3RlZFpvbmUsXG4gICAgICAgICAgICB0YXJnZXQ6IGRuc1RhcmdldCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGEgcmVjb3JkIGZvciBJUHY2XG4gICAgICAgIG5ldyBBYWFhUmVjb3JkKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0taXB2Ni1yZWNvcmRgLCB7XG4gICAgICAgICAgICByZWNvcmROYW1lOiBwcm9wcy5kb21haW4sXG4gICAgICAgICAgICB6b25lOiBob3N0ZWRab25lLFxuICAgICAgICAgICAgdGFyZ2V0OiBkbnNUYXJnZXQsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzY2hlZHVsZWQgcnVsZSB0byBwaW5nIG91ciBOdXh0IGFwcCBsYW1iZGEgZnVuY3Rpb24gZXZlcnkgNSBtaW51dGVzIGluIG9yZGVyIHRvIGtlZXAgaXQgd2FybVxuICAgICAqIGFuZCBzcGVlZCB1cCBpbml0aWFsIFNTUiByZXF1ZXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVQaW5nUnVsZSgpOiB2b2lkIHtcbiAgICAgICAgbmV3IFJ1bGUodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1waW5nZXItcnVsZWAsIHtcbiAgICAgICAgICAgIHJ1bGVOYW1lOiBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LXBpbmdlcmAsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFBpbmdzIHRoZSBsYW1iZGEgZnVuY3Rpb24gb2YgdGhlICR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fSBhcHAgZXZlcnkgNSBtaW51dGVzIHRvIGtlZXAgaXQgd2FybS5gLFxuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgIHNjaGVkdWxlOiBTY2hlZHVsZS5yYXRlKER1cmF0aW9uLm1pbnV0ZXMoNSkpLFxuICAgICAgICAgICAgdGFyZ2V0czogW25ldyBMYW1iZGFGdW5jdGlvbih0aGlzLmxhbWJkYUZ1bmN0aW9uKV0sXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==
|
|
312
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJudXh0LWFwcC1zdGFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBMkQ7QUFFM0QsK0VBQStEO0FBQy9ELCtEQWdCb0M7QUFDcEMsdURBQTJGO0FBQzNGLCtDQUEyRjtBQUMzRix5REFBbUc7QUFDbkcscUVBQW1HO0FBQ25HLCtFQUF3RTtBQUN4RSx5RUFBaUU7QUFDakUsaUZBQStEO0FBQy9ELG1EQUFtRDtBQUNuRCxzR0FBbUY7QUFDbkYsNEVBQWtHO0FBQ2xHLHFFQUF5RjtBQUV6Rix5QkFBeUI7QUFDekIsdURBQXNEO0FBQ3RELHVFQUE4RDtBQXdDOUQ7O0dBRUc7QUFDSCxNQUFhLFlBQWEsU0FBUSxtQkFBSztJQTBEbkMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUM5RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV4QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pGLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFBLHFEQUE0QixFQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDeEQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdC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QUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLGNBQWMsRUFBRTtZQUN0RCxVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU07WUFDeEIsSUFBSSxFQUFFLFVBQVU7WUFDaEIsTUFBTSxFQUFFLFNBQVM7U0FDcEIsQ0FBQyxDQUFDO1FBRUgsMkJBQTJCO1FBQzNCLElBQUksd0JBQVUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLGNBQWMsRUFBRTtZQUN6RCxVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU07WUFDeEIsSUFBSSxFQUFFLFVBQVU7WUFDaEIsTUFBTSxFQUFFLFNBQVM7U0FDcEIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssY0FBYztRQUNsQixJQUFJLGlCQUFJLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixjQUFjLEVBQUU7WUFDbkQsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixTQUFTO1lBQzNDLFdBQVcsRUFBRSxvQ0FBb0MsSUFBSSxDQUFDLGdCQUFnQix1Q0FBdUM7WUFDN0csT0FBTyxFQUFFLElBQUk7WUFDYixRQUFRLEVBQUUscUJBQVEsQ0FBQyxJQUFJLENBQUMsc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUMsT0FBTyxFQUFFLENBQUMsSUFBSSxtQ0FBYyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztTQUNyRCxDQUFDLENBQUM7SUFDUCxDQUFDO0NBQ0o7QUFwWEQsb0NBb1hDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEdXJhdGlvbiwgUmVtb3ZhbFBvbGljeSwgU3RhY2t9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7Q29uc3RydWN0fSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7Q2VydGlmaWNhdGV9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQge1xuICAgIEFsbG93ZWRNZXRob2RzLFxuICAgIEJlaGF2aW9yT3B0aW9ucyxcbiAgICBDYWNoZUNvb2tpZUJlaGF2aW9yLFxuICAgIENhY2hlZE1ldGhvZHMsXG4gICAgQ2FjaGVIZWFkZXJCZWhhdmlvcixcbiAgICBDYWNoZVBvbGljeSxcbiAgICBDYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IsXG4gICAgRGlzdHJpYnV0aW9uLFxuICAgIElDYWNoZVBvbGljeSxcbiAgICBJT3JpZ2luQWNjZXNzSWRlbnRpdHksXG4gICAgT3JpZ2luQWNjZXNzSWRlbnRpdHksXG4gICAgT3JpZ2luUHJvdG9jb2xQb2xpY3ksXG4gICAgUHJpY2VDbGFzcyxcbiAgICBTZWN1cml0eVBvbGljeVByb3RvY29sLFxuICAgIFZpZXdlclByb3RvY29sUG9saWN5XG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udFwiO1xuaW1wb3J0IHtBcmNoaXRlY3R1cmUsIENvZGUsIEZ1bmN0aW9uLCBMYXllclZlcnNpb24sIFJ1bnRpbWV9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQge0Jsb2NrUHVibGljQWNjZXNzLCBCdWNrZXQsIEJ1Y2tldEFjY2Vzc0NvbnRyb2wsIElCdWNrZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7QWFhYVJlY29yZCwgQVJlY29yZCwgSG9zdGVkWm9uZSwgSUhvc3RlZFpvbmUsIFJlY29yZFRhcmdldH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1yb3V0ZTUzXCI7XG5pbXBvcnQge0J1Y2tldERlcGxveW1lbnQsIENhY2hlQ29udHJvbCwgU291cmNlLCBTdG9yYWdlQ2xhc3N9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHtIdHRwT3JpZ2luLCBTM09yaWdpbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250LW9yaWdpbnNcIjtcbmltcG9ydCB7Q2xvdWRGcm9udFRhcmdldH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1yb3V0ZTUzLXRhcmdldHNcIjtcbmltcG9ydCB7SHR0cE1ldGhvZH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzXCI7XG5pbXBvcnQge1JldGVudGlvbkRheXN9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiO1xuaW1wb3J0IHtIdHRwTGFtYmRhSW50ZWdyYXRpb259IGZyb20gJ0Bhd3MtY2RrL2F3cy1hcGlnYXRld2F5djItaW50ZWdyYXRpb25zLWFscGhhJztcbmltcG9ydCB7RG9tYWluTmFtZSwgRW5kcG9pbnRUeXBlLCBIdHRwQXBpLCBTZWN1cml0eVBvbGljeX0gZnJvbSBcIkBhd3MtY2RrL2F3cy1hcGlnYXRld2F5djItYWxwaGFcIjtcbmltcG9ydCB7Z2V0TnV4dEFwcFN0YXRpY0Fzc2V0Q29uZmlncywgU3RhdGljQXNzZXRDb25maWd9IGZyb20gXCIuL251eHQtYXBwLXN0YXRpYy1hc3NldHNcIjtcbmltcG9ydCB7QXBwU3RhY2tQcm9wc30gZnJvbSBcIi4vYXBwLXN0YWNrLXByb3BzXCI7XG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7UnVsZSwgU2NoZWR1bGV9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZXZlbnRzXCI7XG5pbXBvcnQge0xhbWJkYUZ1bmN0aW9ufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzXCI7XG5pbXBvcnQge051eHRDb25maWd9IGZyb20gXCIuL251eHQtY29uZmlnXCI7XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgcHJvcHMgcmVxdWlyZWQgZm9yIHRoZSB7QHNlZSBOdXh0QXBwU3RhY2t9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE51eHRBcHBTdGFja1Byb3BzIGV4dGVuZHMgQXBwU3RhY2tQcm9wcyB7XG4gICAgLyoqXG4gICAgICogVGhlIGRvbWFpbiAod2l0aG91dCB0aGUgcHJvdG9jb2wpIGF0IHdoaWNoIHRoZSBOdXh0IGFwcCBzaGFsbCBiZSBwdWJsaWNseSBhdmFpbGFibGUuXG4gICAgICogQSBETlMgcmVjb3JkIHdpbGwgYmUgYXV0b21hdGljYWxseSBjcmVhdGVkIGluIFJvdXRlNTMgZm9yIHRoZSBkb21haW4uXG4gICAgICogVGhpcyBhbHNvIHN1cHBvcnRzIHN1YmRvbWFpbnMuXG4gICAgICogRXhhbXBsZXM6IFwiZXhhbXBsZS5jb21cIiwgXCJzdWIuZXhhbXBsZS5jb21cIlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkIG9mIHRoZSBob3N0ZWQgem9uZSB0byBjcmVhdGUgYSBETlMgcmVjb3JkIGZvciB0aGUgc3BlY2lmaWVkIGRvbWFpbi5cbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUk4gb2YgdGhlIGNlcnRpZmljYXRlIHRvIHVzZSBvbiBDbG91ZEZyb250IGZvciB0aGUgTnV4dCBhcHAgdG8gbWFrZSBpdCBhY2Nlc3NpYmxlIHZpYSBIVFRQUy5cbiAgICAgKiBUaGUgY2VydGlmaWNhdGUgbXVzdCBiZSBpc3N1ZWQgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluIGluIHVzLWVhc3QtMSAoZ2xvYmFsKSByZWdhcmRsZXNzIG9mIHRoZVxuICAgICAqIHJlZ2lvbiBzcGVjaWZpZWQgdmlhICdlbnYucmVnaW9uJyBhcyBDbG91ZEZyb250IG9ubHkgd29ya3MgZ2xvYmFsbHkuXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ2xvYmFsVGxzQ2VydGlmaWNhdGVBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUk4gb2YgdGhlIGNlcnRpZmljYXRlIHRvIHVzZSBhdCB0aGUgQXBpR2F0ZXdheSBmb3IgdGhlIE51eHQgYXBwIHRvIG1ha2UgaXQgYWNjZXNzaWJsZSB2aWEgdGhlIGN1c3RvbSBkb21haW5cbiAgICAgKiBhbmQgdG8gcHJvdmlkZSB0aGUgY3VzdG9tIGRvbWFpbiB0byB0aGUgTnV4dCBhcHAgb24gc2VydmVyIHNpZGUgcmVuZGVyaW5nLlxuICAgICAqIFRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGlzc3VlZCBpbiB0aGUgc2FtZSByZWdpb24gYXMgc3BlY2lmaWVkIHZpYSAnZW52LnJlZ2lvbicgYXMgQXBpR2F0ZXdheSB3b3JrcyByZWdpb25hbGx5LlxuICAgICAqL1xuICAgIHJlYWRvbmx5IHJlZ2lvbmFsVGxzQ2VydGlmaWNhdGVBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBudXh0LmNvbmZpZy5qcyBvZiB0aGUgTnV4dCBhcHAuXG4gICAgICovXG4gICAgcmVhZG9ubHkgbnV4dENvbmZpZzogTnV4dENvbmZpZztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGFtYmRhIGZ1bmN0aW9uIHRoYXQgcmVuZGVycyB0aGUgTnV4dCBhcHAgYW5kIGlzIHB1YmxpY2x5IHJlYWNoYWJsZSB2aWEgYSBzcGVjaWZpZWQgZG9tYWluLlxuICovXG5leHBvcnQgY2xhc3MgTnV4dEFwcFN0YWNrIGV4dGVuZHMgU3RhY2sge1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkZW50aWZpZXIgcHJlZml4IG9mIHRoZSByZXNvdXJjZXMgY3JlYXRlZCBieSB0aGUgc3RhY2suXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VJZFByZWZpeDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRlcGxveW1lbnQgdGhhdCBpcyB1c2VkIGFzIFMzIGZvbGRlciBuYW1lXG4gICAgICogdG8gc3RvcmUgdGhlIHN0YXRpYyBhc3NldHMgb2YgdGhlIE51eHQgYXBwLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlcGxveW1lbnRSZXZpc2lvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkZW50aXR5IHRvIHVzZSBmb3IgYWNjZXNzaW5nIHRoZSBkZXBsb3ltZW50IGFzc2V0cyBvbiBTMy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZG5BY2Nlc3NJZGVudGl0eTogSU9yaWdpbkFjY2Vzc0lkZW50aXR5O1xuXG4gICAgLyoqXG4gICAgICogVGhlIFMzIGJ1Y2tldCB3aGVyZSB0aGUgZGVwbG95bWVudCBhc3NldHMgZ2V0cyBzdG9yZWQuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpY0Fzc2V0c0J1Y2tldDogSUJ1Y2tldDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBsYW1iZGEgZnVuY3Rpb24gdG8gcmVuZGVyIHRoZSBOdXh0IGFwcCBvbiB0aGUgc2VydmVyIHNpZGUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbGFtYmRhRnVuY3Rpb246IEZ1bmN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFQSSBnYXRld2F5IHRvIG1ha2UgdGhlIGxhbWJkYSBmdW5jdGlvbiB0byByZW5kZXIgdGhlIE51eHQgYXBwIHB1YmxpY2x5IGF2YWlsYWJsZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBhcGlHYXRld2F5OiBIdHRwQXBpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbmZpZ3MgZm9yIHRoZSBzdGF0aWMgYXNzZXRzIG9mIHRoZSBOdXh0IGFwcCB0aGF0IHNoYWxsIGJlIHB1YmxpY2x5IGF2YWlsYWJsZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBzdGF0aWNBc3NldENvbmZpZ3M6IFN0YXRpY0Fzc2V0Q29uZmlnW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gdG8gcm91dGUgaW5jb21pbmcgcmVxdWVzdHMgdG8gdGhlIE51eHQgbGFtYmRhIGZ1bmN0aW9uICh2aWEgdGhlIEFQSSBnYXRld2F5KVxuICAgICAqIG9yIHRoZSBTMyBhc3NldHMgZm9sZGVyICh3aXRoIGNhY2hpbmcpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkbjogRGlzdHJpYnV0aW9uO1xuXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuXG4gICAgICAgIHRoaXMucmVzb3VyY2VJZFByZWZpeCA9IGAke3Byb3BzLnByb2plY3R9LSR7cHJvcHMuc2VydmljZX0tJHtwcm9wcy5lbnZpcm9ubWVudH1gO1xuICAgICAgICB0aGlzLmRlcGxveW1lbnRSZXZpc2lvbiA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgdGhpcy5zdGF0aWNBc3NldENvbmZpZ3MgPSBnZXROdXh0QXBwU3RhdGljQXNzZXRDb25maWdzKHByb3BzLm51eHRDb25maWcpO1xuICAgICAgICB0aGlzLmNkbkFjY2Vzc0lkZW50aXR5ID0gdGhpcy5jcmVhdGVDZG5BY2Nlc3NJZGVudGl0eSgpO1xuICAgICAgICB0aGlzLnN0YXRpY0Fzc2V0c0J1Y2tldCA9IHRoaXMuY3JlYXRlU3RhdGljQXNzZXRzQnVja2V0KCk7XG4gICAgICAgIHRoaXMubGFtYmRhRnVuY3Rpb24gPSB0aGlzLmNyZWF0ZUxhbWJkYUZ1bmN0aW9uKCk7XG4gICAgICAgIHRoaXMuYXBpR2F0ZXdheSA9IHRoaXMuY3JlYXRlQXBpR2F0ZXdheShwcm9wcyk7XG4gICAgICAgIHRoaXMuY2RuID0gdGhpcy5jcmVhdGVDbG91ZEZyb250RGlzdHJpYnV0aW9uKHByb3BzKTtcbiAgICAgICAgdGhpcy5jb25maWd1cmVEZXBsb3ltZW50cygpO1xuICAgICAgICB0aGlzLmNyZWF0ZURuc1JlY29yZHMocHJvcHMpO1xuICAgICAgICB0aGlzLmNyZWF0ZVBpbmdSdWxlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgaWRlbnRpdHkgdG8gYWNjZXNzIHRoZSBTMyBkZXBsb3ltZW50IGFzc2V0IGZpbGVzIHZpYSB0aGUgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlQ2RuQWNjZXNzSWRlbnRpdHkoKTogSU9yaWdpbkFjY2Vzc0lkZW50aXR5IHtcbiAgICAgICAgY29uc3Qgb3JpZ2luQWNjZXNzSWRlbnRpdHlOYW1lID0gYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1jZG4tczMtYWNjZXNzYDtcbiAgICAgICAgcmV0dXJuIG5ldyBPcmlnaW5BY2Nlc3NJZGVudGl0eSh0aGlzLCBvcmlnaW5BY2Nlc3NJZGVudGl0eU5hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIGJ1Y2tldCB0byBzdG9yZSB0aGUgc3RhdGljIGRlcGxveW1lbnQgYXNzZXQgZmlsZXMgb2YgdGhlIE51eHQgYXBwLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZVN0YXRpY0Fzc2V0c0J1Y2tldCgpOiBJQnVja2V0IHtcbiAgICAgICAgY29uc3QgYnVja2V0TmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tYXNzZXRzYDtcbiAgICAgICAgY29uc3QgYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCBidWNrZXROYW1lLCB7XG4gICAgICAgICAgICBhY2Nlc3NDb250cm9sOiBCdWNrZXRBY2Nlc3NDb250cm9sLkFVVEhFTlRJQ0FURURfUkVBRCxcbiAgICAgICAgICAgIGJsb2NrUHVibGljQWNjZXNzOiBCbG9ja1B1YmxpY0FjY2Vzcy5CTE9DS19BTEwsXG4gICAgICAgICAgICBidWNrZXROYW1lLFxuICAgICAgICAgICAgLy8gVGhlIGJ1Y2tldCBhbmQgYWxsIG9mIGl0cyBvYmplY3RzIGNhbiBiZSBkZWxldGVkLCBiZWNhdXNlIGFsbCB0aGUgY29udGVudCBpcyBtYW5hZ2VkIGluIHRoaXMgcHJvamVjdFxuICAgICAgICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJ1Y2tldC5ncmFudFJlYWRXcml0ZSh0aGlzLmNkbkFjY2Vzc0lkZW50aXR5KTtcblxuICAgICAgICByZXR1cm4gYnVja2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBsYW1iZGEgbGF5ZXIgd2l0aCB0aGUgbm9kZV9tb2R1bGVzIHJlcXVpcmVkIHRvIHJlbmRlciB0aGUgTnV4dCBhcHAgb24gdGhlIHNlcnZlciBzaWRlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZVNzckxhbWJkYUxheWVyKCk6IExheWVyVmVyc2lvbiB7XG4gICAgICAgIGNvbnN0IGxheWVyTmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tc3NyLWxheWVyYDtcbiAgICAgICAgcmV0dXJuIG5ldyBMYXllclZlcnNpb24odGhpcywgbGF5ZXJOYW1lLCB7XG4gICAgICAgICAgICBsYXllclZlcnNpb25OYW1lOiBsYXllck5hbWUsXG4gICAgICAgICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldCgnLm51eHQvY2RrLWRlcGxveW1lbnQvbGF5ZXInKSxcbiAgICAgICAgICAgIGNvbXBhdGlibGVSdW50aW1lczogW1J1bnRpbWUuTk9ERUpTXzEyX1hdLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBQcm92aWRlcyB0aGUgbm9kZV9tb2R1bGVzIHJlcXVpcmVkIGZvciBTU1Igb2YgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LmAsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIGxhbWJkYSBmdW5jdGlvbiB0byByZW5kZXIgdGhlIE51eHQgYXBwLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZUxhbWJkYUZ1bmN0aW9uKCk6IEZ1bmN0aW9uIHtcbiAgICAgICAgY29uc3QgZnVuY05hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWZ1bmN0aW9uYDtcblxuICAgICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKHRoaXMsIGZ1bmNOYW1lLCB7XG4gICAgICAgICAgICBmdW5jdGlvbk5hbWU6IGZ1bmNOYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBSZW5kZXJzIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gTnV4dCBhcHAuYCxcbiAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzEyX1gsXG4gICAgICAgICAgICBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICAgICAgICBsYXllcnM6IFt0aGlzLmNyZWF0ZVNzckxhbWJkYUxheWVyKCldLFxuICAgICAgICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoJy5udXh0L2Nkay1kZXBsb3ltZW50L3NyYycsIHtcbiAgICAgICAgICAgICAgICBleGNsdWRlOiBbJyoqLnN2ZycsICcqKi5pY28nLCAnKioucG5nJywgJyoqLmpwZycsICcqKi5qcy5tYXAnXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGltZW91dDogRHVyYXRpb24uc2Vjb25kcygxMCksXG4gICAgICAgICAgICBtZW1vcnlTaXplOiA1MTIsXG4gICAgICAgICAgICBsb2dSZXRlbnRpb246IFJldGVudGlvbkRheXMuT05FX01PTlRILFxuICAgICAgICAgICAgYWxsb3dQdWJsaWNTdWJuZXQ6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIEFQSSBnYXRld2F5IHRvIG1ha2UgdGhlIE51eHQgYXBwIHJlbmRlciBsYW1iZGEgZnVuY3Rpb24gcHVibGljbHkgYXZhaWxhYmxlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZUFwaUdhdGV3YXkocHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKTogSHR0cEFwaSB7XG4gICAgICAgIGNvbnN0IGFwaU5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWFwaWA7XG4gICAgICAgIGNvbnN0IGxhbWJkYUludGVncmF0aW9uID0gbmV3IEh0dHBMYW1iZGFJbnRlZ3JhdGlvbihgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWxhbWJkYS1pbnRlZ3JhdGlvbmAsIHRoaXMubGFtYmRhRnVuY3Rpb24pO1xuXG4gICAgICAgIC8vIFdlIHdhbnQgdGhlIEFQSSBnYXRld2F5IHRvIGJlIGFjY2Vzc2libGUgYnkgdGhlIGN1c3RvbSBkb21haW4gbmFtZS5cbiAgICAgICAgLy8gRXZlbiB0aG91Z2ggd2UgYWNjZXNzIHRoZSBnYXRld2F5IHZpYSBDbG91ZEZyb250IChmb3IgYXV0byBodHRwIHRvIGh0dHBzIHJlZGlyZWN0cyksIHRoaXMgaXMgcmVxdWlyZWRcbiAgICAgICAgLy8gdG8gYmUgYWJsZSB0byByZWRpcmVjdCB0aGUgb3JpZ2luYWwgJ0hvc3QnIGhlYWRlciB0byB0aGUgTnV4dCBhcHBsaWNhdGlvbiwgaWYgcmVxdWVzdGVkLlxuICAgICAgICBjb25zdCBkb21haW5OYW1lID0gbmV3IERvbWFpbk5hbWUodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1hcGktZG9tYWluYCwge1xuICAgICAgICAgICAgZG9tYWluTmFtZTogcHJvcHMuZG9tYWluLFxuICAgICAgICAgICAgY2VydGlmaWNhdGU6IENlcnRpZmljYXRlLmZyb21DZXJ0aWZpY2F0ZUFybih0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LXJlZ2lvbmFsLWNlcnRpZmljYXRlYCwgcHJvcHMucmVnaW9uYWxUbHNDZXJ0aWZpY2F0ZUFybiksXG4gICAgICAgICAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZS5SRUdJT05BTCxcbiAgICAgICAgICAgIHNlY3VyaXR5UG9saWN5OiBTZWN1cml0eVBvbGljeS5UTFNfMV8yXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFwaUdhdGV3YXkgPSBuZXcgSHR0cEFwaSh0aGlzLCBhcGlOYW1lLCB7XG4gICAgICAgICAgICBhcGlOYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBDb25uZWN0cyB0aGUgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9IENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIHdpdGggdGhlICR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fSBsYW1iZGEgZnVuY3Rpb24gdG8gbWFrZSBpdCBwdWJsaWNseSBhdmFpbGFibGUuYCxcbiAgICAgICAgICAgIC8vIFRoZSBhcHAgZG9lcyBub3QgYWxsb3cgYW55IGNyb3NzLW9yaWdpbiBhY2Nlc3MgYnkgcHVycG9zZTogdGhlIGFwcCBzaG91bGQgbm90IGJlIGVtYmVkZGFibGUgYW55d2hlcmVcbiAgICAgICAgICAgIGNvcnNQcmVmbGlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGRlZmF1bHRJbnRlZ3JhdGlvbjogbGFtYmRhSW50ZWdyYXRpb24sXG4gICAgICAgICAgICBkZWZhdWx0RG9tYWluTWFwcGluZzoge1xuICAgICAgICAgICAgICAgIGRvbWFpbk5hbWU6IGRvbWFpbk5hbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXBpR2F0ZXdheS5hZGRSb3V0ZXMoe1xuICAgICAgICAgICAgaW50ZWdyYXRpb246IGxhbWJkYUludGVncmF0aW9uLFxuICAgICAgICAgICAgcGF0aDogJy97cHJveHkrfScsXG4gICAgICAgICAgICBtZXRob2RzOiBbSHR0cE1ldGhvZC5HRVQsIEh0dHBNZXRob2QuSEVBRF0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBhcGlHYXRld2F5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIHRoYXQgcm91dGVzIGluY29taW5nIHJlcXVlc3RzIHRvIHRoZSBOdXh0IGxhbWJkYSBmdW5jdGlvbiAodmlhIHRoZSBBUEkgZ2F0ZXdheSlcbiAgICAgKiBvciB0aGUgUzMgYXNzZXRzIGZvbGRlciAod2l0aCBjYWNoaW5nKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9wc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVDbG91ZEZyb250RGlzdHJpYnV0aW9uKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IERpc3RyaWJ1dGlvbiB7XG4gICAgICAgIGNvbnN0IGNkbk5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbmA7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBEaXN0cmlidXRpb24odGhpcywgY2RuTmFtZSwge1xuICAgICAgICAgICAgZG9tYWluTmFtZXM6IFtwcm9wcy5kb21haW5dLFxuICAgICAgICAgICAgY29tbWVudDogYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1yZWRpcmVjdGAsXG4gICAgICAgICAgICBtaW5pbXVtUHJvdG9jb2xWZXJzaW9uOiBTZWN1cml0eVBvbGljeVByb3RvY29sLlRMU19WMV8yXzIwMTgsXG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGUuZnJvbUNlcnRpZmljYXRlQXJuKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tZ2xvYmFsLWNlcnRpZmljYXRlYCwgcHJvcHMuZ2xvYmFsVGxzQ2VydGlmaWNhdGVBcm4pLFxuICAgICAgICAgICAgZGVmYXVsdEJlaGF2aW9yOiB0aGlzLmNyZWF0ZU51eHRBcHBSb3V0ZUJlaGF2aW9yKCksXG4gICAgICAgICAgICBhZGRpdGlvbmFsQmVoYXZpb3JzOiB0aGlzLmNyZWF0ZVN0YXRpY0Fzc2V0c1JvdXRlQmVoYXZpb3IoKSxcbiAgICAgICAgICAgIHByaWNlQ2xhc3M6IFByaWNlQ2xhc3MuUFJJQ0VfQ0xBU1NfMTAwLCAvLyBVc2Ugb25seSBOb3J0aCBBbWVyaWNhIGFuZCBFdXJvcGVcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGJlaGF2aW9yIGZvciB0aGUgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gdG8gcm91dGUgaW5jb21pbmcgcmVxdWVzdHMgdG8gdGhlIE51eHQgcmVuZGVyIGxhbWJkYSBmdW5jdGlvbiAodmlhIEFQSSBnYXRld2F5KS5cbiAgICAgKiBBZGRpdGlvbmFsbHksIHRoaXMgYXV0b21hdGljYWxseSByZWRpcmVjdHMgSFRUUCByZXF1ZXN0cyB0byBIVFRQUy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVOdXh0QXBwUm91dGVCZWhhdmlvcigpOiBCZWhhdmlvck9wdGlvbnMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb3JpZ2luOiBuZXcgSHR0cE9yaWdpbihgJHt0aGlzLmFwaUdhdGV3YXkuaHR0cEFwaUlkfS5leGVjdXRlLWFwaS4ke3RoaXMucmVnaW9ufS5hbWF6b25hd3MuY29tYCwge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25BdHRlbXB0czogMixcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uVGltZW91dDogRHVyYXRpb24uc2Vjb25kcygyKSxcbiAgICAgICAgICAgICAgICByZWFkVGltZW91dDogRHVyYXRpb24uc2Vjb25kcygxMCksXG4gICAgICAgICAgICAgICAgcHJvdG9jb2xQb2xpY3k6IE9yaWdpblByb3RvY29sUG9saWN5LkhUVFBTX09OTFksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGFsbG93ZWRNZXRob2RzOiBBbGxvd2VkTWV0aG9kcy5BTExPV19HRVRfSEVBRCxcbiAgICAgICAgICAgIGNvbXByZXNzOiB0cnVlLFxuICAgICAgICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IFZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgICAgICAgb3JpZ2luUmVxdWVzdFBvbGljeTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY2FjaGVQb2xpY3k6IHRoaXMuY3JlYXRlU3NyQ2FjaGVQb2xpY3koKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2FjaGUgcG9saWN5IGZvciB0aGUgTnV4dCBhcHAgcm91dGUgYmVoYXZpb3Igb2YgdGhlIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgICAqIEV2ZW50aG91Z2ggd2UgZG9uJ3Qgd2FudCB0byBjYWNoZSBTU1IgcmVxdWVzdHMsIHdlIHN0aWxsIGhhdmUgdG8gY3JlYXRlIHRoaXMgY2FjaGUgcG9saWN5IGluIG9yZGVyIHRvXG4gICAgICogZm9yd2FyZCByZXF1aXJlZCBjb29raWVzLCBxdWVyeSBwYXJhbXMgYW5kIGhlYWRlcnMuIFRoaXMgZG9lc24ndCBtYWtlIGFueSBzZW5zZSwgYmVjYXVzZSBpZiBub3RoaW5nXG4gICAgICogaXMgY2FjaGVkLCBvbmUgd291bGQgZXhwZWN0LCB0aGF0IGFueXRoaW5nIHdvdWxkL2NvdWxkIGJlIGZvcndhcmRlZCwgYnV0IGFueXdheS4uLlxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlU3NyQ2FjaGVQb2xpY3koKTogSUNhY2hlUG9saWN5IHtcblxuICAgICAgICAvLyBUaGUgaGVhZGVycyB0byBtYWtlIGFjY2Vzc2libGUgaW4gdGhlIE51eHQgYXBwIGNvZGUuXG4gICAgICAgIC8vIFRoZXJlIGlzIG5vICdDYWNoZUhlYWRlckJlaGF2aW9yLmFsbCgpJyBvcHRpb24sIHNvIHdlIGhhdmUgdG8gZXhwbGljaXRseSBkZWZpbmUgdGhlbS5cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IFtcbiAgICAgICAgICAgICdVc2VyLUFnZW50JywgLy8gUmVxdWlyZWQgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBtb2JpbGUgYW5kIGRlc2t0b3AgdGVtcGxhdGVcbiAgICAgICAgICAgICdBdXRob3JpemF0aW9uJywgLy8gRm9yIGF1dGhvcml6YXRpb25cbiAgICAgICAgICAgICdIb3N0JyAvLyBUbyBhY2Nlc3MgdGhlIGRvbWFpbiBuYW1lIG9uIFNTUiByZXF1ZXN0c1xuICAgICAgICBdO1xuXG4gICAgICAgIHJldHVybiBuZXcgQ2FjaGVQb2xpY3kodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1jYWNoZS1wb2xpY3lgLCB7XG4gICAgICAgICAgICBjYWNoZVBvbGljeU5hbWU6IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tY2RuLWNhY2hlLXBvbGljeWAsXG4gICAgICAgICAgICBjb21tZW50OiBgUGFzc2VzIGFsbCByZXF1aXJlZCByZXF1ZXN0IGRhdGEgdG8gdGhlICR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fSBvcmlnaW4uYCxcbiAgICAgICAgICAgIGRlZmF1bHRUdGw6IER1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAgICAgICBtaW5UdGw6IER1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAgICAgICBtYXhUdGw6IER1cmF0aW9uLnNlY29uZHMoMSksIC8vIFRoZSBtYXggVFRMIG11c3Qgbm90IGJlIDAgZm9yIGEgY2FjaGUgcG9saWN5XG4gICAgICAgICAgICBxdWVyeVN0cmluZ0JlaGF2aW9yOiBDYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IuYWxsKCksXG4gICAgICAgICAgICBoZWFkZXJCZWhhdmlvcjogQ2FjaGVIZWFkZXJCZWhhdmlvci5hbGxvd0xpc3QoLi4uaGVhZGVycyksXG4gICAgICAgICAgICBjb29raWVCZWhhdmlvcjogQ2FjaGVDb29raWVCZWhhdmlvci5hbGwoKSxcbiAgICAgICAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nQnJvdGxpOiB0cnVlLFxuICAgICAgICAgICAgZW5hYmxlQWNjZXB0RW5jb2RpbmdHemlwOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYmVoYXZpb3IgZm9yIHRoZSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiB0byByb3V0ZSBtYXRjaGluZyBpbmNvbWluZyByZXF1ZXN0cyBmb3IgdGhlIHN0YXRpYyBhc3NldHNcbiAgICAgKiB0byB0aGUgUzMgYnVja2V0IHRoYXQgaG9sZHMgdGhlc2Ugc3RhdGljIGFzc2V0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVTdGF0aWNBc3NldHNSb3V0ZUJlaGF2aW9yKCk6IFJlY29yZDxzdHJpbmcsIEJlaGF2aW9yT3B0aW9ucz4ge1xuICAgICAgICBjb25zdCBzdGF0aWNBc3NldHNDYWNoZUNvbmZpZzogQmVoYXZpb3JPcHRpb25zID0ge1xuICAgICAgICAgICAgb3JpZ2luOiBuZXcgUzNPcmlnaW4odGhpcy5zdGF0aWNBc3NldHNCdWNrZXQsIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uQXR0ZW1wdHM6IDIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvblRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMyksXG4gICAgICAgICAgICAgICAgb3JpZ2luQWNjZXNzSWRlbnRpdHk6IHRoaXMuY2RuQWNjZXNzSWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3JpZ2luUGF0aDogdGhpcy5kZXBsb3ltZW50UmV2aXNpb24sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNvbXByZXNzOiB0cnVlLFxuICAgICAgICAgICAgYWxsb3dlZE1ldGhvZHM6IEFsbG93ZWRNZXRob2RzLkFMTE9XX0dFVF9IRUFEX09QVElPTlMsXG4gICAgICAgICAgICBjYWNoZWRNZXRob2RzOiBDYWNoZWRNZXRob2RzLkNBQ0hFX0dFVF9IRUFEX09QVElPTlMsXG4gICAgICAgICAgICBjYWNoZVBvbGljeTogQ2FjaGVQb2xpY3kuQ0FDSElOR19PUFRJTUlaRUQsXG4gICAgICAgICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcnVsZXM6IFJlY29yZDxzdHJpbmcsIEJlaGF2aW9yT3B0aW9ucz4gPSB7fTtcbiAgICAgICAgdGhpcy5zdGF0aWNBc3NldENvbmZpZ3MuZm9yRWFjaChhc3NldCA9PiB7XG4gICAgICAgICAgICBydWxlc1tgJHthc3NldC50YXJnZXR9JHthc3NldC5wYXR0ZXJufWBdID0gc3RhdGljQXNzZXRzQ2FjaGVDb25maWdcbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gcnVsZXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSBzdGF0aWMgYXNzZXRzIG9mIHRoZSBOdXh0IGFwcCBhcyBkZWZpbmVkIGluIHtAc2VlIGdldE51eHRBcHBTdGF0aWNBc3NldENvbmZpZ3N9IHRvIHRoZSBzdGF0aWMgYXNzZXRzIFMzIGJ1Y2tldC5cbiAgICAgKiBJbiBvcmRlciB0byBlbmFibGUgYSB6ZXJvLWRvd250aW1lIGRlcGxveW1lbnQsIHdlIHVzZSBhIG5ldyBzdWJkaXJlY3RvcnkgKHJldmlzaW9uKSBmb3IgZXZlcnkgZGVwbG95bWVudC5cbiAgICAgKiBUaGUgcHJldmlvdXMgdmVyc2lvbnMgYXJlIHJldGFpbmVkIHRvIGFsbG93IGNsaWVudHMgdG8gY29udGludWUgdG8gd29yayB3aXRoIGFuIG9sZGVyIHJldmlzaW9uIGJ1dCBnZXRzIGNsZWFuZWQgdXBcbiAgICAgKiBhZnRlciBhIHNwZWNpZmllZCBwZXJpb2Qgb2YgdGltZSB2aWEgdGhlIGxhbWJkYSBmdW5jdGlvbiBpbiB0aGUge0BzZWUgTnV4dEFwcEFzc2V0c0NsZWFudXBTdGFja30uXG4gICAgICovXG4gICAgcHJpdmF0ZSBjb25maWd1cmVEZXBsb3ltZW50cygpOiBCdWNrZXREZXBsb3ltZW50W10ge1xuICAgICAgICBjb25zdCBkZWZhdWx0Q2FjaGVDb25maWcgPSBbXG4gICAgICAgICAgICBDYWNoZUNvbnRyb2wuc2V0UHVibGljKCksXG4gICAgICAgICAgICBDYWNoZUNvbnRyb2wubWF4QWdlKER1cmF0aW9uLmRheXMoMzY1KSksXG4gICAgICAgICAgICBDYWNoZUNvbnRyb2wuZnJvbVN0cmluZygnaW1tdXRhYmxlJyksXG4gICAgICAgIF07XG5cbiAgICAgICAgLy8gUmV0dXJucyBhIGRlcGxveW1lbnQgZm9yIGV2ZXJ5IGNvbmZpZ3VyZWQgc3RhdGljIGFzc2V0IHR5cGUgdG8gcmVzcGVjdCB0aGUgZGlmZmVyZW50IGNhY2hlIHNldHRpbmdzXG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRpY0Fzc2V0Q29uZmlncy5maWx0ZXIoYXNzZXQgPT4gZnMuZXhpc3RzU3luYyhhc3NldC5zb3VyY2UpKS5tYXAoKGFzc2V0LCBhc3NldEluZGV4KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1Y2tldERlcGxveW1lbnQodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1hc3NldHMtZGVwbG95bWVudC0ke2Fzc2V0SW5kZXh9YCwge1xuICAgICAgICAgICAgICAgIHNvdXJjZXM6IFtTb3VyY2UuYXNzZXQoYXNzZXQuc291cmNlKV0sXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25CdWNrZXQ6IHRoaXMuc3RhdGljQXNzZXRzQnVja2V0LFxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiB0aGlzLmRlcGxveW1lbnRSZXZpc2lvbiArIGFzc2V0LnRhcmdldCxcbiAgICAgICAgICAgICAgICBwcnVuZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc3RvcmFnZUNsYXNzOiBTdG9yYWdlQ2xhc3MuU1RBTkRBUkQsXG4gICAgICAgICAgICAgICAgZXhjbHVkZTogWycqJ10sXG4gICAgICAgICAgICAgICAgaW5jbHVkZTogW2Fzc2V0LnBhdHRlcm5dLFxuICAgICAgICAgICAgICAgIGNhY2hlQ29udHJvbDogYXNzZXQuY2FjaGVDb250cm9sID8/IGRlZmF1bHRDYWNoZUNvbmZpZyxcbiAgICAgICAgICAgICAgICBjb250ZW50VHlwZTogYXNzZXQuY29udGVudFR5cGUsXG4gICAgICAgICAgICAgICAgbG9nUmV0ZW50aW9uOiBSZXRlbnRpb25EYXlzLk9ORV9EQVksXG4gICAgICAgICAgICAgICAgbWVtb3J5TGltaXQ6IDI1NiAvLyBTb21lIE51eHQgYXBwbGljYXRpb25zIGhhdmUgYSBsb3Qgb2YgYXNzZXRzIHRvIGRlcGxveSB3aGVyZWJ5IHRoZSBmdW5jdGlvbiBtaWdodCBydW4gb3V0IG9mIG1lbW9yeVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzb2x2ZXMgdGhlIGhvc3RlZCB6b25lIGF0IHdoaWNoIHRoZSBETlMgcmVjb3JkcyBzaGFsbCBiZSBjcmVhdGVkIHRvIGFjY2VzcyB0aGUgTnV4dCBhcHAgb24gdGhlIGludGVybmV0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHByb3BzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGZpbmRIb3N0ZWRab25lKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IElIb3N0ZWRab25lIHtcbiAgICAgICAgY29uc3QgZG9tYWluUGFydHMgPSBwcm9wcy5kb21haW4uc3BsaXQoJy4nKTtcblxuICAgICAgICByZXR1cm4gSG9zdGVkWm9uZS5mcm9tSG9zdGVkWm9uZUF0dHJpYnV0ZXModGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1ob3N0ZWQtem9uZWAsIHtcbiAgICAgICAgICAgIGhvc3RlZFpvbmVJZDogcHJvcHMuaG9zdGVkWm9uZUlkLFxuICAgICAgICAgICAgem9uZU5hbWU6IGRvbWFpblBhcnRzW2RvbWFpblBhcnRzLmxlbmd0aCAtIDFdLCAvLyBTdXBwb3J0IHN1YmRvbWFpbnNcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgRE5TIHJlY29yZHMgdG8gYWNjZXNzIHRoZSBOdXh0IGFwcCBvbiB0aGUgaW50ZXJuZXQgdmlhIHRoZSBjdXN0b20gZG9tYWluLlxuICAgICAqXG4gICAgICogQHBhcmFtIHByb3BzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZURuc1JlY29yZHMocHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGhvc3RlZFpvbmUgPSB0aGlzLmZpbmRIb3N0ZWRab25lKHByb3BzKTtcbiAgICAgICAgY29uc3QgZG5zVGFyZ2V0ID0gUmVjb3JkVGFyZ2V0LmZyb21BbGlhcyhuZXcgQ2xvdWRGcm9udFRhcmdldCh0aGlzLmNkbikpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBhIHJlY29yZCBmb3IgSVB2NFxuICAgICAgICBuZXcgQVJlY29yZCh0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWlwdjQtcmVjb3JkYCwge1xuICAgICAgICAgICAgcmVjb3JkTmFtZTogcHJvcHMuZG9tYWluLFxuICAgICAgICAgICAgem9uZTogaG9zdGVkWm9uZSxcbiAgICAgICAgICAgIHRhcmdldDogZG5zVGFyZ2V0LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDcmVhdGUgYSByZWNvcmQgZm9yIElQdjZcbiAgICAgICAgbmV3IEFhYWFSZWNvcmQodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1pcHY2LXJlY29yZGAsIHtcbiAgICAgICAgICAgIHJlY29yZE5hbWU6IHByb3BzLmRvbWFpbixcbiAgICAgICAgICAgIHpvbmU6IGhvc3RlZFpvbmUsXG4gICAgICAgICAgICB0YXJnZXQ6IGRuc1RhcmdldCxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNjaGVkdWxlZCBydWxlIHRvIHBpbmcgdGhlIE51eHQgYXBwIGxhbWJkYSBmdW5jdGlvbiBldmVyeSA1IG1pbnV0ZXMgaW4gb3JkZXIgdG8ga2VlcCBpdCB3YXJtXG4gICAgICogYW5kIHNwZWVkIHVwIGluaXRpYWwgU1NSIHJlcXVlc3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZVBpbmdSdWxlKCk6IHZvaWQge1xuICAgICAgICBuZXcgUnVsZSh0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LXBpbmdlci1ydWxlYCwge1xuICAgICAgICAgICAgcnVsZU5hbWU6IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tcGluZ2VyYCxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgUGluZ3MgdGhlIGxhbWJkYSBmdW5jdGlvbiBvZiB0aGUgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9IGFwcCBldmVyeSA1IG1pbnV0ZXMgdG8ga2VlcCBpdCB3YXJtLmAsXG4gICAgICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICAgICAgc2NoZWR1bGU6IFNjaGVkdWxlLnJhdGUoRHVyYXRpb24ubWludXRlcyg1KSksXG4gICAgICAgICAgICB0YXJnZXRzOiBbbmV3IExhbWJkYUZ1bmN0aW9uKHRoaXMubGFtYmRhRnVuY3Rpb24pXSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIl19
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Duration, RemovalPolicy, Stack} from 'aws-cdk-lib';
|
|
2
2
|
import {Construct} from 'constructs';
|
|
3
|
-
import {Certificate
|
|
3
|
+
import {Certificate} from "aws-cdk-lib/aws-certificatemanager";
|
|
4
4
|
import {
|
|
5
5
|
AllowedMethods,
|
|
6
6
|
BehaviorOptions,
|
|
@@ -53,12 +53,19 @@ export interface NuxtAppStackProps extends AppStackProps {
|
|
|
53
53
|
readonly hostedZoneId: string;
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* The ARN of the certificate to use for the Nuxt app to make it accessible via HTTPS.
|
|
56
|
+
* The ARN of the certificate to use on CloudFront for the Nuxt app to make it accessible via HTTPS.
|
|
57
57
|
* The certificate must be issued for the specified domain in us-east-1 (global) regardless of the
|
|
58
|
-
* region
|
|
58
|
+
* region specified via 'env.region' as CloudFront only works globally.
|
|
59
59
|
*/
|
|
60
60
|
readonly globalTlsCertificateArn: string;
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* The ARN of the certificate to use at the ApiGateway for the Nuxt app to make it accessible via the custom domain
|
|
64
|
+
* and to provide the custom domain to the Nuxt app on server side rendering.
|
|
65
|
+
* The certificate must be issued in the same region as specified via 'env.region' as ApiGateway works regionally.
|
|
66
|
+
*/
|
|
67
|
+
readonly regionalTlsCertificateArn: string;
|
|
68
|
+
|
|
62
69
|
/**
|
|
63
70
|
* The nuxt.config.js of the Nuxt app.
|
|
64
71
|
*/
|
|
@@ -85,13 +92,6 @@ export class NuxtAppStack extends Stack {
|
|
|
85
92
|
*/
|
|
86
93
|
private readonly deploymentRevision: string;
|
|
87
94
|
|
|
88
|
-
/**
|
|
89
|
-
* The certificate to use for the Nuxt app to make it accessible via HTTPS.
|
|
90
|
-
*
|
|
91
|
-
* @private
|
|
92
|
-
*/
|
|
93
|
-
private readonly tlsCertificate: ICertificate;
|
|
94
|
-
|
|
95
95
|
/**
|
|
96
96
|
* The identity to use for accessing the deployment assets on S3.
|
|
97
97
|
*
|
|
@@ -126,7 +126,7 @@ export class NuxtAppStack extends Stack {
|
|
|
126
126
|
private staticAssetConfigs: StaticAssetConfig[];
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
|
-
* The
|
|
129
|
+
* The CloudFront distribution to route incoming requests to the Nuxt lambda function (via the API gateway)
|
|
130
130
|
* or the S3 assets folder (with caching).
|
|
131
131
|
*
|
|
132
132
|
* @private
|
|
@@ -139,7 +139,6 @@ export class NuxtAppStack extends Stack {
|
|
|
139
139
|
this.resourceIdPrefix = `${props.project}-${props.service}-${props.environment}`;
|
|
140
140
|
this.deploymentRevision = new Date().toISOString();
|
|
141
141
|
this.staticAssetConfigs = getNuxtAppStaticAssetConfigs(props.nuxtConfig);
|
|
142
|
-
this.tlsCertificate = this.findTlsCertificate(props);
|
|
143
142
|
this.cdnAccessIdentity = this.createCdnAccessIdentity();
|
|
144
143
|
this.staticAssetsBucket = this.createStaticAssetsBucket();
|
|
145
144
|
this.lambdaFunction = this.createLambdaFunction();
|
|
@@ -151,17 +150,7 @@ export class NuxtAppStack extends Stack {
|
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* @param props
|
|
157
|
-
* @private
|
|
158
|
-
*/
|
|
159
|
-
private findTlsCertificate(props: NuxtAppStackProps): ICertificate {
|
|
160
|
-
return Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-tls-certificate`, props.globalTlsCertificateArn);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Creates the identity to access our S3 deployment asset files via the cloudfront distribution.
|
|
153
|
+
* Creates the identity to access the S3 deployment asset files via the CloudFront distribution.
|
|
165
154
|
*
|
|
166
155
|
* @private
|
|
167
156
|
*/
|
|
@@ -241,18 +230,18 @@ export class NuxtAppStack extends Stack {
|
|
|
241
230
|
const lambdaIntegration = new HttpLambdaIntegration(`${this.resourceIdPrefix}-lambda-integration`, this.lambdaFunction);
|
|
242
231
|
|
|
243
232
|
// We want the API gateway to be accessible by the custom domain name.
|
|
244
|
-
// Even though we access the gateway via
|
|
245
|
-
// to be able to redirect the original 'Host' header to
|
|
233
|
+
// Even though we access the gateway via CloudFront (for auto http to https redirects), this is required
|
|
234
|
+
// to be able to redirect the original 'Host' header to the Nuxt application, if requested.
|
|
246
235
|
const domainName = new DomainName(this, `${this.resourceIdPrefix}-api-domain`, {
|
|
247
236
|
domainName: props.domain,
|
|
248
|
-
certificate: this.
|
|
237
|
+
certificate: Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-regional-certificate`, props.regionalTlsCertificateArn),
|
|
249
238
|
endpointType: EndpointType.REGIONAL,
|
|
250
239
|
securityPolicy: SecurityPolicy.TLS_1_2
|
|
251
240
|
});
|
|
252
241
|
|
|
253
242
|
const apiGateway = new HttpApi(this, apiName, {
|
|
254
243
|
apiName,
|
|
255
|
-
description: `Connects the ${this.resourceIdPrefix}
|
|
244
|
+
description: `Connects the ${this.resourceIdPrefix} CloudFront distribution with the ${this.resourceIdPrefix} lambda function to make it publicly available.`,
|
|
256
245
|
// The app does not allow any cross-origin access by purpose: the app should not be embeddable anywhere
|
|
257
246
|
corsPreflight: undefined,
|
|
258
247
|
defaultIntegration: lambdaIntegration,
|
|
@@ -271,7 +260,7 @@ export class NuxtAppStack extends Stack {
|
|
|
271
260
|
}
|
|
272
261
|
|
|
273
262
|
/**
|
|
274
|
-
* Creates the
|
|
263
|
+
* Creates the CloudFront distribution that routes incoming requests to the Nuxt lambda function (via the API gateway)
|
|
275
264
|
* or the S3 assets folder (with caching).
|
|
276
265
|
*
|
|
277
266
|
* @param props
|
|
@@ -284,7 +273,7 @@ export class NuxtAppStack extends Stack {
|
|
|
284
273
|
domainNames: [props.domain],
|
|
285
274
|
comment: `${this.resourceIdPrefix}-redirect`,
|
|
286
275
|
minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_2_2018,
|
|
287
|
-
certificate: this.
|
|
276
|
+
certificate: Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-global-certificate`, props.globalTlsCertificateArn),
|
|
288
277
|
defaultBehavior: this.createNuxtAppRouteBehavior(),
|
|
289
278
|
additionalBehaviors: this.createStaticAssetsRouteBehavior(),
|
|
290
279
|
priceClass: PriceClass.PRICE_CLASS_100, // Use only North America and Europe
|
|
@@ -292,7 +281,7 @@ export class NuxtAppStack extends Stack {
|
|
|
292
281
|
}
|
|
293
282
|
|
|
294
283
|
/**
|
|
295
|
-
* Creates a behavior for the
|
|
284
|
+
* Creates a behavior for the CloudFront distribution to route incoming requests to the Nuxt render lambda function (via API gateway).
|
|
296
285
|
* Additionally, this automatically redirects HTTP requests to HTTPS.
|
|
297
286
|
*
|
|
298
287
|
* @private
|
|
@@ -314,14 +303,14 @@ export class NuxtAppStack extends Stack {
|
|
|
314
303
|
}
|
|
315
304
|
|
|
316
305
|
/**
|
|
317
|
-
* Creates a cache policy for the Nuxt app route behavior of
|
|
306
|
+
* Creates a cache policy for the Nuxt app route behavior of the CloudFront distribution.
|
|
318
307
|
* Eventhough we don't want to cache SSR requests, we still have to create this cache policy in order to
|
|
319
308
|
* forward required cookies, query params and headers. This doesn't make any sense, because if nothing
|
|
320
309
|
* is cached, one would expect, that anything would/could be forwarded, but anyway...
|
|
321
310
|
*/
|
|
322
311
|
private createSsrCachePolicy(): ICachePolicy {
|
|
323
312
|
|
|
324
|
-
// The headers to make accessible in
|
|
313
|
+
// The headers to make accessible in the Nuxt app code.
|
|
325
314
|
// There is no 'CacheHeaderBehavior.all()' option, so we have to explicitly define them.
|
|
326
315
|
const headers = [
|
|
327
316
|
'User-Agent', // Required to distinguish between mobile and desktop template
|
|
@@ -344,7 +333,7 @@ export class NuxtAppStack extends Stack {
|
|
|
344
333
|
}
|
|
345
334
|
|
|
346
335
|
/**
|
|
347
|
-
* Creates a behavior for the
|
|
336
|
+
* Creates a behavior for the CloudFront distribution to route matching incoming requests for the static assets
|
|
348
337
|
* to the S3 bucket that holds these static assets.
|
|
349
338
|
*
|
|
350
339
|
* @private
|
|
@@ -404,7 +393,7 @@ export class NuxtAppStack extends Stack {
|
|
|
404
393
|
}
|
|
405
394
|
|
|
406
395
|
/**
|
|
407
|
-
* Resolves the hosted zone at which the DNS records shall be created to access
|
|
396
|
+
* Resolves the hosted zone at which the DNS records shall be created to access the Nuxt app on the internet.
|
|
408
397
|
*
|
|
409
398
|
* @param props
|
|
410
399
|
* @private
|
|
@@ -419,7 +408,7 @@ export class NuxtAppStack extends Stack {
|
|
|
419
408
|
}
|
|
420
409
|
|
|
421
410
|
/**
|
|
422
|
-
* Creates the DNS records to access
|
|
411
|
+
* Creates the DNS records to access the Nuxt app on the internet via the custom domain.
|
|
423
412
|
*
|
|
424
413
|
* @param props
|
|
425
414
|
* @private
|
|
@@ -444,7 +433,7 @@ export class NuxtAppStack extends Stack {
|
|
|
444
433
|
}
|
|
445
434
|
|
|
446
435
|
/**
|
|
447
|
-
* Creates a scheduled rule to ping
|
|
436
|
+
* Creates a scheduled rule to ping the Nuxt app lambda function every 5 minutes in order to keep it warm
|
|
448
437
|
* and speed up initial SSR requests.
|
|
449
438
|
*
|
|
450
439
|
* @private
|
|
@@ -30,9 +30,17 @@ const appStackProps: NuxtAppStackProps = {
|
|
|
30
30
|
...commonProps,
|
|
31
31
|
// The domain (without the protocol) at which the Nuxt app shall be publicly available.
|
|
32
32
|
domain: 'example.com',
|
|
33
|
-
|
|
34
|
-
// The
|
|
33
|
+
|
|
34
|
+
// The ARN of the certificate to use on CloudFront for the Nuxt app to make it accessible via HTTPS.
|
|
35
|
+
// The certificate must be issued for the specified domain in us-east-1 (global) regardless of the
|
|
36
|
+
// region specified via 'env.region' as CloudFront only works globally.
|
|
35
37
|
globalTlsCertificateArn: 'arn:aws:acm:us-east-1:XXXXXXXXXX:certificate/XXXXXXXXXXXXXXXXX',
|
|
38
|
+
|
|
39
|
+
// The ARN of the certificate to use at the ApiGateway for the Nuxt app to make it accessible via the custom domain
|
|
40
|
+
// and to provide the custom domain to the Nuxt app on server side rendering.
|
|
41
|
+
// The certificate must be issued in the same region as specified via 'env.region' as ApiGateway works regionally.
|
|
42
|
+
regionalTlsCertificateArn: 'arn:aws:acm:eu-central-1:XXXXXXXXXX:certificate/XXXXXXXXXXXXXXXXX',
|
|
43
|
+
|
|
36
44
|
// The id of the hosted zone to create a DNS record for the specified domain.
|
|
37
45
|
hostedZoneId: 'XXXXXXXXXXXXX',
|
|
38
46
|
|