deployable-awscdk-app-ts 0.1.679 → 0.1.681

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/steps.js CHANGED
@@ -1,163 +1,480 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkoutStep = checkoutStep;
4
- exports.setNodeVersionStep = setNodeVersionStep;
5
- exports.installDependenciesStep = installDependenciesStep;
6
- exports.deploymentStep = deploymentStep;
7
- exports.setAwsCredentialsSteps = setAwsCredentialsSteps;
8
- exports.setNpmConfig = setNpmConfig;
9
- exports.checkActiveDeploymentStep = checkActiveDeploymentStep;
10
- exports.postDeploymentStep = postDeploymentStep;
11
- exports.preDeploymentStep = preDeploymentStep;
12
- exports.preInstallDependenciesStep = preInstallDependenciesStep;
13
- const projen_1 = require("projen");
3
+ exports.DeployableAwsCdkTypeScriptAppStepsFactory = void 0;
4
+ const github_1 = require("projen/lib/github");
5
+ const workflows_model_1 = require("projen/lib/github/workflows-model");
14
6
  const javascript_1 = require("projen/lib/javascript");
15
- function checkoutStep() {
16
- return {
17
- name: 'Checkout',
18
- uses: 'actions/checkout@v4',
19
- with: {
20
- 'ref': '${{ github.sha }}',
21
- 'fetch-depth': 0,
22
- },
23
- };
24
- }
25
- function setNodeVersionStep(nodeVersion, checkActiveDeployment) {
26
- return {
27
- ...getSkipIfAlreadyActiveDeploymentCondition(checkActiveDeployment),
28
- name: 'Setup Node.js',
29
- uses: 'actions/setup-node@v4',
30
- with: {
31
- 'node-version': nodeVersion,
32
- },
33
- };
34
- }
35
- function installDependenciesStep(command, checkActiveDeployment) {
36
- return {
37
- ...getSkipIfAlreadyActiveDeploymentCondition(checkActiveDeployment),
38
- name: 'Install dependencies',
39
- run: command,
40
- };
41
- }
42
- function getPackageManagerCommandPrefix(packageManager) {
43
- if (packageManager === projen_1.javascript.NodePackageManager.NPM) {
44
- return 'npm run';
7
+ const types_1 = require("./types");
8
+ const checkActiveDeploymentStepId = 'deployment-check';
9
+ const skipIfAlreadyActiveDeploymentCondition = `steps.${checkActiveDeploymentStepId}.outputs.has_active_deployment != 'true'`;
10
+ /**
11
+ * Factory to create reusable steps for the deployment workflow
12
+ * @experimental
13
+ */
14
+ class DeployableAwsCdkTypeScriptAppStepsFactory {
15
+ /**
16
+ * Create a new DeployableAwsCdkTypeScriptAppStepsFactory
17
+ * @param project The project
18
+ * @param props The factory properties
19
+ */
20
+ constructor(project, props) {
21
+ this.project = project;
22
+ this.props = props;
45
23
  }
46
- if (packageManager === projen_1.javascript.NodePackageManager.YARN) {
47
- return 'yarn';
24
+ /**
25
+ * Condition to skip a step if an active deployment is already present
26
+ * @returns JobStep condition or undefined if checkActiveDeployment is false
27
+ */
28
+ get skipIfAlreadyActiveDeploymentCondition() {
29
+ return this.props.checkActiveDeployment ? { if: `\${{ ${skipIfAlreadyActiveDeploymentCondition} }}` } : undefined;
48
30
  }
49
- if (packageManager === projen_1.javascript.NodePackageManager.PNPM) {
50
- return 'pnpm';
31
+ get checkoutStep() {
32
+ return github_1.WorkflowSteps.checkout({
33
+ with: {
34
+ fetchDepth: 0,
35
+ ref: '${{ github.sha }}',
36
+ },
37
+ });
51
38
  }
52
- throw new Error(`Invalid package manager selected (${packageManager})`);
53
- }
54
- function deploymentStep(checkActiveDeployment, packageManager) {
55
- return {
56
- ...getSkipIfAlreadyActiveDeploymentCondition(checkActiveDeployment),
57
- name: 'Deployment',
58
- run: `${getPackageManagerCommandPrefix(packageManager)} deploy:workflow`,
59
- };
60
- }
61
- function setAwsCredentialsInEnvironment(checkActiveDeployment) {
62
- const commands = [
63
- 'echo "AWS_ACCESS_KEY_ID=$accessKeyId" >> $GITHUB_ENV',
64
- 'echo "AWS_SECRET_ACCESS_KEY=$secretAccessKey" >> $GITHUB_ENV',
65
- 'echo "AWS_REGION=$region" >> $GITHUB_ENV',
66
- ];
67
- const condition = checkActiveDeployment ?
68
- `\${{ matrix.assumeRole == 'false' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
69
- '${{ matrix.assumeRole == \'false\' }}';
70
- return {
71
- if: condition,
72
- name: 'Configure AWS Credentials',
73
- run: `${commands.join('\n')}`,
74
- env: {
75
- accessKeyId: '${{ secrets[matrix.accessKeyIdSecretName] }}',
76
- secretAccessKey: '${{ secrets[matrix.secretAccessKeySecretName] }}',
77
- region: '${{ matrix.region }}',
78
- },
79
- };
80
- }
81
- function assumeAwsRoleStep(checkActiveDeployment, authProvider) {
82
- const condition = checkActiveDeployment ?
83
- `\${{ matrix.assumeRole == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
84
- '${{ matrix.assumeRole == \'true\' }}';
85
- const secretsParams = authProvider === javascript_1.CodeArtifactAuthProvider.ACCESS_AND_SECRET_KEY_PAIR ?
86
- {
87
- 'aws-access-key-id': '${{ secrets[matrix.accessKeyIdSecretName] }}',
88
- 'aws-secret-access-key': '${{ secrets[matrix.secretAccessKeySecretName] }}',
39
+ /**
40
+ * Step to run before installing dependencies if exists
41
+ * @returns JobStep or undefined if no preInstallTaskName is provided
42
+ */
43
+ get preInstallDependenciesStep() {
44
+ if (!this.props.preInstallTaskName) {
45
+ return undefined;
46
+ }
47
+ return {
48
+ ...this.skipIfAlreadyActiveDeploymentCondition,
49
+ name: this.props.preInstallTaskName,
50
+ run: `npx projen ${this.props.preInstallTaskName}`,
51
+ };
52
+ }
53
+ /**
54
+ * Step to check if there is an active deployment for the environment in the matrix strategy
55
+ * @returns JobStep
56
+ */
57
+ get checkActiveDeploymentStepForMatrix() {
58
+ return this.getCheckActiveDeploymentStepForEnvironment('${{ matrix.environment }}');
59
+ }
60
+ /**
61
+ * Step to check if there is an active deployment for a specific environment
62
+ * @param environment The environment to check
63
+ * @returns JobStep
64
+ */
65
+ getCheckActiveDeploymentStepForEnvironment(environment) {
66
+ if (!this.props.checkActiveDeployment) {
67
+ return undefined;
68
+ }
69
+ return {
70
+ id: checkActiveDeploymentStepId,
71
+ uses: 'AminFazlMondo/check-deployed-environment@v1',
72
+ with: {
73
+ environment: environment,
74
+ },
75
+ env: {
76
+ GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}',
77
+ },
78
+ };
79
+ }
80
+ /**
81
+ * Step to setup AWS credentials in the environment for the matrix strategy
82
+ * @returns JobStep[]
83
+ */
84
+ get setupAwsCredentialsStepsForMatrix() {
85
+ return [
86
+ this.setupAwsCredentialsInEnvironmentForMatrix,
87
+ this.assumeAwsRoleStepForMatrix,
88
+ ];
89
+ }
90
+ /**
91
+ * Get the steps to setup AWS credentials for a specific environment
92
+ * @param environmentOptions The environment options
93
+ * @returns JobStep[]
94
+ */
95
+ getSetupAwsCredentialsStepsForEnvironment(environmentOptions) {
96
+ const steps = [];
97
+ const fromEnvVariableStep = this.getSetupAwsCredentialsInEnvironmentForEnvironment(environmentOptions.awsCredentials.roleToAssume ? true : false, environmentOptions.awsCredentials.accessKeyIdSecretName ?? 'AWS_ACCESS_KEY_ID', environmentOptions.awsCredentials.secretAccessKeySecretName ?? 'AWS_SECRET_ACCESS_KEY', environmentOptions.awsCredentials.region);
98
+ if (fromEnvVariableStep) {
99
+ steps.push(fromEnvVariableStep);
100
+ }
101
+ const assumeRoleStep = this.getAssumeAwsRoleStepForEnvironment(environmentOptions.awsCredentials.roleToAssume ? true : false, environmentOptions.awsCredentials.accessKeyIdSecretName ?? 'AWS_ACCESS_KEY_ID', environmentOptions.awsCredentials.secretAccessKeySecretName ?? 'AWS_SECRET_ACCESS_KEY', environmentOptions.awsCredentials.region, environmentOptions.awsCredentials.roleToAssume ?? '', environmentOptions.awsCredentials.assumeRoleDurationSeconds ?? 900);
102
+ if (assumeRoleStep) {
103
+ steps.push(assumeRoleStep);
104
+ }
105
+ return steps;
106
+ }
107
+ /**
108
+ * Step to setup AWS credentials in the environment for the matrix strategy
109
+ * @returns JobStep
110
+ */
111
+ get setupAwsCredentialsInEnvironmentForMatrix() {
112
+ return this.getSetupAwsCredentialsInEnvironmentForEnvironment('matrix.assumeRole', 'matrix.accessKeyIdSecretName', 'matrix.secretAccessKeySecretName', '${{ matrix.region }}');
113
+ }
114
+ /**
115
+ * Step to setup AWS credentials in the environment for a specific environment
116
+ * @param assumeRoleFlag Whether to assume a role, can be a boolean or a string for matrix strategy
117
+ * @param accessKeyIdSecretName The GitHub secret name for the access key ID
118
+ * @param secretAccessKeySecretName The GitHub secret name for the secret access key
119
+ * @param region The region
120
+ * @returns JobStep or undefined if no AWS credentials are provided,
121
+ * if assumeRoleFlag is boolean will be evaluated and return a JobStep only if false
122
+ * if assumeRoleFlag is string will always return a JobStep (for matrix strategy)
123
+ */
124
+ getSetupAwsCredentialsInEnvironmentForEnvironment(assumeRoleFlag, accessKeyIdSecretName, secretAccessKeySecretName, region) {
125
+ function getCondition(factory) {
126
+ if (typeof assumeRoleFlag === 'boolean') {
127
+ if (assumeRoleFlag) {
128
+ return undefined;
129
+ }
130
+ return factory.props.checkActiveDeployment ? skipIfAlreadyActiveDeploymentCondition : undefined;
131
+ }
132
+ return factory.props.checkActiveDeployment ?
133
+ `\${{ ${assumeRoleFlag} == 'false' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
134
+ `\${{ ${assumeRoleFlag} == 'false' }}`;
135
+ }
136
+ const commands = [
137
+ 'echo "AWS_ACCESS_KEY_ID=$accessKeyId" >> $GITHUB_ENV',
138
+ 'echo "AWS_SECRET_ACCESS_KEY=$secretAccessKey" >> $GITHUB_ENV',
139
+ 'echo "AWS_REGION=$region" >> $GITHUB_ENV',
140
+ ];
141
+ if (typeof assumeRoleFlag === 'boolean' && assumeRoleFlag) {
142
+ return undefined;
143
+ }
144
+ const condition = getCondition(this);
145
+ return {
146
+ if: condition,
147
+ name: 'Configure AWS Credentials',
148
+ run: `${commands.join('\n')}`,
149
+ env: {
150
+ accessKeyId: `\${{ secrets[${accessKeyIdSecretName}] }}`,
151
+ secretAccessKey: `\${{ secrets[${secretAccessKeySecretName}] }}`,
152
+ region,
153
+ },
154
+ };
155
+ }
156
+ /**
157
+ * Step to assume an AWS role for the matrix strategy
158
+ * @returns JobStep
159
+ */
160
+ get assumeAwsRoleStepForMatrix() {
161
+ return this.getAssumeAwsRoleStepForEnvironment('matrix.assumeRole', 'matrix.accessKeyIdSecretName', 'matrix.secretAccessKeySecretName', '${{ matrix.region }}', '${{ matrix.roleToAssume }}', '${{ matrix.assumeRoleDurationSeconds }}');
162
+ }
163
+ /**
164
+ * Step to assume an AWS role for a specific environment
165
+ * @param assumeRoleFlag Whether to assume a role, can be a boolean or a string for matrix strategy
166
+ * @param accessKeyIdSecretName The GitHub secret name for the access key ID
167
+ * @param secretAccessKeySecretName The GitHub secret name for the secret access key
168
+ * @param region The region
169
+ * @param roleToAssume The role to assume
170
+ * @param assumeRoleDurationSeconds The duration for assuming the role
171
+ * @returns JobStep or undefined if assumeRoleFlag is boolean and false
172
+ * if assumeRoleFlag is string will always return a JobStep (for matrix strategy)
173
+ */
174
+ getAssumeAwsRoleStepForEnvironment(assumeRoleFlag, accessKeyIdSecretName, secretAccessKeySecretName, region, roleToAssume, assumeRoleDurationSeconds) {
175
+ function getCondition(factory) {
176
+ if (typeof assumeRoleFlag === 'boolean') {
177
+ if (!assumeRoleFlag) {
178
+ return undefined;
179
+ }
180
+ return factory.props.checkActiveDeployment ? skipIfAlreadyActiveDeploymentCondition : undefined;
181
+ }
182
+ return factory.props.checkActiveDeployment ?
183
+ `\${{ ${assumeRoleFlag} == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
184
+ `\${{ ${assumeRoleFlag} == 'true' }}`;
185
+ }
186
+ if (typeof assumeRoleFlag === 'boolean' && !assumeRoleFlag) {
187
+ return undefined;
188
+ }
189
+ const condition = getCondition(this);
190
+ const secretsParams = this.props.authProvider === javascript_1.CodeArtifactAuthProvider.ACCESS_AND_SECRET_KEY_PAIR ?
191
+ {
192
+ 'aws-access-key-id': `\${{ secrets[${accessKeyIdSecretName}] }}`,
193
+ 'aws-secret-access-key': `\${{ secrets[${secretAccessKeySecretName}] }}`,
194
+ } : undefined;
195
+ return {
196
+ if: condition,
197
+ name: 'Assume AWS Role',
198
+ uses: 'aws-actions/configure-aws-credentials@v4',
199
+ with: {
200
+ ...secretsParams,
201
+ 'role-to-assume': roleToAssume,
202
+ 'aws-region': region,
203
+ 'role-duration-seconds': assumeRoleDurationSeconds,
204
+ },
205
+ };
206
+ }
207
+ /**
208
+ * Step to setup NPM config if provided
209
+ * @returns JobStep or undefined if no npmConfig is provided
210
+ */
211
+ get setupNpmConfigForMatrix() {
212
+ return this.getSetupNpmConfigForEnvironment('${{ matrix.environment }}');
213
+ }
214
+ getSetupNpmConfigForEnvironment(environment) {
215
+ const { npmConfigEnvironment } = this.props;
216
+ if (!npmConfigEnvironment) {
217
+ return undefined;
218
+ }
219
+ const environmentVariableName = 'CONFIG_VALUE';
220
+ return {
221
+ ...this.skipIfAlreadyActiveDeploymentCondition,
222
+ name: 'Setting NPM Config',
223
+ env: {
224
+ [environmentVariableName]: environment,
225
+ },
226
+ run: `npm config set ${npmConfigEnvironment} $${environmentVariableName}`,
227
+ };
228
+ }
229
+ /**
230
+ * Get the step to run a specific script
231
+ * @param scriptName The name of the script to run
232
+ * @param stepName The name of the step in the workflow
233
+ * @param hasScriptFlag Whether the script should be run
234
+ * @returns The job step to run the script or undefined if not applicable
235
+ * If hasScriptFlag is boolean and false will return undefined
236
+ * If hasScriptFlag is string will always return a JobStep (for matrix strategy)
237
+ */
238
+ getRunScriptStep(scriptName, stepName, hasScriptFlag) {
239
+ function getCondition(factory) {
240
+ if (typeof hasScriptFlag === 'boolean') {
241
+ if (!hasScriptFlag) {
242
+ return undefined;
243
+ }
244
+ return factory.props.checkActiveDeployment ? skipIfAlreadyActiveDeploymentCondition : undefined;
245
+ }
246
+ return factory.props.checkActiveDeployment ?
247
+ `\${{ ${hasScriptFlag} == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
248
+ `\${{ ${hasScriptFlag} == 'true' }}`;
249
+ }
250
+ if (typeof hasScriptFlag === 'boolean' && !hasScriptFlag) {
251
+ return undefined;
252
+ }
253
+ const condition = getCondition(this);
254
+ return {
255
+ if: condition,
256
+ name: `Run ${stepName}`,
257
+ run: `${this.project.runScriptCommand} ${scriptName}`,
258
+ };
259
+ }
260
+ /**
261
+ * Step to deploy the workflow
262
+ * @returns JobStep
263
+ */
264
+ get deploymentStep() {
265
+ return this.getRunScriptStep('deploy:workflow', 'Deployment', true);
266
+ }
267
+ /**
268
+ * Step to run post deployment script in matrix strategy
269
+ * @returns JobStep
270
+ */
271
+ get preDeploymentStepForMatrix() {
272
+ return this.getPreDeploymentStepForEnvironment('matrix.hasPreDeployTask', '${{ matrix.preDeploymentScript }}');
273
+ }
274
+ /**
275
+ * Get the pre-deployment step for a specific environment
276
+ * @param hasPreDeployTaskFlag Whether the pre-deployment task should be run
277
+ * @param preDeploymentScript The script to run
278
+ * @returns The job step to run the pre-deployment script or undefined if not applicable
279
+ * If hasPreDeployTaskFlag is boolean and false will return undefined
280
+ * If hasPreDeployTaskFlag is string will always return a JobStep (for matrix strategy)
281
+ */
282
+ getPreDeploymentStepForEnvironment(hasPreDeployTaskFlag, preDeploymentScript) {
283
+ return this.getRunScriptStep(preDeploymentScript, 'Pre Deployment', hasPreDeployTaskFlag);
284
+ }
285
+ /**
286
+ * Step to run post deployment script in matrix strategy
287
+ * @returns JobStep
288
+ */
289
+ get postDeploymentStepForMatrix() {
290
+ return this.getPostDeploymentStepForEnvironment('matrix.hasPostDeployTask', '${{ matrix.postDeploymentScript }}');
291
+ }
292
+ /**
293
+ * Get the post-deployment step for a specific environment
294
+ * @param hasPostDeployTaskFlag Whether the post-deployment task should be run
295
+ * @param postDeploymentScript The script to run
296
+ * @returns The job step to run the post-deployment script or undefined if not applicable
297
+ * If hasPostDeployTaskFlag is boolean and false will return undefined
298
+ * If hasPostDeployTaskFlag is string will always return a JobStep (for matrix strategy)
299
+ */
300
+ getPostDeploymentStepForEnvironment(hasPostDeployTaskFlag, postDeploymentScript) {
301
+ return this.getRunScriptStep(postDeploymentScript, 'Post Deployment', hasPostDeployTaskFlag);
302
+ }
303
+ /**
304
+ * Get all deployment jobs whether for matrix strategy or not
305
+ * @returns Record of jobs
306
+ */
307
+ get deploymentJobs() {
308
+ if (this.props.deployOptions.environments.length === 0) {
309
+ this.project.logger.warn('The project does not have any environment set, make sure this is desired setting');
310
+ }
311
+ return this.props.jobStrategy === types_1.DeployJobStrategy.MATRIX ? this.deploymentJobsForMatrix : this.getDeploymentJobsForMultiJob();
312
+ }
313
+ /**
314
+ * Get deployment jobs for matrix strategy
315
+ * @returns Record of jobs
316
+ */
317
+ get deploymentJobsForMatrix() {
318
+ const { environments, environmentVariableName } = this.props.deployOptions;
319
+ const include = environments.map(environmentOptions => {
320
+ const { awsCredentials } = environmentOptions;
321
+ const assumeRole = awsCredentials.roleToAssume ? 'true' : 'false';
322
+ const assumeRoleSettings = awsCredentials.roleToAssume ? {
323
+ roleToAssume: awsCredentials.roleToAssume,
324
+ assumeRoleDurationSeconds: awsCredentials.assumeRoleDurationSeconds || 900,
325
+ } : undefined;
326
+ const accessKeyIdSecretName = awsCredentials.accessKeyIdSecretName ?? 'AWS_ACCESS_KEY_ID';
327
+ const secretAccessKeySecretName = awsCredentials.secretAccessKeySecretName ?? 'AWS_SECRET_ACCESS_KEY';
328
+ const hasPostDeployTask = environmentOptions.postDeployWorkflowScript ? 'true' : 'false';
329
+ const hasPreDeployTask = environmentOptions.preDeployWorkflowScript ? 'true' : 'false';
330
+ return {
331
+ environment: environmentOptions.name,
332
+ accessKeyIdSecretName,
333
+ secretAccessKeySecretName,
334
+ region: awsCredentials.region,
335
+ assumeRole,
336
+ hasPostDeployTask,
337
+ postDeploymentScript: environmentOptions.postDeployWorkflowScript || '',
338
+ hasPreDeployTask,
339
+ preDeploymentScript: environmentOptions.preDeployWorkflowScript || '',
340
+ ...assumeRoleSettings,
341
+ };
342
+ });
343
+ const deployJobEnv = environmentVariableName ? {
344
+ [environmentVariableName]: '${{ matrix.environment }}',
89
345
  } : undefined;
90
- return {
91
- if: condition,
92
- name: 'Assume AWS Role',
93
- uses: 'aws-actions/configure-aws-credentials@v4',
94
- with: {
95
- ...secretsParams,
96
- 'role-to-assume': '${{ matrix.roleToAssume }}',
97
- 'aws-region': '${{ matrix.region }}',
98
- 'role-duration-seconds': '${{ matrix.assumeRoleDurationSeconds }}',
99
- },
100
- };
101
- }
102
- function setAwsCredentialsSteps(checkActiveDeployment, authProvider = javascript_1.CodeArtifactAuthProvider.ACCESS_AND_SECRET_KEY_PAIR) {
103
- return [
104
- setAwsCredentialsInEnvironment(checkActiveDeployment),
105
- assumeAwsRoleStep(checkActiveDeployment, authProvider),
106
- ];
107
- }
108
- function setNpmConfig(configName, configValue, checkActiveDeployment) {
109
- const environmentVariableName = 'CONFIG_VALUE';
110
- return {
111
- ...getSkipIfAlreadyActiveDeploymentCondition(checkActiveDeployment),
112
- name: 'Setting NPM Config',
113
- env: {
114
- [environmentVariableName]: configValue,
115
- },
116
- run: `npm config set ${configName} $${environmentVariableName}`,
117
- };
118
- }
119
- const checkActiveDeploymentStepId = 'deployment-check';
120
- function checkActiveDeploymentStep() {
121
- return {
122
- id: checkActiveDeploymentStepId,
123
- uses: 'AminFazlMondo/check-deployed-environment@v1',
124
- with: {
125
- environment: '${{ matrix.environment }}',
126
- },
127
- env: {
128
- GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}',
129
- },
130
- };
131
- }
132
- const skipIfAlreadyActiveDeploymentCondition = `steps.${checkActiveDeploymentStepId}.outputs.has_active_deployment != 'true'`;
133
- function getSkipIfAlreadyActiveDeploymentCondition(checkActiveDeployment) {
134
- return checkActiveDeployment ? { if: `\${{ ${skipIfAlreadyActiveDeploymentCondition} }}` } : undefined;
135
- }
136
- function postDeploymentStep(checkActiveDeployment, packageManager) {
137
- const condition = checkActiveDeployment ?
138
- `\${{ matrix.hasPostDeployTask == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
139
- '${{ matrix.hasPostDeployTask == \'true\' }}';
140
- return {
141
- if: condition,
142
- name: 'Post Deployment',
143
- run: `${getPackageManagerCommandPrefix(packageManager)} \${{ matrix.postDeploymentScript }}`,
144
- };
145
- }
146
- function preDeploymentStep(checkActiveDeployment, packageManager) {
147
- const condition = checkActiveDeployment ?
148
- `\${{ matrix.hasPreDeployTask == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
149
- '${{ matrix.hasPreDeployTask == \'true\' }}';
150
- return {
151
- if: condition,
152
- name: 'Pre Deployment',
153
- run: `${getPackageManagerCommandPrefix(packageManager)} \${{ matrix.preDeploymentScript }}`,
154
- };
346
+ const jobDefinition = {
347
+ runsOn: ['ubuntu-latest'],
348
+ concurrency: {
349
+ 'group': '${{ matrix.environment }}-deploy',
350
+ 'cancel-in-progress': false,
351
+ },
352
+ needs: [
353
+ 'release_github',
354
+ ],
355
+ permissions: {
356
+ contents: workflows_model_1.JobPermission.READ,
357
+ deployments: workflows_model_1.JobPermission.READ,
358
+ idToken: this.props.authProvider === javascript_1.CodeArtifactAuthProvider.GITHUB_OIDC ? workflows_model_1.JobPermission.WRITE : undefined,
359
+ },
360
+ strategy: {
361
+ maxParallel: 1,
362
+ matrix: {
363
+ domain: {
364
+ environment: include.map(e => e.environment),
365
+ },
366
+ include,
367
+ },
368
+ },
369
+ environment: {
370
+ name: '${{ matrix.environment }}',
371
+ },
372
+ env: deployJobEnv,
373
+ steps: [],
374
+ };
375
+ jobDefinition.steps.push(this.checkoutStep);
376
+ const preInstallDependenciesStep = this.preInstallDependenciesStep;
377
+ if (preInstallDependenciesStep) {
378
+ jobDefinition.steps.push(preInstallDependenciesStep);
379
+ }
380
+ jobDefinition.steps.push(...(this.project).renderWorkflowSetup());
381
+ const checkActiveDeploymentStepForMatrix = this.checkActiveDeploymentStepForMatrix;
382
+ if (checkActiveDeploymentStepForMatrix) {
383
+ jobDefinition.steps.push(checkActiveDeploymentStepForMatrix);
384
+ }
385
+ jobDefinition.steps.push(...this.setupAwsCredentialsStepsForMatrix);
386
+ const setupNpmConfigStep = this.setupNpmConfigForMatrix;
387
+ if (setupNpmConfigStep) {
388
+ jobDefinition.steps.push(setupNpmConfigStep);
389
+ }
390
+ jobDefinition.steps.push(this.preDeploymentStepForMatrix);
391
+ jobDefinition.steps.push(this.deploymentStep);
392
+ jobDefinition.steps.push(this.postDeploymentStepForMatrix);
393
+ return { deploy: jobDefinition };
394
+ }
395
+ /**
396
+ * Get the IDs of the jobs that must be completed before the specified environment's deployment job
397
+ * @param environmentName The name of the environment
398
+ * @returns An array of job IDs
399
+ */
400
+ getDeploymentJobPrerequisiteJobIds(environmentName) {
401
+ const result = ['release_github'];
402
+ const index = this.props.deployOptions.environments.findIndex(env => env.name === environmentName);
403
+ const prerequisiteEnvironment = index > 0 ? this.props.deployOptions.environments[index - 1] : undefined;
404
+ if (prerequisiteEnvironment) {
405
+ result.push(getDeployJobId(prerequisiteEnvironment.name));
406
+ }
407
+ return result;
408
+ }
409
+ /**
410
+ * Get deployment jobs for multi-job strategy
411
+ * @returns Record of jobs
412
+ */
413
+ getDeploymentJobsForMultiJob() {
414
+ const { environmentVariableName, environments } = this.props.deployOptions;
415
+ const jobs = environments.map((environmentOptions) => {
416
+ return [getDeployJobId(environmentOptions.name), this.getJobForEnvironment(environmentOptions, environmentVariableName)];
417
+ });
418
+ return Object.fromEntries(jobs);
419
+ }
420
+ /**
421
+ * Get the job definition for a specific environment
422
+ * @param environmentOptions The environment options
423
+ * @param environmentVariableName The name of the environment variable to set with the environment name, if any
424
+ * @returns The job definition for the environment
425
+ */
426
+ getJobForEnvironment(environmentOptions, environmentVariableName) {
427
+ const { name } = environmentOptions;
428
+ const deployJobEnv = environmentVariableName ? {
429
+ [environmentVariableName]: name,
430
+ } : undefined;
431
+ const jobDefinition = {
432
+ runsOn: ['ubuntu-latest'],
433
+ concurrency: {
434
+ 'group': `${name}-deploy`,
435
+ 'cancel-in-progress': false,
436
+ },
437
+ needs: this.getDeploymentJobPrerequisiteJobIds(name),
438
+ permissions: {
439
+ contents: workflows_model_1.JobPermission.READ,
440
+ deployments: workflows_model_1.JobPermission.READ,
441
+ idToken: this.props.authProvider === javascript_1.CodeArtifactAuthProvider.GITHUB_OIDC ? workflows_model_1.JobPermission.WRITE : undefined,
442
+ },
443
+ environment: {
444
+ name: name,
445
+ },
446
+ env: deployJobEnv,
447
+ steps: [],
448
+ };
449
+ jobDefinition.steps.push(this.checkoutStep);
450
+ const preInstallDependenciesStep = this.preInstallDependenciesStep;
451
+ if (preInstallDependenciesStep) {
452
+ jobDefinition.steps.push(preInstallDependenciesStep);
453
+ }
454
+ jobDefinition.steps.push(...(this.project).renderWorkflowSetup());
455
+ const checkActiveDeploymentStep = this.getCheckActiveDeploymentStepForEnvironment(name);
456
+ if (checkActiveDeploymentStep) {
457
+ jobDefinition.steps.push(checkActiveDeploymentStep);
458
+ }
459
+ jobDefinition.steps.push(...this.getSetupAwsCredentialsStepsForEnvironment(environmentOptions));
460
+ const setupNpmConfigStep = this.getSetupNpmConfigForEnvironment(name);
461
+ if (setupNpmConfigStep) {
462
+ jobDefinition.steps.push(setupNpmConfigStep);
463
+ }
464
+ const preDeploymentStep = this.getPreDeploymentStepForEnvironment(environmentOptions.preDeployWorkflowScript ? true : false, environmentOptions.preDeployWorkflowScript || '');
465
+ if (preDeploymentStep) {
466
+ jobDefinition.steps.push(preDeploymentStep);
467
+ }
468
+ jobDefinition.steps.push(this.deploymentStep);
469
+ const postDeploymentStep = this.getPostDeploymentStepForEnvironment(environmentOptions.postDeployWorkflowScript ? true : false, environmentOptions.postDeployWorkflowScript || '');
470
+ if (postDeploymentStep) {
471
+ jobDefinition.steps.push(postDeploymentStep);
472
+ }
473
+ return jobDefinition;
474
+ }
155
475
  }
156
- function preInstallDependenciesStep(taskName, checkActiveDeployment) {
157
- return {
158
- ...getSkipIfAlreadyActiveDeploymentCondition(checkActiveDeployment),
159
- name: taskName,
160
- run: `npx projen ${taskName}`,
161
- };
476
+ exports.DeployableAwsCdkTypeScriptAppStepsFactory = DeployableAwsCdkTypeScriptAppStepsFactory;
477
+ function getDeployJobId(environmentName) {
478
+ return `Deploy-${environmentName}`;
162
479
  }
163
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3RlcHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFJQSxvQ0FTQztBQUVELGdEQVNDO0FBRUQsMERBTUM7QUFZRCx3Q0FPQztBQW1ERCx3REFRQztBQUVELG9DQVVDO0FBR0QsOERBV0M7QUFRRCxnREFVQztBQUVELDhDQVVDO0FBRUQsZ0VBTUM7QUE5S0QsbUNBQW9DO0FBRXBDLHNEQUFpRTtBQUVqRSxTQUFnQixZQUFZO0lBQzFCLE9BQU87UUFDTCxJQUFJLEVBQUUsVUFBVTtRQUNoQixJQUFJLEVBQUUscUJBQXFCO1FBQzNCLElBQUksRUFBRTtZQUNKLEtBQUssRUFBRSxtQkFBbUI7WUFDMUIsYUFBYSxFQUFFLENBQUM7U0FDakI7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQWdCLGtCQUFrQixDQUFDLFdBQW1CLEVBQUUscUJBQThCO0lBQ3BGLE9BQU87UUFDTCxHQUFHLHlDQUF5QyxDQUFDLHFCQUFxQixDQUFDO1FBQ25FLElBQUksRUFBRSxlQUFlO1FBQ3JCLElBQUksRUFBRSx1QkFBdUI7UUFDN0IsSUFBSSxFQUFFO1lBQ0osY0FBYyxFQUFFLFdBQVc7U0FDNUI7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQWdCLHVCQUF1QixDQUFDLE9BQWUsRUFBRSxxQkFBOEI7SUFDckYsT0FBTztRQUNMLEdBQUcseUNBQXlDLENBQUMscUJBQXFCLENBQUM7UUFDbkUsSUFBSSxFQUFFLHNCQUFzQjtRQUM1QixHQUFHLEVBQUUsT0FBTztLQUNiLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyw4QkFBOEIsQ0FBQyxjQUE2QztJQUNuRixJQUFJLGNBQWMsS0FBSyxtQkFBVSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQUEsT0FBTyxTQUFTLENBQUM7SUFBQSxDQUFDO0lBRTdFLElBQUksY0FBYyxLQUFLLG1CQUFVLENBQUMsa0JBQWtCLENBQUMsSUFB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QUksRUFBRSxRQUFRO1FBQ2QsR0FBRyxFQUFFLGNBQWMsUUFBUSxFQUFFO0tBQzlCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgamF2YXNjcmlwdCB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBKb2JTdGVwIH0gZnJvbSAncHJvamVuL2xpYi9naXRodWIvd29ya2Zsb3dzLW1vZGVsJztcbmltcG9ydCB7IENvZGVBcnRpZmFjdEF1dGhQcm92aWRlciB9IGZyb20gJ3Byb2plbi9saWIvamF2YXNjcmlwdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGVja291dFN0ZXAoKTogSm9iU3RlcCB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0NoZWNrb3V0JyxcbiAgICB1c2VzOiAnYWN0aW9ucy9jaGVja291dEB2NCcsXG4gICAgd2l0aDoge1xuICAgICAgJ3JlZic6ICcke3sgZ2l0aHViLnNoYSB9fScsXG4gICAgICAnZmV0Y2gtZGVwdGgnOiAwLFxuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXROb2RlVmVyc2lvblN0ZXAobm9kZVZlcnNpb246IHN0cmluZywgY2hlY2tBY3RpdmVEZXBsb3ltZW50OiBib29sZWFuKTogSm9iU3RlcCB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0U2tpcElmQWxyZWFkeUFjdGl2ZURlcGxveW1lbnRDb25kaXRpb24oY2hlY2tBY3RpdmVEZXBsb3ltZW50KSxcbiAgICBuYW1lOiAnU2V0dXAgTm9kZS5qcycsXG4gICAgdXNlczogJ2FjdGlvbnMvc2V0dXAtbm9kZUB2NCcsXG4gICAgd2l0aDoge1xuICAgICAgJ25vZGUtdmVyc2lvbic6IG5vZGVWZXJzaW9uLFxuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsRGVwZW5kZW5jaWVzU3RlcChjb21tYW5kOiBzdHJpbmcsIGNoZWNrQWN0aXZlRGVwbG95bWVudDogYm9vbGVhbik6IEpvYlN0ZXAge1xuICByZXR1cm4ge1xuICAgIC4uLmdldFNraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9uKGNoZWNrQWN0aXZlRGVwbG95bWVudCksXG4gICAgbmFtZTogJ0luc3RhbGwgZGVwZW5kZW5jaWVzJyxcbiAgICBydW46IGNvbW1hbmQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFBhY2thZ2VNYW5hZ2VyQ29tbWFuZFByZWZpeChwYWNrYWdlTWFuYWdlcjogamF2YXNjcmlwdC5Ob2RlUGFja2FnZU1hbmFnZXIpOiBzdHJpbmcge1xuICBpZiAocGFja2FnZU1hbmFnZXIgPT09IGphdmFzY3JpcHQuTm9kZVBhY2thZ2VNYW5hZ2VyLk5QTSkge3JldHVybiAnbnBtIHJ1bic7fVxuXG4gIGlmIChwYWNrYWdlTWFuYWdlciA9PT0gamF2YXNjcmlwdC5Ob2RlUGFja2FnZU1hbmFnZXIuWUFSTikge3JldHVybiAneWFybic7fVxuXG4gIGlmIChwYWNrYWdlTWFuYWdlciA9PT0gamF2YXNjcmlwdC5Ob2RlUGFja2FnZU1hbmFnZXIuUE5QTSkge3JldHVybiAncG5wbSc7fVxuXG4gIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwYWNrYWdlIG1hbmFnZXIgc2VsZWN0ZWQgKCR7cGFja2FnZU1hbmFnZXJ9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVwbG95bWVudFN0ZXAoY2hlY2tBY3RpdmVEZXBsb3ltZW50OiBib29sZWFuLCBwYWNrYWdlTWFuYWdlcjogamF2YXNjcmlwdC5Ob2RlUGFja2FnZU1hbmFnZXIpOiBKb2JTdGVwIHtcblxuICByZXR1cm4ge1xuICAgIC4uLmdldFNraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9uKGNoZWNrQWN0aXZlRGVwbG95bWVudCksXG4gICAgbmFtZTogJ0RlcGxveW1lbnQnLFxuICAgIHJ1bjogYCR7Z2V0UGFja2FnZU1hbmFnZXJDb21tYW5kUHJlZml4KHBhY2thZ2VNYW5hZ2VyKX0gZGVwbG95OndvcmtmbG93YCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2V0QXdzQ3JlZGVudGlhbHNJbkVudmlyb25tZW50KGNoZWNrQWN0aXZlRGVwbG95bWVudDogYm9vbGVhbik6IEpvYlN0ZXAge1xuICBjb25zdCBjb21tYW5kcyA9IFtcbiAgICAnZWNobyBcIkFXU19BQ0NFU1NfS0VZX0lEPSRhY2Nlc3NLZXlJZFwiID4+ICRHSVRIVUJfRU5WJyxcbiAgICAnZWNobyBcIkFXU19TRUNSRVRfQUNDRVNTX0tFWT0kc2VjcmV0QWNjZXNzS2V5XCIgPj4gJEdJVEhVQl9FTlYnLFxuICAgICdlY2hvIFwiQVdTX1JFR0lPTj0kcmVnaW9uXCIgPj4gJEdJVEhVQl9FTlYnLFxuICBdO1xuXG4gIGNvbnN0IGNvbmRpdGlvbiA9XG4gICAgY2hlY2tBY3RpdmVEZXBsb3ltZW50ID9cbiAgICAgIGBcXCR7eyBtYXRyaXguYXNzdW1lUm9sZSA9PSAnZmFsc2UnICYmICR7c2tpcElmQWxyZWFkeUFjdGl2ZURlcGxveW1lbnRDb25kaXRpb259IH19YCA6XG4gICAgICAnJHt7IG1hdHJpeC5hc3N1bWVSb2xlID09IFxcJ2ZhbHNlXFwnIH19JztcblxuICByZXR1cm4ge1xuICAgIGlmOiBjb25kaXRpb24sXG4gICAgbmFtZTogJ0NvbmZpZ3VyZSBBV1MgQ3JlZGVudGlhbHMnLFxuICAgIHJ1bjogYCR7Y29tbWFuZHMuam9pbignXFxuJyl9YCxcbiAgICBlbnY6IHtcbiAgICAgIGFjY2Vzc0tleUlkOiAnJHt7IHNlY3JldHNbbWF0cml4LmFjY2Vzc0tleUlkU2VjcmV0TmFtZV0gfX0nLFxuICAgICAgc2VjcmV0QWNjZXNzS2V5OiAnJHt7IHNlY3JldHNbbWF0cml4LnNlY3JldEFjY2Vzc0tleVNlY3JldE5hbWVdIH19JyxcbiAgICAgIHJlZ2lvbjogJyR7eyBtYXRyaXgucmVnaW9uIH19JyxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBhc3N1bWVBd3NSb2xlU3RlcChjaGVja0FjdGl2ZURlcGxveW1lbnQ6IGJvb2xlYW4sIGF1dGhQcm92aWRlcjogQ29kZUFydGlmYWN0QXV0aFByb3ZpZGVyKTogSm9iU3RlcCB7XG4gIGNvbnN0IGNvbmRpdGlvbiA9XG4gICAgY2hlY2tBY3RpdmVEZXBsb3ltZW50ID9cbiAgICAgIGBcXCR7eyBtYXRyaXguYXNzdW1lUm9sZSA9PSAndHJ1ZScgJiYgJHtza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbn0gfX1gIDpcbiAgICAgICcke3sgbWF0cml4LmFzc3VtZVJvbGUgPT0gXFwndHJ1ZVxcJyB9fSc7XG5cbiAgY29uc3Qgc2VjcmV0c1BhcmFtcyA9XG4gICAgYXV0aFByb3ZpZGVyID09PSBDb2RlQXJ0aWZhY3RBdXRoUHJvdmlkZXIuQUNDRVNTX0FORF9TRUNSRVRfS0VZX1BBSVIgP1xuICAgICAge1xuICAgICAgICAnYXdzLWFjY2Vzcy1rZXktaWQnOiAnJHt7IHNlY3JldHNbbWF0cml4LmFjY2Vzc0tleUlkU2VjcmV0TmFtZV0gfX0nLFxuICAgICAgICAnYXdzLXNlY3JldC1hY2Nlc3Mta2V5JzogJyR7eyBzZWNyZXRzW21hdHJpeC5zZWNyZXRBY2Nlc3NLZXlTZWNyZXROYW1lXSB9fScsXG4gICAgICB9IDogdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIGlmOiBjb25kaXRpb24sXG4gICAgbmFtZTogJ0Fzc3VtZSBBV1MgUm9sZScsXG4gICAgdXNlczogJ2F3cy1hY3Rpb25zL2NvbmZpZ3VyZS1hd3MtY3JlZGVudGlhbHNAdjQnLFxuICAgIHdpdGg6IHtcbiAgICAgIC4uLnNlY3JldHNQYXJhbXMsXG4gICAgICAncm9sZS10by1hc3N1bWUnOiAnJHt7IG1hdHJpeC5yb2xlVG9Bc3N1bWUgfX0nLFxuICAgICAgJ2F3cy1yZWdpb24nOiAnJHt7IG1hdHJpeC5yZWdpb24gfX0nLFxuICAgICAgJ3JvbGUtZHVyYXRpb24tc2Vjb25kcyc6ICcke3sgbWF0cml4LmFzc3VtZVJvbGVEdXJhdGlvblNlY29uZHMgfX0nLFxuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRBd3NDcmVkZW50aWFsc1N0ZXBzKFxuICBjaGVja0FjdGl2ZURlcGxveW1lbnQ6IGJvb2xlYW4sXG4gIGF1dGhQcm92aWRlcjogQ29kZUFydGlmYWN0QXV0aFByb3ZpZGVyID0gQ29kZUFydGlmYWN0QXV0aFByb3ZpZGVyLkFDQ0VTU19BTkRfU0VDUkVUX0tFWV9QQUlSKVxuICA6IEpvYlN0ZXBbXSB7XG4gIHJldHVybiBbXG4gICAgc2V0QXdzQ3JlZGVudGlhbHNJbkVudmlyb25tZW50KGNoZWNrQWN0aXZlRGVwbG95bWVudCksXG4gICAgYXNzdW1lQXdzUm9sZVN0ZXAoY2hlY2tBY3RpdmVEZXBsb3ltZW50LCBhdXRoUHJvdmlkZXIpLFxuICBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0TnBtQ29uZmlnKGNvbmZpZ05hbWU6IHN0cmluZywgY29uZmlnVmFsdWU6IHN0cmluZywgY2hlY2tBY3RpdmVEZXBsb3ltZW50OiBib29sZWFuKTogSm9iU3RlcCB7XG4gIGNvbnN0IGVudmlyb25tZW50VmFyaWFibGVOYW1lID0gJ0NPTkZJR19WQUxVRSc7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0U2tpcElmQWxyZWFkeUFjdGl2ZURlcGxveW1lbnRDb25kaXRpb24oY2hlY2tBY3RpdmVEZXBsb3ltZW50KSxcbiAgICBuYW1lOiAnU2V0dGluZyBOUE0gQ29uZmlnJyxcbiAgICBlbnY6IHtcbiAgICAgIFtlbnZpcm9ubWVudFZhcmlhYmxlTmFtZV06IGNvbmZpZ1ZhbHVlLFxuICAgIH0sXG4gICAgcnVuOiBgbnBtIGNvbmZpZyBzZXQgJHtjb25maWdOYW1lfSAkJHtlbnZpcm9ubWVudFZhcmlhYmxlTmFtZX1gLFxuICB9O1xufVxuXG5jb25zdCBjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwSWQgPSAnZGVwbG95bWVudC1jaGVjayc7XG5leHBvcnQgZnVuY3Rpb24gY2hlY2tBY3RpdmVEZXBsb3ltZW50U3RlcCgpOiBKb2JTdGVwIHtcbiAgcmV0dXJuIHtcbiAgICBpZDogY2hlY2tBY3RpdmVEZXBsb3ltZW50U3RlcElkLFxuICAgIHVzZXM6ICdBbWluRmF6bE1vbmRvL2NoZWNrLWRlcGxveWVkLWVudmlyb25tZW50QHYxJyxcbiAgICB3aXRoOiB7XG4gICAgICBlbnZpcm9ubWVudDogJyR7eyBtYXRyaXguZW52aXJvbm1lbnQgfX0nLFxuICAgIH0sXG4gICAgZW52OiB7XG4gICAgICBHSVRIVUJfVE9LRU46ICcke3sgc2VjcmV0cy5HSVRIVUJfVE9LRU4gfX0nLFxuICAgIH0sXG4gIH07XG59XG5cbmNvbnN0IHNraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9uPSBgc3RlcHMuJHtjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwSWR9Lm91dHB1dHMuaGFzX2FjdGl2ZV9kZXBsb3ltZW50ICE9ICd0cnVlJ2A7XG5cbmZ1bmN0aW9uIGdldFNraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9uKGNoZWNrQWN0aXZlRGVwbG95bWVudDogYm9vbGVhbik6IEpvYlN0ZXAgfCB1bmRlZmluZWQge1xuICByZXR1cm4gY2hlY2tBY3RpdmVEZXBsb3ltZW50ID8geyBpZjogYFxcJHt7ICR7c2tpcElmQWxyZWFkeUFjdGl2ZURlcGxveW1lbnRDb25kaXRpb259IH19YCB9IDogdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcG9zdERlcGxveW1lbnRTdGVwKGNoZWNrQWN0aXZlRGVwbG95bWVudDogYm9vbGVhbiwgcGFja2FnZU1hbmFnZXI6IGphdmFzY3JpcHQuTm9kZVBhY2thZ2VNYW5hZ2VyKTogSm9iU3RlcCB7XG4gIGNvbnN0IGNvbmRpdGlvbiA9XG4gIGNoZWNrQWN0aXZlRGVwbG95bWVudCA/XG4gICAgYFxcJHt7IG1hdHJpeC5oYXNQb3N0RGVwbG95VGFzayA9PSAndHJ1ZScgJiYgJHtza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbn0gfX1gIDpcbiAgICAnJHt7IG1hdHJpeC5oYXNQb3N0RGVwbG95VGFzayA9PSBcXCd0cnVlXFwnIH19JztcbiAgcmV0dXJuIHtcbiAgICBpZjogY29uZGl0aW9uLFxuICAgIG5hbWU6ICdQb3N0IERlcGxveW1lbnQnLFxuICAgIHJ1bjogYCR7Z2V0UGFja2FnZU1hbmFnZXJDb21tYW5kUHJlZml4KHBhY2thZ2VNYW5hZ2VyKX0gXFwke3sgbWF0cml4LnBvc3REZXBsb3ltZW50U2NyaXB0IH19YCxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByZURlcGxveW1lbnRTdGVwKGNoZWNrQWN0aXZlRGVwbG95bWVudDogYm9vbGVhbiwgcGFja2FnZU1hbmFnZXI6IGphdmFzY3JpcHQuTm9kZVBhY2thZ2VNYW5hZ2VyKTogSm9iU3RlcCB7XG4gIGNvbnN0IGNvbmRpdGlvbiA9XG4gIGNoZWNrQWN0aXZlRGVwbG95bWVudCA/XG4gICAgYFxcJHt7IG1hdHJpeC5oYXNQcmVEZXBsb3lUYXNrID09ICd0cnVlJyAmJiAke3NraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9ufSB9fWAgOlxuICAgICcke3sgbWF0cml4Lmhhc1ByZURlcGxveVRhc2sgPT0gXFwndHJ1ZVxcJyB9fSc7XG4gIHJldHVybiB7XG4gICAgaWY6IGNvbmRpdGlvbixcbiAgICBuYW1lOiAnUHJlIERlcGxveW1lbnQnLFxuICAgIHJ1bjogYCR7Z2V0UGFja2FnZU1hbmFnZXJDb21tYW5kUHJlZml4KHBhY2thZ2VNYW5hZ2VyKX0gXFwke3sgbWF0cml4LnByZURlcGxveW1lbnRTY3JpcHQgfX1gLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJlSW5zdGFsbERlcGVuZGVuY2llc1N0ZXAodGFza05hbWU6IHN0cmluZywgY2hlY2tBY3RpdmVEZXBsb3ltZW50OiBib29sZWFuKTogSm9iU3RlcCB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0U2tpcElmQWxyZWFkeUFjdGl2ZURlcGxveW1lbnRDb25kaXRpb24oY2hlY2tBY3RpdmVEZXBsb3ltZW50KSxcbiAgICBuYW1lOiB0YXNrTmFtZSxcbiAgICBydW46IGBucHggcHJvamVuICR7dGFza05hbWV9YCxcbiAgfTtcbn0iXX0=
480
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3RlcHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsOENBQWtEO0FBQ2xELHVFQUFnRjtBQUNoRixzREFBaUU7QUFDakUsbUNBQStFO0FBRS9FLE1BQU0sMkJBQTJCLEdBQUcsa0JBQWtCLENBQUM7QUFDdkQsTUFBTSxzQ0FBc0MsR0FBRSxTQUFTLDJCQUEyQiwwQ0FBMEMsQ0FBQztBQW1DN0g7OztHQUdHO0FBQ0gsTUFBYSx5Q0FBeUM7SUFDcEQ7Ozs7T0FJRztJQUNILFlBQ21CLE9BQStCLEVBQy9CLEtBQXFEO1FBRHJELFlBQU8sR0FBUCxPQUFPLENBQXdCO1FBQy9CLFVBQUssR0FBTCxLQUFLLENBQWdEO0lBQ3JFLENBQUM7SUFFSjs7O09BR0c7SUFDSCxJQUFXLHNDQUFzQztRQUMvQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLFFBQVEsc0NBQXNDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDcEgsQ0FBQztJQUVELElBQVcsWUFBWTtRQUNyQixPQUFPLHNCQUFhLENBQUMsUUFBUSxDQUFDO1lBQzVCLElBQUksRUFBRTtnQkFDSixVQUFVLEVBQUUsQ0FBQztnQkFDYixHQUFHLEVBQUUsbUJBQW1CO2FBQ3pCO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQVcsMEJBQTBCO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDbkMsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU87WUFDTCxHQUFHLElBQUksQ0FBQyxzQ0FBc0M7WUFDOUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO1lBQ25DLEdBQUcsRUFBRSxjQUFjLElBQUksQ0FBQyxLQUFLLENB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QixJQUFJLEVBQUUsQ0FDbEQsQ0FBQztRQUNGLElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUN2QixhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0NBRUY7QUFqbUJELDhGQWltQkM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxlQUF1QjtJQUM3QyxPQUFPLFVBQVUsZUFBZSxFQUFFLENBQUM7QUFDckMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGphdmFzY3JpcHQgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgV29ya2Zsb3dTdGVwcyB9IGZyb20gJ3Byb2plbi9saWIvZ2l0aHViJztcbmltcG9ydCB7IEpvYlBlcm1pc3Npb24sIEpvYlN0ZXAsIEpvYiB9IGZyb20gJ3Byb2plbi9saWIvZ2l0aHViL3dvcmtmbG93cy1tb2RlbCc7XG5pbXBvcnQgeyBDb2RlQXJ0aWZhY3RBdXRoUHJvdmlkZXIgfSBmcm9tICdwcm9qZW4vbGliL2phdmFzY3JpcHQnO1xuaW1wb3J0IHsgRGVwbG95Sm9iU3RyYXRlZ3ksIERlcGxveU9wdGlvbnMsIEVudmlyb25tZW50T3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwSWQgPSAnZGVwbG95bWVudC1jaGVjayc7XG5jb25zdCBza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbj0gYHN0ZXBzLiR7Y2hlY2tBY3RpdmVEZXBsb3ltZW50U3RlcElkfS5vdXRwdXRzLmhhc19hY3RpdmVfZGVwbG95bWVudCAhPSAndHJ1ZSdgO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlcGxveWFibGVBd3NDZGtUeXBlU2NyaXB0QXBwU3RlcHNGYWN0b3J5UHJvcHMge1xuICAvKipcbiAgICogRGVwbG95bWVudCBvcHRpb25zXG4gICAqL1xuICByZWFkb25seSBkZXBsb3lPcHRpb25zOiBEZXBsb3lPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNoZWNrIGZvciBhY3RpdmUgZGVwbG95bWVudHMgYmVmb3JlIHByb2NlZWRpbmcgd2l0aCBkZXBsb3ltZW50XG4gICAqL1xuICByZWFkb25seSBjaGVja0FjdGl2ZURlcGxveW1lbnQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB0YXNrIHRvIHJ1biBiZWZvcmUgaW5zdGFsbGluZyBkZXBlbmRlbmNpZXMsIGlmIGFueVxuICAgKi9cbiAgcmVhZG9ubHkgcHJlSW5zdGFsbFRhc2tOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYXV0aGVudGljYXRpb24gcHJvdmlkZXIgZm9yIENvZGVBcnRpZmFjdCwgaWYgYW55XG4gICAqL1xuICByZWFkb25seSBhdXRoUHJvdmlkZXI/OiBDb2RlQXJ0aWZhY3RBdXRoUHJvdmlkZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBucG0gY29uZmlnIHRvIHNldCB3aXRoIHRoZSBlbnZpcm9ubWVudCB0aGF0IGlzIGJlaW5nIGRlcGxveWVkLCBpZiBhbnlcbiAgICogTm90ZTogVGhpcyBpcyBub3Qgc3VwcG9ydGVkIGZvciBub2RlIHZlcnNpb25zIGFib3ZlIDE4XG4gICAqL1xuICByZWFkb25seSBucG1Db25maWdFbnZpcm9ubWVudD86IHN0cmluZztcblxuICAvKipcbiAgICogRGVwbG95bWVudCBqb2Igc3RyYXRlZ3ksIHdoZXRoZXIgdG8gdXNlIGEgbWF0cml4IGpvYiBvciBtdWx0aXBsZSBqb2JzIGZvciBlYWNoIGVudmlyb25tZW50XG4gICAqL1xuICByZWFkb25seSBqb2JTdHJhdGVneTogRGVwbG95Sm9iU3RyYXRlZ3k7XG59XG5cbi8qKlxuICogRmFjdG9yeSB0byBjcmVhdGUgcmV1c2FibGUgc3RlcHMgZm9yIHRoZSBkZXBsb3ltZW50IHdvcmtmbG93XG4gKiBAZXhwZXJpbWVudGFsXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXBsb3lhYmxlQXdzQ2RrVHlwZVNjcmlwdEFwcFN0ZXBzRmFjdG9yeSB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgRGVwbG95YWJsZUF3c0Nka1R5cGVTY3JpcHRBcHBTdGVwc0ZhY3RvcnlcbiAgICogQHBhcmFtIHByb2plY3QgVGhlIHByb2plY3RcbiAgICogQHBhcmFtIHByb3BzIFRoZSBmYWN0b3J5IHByb3BlcnRpZXNcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJvamVjdDogamF2YXNjcmlwdC5Ob2RlUHJvamVjdCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBEZXBsb3lhYmxlQXdzQ2RrVHlwZVNjcmlwdEFwcFN0ZXBzRmFjdG9yeVByb3BzLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIENvbmRpdGlvbiB0byBza2lwIGEgc3RlcCBpZiBhbiBhY3RpdmUgZGVwbG95bWVudCBpcyBhbHJlYWR5IHByZXNlbnRcbiAgICogQHJldHVybnMgSm9iU3RlcCBjb25kaXRpb24gb3IgdW5kZWZpbmVkIGlmIGNoZWNrQWN0aXZlRGVwbG95bWVudCBpcyBmYWxzZVxuICAgKi9cbiAgcHVibGljIGdldCBza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbigpOiBKb2JTdGVwIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGVja0FjdGl2ZURlcGxveW1lbnQgPyB7IGlmOiBgXFwke3sgJHtza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbn0gfX1gIH0gOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGNoZWNrb3V0U3RlcCgpOiBKb2JTdGVwIHtcbiAgICByZXR1cm4gV29ya2Zsb3dTdGVwcy5jaGVja291dCh7XG4gICAgICB3aXRoOiB7XG4gICAgICAgIGZldGNoRGVwdGg6IDAsXG4gICAgICAgIHJlZjogJyR7eyBnaXRodWIuc2hhIH19JyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RlcCB0byBydW4gYmVmb3JlIGluc3RhbGxpbmcgZGVwZW5kZW5jaWVzIGlmIGV4aXN0c1xuICAgKiBAcmV0dXJucyBKb2JTdGVwIG9yIHVuZGVmaW5lZCBpZiBubyBwcmVJbnN0YWxsVGFza05hbWUgaXMgcHJvdmlkZWRcbiAgICovXG4gIHB1YmxpYyBnZXQgcHJlSW5zdGFsbERlcGVuZGVuY2llc1N0ZXAoKTogSm9iU3RlcCB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLnByb3BzLnByZUluc3RhbGxUYXNrTmFtZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5za2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbixcbiAgICAgIG5hbWU6IHRoaXMucHJvcHMucHJlSW5zdGFsbFRhc2tOYW1lLFxuICAgICAgcnVuOiBgbnB4IHByb2plbiAke3RoaXMucHJvcHMucHJlSW5zdGFsbFRhc2tOYW1lfWAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGVwIHRvIGNoZWNrIGlmIHRoZXJlIGlzIGFuIGFjdGl2ZSBkZXBsb3ltZW50IGZvciB0aGUgZW52aXJvbm1lbnQgaW4gdGhlIG1hdHJpeCBzdHJhdGVneVxuICAgKiBAcmV0dXJucyBKb2JTdGVwXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNoZWNrQWN0aXZlRGVwbG95bWVudFN0ZXBGb3JNYXRyaXgoKTogSm9iU3RlcCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2hlY2tBY3RpdmVEZXBsb3ltZW50U3RlcEZvckVudmlyb25tZW50KCcke3sgbWF0cml4LmVudmlyb25tZW50IH19Jyk7XG4gIH1cblxuICAvKipcbiAgICogU3RlcCB0byBjaGVjayBpZiB0aGVyZSBpcyBhbiBhY3RpdmUgZGVwbG95bWVudCBmb3IgYSBzcGVjaWZpYyBlbnZpcm9ubWVudFxuICAgKiBAcGFyYW0gZW52aXJvbm1lbnQgVGhlIGVudmlyb25tZW50IHRvIGNoZWNrXG4gICAqIEByZXR1cm5zIEpvYlN0ZXBcbiAgICovXG4gIHB1YmxpYyBnZXRDaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwRm9yRW52aXJvbm1lbnQoZW52aXJvbm1lbnQ6IHN0cmluZyk6IEpvYlN0ZXAgfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5wcm9wcy5jaGVja0FjdGl2ZURlcGxveW1lbnQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwSWQsXG4gICAgICB1c2VzOiAnQW1pbkZhemxNb25kby9jaGVjay1kZXBsb3llZC1lbnZpcm9ubWVudEB2MScsXG4gICAgICB3aXRoOiB7XG4gICAgICAgIGVudmlyb25tZW50OiBlbnZpcm9ubWVudCxcbiAgICAgIH0sXG4gICAgICBlbnY6IHtcbiAgICAgICAgR0lUSFVCX1RPS0VOOiAnJHt7IHNlY3JldHMuR0lUSFVCX1RPS0VOIH19JyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGVwIHRvIHNldHVwIEFXUyBjcmVkZW50aWFscyBpbiB0aGUgZW52aXJvbm1lbnQgZm9yIHRoZSBtYXRyaXggc3RyYXRlZ3lcbiAgICogQHJldHVybnMgSm9iU3RlcFtdXG4gICAqL1xuICBwdWJsaWMgZ2V0IHNldHVwQXdzQ3JlZGVudGlhbHNTdGVwc0Zvck1hdHJpeCgpOiBKb2JTdGVwW10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLnNldHVwQXdzQ3JlZGVudGlhbHNJbkVudmlyb25tZW50Rm9yTWF0cml4LFxuICAgICAgdGhpcy5hc3N1bWVBd3NSb2xlU3RlcEZvck1hdHJpeCxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc3RlcHMgdG8gc2V0dXAgQVdTIGNyZWRlbnRpYWxzIGZvciBhIHNwZWNpZmljIGVudmlyb25tZW50XG4gICAqIEBwYXJhbSBlbnZpcm9ubWVudE9wdGlvbnMgVGhlIGVudmlyb25tZW50IG9wdGlvbnNcbiAgICogQHJldHVybnMgSm9iU3RlcFtdXG4gICAqL1xuICBwdWJsaWMgZ2V0U2V0dXBBd3NDcmVkZW50aWFsc1N0ZXBzRm9yRW52aXJvbm1lbnQoZW52aXJvbm1lbnRPcHRpb25zOiBFbnZpcm9ubWVudE9wdGlvbnMpOiBKb2JTdGVwW10ge1xuICAgIGNvbnN0IHN0ZXBzOiBKb2JTdGVwW10gPSBbXTtcblxuICAgIGNvbnN0IGZyb21FbnZWYXJpYWJsZVN0ZXAgPSB0aGlzLmdldFNldHVwQXdzQ3JlZGVudGlhbHNJbkVudmlyb25tZW50Rm9yRW52aXJvbm1lbnQoXG4gICAgICBlbnZpcm9ubWVudE9wdGlvbnMuYXdzQ3JlZGVudGlhbHMucm9sZVRvQXNzdW1lID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgZW52aXJvbm1lbnRPcHRpb25zLmF3c0NyZWRlbnRpYWxzLmFjY2Vzc0tleUlkU2VjcmV0TmFtZSA/PyAnQVdTX0FDQ0VTU19LRVlfSUQnLFxuICAgICAgZW52aXJvbm1lbnRPcHRpb25zLmF3c0NyZWRlbnRpYWxzLnNlY3JldEFjY2Vzc0tleVNlY3JldE5hbWUgPz8gJ0FXU19TRUNSRVRfQUNDRVNTX0tFWScsXG4gICAgICBlbnZpcm9ubWVudE9wdGlvbnMuYXdzQ3JlZGVudGlhbHMucmVnaW9uLFxuICAgICk7XG5cbiAgICBpZiAoZnJvbUVudlZhcmlhYmxlU3RlcCkge1xuICAgICAgc3RlcHMucHVzaChmcm9tRW52VmFyaWFibGVTdGVwKTtcbiAgICB9XG5cbiAgICBjb25zdCBhc3N1bWVSb2xlU3RlcCA9IHRoaXMuZ2V0QXNzdW1lQXdzUm9sZVN0ZXBGb3JFbnZpcm9ubWVudChcbiAgICAgIGVudmlyb25tZW50T3B0aW9ucy5hd3NDcmVkZW50aWFscy5yb2xlVG9Bc3N1bWUgPyB0cnVlIDogZmFsc2UsXG4gICAgICBlbnZpcm9ubWVudE9wdGlvbnMuYXdzQ3JlZGVudGlhbHMuYWNjZXNzS2V5SWRTZWNyZXROYW1lID8/ICdBV1NfQUNDRVNTX0tFWV9JRCcsXG4gICAgICBlbnZpcm9ubWVudE9wdGlvbnMuYXdzQ3JlZGVudGlhbHMuc2VjcmV0QWNjZXNzS2V5U2VjcmV0TmFtZSA/PyAnQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZJyxcbiAgICAgIGVudmlyb25tZW50T3B0aW9ucy5hd3NDcmVkZW50aWFscy5yZWdpb24sXG4gICAgICBlbnZpcm9ubWVudE9wdGlvbnMuYXdzQ3JlZGVudGlhbHMucm9sZVRvQXNzdW1lID8/ICcnLFxuICAgICAgZW52aXJvbm1lbnRPcHRpb25zLmF3c0NyZWRlbnRpYWxzLmFzc3VtZVJvbGVEdXJhdGlvblNlY29uZHMgPz8gOTAwLFxuICAgICk7XG5cbiAgICBpZiAoYXNzdW1lUm9sZVN0ZXApIHtcbiAgICAgIHN0ZXBzLnB1c2goYXNzdW1lUm9sZVN0ZXApO1xuICAgIH1cblxuICAgIHJldHVybiBzdGVwcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGVwIHRvIHNldHVwIEFXUyBjcmVkZW50aWFscyBpbiB0aGUgZW52aXJvbm1lbnQgZm9yIHRoZSBtYXRyaXggc3RyYXRlZ3lcbiAgICogQHJldHVybnMgSm9iU3RlcFxuICAgKi9cbiAgcHVibGljIGdldCBzZXR1cEF3c0NyZWRlbnRpYWxzSW5FbnZpcm9ubWVudEZvck1hdHJpeCgpOiBKb2JTdGVwIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTZXR1cEF3c0NyZWRlbnRpYWxzSW5FbnZpcm9ubWVudEZvckVudmlyb25tZW50KFxuICAgICAgJ21hdHJpeC5hc3N1bWVSb2xlJyxcbiAgICAgICdtYXRyaXguYWNjZXNzS2V5SWRTZWNyZXROYW1lJyxcbiAgICAgICdtYXRyaXguc2VjcmV0QWNjZXNzS2V5U2VjcmV0TmFtZScsXG4gICAgICAnJHt7IG1hdHJpeC5yZWdpb24gfX0nLFxuICAgICkhO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0ZXAgdG8gc2V0dXAgQVdTIGNyZWRlbnRpYWxzIGluIHRoZSBlbnZpcm9ubWVudCBmb3IgYSBzcGVjaWZpYyBlbnZpcm9ubWVudFxuICAgKiBAcGFyYW0gYXNzdW1lUm9sZUZsYWcgV2hldGhlciB0byBhc3N1bWUgYSByb2xlLCBjYW4gYmUgYSBib29sZWFuIG9yIGEgc3RyaW5nIGZvciBtYXRyaXggc3RyYXRlZ3lcbiAgICogQHBhcmFtIGFjY2Vzc0tleUlkU2VjcmV0TmFtZSBUaGUgR2l0SHViIHNlY3JldCBuYW1lIGZvciB0aGUgYWNjZXNzIGtleSBJRFxuICAgKiBAcGFyYW0gc2VjcmV0QWNjZXNzS2V5U2VjcmV0TmFtZSBUaGUgR2l0SHViIHNlY3JldCBuYW1lIGZvciB0aGUgc2VjcmV0IGFjY2VzcyBrZXlcbiAgICogQHBhcmFtIHJlZ2lvbiBUaGUgcmVnaW9uXG4gICAqIEByZXR1cm5zIEpvYlN0ZXAgb3IgdW5kZWZpbmVkIGlmIG5vIEFXUyBjcmVkZW50aWFscyBhcmUgcHJvdmlkZWQsXG4gICAqIGlmIGFzc3VtZVJvbGVGbGFnIGlzIGJvb2xlYW4gd2lsbCBiZSBldmFsdWF0ZWQgYW5kIHJldHVybiBhIEpvYlN0ZXAgb25seSBpZiBmYWxzZVxuICAgKiBpZiBhc3N1bWVSb2xlRmxhZyBpcyBzdHJpbmcgd2lsbCBhbHdheXMgcmV0dXJuIGEgSm9iU3RlcCAoZm9yIG1hdHJpeCBzdHJhdGVneSlcbiAgICovXG4gIHB1YmxpYyBnZXRTZXR1cEF3c0NyZWRlbnRpYWxzSW5FbnZpcm9ubWVudEZvckVudmlyb25tZW50KFxuICAgIGFzc3VtZVJvbGVGbGFnOiBib29sZWFuIHwgc3RyaW5nLFxuICAgIGFjY2Vzc0tleUlkU2VjcmV0TmFtZTogc3RyaW5nLFxuICAgIHNlY3JldEFjY2Vzc0tleVNlY3JldE5hbWU6IHN0cmluZyxcbiAgICByZWdpb246IHN0cmluZyxcbiAgKTogSm9iU3RlcCB8IHVuZGVmaW5lZCB7XG5cbiAgICBmdW5jdGlvbiBnZXRDb25kaXRpb24oZmFjdG9yeTogRGVwbG95YWJsZUF3c0Nka1R5cGVTY3JpcHRBcHBTdGVwc0ZhY3RvcnkpIHtcbiAgICAgIGlmICh0eXBlb2YgYXNzdW1lUm9sZUZsYWcgPT09ICdib29sZWFuJykge1xuICAgICAgICBpZiAoYXNzdW1lUm9sZUZsYWcpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWN0b3J5LnByb3BzLmNoZWNrQWN0aXZlRGVwbG95bWVudCA/IHNraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9uIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhY3RvcnkucHJvcHMuY2hlY2tBY3RpdmVEZXBsb3ltZW50ID9cbiAgICAgICAgYFxcJHt7ICR7YXNzdW1lUm9sZUZsYWd9ID09ICdmYWxzZScgJiYgJHtza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbn0gfX1gIDpcbiAgICAgICAgYFxcJHt7ICR7YXNzdW1lUm9sZUZsYWd9ID09ICdmYWxzZScgfX1gO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbW1hbmRzID0gW1xuICAgICAgJ2VjaG8gXCJBV1NfQUNDRVNTX0tFWV9JRD0kYWNjZXNzS2V5SWRcIiA+PiAkR0lUSFVCX0VOVicsXG4gICAgICAnZWNobyBcIkFXU19TRUNSRVRfQUNDRVNTX0tFWT0kc2VjcmV0QWNjZXNzS2V5XCIgPj4gJEdJVEhVQl9FTlYnLFxuICAgICAgJ2VjaG8gXCJBV1NfUkVHSU9OPSRyZWdpb25cIiA+PiAkR0lUSFVCX0VOVicsXG4gICAgXTtcblxuICAgIGlmICh0eXBlb2YgYXNzdW1lUm9sZUZsYWcgPT09ICdib29sZWFuJyAmJiBhc3N1bWVSb2xlRmxhZykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBjb25kaXRpb24gPSBnZXRDb25kaXRpb24odGhpcyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWY6IGNvbmRpdGlvbixcbiAgICAgIG5hbWU6ICdDb25maWd1cmUgQVdTIENyZWRlbnRpYWxzJyxcbiAgICAgIHJ1bjogYCR7Y29tbWFuZHMuam9pbignXFxuJyl9YCxcbiAgICAgIGVudjoge1xuICAgICAgICBhY2Nlc3NLZXlJZDogYFxcJHt7IHNlY3JldHNbJHthY2Nlc3NLZXlJZFNlY3JldE5hbWV9XSB9fWAsXG4gICAgICAgIHNlY3JldEFjY2Vzc0tleTogYFxcJHt7IHNlY3JldHNbJHtzZWNyZXRBY2Nlc3NLZXlTZWNyZXROYW1lfV0gfX1gLFxuICAgICAgICByZWdpb24sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogU3RlcCB0byBhc3N1bWUgYW4gQVdTIHJvbGUgZm9yIHRoZSBtYXRyaXggc3RyYXRlZ3lcbiAgICogQHJldHVybnMgSm9iU3RlcFxuICAgKi9cbiAgcHVibGljIGdldCBhc3N1bWVBd3NSb2xlU3RlcEZvck1hdHJpeCgpOiBKb2JTdGVwIHtcbiAgICByZXR1cm4gdGhpcy5nZXRBc3N1bWVBd3NSb2xlU3RlcEZvckVudmlyb25tZW50KFxuICAgICAgJ21hdHJpeC5hc3N1bWVSb2xlJyxcbiAgICAgICdtYXRyaXguYWNjZXNzS2V5SWRTZWNyZXROYW1lJyxcbiAgICAgICdtYXRyaXguc2VjcmV0QWNjZXNzS2V5U2VjcmV0TmFtZScsXG4gICAgICAnJHt7IG1hdHJpeC5yZWdpb24gfX0nLFxuICAgICAgJyR7eyBtYXRyaXgucm9sZVRvQXNzdW1lIH19JyxcbiAgICAgICcke3sgbWF0cml4LmFzc3VtZVJvbGVEdXJhdGlvblNlY29uZHMgfX0nLFxuICAgICkhO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0ZXAgdG8gYXNzdW1lIGFuIEFXUyByb2xlIGZvciBhIHNwZWNpZmljIGVudmlyb25tZW50XG4gICAqIEBwYXJhbSBhc3N1bWVSb2xlRmxhZyBXaGV0aGVyIHRvIGFzc3VtZSBhIHJvbGUsIGNhbiBiZSBhIGJvb2xlYW4gb3IgYSBzdHJpbmcgZm9yIG1hdHJpeCBzdHJhdGVneVxuICAgKiBAcGFyYW0gYWNjZXNzS2V5SWRTZWNyZXROYW1lIFRoZSBHaXRIdWIgc2VjcmV0IG5hbWUgZm9yIHRoZSBhY2Nlc3Mga2V5IElEXG4gICAqIEBwYXJhbSBzZWNyZXRBY2Nlc3NLZXlTZWNyZXROYW1lIFRoZSBHaXRIdWIgc2VjcmV0IG5hbWUgZm9yIHRoZSBzZWNyZXQgYWNjZXNzIGtleVxuICAgKiBAcGFyYW0gcmVnaW9uIFRoZSByZWdpb25cbiAgICogQHBhcmFtIHJvbGVUb0Fzc3VtZSBUaGUgcm9sZSB0byBhc3N1bWVcbiAgICogQHBhcmFtIGFzc3VtZVJvbGVEdXJhdGlvblNlY29uZHMgVGhlIGR1cmF0aW9uIGZvciBhc3N1bWluZyB0aGUgcm9sZVxuICAgKiBAcmV0dXJucyBKb2JTdGVwIG9yIHVuZGVmaW5lZCBpZiBhc3N1bWVSb2xlRmxhZyBpcyBib29sZWFuIGFuZCBmYWxzZVxuICAgKiBpZiBhc3N1bWVSb2xlRmxhZyBpcyBzdHJpbmcgd2lsbCBhbHdheXMgcmV0dXJuIGEgSm9iU3RlcCAoZm9yIG1hdHJpeCBzdHJhdGVneSlcbiAgICovXG4gIHB1YmxpYyBnZXRBc3N1bWVBd3NSb2xlU3RlcEZvckVudmlyb25tZW50KFxuICAgIGFzc3VtZVJvbGVGbGFnOiBib29sZWFuIHwgc3RyaW5nLFxuICAgIGFjY2Vzc0tleUlkU2VjcmV0TmFtZTogc3RyaW5nLFxuICAgIHNlY3JldEFjY2Vzc0tleVNlY3JldE5hbWU6IHN0cmluZyxcbiAgICByZWdpb246IHN0cmluZyxcbiAgICByb2xlVG9Bc3N1bWU6IHN0cmluZyxcbiAgICBhc3N1bWVSb2xlRHVyYXRpb25TZWNvbmRzPzogc3RyaW5nIHwgbnVtYmVyLFxuICApOiBKb2JTdGVwIHwgdW5kZWZpbmVkIHtcbiAgICBmdW5jdGlvbiBnZXRDb25kaXRpb24oZmFjdG9yeTogRGVwbG95YWJsZUF3c0Nka1R5cGVTY3JpcHRBcHBTdGVwc0ZhY3RvcnkpIHtcbiAgICAgIGlmICh0eXBlb2YgYXNzdW1lUm9sZUZsYWcgPT09ICdib29sZWFuJykge1xuICAgICAgICBpZiAoIWFzc3VtZVJvbGVGbGFnKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFjdG9yeS5wcm9wcy5jaGVja0FjdGl2ZURlcGxveW1lbnQgPyBza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbiA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWN0b3J5LnByb3BzLmNoZWNrQWN0aXZlRGVwbG95bWVudCA/XG4gICAgICAgIGBcXCR7eyAke2Fzc3VtZVJvbGVGbGFnfSA9PSAndHJ1ZScgJiYgJHtza2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbn0gfX1gIDpcbiAgICAgICAgYFxcJHt7ICR7YXNzdW1lUm9sZUZsYWd9ID09ICd0cnVlJyB9fWA7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBhc3N1bWVSb2xlRmxhZyA9PT0gJ2Jvb2xlYW4nICYmICFhc3N1bWVSb2xlRmxhZykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBjb25kaXRpb24gPSBnZXRDb25kaXRpb24odGhpcyk7XG5cbiAgICBjb25zdCBzZWNyZXRzUGFyYW1zID1cbiAgICAgIHRoaXMucHJvcHMuYXV0aFByb3ZpZGVyID09PSBDb2RlQXJ0aWZhY3RBdXRoUHJvdmlkZXIuQUNDRVNTX0FORF9TRUNSRVRfS0VZX1BBSVIgP1xuICAgICAgICB7XG4gICAgICAgICAgJ2F3cy1hY2Nlc3Mta2V5LWlkJzogYFxcJHt7IHNlY3JldHNbJHthY2Nlc3NLZXlJZFNlY3JldE5hbWV9XSB9fWAsXG4gICAgICAgICAgJ2F3cy1zZWNyZXQtYWNjZXNzLWtleSc6IGBcXCR7eyBzZWNyZXRzWyR7c2VjcmV0QWNjZXNzS2V5U2VjcmV0TmFtZX1dIH19YCxcbiAgICAgICAgfSA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4ge1xuICAgICAgaWY6IGNvbmRpdGlvbixcbiAgICAgIG5hbWU6ICdBc3N1bWUgQVdTIFJvbGUnLFxuICAgICAgdXNlczogJ2F3cy1hY3Rpb25zL2NvbmZpZ3VyZS1hd3MtY3JlZGVudGlhbHNAdjQnLFxuICAgICAgd2l0aDoge1xuICAgICAgICAuLi5zZWNyZXRzUGFyYW1zLFxuICAgICAgICAncm9sZS10by1hc3N1bWUnOiByb2xlVG9Bc3N1bWUsXG4gICAgICAgICdhd3MtcmVnaW9uJzogcmVnaW9uLFxuICAgICAgICAncm9sZS1kdXJhdGlvbi1zZWNvbmRzJzogYXNzdW1lUm9sZUR1cmF0aW9uU2Vjb25kcyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGVwIHRvIHNldHVwIE5QTSBjb25maWcgaWYgcHJvdmlkZWRcbiAgICogQHJldHVybnMgSm9iU3RlcCBvciB1bmRlZmluZWQgaWYgbm8gbnBtQ29uZmlnIGlzIHByb3ZpZGVkXG4gICAqL1xuICBwdWJsaWMgZ2V0IHNldHVwTnBtQ29uZmlnRm9yTWF0cml4KCk6IEpvYlN0ZXAgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmdldFNldHVwTnBtQ29uZmlnRm9yRW52aXJvbm1lbnQoJyR7eyBtYXRyaXguZW52aXJvbm1lbnQgfX0nKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTZXR1cE5wbUNvbmZpZ0ZvckVudmlyb25tZW50KGVudmlyb25tZW50OiBzdHJpbmcpOiBKb2JTdGVwIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB7IG5wbUNvbmZpZ0Vudmlyb25tZW50IH0gPSB0aGlzLnByb3BzO1xuICAgIGlmICghbnBtQ29uZmlnRW52aXJvbm1lbnQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUgPSAnQ09ORklHX1ZBTFVFJztcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5za2lwSWZBbHJlYWR5QWN0aXZlRGVwbG95bWVudENvbmRpdGlvbixcbiAgICAgIG5hbWU6ICdTZXR0aW5nIE5QTSBDb25maWcnLFxuICAgICAgZW52OiB7XG4gICAgICAgIFtlbnZpcm9ubWVudFZhcmlhYmxlTmFtZV06IGVudmlyb25tZW50LFxuICAgICAgfSxcbiAgICAgIHJ1bjogYG5wbSBjb25maWcgc2V0ICR7bnBtQ29uZmlnRW52aXJvbm1lbnR9ICQke2Vudmlyb25tZW50VmFyaWFibGVOYW1lfWAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHN0ZXAgdG8gcnVuIGEgc3BlY2lmaWMgc2NyaXB0XG4gICAqIEBwYXJhbSBzY3JpcHROYW1lIFRoZSBuYW1lIG9mIHRoZSBzY3JpcHQgdG8gcnVuXG4gICAqIEBwYXJhbSBzdGVwTmFtZSBUaGUgbmFtZSBvZiB0aGUgc3RlcCBpbiB0aGUgd29ya2Zsb3dcbiAgICogQHBhcmFtIGhhc1NjcmlwdEZsYWcgV2hldGhlciB0aGUgc2NyaXB0IHNob3VsZCBiZSBydW5cbiAgICogQHJldHVybnMgVGhlIGpvYiBzdGVwIHRvIHJ1biB0aGUgc2NyaXB0IG9yIHVuZGVmaW5lZCBpZiBub3QgYXBwbGljYWJsZVxuICAgKiBJZiBoYXNTY3JpcHRGbGFnIGlzIGJvb2xlYW4gYW5kIGZhbHNlIHdpbGwgcmV0dXJuIHVuZGVmaW5lZFxuICAgKiBJZiBoYXNTY3JpcHRGbGFnIGlzIHN0cmluZyB3aWxsIGFsd2F5cyByZXR1cm4gYSBKb2JTdGVwIChmb3IgbWF0cml4IHN0cmF0ZWd5KVxuICAgKi9cbiAgcHVibGljIGdldFJ1blNjcmlwdFN0ZXAoXG4gICAgc2NyaXB0TmFtZTogc3RyaW5nLFxuICAgIHN0ZXBOYW1lOiBzdHJpbmcsXG4gICAgaGFzU2NyaXB0RmxhZzogYm9vbGVhbiB8IHN0cmluZyxcbiAgKTogSm9iU3RlcCB8IHVuZGVmaW5lZCB7XG4gICAgZnVuY3Rpb24gZ2V0Q29uZGl0aW9uKGZhY3Rvcnk6IERlcGxveWFibGVBd3NDZGtUeXBlU2NyaXB0QXBwU3RlcHNGYWN0b3J5KSB7XG4gICAgICBpZiAodHlwZW9mIGhhc1NjcmlwdEZsYWcgPT09ICdib29sZWFuJykge1xuICAgICAgICBpZiAoIWhhc1NjcmlwdEZsYWcpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWN0b3J5LnByb3BzLmNoZWNrQWN0aXZlRGVwbG95bWVudCA/IHNraXBJZkFscmVhZHlBY3RpdmVEZXBsb3ltZW50Q29uZGl0aW9uIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhY3RvcnkucHJvcHMuY2hlY2tBY3RpdmVEZXBsb3ltZW50ID9cbiAgICAgICAgYFxcJHt7ICR7aGFzU2NyaXB0RmxhZ30gPT0gJ3RydWUnICYmICR7c2tpcElmQWxyZWFkeUFjdGl2ZURlcGxveW1lbnRDb25kaXRpb259IH19YCA6XG4gICAgICAgIGBcXCR7eyAke2hhc1NjcmlwdEZsYWd9ID09ICd0cnVlJyB9fWA7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgaGFzU2NyaXB0RmxhZyA9PT0gJ2Jvb2xlYW4nICYmICFoYXNTY3JpcHRGbGFnKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbmRpdGlvbiA9IGdldENvbmRpdGlvbih0aGlzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBpZjogY29uZGl0aW9uLFxuICAgICAgbmFtZTogYFJ1biAke3N0ZXBOYW1lfWAsXG4gICAgICBydW46IGAke3RoaXMucHJvamVjdC5ydW5TY3JpcHRDb21tYW5kfSAke3NjcmlwdE5hbWV9YCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0ZXAgdG8gZGVwbG95IHRoZSB3b3JrZmxvd1xuICAgKiBAcmV0dXJucyBKb2JTdGVwXG4gICAqL1xuICBwdWJsaWMgZ2V0IGRlcGxveW1lbnRTdGVwKCk6IEpvYlN0ZXAge1xuICAgIHJldHVybiB0aGlzLmdldFJ1blNjcmlwdFN0ZXAoXG4gICAgICAnZGVwbG95OndvcmtmbG93JyxcbiAgICAgICdEZXBsb3ltZW50JyxcbiAgICAgIHRydWUsXG4gICAgKSE7XG4gIH1cblxuICAvKipcbiAgICogU3RlcCB0byBydW4gcG9zdCBkZXBsb3ltZW50IHNjcmlwdCBpbiBtYXRyaXggc3RyYXRlZ3lcbiAgICogQHJldHVybnMgSm9iU3RlcFxuICAgKi9cbiAgcHVibGljIGdldCBwcmVEZXBsb3ltZW50U3RlcEZvck1hdHJpeCgpOiBKb2JTdGVwIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQcmVEZXBsb3ltZW50U3RlcEZvckVudmlyb25tZW50KFxuICAgICAgJ21hdHJpeC5oYXNQcmVEZXBsb3lUYXNrJyxcbiAgICAgICcke3sgbWF0cml4LnByZURlcGxveW1lbnRTY3JpcHQgfX0nLFxuICAgICkhO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcHJlLWRlcGxveW1lbnQgc3RlcCBmb3IgYSBzcGVjaWZpYyBlbnZpcm9ubWVudFxuICAgKiBAcGFyYW0gaGFzUHJlRGVwbG95VGFza0ZsYWcgV2hldGhlciB0aGUgcHJlLWRlcGxveW1lbnQgdGFzayBzaG91bGQgYmUgcnVuXG4gICAqIEBwYXJhbSBwcmVEZXBsb3ltZW50U2NyaXB0IFRoZSBzY3JpcHQgdG8gcnVuXG4gICAqIEByZXR1cm5zIFRoZSBqb2Igc3RlcCB0byBydW4gdGhlIHByZS1kZXBsb3ltZW50IHNjcmlwdCBvciB1bmRlZmluZWQgaWYgbm90IGFwcGxpY2FibGVcbiAgICogSWYgaGFzUHJlRGVwbG95VGFza0ZsYWcgaXMgYm9vbGVhbiBhbmQgZmFsc2Ugd2lsbCByZXR1cm4gdW5kZWZpbmVkXG4gICAqIElmIGhhc1ByZURlcGxveVRhc2tGbGFnIGlzIHN0cmluZyB3aWxsIGFsd2F5cyByZXR1cm4gYSBKb2JTdGVwIChmb3IgbWF0cml4IHN0cmF0ZWd5KVxuICAgKi9cbiAgcHVibGljIGdldFByZURlcGxveW1lbnRTdGVwRm9yRW52aXJvbm1lbnQoXG4gICAgaGFzUHJlRGVwbG95VGFza0ZsYWc6IGJvb2xlYW4gfCBzdHJpbmcsXG4gICAgcHJlRGVwbG95bWVudFNjcmlwdDogc3RyaW5nLFxuICApOiBKb2JTdGVwIHwgdW5kZWZpbmVkIHtcblxuICAgIHJldHVybiB0aGlzLmdldFJ1blNjcmlwdFN0ZXAoXG4gICAgICBwcmVEZXBsb3ltZW50U2NyaXB0LFxuICAgICAgJ1ByZSBEZXBsb3ltZW50JyxcbiAgICAgIGhhc1ByZURlcGxveVRhc2tGbGFnLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU3RlcCB0byBydW4gcG9zdCBkZXBsb3ltZW50IHNjcmlwdCBpbiBtYXRyaXggc3RyYXRlZ3lcbiAgICogQHJldHVybnMgSm9iU3RlcFxuICAgKi9cbiAgcHVibGljIGdldCBwb3N0RGVwbG95bWVudFN0ZXBGb3JNYXRyaXgoKTogSm9iU3RlcCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UG9zdERlcGxveW1lbnRTdGVwRm9yRW52aXJvbm1lbnQoXG4gICAgICAnbWF0cml4Lmhhc1Bvc3REZXBsb3lUYXNrJyxcbiAgICAgICcke3sgbWF0cml4LnBvc3REZXBsb3ltZW50U2NyaXB0IH19JyxcbiAgICApITtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHBvc3QtZGVwbG95bWVudCBzdGVwIGZvciBhIHNwZWNpZmljIGVudmlyb25tZW50XG4gICAqIEBwYXJhbSBoYXNQb3N0RGVwbG95VGFza0ZsYWcgV2hldGhlciB0aGUgcG9zdC1kZXBsb3ltZW50IHRhc2sgc2hvdWxkIGJlIHJ1blxuICAgKiBAcGFyYW0gcG9zdERlcGxveW1lbnRTY3JpcHQgVGhlIHNjcmlwdCB0byBydW5cbiAgICogQHJldHVybnMgVGhlIGpvYiBzdGVwIHRvIHJ1biB0aGUgcG9zdC1kZXBsb3ltZW50IHNjcmlwdCBvciB1bmRlZmluZWQgaWYgbm90IGFwcGxpY2FibGVcbiAgICogSWYgaGFzUG9zdERlcGxveVRhc2tGbGFnIGlzIGJvb2xlYW4gYW5kIGZhbHNlIHdpbGwgcmV0dXJuIHVuZGVmaW5lZFxuICAgKiBJZiBoYXNQb3N0RGVwbG95VGFza0ZsYWcgaXMgc3RyaW5nIHdpbGwgYWx3YXlzIHJldHVybiBhIEpvYlN0ZXAgKGZvciBtYXRyaXggc3RyYXRlZ3kpXG4gICAqL1xuICBwdWJsaWMgZ2V0UG9zdERlcGxveW1lbnRTdGVwRm9yRW52aXJvbm1lbnQoXG4gICAgaGFzUG9zdERlcGxveVRhc2tGbGFnOiBib29sZWFuIHwgc3RyaW5nLFxuICAgIHBvc3REZXBsb3ltZW50U2NyaXB0OiBzdHJpbmcsXG4gICk6IEpvYlN0ZXAgfCB1bmRlZmluZWQge1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0UnVuU2NyaXB0U3RlcChcbiAgICAgIHBvc3REZXBsb3ltZW50U2NyaXB0LFxuICAgICAgJ1Bvc3QgRGVwbG95bWVudCcsXG4gICAgICBoYXNQb3N0RGVwbG95VGFza0ZsYWcsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGRlcGxveW1lbnQgam9icyB3aGV0aGVyIGZvciBtYXRyaXggc3RyYXRlZ3kgb3Igbm90XG4gICAqIEByZXR1cm5zIFJlY29yZCBvZiBqb2JzXG4gICAqL1xuICBwdWJsaWMgZ2V0IGRlcGxveW1lbnRKb2JzKCk6IFJlY29yZDxzdHJpbmcsIEpvYj4ge1xuXG4gICAgaWYgKHRoaXMucHJvcHMuZGVwbG95T3B0aW9ucy5lbnZpcm9ubWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnByb2plY3QubG9nZ2VyLndhcm4oJ1RoZSBwcm9qZWN0IGRvZXMgbm90IGhhdmUgYW55IGVudmlyb25tZW50IHNldCwgbWFrZSBzdXJlIHRoaXMgaXMgZGVzaXJlZCBzZXR0aW5nJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb3BzLmpvYlN0cmF0ZWd5ID09PSBEZXBsb3lKb2JTdHJhdGVneS5NQVRSSVggPyB0aGlzLmRlcGxveW1lbnRKb2JzRm9yTWF0cml4IDogdGhpcy5nZXREZXBsb3ltZW50Sm9ic0Zvck11bHRpSm9iKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGRlcGxveW1lbnQgam9icyBmb3IgbWF0cml4IHN0cmF0ZWd5XG4gICAqIEByZXR1cm5zIFJlY29yZCBvZiBqb2JzXG4gICAqL1xuICBwdWJsaWMgZ2V0IGRlcGxveW1lbnRKb2JzRm9yTWF0cml4KCk6IFJlY29yZDxzdHJpbmcsIEpvYj4ge1xuXG4gICAgY29uc3QgeyBlbnZpcm9ubWVudHMsIGVudmlyb25tZW50VmFyaWFibGVOYW1lIH0gPSB0aGlzLnByb3BzLmRlcGxveU9wdGlvbnM7XG5cbiAgICBjb25zdCBpbmNsdWRlID0gZW52aXJvbm1lbnRzLm1hcChlbnZpcm9ubWVudE9wdGlvbnMgPT4ge1xuICAgICAgY29uc3QgeyBhd3NDcmVkZW50aWFscyB9ID0gZW52aXJvbm1lbnRPcHRpb25zO1xuXG4gICAgICBjb25zdCBhc3N1bWVSb2xlID0gYXdzQ3JlZGVudGlhbHMucm9sZVRvQXNzdW1lID8gJ3RydWUnIDogJ2ZhbHNlJztcblxuICAgICAgY29uc3QgYXNzdW1lUm9sZVNldHRpbmdzID0gYXdzQ3JlZGVudGlhbHMucm9sZVRvQXNzdW1lID8ge1xuICAgICAgICByb2xlVG9Bc3N1bWU6IGF3c0NyZWRlbnRpYWxzLnJvbGVUb0Fzc3VtZSxcbiAgICAgICAgYXNzdW1lUm9sZUR1cmF0aW9uU2Vjb25kczogYXdzQ3JlZGVudGlhbHMuYXNzdW1lUm9sZUR1cmF0aW9uU2Vjb25kcyB8fCA5MDAsXG4gICAgICB9OiB1bmRlZmluZWQ7XG5cbiAgICAgIGNvbnN0IGFjY2Vzc0tleUlkU2VjcmV0TmFtZSA9IGF3c0NyZWRlbnRpYWxzLmFjY2Vzc0tleUlkU2VjcmV0TmFtZSA/PyAnQVdTX0FDQ0VTU19LRVlfSUQnO1xuICAgICAgY29uc3Qgc2VjcmV0QWNjZXNzS2V5U2VjcmV0TmFtZSA9IGF3c0NyZWRlbnRpYWxzLnNlY3JldEFjY2Vzc0tleVNlY3JldE5hbWUgPz8gJ0FXU19TRUNSRVRfQUNDRVNTX0tFWSc7XG5cbiAgICAgIGNvbnN0IGhhc1Bvc3REZXBsb3lUYXNrID0gZW52aXJvbm1lbnRPcHRpb25zLnBvc3REZXBsb3lXb3JrZmxvd1NjcmlwdCA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgICBjb25zdCBoYXNQcmVEZXBsb3lUYXNrID0gZW52aXJvbm1lbnRPcHRpb25zLnByZURlcGxveVdvcmtmbG93U2NyaXB0ID8gJ3RydWUnIDogJ2ZhbHNlJztcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZW52aXJvbm1lbnQ6IGVudmlyb25tZW50T3B0aW9ucy5uYW1lLFxuICAgICAgICBhY2Nlc3NLZXlJZFNlY3JldE5hbWUsXG4gICAgICAgIHNlY3JldEFjY2Vzc0tleVNlY3JldE5hbWUsXG4gICAgICAgIHJlZ2lvbjogYXdzQ3JlZGVudGlhbHMucmVnaW9uLFxuICAgICAgICBhc3N1bWVSb2xlLFxuICAgICAgICBoYXNQb3N0RGVwbG95VGFzayxcbiAgICAgICAgcG9zdERlcGxveW1lbnRTY3JpcHQ6IGVudmlyb25tZW50T3B0aW9ucy5wb3N0RGVwbG95V29ya2Zsb3dTY3JpcHQgfHwgJycsXG4gICAgICAgIGhhc1ByZURlcGxveVRhc2ssXG4gICAgICAgIHByZURlcGxveW1lbnRTY3JpcHQ6IGVudmlyb25tZW50T3B0aW9ucy5wcmVEZXBsb3lXb3JrZmxvd1NjcmlwdCB8fCAnJyxcbiAgICAgICAgLi4uYXNzdW1lUm9sZVNldHRpbmdzLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlcGxveUpvYkVudiA9IGVudmlyb25tZW50VmFyaWFibGVOYW1lID8ge1xuICAgICAgW2Vudmlyb25tZW50VmFyaWFibGVOYW1lXTogJyR7eyBtYXRyaXguZW52aXJvbm1lbnQgfX0nLFxuICAgIH0gOiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBqb2JEZWZpbml0aW9uOiBKb2IgPSB7XG4gICAgICBydW5zT246IFsndWJ1bnR1LWxhdGVzdCddLFxuICAgICAgY29uY3VycmVuY3k6IHtcbiAgICAgICAgJ2dyb3VwJzogJyR7eyBtYXRyaXguZW52aXJvbm1lbnQgfX0tZGVwbG95JyxcbiAgICAgICAgJ2NhbmNlbC1pbi1wcm9ncmVzcyc6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIG5lZWRzOiBbXG4gICAgICAgICdyZWxlYXNlX2dpdGh1YicsXG4gICAgICBdLFxuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgICAgZGVwbG95bWVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgICAgaWRUb2tlbjogdGhpcy5wcm9wcy5hdXRoUHJvdmlkZXIgPT09IENvZGVBcnRpZmFjdEF1dGhQcm92aWRlci5HSVRIVUJfT0lEQyA/IEpvYlBlcm1pc3Npb24uV1JJVEUgOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgICAgc3RyYXRlZ3k6IHtcbiAgICAgICAgbWF4UGFyYWxsZWw6IDEsXG4gICAgICAgIG1hdHJpeDoge1xuICAgICAgICAgIGRvbWFpbjoge1xuICAgICAgICAgICAgZW52aXJvbm1lbnQ6IGluY2x1ZGUubWFwKGUgPT4gZS5lbnZpcm9ubWVudCksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIG5hbWU6ICcke3sgbWF0cml4LmVudmlyb25tZW50IH19JyxcbiAgICAgIH0sXG4gICAgICBlbnY6IGRlcGxveUpvYkVudixcbiAgICAgIHN0ZXBzOiBbXSxcbiAgICB9O1xuXG4gICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKHRoaXMuY2hlY2tvdXRTdGVwKTtcblxuICAgIGNvbnN0IHByZUluc3RhbGxEZXBlbmRlbmNpZXNTdGVwID0gdGhpcy5wcmVJbnN0YWxsRGVwZW5kZW5jaWVzU3RlcDtcbiAgICBpZiAocHJlSW5zdGFsbERlcGVuZGVuY2llc1N0ZXApIHtcbiAgICAgIGpvYkRlZmluaXRpb24uc3RlcHMucHVzaChwcmVJbnN0YWxsRGVwZW5kZW5jaWVzU3RlcCk7XG4gICAgfVxuXG4gICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKC4uLih0aGlzLnByb2plY3QpLnJlbmRlcldvcmtmbG93U2V0dXAoKSk7XG5cbiAgICBjb25zdCBjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwRm9yTWF0cml4ID0gdGhpcy5jaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwRm9yTWF0cml4O1xuICAgIGlmIChjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwRm9yTWF0cml4KSB7XG4gICAgICBqb2JEZWZpbml0aW9uLnN0ZXBzLnB1c2goY2hlY2tBY3RpdmVEZXBsb3ltZW50U3RlcEZvck1hdHJpeCk7XG4gICAgfVxuXG4gICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKC4uLnRoaXMuc2V0dXBBd3NDcmVkZW50aWFsc1N0ZXBzRm9yTWF0cml4KTtcblxuICAgIGNvbnN0IHNldHVwTnBtQ29uZmlnU3RlcCA9IHRoaXMuc2V0dXBOcG1Db25maWdGb3JNYXRyaXg7XG4gICAgaWYgKHNldHVwTnBtQ29uZmlnU3RlcCkge1xuICAgICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKHNldHVwTnBtQ29uZmlnU3RlcCk7XG4gICAgfVxuXG4gICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKHRoaXMucHJlRGVwbG95bWVudFN0ZXBGb3JNYXRyaXgpO1xuICAgIGpvYkRlZmluaXRpb24uc3RlcHMucHVzaCh0aGlzLmRlcGxveW1lbnRTdGVwKTtcbiAgICBqb2JEZWZpbml0aW9uLnN0ZXBzLnB1c2godGhpcy5wb3N0RGVwbG95bWVudFN0ZXBGb3JNYXRyaXgpO1xuXG4gICAgcmV0dXJuIHsgZGVwbG95OiBqb2JEZWZpbml0aW9uIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBJRHMgb2YgdGhlIGpvYnMgdGhhdCBtdXN0IGJlIGNvbXBsZXRlZCBiZWZvcmUgdGhlIHNwZWNpZmllZCBlbnZpcm9ubWVudCdzIGRlcGxveW1lbnQgam9iXG4gICAqIEBwYXJhbSBlbnZpcm9ubWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudmlyb25tZW50XG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGpvYiBJRHNcbiAgICovXG4gIHB1YmxpYyBnZXREZXBsb3ltZW50Sm9iUHJlcmVxdWlzaXRlSm9iSWRzKGVudmlyb25tZW50TmFtZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHJlc3VsdCA9IFsncmVsZWFzZV9naXRodWInXTtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMucHJvcHMuZGVwbG95T3B0aW9ucy5lbnZpcm9ubWVudHMuZmluZEluZGV4KGVudiA9PiBlbnYubmFtZSA9PT0gZW52aXJvbm1lbnROYW1lKTtcbiAgICBjb25zdCBwcmVyZXF1aXNpdGVFbnZpcm9ubWVudCA9IGluZGV4ID4gMCA/IHRoaXMucHJvcHMuZGVwbG95T3B0aW9ucy5lbnZpcm9ubWVudHNbaW5kZXggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICBpZiAocHJlcmVxdWlzaXRlRW52aXJvbm1lbnQpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGdldERlcGxveUpvYklkKHByZXJlcXVpc2l0ZUVudmlyb25tZW50Lm5hbWUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGVwbG95bWVudCBqb2JzIGZvciBtdWx0aS1qb2Igc3RyYXRlZ3lcbiAgICogQHJldHVybnMgUmVjb3JkIG9mIGpvYnNcbiAgICovXG4gIHB1YmxpYyBnZXREZXBsb3ltZW50Sm9ic0Zvck11bHRpSm9iKCk6IFJlY29yZDxzdHJpbmcsIEpvYj4ge1xuICAgIGNvbnN0IHsgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUsIGVudmlyb25tZW50cyB9ID0gdGhpcy5wcm9wcy5kZXBsb3lPcHRpb25zO1xuICAgIGNvbnN0IGpvYnMgPSBlbnZpcm9ubWVudHMubWFwKChlbnZpcm9ubWVudE9wdGlvbnMpOiBbc3RyaW5nLCBKb2JdID0+IHtcbiAgICAgIHJldHVybiBbZ2V0RGVwbG95Sm9iSWQoZW52aXJvbm1lbnRPcHRpb25zLm5hbWUpLCB0aGlzLmdldEpvYkZvckVudmlyb25tZW50KGVudmlyb25tZW50T3B0aW9ucywgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUpXTtcbiAgICB9KTtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKGpvYnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgam9iIGRlZmluaXRpb24gZm9yIGEgc3BlY2lmaWMgZW52aXJvbm1lbnRcbiAgICogQHBhcmFtIGVudmlyb25tZW50T3B0aW9ucyBUaGUgZW52aXJvbm1lbnQgb3B0aW9uc1xuICAgKiBAcGFyYW0gZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIHNldCB3aXRoIHRoZSBlbnZpcm9ubWVudCBuYW1lLCBpZiBhbnlcbiAgICogQHJldHVybnMgVGhlIGpvYiBkZWZpbml0aW9uIGZvciB0aGUgZW52aXJvbm1lbnRcbiAgICovXG4gIHB1YmxpYyBnZXRKb2JGb3JFbnZpcm9ubWVudChcbiAgICBlbnZpcm9ubWVudE9wdGlvbnM6IEVudmlyb25tZW50T3B0aW9ucyxcbiAgICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICApOiBKb2Ige1xuICAgIGNvbnN0IHsgbmFtZSB9ID0gZW52aXJvbm1lbnRPcHRpb25zO1xuICAgIGNvbnN0IGRlcGxveUpvYkVudiA9IGVudmlyb25tZW50VmFyaWFibGVOYW1lID8ge1xuICAgICAgW2Vudmlyb25tZW50VmFyaWFibGVOYW1lXTogbmFtZSxcbiAgICB9IDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3Qgam9iRGVmaW5pdGlvbjogSm9iID0ge1xuICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgIGNvbmN1cnJlbmN5OiB7XG4gICAgICAgICdncm91cCc6IGAke25hbWV9LWRlcGxveWAsXG4gICAgICAgICdjYW5jZWwtaW4tcHJvZ3Jlc3MnOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBuZWVkczogdGhpcy5nZXREZXBsb3ltZW50Sm9iUHJlcmVxdWlzaXRlSm9iSWRzKG5hbWUpLFxuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgICAgZGVwbG95bWVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgICAgaWRUb2tlbjogdGhpcy5wcm9wcy5hdXRoUHJvdmlkZXIgPT09IENvZGVBcnRpZmFjdEF1dGhQcm92aWRlci5HSVRIVUJfT0lEQyA/IEpvYlBlcm1pc3Npb24uV1JJVEUgOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgIH0sXG4gICAgICBlbnY6IGRlcGxveUpvYkVudixcbiAgICAgIHN0ZXBzOiBbXSxcbiAgICB9O1xuXG4gICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKHRoaXMuY2hlY2tvdXRTdGVwKTtcblxuICAgIGNvbnN0IHByZUluc3RhbGxEZXBlbmRlbmNpZXNTdGVwID0gdGhpcy5wcmVJbnN0YWxsRGVwZW5kZW5jaWVzU3RlcDtcbiAgICBpZiAocHJlSW5zdGFsbERlcGVuZGVuY2llc1N0ZXApIHtcbiAgICAgIGpvYkRlZmluaXRpb24uc3RlcHMucHVzaChwcmVJbnN0YWxsRGVwZW5kZW5jaWVzU3RlcCk7XG4gICAgfVxuXG4gICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKC4uLih0aGlzLnByb2plY3QpLnJlbmRlcldvcmtmbG93U2V0dXAoKSk7XG5cbiAgICBjb25zdCBjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwID0gdGhpcy5nZXRDaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwRm9yRW52aXJvbm1lbnQobmFtZSk7XG4gICAgaWYgKGNoZWNrQWN0aXZlRGVwbG95bWVudFN0ZXApIHtcbiAgICAgIGpvYkRlZmluaXRpb24uc3RlcHMucHVzaChjaGVja0FjdGl2ZURlcGxveW1lbnRTdGVwKTtcbiAgICB9XG5cbiAgICBqb2JEZWZpbml0aW9uLnN0ZXBzLnB1c2goLi4udGhpcy5nZXRTZXR1cEF3c0NyZWRlbnRpYWxzU3RlcHNGb3JFbnZpcm9ubWVudChlbnZpcm9ubWVudE9wdGlvbnMpKTtcblxuICAgIGNvbnN0IHNldHVwTnBtQ29uZmlnU3RlcCA9IHRoaXMuZ2V0U2V0dXBOcG1Db25maWdGb3JFbnZpcm9ubWVudChuYW1lKTtcbiAgICBpZiAoc2V0dXBOcG1Db25maWdTdGVwKSB7XG4gICAgICBqb2JEZWZpbml0aW9uLnN0ZXBzLnB1c2goc2V0dXBOcG1Db25maWdTdGVwKTtcbiAgICB9XG5cbiAgICBjb25zdCBwcmVEZXBsb3ltZW50U3RlcCA9IHRoaXMuZ2V0UHJlRGVwbG95bWVudFN0ZXBGb3JFbnZpcm9ubWVudChcbiAgICAgIGVudmlyb25tZW50T3B0aW9ucy5wcmVEZXBsb3lXb3JrZmxvd1NjcmlwdCA/IHRydWUgOiBmYWxzZSxcbiAgICAgIGVudmlyb25tZW50T3B0aW9ucy5wcmVEZXBsb3lXb3JrZmxvd1NjcmlwdCB8fCAnJyxcbiAgICApO1xuICAgIGlmIChwcmVEZXBsb3ltZW50U3RlcCkge1xuICAgICAgam9iRGVmaW5pdGlvbi5zdGVwcy5wdXNoKHByZURlcGxveW1lbnRTdGVwKTtcbiAgICB9XG5cbiAgICBqb2JEZWZpbml0aW9uLnN0ZXBzLnB1c2godGhpcy5kZXBsb3ltZW50U3RlcCk7XG5cbiAgICBjb25zdCBwb3N0RGVwbG95bWVudFN0ZXAgPSB0aGlzLmdldFBvc3REZXBsb3ltZW50U3RlcEZvckVudmlyb25tZW50KFxuICAgICAgZW52aXJvbm1lbnRPcHRpb25zLnBvc3REZXBsb3lXb3JrZmxvd1NjcmlwdCA/IHRydWUgOiBmYWxzZSxcbiAgICAgIGVudmlyb25tZW50T3B0aW9ucy5wb3N0RGVwbG95V29ya2Zsb3dTY3JpcHQgfHwgJycsXG4gICAgKTtcbiAgICBpZiAocG9zdERlcGxveW1lbnRTdGVwKSB7XG4gICAgICBqb2JEZWZpbml0aW9uLnN0ZXBzLnB1c2gocG9zdERlcGxveW1lbnRTdGVwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gam9iRGVmaW5pdGlvbjtcbiAgfVxuXG59XG5cbmZ1bmN0aW9uIGdldERlcGxveUpvYklkKGVudmlyb25tZW50TmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBEZXBsb3ktJHtlbnZpcm9ubWVudE5hbWV9YDtcbn1cbiJdfQ==