@aws-cdk/toolkit-lib 0.1.3 → 0.1.5

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.
Files changed (91) hide show
  1. package/build-info.json +2 -2
  2. package/db.json.gz +0 -0
  3. package/lib/actions/bootstrap/index.d.ts +174 -0
  4. package/lib/actions/bootstrap/index.js +94 -0
  5. package/lib/actions/bootstrap/private/helpers.d.ts +5 -0
  6. package/lib/actions/bootstrap/private/helpers.js +23 -0
  7. package/lib/actions/bootstrap/private/index.d.ts +1 -0
  8. package/lib/actions/bootstrap/private/index.js +18 -0
  9. package/lib/actions/deploy/index.d.ts +4 -2
  10. package/lib/actions/deploy/index.js +4 -1
  11. package/lib/actions/deploy/private/deploy-options.d.ts +1 -1
  12. package/lib/actions/deploy/private/deploy-options.js +1 -1
  13. package/lib/actions/deploy/private/helpers.d.ts +3 -2
  14. package/lib/actions/deploy/private/helpers.js +1 -1
  15. package/lib/actions/destroy/index.d.ts +1 -1
  16. package/lib/actions/destroy/index.js +1 -1
  17. package/lib/actions/diff/private/helpers.d.ts +5 -5
  18. package/lib/actions/diff/private/helpers.js +13 -11
  19. package/lib/actions/index.d.ts +1 -0
  20. package/lib/actions/index.js +2 -1
  21. package/lib/api/aws-cdk.d.ts +5 -9
  22. package/lib/api/aws-cdk.js +1593 -735
  23. package/lib/api/aws-cdk.js.map +4 -4
  24. package/lib/api/bootstrap/bootstrap-template.yaml +707 -0
  25. package/lib/api/cloud-assembly/index.d.ts +1 -1
  26. package/lib/api/cloud-assembly/index.js +2 -2
  27. package/lib/api/cloud-assembly/private/cached-source.d.ts +2 -2
  28. package/lib/api/cloud-assembly/private/cached-source.js +1 -1
  29. package/lib/api/cloud-assembly/private/context-aware-source.d.ts +4 -4
  30. package/lib/api/cloud-assembly/private/context-aware-source.js +11 -12
  31. package/lib/api/cloud-assembly/private/identity-source.d.ts +1 -1
  32. package/lib/api/cloud-assembly/private/identity-source.js +1 -1
  33. package/lib/api/cloud-assembly/private/prepare-source.d.ts +5 -5
  34. package/lib/api/cloud-assembly/private/prepare-source.js +10 -7
  35. package/lib/api/cloud-assembly/private/source-builder.d.ts +4 -4
  36. package/lib/api/cloud-assembly/private/source-builder.js +24 -12
  37. package/lib/api/cloud-assembly/private/stack-assembly.d.ts +3 -3
  38. package/lib/api/cloud-assembly/private/stack-assembly.js +1 -1
  39. package/lib/api/cloud-assembly/private/stack-selectors.d.ts +1 -1
  40. package/lib/api/cloud-assembly/private/stack-selectors.js +1 -1
  41. package/lib/api/cloud-assembly/source-builder.d.ts +36 -0
  42. package/lib/api/cloud-assembly/source-builder.js +1 -1
  43. package/lib/api/cloud-assembly/stack-selector.d.ts +2 -81
  44. package/lib/api/cloud-assembly/stack-selector.js +5 -62
  45. package/lib/api/io/index.d.ts +1 -2
  46. package/lib/api/io/index.js +1 -17
  47. package/lib/api/io/private/index.d.ts +3 -6
  48. package/lib/api/io/private/index.js +7 -7
  49. package/lib/api/io/private/io-host-wrappers.d.ts +17 -0
  50. package/lib/api/io/private/io-host-wrappers.js +74 -0
  51. package/lib/api/io/private/sdk-logger.d.ts +3 -0
  52. package/lib/api/io/private/sdk-logger.js +124 -0
  53. package/lib/api/shared-private.d.ts +1 -0
  54. package/lib/api/shared-private.js +711 -0
  55. package/lib/api/shared-private.js.map +7 -0
  56. package/lib/api/shared-public.d.ts +2464 -1
  57. package/lib/api/shared-public.js +78 -5
  58. package/lib/api/shared-public.js.map +4 -4
  59. package/lib/index.d.ts +3 -0
  60. package/lib/index.js +4 -1
  61. package/lib/private/util.d.ts +1 -0
  62. package/lib/private/util.js +720 -0
  63. package/lib/private/util.js.map +7 -0
  64. package/lib/toolkit/index.d.ts +1 -1
  65. package/lib/toolkit/index.js +2 -2
  66. package/lib/toolkit/private/index.d.ts +12 -3
  67. package/lib/toolkit/private/index.js +18 -1
  68. package/lib/toolkit/toolkit.d.ts +10 -16
  69. package/lib/toolkit/toolkit.js +205 -152
  70. package/lib/util/concurrency.d.ts +5 -0
  71. package/lib/util/concurrency.js +11 -0
  72. package/package.json +12 -11
  73. package/CODE_REGISTRY.md +0 -35
  74. package/lib/api/io/io-host.d.ts +0 -15
  75. package/lib/api/io/io-host.js +0 -3
  76. package/lib/api/io/io-message.d.ts +0 -59
  77. package/lib/api/io/io-message.js +0 -3
  78. package/lib/api/io/private/codes.d.ts +0 -67
  79. package/lib/api/io/private/codes.js +0 -187
  80. package/lib/api/io/private/level-priority.d.ts +0 -11
  81. package/lib/api/io/private/level-priority.js +0 -33
  82. package/lib/api/io/private/logger.d.ts +0 -40
  83. package/lib/api/io/private/logger.js +0 -211
  84. package/lib/api/io/private/messages.d.ts +0 -58
  85. package/lib/api/io/private/messages.js +0 -163
  86. package/lib/api/io/private/timer.d.ts +0 -29
  87. package/lib/api/io/private/timer.js +0 -55
  88. package/lib/api/io/private/types.d.ts +0 -25
  89. package/lib/api/io/private/types.js +0 -3
  90. package/lib/toolkit/types.d.ts +0 -76
  91. package/lib/toolkit/types.js +0 -3
@@ -6,19 +6,24 @@ const cxapi = require("@aws-cdk/cx-api");
6
6
  const chalk = require("chalk");
7
7
  const chokidar = require("chokidar");
8
8
  const fs = require("fs-extra");
9
+ const private_1 = require("./private");
10
+ const bootstrap_1 = require("../actions/bootstrap");
9
11
  const deploy_1 = require("../actions/deploy");
10
- const private_1 = require("../actions/deploy/private");
11
- const private_2 = require("../actions/diff/private");
12
- const private_3 = require("../actions/watch/private");
12
+ const private_2 = require("../actions/deploy/private");
13
+ const private_3 = require("../actions/diff/private");
14
+ const private_4 = require("../actions/watch/private");
13
15
  const aws_cdk_1 = require("../api/aws-cdk");
14
16
  const cloud_assembly_1 = require("../api/cloud-assembly");
15
- const private_4 = require("../api/cloud-assembly/private");
16
- const private_5 = require("../api/io/private");
17
+ const private_5 = require("../api/cloud-assembly/private");
18
+ const private_6 = require("../api/io/private");
19
+ const shared_private_1 = require("../api/shared-private");
17
20
  const shared_public_1 = require("../api/shared-public");
21
+ const util_1 = require("../private/util");
22
+ const concurrency_1 = require("../util/concurrency");
18
23
  /**
19
24
  * The AWS CDK Programmatic Toolkit
20
25
  */
21
- class Toolkit extends private_4.CloudAssemblySourceBuilder {
26
+ class Toolkit extends private_5.CloudAssemblySourceBuilder {
22
27
  props;
23
28
  /**
24
29
  * The toolkit stack name used for bootstrapping resources.
@@ -40,14 +45,14 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
40
45
  }
41
46
  let ioHost = globalIoHost;
42
47
  if (props.emojis === false) {
43
- ioHost = (0, private_5.withoutEmojis)(ioHost);
48
+ ioHost = (0, private_6.withoutEmojis)(ioHost);
44
49
  }
45
50
  if (props.color === false) {
46
- ioHost = (0, private_5.withoutColor)(ioHost);
51
+ ioHost = (0, private_6.withoutColor)(ioHost);
47
52
  }
48
53
  // After removing emojis and color, we might end up with floating whitespace at either end of the message
49
54
  // This also removes newlines that we currently emit for CLI backwards compatibility.
50
- this.ioHost = (0, private_5.withTrimmedWhitespace)(ioHost);
55
+ this.ioHost = (0, private_6.withTrimmedWhitespace)(ioHost);
51
56
  }
52
57
  async dispose() {
53
58
  // nothing to do yet
@@ -63,7 +68,7 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
63
68
  if (!this._sdkProvider) {
64
69
  this._sdkProvider = await aws_cdk_1.SdkProvider.withAwsCliCompatibleDefaults({
65
70
  ...this.props.sdkConfig,
66
- logger: (0, private_5.asSdkLogger)(this.ioHost, action),
71
+ logger: (0, private_6.asSdkLogger)((0, shared_private_1.asIoHelper)(this.ioHost, action)),
67
72
  });
68
73
  }
69
74
  return this._sdkProvider;
@@ -73,21 +78,61 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
73
78
  */
74
79
  async sourceBuilderServices() {
75
80
  return {
76
- ioHost: (0, private_5.withAction)(this.ioHost, 'assembly'),
81
+ ioHelper: (0, shared_private_1.asIoHelper)(this.ioHost, 'assembly'),
77
82
  sdkProvider: await this.sdkProvider('assembly'),
78
83
  };
79
84
  }
85
+ /**
86
+ * Bootstrap Action
87
+ */
88
+ async bootstrap(environments, options) {
89
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, 'bootstrap');
90
+ const bootstrapEnvironments = await environments.getEnvironments();
91
+ const source = options.source ?? bootstrap_1.BootstrapSource.default();
92
+ const parameters = options.parameters;
93
+ const bootstrapper = new aws_cdk_1.Bootstrapper(source, ioHelper);
94
+ const sdkProvider = await this.sdkProvider('bootstrap');
95
+ const limit = (0, concurrency_1.pLimit)(20);
96
+ // eslint-disable-next-line @cdklabs/promiseall-no-unbounded-parallelism
97
+ await Promise.all(bootstrapEnvironments.map((environment, currentIdx) => limit(async () => {
98
+ const bootstrapSpan = await ioHelper.span(private_6.SPAN.BOOTSTRAP_SINGLE)
99
+ .begin(`${chalk.bold(environment.name)}: bootstrapping...`, {
100
+ total: bootstrapEnvironments.length,
101
+ current: currentIdx + 1,
102
+ environment,
103
+ });
104
+ try {
105
+ const bootstrapResult = await bootstrapper.bootstrapEnvironment(environment, sdkProvider, {
106
+ ...options,
107
+ toolkitStackName: this.toolkitStackName,
108
+ source,
109
+ parameters: parameters?.parameters,
110
+ usePreviousParameters: parameters?.keepExistingParameters,
111
+ });
112
+ const message = bootstrapResult.noOp
113
+ ? ` ✅ ${environment.name} (no changes)`
114
+ : ` ✅ ${environment.name}`;
115
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I9900.msg(chalk.green('\n' + message), { environment }));
116
+ await bootstrapSpan.end();
117
+ }
118
+ catch (e) {
119
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_E9900.msg(`\n ❌ ${chalk.bold(environment.name)} failed: ${(0, util_1.formatErrorMessage)(e)}`, { error: e }));
120
+ throw e;
121
+ }
122
+ })));
123
+ }
80
124
  /**
81
125
  * Synth Action
82
126
  */
83
127
  async synth(cx, options = {}) {
84
- const ioHost = (0, private_5.withAction)(this.ioHost, 'synth');
85
- const synthTimer = private_5.Timer.start();
86
- const assembly = await this.assemblyFromSource(cx);
87
- const stacks = assembly.selectStacksV2(options.stacks ?? private_4.ALL_STACKS);
128
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, 'synth');
129
+ const selectStacks = options.stacks ?? private_5.ALL_STACKS;
130
+ const synthSpan = await ioHelper.span(private_6.SPAN.SYNTH_ASSEMBLY).begin({ stacks: selectStacks });
131
+ const assembly = await (0, private_1.assemblyFromSource)(cx);
132
+ const stacks = assembly.selectStacksV2(selectStacks);
88
133
  const autoValidateStacks = options.validateStacks ? [assembly.selectStacksForValidation()] : [];
89
- await this.validateStacksMetadata(stacks.concat(...autoValidateStacks), ioHost);
90
- await synthTimer.endAs(ioHost, 'synth');
134
+ await this.validateStacksMetadata(stacks.concat(...autoValidateStacks), ioHelper);
135
+ await synthSpan.end();
91
136
  // if we have a single stack, print it to STDOUT
92
137
  const message = `Successfully synthesized to ${chalk.blue(path.resolve(stacks.assembly.directory))}`;
93
138
  const assemblyData = {
@@ -98,24 +143,24 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
98
143
  if (stacks.stackCount === 1) {
99
144
  const firstStack = stacks.firstStack;
100
145
  const template = firstStack.template;
101
- const obscuredTemplate = (0, aws_cdk_1.obscureTemplate)(template);
102
- await ioHost.notify((0, private_5.result)(message, private_5.CODES.CDK_TOOLKIT_I1901, {
146
+ const obscuredTemplate = (0, util_1.obscureTemplate)(template);
147
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I1901.msg(message, {
103
148
  ...assemblyData,
104
149
  stack: {
105
150
  stackName: firstStack.stackName,
106
151
  hierarchicalId: firstStack.hierarchicalId,
107
152
  template,
108
- stringifiedJson: (0, aws_cdk_1.serializeStructure)(obscuredTemplate, true),
109
- stringifiedYaml: (0, aws_cdk_1.serializeStructure)(obscuredTemplate, false),
153
+ stringifiedJson: (0, util_1.serializeStructure)(obscuredTemplate, true),
154
+ stringifiedYaml: (0, util_1.serializeStructure)(obscuredTemplate, false),
110
155
  },
111
156
  }));
112
157
  }
113
158
  else {
114
159
  // not outputting template to stdout, let's explain things to the user a little bit...
115
- await ioHost.notify((0, private_5.result)(chalk.green(message), private_5.CODES.CDK_TOOLKIT_I1902, assemblyData));
116
- await ioHost.notify((0, private_5.info)(`Supply a stack id (${stacks.stackArtifacts.map((s) => chalk.green(s.hierarchicalId)).join(', ')}) to display its template.`));
160
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I1902.msg(chalk.green(message), assemblyData));
161
+ await ioHelper.notify(private_6.IO.DEFAULT_TOOLKIT_INFO.msg(`Supply a stack id (${stacks.stackArtifacts.map((s) => chalk.green(s.hierarchicalId)).join(', ')}) to display its template.`));
117
162
  }
118
- return new private_4.IdentityCloudAssemblySource(assembly.assembly);
163
+ return new private_5.IdentityCloudAssemblySource(assembly.assembly);
119
164
  }
120
165
  /**
121
166
  * List Action
@@ -123,14 +168,15 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
123
168
  * List selected stacks and their dependencies
124
169
  */
125
170
  async list(cx, options = {}) {
126
- const ioHost = (0, private_5.withAction)(this.ioHost, 'list');
127
- const synthTimer = private_5.Timer.start();
128
- const assembly = await this.assemblyFromSource(cx);
129
- const stackCollection = await assembly.selectStacksV2(options.stacks ?? private_4.ALL_STACKS);
130
- await synthTimer.endAs(ioHost, 'synth');
171
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, 'list');
172
+ const selectStacks = options.stacks ?? private_5.ALL_STACKS;
173
+ const synthSpan = await ioHelper.span(private_6.SPAN.SYNTH_ASSEMBLY).begin({ stacks: selectStacks });
174
+ const assembly = await (0, private_1.assemblyFromSource)(cx);
175
+ const stackCollection = await assembly.selectStacksV2(selectStacks);
176
+ await synthSpan.end();
131
177
  const stacks = stackCollection.withDependencies();
132
178
  const message = stacks.map(s => s.id).join('\n');
133
- await ioHost.notify((0, private_5.result)(message, private_5.CODES.CDK_TOOLKIT_I2901, { stacks }));
179
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I2901.msg(message, { stacks }));
134
180
  return stacks;
135
181
  }
136
182
  /**
@@ -139,30 +185,30 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
139
185
  * Deploys the selected stacks into an AWS account
140
186
  */
141
187
  async deploy(cx, options = {}) {
142
- const assembly = await this.assemblyFromSource(cx);
188
+ const assembly = await (0, private_1.assemblyFromSource)(cx);
143
189
  return this._deploy(assembly, 'deploy', options);
144
190
  }
145
191
  /**
146
192
  * Helper to allow deploy being called as part of the watch action.
147
193
  */
148
194
  async _deploy(assembly, action, options = {}) {
149
- const ioHost = (0, private_5.withAction)(this.ioHost, action);
150
- const synthTimer = private_5.Timer.start();
151
- const stackCollection = assembly.selectStacksV2(options.stacks ?? private_4.ALL_STACKS);
152
- await this.validateStacksMetadata(stackCollection, ioHost);
153
- const synthDuration = await synthTimer.endAs(ioHost, 'synth');
195
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, action);
196
+ const selectStacks = options.stacks ?? private_5.ALL_STACKS;
197
+ const synthSpan = await ioHelper.span(private_6.SPAN.SYNTH_ASSEMBLY).begin({ stacks: selectStacks });
198
+ const stackCollection = assembly.selectStacksV2(selectStacks);
199
+ await this.validateStacksMetadata(stackCollection, ioHelper);
200
+ const synthDuration = await synthSpan.end();
154
201
  if (stackCollection.stackCount === 0) {
155
- await ioHost.notify((0, private_5.error)('This app contains no stacks', private_5.CODES.CDK_TOOLKIT_E5001));
202
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_E5001.msg('This app contains no stacks'));
156
203
  return;
157
204
  }
158
205
  const deployments = await this.deploymentsForAction('deploy');
159
- const migrator = new aws_cdk_1.ResourceMigrator({ deployments, ioHost, action });
206
+ const migrator = new aws_cdk_1.ResourceMigrator({ deployments, ioHelper });
160
207
  await migrator.tryMigrateResources(stackCollection, options);
161
- const requireApproval = options.requireApproval ?? deploy_1.RequireApproval.NEVER;
162
- const parameterMap = (0, private_1.buildParameterMap)(options.parameters?.parameters);
208
+ const parameterMap = (0, private_2.buildParameterMap)(options.parameters?.parameters);
163
209
  const hotswapMode = options.hotswap ?? aws_cdk_1.HotswapMode.FULL_DEPLOYMENT;
164
210
  if (hotswapMode !== aws_cdk_1.HotswapMode.FULL_DEPLOYMENT) {
165
- await ioHost.notify((0, private_5.warn)([
211
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_W5400.msg([
166
212
  '⚠️ The --hotswap and --hotswap-fallback flags deliberately introduce CloudFormation drift to speed up deployments',
167
213
  '⚠️ They should only be used for development - never use them for your production Stacks!',
168
214
  ].join('\n')));
@@ -171,23 +217,32 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
171
217
  const stackOutputs = {};
172
218
  const outputsFile = options.outputsFile;
173
219
  const buildAsset = async (assetNode) => {
220
+ const buildAssetSpan = await ioHelper.span(private_6.SPAN.BUILD_ASSET).begin({
221
+ asset: assetNode.asset,
222
+ });
174
223
  await deployments.buildSingleAsset(assetNode.assetManifestArtifact, assetNode.assetManifest, assetNode.asset, {
175
224
  stack: assetNode.parentStack,
176
225
  roleArn: options.roleArn,
177
226
  stackName: assetNode.parentStack.stackName,
178
227
  });
228
+ await buildAssetSpan.end();
179
229
  };
180
230
  const publishAsset = async (assetNode) => {
231
+ const publishAssetSpan = await ioHelper.span(private_6.SPAN.PUBLISH_ASSET).begin({
232
+ asset: assetNode.asset,
233
+ });
181
234
  await deployments.publishSingleAsset(assetNode.assetManifest, assetNode.asset, {
182
235
  stack: assetNode.parentStack,
183
236
  roleArn: options.roleArn,
184
237
  stackName: assetNode.parentStack.stackName,
238
+ forcePublish: options.force,
185
239
  });
240
+ await publishAssetSpan.end();
186
241
  };
187
242
  const deployStack = async (stackNode) => {
188
243
  const stack = stackNode.stack;
189
244
  if (stackCollection.stackCount !== 1) {
190
- await ioHost.notify((0, private_5.info)(chalk.bold(stack.displayName)));
245
+ await ioHelper.notify(private_6.IO.DEFAULT_TOOLKIT_INFO.msg(chalk.bold(stack.displayName)));
191
246
  }
192
247
  if (!stack.environment) {
193
248
  throw new shared_public_1.ToolkitError(`Stack ${stack.displayName} does not define an environment, and AWS credentials could not be obtained from standard locations or no region was configured.`);
@@ -197,10 +252,10 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
197
252
  // stack is empty and doesn't exist => do nothing
198
253
  const stackExists = await deployments.stackExists({ stack });
199
254
  if (!stackExists) {
200
- return ioHost.notify((0, private_5.warn)(`${chalk.bold(stack.displayName)}: stack has no resources, skipping deployment.`));
255
+ return ioHelper.notify(private_6.IO.CDK_TOOLKIT_W5021.msg(`${chalk.bold(stack.displayName)}: stack has no resources, skipping deployment.`));
201
256
  }
202
257
  // stack is empty, but exists => delete
203
- await ioHost.notify((0, private_5.warn)(`${chalk.bold(stack.displayName)}: stack has no resources, deleting existing stack.`));
258
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_W5022.msg(`${chalk.bold(stack.displayName)}: stack has no resources, deleting existing stack.`));
204
259
  await this._destroy(assembly, 'deploy', {
205
260
  stacks: { patterns: [stack.hierarchicalId], strategy: cloud_assembly_1.StackSelectionStrategy.PATTERN_MUST_MATCH_SINGLE },
206
261
  roleArn: options.roleArn,
@@ -208,16 +263,17 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
208
263
  });
209
264
  return;
210
265
  }
211
- if (requireApproval !== deploy_1.RequireApproval.NEVER) {
212
- const currentTemplate = await deployments.readCurrentTemplate(stack);
213
- if ((0, private_2.diffRequiresApproval)(currentTemplate, stack, requireApproval)) {
214
- const motivation = '"--require-approval" is enabled and stack includes security-sensitive updates.';
215
- const question = `${motivation}\nDo you wish to deploy these changes`;
216
- const confirmed = await ioHost.requestResponse((0, private_5.confirm)(private_5.CODES.CDK_TOOLKIT_I5060, question, motivation, true, concurrency));
217
- if (!confirmed) {
218
- throw new shared_public_1.ToolkitError('Aborted by user');
219
- }
220
- }
266
+ const currentTemplate = await deployments.readCurrentTemplate(stack);
267
+ const permissionChangeType = (0, private_3.determinePermissionType)(currentTemplate, stack);
268
+ const deployMotivation = '"--require-approval" is enabled and stack includes security-sensitive updates.';
269
+ const deployQuestion = `${deployMotivation}\nDo you wish to deploy these changes`;
270
+ const deployConfirmed = await ioHelper.requestResponse(private_6.IO.CDK_TOOLKIT_I5060.req(deployQuestion, {
271
+ motivation: deployMotivation,
272
+ concurrency,
273
+ permissionChangeType,
274
+ }));
275
+ if (!deployConfirmed) {
276
+ throw new shared_public_1.ToolkitError('Aborted by user');
221
277
  }
222
278
  // Following are the same semantics we apply with respect to Notification ARNs (dictated by the SDK)
223
279
  //
@@ -228,13 +284,17 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
228
284
  ? (options.notificationArns ?? []).concat(stack.notificationArns ?? [])
229
285
  : undefined;
230
286
  for (const notificationArn of notificationArns ?? []) {
231
- if (!(0, aws_cdk_1.validateSnsTopicArn)(notificationArn)) {
287
+ if (!(0, util_1.validateSnsTopicArn)(notificationArn)) {
232
288
  throw new shared_public_1.ToolkitError(`Notification arn ${notificationArn} is not a valid arn for an SNS topic`);
233
289
  }
234
290
  }
235
291
  const stackIndex = stacks.indexOf(stack) + 1;
236
- await ioHost.notify((0, private_5.info)(`${chalk.bold(stack.displayName)}: deploying... [${stackIndex}/${stackCollection.stackCount}]`));
237
- const deployTimer = private_5.Timer.start();
292
+ const deploySpan = await ioHelper.span(private_6.SPAN.DEPLOY_STACK)
293
+ .begin(`${chalk.bold(stack.displayName)}: deploying... [${stackIndex}/${stackCollection.stackCount}]`, {
294
+ total: stackCollection.stackCount,
295
+ current: stackIndex,
296
+ stack,
297
+ });
238
298
  let tags = options.tags;
239
299
  if (!tags || tags.length === 0) {
240
300
  tags = (0, aws_cdk_1.tagsForStack)(stack);
@@ -263,7 +323,7 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
263
323
  rollback,
264
324
  hotswap: hotswapMode,
265
325
  extraUserAgent: options.extraUserAgent,
266
- hotswapPropertyOverrides: options.hotswapProperties ? (0, private_1.createHotswapPropertyOverrides)(options.hotswapProperties) : undefined,
326
+ hotswapPropertyOverrides: options.hotswapProperties ? (0, private_2.createHotswapPropertyOverrides)(options.hotswapProperties) : undefined,
267
327
  assetParallelism: options.assetParallelism,
268
328
  });
269
329
  switch (r.type) {
@@ -276,10 +336,13 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
276
336
  : `Stack is in a paused fail state (${r.status}) and command line arguments do not include "--no-rollback"`;
277
337
  const question = `${motivation}. Perform a regular deployment`;
278
338
  if (options.force) {
279
- await ioHost.notify((0, private_5.warn)(`${motivation}. Rolling back first (--force).`));
339
+ await ioHelper.notify(private_6.IO.DEFAULT_TOOLKIT_WARN.msg(`${motivation}. Rolling back first (--force).`));
280
340
  }
281
341
  else {
282
- const confirmed = await ioHost.requestResponse((0, private_5.confirm)(private_5.CODES.CDK_TOOLKIT_I5050, question, motivation, true, concurrency));
342
+ const confirmed = await ioHelper.requestResponse(private_6.IO.CDK_TOOLKIT_I5050.req(question, {
343
+ motivation,
344
+ concurrency,
345
+ }));
283
346
  if (!confirmed) {
284
347
  throw new shared_public_1.ToolkitError('Aborted by user');
285
348
  }
@@ -298,10 +361,13 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
298
361
  const question = `${motivation}. Perform a regular deployment`;
299
362
  // @todo no force here
300
363
  if (options.force) {
301
- await ioHost.notify((0, private_5.warn)(`${motivation}. Proceeding with regular deployment (--force).`));
364
+ await ioHelper.notify(private_6.IO.DEFAULT_TOOLKIT_WARN.msg(`${motivation}. Proceeding with regular deployment (--force).`));
302
365
  }
303
366
  else {
304
- const confirmed = await ioHost.requestResponse((0, private_5.confirm)(private_5.CODES.CDK_TOOLKIT_I5050, question, motivation, true, concurrency));
367
+ const confirmed = await ioHelper.requestResponse(private_6.IO.CDK_TOOLKIT_I5050.req(question, {
368
+ motivation,
369
+ concurrency,
370
+ }));
305
371
  if (!confirmed) {
306
372
  throw new shared_public_1.ToolkitError('Aborted by user');
307
373
  }
@@ -317,8 +383,8 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
317
383
  const message = deployResult.noOp
318
384
  ? ` ✅ ${stack.displayName} (no changes)`
319
385
  : ` ✅ ${stack.displayName}`;
320
- await ioHost.notify((0, private_5.result)(chalk.green('\n' + message), private_5.CODES.CDK_TOOLKIT_I5900, deployResult));
321
- deployDuration = await deployTimer.endAs(ioHost, 'deploy');
386
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5900.msg(chalk.green('\n' + message), deployResult));
387
+ deployDuration = await deploySpan.timing(private_6.IO.CDK_TOOLKIT_I5000);
322
388
  if (Object.keys(deployResult.outputs).length > 0) {
323
389
  const buffer = ['Outputs:'];
324
390
  stackOutputs[stack.stackName] = deployResult.outputs;
@@ -326,9 +392,9 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
326
392
  const value = deployResult.outputs[name];
327
393
  buffer.push(`${chalk.cyan(stack.id)}.${chalk.cyan(name)} = ${chalk.underline(chalk.cyan(value))}`);
328
394
  }
329
- await ioHost.notify((0, private_5.info)(buffer.join('\n')));
395
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5901.msg(buffer.join('\n')));
330
396
  }
331
- await ioHost.notify((0, private_5.info)(`Stack ARN:\n${deployResult.stackArn}`));
397
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5901.msg(`Stack ARN:\n${deployResult.stackArn}`));
332
398
  }
333
399
  catch (e) {
334
400
  // It has to be exactly this string because an integration test tests for
@@ -338,10 +404,10 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
338
404
  finally {
339
405
  if (options.traceLogs) {
340
406
  // deploy calls that originate from watch will come with their own cloudWatchLogMonitor
341
- const cloudWatchLogMonitor = options.cloudWatchLogMonitor ?? new aws_cdk_1.CloudWatchLogEventMonitor();
342
- const foundLogGroupsResult = await (0, aws_cdk_1.findCloudWatchLogGroups)(await this.sdkProvider('deploy'), { ioHost, action }, stack);
407
+ const cloudWatchLogMonitor = options.cloudWatchLogMonitor ?? new aws_cdk_1.CloudWatchLogEventMonitor({ ioHelper });
408
+ const foundLogGroupsResult = await (0, aws_cdk_1.findCloudWatchLogGroups)(await this.sdkProvider('deploy'), ioHelper, stack);
343
409
  cloudWatchLogMonitor.addLogGroups(foundLogGroupsResult.env, foundLogGroupsResult.sdk, foundLogGroupsResult.logGroupNames);
344
- await ioHost.notify((0, private_5.info)(`The following log groups are added: ${foundLogGroupsResult.logGroupNames}`, private_5.CODES.CDK_TOOLKIT_I5031));
410
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5031.msg(`The following log groups are added: ${foundLogGroupsResult.logGroupNames}`));
345
411
  }
346
412
  // If an outputs file has been specified, create the file path and write stack outputs to it once.
347
413
  // Outputs are written after all stacks have been deployed. If a stack deployment fails,
@@ -355,7 +421,7 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
355
421
  }
356
422
  }
357
423
  const duration = synthDuration.asMs + (deployDuration?.asMs ?? 0);
358
- await ioHost.notify((0, private_5.info)(`\n✨ Total time: ${(0, aws_cdk_1.formatTime)(duration)}s\n`, private_5.CODES.CDK_TOOLKIT_I5001, { duration }));
424
+ await deploySpan.end(`\n✨ Total time: ${(0, util_1.formatTime)(duration)}s\n`, { duration });
359
425
  };
360
426
  const assetBuildTime = options.assetBuildTime ?? deploy_1.AssetBuildTime.ALL_BEFORE_DEPLOY;
361
427
  const prebuildAssets = assetBuildTime === deploy_1.AssetBuildTime.ALL_BEFORE_DEPLOY;
@@ -364,10 +430,10 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
364
430
  stack,
365
431
  ...stack.dependencies.filter(x => cxapi.AssetManifestArtifact.isAssetManifestArtifact(x)),
366
432
  ]);
367
- const workGraph = new aws_cdk_1.WorkGraphBuilder({ ioHost, action }, prebuildAssets).build(stacksAndTheirAssetManifests);
433
+ const workGraph = new aws_cdk_1.WorkGraphBuilder(ioHelper, prebuildAssets).build(stacksAndTheirAssetManifests);
368
434
  // Unless we are running with '--force', skip already published assets
369
435
  if (!options.force) {
370
- await (0, private_1.removePublishedAssets)(workGraph, deployments, options);
436
+ await (0, private_2.removePublishedAssets)(workGraph, deployments, options);
371
437
  }
372
438
  const graphConcurrency = {
373
439
  'stack': concurrency,
@@ -387,10 +453,9 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
387
453
  * Implies hotswap deployments.
388
454
  */
389
455
  async watch(cx, options) {
390
- const assembly = await this.assemblyFromSource(cx, false);
391
- const ioHost = (0, private_5.withAction)(this.ioHost, 'watch');
456
+ const assembly = await (0, private_1.assemblyFromSource)(cx, false);
457
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, 'watch');
392
458
  const rootDir = options.watchDir ?? process.cwd();
393
- await ioHost.notify((0, private_5.debug)(`root directory used for 'watch' is: ${rootDir}`));
394
459
  if (options.include === undefined && options.exclude === undefined) {
395
460
  throw new shared_public_1.ToolkitError("Cannot use the 'watch' command without specifying at least one directory to monitor. " +
396
461
  'Make sure to add a "watch" key to your cdk.json');
@@ -400,11 +465,10 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
400
465
  // 2. "watch" setting without an "include" key? We default to observing "./**".
401
466
  // 3. "watch" setting with an empty "include" key? We default to observing "./**".
402
467
  // 4. Non-empty "include" key? Just use the "include" key.
403
- const watchIncludes = (0, private_3.patternsArrayForWatch)(options.include, {
468
+ const watchIncludes = (0, private_4.patternsArrayForWatch)(options.include, {
404
469
  rootDir,
405
470
  returnRootDirIfEmpty: true,
406
471
  });
407
- await ioHost.notify((0, private_5.debug)(`'include' patterns for 'watch': ${JSON.stringify(watchIncludes)}`));
408
472
  // For the "exclude" subkey under the "watch" key,
409
473
  // the behavior is to add some default excludes in addition to the ones specified by the user:
410
474
  // 1. The CDK output directory.
@@ -412,27 +476,25 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
412
476
  // 3. Any directory's content whose name starts with a dot.
413
477
  // 4. Any node_modules and its content (even if it's not a JS/TS project, you might be using a local aws-cli package)
414
478
  const outdir = options.outdir ?? 'cdk.out';
415
- const watchExcludes = (0, private_3.patternsArrayForWatch)(options.exclude, {
479
+ const watchExcludes = (0, private_4.patternsArrayForWatch)(options.exclude, {
416
480
  rootDir,
417
481
  returnRootDirIfEmpty: false,
418
482
  }).concat(`${outdir}/**`, '**/.*', '**/.*/**', '**/node_modules/**');
419
- await ioHost.notify((0, private_5.debug)(`'exclude' patterns for 'watch': ${JSON.stringify(watchExcludes)}`));
420
- // Since 'cdk deploy' is a relatively slow operation for a 'watch' process,
421
- // introduce a concurrency latch that tracks the state.
422
- // This way, if file change events arrive when a 'cdk deploy' is still executing,
423
- // we will batch them, and trigger another 'cdk deploy' after the current one finishes,
424
- // making sure 'cdk deploy's always execute one at a time.
425
- // Here's a diagram showing the state transitions:
426
- // -------------- -------- file changed -------------- file changed -------------- file changed
427
- // | | ready event | | ------------------> | | ------------------> | | --------------|
428
- // | pre-ready | -------------> | open | | deploying | | queued | |
429
- // | | | | <------------------ | | <------------------ | | <-------------|
430
- // -------------- -------- 'cdk deploy' done -------------- 'cdk deploy' done --------------
483
+ // Print some debug information on computed settings
484
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5310.msg([
485
+ `root directory used for 'watch' is: ${rootDir}`,
486
+ `'include' patterns for 'watch': ${JSON.stringify(watchIncludes)}`,
487
+ `'exclude' patterns for 'watch': ${JSON.stringify(watchExcludes)}`,
488
+ ].join('\n'), {
489
+ watchDir: rootDir,
490
+ includes: watchIncludes,
491
+ excludes: watchExcludes,
492
+ }));
431
493
  let latch = 'pre-ready';
432
- const cloudWatchLogMonitor = options.traceLogs ? new aws_cdk_1.CloudWatchLogEventMonitor() : undefined;
494
+ const cloudWatchLogMonitor = options.traceLogs ? new aws_cdk_1.CloudWatchLogEventMonitor({ ioHelper }) : undefined;
433
495
  const deployAndWatch = async () => {
434
496
  latch = 'deploying';
435
- cloudWatchLogMonitor?.deactivate();
497
+ await cloudWatchLogMonitor?.deactivate();
436
498
  await this.invokeDeployFromWatch(assembly, options, cloudWatchLogMonitor);
437
499
  // If latch is still 'deploying' after the 'await', that's fine,
438
500
  // but if it's 'queued', that means we need to deploy again
@@ -440,11 +502,11 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
440
502
  // TypeScript doesn't realize latch can change between 'awaits',
441
503
  // and thinks the above 'while' condition is always 'false' without the cast
442
504
  latch = 'deploying';
443
- await ioHost.notify((0, private_5.info)("Detected file changes during deployment. Invoking 'cdk deploy' again"));
505
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5315.msg("Detected file changes during deployment. Invoking 'cdk deploy' again"));
444
506
  await this.invokeDeployFromWatch(assembly, options, cloudWatchLogMonitor);
445
507
  }
446
508
  latch = 'open';
447
- cloudWatchLogMonitor?.activate();
509
+ await cloudWatchLogMonitor?.activate();
448
510
  };
449
511
  chokidar
450
512
  .watch(watchIncludes, {
@@ -453,22 +515,26 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
453
515
  })
454
516
  .on('ready', async () => {
455
517
  latch = 'open';
456
- await ioHost.notify((0, private_5.debug)("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment"));
457
- await ioHost.notify((0, private_5.info)("Triggering initial 'cdk deploy'"));
518
+ await ioHelper.notify(private_6.IO.DEFAULT_TOOLKIT_DEBUG.msg("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment"));
519
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5314.msg("Triggering initial 'cdk deploy'"));
458
520
  await deployAndWatch();
459
521
  })
460
522
  .on('all', async (event, filePath) => {
523
+ const watchEvent = {
524
+ event,
525
+ path: filePath,
526
+ };
461
527
  if (latch === 'pre-ready') {
462
- await ioHost.notify((0, private_5.info)(`'watch' is observing ${event === 'addDir' ? 'directory' : 'the file'} '${filePath}' for changes`));
528
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5311.msg(`'watch' is observing ${event === 'addDir' ? 'directory' : 'the file'} '${filePath}' for changes`, watchEvent));
463
529
  }
464
530
  else if (latch === 'open') {
465
- await ioHost.notify((0, private_5.info)(`Detected change to '${filePath}' (type: ${event}). Triggering 'cdk deploy'`));
531
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5312.msg(`Detected change to '${filePath}' (type: ${event}). Triggering 'cdk deploy'`, watchEvent));
466
532
  await deployAndWatch();
467
533
  }
468
534
  else {
469
535
  // this means latch is either 'deploying' or 'queued'
470
536
  latch = 'queued';
471
- await ioHost.notify((0, private_5.info)(`Detected change to '${filePath}' (type: ${event}) while 'cdk deploy' is still running. Will queue for another deployment after this one finishes'`));
537
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I5313.msg(`Detected change to '${filePath}' (type: ${event}) while 'cdk deploy' is still running. Will queue for another deployment after this one finishes'`, watchEvent));
472
538
  }
473
539
  });
474
540
  }
@@ -478,26 +544,29 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
478
544
  * Rolls back the selected stacks.
479
545
  */
480
546
  async rollback(cx, options) {
481
- const assembly = await this.assemblyFromSource(cx);
547
+ const assembly = await (0, private_1.assemblyFromSource)(cx);
482
548
  return this._rollback(assembly, 'rollback', options);
483
549
  }
484
550
  /**
485
551
  * Helper to allow rollback being called as part of the deploy or watch action.
486
552
  */
487
553
  async _rollback(assembly, action, options) {
488
- const ioHost = (0, private_5.withAction)(this.ioHost, action);
489
- const synthTimer = private_5.Timer.start();
554
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, action);
555
+ const synthSpan = await ioHelper.span(private_6.SPAN.SYNTH_ASSEMBLY).begin({ stacks: options.stacks });
490
556
  const stacks = assembly.selectStacksV2(options.stacks);
491
- await this.validateStacksMetadata(stacks, ioHost);
492
- await synthTimer.endAs(ioHost, 'synth');
557
+ await this.validateStacksMetadata(stacks, ioHelper);
558
+ await synthSpan.end();
493
559
  if (stacks.stackCount === 0) {
494
- await ioHost.notify((0, private_5.error)('No stacks selected', private_5.CODES.CDK_TOOLKIT_E6001));
560
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_E6001.msg('No stacks selected'));
495
561
  return;
496
562
  }
497
563
  let anyRollbackable = false;
498
- for (const stack of stacks.stackArtifacts) {
499
- await ioHost.notify((0, private_5.info)(`Rolling back ${chalk.bold(stack.displayName)}`));
500
- const rollbackTimer = private_5.Timer.start();
564
+ for (const [index, stack] of stacks.stackArtifacts.entries()) {
565
+ const rollbackSpan = await ioHelper.span(private_6.SPAN.ROLLBACK_STACK).begin(`Rolling back ${chalk.bold(stack.displayName)}`, {
566
+ total: stacks.stackCount,
567
+ current: index + 1,
568
+ stack,
569
+ });
501
570
  const deployments = await this.deploymentsForAction('rollback');
502
571
  try {
503
572
  const stackResult = await deployments.rollbackStack({
@@ -511,10 +580,10 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
511
580
  if (!stackResult.notInRollbackableState) {
512
581
  anyRollbackable = true;
513
582
  }
514
- await rollbackTimer.endAs(ioHost, 'rollback');
583
+ await rollbackSpan.end();
515
584
  }
516
585
  catch (e) {
517
- await ioHost.notify((0, private_5.error)(`\n ❌ ${chalk.bold(stack.displayName)} failed: ${(0, aws_cdk_1.formatErrorMessage)(e)}`, private_5.CODES.CDK_TOOLKIT_E6900));
586
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_E6900.msg(`\n ❌ ${chalk.bold(stack.displayName)} failed: ${(0, util_1.formatErrorMessage)(e)}`, { error: e }));
518
587
  throw new shared_public_1.ToolkitError('Rollback failed (use --force to orphan failing resources)');
519
588
  }
520
589
  }
@@ -528,82 +597,67 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
528
597
  * Destroys the selected Stacks.
529
598
  */
530
599
  async destroy(cx, options) {
531
- const assembly = await this.assemblyFromSource(cx);
600
+ const assembly = await (0, private_1.assemblyFromSource)(cx);
532
601
  return this._destroy(assembly, 'destroy', options);
533
602
  }
534
603
  /**
535
604
  * Helper to allow destroy being called as part of the deploy action.
536
605
  */
537
606
  async _destroy(assembly, action, options) {
538
- const ioHost = (0, private_5.withAction)(this.ioHost, action);
539
- const synthTimer = private_5.Timer.start();
607
+ const ioHelper = (0, shared_private_1.asIoHelper)(this.ioHost, action);
608
+ const synthSpan = await ioHelper.span(private_6.SPAN.SYNTH_ASSEMBLY).begin({ stacks: options.stacks });
540
609
  // The stacks will have been ordered for deployment, so reverse them for deletion.
541
610
  const stacks = await assembly.selectStacksV2(options.stacks).reversed();
542
- await synthTimer.endAs(ioHost, 'synth');
611
+ await synthSpan.end();
543
612
  const motivation = 'Destroying stacks is an irreversible action';
544
613
  const question = `Are you sure you want to delete: ${chalk.red(stacks.hierarchicalIds.join(', '))}`;
545
- const confirmed = await ioHost.requestResponse((0, private_5.confirm)(private_5.CODES.CDK_TOOLKIT_I7010, question, motivation, true));
614
+ const confirmed = await ioHelper.requestResponse(private_6.IO.CDK_TOOLKIT_I7010.req(question, { motivation }));
546
615
  if (!confirmed) {
547
- return ioHost.notify((0, private_5.error)('Aborted by user', private_5.CODES.CDK_TOOLKIT_E7010));
616
+ return ioHelper.notify(private_6.IO.CDK_TOOLKIT_E7010.msg('Aborted by user'));
548
617
  }
549
- const destroyTimer = private_5.Timer.start();
618
+ const destroySpan = await ioHelper.span(private_6.SPAN.DESTROY_ACTION).begin({
619
+ stacks: stacks.stackArtifacts,
620
+ });
550
621
  try {
551
622
  for (const [index, stack] of stacks.stackArtifacts.entries()) {
552
- await ioHost.notify((0, private_5.success)(`${chalk.blue(stack.displayName)}: destroying... [${index + 1}/${stacks.stackCount}]`));
553
623
  try {
624
+ const singleDestroySpan = await ioHelper.span(private_6.SPAN.DESTROY_STACK)
625
+ .begin(chalk.green(`${chalk.blue(stack.displayName)}: destroying... [${index + 1}/${stacks.stackCount}]`), {
626
+ total: stacks.stackCount,
627
+ current: index + 1,
628
+ stack,
629
+ });
554
630
  const deployments = await this.deploymentsForAction(action);
555
631
  await deployments.destroyStack({
556
632
  stack,
557
633
  deployName: stack.stackName,
558
634
  roleArn: options.roleArn,
559
- ci: options.ci,
560
635
  });
561
- await ioHost.notify((0, private_5.success)(`\n ✅ ${chalk.blue(stack.displayName)}: ${action}ed`));
636
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_I7900.msg(chalk.green(`\n ✅ ${chalk.blue(stack.displayName)}: ${action}ed`), stack));
637
+ await singleDestroySpan.end();
562
638
  }
563
639
  catch (e) {
564
- await ioHost.notify((0, private_5.error)(`\n ❌ ${chalk.blue(stack.displayName)}: ${action} failed ${e}`, private_5.CODES.CDK_TOOLKIT_E7900));
640
+ await ioHelper.notify(private_6.IO.CDK_TOOLKIT_E7900.msg(`\n ❌ ${chalk.blue(stack.displayName)}: ${action} failed ${e}`, { error: e }));
565
641
  throw e;
566
642
  }
567
643
  }
568
644
  }
569
645
  finally {
570
- await destroyTimer.endAs(ioHost, 'destroy');
646
+ await destroySpan.end();
571
647
  }
572
648
  }
573
649
  /**
574
650
  * Validate the stacks for errors and warnings according to the CLI's current settings
575
651
  */
576
652
  async validateStacksMetadata(stacks, ioHost) {
577
- // @TODO define these somewhere central
578
- const code = (level) => {
653
+ const builder = (level) => {
579
654
  switch (level) {
580
- case 'error': return 'CDK_ASSEMBLY_E9999';
581
- case 'warn': return 'CDK_ASSEMBLY_W9999';
582
- default: return 'CDK_ASSEMBLY_I9999';
655
+ case 'error': return private_6.IO.CDK_ASSEMBLY_E9999;
656
+ case 'warn': return private_6.IO.CDK_ASSEMBLY_W9999;
657
+ default: return private_6.IO.CDK_ASSEMBLY_I9999;
583
658
  }
584
659
  };
585
- await stacks.validateMetadata(this.props.assemblyFailureAt, async (level, msg) => ioHost.notify({
586
- time: new Date(),
587
- level,
588
- code: code(level),
589
- message: `[${level} at ${msg.id}] ${msg.entry.data}`,
590
- data: msg,
591
- }));
592
- }
593
- /**
594
- * Creates a Toolkit internal CloudAssembly from a CloudAssemblySource.
595
- * @param assemblySource the source for the cloud assembly
596
- * @param cache if the assembly should be cached, default: `true`
597
- * @returns the CloudAssembly object
598
- */
599
- async assemblyFromSource(assemblySource, cache = true) {
600
- if (assemblySource instanceof private_4.StackAssembly) {
601
- return assemblySource;
602
- }
603
- if (cache) {
604
- return new private_4.StackAssembly(await new private_4.CachedCloudAssemblySource(assemblySource).produce());
605
- }
606
- return new private_4.StackAssembly(await assemblySource.produce());
660
+ await stacks.validateMetadata(this.props.assemblyFailureAt, async (level, msg) => ioHost.notify(builder(level).msg(`[${level} at ${msg.id}] ${msg.entry.data}`, msg)));
607
661
  }
608
662
  /**
609
663
  * Create a deployments class
@@ -612,8 +666,7 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
612
666
  return new aws_cdk_1.Deployments({
613
667
  sdkProvider: await this.sdkProvider(action),
614
668
  toolkitStackName: this.toolkitStackName,
615
- ioHost: this.ioHost, // @todo temporary while we have to separate IIoHost interfaces
616
- action,
669
+ ioHelper: (0, shared_private_1.asIoHelper)(this.ioHost, action),
617
670
  });
618
671
  }
619
672
  async invokeDeployFromWatch(assembly, options, cloudWatchLogMonitor) {
@@ -635,4 +688,4 @@ class Toolkit extends private_4.CloudAssemblySourceBuilder {
635
688
  }
636
689
  }
637
690
  exports.Toolkit = Toolkit;
638
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGtpdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRvb2xraXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsa0NBQWtDO0FBQ2xDLHlDQUF5QztBQUN6QywrQkFBK0I7QUFDL0IscUNBQXFDO0FBQ3JDLCtCQUErQjtBQUcvQiw4Q0FBd0Y7QUFDeEYsdURBQWlKO0FBRWpKLHFEQUErRDtBQUsvRCxzREFBaUU7QUFFakUsNENBQW9hO0FBQ3BhLDBEQUFxRjtBQUNyRiwyREFBOEo7QUFFOUosK0NBQXFNO0FBQ3JNLHdEQUFvRDtBQWlFcEQ7O0dBRUc7QUFDSCxNQUFhLE9BQVEsU0FBUSxvQ0FBMEI7SUFZakI7SUFYcEM7O09BRUc7SUFDYSxnQkFBZ0IsQ0FBUztJQUV6Qzs7T0FFRztJQUNhLE1BQU0sQ0FBVTtJQUN4QixZQUFZLENBQWU7SUFFbkMsWUFBb0MsUUFBd0IsRUFBRTtRQUM1RCxLQUFLLEVBQUUsQ0FBQztRQUQwQixVQUFLLEdBQUwsS0FBSyxDQUFxQjtRQUU1RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixJQUFJLG9DQUEwQixDQUFDO1FBRTdFLG9GQUFvRjtRQUNwRixNQUFNLFlBQVksR0FBRyxtQkFBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzFDLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLFlBQVksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLE1BQWEsQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFDRCxJQUFJLE1BQU0sR0FBRyxZQUF1QixDQUFDO1FBQ3JDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUMzQixNQUFNLEdBQUcsSUFBQSx1QkFBYSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDMUIsTUFBTSxHQUFHLElBQUEsc0JBQVksRUFB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YSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLDZDQUE2QztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBcHNCRCwwQkFvc0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCAqIGFzIGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCAqIGFzIGNob2tpZGFyIGZyb20gJ2Nob2tpZGFyJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IFRvb2xraXRTZXJ2aWNlcyB9IGZyb20gJy4vcHJpdmF0ZSc7XG5pbXBvcnQgeyBBc3NlbWJseURhdGEsIFN0YWNrQW5kQXNzZW1ibHlEYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBBc3NldEJ1aWxkVGltZSwgdHlwZSBEZXBsb3lPcHRpb25zLCBSZXF1aXJlQXBwcm92YWwgfSBmcm9tICcuLi9hY3Rpb25zL2RlcGxveSc7XG5pbXBvcnQgeyB0eXBlIEV4dGVuZGVkRGVwbG95T3B0aW9ucywgYnVpbGRQYXJhbWV0ZXJNYXAsIGNyZWF0ZUhvdHN3YXBQcm9wZXJ0eU92ZXJyaWRlcywgcmVtb3ZlUHVibGlzaGVkQXNzZXRzIH0gZnJvbSAnLi4vYWN0aW9ucy9kZXBsb3kvcHJpdmF0ZSc7XG5pbXBvcnQgeyB0eXBlIERlc3Ryb3lPcHRpb25zIH0gZnJvbSAnLi4vYWN0aW9ucy9kZXN0cm95JztcbmltcG9ydCB7IGRpZmZSZXF1aXJlc0FwcHJvdmFsIH0gZnJvbSAnLi4vYWN0aW9ucy9kaWZmL3ByaXZhdGUnO1xuaW1wb3J0IHsgdHlwZSBMaXN0T3B0aW9ucyB9IGZyb20gJy4uL2FjdGlvbnMvbGlzdCc7XG5pbXBvcnQgeyB0eXBlIFJvbGxiYWNrT3B0aW9ucyB9IGZyb20gJy4uL2FjdGlvbnMvcm9sbGJhY2snO1xuaW1wb3J0IHsgdHlwZSBTeW50aE9wdGlvbnMgfSBmcm9tICcuLi9hY3Rpb25zL3N5bnRoJztcbmltcG9ydCB7IFdhdGNoT3B0aW9ucyB9IGZyb20gJy4uL2FjdGlvbnMvd2F0Y2gnO1xuaW1wb3J0IHsgcGF0dGVybnNBcnJheUZvcldhdGNoIH0gZnJvbSAnLi4vYWN0aW9ucy93YXRjaC9wcml2YXRlJztcbmltcG9ydCB7IHR5cGUgU2RrQ29uZmlnIH0gZnJvbSAnLi4vYXBpL2F3cy1hdXRoJztcbmltcG9ydCB7IERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FLCBTZGtQcm92aWRlciwgU3VjY2Vzc2Z1bERlcGxveVN0YWNrUmVzdWx0LCBTdGFja0NvbGxlY3Rpb24sIERlcGxveW1lbnRzLCBIb3Rzd2FwTW9kZSwgUmVzb3VyY2VNaWdyYXRvciwgb2JzY3VyZVRlbXBsYXRlLCBzZXJpYWxpemVTdHJ1Y3R1cmUsIHRhZ3NGb3JTdGFjaywgQ2xpSW9Ib3N0LCB2YWxpZGF0ZVNuc1RvcGljQXJuLCBDb25jdXJyZW5jeSwgV29ya0dyYXBoQnVpbGRlciwgQXNzZXRCdWlsZE5vZGUsIEFzc2V0UHVibGlzaE5vZGUsIFN0YWNrTm9kZSwgZm9ybWF0RXJyb3JNZXNzYWdlLCBDbG91ZFdhdGNoTG9nRXZlbnRNb25pdG9yLCBmaW5kQ2xvdWRXYXRjaExvZ0dyb3VwcywgZm9ybWF0VGltZSwgU3RhY2tEZXRhaWxzIH0gZnJvbSAnLi4vYXBpL2F3cy1jZGsnO1xuaW1wb3J0IHsgSUNsb3VkQXNzZW1ibHlTb3VyY2UsIFN0YWNrU2VsZWN0aW9uU3RyYXRlZ3kgfSBmcm9tICcuLi9hcGkvY2xvdWQtYXNzZW1ibHknO1xuaW1wb3J0IHsgQUxMX1NUQUNLUywgQ2FjaGVkQ2xvdWRBc3NlbWJseVNvdXJjZSwgQ2xvdWRBc3NlbWJseVNvdXJjZUJ1aWxkZXIsIElkZW50aXR5Q2xvdWRBc3NlbWJseVNvdXJjZSwgU3RhY2tBc3NlbWJseSB9IGZyb20gJy4uL2FwaS9jbG91ZC1hc3NlbWJseS9wcml2YXRlJztcbmltcG9ydCB7IElJb0hvc3QsIElvTWVzc2FnZUNvZGUsIElvTWVzc2FnZUxldmVsIH0gZnJvbSAnLi4vYXBpL2lvJztcbmltcG9ydCB7IGFzU2RrTG9nZ2VyLCB3aXRoQWN0aW9uLCBUaW1lciwgY29uZmlybSwgZXJyb3IsIGluZm8sIHN1Y2Nlc3MsIHdhcm4sIEFjdGlvbkF3YXJlSW9Ib3N0LCBkZWJ1ZywgcmVzdWx0LCB3aXRob3V0RW1vamlzLCB3aXRob3V0Q29sb3IsIHdpdGhUcmltbWVkV2hpdGVzcGFjZSwgQ09ERVMgfSBmcm9tICcuLi9hcGkvaW8vcHJpdmF0ZSc7XG5pbXBvcnQgeyBUb29sa2l0RXJyb3IgfSBmcm9tICcuLi9hcGkvc2hhcmVkLXB1YmxpYyc7XG5cbi8qKlxuICogVGhlIGN1cnJlbnQgYWN0aW9uIGJlaW5nIHBlcmZvcm1lZCBieSB0aGUgQ0xJLiAnbm9uZScgcmVwcmVzZW50cyB0aGUgYWJzZW5jZSBvZiBhbiBhY3Rpb24uXG4gKi9cbmV4cG9ydCB0eXBlIFRvb2xraXRBY3Rpb24gPVxufCAnYXNzZW1ibHknXG58ICdib290c3RyYXAnXG58ICdzeW50aCdcbnwgJ2xpc3QnXG58ICdkaWZmJ1xufCAnZGVwbG95J1xufCAncm9sbGJhY2snXG58ICd3YXRjaCdcbnwgJ2Rlc3Ryb3knXG58ICdkb2N0b3InXG58ICdnYydcbnwgJ2ltcG9ydCdcbnwgJ21ldGFkYXRhJ1xufCAnaW5pdCdcbnwgJ21pZ3JhdGUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRvb2xraXRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBJb0hvc3QgaW1wbGVtZW50YXRpb24sIGhhbmRsaW5nIHRoZSBpbmxpbmUgaW50ZXJhY3Rpb25zIGJldHdlZW4gdGhlIFRvb2xraXQgYW5kIGFuIGludGVncmF0aW9uLlxuICAgKi9cbiAgaW9Ib3N0PzogSUlvSG9zdDtcblxuICAvKipcbiAgICogQWxsb3cgZW1vamlzIGluIG1lc3NhZ2VzIHNlbnQgdG8gdGhlIElvSG9zdC5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgZW1vamlzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBhbGxvdyBBTlNJIGNvbG9ycyBhbmQgZm9ybWF0dGluZyBpbiBJb0hvc3QgbWVzc2FnZXMuXG4gICAqIFNldHRpbmcgdGhpcyB2YWx1ZSB0byBgZmFsc2VgIGVuZm9yY2VzIHRoYXQgbm8gY29sb3Igb3Igc3R5bGUgc2hvd3MgdXBcbiAgICogaW4gbWVzc2FnZXMgc2VudCB0byB0aGUgSW9Ib3N0LlxuICAgKiBTZXR0aW5nIHRoaXMgdmFsdWUgdG8gdHJ1ZSBpcyBhIG5vLW9wOyBpdCBpcyBlcXVpdmFsZW50IHRvIHRoZSBkZWZhdWx0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRldGVjdHMgY29sb3IgZnJvbSB0aGUgVFRZIHN0YXR1cyBvZiB0aGUgSW9Ib3N0XG4gICAqL1xuICBjb2xvcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIFNESy5cbiAgICovXG4gIHNka0NvbmZpZz86IFNka0NvbmZpZztcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgdG9vbGtpdCBzdGFjayB0byBiZSB1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIkNES1Rvb2xraXRcIlxuICAgKi9cbiAgdG9vbGtpdFN0YWNrTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogRmFpbCBDbG91ZCBBc3NlbWJsaWVzXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiZXJyb3JcIlxuICAgKi9cbiAgYXNzZW1ibHlGYWlsdXJlQXQ/OiAnZXJyb3InIHwgJ3dhcm4nIHwgJ25vbmUnO1xufVxuXG4vKipcbiAqIFRoZSBBV1MgQ0RLIFByb2dyYW1tYXRpYyBUb29sa2l0XG4gKi9cbmV4cG9ydCBjbGFzcyBUb29sa2l0IGV4dGVuZHMgQ2xvdWRBc3NlbWJseVNvdXJjZUJ1aWxkZXIgaW1wbGVtZW50cyBBc3luY0Rpc3Bvc2FibGUge1xuICAvKipcbiAgICogVGhlIHRvb2xraXQgc3RhY2sgbmFtZSB1c2VkIGZvciBib290c3RyYXBwaW5nIHJlc291cmNlcy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB0b29sa2l0U3RhY2tOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBJb0hvc3Qgb2YgdGhpcyBUb29sa2l0XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaW9Ib3N0OiBJSW9Ib3N0O1xuICBwcml2YXRlIF9zZGtQcm92aWRlcj86IFNka1Byb3ZpZGVyO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBUb29sa2l0T3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnRvb2xraXRTdGFja05hbWUgPSBwcm9wcy50b29sa2l0U3RhY2tOYW1lID8/IERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FO1xuXG4gICAgLy8gSGFja3kgd2F5IHRvIHJlLXVzZSB0aGUgZ2xvYmFsIElvSG9zdCB1bnRpbCB3ZSBoYXZlIGZ1bGx5IHJlbW92ZWQgdGhlIG5lZWQgZm9yIGl0XG4gICAgY29uc3QgZ2xvYmFsSW9Ib3N0ID0gQ2xpSW9Ib3N0Lmluc3RhbmNlKCk7XG4gICAgaWYgKHByb3BzLmlvSG9zdCkge1xuICAgICAgZ2xvYmFsSW9Ib3N0LnJlZ2lzdGVySW9Ib3N0KHByb3BzLmlvSG9zdCBhcyBhbnkpO1xuICAgIH1cbiAgICBsZXQgaW9Ib3N0ID0gZ2xvYmFsSW9Ib3N0IGFzIElJb0hvc3Q7XG4gICAgaWYgKHByb3BzLmVtb2ppcyA9PT0gZmFsc2UpIHtcbiAgICAgIGlvSG9zdCA9IHdpdGhvdXRFbW9qaXMoaW9Ib3N0KTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmNvbG9yID09PSBmYWxzZSkge1xuICAgICAgaW9Ib3N0ID0gd2l0aG91dENvbG9yKGlvSG9zdCk7XG4gICAgfVxuICAgIC8vIEFmdGVyIHJlbW92aW5nIGVtb2ppcyBhbmQgY29sb3IsIHdlIG1pZ2h0IGVuZCB1cCB3aXRoIGZsb2F0aW5nIHdoaXRlc3BhY2UgYXQgZWl0aGVyIGVuZCBvZiB0aGUgbWVzc2FnZVxuICAgIC8vIFRoaXMgYWxzbyByZW1vdmVzIG5ld2xpbmVzIHRoYXQgd2UgY3VycmVudGx5IGVtaXQgZm9yIENMSSBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgICB0aGlzLmlvSG9zdCA9IHdpdGhUcmltbWVkV2hpdGVzcGFjZShpb0hvc3QpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gbm90aGluZyB0byBkbyB5ZXRcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBbU3ltYm9sLmFzeW5jRGlzcG9zZV0oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5kaXNwb3NlKCk7XG4gIH1cblxuICAvKipcbiAgICogQWNjZXNzIHRvIHRoZSBBV1MgU0RLXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNka1Byb3ZpZGVyKGFjdGlvbjogVG9vbGtpdEFjdGlvbik6IFByb21pc2U8U2RrUHJvdmlkZXI+IHtcbiAgICAvLyBAdG9kbyB0aGlzIG5lZWRzIHRvIGJlIGRpZmZlcmVudCBpbnN0YW5jZSBwZXIgYWN0aW9uXG4gICAgaWYgKCF0aGlzLl9zZGtQcm92aWRlcikge1xuICAgICAgdGhpcy5fc2RrUHJvdmlkZXIgPSBhd2FpdCBTZGtQcm92aWRlci53aXRoQXdzQ2xpQ29tcGF0aWJsZURlZmF1bHRzKHtcbiAgICAgICAgLi4udGhpcy5wcm9wcy5zZGtDb25maWcsXG4gICAgICAgIGxvZ2dlcjogYXNTZGtMb2dnZXIodGhpcy5pb0hvc3QsIGFjdGlvbiksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc2RrUHJvdmlkZXI7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIHByb3ZpZGUgdGhlIENsb3VkQXNzZW1ibHlTb3VyY2VCdWlsZGVyIHdpdGggcmVxdWlyZWQgdG9vbGtpdCBzZXJ2aWNlc1xuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIHNvdXJjZUJ1aWxkZXJTZXJ2aWNlcygpOiBQcm9taXNlPFRvb2xraXRTZXJ2aWNlcz4ge1xuICAgIHJldHVybiB7XG4gICAgICBpb0hvc3Q6IHdpdGhBY3Rpb24odGhpcy5pb0hvc3QsICdhc3NlbWJseScpLFxuICAgICAgc2RrUHJvdmlkZXI6IGF3YWl0IHRoaXMuc2RrUHJvdmlkZXIoJ2Fzc2VtYmx5JyksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW50aCBBY3Rpb25cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzeW50aChjeDogSUNsb3VkQXNzZW1ibHlTb3VyY2UsIG9wdGlvbnM6IFN5bnRoT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxJQ2xvdWRBc3NlbWJseVNvdXJjZT4ge1xuICAgIGNvbnN0IGlvSG9zdCA9IHdpdGhBY3Rpb24odGhpcy5pb0hvc3QsICdzeW50aCcpO1xuICAgIGNvbnN0IHN5bnRoVGltZXIgPSBUaW1lci5zdGFydCgpO1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgdGhpcy5hc3NlbWJseUZyb21Tb3VyY2UoY3gpO1xuICAgIGNvbnN0IHN0YWNrcyA9IGFzc2VtYmx5LnNlbGVjdFN0YWNrc1YyKG9wdGlvbnMuc3RhY2tzID8/IEFMTF9TVEFDS1MpO1xuICAgIGNvbnN0IGF1dG9WYWxpZGF0ZVN0YWNrcyA9IG9wdGlvbnMudmFsaWRhdGVTdGFja3MgPyBbYXNzZW1ibHkuc2VsZWN0U3RhY2tzRm9yVmFsaWRhdGlvbigpXSA6IFtdO1xuICAgIGF3YWl0IHRoaXMudmFsaWRhdGVTdGFja3NNZXRhZGF0YShzdGFja3MuY29uY2F0KC4uLmF1dG9WYWxpZGF0ZVN0YWNrcyksIGlvSG9zdCk7XG4gICAgYXdhaXQgc3ludGhUaW1lci5lbmRBcyhpb0hvc3QsICdzeW50aCcpO1xuXG4gICAgLy8gaWYgd2UgaGF2ZSBhIHNpbmdsZSBzdGFjaywgcHJpbnQgaXQgdG8gU1RET1VUXG4gICAgY29uc3QgbWVzc2FnZSA9IGBTdWNjZXNzZnVsbHkgc3ludGhlc2l6ZWQgdG8gJHtjaGFsay5ibHVlKHBhdGgucmVzb2x2ZShzdGFja3MuYXNzZW1ibHkuZGlyZWN0b3J5KSl9YDtcbiAgICBjb25zdCBhc3NlbWJseURhdGE6IEFzc2VtYmx5RGF0YSA9IHtcbiAgICAgIGFzc2VtYmx5RGlyZWN0b3J5OiBzdGFja3MuYXNzZW1ibHkuZGlyZWN0b3J5LFxuICAgICAgc3RhY2tzQ291bnQ6IHN0YWNrcy5zdGFja0NvdW50LFxuICAgICAgc3RhY2tJZHM6IHN0YWNrcy5oaWVyYXJjaGljYWxJZHMsXG4gICAgfTtcblxuICAgIGlmIChzdGFja3Muc3RhY2tDb3VudCA9PT0gMSkge1xuICAgICAgY29uc3QgZmlyc3RTdGFjayA9IHN0YWNrcy5maXJzdFN0YWNrITtcbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gZmlyc3RTdGFjay50ZW1wbGF0ZTtcbiAgICAgIGNvbnN0IG9ic2N1cmVkVGVtcGxhdGUgPSBvYnNjdXJlVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShyZXN1bHQobWVzc2FnZSwgQ09ERVMuQ0RLX1RPT0xLSVRfSTE5MDEsIHtcbiAgICAgICAgLi4uYXNzZW1ibHlEYXRhLFxuICAgICAgICBzdGFjazoge1xuICAgICAgICAgIHN0YWNrTmFtZTogZmlyc3RTdGFjay5zdGFja05hbWUsXG4gICAgICAgICAgaGllcmFyY2hpY2FsSWQ6IGZpcnN0U3RhY2suaGllcmFyY2hpY2FsSWQsXG4gICAgICAgICAgdGVtcGxhdGUsXG4gICAgICAgICAgc3RyaW5naWZpZWRKc29uOiBzZXJpYWxpemVTdHJ1Y3R1cmUob2JzY3VyZWRUZW1wbGF0ZSwgdHJ1ZSksXG4gICAgICAgICAgc3RyaW5naWZpZWRZYW1sOiBzZXJpYWxpemVTdHJ1Y3R1cmUob2JzY3VyZWRUZW1wbGF0ZSwgZmFsc2UpLFxuICAgICAgICB9LFxuICAgICAgfSBhcyBTdGFja0FuZEFzc2VtYmx5RGF0YSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub3Qgb3V0cHV0dGluZyB0ZW1wbGF0ZSB0byBzdGRvdXQsIGxldCdzIGV4cGxhaW4gdGhpbmdzIHRvIHRoZSB1c2VyIGEgbGl0dGxlIGJpdC4uLlxuICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShyZXN1bHQoY2hhbGsuZ3JlZW4obWVzc2FnZSksIENPREVTLkNES19UT09MS0lUX0kxOTAyLCBhc3NlbWJseURhdGEpKTtcbiAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoaW5mbyhgU3VwcGx5IGEgc3RhY2sgaWQgKCR7c3RhY2tzLnN0YWNrQXJ0aWZhY3RzLm1hcCgocykgPT4gY2hhbGsuZ3JlZW4ocy5oaWVyYXJjaGljYWxJZCkpLmpvaW4oJywgJyl9KSB0byBkaXNwbGF5IGl0cyB0ZW1wbGF0ZS5gKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJZGVudGl0eUNsb3VkQXNzZW1ibHlTb3VyY2UoYXNzZW1ibHkuYXNzZW1ibHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3QgQWN0aW9uXG4gICAqXG4gICAqIExpc3Qgc2VsZWN0ZWQgc3RhY2tzIGFuZCB0aGVpciBkZXBlbmRlbmNpZXNcbiAgICovXG4gIHB1YmxpYyBhc3luYyBsaXN0KGN4OiBJQ2xvdWRBc3NlbWJseVNvdXJjZSwgb3B0aW9uczogTGlzdE9wdGlvbnMgPSB7fSk6IFByb21pc2U8U3RhY2tEZXRhaWxzW10+IHtcbiAgICBjb25zdCBpb0hvc3QgPSB3aXRoQWN0aW9uKHRoaXMuaW9Ib3N0LCAnbGlzdCcpO1xuICAgIGNvbnN0IHN5bnRoVGltZXIgPSBUaW1lci5zdGFydCgpO1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgdGhpcy5hc3NlbWJseUZyb21Tb3VyY2UoY3gpO1xuICAgIGNvbnN0IHN0YWNrQ29sbGVjdGlvbiA9IGF3YWl0IGFzc2VtYmx5LnNlbGVjdFN0YWNrc1YyKG9wdGlvbnMuc3RhY2tzID8/IEFMTF9TVEFDS1MpO1xuICAgIGF3YWl0IHN5bnRoVGltZXIuZW5kQXMoaW9Ib3N0LCAnc3ludGgnKTtcblxuICAgIGNvbnN0IHN0YWNrcyA9IHN0YWNrQ29sbGVjdGlvbi53aXRoRGVwZW5kZW5jaWVzKCk7XG4gICAgY29uc3QgbWVzc2FnZSA9IHN0YWNrcy5tYXAocyA9PiBzLmlkKS5qb2luKCdcXG4nKTtcblxuICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkocmVzdWx0KG1lc3NhZ2UsIENPREVTLkNES19UT09MS0lUX0kyOTAxLCB7IHN0YWNrcyB9KSk7XG4gICAgcmV0dXJuIHN0YWNrcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXBsb3kgQWN0aW9uXG4gICAqXG4gICAqIERlcGxveXMgdGhlIHNlbGVjdGVkIHN0YWNrcyBpbnRvIGFuIEFXUyBhY2NvdW50XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGVwbG95KGN4OiBJQ2xvdWRBc3NlbWJseVNvdXJjZSwgb3B0aW9uczogRGVwbG95T3B0aW9ucyA9IHt9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYXNzZW1ibHkgPSBhd2FpdCB0aGlzLmFzc2VtYmx5RnJvbVNvdXJjZShjeCk7XG4gICAgcmV0dXJuIHRoaXMuX2RlcGxveShhc3NlbWJseSwgJ2RlcGxveScsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciB0byBhbGxvdyBkZXBsb3kgYmVpbmcgY2FsbGVkIGFzIHBhcnQgb2YgdGhlIHdhdGNoIGFjdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2RlcGxveShhc3NlbWJseTogU3RhY2tBc3NlbWJseSwgYWN0aW9uOiAnZGVwbG95JyB8ICd3YXRjaCcsIG9wdGlvbnM6IEV4dGVuZGVkRGVwbG95T3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgaW9Ib3N0ID0gd2l0aEFjdGlvbih0aGlzLmlvSG9zdCwgYWN0aW9uKTtcbiAgICBjb25zdCBzeW50aFRpbWVyID0gVGltZXIuc3RhcnQoKTtcbiAgICBjb25zdCBzdGFja0NvbGxlY3Rpb24gPSBhc3NlbWJseS5zZWxlY3RTdGFja3NWMihvcHRpb25zLnN0YWNrcyA/PyBBTExfU1RBQ0tTKTtcbiAgICBhd2FpdCB0aGlzLnZhbGlkYXRlU3RhY2tzTWV0YWRhdGEoc3RhY2tDb2xsZWN0aW9uLCBpb0hvc3QpO1xuICAgIGNvbnN0IHN5bnRoRHVyYXRpb24gPSBhd2FpdCBzeW50aFRpbWVyLmVuZEFzKGlvSG9zdCwgJ3N5bnRoJyk7XG5cbiAgICBpZiAoc3RhY2tDb2xsZWN0aW9uLnN0YWNrQ291bnQgPT09IDApIHtcbiAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoZXJyb3IoJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycsIENPREVTLkNES19UT09MS0lUX0U1MDAxKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVwbG95bWVudHMgPSBhd2FpdCB0aGlzLmRlcGxveW1lbnRzRm9yQWN0aW9uKCdkZXBsb3knKTtcbiAgICBjb25zdCBtaWdyYXRvciA9IG5ldyBSZXNvdXJjZU1pZ3JhdG9yKHsgZGVwbG95bWVudHMsIGlvSG9zdCwgYWN0aW9uIH0pO1xuXG4gICAgYXdhaXQgbWlncmF0b3IudHJ5TWlncmF0ZVJlc291cmNlcyhzdGFja0NvbGxlY3Rpb24sIG9wdGlvbnMpO1xuXG4gICAgY29uc3QgcmVxdWlyZUFwcHJvdmFsID0gb3B0aW9ucy5yZXF1aXJlQXBwcm92YWwgPz8gUmVxdWlyZUFwcHJvdmFsLk5FVkVSO1xuXG4gICAgY29uc3QgcGFyYW1ldGVyTWFwID0gYnVpbGRQYXJhbWV0ZXJNYXAob3B0aW9ucy5wYXJhbWV0ZXJzPy5wYXJhbWV0ZXJzKTtcblxuICAgIGNvbnN0IGhvdHN3YXBNb2RlID0gb3B0aW9ucy5ob3Rzd2FwID8/IEhvdHN3YXBNb2RlLkZVTExfREVQTE9ZTUVOVDtcbiAgICBpZiAoaG90c3dhcE1vZGUgIT09IEhvdHN3YXBNb2RlLkZVTExfREVQTE9ZTUVOVCkge1xuICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeSh3YXJuKFtcbiAgICAgICAgJ+KaoO+4jyBUaGUgLS1ob3Rzd2FwIGFuZCAtLWhvdHN3YXAtZmFsbGJhY2sgZmxhZ3MgZGVsaWJlcmF0ZWx5IGludHJvZHVjZSBDbG91ZEZvcm1hdGlvbiBkcmlmdCB0byBzcGVlZCB1cCBkZXBsb3ltZW50cycsXG4gICAgICAgICfimqDvuI8gVGhleSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBkZXZlbG9wbWVudCAtIG5ldmVyIHVzZSB0aGVtIGZvciB5b3VyIHByb2R1Y3Rpb24gU3RhY2tzIScsXG4gICAgICBdLmpvaW4oJ1xcbicpKSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhY2tzID0gc3RhY2tDb2xsZWN0aW9uLnN0YWNrQXJ0aWZhY3RzO1xuICAgIGNvbnN0IHN0YWNrT3V0cHV0czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuICAgIGNvbnN0IG91dHB1dHNGaWxlID0gb3B0aW9ucy5vdXRwdXRzRmlsZTtcblxuICAgIGNvbnN0IGJ1aWxkQXNzZXQgPSBhc3luYyAoYXNzZXROb2RlOiBBc3NldEJ1aWxkTm9kZSkgPT4ge1xuICAgICAgYXdhaXQgZGVwbG95bWVudHMuYnVpbGRTaW5nbGVBc3NldChcbiAgICAgICAgYXNzZXROb2RlLmFzc2V0TWFuaWZlc3RBcnRpZmFjdCxcbiAgICAgICAgYXNzZXROb2RlLmFzc2V0TWFuaWZlc3QsXG4gICAgICAgIGFzc2V0Tm9kZS5hc3NldCxcbiAgICAgICAge1xuICAgICAgICAgIHN0YWNrOiBhc3NldE5vZGUucGFyZW50U3RhY2ssXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIHN0YWNrTmFtZTogYXNzZXROb2RlLnBhcmVudFN0YWNrLnN0YWNrTmFtZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfTtcblxuICAgIGNvbnN0IHB1Ymxpc2hBc3NldCA9IGFzeW5jIChhc3NldE5vZGU6IEFzc2V0UHVibGlzaE5vZGUpID0+IHtcbiAgICAgIGF3YWl0IGRlcGxveW1lbnRzLnB1Ymxpc2hTaW5nbGVBc3NldChhc3NldE5vZGUuYXNzZXRNYW5pZmVzdCwgYXNzZXROb2RlLmFzc2V0LCB7XG4gICAgICAgIHN0YWNrOiBhc3NldE5vZGUucGFyZW50U3RhY2ssXG4gICAgICAgIHJvbGVBcm46IG9wdGlvbnMucm9sZUFybixcbiAgICAgICAgc3RhY2tOYW1lOiBhc3NldE5vZGUucGFyZW50U3RhY2suc3RhY2tOYW1lLFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGRlcGxveVN0YWNrID0gYXN5bmMgKHN0YWNrTm9kZTogU3RhY2tOb2RlKSA9PiB7XG4gICAgICBjb25zdCBzdGFjayA9IHN0YWNrTm9kZS5zdGFjaztcbiAgICAgIGlmIChzdGFja0NvbGxlY3Rpb24uc3RhY2tDb3VudCAhPT0gMSkge1xuICAgICAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KGluZm8oY2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSkpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFzdGFjay5lbnZpcm9ubWVudCkge1xuICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKFxuICAgICAgICAgIGBTdGFjayAke3N0YWNrLmRpc3BsYXlOYW1lfSBkb2VzIG5vdCBkZWZpbmUgYW4gZW52aXJvbm1lbnQsIGFuZCBBV1MgY3JlZGVudGlhbHMgY291bGQgbm90IGJlIG9idGFpbmVkIGZyb20gc3RhbmRhcmQgbG9jYXRpb25zIG9yIG5vIHJlZ2lvbiB3YXMgY29uZmlndXJlZC5gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgZ2VuZXJhdGVkIHN0YWNrIGhhcyBubyByZXNvdXJjZXNcbiAgICAgIGlmIChPYmplY3Qua2V5cyhzdGFjay50ZW1wbGF0ZS5SZXNvdXJjZXMgfHwge30pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAvLyBzdGFjayBpcyBlbXB0eSBhbmQgZG9lc24ndCBleGlzdCA9PiBkbyBub3RoaW5nXG4gICAgICAgIGNvbnN0IHN0YWNrRXhpc3RzID0gYXdhaXQgZGVwbG95bWVudHMuc3RhY2tFeGlzdHMoeyBzdGFjayB9KTtcbiAgICAgICAgaWYgKCFzdGFja0V4aXN0cykge1xuICAgICAgICAgIHJldHVybiBpb0hvc3Qubm90aWZ5KHdhcm4oYCR7Y2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSl9OiBzdGFjayBoYXMgbm8gcmVzb3VyY2VzLCBza2lwcGluZyBkZXBsb3ltZW50LmApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHN0YWNrIGlzIGVtcHR5LCBidXQgZXhpc3RzID0+IGRlbGV0ZVxuICAgICAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KHdhcm4oYCR7Y2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSl9OiBzdGFjayBoYXMgbm8gcmVzb3VyY2VzLCBkZWxldGluZyBleGlzdGluZyBzdGFjay5gKSk7XG4gICAgICAgIGF3YWl0IHRoaXMuX2Rlc3Ryb3koYXNzZW1ibHksICdkZXBsb3knLCB7XG4gICAgICAgICAgc3RhY2tzOiB7IHBhdHRlcm5zOiBbc3RhY2suaGllcmFyY2hpY2FsSWRdLCBzdHJhdGVneTogU3RhY2tTZWxlY3Rpb25TdHJhdGVneS5QQVRURVJOX01VU1RfTUFUQ0hfU0lOR0xFIH0sXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIGNpOiBvcHRpb25zLmNpLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXF1aXJlQXBwcm92YWwgIT09IFJlcXVpcmVBcHByb3ZhbC5ORVZFUikge1xuICAgICAgICBjb25zdCBjdXJyZW50VGVtcGxhdGUgPSBhd2FpdCBkZXBsb3ltZW50cy5yZWFkQ3VycmVudFRlbXBsYXRlKHN0YWNrKTtcbiAgICAgICAgaWYgKGRpZmZSZXF1aXJlc0FwcHJvdmFsKGN1cnJlbnRUZW1wbGF0ZSwgc3RhY2ssIHJlcXVpcmVBcHByb3ZhbCkpIHtcbiAgICAgICAgICBjb25zdCBtb3RpdmF0aW9uID0gJ1wiLS1yZXF1aXJlLWFwcHJvdmFsXCIgaXMgZW5hYmxlZCBhbmQgc3RhY2sgaW5jbHVkZXMgc2VjdXJpdHktc2Vuc2l0aXZlIHVwZGF0ZXMuJztcbiAgICAgICAgICBjb25zdCBxdWVzdGlvbiA9IGAke21vdGl2YXRpb259XFxuRG8geW91IHdpc2ggdG8gZGVwbG95IHRoZXNlIGNoYW5nZXNgO1xuICAgICAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IGlvSG9zdC5yZXF1ZXN0UmVzcG9uc2UoY29uZmlybShDT0RFUy5DREtfVE9PTEtJVF9JNTA2MCwgcXVlc3Rpb24sIG1vdGl2YXRpb24sIHRydWUsIGNvbmN1cnJlbmN5KSk7XG4gICAgICAgICAgaWYgKCFjb25maXJtZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0Fib3J0ZWQgYnkgdXNlcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBGb2xsb3dpbmcgYXJlIHRoZSBzYW1lIHNlbWFudGljcyB3ZSBhcHBseSB3aXRoIHJlc3BlY3QgdG8gTm90aWZpY2F0aW9uIEFSTnMgKGRpY3RhdGVkIGJ5IHRoZSBTREspXG4gICAgICAvL1xuICAgICAgLy8gIC0gdW5kZWZpbmVkICA9PiAgY2RrIGlnbm9yZXMgaXQsIGFzIGlmIGl0IHdhc24ndCBzdXBwb3J0ZWQgKGFsbG93cyBleHRlcm5hbCBtYW5hZ2VtZW50KS5cbiAgICAgIC8vICAtIFtdOiAgICAgICAgPT4gIGNkayBtYW5hZ2VzIGl0LCBhbmQgdGhlIHVzZXIgd2FudHMgdG8gd2lwZSBpdCBvdXQuXG4gICAgICAvLyAgLSBbJ2Fybi0xJ10gID0+ICBjZGsgbWFuYWdlcyBpdCwgYW5kIHRoZSB1c2VyIHdhbnRzIHRvIHNldCBpdCB0byBbJ2Fybi0xJ10uXG4gICAgICBjb25zdCBub3RpZmljYXRpb25Bcm5zID0gKCEhb3B0aW9ucy5ub3RpZmljYXRpb25Bcm5zIHx8ICEhc3RhY2subm90aWZpY2F0aW9uQXJucylcbiAgICAgICAgPyAob3B0aW9ucy5ub3RpZmljYXRpb25Bcm5zID8/IFtdKS5jb25jYXQoc3RhY2subm90aWZpY2F0aW9uQXJucyA/PyBbXSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIGZvciAoY29uc3Qgbm90aWZpY2F0aW9uQXJuIG9mIG5vdGlmaWNhdGlvbkFybnMgPz8gW10pIHtcbiAgICAgICAgaWYgKCF2YWxpZGF0ZVNuc1RvcGljQXJuKG5vdGlmaWNhdGlvbkFybikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGBOb3RpZmljYXRpb24gYXJuICR7bm90aWZpY2F0aW9uQXJufSBpcyBub3QgYSB2YWxpZCBhcm4gZm9yIGFuIFNOUyB0b3BpY2ApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YWNrSW5kZXggPSBzdGFja3MuaW5kZXhPZihzdGFjaykgKyAxO1xuICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShcbiAgICAgICAgaW5mbyhgJHtjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKX06IGRlcGxveWluZy4uLiBbJHtzdGFja0luZGV4fS8ke3N0YWNrQ29sbGVjdGlvbi5zdGFja0NvdW50fV1gKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBkZXBsb3lUaW1lciA9IFRpbWVyLnN0YXJ0KCk7XG5cbiAgICAgIGxldCB0YWdzID0gb3B0aW9ucy50YWdzO1xuICAgICAgaWYgKCF0YWdzIHx8IHRhZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRhZ3MgPSB0YWdzRm9yU3RhY2soc3RhY2spO1xuICAgICAgfVxuXG4gICAgICBsZXQgZGVwbG95RHVyYXRpb247XG4gICAgICB0cnkge1xuICAgICAgICBsZXQgZGVwbG95UmVzdWx0OiBTdWNjZXNzZnVsRGVwbG95U3RhY2tSZXN1bHQgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgbGV0IHJvbGxiYWNrID0gb3B0aW9ucy5yb2xsYmFjaztcbiAgICAgICAgbGV0IGl0ZXJhdGlvbiA9IDA7XG4gICAgICAgIHdoaWxlICghZGVwbG95UmVzdWx0KSB7XG4gICAgICAgICAgaWYgKCsraXRlcmF0aW9uID4gMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignVGhpcyBsb29wIHNob3VsZCBoYXZlIHN0YWJpbGl6ZWQgaW4gMiBpdGVyYXRpb25zLCBidXQgZGlkblxcJ3QuIElmIHlvdSBhcmUgc2VlaW5nIHRoaXMgZXJyb3IsIHBsZWFzZSByZXBvcnQgaXQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy9uZXcvY2hvb3NlJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgciA9IGF3YWl0IGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgZGVwbG95TmFtZTogc3RhY2suc3RhY2tOYW1lLFxuICAgICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgICAgdG9vbGtpdFN0YWNrTmFtZTogdGhpcy50b29sa2l0U3RhY2tOYW1lLFxuICAgICAgICAgICAgcmV1c2VBc3NldHM6IG9wdGlvbnMucmV1c2VBc3NldHMsXG4gICAgICAgICAgICBub3RpZmljYXRpb25Bcm5zLFxuICAgICAgICAgICAgdGFncyxcbiAgICAgICAgICAgIGRlcGxveW1lbnRNZXRob2Q6IG9wdGlvbnMuZGVwbG95bWVudE1ldGhvZCxcbiAgICAgICAgICAgIGZvcmNlOiBvcHRpb25zLmZvcmNlLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogT2JqZWN0LmFzc2lnbih7fSwgcGFyYW1ldGVyTWFwWycqJ10sIHBhcmFtZXRlck1hcFtzdGFjay5zdGFja05hbWVdKSxcbiAgICAgICAgICAgIHVzZVByZXZpb3VzUGFyYW1ldGVyczogb3B0aW9ucy5wYXJhbWV0ZXJzPy5rZWVwRXhpc3RpbmdQYXJhbWV0ZXJzLFxuICAgICAgICAgICAgcm9sbGJhY2ssXG4gICAgICAgICAgICBob3Rzd2FwOiBob3Rzd2FwTW9kZSxcbiAgICAgICAgICAgIGV4dHJhVXNlckFnZW50OiBvcHRpb25zLmV4dHJhVXNlckFnZW50LFxuICAgICAgICAgICAgaG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzOiBvcHRpb25zLmhvdHN3YXBQcm9wZXJ0aWVzID8gY3JlYXRlSG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzKG9wdGlvbnMuaG90c3dhcFByb3BlcnRpZXMpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXNzZXRQYXJhbGxlbGlzbTogb3B0aW9ucy5hc3NldFBhcmFsbGVsaXNtLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc3dpdGNoIChyLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2RpZC1kZXBsb3ktc3RhY2snOlxuICAgICAgICAgICAgICBkZXBsb3lSZXN1bHQgPSByO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnZmFpbHBhdXNlZC1uZWVkLXJvbGxiYWNrLWZpcnN0Jzoge1xuICAgICAgICAgICAgICBjb25zdCBtb3RpdmF0aW9uID0gci5yZWFzb24gPT09ICdyZXBsYWNlbWVudCdcbiAgICAgICAgICAgICAgICA/IGBTdGFjayBpcyBpbiBhIHBhdXNlZCBmYWlsIHN0YXRlICgke3Iuc3RhdHVzfSkgYW5kIGNoYW5nZSBpbmNsdWRlcyBhIHJlcGxhY2VtZW50IHdoaWNoIGNhbm5vdCBiZSBkZXBsb3llZCB3aXRoIFwiLS1uby1yb2xsYmFja1wiYFxuICAgICAgICAgICAgICAgIDogYFN0YWNrIGlzIGluIGEgcGF1c2VkIGZhaWwgc3RhdGUgKCR7ci5zdGF0dXN9KSBhbmQgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBkbyBub3QgaW5jbHVkZSBcIi0tbm8tcm9sbGJhY2tcImA7XG4gICAgICAgICAgICAgIGNvbnN0IHF1ZXN0aW9uID0gYCR7bW90aXZhdGlvbn0uIFBlcmZvcm0gYSByZWd1bGFyIGRlcGxveW1lbnRgO1xuXG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeSh3YXJuKGAke21vdGl2YXRpb259LiBSb2xsaW5nIGJhY2sgZmlyc3QgKC0tZm9yY2UpLmApKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBpb0hvc3QucmVxdWVzdFJlc3BvbnNlKGNvbmZpcm0oQ09ERVMuQ0RLX1RPT0xLSVRfSTUwNTAsIHF1ZXN0aW9uLCBtb3RpdmF0aW9uLCB0cnVlLCBjb25jdXJyZW5jeSkpO1xuICAgICAgICAgICAgICAgIGlmICghY29uZmlybWVkKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdBYm9ydGVkIGJ5IHVzZXInKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBQZXJmb3JtIGEgcm9sbGJhY2tcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fcm9sbGJhY2soYXNzZW1ibHksIGFjdGlvbiwge1xuICAgICAgICAgICAgICAgIHN0YWNrczogeyBwYXR0ZXJuczogW3N0YWNrLmhpZXJhcmNoaWNhbElkXSwgc3RyYXRlZ3k6IFN0YWNrU2VsZWN0aW9uU3RyYXRlZ3kuUEFUVEVSTl9NVVNUX01BVENIX1NJTkdMRSB9LFxuICAgICAgICAgICAgICAgIG9ycGhhbkZhaWxlZFJlc291cmNlczogb3B0aW9ucy5mb3JjZSxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgLy8gR28gYXJvdW5kIHRocm91Z2ggdGhlICd3aGlsZScgbG9vcCBhZ2FpbiBidXQgc3dpdGNoIHJvbGxiYWNrIHRvIHRydWUuXG4gICAgICAgICAgICAgIHJvbGxiYWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3JlcGxhY2VtZW50LXJlcXVpcmVzLXJvbGxiYWNrJzoge1xuICAgICAgICAgICAgICBjb25zdCBtb3RpdmF0aW9uID0gJ0NoYW5nZSBpbmNsdWRlcyBhIHJlcGxhY2VtZW50IHdoaWNoIGNhbm5vdCBiZSBkZXBsb3llZCB3aXRoIFwiLS1uby1yb2xsYmFja1wiJztcbiAgICAgICAgICAgICAgY29uc3QgcXVlc3Rpb24gPSBgJHttb3RpdmF0aW9ufS4gUGVyZm9ybSBhIHJlZ3VsYXIgZGVwbG95bWVudGA7XG5cbiAgICAgICAgICAgICAgLy8gQHRvZG8gbm8gZm9yY2UgaGVyZVxuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkod2FybihgJHttb3RpdmF0aW9ufS4gUHJvY2VlZGluZyB3aXRoIHJlZ3VsYXIgZGVwbG95bWVudCAoLS1mb3JjZSkuYCkpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IGlvSG9zdC5yZXF1ZXN0UmVzcG9uc2UoY29uZmlybShDT0RFUy5DREtfVE9PTEtJVF9JNTA1MCwgcXVlc3Rpb24sIG1vdGl2YXRpb24sIHRydWUsIGNvbmN1cnJlbmN5KSk7XG4gICAgICAgICAgICAgICAgaWYgKCFjb25maXJtZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0Fib3J0ZWQgYnkgdXNlcicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIEdvIGFyb3VuZCB0aHJvdWdoIHRoZSAnd2hpbGUnIGxvb3AgYWdhaW4gYnV0IHN3aXRjaCByb2xsYmFjayB0byB0cnVlLlxuICAgICAgICAgICAgICByb2xsYmFjayA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGBVbmV4cGVjdGVkIHJlc3VsdCB0eXBlIGZyb20gZGVwbG95U3RhY2s6ICR7SlNPTi5zdHJpbmdpZnkocil9LiBJZiB5b3UgYXJlIHNlZWluZyB0aGlzIGVycm9yLCBwbGVhc2UgcmVwb3J0IGl0IGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvbmV3L2Nob29zZWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBkZXBsb3lSZXN1bHQubm9PcFxuICAgICAgICAgID8gYCDinIUgICR7c3RhY2suZGlzcGxheU5hbWV9IChubyBjaGFuZ2VzKWBcbiAgICAgICAgICA6IGAg4pyFICAke3N0YWNrLmRpc3BsYXlOYW1lfWA7XG5cbiAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShyZXN1bHQoY2hhbGsuZ3JlZW4oJ1xcbicgKyBtZXNzYWdlKSwgQ09ERVMuQ0RLX1RPT0xLSVRfSTU5MDAsIGRlcGxveVJlc3VsdCkpO1xuICAgICAgICBkZXBsb3lEdXJhdGlvbiA9IGF3YWl0IGRlcGxveVRpbWVyLmVuZEFzKGlvSG9zdCwgJ2RlcGxveScpO1xuXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhkZXBsb3lSZXN1bHQub3V0cHV0cykubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFsnT3V0cHV0czonXTtcbiAgICAgICAgICBzdGFja091dHB1dHNbc3RhY2suc3RhY2tOYW1lXSA9IGRlcGxveVJlc3VsdC5vdXRwdXRzO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGRlcGxveVJlc3VsdC5vdXRwdXRzKS5zb3J0KCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZGVwbG95UmVzdWx0Lm91dHB1dHNbbmFtZV07XG4gICAgICAgICAgICBidWZmZXIucHVzaChgJHtjaGFsay5jeWFuKHN0YWNrLmlkKX0uJHtjaGFsay5jeWFuKG5hbWUpfSA9ICR7Y2hhbGsudW5kZXJsaW5lKGNoYWxrLmN5YW4odmFsdWUpKX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShpbmZvKGJ1ZmZlci5qb2luKCdcXG4nKSkpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoaW5mbyhgU3RhY2sgQVJOOlxcbiR7ZGVwbG95UmVzdWx0LnN0YWNrQXJufWApKTtcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAvLyBJdCBoYXMgdG8gYmUgZXhhY3RseSB0aGlzIHN0cmluZyBiZWNhdXNlIGFuIGludGVncmF0aW9uIHRlc3QgdGVzdHMgZm9yXG4gICAgICAgIC8vIFwiYm9sZChzdGFja25hbWUpIGZhaWxlZDogUmVzb3VyY2VOb3RSZWFkeTogPGVycm9yPlwiXG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICAgW2DinYwgICR7Y2hhbGsuYm9sZChzdGFjay5zdGFja05hbWUpfSBmYWlsZWQ6YCwgLi4uKGUubmFtZSA/IFtgJHtlLm5hbWV9OmBdIDogW10pLCBlLm1lc3NhZ2VdLmpvaW4oJyAnKSxcbiAgICAgICAgKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChvcHRpb25zLnRyYWNlTG9ncykge1xuICAgICAgICAgIC8vIGRlcGxveSBjYWxscyB0aGF0IG9yaWdpbmF0ZSBmcm9tIHdhdGNoIHdpbGwgY29tZSB3aXRoIHRoZWlyIG93biBjbG91ZFdhdGNoTG9nTW9uaXRvclxuICAgICAgICAgIGNvbnN0IGNsb3VkV2F0Y2hMb2dNb25pdG9yID0gb3B0aW9ucy5jbG91ZFdhdGNoTG9nTW9uaXRvciA/PyBuZXcgQ2xvdWRXYXRjaExvZ0V2ZW50TW9uaXRvcigpO1xuICAgICAgICAgIGNvbnN0IGZvdW5kTG9nR3JvdXBzUmVzdWx0ID0gYXdhaXQgZmluZENsb3VkV2F0Y2hMb2dHcm91cHMoYXdhaXQgdGhpcy5zZGtQcm92aWRlcignZGVwbG95JyksIHsgaW9Ib3N0LCBhY3Rpb24gfSwgc3RhY2spO1xuICAgICAgICAgIGNsb3VkV2F0Y2hMb2dNb25pdG9yLmFkZExvZ0dyb3VwcyhcbiAgICAgICAgICAgIGZvdW5kTG9nR3JvdXBzUmVzdWx0LmVudixcbiAgICAgICAgICAgIGZvdW5kTG9nR3JvdXBzUmVzdWx0LnNkayxcbiAgICAgICAgICAgIGZvdW5kTG9nR3JvdXBzUmVzdWx0LmxvZ0dyb3VwTmFtZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KGluZm8oYFRoZSBmb2xsb3dpbmcgbG9nIGdyb3VwcyBhcmUgYWRkZWQ6ICR7Zm91bmRMb2dHcm91cHNSZXN1bHQubG9nR3JvdXBOYW1lc31gLCBDT0RFUy5DREtfVE9PTEtJVF9JNTAzMSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgYW4gb3V0cHV0cyBmaWxlIGhhcyBiZWVuIHNwZWNpZmllZCwgY3JlYXRlIHRoZSBmaWxlIHBhdGggYW5kIHdyaXRlIHN0YWNrIG91dHB1dHMgdG8gaXQgb25jZS5cbiAgICAgICAgLy8gT3V0cHV0cyBhcmUgd3JpdHRlbiBhZnRlciBhbGwgc3RhY2tzIGhhdmUgYmVlbiBkZXBsb3llZC4gSWYgYSBzdGFjayBkZXBsb3ltZW50IGZhaWxzLFxuICAgICAgICAvLyBhbGwgb2YgdGhlIG91dHB1dHMgZnJvbSBzdWNjZXNzZnVsbHkgZGVwbG95ZWQgc3RhY2tzIGJlZm9yZSB0aGUgZmFpbHVyZSB3aWxsIHN0aWxsIGJlIHdyaXR0ZW4uXG4gICAgICAgIGlmIChvdXRwdXRzRmlsZSkge1xuICAgICAgICAgIGZzLmVuc3VyZUZpbGVTeW5jKG91dHB1dHNGaWxlKTtcbiAgICAgICAgICBhd2FpdCBmcy53cml0ZUpzb24ob3V0cHV0c0ZpbGUsIHN0YWNrT3V0cHV0cywge1xuICAgICAgICAgICAgc3BhY2VzOiAyLFxuICAgICAgICAgICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZHVyYXRpb24gPSBzeW50aER1cmF0aW9uLmFzTXMgKyAoZGVwbG95RHVyYXRpb24/LmFzTXMgPz8gMCk7XG4gICAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KGluZm8oYFxcbuKcqCAgVG90YWwgdGltZTogJHtmb3JtYXRUaW1lKGR1cmF0aW9uKX1zXFxuYCwgQ09ERVMuQ0RLX1RPT0xLSVRfSTUwMDEsIHsgZHVyYXRpb24gfSkpO1xuICAgIH07XG5cbiAgICBjb25zdCBhc3NldEJ1aWxkVGltZSA9IG9wdGlvbnMuYXNzZXRCdWlsZFRpbWUgPz8gQXNzZXRCdWlsZFRpbWUuQUxMX0JFRk9SRV9ERVBMT1k7XG4gICAgY29uc3QgcHJlYnVpbGRBc3NldHMgPSBhc3NldEJ1aWxkVGltZSA9PT0gQXNzZXRCdWlsZFRpbWUuQUxMX0JFRk9SRV9ERVBMT1k7XG4gICAgY29uc3QgY29uY3VycmVuY3kgPSBvcHRpb25zLmNvbmN1cnJlbmN5IHx8IDE7XG5cbiAgICBjb25zdCBzdGFja3NBbmRUaGVpckFzc2V0TWFuaWZlc3RzID0gc3RhY2tzLmZsYXRNYXAoKHN0YWNrKSA9PiBbXG4gICAgICBzdGFjayxcbiAgICAgIC4uLnN0YWNrLmRlcGVuZGVuY2llcy5maWx0ZXIoeCA9PiBjeGFwaS5Bc3NldE1hbmlmZXN0QXJ0aWZhY3QuaXNBc3NldE1hbmlmZXN0QXJ0aWZhY3QoeCkpLFxuICAgIF0pO1xuICAgIGNvbnN0IHdvcmtHcmFwaCA9IG5ldyBXb3JrR3JhcGhCdWlsZGVyKHsgaW9Ib3N0LCBhY3Rpb24gfSwgcHJlYnVpbGRBc3NldHMpLmJ1aWxkKHN0YWNrc0FuZFRoZWlyQXNzZXRNYW5pZmVzdHMpO1xuXG4gICAgLy8gVW5sZXNzIHdlIGFyZSBydW5uaW5nIHdpdGggJy0tZm9yY2UnLCBza2lwIGFscmVhZHkgcHVibGlzaGVkIGFzc2V0c1xuICAgIGlmICghb3B0aW9ucy5mb3JjZSkge1xuICAgICAgYXdhaXQgcmVtb3ZlUHVibGlzaGVkQXNzZXRzKHdvcmtHcmFwaCwgZGVwbG95bWVudHMsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGNvbnN0IGdyYXBoQ29uY3VycmVuY3k6IENvbmN1cnJlbmN5ID0ge1xuICAgICAgJ3N0YWNrJzogY29uY3VycmVuY3ksXG4gICAgICAnYXNzZXQtYnVpbGQnOiAxLCAvLyBUaGlzIHdpbGwgYmUgQ1BVLWJvdW5kL21lbW9yeSBib3VuZCwgbW9zdGx5IG1hdHRlcnMgZm9yIERvY2tlciBidWlsZHNcbiAgICAgICdhc3NldC1wdWJsaXNoJzogKG9wdGlvbnMuYXNzZXRQYXJhbGxlbGlzbSA/PyB0cnVlKSA/IDggOiAxLCAvLyBUaGlzIHdpbGwgYmUgSS9PLWJvdW5kLCA4IGluIHBhcmFsbGVsIHNlZW1zIHJlYXNvbmFibGVcbiAgICB9O1xuXG4gICAgYXdhaXQgd29ya0dyYXBoLmRvUGFyYWxsZWwoZ3JhcGhDb25jdXJyZW5jeSwge1xuICAgICAgZGVwbG95U3RhY2ssXG4gICAgICBidWlsZEFzc2V0LFxuICAgICAgcHVibGlzaEFzc2V0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoIEFjdGlvblxuICAgKlxuICAgKiBDb250aW51b3VzbHkgb2JzZXJ2ZSBwcm9qZWN0IGZpbGVzIGFuZCBkZXBsb3kgdGhlIHNlbGVjdGVkIHN0YWNrcyBhdXRvbWF0aWNhbGx5IHdoZW4gY2hhbmdlcyBhcmUgZGV0ZWN0ZWQuXG4gICAqIEltcGxpZXMgaG90c3dhcCBkZXBsb3ltZW50cy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB3YXRjaChjeDogSUNsb3VkQXNzZW1ibHlTb3VyY2UsIG9wdGlvbnM6IFdhdGNoT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgdGhpcy5hc3NlbWJseUZyb21Tb3VyY2UoY3gsIGZhbHNlKTtcbiAgICBjb25zdCBpb0hvc3QgPSB3aXRoQWN0aW9uKHRoaXMuaW9Ib3N0LCAnd2F0Y2gnKTtcbiAgICBjb25zdCByb290RGlyID0gb3B0aW9ucy53YXRjaERpciA/PyBwcm9jZXNzLmN3ZCgpO1xuICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoZGVidWcoYHJvb3QgZGlyZWN0b3J5IHVzZWQgZm9yICd3YXRjaCcgaXM6ICR7cm9vdERpcn1gKSk7XG5cbiAgICBpZiAob3B0aW9ucy5pbmNsdWRlID09PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5leGNsdWRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgIFwiQ2Fubm90IHVzZSB0aGUgJ3dhdGNoJyBjb21tYW5kIHdpdGhvdXQgc3BlY2lmeWluZyBhdCBsZWFzdCBvbmUgZGlyZWN0b3J5IHRvIG1vbml0b3IuIFwiICtcbiAgICAgICAgICAnTWFrZSBzdXJlIHRvIGFkZCBhIFwid2F0Y2hcIiBrZXkgdG8geW91ciBjZGsuanNvbicsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEZvciB0aGUgXCJpbmNsdWRlXCIgc3Via2V5IHVuZGVyIHRoZSBcIndhdGNoXCIga2V5LCB0aGUgYmVoYXZpb3IgaXM6XG4gICAgLy8gMS4gTm8gXCJ3YXRjaFwiIHNldHRpbmc/IFdlIGVycm9yIG91dC5cbiAgICAvLyAyLiBcIndhdGNoXCIgc2V0dGluZyB3aXRob3V0IGFuIFwiaW5jbHVkZVwiIGtleT8gV2UgZGVmYXVsdCB0byBvYnNlcnZpbmcgXCIuLyoqXCIuXG4gICAgLy8gMy4gXCJ3YXRjaFwiIHNldHRpbmcgd2l0aCBhbiBlbXB0eSBcImluY2x1ZGVcIiBrZXk/IFdlIGRlZmF1bHQgdG8gb2JzZXJ2aW5nIFwiLi8qKlwiLlxuICAgIC8vIDQuIE5vbi1lbXB0eSBcImluY2x1ZGVcIiBrZXk/IEp1c3QgdXNlIHRoZSBcImluY2x1ZGVcIiBrZXkuXG4gICAgY29uc3Qgd2F0Y2hJbmNsdWRlcyA9IHBhdHRlcm5zQXJyYXlGb3JXYXRjaChvcHRpb25zLmluY2x1ZGUsIHtcbiAgICAgIHJvb3REaXIsXG4gICAgICByZXR1cm5Sb290RGlySWZFbXB0eTogdHJ1ZSxcbiAgICB9KTtcbiAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KGRlYnVnKGAnaW5jbHVkZScgcGF0dGVybnMgZm9yICd3YXRjaCc6ICR7SlNPTi5zdHJpbmdpZnkod2F0Y2hJbmNsdWRlcyl9YCkpO1xuXG4gICAgLy8gRm9yIHRoZSBcImV4Y2x1ZGVcIiBzdWJrZXkgdW5kZXIgdGhlIFwid2F0Y2hcIiBrZXksXG4gICAgLy8gdGhlIGJlaGF2aW9yIGlzIHRvIGFkZCBzb21lIGRlZmF1bHQgZXhjbHVkZXMgaW4gYWRkaXRpb24gdG8gdGhlIG9uZXMgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyOlxuICAgIC8vIDEuIFRoZSBDREsgb3V0cHV0IGRpcmVjdG9yeS5cbiAgICAvLyAyLiBBbnkgZmlsZSB3aG9zZSBuYW1lIHN0YXJ0cyB3aXRoIGEgZG90LlxuICAgIC8vIDMuIEFueSBkaXJlY3RvcnkncyBjb250ZW50IHdob3NlIG5hbWUgc3RhcnRzIHdpdGggYSBkb3QuXG4gICAgLy8gNC4gQW55IG5vZGVfbW9kdWxlcyBhbmQgaXRzIGNvbnRlbnQgKGV2ZW4gaWYgaXQncyBub3QgYSBKUy9UUyBwcm9qZWN0LCB5b3UgbWlnaHQgYmUgdXNpbmcgYSBsb2NhbCBhd3MtY2xpIHBhY2thZ2UpXG4gICAgY29uc3Qgb3V0ZGlyID0gb3B0aW9ucy5vdXRkaXIgPz8gJ2Nkay5vdXQnO1xuICAgIGNvbnN0IHdhdGNoRXhjbHVkZXMgPSBwYXR0ZXJuc0FycmF5Rm9yV2F0Y2gob3B0aW9ucy5leGNsdWRlLCB7XG4gICAgICByb290RGlyLFxuICAgICAgcmV0dXJuUm9vdERpcklmRW1wdHk6IGZhbHNlLFxuICAgIH0pLmNvbmNhdChgJHtvdXRkaXJ9LyoqYCwgJyoqLy4qJywgJyoqLy4qLyoqJywgJyoqL25vZGVfbW9kdWxlcy8qKicpO1xuICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoZGVidWcoYCdleGNsdWRlJyBwYXR0ZXJucyBmb3IgJ3dhdGNoJzogJHtKU09OLnN0cmluZ2lmeSh3YXRjaEV4Y2x1ZGVzKX1gKSk7XG5cbiAgICAvLyBTaW5jZSAnY2RrIGRlcGxveScgaXMgYSByZWxhdGl2ZWx5IHNsb3cgb3BlcmF0aW9uIGZvciBhICd3YXRjaCcgcHJvY2VzcyxcbiAgICAvLyBpbnRyb2R1Y2UgYSBjb25jdXJyZW5jeSBsYXRjaCB0aGF0IHRyYWNrcyB0aGUgc3RhdGUuXG4gICAgLy8gVGhpcyB3YXksIGlmIGZpbGUgY2hhbmdlIGV2ZW50cyBhcnJpdmUgd2hlbiBhICdjZGsgZGVwbG95JyBpcyBzdGlsbCBleGVjdXRpbmcsXG4gICAgLy8gd2Ugd2lsbCBiYXRjaCB0aGVtLCBhbmQgdHJpZ2dlciBhbm90aGVyICdjZGsgZGVwbG95JyBhZnRlciB0aGUgY3VycmVudCBvbmUgZmluaXNoZXMsXG4gICAgLy8gbWFraW5nIHN1cmUgJ2NkayBkZXBsb3kncyAgYWx3YXlzIGV4ZWN1dGUgb25lIGF0IGEgdGltZS5cbiAgICAvLyBIZXJlJ3MgYSBkaWFncmFtIHNob3dpbmcgdGhlIHN0YXRlIHRyYW5zaXRpb25zOlxuICAgIC8vIC0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tICAgIGZpbGUgY2hhbmdlZCAgICAgLS0tLS0tLS0tLS0tLS0gICAgZmlsZSBjaGFuZ2VkICAgICAtLS0tLS0tLS0tLS0tLSAgZmlsZSBjaGFuZ2VkXG4gICAgLy8gfCAgICAgICAgICAgIHwgIHJlYWR5IGV2ZW50ICAgfCAgICAgIHwgLS0tLS0tLS0tLS0tLS0tLS0tPiB8ICAgICAgICAgICAgfCAtLS0tLS0tLS0tLS0tLS0tLS0+IHwgICAgICAgICAgICB8IC0tLS0tLS0tLS0tLS0tfFxuICAgIC8vIHwgcHJlLXJlYWR5ICB8IC0tLS0tLS0tLS0tLS0+IHwgb3BlbiB8ICAgICAgICAgICAgICAgICAgICAgfCBkZXBsb3lpbmcgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgcXVldWVkICAgfCAgICAgICAgICAgICAgIHxcbiAgICAvLyB8ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8ICAgICAgfCA8LS0tLS0tLS0tLS0tLS0tLS0tIHwgICAgICAgICAgICB8IDwtLS0tLS0tLS0tLS0tLS0tLS0gfCAgICAgICAgICAgIHwgPC0tLS0tLS0tLS0tLS18XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgLS0tLS0tLS0gICdjZGsgZGVwbG95JyBkb25lICAtLS0tLS0tLS0tLS0tLSAgJ2NkayBkZXBsb3knIGRvbmUgIC0tLS0tLS0tLS0tLS0tXG4gICAgbGV0IGxhdGNoOiAncHJlLXJlYWR5JyB8ICdvcGVuJyB8ICdkZXBsb3lpbmcnIHwgJ3F1ZXVlZCcgPSAncHJlLXJlYWR5JztcblxuICAgIGNvbnN0IGNsb3VkV2F0Y2hMb2dNb25pdG9yID0gb3B0aW9ucy50cmFjZUxvZ3MgPyBuZXcgQ2xvdWRXYXRjaExvZ0V2ZW50TW9uaXRvcigpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IGRlcGxveUFuZFdhdGNoID0gYXN5bmMgKCkgPT4ge1xuICAgICAgbGF0Y2ggPSAnZGVwbG95aW5nJztcbiAgICAgIGNsb3VkV2F0Y2hMb2dNb25pdG9yPy5kZWFjdGl2YXRlKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuaW52b2tlRGVwbG95RnJvbVdhdGNoKGFzc2VtYmx5LCBvcHRpb25zLCBjbG91ZFdhdGNoTG9nTW9uaXRvcik7XG5cbiAgICAgIC8vIElmIGxhdGNoIGlzIHN0aWxsICdkZXBsb3lpbmcnIGFmdGVyIHRoZSAnYXdhaXQnLCB0aGF0J3MgZmluZSxcbiAgICAgIC8vIGJ1dCBpZiBpdCdzICdxdWV1ZWQnLCB0aGF0IG1lYW5zIHdlIG5lZWQgdG8gZGVwbG95IGFnYWluXG4gICAgICB3aGlsZSAoKGxhdGNoIGFzICdkZXBsb3lpbmcnIHwgJ3F1ZXVlZCcpID09PSAncXVldWVkJykge1xuICAgICAgICAvLyBUeXBlU2NyaXB0IGRvZXNuJ3QgcmVhbGl6ZSBsYXRjaCBjYW4gY2hhbmdlIGJldHdlZW4gJ2F3YWl0cycsXG4gICAgICAgIC8vIGFuZCB0aGlua3MgdGhlIGFib3ZlICd3aGlsZScgY29uZGl0aW9uIGlzIGFsd2F5cyAnZmFsc2UnIHdpdGhvdXQgdGhlIGNhc3RcbiAgICAgICAgbGF0Y2ggPSAnZGVwbG95aW5nJztcbiAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShpbmZvKFwiRGV0ZWN0ZWQgZmlsZSBjaGFuZ2VzIGR1cmluZyBkZXBsb3ltZW50LiBJbnZva2luZyAnY2RrIGRlcGxveScgYWdhaW5cIikpO1xuICAgICAgICBhd2FpdCB0aGlzLmludm9rZURlcGxveUZyb21XYXRjaChhc3NlbWJseSwgb3B0aW9ucywgY2xvdWRXYXRjaExvZ01vbml0b3IpO1xuICAgICAgfVxuICAgICAgbGF0Y2ggPSAnb3Blbic7XG4gICAgICBjbG91ZFdhdGNoTG9nTW9uaXRvcj8uYWN0aXZhdGUoKTtcbiAgICB9O1xuXG4gICAgY2hva2lkYXJcbiAgICAgIC53YXRjaCh3YXRjaEluY2x1ZGVzLCB7XG4gICAgICAgIGlnbm9yZWQ6IHdhdGNoRXhjbHVkZXMsXG4gICAgICAgIGN3ZDogcm9vdERpcixcbiAgICAgIH0pXG4gICAgICAub24oJ3JlYWR5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBsYXRjaCA9ICdvcGVuJztcbiAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShkZWJ1ZyhcIid3YXRjaCcgcmVjZWl2ZWQgdGhlICdyZWFkeScgZXZlbnQuIEZyb20gbm93IG9uLCBhbGwgZmlsZSBjaGFuZ2VzIHdpbGwgdHJpZ2dlciBhIGRlcGxveW1lbnRcIikpO1xuICAgICAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KGluZm8oXCJUcmlnZ2VyaW5nIGluaXRpYWwgJ2NkayBkZXBsb3knXCIpKTtcbiAgICAgICAgYXdhaXQgZGVwbG95QW5kV2F0Y2goKTtcbiAgICAgIH0pXG4gICAgICAub24oJ2FsbCcsIGFzeW5jIChldmVudDogJ2FkZCcgfCAnYWRkRGlyJyB8ICdjaGFuZ2UnIHwgJ3VubGluaycgfCAndW5saW5rRGlyJywgZmlsZVBhdGg/OiBzdHJpbmcpID0+IHtcbiAgICAgICAgaWYgKGxhdGNoID09PSAncHJlLXJlYWR5Jykge1xuICAgICAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoaW5mbyhgJ3dhdGNoJyBpcyBvYnNlcnZpbmcgJHtldmVudCA9PT0gJ2FkZERpcicgPyAnZGlyZWN0b3J5JyA6ICd0aGUgZmlsZSd9ICcke2ZpbGVQYXRofScgZm9yIGNoYW5nZXNgKSk7XG4gICAgICAgIH0gZWxzZSBpZiAobGF0Y2ggPT09ICdvcGVuJykge1xuICAgICAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoaW5mbyhgRGV0ZWN0ZWQgY2hhbmdlIHRvICcke2ZpbGVQYXRofScgKHR5cGU6ICR7ZXZlbnR9KS4gVHJpZ2dlcmluZyAnY2RrIGRlcGxveSdgKSk7XG4gICAgICAgICAgYXdhaXQgZGVwbG95QW5kV2F0Y2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB0aGlzIG1lYW5zIGxhdGNoIGlzIGVpdGhlciAnZGVwbG95aW5nJyBvciAncXVldWVkJ1xuICAgICAgICAgIGxhdGNoID0gJ3F1ZXVlZCc7XG4gICAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShpbmZvKFxuICAgICAgICAgICAgYERldGVjdGVkIGNoYW5nZSB0byAnJHtmaWxlUGF0aH0nICh0eXBlOiAke2V2ZW50fSkgd2hpbGUgJ2NkayBkZXBsb3knIGlzIHN0aWxsIHJ1bm5pbmcuIFdpbGwgcXVldWUgZm9yIGFub3RoZXIgZGVwbG95bWVudCBhZnRlciB0aGlzIG9uZSBmaW5pc2hlcydgLFxuICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xsYmFjayBBY3Rpb25cbiAgICpcbiAgICogUm9sbHMgYmFjayB0aGUgc2VsZWN0ZWQgc3RhY2tzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJvbGxiYWNrKGN4OiBJQ2xvdWRBc3NlbWJseVNvdXJjZSwgb3B0aW9uczogUm9sbGJhY2tPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYXNzZW1ibHkgPSBhd2FpdCB0aGlzLmFzc2VtYmx5RnJvbVNvdXJjZShjeCk7XG4gICAgcmV0dXJuIHRoaXMuX3JvbGxiYWNrKGFzc2VtYmx5LCAncm9sbGJhY2snLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gYWxsb3cgcm9sbGJhY2sgYmVpbmcgY2FsbGVkIGFzIHBhcnQgb2YgdGhlIGRlcGxveSBvciB3YXRjaCBhY3Rpb24uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9yb2xsYmFjayhhc3NlbWJseTogU3RhY2tBc3NlbWJseSwgYWN0aW9uOiAncm9sbGJhY2snIHwgJ2RlcGxveScgfCAnd2F0Y2gnLCBvcHRpb25zOiBSb2xsYmFja09wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpb0hvc3QgPSB3aXRoQWN0aW9uKHRoaXMuaW9Ib3N0LCBhY3Rpb24pO1xuICAgIGNvbnN0IHN5bnRoVGltZXIgPSBUaW1lci5zdGFydCgpO1xuICAgIGNvbnN0IHN0YWNrcyA9IGFzc2VtYmx5LnNlbGVjdFN0YWNrc1YyKG9wdGlvbnMuc3RhY2tzKTtcbiAgICBhd2FpdCB0aGlzLnZhbGlkYXRlU3RhY2tzTWV0YWRhdGEoc3RhY2tzLCBpb0hvc3QpO1xuICAgIGF3YWl0IHN5bnRoVGltZXIuZW5kQXMoaW9Ib3N0LCAnc3ludGgnKTtcblxuICAgIGlmIChzdGFja3Muc3RhY2tDb3VudCA9PT0gMCkge1xuICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShlcnJvcignTm8gc3RhY2tzIHNlbGVjdGVkJywgQ09ERVMuQ0RLX1RPT0xLSVRfRTYwMDEpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgYW55Um9sbGJhY2thYmxlID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIHN0YWNrcy5zdGFja0FydGlmYWN0cykge1xuICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShpbmZvKGBSb2xsaW5nIGJhY2sgJHtjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKX1gKSk7XG4gICAgICBjb25zdCByb2xsYmFja1RpbWVyID0gVGltZXIuc3RhcnQoKTtcbiAgICAgIGNvbnN0IGRlcGxveW1lbnRzID0gYXdhaXQgdGhpcy5kZXBsb3ltZW50c0ZvckFjdGlvbigncm9sbGJhY2snKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHN0YWNrUmVzdWx0ID0gYXdhaXQgZGVwbG95bWVudHMucm9sbGJhY2tTdGFjayh7XG4gICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIHRvb2xraXRTdGFja05hbWU6IHRoaXMudG9vbGtpdFN0YWNrTmFtZSxcbiAgICAgICAgICBmb3JjZTogb3B0aW9ucy5vcnBoYW5GYWlsZWRSZXNvdXJjZXMsXG4gICAgICAgICAgdmFsaWRhdGVCb290c3RyYXBTdGFja1ZlcnNpb246IG9wdGlvbnMudmFsaWRhdGVCb290c3RyYXBTdGFja1ZlcnNpb24sXG4gICAgICAgICAgb3JwaGFuTG9naWNhbElkczogb3B0aW9ucy5vcnBoYW5Mb2dpY2FsSWRzLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFzdGFja1Jlc3VsdC5ub3RJblJvbGxiYWNrYWJsZVN0YXRlKSB7XG4gICAgICAgICAgYW55Um9sbGJhY2thYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCByb2xsYmFja1RpbWVyLmVuZEFzKGlvSG9zdCwgJ3JvbGxiYWNrJyk7XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShlcnJvcihgXFxuIOKdjCAgJHtjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKX0gZmFpbGVkOiAke2Zvcm1hdEVycm9yTWVzc2FnZShlKX1gLCBDT0RFUy5DREtfVE9PTEtJVF9FNjkwMCkpO1xuICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdSb2xsYmFjayBmYWlsZWQgKHVzZSAtLWZvcmNlIHRvIG9ycGhhbiBmYWlsaW5nIHJlc291cmNlcyknKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFhbnlSb2xsYmFja2FibGUpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ05vIHN0YWNrcyB3ZXJlIGluIGEgc3RhdGUgdGhhdCBjb3VsZCBiZSByb2xsZWQgYmFjaycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95IEFjdGlvblxuICAgKlxuICAgKiBEZXN0cm95cyB0aGUgc2VsZWN0ZWQgU3RhY2tzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRlc3Ryb3koY3g6IElDbG91ZEFzc2VtYmx5U291cmNlLCBvcHRpb25zOiBEZXN0cm95T3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgdGhpcy5hc3NlbWJseUZyb21Tb3VyY2UoY3gpO1xuICAgIHJldHVybiB0aGlzLl9kZXN0cm95KGFzc2VtYmx5LCAnZGVzdHJveScsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciB0byBhbGxvdyBkZXN0cm95IGJlaW5nIGNhbGxlZCBhcyBwYXJ0IG9mIHRoZSBkZXBsb3kgYWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfZGVzdHJveShhc3NlbWJseTogU3RhY2tBc3NlbWJseSwgYWN0aW9uOiAnZGVwbG95JyB8ICdkZXN0cm95Jywgb3B0aW9uczogRGVzdHJveU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpb0hvc3QgPSB3aXRoQWN0aW9uKHRoaXMuaW9Ib3N0LCBhY3Rpb24pO1xuICAgIGNvbnN0IHN5bnRoVGltZXIgPSBUaW1lci5zdGFydCgpO1xuICAgIC8vIFRoZSBzdGFja3Mgd2lsbCBoYXZlIGJlZW4gb3JkZXJlZCBmb3IgZGVwbG95bWVudCwgc28gcmV2ZXJzZSB0aGVtIGZvciBkZWxldGlvbi5cbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCBhc3NlbWJseS5zZWxlY3RTdGFja3NWMihvcHRpb25zLnN0YWNrcykucmV2ZXJzZWQoKTtcbiAgICBhd2FpdCBzeW50aFRpbWVyLmVuZEFzKGlvSG9zdCwgJ3N5bnRoJyk7XG5cbiAgICBjb25zdCBtb3RpdmF0aW9uID0gJ0Rlc3Ryb3lpbmcgc3RhY2tzIGlzIGFuIGlycmV2ZXJzaWJsZSBhY3Rpb24nO1xuICAgIGNvbnN0IHF1ZXN0aW9uID0gYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGU6ICR7Y2hhbGsucmVkKHN0YWNrcy5oaWVyYXJjaGljYWxJZHMuam9pbignLCAnKSl9YDtcbiAgICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBpb0hvc3QucmVxdWVzdFJlc3BvbnNlKGNvbmZpcm0oQ09ERVMuQ0RLX1RPT0xLSVRfSTcwMTAsIHF1ZXN0aW9uLCBtb3RpdmF0aW9uLCB0cnVlKSk7XG4gICAgaWYgKCFjb25maXJtZWQpIHtcbiAgICAgIHJldHVybiBpb0hvc3Qubm90aWZ5KGVycm9yKCdBYm9ydGVkIGJ5IHVzZXInLCBDT0RFUy5DREtfVE9PTEtJVF9FNzAxMCkpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlc3Ryb3lUaW1lciA9IFRpbWVyLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgIGZvciAoY29uc3QgW2luZGV4LCBzdGFja10gb2Ygc3RhY2tzLnN0YWNrQXJ0aWZhY3RzLmVudHJpZXMoKSkge1xuICAgICAgICBhd2FpdCBpb0hvc3Qubm90aWZ5KHN1Y2Nlc3MoYCR7Y2hhbGsuYmx1ZShzdGFjay5kaXNwbGF5TmFtZSl9OiBkZXN0cm95aW5nLi4uIFske2luZGV4ICsgMX0vJHtzdGFja3Muc3RhY2tDb3VudH1dYCkpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGRlcGxveW1lbnRzID0gYXdhaXQgdGhpcy5kZXBsb3ltZW50c0ZvckFjdGlvbihhY3Rpb24pO1xuICAgICAgICAgIGF3YWl0IGRlcGxveW1lbnRzLmRlc3Ryb3lTdGFjayh7XG4gICAgICAgICAgICBzdGFjayxcbiAgICAgICAgICAgIGRlcGxveU5hbWU6IHN0YWNrLnN0YWNrTmFtZSxcbiAgICAgICAgICAgIHJvbGVBcm46IG9wdGlvbnMucm9sZUFybixcbiAgICAgICAgICAgIGNpOiBvcHRpb25zLmNpLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGF3YWl0IGlvSG9zdC5ub3RpZnkoc3VjY2VzcyhgXFxuIOKchSAgJHtjaGFsay5ibHVlKHN0YWNrLmRpc3BsYXlOYW1lKX06ICR7YWN0aW9ufWVkYCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgYXdhaXQgaW9Ib3N0Lm5vdGlmeShlcnJvcihgXFxuIOKdjCAgJHtjaGFsay5ibHVlKHN0YWNrLmRpc3BsYXlOYW1lKX06ICR7YWN0aW9ufSBmYWlsZWQgJHtlfWAsIENPREVTLkNES19UT09MS0lUX0U3OTAwKSk7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBkZXN0cm95VGltZXIuZW5kQXMoaW9Ib3N0LCAnZGVzdHJveScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgc3RhY2tzIGZvciBlcnJvcnMgYW5kIHdhcm5pbmdzIGFjY29yZGluZyB0byB0aGUgQ0xJJ3MgY3VycmVudCBzZXR0aW5nc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2YWxpZGF0ZVN0YWNrc01ldGFkYXRhKHN0YWNrczogU3RhY2tDb2xsZWN0aW9uLCBpb0hvc3Q6IEFjdGlvbkF3YXJlSW9Ib3N0KSB7XG4gICAgLy8gQFRPRE8gZGVmaW5lIHRoZXNlIHNvbWV3aGVyZSBjZW50cmFsXG4gICAgY29uc3QgY29kZSA9IChsZXZlbDogSW9NZXNzYWdlTGV2ZWwpOiBJb01lc3NhZ2VDb2RlID0+IHtcbiAgICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgICAgY2FzZSAnZXJyb3InOiByZXR1cm4gJ0NES19BU1NFTUJMWV9FOTk5OSc7XG4gICAgICAgIGNhc2UgJ3dhcm4nOiByZXR1cm4gJ0NES19BU1NFTUJMWV9XOTk5OSc7XG4gICAgICAgIGRlZmF1bHQ6IHJldHVybiAnQ0RLX0FTU0VNQkxZX0k5OTk5JztcbiAgICAgIH1cbiAgICB9O1xuICAgIGF3YWl0IHN0YWNrcy52YWxpZGF0ZU1ldGFkYXRhKHRoaXMucHJvcHMuYXNzZW1ibHlGYWlsdXJlQXQsIGFzeW5jIChsZXZlbCwgbXNnKSA9PiBpb0hvc3Qubm90aWZ5KHtcbiAgICAgIHRpbWU6IG5ldyBEYXRlKCksXG4gICAgICBsZXZlbCxcbiAgICAgIGNvZGU6IGNvZGUobGV2ZWwpLFxuICAgICAgbWVzc2FnZTogYFske2xldmVsfSBhdCAke21zZy5pZH1dICR7bXNnLmVudHJ5LmRhdGF9YCxcbiAgICAgIGRhdGE6IG1zZyxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIFRvb2xraXQgaW50ZXJuYWwgQ2xvdWRBc3NlbWJseSBmcm9tIGEgQ2xvdWRBc3NlbWJseVNvdXJjZS5cbiAgICogQHBhcmFtIGFzc2VtYmx5U291cmNlIHRoZSBzb3VyY2UgZm9yIHRoZSBjbG91ZCBhc3NlbWJseVxuICAgKiBAcGFyYW0gY2FjaGUgaWYgdGhlIGFzc2VtYmx5IHNob3VsZCBiZSBjYWNoZWQsIGRlZmF1bHQ6IGB0cnVlYFxuICAgKiBAcmV0dXJucyB0aGUgQ2xvdWRBc3NlbWJseSBvYmplY3RcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYXNzZW1ibHlGcm9tU291cmNlKGFzc2VtYmx5U291cmNlOiBJQ2xvdWRBc3NlbWJseVNvdXJjZSwgY2FjaGU6IGJvb2xlYW4gPSB0cnVlKTogUHJvbWlzZTxTdGFja0Fzc2VtYmx5PiB7XG4gICAgaWYgKGFzc2VtYmx5U291cmNlIGluc3RhbmNlb2YgU3RhY2tBc3NlbWJseSkge1xuICAgICAgcmV0dXJuIGFzc2VtYmx5U291cmNlO1xuICAgIH1cblxuICAgIGlmIChjYWNoZSkge1xuICAgICAgcmV0dXJuIG5ldyBTdGFja0Fzc2VtYmx5KGF3YWl0IG5ldyBDYWNoZWRDbG91ZEFzc2VtYmx5U291cmNlKGFzc2VtYmx5U291cmNlKS5wcm9kdWNlKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgU3RhY2tBc3NlbWJseShhd2FpdCBhc3NlbWJseVNvdXJjZS5wcm9kdWNlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGRlcGxveW1lbnRzIGNsYXNzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlcGxveW1lbnRzRm9yQWN0aW9uKGFjdGlvbjogVG9vbGtpdEFjdGlvbik6IFByb21pc2U8RGVwbG95bWVudHM+IHtcbiAgICByZXR1cm4gbmV3IERlcGxveW1lbnRzKHtcbiAgICAgIHNka1Byb3ZpZGVyOiBhd2FpdCB0aGlzLnNka1Byb3ZpZGVyKGFjdGlvbiksXG4gICAgICB0b29sa2l0U3RhY2tOYW1lOiB0aGlzLnRvb2xraXRTdGFja05hbWUsXG4gICAgICBpb0hvc3Q6IHRoaXMuaW9Ib3N0IGFzIGFueSwgLy8gQHRvZG8gdGVtcG9yYXJ5IHdoaWxlIHdlIGhhdmUgdG8gc2VwYXJhdGUgSUlvSG9zdCBpbnRlcmZhY2VzXG4gICAgICBhY3Rpb24sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGludm9rZURlcGxveUZyb21XYXRjaChcbiAgICBhc3NlbWJseTogU3RhY2tBc3NlbWJseSxcbiAgICBvcHRpb25zOiBXYXRjaE9wdGlvbnMsXG4gICAgY2xvdWRXYXRjaExvZ01vbml0b3I/OiBDbG91ZFdhdGNoTG9nRXZlbnRNb25pdG9yLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyB3YXRjaCBkZWZhdWx0cyBob3Rzd2FwIHRvIGVuYWJsZWRcbiAgICBjb25zdCBob3Rzd2FwID0gb3B0aW9ucy5ob3Rzd2FwID8/IEhvdHN3YXBNb2RlLkhPVFNXQVBfT05MWTtcbiAgICBjb25zdCBkZXBsb3lPcHRpb25zOiBFeHRlbmRlZERlcGxveU9wdGlvbnMgPSB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgcmVxdWlyZUFwcHJvdmFsOiBSZXF1aXJlQXBwcm92YWwuTkVWRVIsXG4gICAgICBjbG91ZFdhdGNoTG9nTW9uaXRvcixcbiAgICAgIGhvdHN3YXAsXG4gICAgICBleHRyYVVzZXJBZ2VudDogYGNkay13YXRjaC9ob3Rzd2FwLSR7aG90c3dhcCA9PT0gSG90c3dhcE1vZGUuRlVMTF9ERVBMT1lNRU5UID8gJ29mZicgOiAnb24nfWAsXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9kZXBsb3koYXNzZW1ibHksICd3YXRjaCcsIGRlcGxveU9wdGlvbnMpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8ganVzdCBjb250aW51ZSAtIGRlcGxveSB3aWxsIHNob3cgdGhlIGVycm9yXG4gICAgfVxuICB9XG59XG4iXX0=
691
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGtpdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRvb2xraXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsa0NBQWtDO0FBQ2xDLHlDQUF5QztBQUN6QywrQkFBK0I7QUFDL0IscUNBQXFDO0FBQ3JDLCtCQUErQjtBQUUvQix1Q0FBK0M7QUFFL0Msb0RBQXVEO0FBQ3ZELDhDQUF3RjtBQUN4Rix1REFBaUo7QUFFakoscURBQWtFO0FBS2xFLHNEQUFpRTtBQUdqRSw0Q0FBa087QUFFbE8sMERBQStEO0FBRS9ELDJEQUFvSDtBQUVwSCwrQ0FBOEc7QUFFOUcsMERBQW1EO0FBRW5ELHdEQUFvRDtBQUNwRCwwQ0FBMkg7QUFDM0gscURBQTZDO0FBNkM3Qzs7R0FFRztBQUNILE1BQWEsT0FBUSxTQUFRLG9DQUEwQjtJQVlqQjtJQVhwQzs7T0FFRztJQUNhLGdCQUFnQixDQUFTO0lBRXpDOztPQUVHO0lBQ2EsTUFBTSxDQUFVO0lBQ3hCLFlBQVksQ0FBZTtJQUVuQyxZQUFvQyxRQUF3QixFQUFFO1FBQzVELEtBQUssRUFBRSxDQUFDO1FBRDBCLFVBQUssR0FBTCxLQUFLLENBQXFCO1FBRTVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLElBQUksb0NBQTBCLENBQUM7UUFFN0Usb0ZBQW9GO1FBQ3BGLE1BQU0sWUFBWSxHQUFHLG1CQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDMUMsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsWUFBWSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsTUFBYSxDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUNELElBQUksTUFBTSxHQUFHLFlBQXVCLENBQUM7UUFDckMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQzNCLE1BQU0sR0FBRyxJQUFBLHVCQUFhLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUNELElBQUks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XG5pbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0ICogYXMgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0ICogYXMgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHR5cGUgeyBUb29sa2l0U2VydmljZXMgfSBmcm9tICcuL3ByaXZhdGUnO1xuaW1wb3J0IHsgYXNzZW1ibHlGcm9tU291cmNlIH0gZnJvbSAnLi9wcml2YXRlJztcbmltcG9ydCB0eXBlIHsgQm9vdHN0cmFwRW52aXJvbm1lbnRzLCBCb290c3RyYXBPcHRpb25zIH0gZnJvbSAnLi4vYWN0aW9ucy9ib290c3RyYXAnO1xuaW1wb3J0IHsgQm9vdHN0cmFwU291cmNlIH0gZnJvbSAnLi4vYWN0aW9ucy9ib290c3RyYXAnO1xuaW1wb3J0IHsgQXNzZXRCdWlsZFRpbWUsIHR5cGUgRGVwbG95T3B0aW9ucywgUmVxdWlyZUFwcHJvdmFsIH0gZnJvbSAnLi4vYWN0aW9ucy9kZXBsb3knO1xuaW1wb3J0IHsgdHlwZSBFeHRlbmRlZERlcGxveU9wdGlvbnMsIGJ1aWxkUGFyYW1ldGVyTWFwLCBjcmVhdGVIb3Rzd2FwUHJvcGVydHlPdmVycmlkZXMsIHJlbW92ZVB1Ymxpc2hlZEFzc2V0cyB9IGZyb20gJy4uL2FjdGlvbnMvZGVwbG95L3ByaXZhdGUnO1xuaW1wb3J0IHsgdHlwZSBEZXN0cm95T3B0aW9ucyB9IGZyb20gJy4uL2FjdGlvbnMvZGVzdHJveSc7XG5pbXBvcnQgeyBkZXRlcm1pbmVQZXJtaXNzaW9uVHlwZSB9IGZyb20gJy4uL2FjdGlvbnMvZGlmZi9wcml2YXRlJztcbmltcG9ydCB7IHR5cGUgTGlzdE9wdGlvbnMgfSBmcm9tICcuLi9hY3Rpb25zL2xpc3QnO1xuaW1wb3J0IHsgdHlwZSBSb2xsYmFja09wdGlvbnMgfSBmcm9tICcuLi9hY3Rpb25zL3JvbGxiYWNrJztcbmltcG9ydCB7IHR5cGUgU3ludGhPcHRpb25zIH0gZnJvbSAnLi4vYWN0aW9ucy9zeW50aCc7XG5pbXBvcnQgdHlwZSB7IFdhdGNoT3B0aW9ucyB9IGZyb20gJy4uL2FjdGlvbnMvd2F0Y2gnO1xuaW1wb3J0IHsgcGF0dGVybnNBcnJheUZvcldhdGNoIH0gZnJvbSAnLi4vYWN0aW9ucy93YXRjaC9wcml2YXRlJztcbmltcG9ydCB7IHR5cGUgU2RrQ29uZmlnIH0gZnJvbSAnLi4vYXBpL2F3cy1hdXRoJztcbmltcG9ydCB0eXBlIHsgU3VjY2Vzc2Z1bERlcGxveVN0YWNrUmVzdWx0LCBTdGFja0NvbGxlY3Rpb24sIENvbmN1cnJlbmN5LCBBc3NldEJ1aWxkTm9kZSwgQXNzZXRQdWJsaXNoTm9kZSwgU3RhY2tOb2RlIH0gZnJvbSAnLi4vYXBpL2F3cy1jZGsnO1xuaW1wb3J0IHsgREVGQVVMVF9UT09MS0lUX1NUQUNLX05BTUUsIEJvb3RzdHJhcHBlciwgU2RrUHJvdmlkZXIsIERlcGxveW1lbnRzLCBIb3Rzd2FwTW9kZSwgUmVzb3VyY2VNaWdyYXRvciwgdGFnc0ZvclN0YWNrLCBDbGlJb0hvc3QsIFdvcmtHcmFwaEJ1aWxkZXIsIENsb3VkV2F0Y2hMb2dFdmVudE1vbml0b3IsIGZpbmRDbG91ZFdhdGNoTG9nR3JvdXBzIH0gZnJvbSAnLi4vYXBpL2F3cy1jZGsnO1xuaW1wb3J0IHR5cGUgeyBJQ2xvdWRBc3NlbWJseVNvdXJjZSB9IGZyb20gJy4uL2FwaS9jbG91ZC1hc3NlbWJseSc7XG5pbXBvcnQgeyBTdGFja1NlbGVjdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi4vYXBpL2Nsb3VkLWFzc2VtYmx5JztcbmltcG9ydCB0eXBlIHsgU3RhY2tBc3NlbWJseSB9IGZyb20gJy4uL2FwaS9jbG91ZC1hc3NlbWJseS9wcml2YXRlJztcbmltcG9ydCB7IEFMTF9TVEFDS1MsIENsb3VkQXNzZW1ibHlTb3VyY2VCdWlsZGVyLCBJZGVudGl0eUNsb3VkQXNzZW1ibHlTb3VyY2UgfSBmcm9tICcuLi9hcGkvY2xvdWQtYXNzZW1ibHkvcHJpdmF0ZSc7XG5pbXBvcnQgdHlwZSB7IElJb0hvc3QsIElvTWVzc2FnZUxldmVsIH0gZnJvbSAnLi4vYXBpL2lvJztcbmltcG9ydCB7IElPLCBTUEFOLCBhc1Nka0xvZ2dlciwgd2l0aG91dENvbG9yLCB3aXRob3V0RW1vamlzLCB3aXRoVHJpbW1lZFdoaXRlc3BhY2UgfSBmcm9tICcuLi9hcGkvaW8vcHJpdmF0ZSc7XG5pbXBvcnQgdHlwZSB7IElvSGVscGVyIH0gZnJvbSAnLi4vYXBpL3NoYXJlZC1wcml2YXRlJztcbmltcG9ydCB7IGFzSW9IZWxwZXIgfSBmcm9tICcuLi9hcGkvc2hhcmVkLXByaXZhdGUnO1xuaW1wb3J0IHR5cGUgeyBBc3NlbWJseURhdGEsIFN0YWNrRGV0YWlscywgVG9vbGtpdEFjdGlvbiB9IGZyb20gJy4uL2FwaS9zaGFyZWQtcHVibGljJztcbmltcG9ydCB7IFRvb2xraXRFcnJvciB9IGZyb20gJy4uL2FwaS9zaGFyZWQtcHVibGljJztcbmltcG9ydCB7IG9ic2N1cmVUZW1wbGF0ZSwgc2VyaWFsaXplU3RydWN0dXJlLCB2YWxpZGF0ZVNuc1RvcGljQXJuLCBmb3JtYXRUaW1lLCBmb3JtYXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi9wcml2YXRlL3V0aWwnO1xuaW1wb3J0IHsgcExpbWl0IH0gZnJvbSAnLi4vdXRpbC9jb25jdXJyZW5jeSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbGtpdE9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIElvSG9zdCBpbXBsZW1lbnRhdGlvbiwgaGFuZGxpbmcgdGhlIGlubGluZSBpbnRlcmFjdGlvbnMgYmV0d2VlbiB0aGUgVG9vbGtpdCBhbmQgYW4gaW50ZWdyYXRpb24uXG4gICAqL1xuICBpb0hvc3Q/OiBJSW9Ib3N0O1xuXG4gIC8qKlxuICAgKiBBbGxvdyBlbW9qaXMgaW4gbWVzc2FnZXMgc2VudCB0byB0aGUgSW9Ib3N0LlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBlbW9qaXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGFsbG93IEFOU0kgY29sb3JzIGFuZCBmb3JtYXR0aW5nIGluIElvSG9zdCBtZXNzYWdlcy5cbiAgICogU2V0dGluZyB0aGlzIHZhbHVlIHRvIGBmYWxzZWAgZW5mb3JjZXMgdGhhdCBubyBjb2xvciBvciBzdHlsZSBzaG93cyB1cFxuICAgKiBpbiBtZXNzYWdlcyBzZW50IHRvIHRoZSBJb0hvc3QuXG4gICAqIFNldHRpbmcgdGhpcyB2YWx1ZSB0byB0cnVlIGlzIGEgbm8tb3A7IGl0IGlzIGVxdWl2YWxlbnQgdG8gdGhlIGRlZmF1bHQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZGV0ZWN0cyBjb2xvciBmcm9tIHRoZSBUVFkgc3RhdHVzIG9mIHRoZSBJb0hvc3RcbiAgICovXG4gIGNvbG9yPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgU0RLLlxuICAgKi9cbiAgc2RrQ29uZmlnPzogU2RrQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSB0b29sa2l0IHN0YWNrIHRvIGJlIHVzZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiQ0RLVG9vbGtpdFwiXG4gICAqL1xuICB0b29sa2l0U3RhY2tOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGYWlsIENsb3VkIEFzc2VtYmxpZXNcbiAgICpcbiAgICogQGRlZmF1bHQgXCJlcnJvclwiXG4gICAqL1xuICBhc3NlbWJseUZhaWx1cmVBdD86ICdlcnJvcicgfCAnd2FybicgfCAnbm9uZSc7XG59XG5cbi8qKlxuICogVGhlIEFXUyBDREsgUHJvZ3JhbW1hdGljIFRvb2xraXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRvb2xraXQgZXh0ZW5kcyBDbG91ZEFzc2VtYmx5U291cmNlQnVpbGRlciBpbXBsZW1lbnRzIEFzeW5jRGlzcG9zYWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgdG9vbGtpdCBzdGFjayBuYW1lIHVzZWQgZm9yIGJvb3RzdHJhcHBpbmcgcmVzb3VyY2VzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHRvb2xraXRTdGFja05hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElvSG9zdCBvZiB0aGlzIFRvb2xraXRcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpb0hvc3Q6IElJb0hvc3Q7XG4gIHByaXZhdGUgX3Nka1Byb3ZpZGVyPzogU2RrUHJvdmlkZXI7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IFRvb2xraXRPcHRpb25zID0ge30pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudG9vbGtpdFN0YWNrTmFtZSA9IHByb3BzLnRvb2xraXRTdGFja05hbWUgPz8gREVGQVVMVF9UT09MS0lUX1NUQUNLX05BTUU7XG5cbiAgICAvLyBIYWNreSB3YXkgdG8gcmUtdXNlIHRoZSBnbG9iYWwgSW9Ib3N0IHVudGlsIHdlIGhhdmUgZnVsbHkgcmVtb3ZlZCB0aGUgbmVlZCBmb3IgaXRcbiAgICBjb25zdCBnbG9iYWxJb0hvc3QgPSBDbGlJb0hvc3QuaW5zdGFuY2UoKTtcbiAgICBpZiAocHJvcHMuaW9Ib3N0KSB7XG4gICAgICBnbG9iYWxJb0hvc3QucmVnaXN0ZXJJb0hvc3QocHJvcHMuaW9Ib3N0IGFzIGFueSk7XG4gICAgfVxuICAgIGxldCBpb0hvc3QgPSBnbG9iYWxJb0hvc3QgYXMgSUlvSG9zdDtcbiAgICBpZiAocHJvcHMuZW1vamlzID09PSBmYWxzZSkge1xuICAgICAgaW9Ib3N0ID0gd2l0aG91dEVtb2ppcyhpb0hvc3QpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuY29sb3IgPT09IGZhbHNlKSB7XG4gICAgICBpb0hvc3QgPSB3aXRob3V0Q29sb3IoaW9Ib3N0KTtcbiAgICB9XG4gICAgLy8gQWZ0ZXIgcmVtb3ZpbmcgZW1vamlzIGFuZCBjb2xvciwgd2UgbWlnaHQgZW5kIHVwIHdpdGggZmxvYXRpbmcgd2hpdGVzcGFjZSBhdCBlaXRoZXIgZW5kIG9mIHRoZSBtZXNzYWdlXG4gICAgLy8gVGhpcyBhbHNvIHJlbW92ZXMgbmV3bGluZXMgdGhhdCB3ZSBjdXJyZW50bHkgZW1pdCBmb3IgQ0xJIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuICAgIHRoaXMuaW9Ib3N0ID0gd2l0aFRyaW1tZWRXaGl0ZXNwYWNlKGlvSG9zdCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBub3RoaW5nIHRvIGRvIHlldFxuICB9XG5cbiAgcHVibGljIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRpc3Bvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY2Nlc3MgdG8gdGhlIEFXUyBTREtcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2RrUHJvdmlkZXIoYWN0aW9uOiBUb29sa2l0QWN0aW9uKTogUHJvbWlzZTxTZGtQcm92aWRlcj4ge1xuICAgIC8vIEB0b2RvIHRoaXMgbmVlZHMgdG8gYmUgZGlmZmVyZW50IGluc3RhbmNlIHBlciBhY3Rpb25cbiAgICBpZiAoIXRoaXMuX3Nka1Byb3ZpZGVyKSB7XG4gICAgICB0aGlzLl9zZGtQcm92aWRlciA9IGF3YWl0IFNka1Byb3ZpZGVyLndpdGhBd3NDbGlDb21wYXRpYmxlRGVmYXVsdHMoe1xuICAgICAgICAuLi50aGlzLnByb3BzLnNka0NvbmZpZyxcbiAgICAgICAgbG9nZ2VyOiBhc1Nka0xvZ2dlcihhc0lvSGVscGVyKHRoaXMuaW9Ib3N0LCBhY3Rpb24pKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9zZGtQcm92aWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gcHJvdmlkZSB0aGUgQ2xvdWRBc3NlbWJseVNvdXJjZUJ1aWxkZXIgd2l0aCByZXF1aXJlZCB0b29sa2l0IHNlcnZpY2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgc291cmNlQnVpbGRlclNlcnZpY2VzKCk6IFByb21pc2U8VG9vbGtpdFNlcnZpY2VzPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlvSGVscGVyOiBhc0lvSGVscGVyKHRoaXMuaW9Ib3N0LCAnYXNzZW1ibHknKSxcbiAgICAgIHNka1Byb3ZpZGVyOiBhd2FpdCB0aGlzLnNka1Byb3ZpZGVyKCdhc3NlbWJseScpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQm9vdHN0cmFwIEFjdGlvblxuICAgKi9cbiAgcHVibGljIGFzeW5jIGJvb3RzdHJhcChlbnZpcm9ubWVudHM6IEJvb3RzdHJhcEVudmlyb25tZW50cywgb3B0aW9uczogQm9vdHN0cmFwT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlvSGVscGVyID0gYXNJb0hlbHBlcih0aGlzLmlvSG9zdCwgJ2Jvb3RzdHJhcCcpO1xuICAgIGNvbnN0IGJvb3RzdHJhcEVudmlyb25tZW50cyA9IGF3YWl0IGVudmlyb25tZW50cy5nZXRFbnZpcm9ubWVudHMoKTtcbiAgICBjb25zdCBzb3VyY2UgPSBvcHRpb25zLnNvdXJjZSA/PyBCb290c3RyYXBTb3VyY2UuZGVmYXVsdCgpO1xuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBvcHRpb25zLnBhcmFtZXRlcnM7XG4gICAgY29uc3QgYm9vdHN0cmFwcGVyID0gbmV3IEJvb3RzdHJhcHBlcihzb3VyY2UsIGlvSGVscGVyKTtcbiAgICBjb25zdCBzZGtQcm92aWRlciA9IGF3YWl0IHRoaXMuc2RrUHJvdmlkZXIoJ2Jvb3RzdHJhcCcpO1xuICAgIGNvbnN0IGxpbWl0ID0gcExpbWl0KDIwKTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAY2RrbGFicy9wcm9taXNlYWxsLW5vLXVuYm91bmRlZC1wYXJhbGxlbGlzbVxuICAgIGF3YWl0IFByb21pc2UuYWxsKGJvb3RzdHJhcEVudmlyb25tZW50cy5tYXAoKGVudmlyb25tZW50OiBjeGFwaS5FbnZpcm9ubWVudCwgY3VycmVudElkeCkgPT4gbGltaXQoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYm9vdHN0cmFwU3BhbiA9IGF3YWl0IGlvSGVscGVyLnNwYW4oU1BBTi5CT09UU1RSQVBfU0lOR0xFKVxuICAgICAgICAuYmVnaW4oYCR7Y2hhbGsuYm9sZChlbnZpcm9ubWVudC5uYW1lKX06IGJvb3RzdHJhcHBpbmcuLi5gLCB7XG4gICAgICAgICAgdG90YWw6IGJvb3RzdHJhcEVudmlyb25tZW50cy5sZW5ndGgsXG4gICAgICAgICAgY3VycmVudDogY3VycmVudElkeCsxLFxuICAgICAgICAgIGVudmlyb25tZW50LFxuICAgICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYm9vdHN0cmFwUmVzdWx0ID0gYXdhaXQgYm9vdHN0cmFwcGVyLmJvb3RzdHJhcEVudmlyb25tZW50KFxuICAgICAgICAgIGVudmlyb25tZW50LFxuICAgICAgICAgIHNka1Byb3ZpZGVyLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICB0b29sa2l0U3RhY2tOYW1lOiB0aGlzLnRvb2xraXRTdGFja05hbWUsXG4gICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJzPy5wYXJhbWV0ZXJzLFxuICAgICAgICAgICAgdXNlUHJldmlvdXNQYXJhbWV0ZXJzOiBwYXJhbWV0ZXJzPy5rZWVwRXhpc3RpbmdQYXJhbWV0ZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBib290c3RyYXBSZXN1bHQubm9PcFxuICAgICAgICAgID8gYCDinIUgICR7ZW52aXJvbm1lbnQubmFtZX0gKG5vIGNoYW5nZXMpYFxuICAgICAgICAgIDogYCDinIUgICR7ZW52aXJvbm1lbnQubmFtZX1gO1xuXG4gICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JOTkwMC5tc2coY2hhbGsuZ3JlZW4oJ1xcbicgKyBtZXNzYWdlKSwgeyBlbnZpcm9ubWVudCB9KSk7XG4gICAgICAgIGF3YWl0IGJvb3RzdHJhcFNwYW4uZW5kKCk7XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0U5OTAwLm1zZyhgXFxuIOKdjCAgJHtjaGFsay5ib2xkKGVudmlyb25tZW50Lm5hbWUpfSBmYWlsZWQ6ICR7Zm9ybWF0RXJyb3JNZXNzYWdlKGUpfWAsIHsgZXJyb3I6IGUgfSkpO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0pKSk7XG4gIH1cblxuICAvKipcbiAgICogU3ludGggQWN0aW9uXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3ludGgoY3g6IElDbG91ZEFzc2VtYmx5U291cmNlLCBvcHRpb25zOiBTeW50aE9wdGlvbnMgPSB7fSk6IFByb21pc2U8SUNsb3VkQXNzZW1ibHlTb3VyY2U+IHtcbiAgICBjb25zdCBpb0hlbHBlciA9IGFzSW9IZWxwZXIodGhpcy5pb0hvc3QsICdzeW50aCcpO1xuICAgIGNvbnN0IHNlbGVjdFN0YWNrcyA9IG9wdGlvbnMuc3RhY2tzID8/IEFMTF9TVEFDS1M7XG4gICAgY29uc3Qgc3ludGhTcGFuID0gYXdhaXQgaW9IZWxwZXIuc3BhbihTUEFOLlNZTlRIX0FTU0VNQkxZKS5iZWdpbih7IHN0YWNrczogc2VsZWN0U3RhY2tzIH0pO1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgYXNzZW1ibHlGcm9tU291cmNlKGN4KTtcbiAgICBjb25zdCBzdGFja3MgPSBhc3NlbWJseS5zZWxlY3RTdGFja3NWMihzZWxlY3RTdGFja3MpO1xuICAgIGNvbnN0IGF1dG9WYWxpZGF0ZVN0YWNrcyA9IG9wdGlvbnMudmFsaWRhdGVTdGFja3MgPyBbYXNzZW1ibHkuc2VsZWN0U3RhY2tzRm9yVmFsaWRhdGlvbigpXSA6IFtdO1xuICAgIGF3YWl0IHRoaXMudmFsaWRhdGVTdGFja3NNZXRhZGF0YShzdGFja3MuY29uY2F0KC4uLmF1dG9WYWxpZGF0ZVN0YWNrcyksIGlvSGVscGVyKTtcbiAgICBhd2FpdCBzeW50aFNwYW4uZW5kKCk7XG5cbiAgICAvLyBpZiB3ZSBoYXZlIGEgc2luZ2xlIHN0YWNrLCBwcmludCBpdCB0byBTVERPVVRcbiAgICBjb25zdCBtZXNzYWdlID0gYFN1Y2Nlc3NmdWxseSBzeW50aGVzaXplZCB0byAke2NoYWxrLmJsdWUocGF0aC5yZXNvbHZlKHN0YWNrcy5hc3NlbWJseS5kaXJlY3RvcnkpKX1gO1xuICAgIGNvbnN0IGFzc2VtYmx5RGF0YTogQXNzZW1ibHlEYXRhID0ge1xuICAgICAgYXNzZW1ibHlEaXJlY3Rvcnk6IHN0YWNrcy5hc3NlbWJseS5kaXJlY3RvcnksXG4gICAgICBzdGFja3NDb3VudDogc3RhY2tzLnN0YWNrQ291bnQsXG4gICAgICBzdGFja0lkczogc3RhY2tzLmhpZXJhcmNoaWNhbElkcyxcbiAgICB9O1xuXG4gICAgaWYgKHN0YWNrcy5zdGFja0NvdW50ID09PSAxKSB7XG4gICAgICBjb25zdCBmaXJzdFN0YWNrID0gc3RhY2tzLmZpcnN0U3RhY2shO1xuICAgICAgY29uc3QgdGVtcGxhdGUgPSBmaXJzdFN0YWNrLnRlbXBsYXRlO1xuICAgICAgY29uc3Qgb2JzY3VyZWRUZW1wbGF0ZSA9IG9ic2N1cmVUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uQ0RLX1RPT0xLSVRfSTE5MDEubXNnKG1lc3NhZ2UsIHtcbiAgICAgICAgLi4uYXNzZW1ibHlEYXRhLFxuICAgICAgICBzdGFjazoge1xuICAgICAgICAgIHN0YWNrTmFtZTogZmlyc3RTdGFjay5zdGFja05hbWUsXG4gICAgICAgICAgaGllcmFyY2hpY2FsSWQ6IGZpcnN0U3RhY2suaGllcmFyY2hpY2FsSWQsXG4gICAgICAgICAgdGVtcGxhdGUsXG4gICAgICAgICAgc3RyaW5naWZpZWRKc29uOiBzZXJpYWxpemVTdHJ1Y3R1cmUob2JzY3VyZWRUZW1wbGF0ZSwgdHJ1ZSksXG4gICAgICAgICAgc3RyaW5naWZpZWRZYW1sOiBzZXJpYWxpemVTdHJ1Y3R1cmUob2JzY3VyZWRUZW1wbGF0ZSwgZmFsc2UpLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub3Qgb3V0cHV0dGluZyB0ZW1wbGF0ZSB0byBzdGRvdXQsIGxldCdzIGV4cGxhaW4gdGhpbmdzIHRvIHRoZSB1c2VyIGEgbGl0dGxlIGJpdC4uLlxuICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0kxOTAyLm1zZyhjaGFsay5ncmVlbihtZXNzYWdlKSwgYXNzZW1ibHlEYXRhKSk7XG4gICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uREVGQVVMVF9UT09MS0lUX0lORk8ubXNnKGBTdXBwbHkgYSBzdGFjayBpZCAoJHtzdGFja3Muc3RhY2tBcnRpZmFjdHMubWFwKChzKSA9PiBjaGFsay5ncmVlbihzLmhpZXJhcmNoaWNhbElkKSkuam9pbignLCAnKX0pIHRvIGRpc3BsYXkgaXRzIHRlbXBsYXRlLmApKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IElkZW50aXR5Q2xvdWRBc3NlbWJseVNvdXJjZShhc3NlbWJseS5hc3NlbWJseSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBBY3Rpb25cbiAgICpcbiAgICogTGlzdCBzZWxlY3RlZCBzdGFja3MgYW5kIHRoZWlyIGRlcGVuZGVuY2llc1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3QoY3g6IElDbG91ZEFzc2VtYmx5U291cmNlLCBvcHRpb25zOiBMaXN0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxTdGFja0RldGFpbHNbXT4ge1xuICAgIGNvbnN0IGlvSGVscGVyID0gYXNJb0hlbHBlcih0aGlzLmlvSG9zdCwgJ2xpc3QnKTtcbiAgICBjb25zdCBzZWxlY3RTdGFja3MgPSBvcHRpb25zLnN0YWNrcyA/PyBBTExfU1RBQ0tTO1xuICAgIGNvbnN0IHN5bnRoU3BhbiA9IGF3YWl0IGlvSGVscGVyLnNwYW4oU1BBTi5TWU5USF9BU1NFTUJMWSkuYmVnaW4oeyBzdGFja3M6IHNlbGVjdFN0YWNrcyB9KTtcbiAgICBjb25zdCBhc3NlbWJseSA9IGF3YWl0IGFzc2VtYmx5RnJvbVNvdXJjZShjeCk7XG4gICAgY29uc3Qgc3RhY2tDb2xsZWN0aW9uID0gYXdhaXQgYXNzZW1ibHkuc2VsZWN0U3RhY2tzVjIoc2VsZWN0U3RhY2tzKTtcbiAgICBhd2FpdCBzeW50aFNwYW4uZW5kKCk7XG5cbiAgICBjb25zdCBzdGFja3MgPSBzdGFja0NvbGxlY3Rpb24ud2l0aERlcGVuZGVuY2llcygpO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBzdGFja3MubWFwKHMgPT4gcy5pZCkuam9pbignXFxuJyk7XG5cbiAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uQ0RLX1RPT0xLSVRfSTI5MDEubXNnKG1lc3NhZ2UsIHsgc3RhY2tzIH0pKTtcbiAgICByZXR1cm4gc3RhY2tzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlcGxveSBBY3Rpb25cbiAgICpcbiAgICogRGVwbG95cyB0aGUgc2VsZWN0ZWQgc3RhY2tzIGludG8gYW4gQVdTIGFjY291bnRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBkZXBsb3koY3g6IElDbG91ZEFzc2VtYmx5U291cmNlLCBvcHRpb25zOiBEZXBsb3lPcHRpb25zID0ge30pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBhc3NlbWJseSA9IGF3YWl0IGFzc2VtYmx5RnJvbVNvdXJjZShjeCk7XG4gICAgcmV0dXJuIHRoaXMuX2RlcGxveShhc3NlbWJseSwgJ2RlcGxveScsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciB0byBhbGxvdyBkZXBsb3kgYmVpbmcgY2FsbGVkIGFzIHBhcnQgb2YgdGhlIHdhdGNoIGFjdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2RlcGxveShhc3NlbWJseTogU3RhY2tBc3NlbWJseSwgYWN0aW9uOiAnZGVwbG95JyB8ICd3YXRjaCcsIG9wdGlvbnM6IEV4dGVuZGVkRGVwbG95T3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgaW9IZWxwZXIgPSBhc0lvSGVscGVyKHRoaXMuaW9Ib3N0LCBhY3Rpb24pO1xuICAgIGNvbnN0IHNlbGVjdFN0YWNrcyA9IG9wdGlvbnMuc3RhY2tzID8/IEFMTF9TVEFDS1M7XG4gICAgY29uc3Qgc3ludGhTcGFuID0gYXdhaXQgaW9IZWxwZXIuc3BhbihTUEFOLlNZTlRIX0FTU0VNQkxZKS5iZWdpbih7IHN0YWNrczogc2VsZWN0U3RhY2tzIH0pO1xuICAgIGNvbnN0IHN0YWNrQ29sbGVjdGlvbiA9IGFzc2VtYmx5LnNlbGVjdFN0YWNrc1YyKHNlbGVjdFN0YWNrcyk7XG4gICAgYXdhaXQgdGhpcy52YWxpZGF0ZVN0YWNrc01ldGFkYXRhKHN0YWNrQ29sbGVjdGlvbiwgaW9IZWxwZXIpO1xuICAgIGNvbnN0IHN5bnRoRHVyYXRpb24gPSBhd2FpdCBzeW50aFNwYW4uZW5kKCk7XG5cbiAgICBpZiAoc3RhY2tDb2xsZWN0aW9uLnN0YWNrQ291bnQgPT09IDApIHtcbiAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9FNTAwMS5tc2coJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZXBsb3ltZW50cyA9IGF3YWl0IHRoaXMuZGVwbG95bWVudHNGb3JBY3Rpb24oJ2RlcGxveScpO1xuICAgIGNvbnN0IG1pZ3JhdG9yID0gbmV3IFJlc291cmNlTWlncmF0b3IoeyBkZXBsb3ltZW50cywgaW9IZWxwZXIgfSk7XG5cbiAgICBhd2FpdCBtaWdyYXRvci50cnlNaWdyYXRlUmVzb3VyY2VzKHN0YWNrQ29sbGVjdGlvbiwgb3B0aW9ucyk7XG5cbiAgICBjb25zdCBwYXJhbWV0ZXJNYXAgPSBidWlsZFBhcmFtZXRlck1hcChvcHRpb25zLnBhcmFtZXRlcnM/LnBhcmFtZXRlcnMpO1xuXG4gICAgY29uc3QgaG90c3dhcE1vZGUgPSBvcHRpb25zLmhvdHN3YXAgPz8gSG90c3dhcE1vZGUuRlVMTF9ERVBMT1lNRU5UO1xuICAgIGlmIChob3Rzd2FwTW9kZSAhPT0gSG90c3dhcE1vZGUuRlVMTF9ERVBMT1lNRU5UKSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uQ0RLX1RPT0xLSVRfVzU0MDAubXNnKFtcbiAgICAgICAgJ+KaoO+4jyBUaGUgLS1ob3Rzd2FwIGFuZCAtLWhvdHN3YXAtZmFsbGJhY2sgZmxhZ3MgZGVsaWJlcmF0ZWx5IGludHJvZHVjZSBDbG91ZEZvcm1hdGlvbiBkcmlmdCB0byBzcGVlZCB1cCBkZXBsb3ltZW50cycsXG4gICAgICAgICfimqDvuI8gVGhleSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBkZXZlbG9wbWVudCAtIG5ldmVyIHVzZSB0aGVtIGZvciB5b3VyIHByb2R1Y3Rpb24gU3RhY2tzIScsXG4gICAgICBdLmpvaW4oJ1xcbicpKSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhY2tzID0gc3RhY2tDb2xsZWN0aW9uLnN0YWNrQXJ0aWZhY3RzO1xuICAgIGNvbnN0IHN0YWNrT3V0cHV0czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuICAgIGNvbnN0IG91dHB1dHNGaWxlID0gb3B0aW9ucy5vdXRwdXRzRmlsZTtcblxuICAgIGNvbnN0IGJ1aWxkQXNzZXQgPSBhc3luYyAoYXNzZXROb2RlOiBBc3NldEJ1aWxkTm9kZSkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRBc3NldFNwYW4gPSBhd2FpdCBpb0hlbHBlci5zcGFuKFNQQU4uQlVJTERfQVNTRVQpLmJlZ2luKHtcbiAgICAgICAgYXNzZXQ6IGFzc2V0Tm9kZS5hc3NldCxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgZGVwbG95bWVudHMuYnVpbGRTaW5nbGVBc3NldChcbiAgICAgICAgYXNzZXROb2RlLmFzc2V0TWFuaWZlc3RBcnRpZmFjdCxcbiAgICAgICAgYXNzZXROb2RlLmFzc2V0TWFuaWZlc3QsXG4gICAgICAgIGFzc2V0Tm9kZS5hc3NldCxcbiAgICAgICAge1xuICAgICAgICAgIHN0YWNrOiBhc3NldE5vZGUucGFyZW50U3RhY2ssXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIHN0YWNrTmFtZTogYXNzZXROb2RlLnBhcmVudFN0YWNrLnN0YWNrTmFtZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBhd2FpdCBidWlsZEFzc2V0U3Bhbi5lbmQoKTtcbiAgICB9O1xuXG4gICAgY29uc3QgcHVibGlzaEFzc2V0ID0gYXN5bmMgKGFzc2V0Tm9kZTogQXNzZXRQdWJsaXNoTm9kZSkgPT4ge1xuICAgICAgY29uc3QgcHVibGlzaEFzc2V0U3BhbiA9IGF3YWl0IGlvSGVscGVyLnNwYW4oU1BBTi5QVUJMSVNIX0FTU0VUKS5iZWdpbih7XG4gICAgICAgIGFzc2V0OiBhc3NldE5vZGUuYXNzZXQsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGRlcGxveW1lbnRzLnB1Ymxpc2hTaW5nbGVBc3NldChhc3NldE5vZGUuYXNzZXRNYW5pZmVzdCwgYXNzZXROb2RlLmFzc2V0LCB7XG4gICAgICAgIHN0YWNrOiBhc3NldE5vZGUucGFyZW50U3RhY2ssXG4gICAgICAgIHJvbGVBcm46IG9wdGlvbnMucm9sZUFybixcbiAgICAgICAgc3RhY2tOYW1lOiBhc3NldE5vZGUucGFyZW50U3RhY2suc3RhY2tOYW1lLFxuICAgICAgICBmb3JjZVB1Ymxpc2g6IG9wdGlvbnMuZm9yY2UsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHB1Ymxpc2hBc3NldFNwYW4uZW5kKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGRlcGxveVN0YWNrID0gYXN5bmMgKHN0YWNrTm9kZTogU3RhY2tOb2RlKSA9PiB7XG4gICAgICBjb25zdCBzdGFjayA9IHN0YWNrTm9kZS5zdGFjaztcbiAgICAgIGlmIChzdGFja0NvbGxlY3Rpb24uc3RhY2tDb3VudCAhPT0gMSkge1xuICAgICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uREVGQVVMVF9UT09MS0lUX0lORk8ubXNnKGNoYWxrLmJvbGQoc3RhY2suZGlzcGxheU5hbWUpKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghc3RhY2suZW52aXJvbm1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgICBgU3RhY2sgJHtzdGFjay5kaXNwbGF5TmFtZX0gZG9lcyBub3QgZGVmaW5lIGFuIGVudmlyb25tZW50LCBhbmQgQVdTIGNyZWRlbnRpYWxzIGNvdWxkIG5vdCBiZSBvYnRhaW5lZCBmcm9tIHN0YW5kYXJkIGxvY2F0aW9ucyBvciBubyByZWdpb24gd2FzIGNvbmZpZ3VyZWQuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gVGhlIGdlbmVyYXRlZCBzdGFjayBoYXMgbm8gcmVzb3VyY2VzXG4gICAgICBpZiAoT2JqZWN0LmtleXMoc3RhY2sudGVtcGxhdGUuUmVzb3VyY2VzIHx8IHt9KS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gc3RhY2sgaXMgZW1wdHkgYW5kIGRvZXNuJ3QgZXhpc3QgPT4gZG8gbm90aGluZ1xuICAgICAgICBjb25zdCBzdGFja0V4aXN0cyA9IGF3YWl0IGRlcGxveW1lbnRzLnN0YWNrRXhpc3RzKHsgc3RhY2sgfSk7XG4gICAgICAgIGlmICghc3RhY2tFeGlzdHMpIHtcbiAgICAgICAgICByZXR1cm4gaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX1c1MDIxLm1zZyhgJHtjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKX06IHN0YWNrIGhhcyBubyByZXNvdXJjZXMsIHNraXBwaW5nIGRlcGxveW1lbnQuYCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RhY2sgaXMgZW1wdHksIGJ1dCBleGlzdHMgPT4gZGVsZXRlXG4gICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9XNTAyMi5tc2coYCR7Y2hhbGsuYm9sZChzdGFjay5kaXNwbGF5TmFtZSl9OiBzdGFjayBoYXMgbm8gcmVzb3VyY2VzLCBkZWxldGluZyBleGlzdGluZyBzdGFjay5gKSk7XG4gICAgICAgIGF3YWl0IHRoaXMuX2Rlc3Ryb3koYXNzZW1ibHksICdkZXBsb3knLCB7XG4gICAgICAgICAgc3RhY2tzOiB7IHBhdHRlcm5zOiBbc3RhY2suaGllcmFyY2hpY2FsSWRdLCBzdHJhdGVneTogU3RhY2tTZWxlY3Rpb25TdHJhdGVneS5QQVRURVJOX01VU1RfTUFUQ0hfU0lOR0xFIH0sXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgIGNpOiBvcHRpb25zLmNpLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGN1cnJlbnRUZW1wbGF0ZSA9IGF3YWl0IGRlcGxveW1lbnRzLnJlYWRDdXJyZW50VGVtcGxhdGUoc3RhY2spO1xuICAgICAgY29uc3QgcGVybWlzc2lvbkNoYW5nZVR5cGUgPSBkZXRlcm1pbmVQZXJtaXNzaW9uVHlwZShjdXJyZW50VGVtcGxhdGUsIHN0YWNrKTtcbiAgICAgIGNvbnN0IGRlcGxveU1vdGl2YXRpb24gPSAnXCItLXJlcXVpcmUtYXBwcm92YWxcIiBpcyBlbmFibGVkIGFuZCBzdGFjayBpbmNsdWRlcyBzZWN1cml0eS1zZW5zaXRpdmUgdXBkYXRlcy4nO1xuICAgICAgY29uc3QgZGVwbG95UXVlc3Rpb24gPSBgJHtkZXBsb3lNb3RpdmF0aW9ufVxcbkRvIHlvdSB3aXNoIHRvIGRlcGxveSB0aGVzZSBjaGFuZ2VzYDtcbiAgICAgIGNvbnN0IGRlcGxveUNvbmZpcm1lZCA9IGF3YWl0IGlvSGVscGVyLnJlcXVlc3RSZXNwb25zZShJTy5DREtfVE9PTEtJVF9JNTA2MC5yZXEoZGVwbG95UXVlc3Rpb24sIHtcbiAgICAgICAgbW90aXZhdGlvbjogZGVwbG95TW90aXZhdGlvbixcbiAgICAgICAgY29uY3VycmVuY3ksXG4gICAgICAgIHBlcm1pc3Npb25DaGFuZ2VUeXBlLFxuICAgICAgfSkpO1xuICAgICAgaWYgKCFkZXBsb3lDb25maXJtZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQWJvcnRlZCBieSB1c2VyJyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvbGxvd2luZyBhcmUgdGhlIHNhbWUgc2VtYW50aWNzIHdlIGFwcGx5IHdpdGggcmVzcGVjdCB0byBOb3RpZmljYXRpb24gQVJOcyAoZGljdGF0ZWQgYnkgdGhlIFNESylcbiAgICAgIC8vXG4gICAgICAvLyAgLSB1bmRlZmluZWQgID0+ICBjZGsgaWdub3JlcyBpdCwgYXMgaWYgaXQgd2Fzbid0IHN1cHBvcnRlZCAoYWxsb3dzIGV4dGVybmFsIG1hbmFnZW1lbnQpLlxuICAgICAgLy8gIC0gW106ICAgICAgICA9PiAgY2RrIG1hbmFnZXMgaXQsIGFuZCB0aGUgdXNlciB3YW50cyB0byB3aXBlIGl0IG91dC5cbiAgICAgIC8vICAtIFsnYXJuLTEnXSAgPT4gIGNkayBtYW5hZ2VzIGl0LCBhbmQgdGhlIHVzZXIgd2FudHMgdG8gc2V0IGl0IHRvIFsnYXJuLTEnXS5cbiAgICAgIGNvbnN0IG5vdGlmaWNhdGlvbkFybnMgPSAoISFvcHRpb25zLm5vdGlmaWNhdGlvbkFybnMgfHwgISFzdGFjay5ub3RpZmljYXRpb25Bcm5zKVxuICAgICAgICA/IChvcHRpb25zLm5vdGlmaWNhdGlvbkFybnMgPz8gW10pLmNvbmNhdChzdGFjay5ub3RpZmljYXRpb25Bcm5zID8/IFtdKVxuICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgZm9yIChjb25zdCBub3RpZmljYXRpb25Bcm4gb2Ygbm90aWZpY2F0aW9uQXJucyA/PyBbXSkge1xuICAgICAgICBpZiAoIXZhbGlkYXRlU25zVG9waWNBcm4obm90aWZpY2F0aW9uQXJuKSkge1xuICAgICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoYE5vdGlmaWNhdGlvbiBhcm4gJHtub3RpZmljYXRpb25Bcm59IGlzIG5vdCBhIHZhbGlkIGFybiBmb3IgYW4gU05TIHRvcGljYCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhY2tJbmRleCA9IHN0YWNrcy5pbmRleE9mKHN0YWNrKSArIDE7XG4gICAgICBjb25zdCBkZXBsb3lTcGFuID0gYXdhaXQgaW9IZWxwZXIuc3BhbihTUEFOLkRFUExPWV9TVEFDSylcbiAgICAgICAgLmJlZ2luKGAke2NoYWxrLmJvbGQoc3RhY2suZGlzcGxheU5hbWUpfTogZGVwbG95aW5nLi4uIFske3N0YWNrSW5kZXh9LyR7c3RhY2tDb2xsZWN0aW9uLnN0YWNrQ291bnR9XWAsIHtcbiAgICAgICAgICB0b3RhbDogc3RhY2tDb2xsZWN0aW9uLnN0YWNrQ291bnQsXG4gICAgICAgICAgY3VycmVudDogc3RhY2tJbmRleCxcbiAgICAgICAgICBzdGFjayxcbiAgICAgICAgfSk7XG5cbiAgICAgIGxldCB0YWdzID0gb3B0aW9ucy50YWdzO1xuICAgICAgaWYgKCF0YWdzIHx8IHRhZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRhZ3MgPSB0YWdzRm9yU3RhY2soc3RhY2spO1xuICAgICAgfVxuXG4gICAgICBsZXQgZGVwbG95RHVyYXRpb247XG4gICAgICB0cnkge1xuICAgICAgICBsZXQgZGVwbG95UmVzdWx0OiBTdWNjZXNzZnVsRGVwbG95U3RhY2tSZXN1bHQgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgbGV0IHJvbGxiYWNrID0gb3B0aW9ucy5yb2xsYmFjaztcbiAgICAgICAgbGV0IGl0ZXJhdGlvbiA9IDA7XG4gICAgICAgIHdoaWxlICghZGVwbG95UmVzdWx0KSB7XG4gICAgICAgICAgaWYgKCsraXRlcmF0aW9uID4gMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignVGhpcyBsb29wIHNob3VsZCBoYXZlIHN0YWJpbGl6ZWQgaW4gMiBpdGVyYXRpb25zLCBidXQgZGlkblxcJ3QuIElmIHlvdSBhcmUgc2VlaW5nIHRoaXMgZXJyb3IsIHBsZWFzZSByZXBvcnQgaXQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy9uZXcvY2hvb3NlJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgciA9IGF3YWl0IGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgZGVwbG95TmFtZTogc3RhY2suc3RhY2tOYW1lLFxuICAgICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICAgICAgdG9vbGtpdFN0YWNrTmFtZTogdGhpcy50b29sa2l0U3RhY2tOYW1lLFxuICAgICAgICAgICAgcmV1c2VBc3NldHM6IG9wdGlvbnMucmV1c2VBc3NldHMsXG4gICAgICAgICAgICBub3RpZmljYXRpb25Bcm5zLFxuICAgICAgICAgICAgdGFncyxcbiAgICAgICAgICAgIGRlcGxveW1lbnRNZXRob2Q6IG9wdGlvbnMuZGVwbG95bWVudE1ldGhvZCxcbiAgICAgICAgICAgIGZvcmNlOiBvcHRpb25zLmZvcmNlLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogT2JqZWN0LmFzc2lnbih7fSwgcGFyYW1ldGVyTWFwWycqJ10sIHBhcmFtZXRlck1hcFtzdGFjay5zdGFja05hbWVdKSxcbiAgICAgICAgICAgIHVzZVByZXZpb3VzUGFyYW1ldGVyczogb3B0aW9ucy5wYXJhbWV0ZXJzPy5rZWVwRXhpc3RpbmdQYXJhbWV0ZXJzLFxuICAgICAgICAgICAgcm9sbGJhY2ssXG4gICAgICAgICAgICBob3Rzd2FwOiBob3Rzd2FwTW9kZSxcbiAgICAgICAgICAgIGV4dHJhVXNlckFnZW50OiBvcHRpb25zLmV4dHJhVXNlckFnZW50LFxuICAgICAgICAgICAgaG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzOiBvcHRpb25zLmhvdHN3YXBQcm9wZXJ0aWVzID8gY3JlYXRlSG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzKG9wdGlvbnMuaG90c3dhcFByb3BlcnRpZXMpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXNzZXRQYXJhbGxlbGlzbTogb3B0aW9ucy5hc3NldFBhcmFsbGVsaXNtLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc3dpdGNoIChyLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2RpZC1kZXBsb3ktc3RhY2snOlxuICAgICAgICAgICAgICBkZXBsb3lSZXN1bHQgPSByO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnZmFpbHBhdXNlZC1uZWVkLXJvbGxiYWNrLWZpcnN0Jzoge1xuICAgICAgICAgICAgICBjb25zdCBtb3RpdmF0aW9uID0gci5yZWFzb24gPT09ICdyZXBsYWNlbWVudCdcbiAgICAgICAgICAgICAgICA/IGBTdGFjayBpcyBpbiBhIHBhdXNlZCBmYWlsIHN0YXRlICgke3Iuc3RhdHVzfSkgYW5kIGNoYW5nZSBpbmNsdWRlcyBhIHJlcGxhY2VtZW50IHdoaWNoIGNhbm5vdCBiZSBkZXBsb3llZCB3aXRoIFwiLS1uby1yb2xsYmFja1wiYFxuICAgICAgICAgICAgICAgIDogYFN0YWNrIGlzIGluIGEgcGF1c2VkIGZhaWwgc3RhdGUgKCR7ci5zdGF0dXN9KSBhbmQgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBkbyBub3QgaW5jbHVkZSBcIi0tbm8tcm9sbGJhY2tcImA7XG4gICAgICAgICAgICAgIGNvbnN0IHF1ZXN0aW9uID0gYCR7bW90aXZhdGlvbn0uIFBlcmZvcm0gYSByZWd1bGFyIGRlcGxveW1lbnRgO1xuXG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkRFRkFVTFRfVE9PTEtJVF9XQVJOLm1zZyhgJHttb3RpdmF0aW9ufS4gUm9sbGluZyBiYWNrIGZpcnN0ICgtLWZvcmNlKS5gKSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uZmlybWVkID0gYXdhaXQgaW9IZWxwZXIucmVxdWVzdFJlc3BvbnNlKElPLkNES19UT09MS0lUX0k1MDUwLnJlcShxdWVzdGlvbiwge1xuICAgICAgICAgICAgICAgICAgbW90aXZhdGlvbixcbiAgICAgICAgICAgICAgICAgIGNvbmN1cnJlbmN5LFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbmZpcm1lZCkge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQWJvcnRlZCBieSB1c2VyJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gUGVyZm9ybSBhIHJvbGxiYWNrXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuX3JvbGxiYWNrKGFzc2VtYmx5LCBhY3Rpb24sIHtcbiAgICAgICAgICAgICAgICBzdGFja3M6IHsgcGF0dGVybnM6IFtzdGFjay5oaWVyYXJjaGljYWxJZF0sIHN0cmF0ZWd5OiBTdGFja1NlbGVjdGlvblN0cmF0ZWd5LlBBVFRFUk5fTVVTVF9NQVRDSF9TSU5HTEUgfSxcbiAgICAgICAgICAgICAgICBvcnBoYW5GYWlsZWRSZXNvdXJjZXM6IG9wdGlvbnMuZm9yY2UsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIC8vIEdvIGFyb3VuZCB0aHJvdWdoIHRoZSAnd2hpbGUnIGxvb3AgYWdhaW4gYnV0IHN3aXRjaCByb2xsYmFjayB0byB0cnVlLlxuICAgICAgICAgICAgICByb2xsYmFjayA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdyZXBsYWNlbWVudC1yZXF1aXJlcy1yb2xsYmFjayc6IHtcbiAgICAgICAgICAgICAgY29uc3QgbW90aXZhdGlvbiA9ICdDaGFuZ2UgaW5jbHVkZXMgYSByZXBsYWNlbWVudCB3aGljaCBjYW5ub3QgYmUgZGVwbG95ZWQgd2l0aCBcIi0tbm8tcm9sbGJhY2tcIic7XG4gICAgICAgICAgICAgIGNvbnN0IHF1ZXN0aW9uID0gYCR7bW90aXZhdGlvbn0uIFBlcmZvcm0gYSByZWd1bGFyIGRlcGxveW1lbnRgO1xuXG4gICAgICAgICAgICAgIC8vIEB0b2RvIG5vIGZvcmNlIGhlcmVcbiAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uREVGQVVMVF9UT09MS0lUX1dBUk4ubXNnKGAke21vdGl2YXRpb259LiBQcm9jZWVkaW5nIHdpdGggcmVndWxhciBkZXBsb3ltZW50ICgtLWZvcmNlKS5gKSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uZmlybWVkID0gYXdhaXQgaW9IZWxwZXIucmVxdWVzdFJlc3BvbnNlKElPLkNES19UT09MS0lUX0k1MDUwLnJlcShxdWVzdGlvbiwge1xuICAgICAgICAgICAgICAgICAgbW90aXZhdGlvbixcbiAgICAgICAgICAgICAgICAgIGNvbmN1cnJlbmN5LFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbmZpcm1lZCkge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQWJvcnRlZCBieSB1c2VyJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gR28gYXJvdW5kIHRocm91Z2ggdGhlICd3aGlsZScgbG9vcCBhZ2FpbiBidXQgc3dpdGNoIHJvbGxiYWNrIHRvIHRydWUuXG4gICAgICAgICAgICAgIHJvbGxiYWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoYFVuZXhwZWN0ZWQgcmVzdWx0IHR5cGUgZnJvbSBkZXBsb3lTdGFjazogJHtKU09OLnN0cmluZ2lmeShyKX0uIElmIHlvdSBhcmUgc2VlaW5nIHRoaXMgZXJyb3IsIHBsZWFzZSByZXBvcnQgaXQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy9uZXcvY2hvb3NlYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGRlcGxveVJlc3VsdC5ub09wXG4gICAgICAgICAgPyBgIOKchSAgJHtzdGFjay5kaXNwbGF5TmFtZX0gKG5vIGNoYW5nZXMpYFxuICAgICAgICAgIDogYCDinIUgICR7c3RhY2suZGlzcGxheU5hbWV9YDtcblxuICAgICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uQ0RLX1RPT0xLSVRfSTU5MDAubXNnKGNoYWxrLmdyZWVuKCdcXG4nICsgbWVzc2FnZSksIGRlcGxveVJlc3VsdCkpO1xuICAgICAgICBkZXBsb3lEdXJhdGlvbiA9IGF3YWl0IGRlcGxveVNwYW4udGltaW5nKElPLkNES19UT09MS0lUX0k1MDAwKTtcblxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoZGVwbG95UmVzdWx0Lm91dHB1dHMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBidWZmZXIgPSBbJ091dHB1dHM6J107XG4gICAgICAgICAgc3RhY2tPdXRwdXRzW3N0YWNrLnN0YWNrTmFtZV0gPSBkZXBsb3lSZXN1bHQub3V0cHV0cztcblxuICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhkZXBsb3lSZXN1bHQub3V0cHV0cykuc29ydCgpKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGRlcGxveVJlc3VsdC5vdXRwdXRzW25hbWVdO1xuICAgICAgICAgICAgYnVmZmVyLnB1c2goYCR7Y2hhbGsuY3lhbihzdGFjay5pZCl9LiR7Y2hhbGsuY3lhbihuYW1lKX0gPSAke2NoYWxrLnVuZGVybGluZShjaGFsay5jeWFuKHZhbHVlKSl9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JNTkwMS5tc2coYnVmZmVyLmpvaW4oJ1xcbicpKSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0k1OTAxLm1zZyhgU3RhY2sgQVJOOlxcbiR7ZGVwbG95UmVzdWx0LnN0YWNrQXJufWApKTtcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAvLyBJdCBoYXMgdG8gYmUgZXhhY3RseSB0aGlzIHN0cmluZyBiZWNhdXNlIGFuIGludGVncmF0aW9uIHRlc3QgdGVzdHMgZm9yXG4gICAgICAgIC8vIFwiYm9sZChzdGFja25hbWUpIGZhaWxlZDogUmVzb3VyY2VOb3RSZWFkeTogPGVycm9yPlwiXG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICAgW2DinYwgICR7Y2hhbGsuYm9sZChzdGFjay5zdGFja05hbWUpfSBmYWlsZWQ6YCwgLi4uKGUubmFtZSA/IFtgJHtlLm5hbWV9OmBdIDogW10pLCBlLm1lc3NhZ2VdLmpvaW4oJyAnKSxcbiAgICAgICAgKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChvcHRpb25zLnRyYWNlTG9ncykge1xuICAgICAgICAgIC8vIGRlcGxveSBjYWxscyB0aGF0IG9yaWdpbmF0ZSBmcm9tIHdhdGNoIHdpbGwgY29tZSB3aXRoIHRoZWlyIG93biBjbG91ZFdhdGNoTG9nTW9uaXRvclxuICAgICAgICAgIGNvbnN0IGNsb3VkV2F0Y2hMb2dNb25pdG9yID0gb3B0aW9ucy5jbG91ZFdhdGNoTG9nTW9uaXRvciA/PyBuZXcgQ2xvdWRXYXRjaExvZ0V2ZW50TW9uaXRvcih7IGlvSGVscGVyIH0pO1xuICAgICAgICAgIGNvbnN0IGZvdW5kTG9nR3JvdXBzUmVzdWx0ID0gYXdhaXQgZmluZENsb3VkV2F0Y2hMb2dHcm91cHMoYXdhaXQgdGhpcy5zZGtQcm92aWRlcignZGVwbG95JyksIGlvSGVscGVyLCBzdGFjayk7XG4gICAgICAgICAgY2xvdWRXYXRjaExvZ01vbml0b3IuYWRkTG9nR3JvdXBzKFxuICAgICAgICAgICAgZm91bmRMb2dHcm91cHNSZXN1bHQuZW52LFxuICAgICAgICAgICAgZm91bmRMb2dHcm91cHNSZXN1bHQuc2RrLFxuICAgICAgICAgICAgZm91bmRMb2dHcm91cHNSZXN1bHQubG9nR3JvdXBOYW1lcyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JNTAzMS5tc2coYFRoZSBmb2xsb3dpbmcgbG9nIGdyb3VwcyBhcmUgYWRkZWQ6ICR7Zm91bmRMb2dHcm91cHNSZXN1bHQubG9nR3JvdXBOYW1lc31gKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBhbiBvdXRwdXRzIGZpbGUgaGFzIGJlZW4gc3BlY2lmaWVkLCBjcmVhdGUgdGhlIGZpbGUgcGF0aCBhbmQgd3JpdGUgc3RhY2sgb3V0cHV0cyB0byBpdCBvbmNlLlxuICAgICAgICAvLyBPdXRwdXRzIGFyZSB3cml0dGVuIGFmdGVyIGFsbCBzdGFja3MgaGF2ZSBiZWVuIGRlcGxveWVkLiBJZiBhIHN0YWNrIGRlcGxveW1lbnQgZmFpbHMsXG4gICAgICAgIC8vIGFsbCBvZiB0aGUgb3V0cHV0cyBmcm9tIHN1Y2Nlc3NmdWxseSBkZXBsb3llZCBzdGFja3MgYmVmb3JlIHRoZSBmYWlsdXJlIHdpbGwgc3RpbGwgYmUgd3JpdHRlbi5cbiAgICAgICAgaWYgKG91dHB1dHNGaWxlKSB7XG4gICAgICAgICAgZnMuZW5zdXJlRmlsZVN5bmMob3V0cHV0c0ZpbGUpO1xuICAgICAgICAgIGF3YWl0IGZzLndyaXRlSnNvbihvdXRwdXRzRmlsZSwgc3RhY2tPdXRwdXRzLCB7XG4gICAgICAgICAgICBzcGFjZXM6IDIsXG4gICAgICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBkdXJhdGlvbiA9IHN5bnRoRHVyYXRpb24uYXNNcyArIChkZXBsb3lEdXJhdGlvbj8uYXNNcyA/PyAwKTtcbiAgICAgIGF3YWl0IGRlcGxveVNwYW4uZW5kKGBcXG7inKggIFRvdGFsIHRpbWU6ICR7Zm9ybWF0VGltZShkdXJhdGlvbil9c1xcbmAsIHsgZHVyYXRpb24gfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGFzc2V0QnVpbGRUaW1lID0gb3B0aW9ucy5hc3NldEJ1aWxkVGltZSA/PyBBc3NldEJ1aWxkVGltZS5BTExfQkVGT1JFX0RFUExPWTtcbiAgICBjb25zdCBwcmVidWlsZEFzc2V0cyA9IGFzc2V0QnVpbGRUaW1lID09PSBBc3NldEJ1aWxkVGltZS5BTExfQkVGT1JFX0RFUExPWTtcbiAgICBjb25zdCBjb25jdXJyZW5jeSA9IG9wdGlvbnMuY29uY3VycmVuY3kgfHwgMTtcblxuICAgIGNvbnN0IHN0YWNrc0FuZFRoZWlyQXNzZXRNYW5pZmVzdHMgPSBzdGFja3MuZmxhdE1hcCgoc3RhY2spID0+IFtcbiAgICAgIHN0YWNrLFxuICAgICAgLi4uc3RhY2suZGVwZW5kZW5jaWVzLmZpbHRlcih4ID0+IGN4YXBpLkFzc2V0TWFuaWZlc3RBcnRpZmFjdC5pc0Fzc2V0TWFuaWZlc3RBcnRpZmFjdCh4KSksXG4gICAgXSk7XG4gICAgY29uc3Qgd29ya0dyYXBoID0gbmV3IFdvcmtHcmFwaEJ1aWxkZXIoaW9IZWxwZXIsIHByZWJ1aWxkQXNzZXRzKS5idWlsZChzdGFja3NBbmRUaGVpckFzc2V0TWFuaWZlc3RzKTtcblxuICAgIC8vIFVubGVzcyB3ZSBhcmUgcnVubmluZyB3aXRoICctLWZvcmNlJywgc2tpcCBhbHJlYWR5IHB1Ymxpc2hlZCBhc3NldHNcbiAgICBpZiAoIW9wdGlvbnMuZm9yY2UpIHtcbiAgICAgIGF3YWl0IHJlbW92ZVB1Ymxpc2hlZEFzc2V0cyh3b3JrR3JhcGgsIGRlcGxveW1lbnRzLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBjb25zdCBncmFwaENvbmN1cnJlbmN5OiBDb25jdXJyZW5jeSA9IHtcbiAgICAgICdzdGFjayc6IGNvbmN1cnJlbmN5LFxuICAgICAgJ2Fzc2V0LWJ1aWxkJzogMSwgLy8gVGhpcyB3aWxsIGJlIENQVS1ib3VuZC9tZW1vcnkgYm91bmQsIG1vc3RseSBtYXR0ZXJzIGZvciBEb2NrZXIgYnVpbGRzXG4gICAgICAnYXNzZXQtcHVibGlzaCc6IChvcHRpb25zLmFzc2V0UGFyYWxsZWxpc20gPz8gdHJ1ZSkgPyA4IDogMSwgLy8gVGhpcyB3aWxsIGJlIEkvTy1ib3VuZCwgOCBpbiBwYXJhbGxlbCBzZWVtcyByZWFzb25hYmxlXG4gICAgfTtcblxuICAgIGF3YWl0IHdvcmtHcmFwaC5kb1BhcmFsbGVsKGdyYXBoQ29uY3VycmVuY3ksIHtcbiAgICAgIGRlcGxveVN0YWNrLFxuICAgICAgYnVpbGRBc3NldCxcbiAgICAgIHB1Ymxpc2hBc3NldCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYXRjaCBBY3Rpb25cbiAgICpcbiAgICogQ29udGludW91c2x5IG9ic2VydmUgcHJvamVjdCBmaWxlcyBhbmQgZGVwbG95IHRoZSBzZWxlY3RlZCBzdGFja3MgYXV0b21hdGljYWxseSB3aGVuIGNoYW5nZXMgYXJlIGRldGVjdGVkLlxuICAgKiBJbXBsaWVzIGhvdHN3YXAgZGVwbG95bWVudHMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgd2F0Y2goY3g6IElDbG91ZEFzc2VtYmx5U291cmNlLCBvcHRpb25zOiBXYXRjaE9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBhc3NlbWJseSA9IGF3YWl0IGFzc2VtYmx5RnJvbVNvdXJjZShjeCwgZmFsc2UpO1xuICAgIGNvbnN0IGlvSGVscGVyID0gYXNJb0hlbHBlcih0aGlzLmlvSG9zdCwgJ3dhdGNoJyk7XG4gICAgY29uc3Qgcm9vdERpciA9IG9wdGlvbnMud2F0Y2hEaXIgPz8gcHJvY2Vzcy5jd2QoKTtcblxuICAgIGlmIChvcHRpb25zLmluY2x1ZGUgPT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLmV4Y2x1ZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgXCJDYW5ub3QgdXNlIHRoZSAnd2F0Y2gnIGNvbW1hbmQgd2l0aG91dCBzcGVjaWZ5aW5nIGF0IGxlYXN0IG9uZSBkaXJlY3RvcnkgdG8gbW9uaXRvci4gXCIgK1xuICAgICAgICAgICdNYWtlIHN1cmUgdG8gYWRkIGEgXCJ3YXRjaFwiIGtleSB0byB5b3VyIGNkay5qc29uJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gRm9yIHRoZSBcImluY2x1ZGVcIiBzdWJrZXkgdW5kZXIgdGhlIFwid2F0Y2hcIiBrZXksIHRoZSBiZWhhdmlvciBpczpcbiAgICAvLyAxLiBObyBcIndhdGNoXCIgc2V0dGluZz8gV2UgZXJyb3Igb3V0LlxuICAgIC8vIDIuIFwid2F0Y2hcIiBzZXR0aW5nIHdpdGhvdXQgYW4gXCJpbmNsdWRlXCIga2V5PyBXZSBkZWZhdWx0IHRvIG9ic2VydmluZyBcIi4vKipcIi5cbiAgICAvLyAzLiBcIndhdGNoXCIgc2V0dGluZyB3aXRoIGFuIGVtcHR5IFwiaW5jbHVkZVwiIGtleT8gV2UgZGVmYXVsdCB0byBvYnNlcnZpbmcgXCIuLyoqXCIuXG4gICAgLy8gNC4gTm9uLWVtcHR5IFwiaW5jbHVkZVwiIGtleT8gSnVzdCB1c2UgdGhlIFwiaW5jbHVkZVwiIGtleS5cbiAgICBjb25zdCB3YXRjaEluY2x1ZGVzID0gcGF0dGVybnNBcnJheUZvcldhdGNoKG9wdGlvbnMuaW5jbHVkZSwge1xuICAgICAgcm9vdERpcixcbiAgICAgIHJldHVyblJvb3REaXJJZkVtcHR5OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgLy8gRm9yIHRoZSBcImV4Y2x1ZGVcIiBzdWJrZXkgdW5kZXIgdGhlIFwid2F0Y2hcIiBrZXksXG4gICAgLy8gdGhlIGJlaGF2aW9yIGlzIHRvIGFkZCBzb21lIGRlZmF1bHQgZXhjbHVkZXMgaW4gYWRkaXRpb24gdG8gdGhlIG9uZXMgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyOlxuICAgIC8vIDEuIFRoZSBDREsgb3V0cHV0IGRpcmVjdG9yeS5cbiAgICAvLyAyLiBBbnkgZmlsZSB3aG9zZSBuYW1lIHN0YXJ0cyB3aXRoIGEgZG90LlxuICAgIC8vIDMuIEFueSBkaXJlY3RvcnkncyBjb250ZW50IHdob3NlIG5hbWUgc3RhcnRzIHdpdGggYSBkb3QuXG4gICAgLy8gNC4gQW55IG5vZGVfbW9kdWxlcyBhbmQgaXRzIGNvbnRlbnQgKGV2ZW4gaWYgaXQncyBub3QgYSBKUy9UUyBwcm9qZWN0LCB5b3UgbWlnaHQgYmUgdXNpbmcgYSBsb2NhbCBhd3MtY2xpIHBhY2thZ2UpXG4gICAgY29uc3Qgb3V0ZGlyID0gb3B0aW9ucy5vdXRkaXIgPz8gJ2Nkay5vdXQnO1xuICAgIGNvbnN0IHdhdGNoRXhjbHVkZXMgPSBwYXR0ZXJuc0FycmF5Rm9yV2F0Y2gob3B0aW9ucy5leGNsdWRlLCB7XG4gICAgICByb290RGlyLFxuICAgICAgcmV0dXJuUm9vdERpcklmRW1wdHk6IGZhbHNlLFxuICAgIH0pLmNvbmNhdChgJHtvdXRkaXJ9LyoqYCwgJyoqLy4qJywgJyoqLy4qLyoqJywgJyoqL25vZGVfbW9kdWxlcy8qKicpO1xuXG4gICAgLy8gUHJpbnQgc29tZSBkZWJ1ZyBpbmZvcm1hdGlvbiBvbiBjb21wdXRlZCBzZXR0aW5nc1xuICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JNTMxMC5tc2coW1xuICAgICAgYHJvb3QgZGlyZWN0b3J5IHVzZWQgZm9yICd3YXRjaCcgaXM6ICR7cm9vdERpcn1gLFxuICAgICAgYCdpbmNsdWRlJyBwYXR0ZXJucyBmb3IgJ3dhdGNoJzogJHtKU09OLnN0cmluZ2lmeSh3YXRjaEluY2x1ZGVzKX1gLFxuICAgICAgYCdleGNsdWRlJyBwYXR0ZXJucyBmb3IgJ3dhdGNoJzogJHtKU09OLnN0cmluZ2lmeSh3YXRjaEV4Y2x1ZGVzKX1gLFxuICAgIF0uam9pbignXFxuJyksIHtcbiAgICAgIHdhdGNoRGlyOiByb290RGlyLFxuICAgICAgaW5jbHVkZXM6IHdhdGNoSW5jbHVkZXMsXG4gICAgICBleGNsdWRlczogd2F0Y2hFeGNsdWRlcyxcbiAgICB9KSk7XG5cbiAgICAvLyBTaW5jZSAnY2RrIGRlcGxveScgaXMgYSByZWxhdGl2ZWx5IHNsb3cgb3BlcmF0aW9uIGZvciBhICd3YXRjaCcgcHJvY2VzcyxcbiAgICAvLyBpbnRyb2R1Y2UgYSBjb25jdXJyZW5jeSBsYXRjaCB0aGF0IHRyYWNrcyB0aGUgc3RhdGUuXG4gICAgLy8gVGhpcyB3YXksIGlmIGZpbGUgY2hhbmdlIGV2ZW50cyBhcnJpdmUgd2hlbiBhICdjZGsgZGVwbG95JyBpcyBzdGlsbCBleGVjdXRpbmcsXG4gICAgLy8gd2Ugd2lsbCBiYXRjaCB0aGVtLCBhbmQgdHJpZ2dlciBhbm90aGVyICdjZGsgZGVwbG95JyBhZnRlciB0aGUgY3VycmVudCBvbmUgZmluaXNoZXMsXG4gICAgLy8gbWFraW5nIHN1cmUgJ2NkayBkZXBsb3kncyAgYWx3YXlzIGV4ZWN1dGUgb25lIGF0IGEgdGltZS5cbiAgICAvLyBIZXJlJ3MgYSBkaWFncmFtIHNob3dpbmcgdGhlIHN0YXRlIHRyYW5zaXRpb25zOlxuICAgIC8vIC0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tICAgIGZpbGUgY2hhbmdlZCAgICAgLS0tLS0tLS0tLS0tLS0gICAgZmlsZSBjaGFuZ2VkICAgICAtLS0tLS0tLS0tLS0tLSAgZmlsZSBjaGFuZ2VkXG4gICAgLy8gfCAgICAgICAgICAgIHwgIHJlYWR5IGV2ZW50ICAgfCAgICAgIHwgLS0tLS0tLS0tLS0tLS0tLS0tPiB8ICAgICAgICAgICAgfCAtLS0tLS0tLS0tLS0tLS0tLS0+IHwgICAgICAgICAgICB8IC0tLS0tLS0tLS0tLS0tfFxuICAgIC8vIHwgcHJlLXJlYWR5ICB8IC0tLS0tLS0tLS0tLS0+IHwgb3BlbiB8ICAgICAgICAgICAgICAgICAgICAgfCBkZXBsb3lpbmcgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgcXVldWVkICAgfCAgICAgICAgICAgICAgIHxcbiAgICAvLyB8ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8ICAgICAgfCA8LS0tLS0tLS0tLS0tLS0tLS0tIHwgICAgICAgICAgICB8IDwtLS0tLS0tLS0tLS0tLS0tLS0gfCAgICAgICAgICAgIHwgPC0tLS0tLS0tLS0tLS18XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgLS0tLS0tLS0gICdjZGsgZGVwbG95JyBkb25lICAtLS0tLS0tLS0tLS0tLSAgJ2NkayBkZXBsb3knIGRvbmUgIC0tLS0tLS0tLS0tLS0tXG4gICAgdHlwZSBMYXRjaFN0YXRlID0gJ3ByZS1yZWFkeScgfCAnb3BlbicgfCAnZGVwbG95aW5nJyB8ICdxdWV1ZWQnO1xuICAgIGxldCBsYXRjaDogTGF0Y2hTdGF0ZSA9ICdwcmUtcmVhZHknO1xuXG4gICAgY29uc3QgY2xvdWRXYXRjaExvZ01vbml0b3IgPSBvcHRpb25zLnRyYWNlTG9ncyA/IG5ldyBDbG91ZFdhdGNoTG9nRXZlbnRNb25pdG9yKHsgaW9IZWxwZXIgfSkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgZGVwbG95QW5kV2F0Y2ggPSBhc3luYyAoKSA9PiB7XG4gICAgICBsYXRjaCA9ICdkZXBsb3lpbmcnIGFzIExhdGNoU3RhdGU7XG4gICAgICBhd2FpdCBjbG91ZFdhdGNoTG9nTW9uaXRvcj8uZGVhY3RpdmF0ZSgpO1xuXG4gICAgICBhd2FpdCB0aGlzLmludm9rZURlcGxveUZyb21XYXRjaChhc3NlbWJseSwgb3B0aW9ucywgY2xvdWRXYXRjaExvZ01vbml0b3IpO1xuXG4gICAgICAvLyBJZiBsYXRjaCBpcyBzdGlsbCAnZGVwbG95aW5nJyBhZnRlciB0aGUgJ2F3YWl0JywgdGhhdCdzIGZpbmUsXG4gICAgICAvLyBidXQgaWYgaXQncyAncXVldWVkJywgdGhhdCBtZWFucyB3ZSBuZWVkIHRvIGRlcGxveSBhZ2FpblxuICAgICAgd2hpbGUgKGxhdGNoID09PSAncXVldWVkJykge1xuICAgICAgICAvLyBUeXBlU2NyaXB0IGRvZXNuJ3QgcmVhbGl6ZSBsYXRjaCBjYW4gY2hhbmdlIGJldHdlZW4gJ2F3YWl0cycsXG4gICAgICAgIC8vIGFuZCB0aGlua3MgdGhlIGFib3ZlICd3aGlsZScgY29uZGl0aW9uIGlzIGFsd2F5cyAnZmFsc2UnIHdpdGhvdXQgdGhlIGNhc3RcbiAgICAgICAgbGF0Y2ggPSAnZGVwbG95aW5nJztcbiAgICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0k1MzE1Lm1zZyhcIkRldGVjdGVkIGZpbGUgY2hhbmdlcyBkdXJpbmcgZGVwbG95bWVudC4gSW52b2tpbmcgJ2NkayBkZXBsb3knIGFnYWluXCIpKTtcbiAgICAgICAgYXdhaXQgdGhpcy5pbnZva2VEZXBsb3lGcm9tV2F0Y2goYXNzZW1ibHksIG9wdGlvbnMsIGNsb3VkV2F0Y2hMb2dNb25pdG9yKTtcbiAgICAgIH1cbiAgICAgIGxhdGNoID0gJ29wZW4nO1xuICAgICAgYXdhaXQgY2xvdWRXYXRjaExvZ01vbml0b3I/LmFjdGl2YXRlKCk7XG4gICAgfTtcblxuICAgIGNob2tpZGFyXG4gICAgICAud2F0Y2god2F0Y2hJbmNsdWRlcywge1xuICAgICAgICBpZ25vcmVkOiB3YXRjaEV4Y2x1ZGVzLFxuICAgICAgICBjd2Q6IHJvb3REaXIsXG4gICAgICB9KVxuICAgICAgLm9uKCdyZWFkeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbGF0Y2ggPSAnb3Blbic7XG4gICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5ERUZBVUxUX1RPT0xLSVRfREVCVUcubXNnKFwiJ3dhdGNoJyByZWNlaXZlZCB0aGUgJ3JlYWR5JyBldmVudC4gRnJvbSBub3cgb24sIGFsbCBmaWxlIGNoYW5nZXMgd2lsbCB0cmlnZ2VyIGEgZGVwbG95bWVudFwiKSk7XG4gICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JNTMxNC5tc2coXCJUcmlnZ2VyaW5nIGluaXRpYWwgJ2NkayBkZXBsb3knXCIpKTtcbiAgICAgICAgYXdhaXQgZGVwbG95QW5kV2F0Y2goKTtcbiAgICAgIH0pXG4gICAgICAub24oJ2FsbCcsIGFzeW5jIChldmVudDogJ2FkZCcgfCAnYWRkRGlyJyB8ICdjaGFuZ2UnIHwgJ3VubGluaycgfCAndW5saW5rRGlyJywgZmlsZVBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCB3YXRjaEV2ZW50ID0ge1xuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHBhdGg6IGZpbGVQYXRoLFxuICAgICAgICB9O1xuICAgICAgICBpZiAobGF0Y2ggPT09ICdwcmUtcmVhZHknKSB7XG4gICAgICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0k1MzExLm1zZyhgJ3dhdGNoJyBpcyBvYnNlcnZpbmcgJHtldmVudCA9PT0gJ2FkZERpcicgPyAnZGlyZWN0b3J5JyA6ICd0aGUgZmlsZSd9ICcke2ZpbGVQYXRofScgZm9yIGNoYW5nZXNgLCB3YXRjaEV2ZW50KSk7XG4gICAgICAgIH0gZWxzZSBpZiAobGF0Y2ggPT09ICdvcGVuJykge1xuICAgICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JNTMxMi5tc2coYERldGVjdGVkIGNoYW5nZSB0byAnJHtmaWxlUGF0aH0nICh0eXBlOiAke2V2ZW50fSkuIFRyaWdnZXJpbmcgJ2NkayBkZXBsb3knYCwgd2F0Y2hFdmVudCkpO1xuICAgICAgICAgIGF3YWl0IGRlcGxveUFuZFdhdGNoKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdGhpcyBtZWFucyBsYXRjaCBpcyBlaXRoZXIgJ2RlcGxveWluZycgb3IgJ3F1ZXVlZCdcbiAgICAgICAgICBsYXRjaCA9ICdxdWV1ZWQnO1xuICAgICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9JNTMxMy5tc2coXG4gICAgICAgICAgICBgRGV0ZWN0ZWQgY2hhbmdlIHRvICcke2ZpbGVQYXRofScgKHR5cGU6ICR7ZXZlbnR9KSB3aGlsZSAnY2RrIGRlcGxveScgaXMgc3RpbGwgcnVubmluZy4gV2lsbCBxdWV1ZSBmb3IgYW5vdGhlciBkZXBsb3ltZW50IGFmdGVyIHRoaXMgb25lIGZpbmlzaGVzJ2AsXG4gICAgICAgICAgICB3YXRjaEV2ZW50LFxuICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xsYmFjayBBY3Rpb25cbiAgICpcbiAgICogUm9sbHMgYmFjayB0aGUgc2VsZWN0ZWQgc3RhY2tzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJvbGxiYWNrKGN4OiBJQ2xvdWRBc3NlbWJseVNvdXJjZSwgb3B0aW9uczogUm9sbGJhY2tPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYXNzZW1ibHkgPSBhd2FpdCBhc3NlbWJseUZyb21Tb3VyY2UoY3gpO1xuICAgIHJldHVybiB0aGlzLl9yb2xsYmFjayhhc3NlbWJseSwgJ3JvbGxiYWNrJywgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIGFsbG93IHJvbGxiYWNrIGJlaW5nIGNhbGxlZCBhcyBwYXJ0IG9mIHRoZSBkZXBsb3kgb3Igd2F0Y2ggYWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfcm9sbGJhY2soYXNzZW1ibHk6IFN0YWNrQXNzZW1ibHksIGFjdGlvbjogJ3JvbGxiYWNrJyB8ICdkZXBsb3knIHwgJ3dhdGNoJywgb3B0aW9uczogUm9sbGJhY2tPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW9IZWxwZXIgPSBhc0lvSGVscGVyKHRoaXMuaW9Ib3N0LCBhY3Rpb24pO1xuICAgIGNvbnN0IHN5bnRoU3BhbiA9IGF3YWl0IGlvSGVscGVyLnNwYW4oU1BBTi5TWU5USF9BU1NFTUJMWSkuYmVnaW4oeyBzdGFja3M6IG9wdGlvbnMuc3RhY2tzIH0pO1xuICAgIGNvbnN0IHN0YWNrcyA9IGFzc2VtYmx5LnNlbGVjdFN0YWNrc1YyKG9wdGlvbnMuc3RhY2tzKTtcbiAgICBhd2FpdCB0aGlzLnZhbGlkYXRlU3RhY2tzTWV0YWRhdGEoc3RhY2tzLCBpb0hlbHBlcik7XG4gICAgYXdhaXQgc3ludGhTcGFuLmVuZCgpO1xuXG4gICAgaWYgKHN0YWNrcy5zdGFja0NvdW50ID09PSAwKSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uQ0RLX1RPT0xLSVRfRTYwMDEubXNnKCdObyBzdGFja3Mgc2VsZWN0ZWQnKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGFueVJvbGxiYWNrYWJsZSA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBbaW5kZXgsIHN0YWNrXSBvZiBzdGFja3Muc3RhY2tBcnRpZmFjdHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCByb2xsYmFja1NwYW4gPSBhd2FpdCBpb0hlbHBlci5zcGFuKFNQQU4uUk9MTEJBQ0tfU1RBQ0spLmJlZ2luKGBSb2xsaW5nIGJhY2sgJHtjaGFsay5ib2xkKHN0YWNrLmRpc3BsYXlOYW1lKX1gLCB7XG4gICAgICAgIHRvdGFsOiBzdGFja3Muc3RhY2tDb3VudCxcbiAgICAgICAgY3VycmVudDogaW5kZXggKyAxLFxuICAgICAgICBzdGFjayxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGVwbG95bWVudHMgPSBhd2FpdCB0aGlzLmRlcGxveW1lbnRzRm9yQWN0aW9uKCdyb2xsYmFjaycpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc3RhY2tSZXN1bHQgPSBhd2FpdCBkZXBsb3ltZW50cy5yb2xsYmFja1N0YWNrKHtcbiAgICAgICAgICBzdGFjayxcbiAgICAgICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4sXG4gICAgICAgICAgdG9vbGtpdFN0YWNrTmFtZTogdGhpcy50b29sa2l0U3RhY2tOYW1lLFxuICAgICAgICAgIGZvcmNlOiBvcHRpb25zLm9ycGhhbkZhaWxlZFJlc291cmNlcyxcbiAgICAgICAgICB2YWxpZGF0ZUJvb3RzdHJhcFN0YWNrVmVyc2lvbjogb3B0aW9ucy52YWxpZGF0ZUJvb3RzdHJhcFN0YWNrVmVyc2lvbixcbiAgICAgICAgICBvcnBoYW5Mb2dpY2FsSWRzOiBvcHRpb25zLm9ycGhhbkxvZ2ljYWxJZHMsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXN0YWNrUmVzdWx0Lm5vdEluUm9sbGJhY2thYmxlU3RhdGUpIHtcbiAgICAgICAgICBhbnlSb2xsYmFja2FibGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHJvbGxiYWNrU3Bhbi5lbmQoKTtcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uQ0RLX1RPT0xLSVRfRTY5MDAubXNnKGBcXG4g4p2MICAke2NoYWxrLmJvbGQoc3RhY2suZGlzcGxheU5hbWUpfSBmYWlsZWQ6ICR7Zm9ybWF0RXJyb3JNZXNzYWdlKGUpfWAsIHsgZXJyb3I6IGUgfSkpO1xuICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdSb2xsYmFjayBmYWlsZWQgKHVzZSAtLWZvcmNlIHRvIG9ycGhhbiBmYWlsaW5nIHJlc291cmNlcyknKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFhbnlSb2xsYmFja2FibGUpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ05vIHN0YWNrcyB3ZXJlIGluIGEgc3RhdGUgdGhhdCBjb3VsZCBiZSByb2xsZWQgYmFjaycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95IEFjdGlvblxuICAgKlxuICAgKiBEZXN0cm95cyB0aGUgc2VsZWN0ZWQgU3RhY2tzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRlc3Ryb3koY3g6IElDbG91ZEFzc2VtYmx5U291cmNlLCBvcHRpb25zOiBEZXN0cm95T3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFzc2VtYmx5ID0gYXdhaXQgYXNzZW1ibHlGcm9tU291cmNlKGN4KTtcbiAgICByZXR1cm4gdGhpcy5fZGVzdHJveShhc3NlbWJseSwgJ2Rlc3Ryb3knLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gYWxsb3cgZGVzdHJveSBiZWluZyBjYWxsZWQgYXMgcGFydCBvZiB0aGUgZGVwbG95IGFjdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2Rlc3Ryb3koYXNzZW1ibHk6IFN0YWNrQXNzZW1ibHksIGFjdGlvbjogJ2RlcGxveScgfCAnZGVzdHJveScsIG9wdGlvbnM6IERlc3Ryb3lPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW9IZWxwZXIgPSBhc0lvSGVscGVyKHRoaXMuaW9Ib3N0LCBhY3Rpb24pO1xuICAgIGNvbnN0IHN5bnRoU3BhbiA9IGF3YWl0IGlvSGVscGVyLnNwYW4oU1BBTi5TWU5USF9BU1NFTUJMWSkuYmVnaW4oeyBzdGFja3M6IG9wdGlvbnMuc3RhY2tzIH0pO1xuICAgIC8vIFRoZSBzdGFja3Mgd2lsbCBoYXZlIGJlZW4gb3JkZXJlZCBmb3IgZGVwbG95bWVudCwgc28gcmV2ZXJzZSB0aGVtIGZvciBkZWxldGlvbi5cbiAgICBjb25zdCBzdGFja3MgPSBhd2FpdCBhc3NlbWJseS5zZWxlY3RTdGFja3NWMihvcHRpb25zLnN0YWNrcykucmV2ZXJzZWQoKTtcbiAgICBhd2FpdCBzeW50aFNwYW4uZW5kKCk7XG5cbiAgICBjb25zdCBtb3RpdmF0aW9uID0gJ0Rlc3Ryb3lpbmcgc3RhY2tzIGlzIGFuIGlycmV2ZXJzaWJsZSBhY3Rpb24nO1xuICAgIGNvbnN0IHF1ZXN0aW9uID0gYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGU6ICR7Y2hhbGsucmVkKHN0YWNrcy5oaWVyYXJjaGljYWxJZHMuam9pbignLCAnKSl9YDtcbiAgICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBpb0hlbHBlci5yZXF1ZXN0UmVzcG9uc2UoSU8uQ0RLX1RPT0xLSVRfSTcwMTAucmVxKHF1ZXN0aW9uLCB7IG1vdGl2YXRpb24gfSkpO1xuICAgIGlmICghY29uZmlybWVkKSB7XG4gICAgICByZXR1cm4gaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0U3MDEwLm1zZygnQWJvcnRlZCBieSB1c2VyJykpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlc3Ryb3lTcGFuID0gYXdhaXQgaW9IZWxwZXIuc3BhbihTUEFOLkRFU1RST1lfQUNUSU9OKS5iZWdpbih7XG4gICAgICBzdGFja3M6IHN0YWNrcy5zdGFja0FydGlmYWN0cyxcbiAgICB9KTtcbiAgICB0cnkge1xuICAgICAgZm9yIChjb25zdCBbaW5kZXgsIHN0YWNrXSBvZiBzdGFja3Muc3RhY2tBcnRpZmFjdHMuZW50cmllcygpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc2luZ2xlRGVzdHJveVNwYW4gPSBhd2FpdCBpb0hlbHBlci5zcGFuKFNQQU4uREVTVFJPWV9TVEFDSylcbiAgICAgICAgICAgIC5iZWdpbihjaGFsay5ncmVlbihgJHtjaGFsay5ibHVlKHN0YWNrLmRpc3BsYXlOYW1lKX06IGRlc3Ryb3lpbmcuLi4gWyR7aW5kZXggKyAxfS8ke3N0YWNrcy5zdGFja0NvdW50fV1gKSwge1xuICAgICAgICAgICAgICB0b3RhbDogc3RhY2tzLnN0YWNrQ291bnQsXG4gICAgICAgICAgICAgIGN1cnJlbnQ6IGluZGV4ICsgMSxcbiAgICAgICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICBjb25zdCBkZXBsb3ltZW50cyA9IGF3YWl0IHRoaXMuZGVwbG95bWVudHNGb3JBY3Rpb24oYWN0aW9uKTtcbiAgICAgICAgICBhd2FpdCBkZXBsb3ltZW50cy5kZXN0cm95U3RhY2soe1xuICAgICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgICBkZXBsb3lOYW1lOiBzdGFjay5zdGFja05hbWUsXG4gICAgICAgICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkNES19UT09MS0lUX0k3OTAwLm1zZyhjaGFsay5ncmVlbihgXFxuIOKchSAgJHtjaGFsay5ibHVlKHN0YWNrLmRpc3BsYXlOYW1lKX06ICR7YWN0aW9ufWVkYCksIHN0YWNrKSk7XG4gICAgICAgICAgYXdhaXQgc2luZ2xlRGVzdHJveVNwYW4uZW5kKCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5DREtfVE9PTEtJVF9FNzkwMC5tc2coYFxcbiDinYwgICR7Y2hhbGsuYmx1ZShzdGFjay5kaXNwbGF5TmFtZSl9OiAke2FjdGlvbn0gZmFpbGVkICR7ZX1gLCB7IGVycm9yOiBlIH0pKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGRlc3Ryb3lTcGFuLmVuZCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgc3RhY2tzIGZvciBlcnJvcnMgYW5kIHdhcm5pbmdzIGFjY29yZGluZyB0byB0aGUgQ0xJJ3MgY3VycmVudCBzZXR0aW5nc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2YWxpZGF0ZVN0YWNrc01ldGFkYXRhKHN0YWNrczogU3RhY2tDb2xsZWN0aW9uLCBpb0hvc3Q6IElvSGVscGVyKSB7XG4gICAgY29uc3QgYnVpbGRlciA9IChsZXZlbDogSW9NZXNzYWdlTGV2ZWwpID0+IHtcbiAgICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgICAgY2FzZSAnZXJyb3InOiByZXR1cm4gSU8uQ0RLX0FTU0VNQkxZX0U5OTk5O1xuICAgICAgICBjYXNlICd3YXJuJzogcmV0dXJuIElPLkNES19BU1NFTUJMWV9XOTk5OTtcbiAgICAgICAgZGVmYXVsdDogcmV0dXJuIElPLkNES19BU1NFTUJMWV9JOTk5OTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGF3YWl0IHN0YWNrcy52YWxpZGF0ZU1ldGFkYXRhKFxuICAgICAgdGhpcy5wcm9wcy5hc3NlbWJseUZhaWx1cmVBdCxcbiAgICAgIGFzeW5jIChsZXZlbCwgbXNnKSA9PiBpb0hvc3Qubm90aWZ5KGJ1aWxkZXIobGV2ZWwpLm1zZyhgWyR7bGV2ZWx9IGF0ICR7bXNnLmlkfV0gJHttc2cuZW50cnkuZGF0YX1gLCBtc2cpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGRlcGxveW1lbnRzIGNsYXNzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlcGxveW1lbnRzRm9yQWN0aW9uKGFjdGlvbjogVG9vbGtpdEFjdGlvbik6IFByb21pc2U8RGVwbG95bWVudHM+IHtcbiAgICByZXR1cm4gbmV3IERlcGxveW1lbnRzKHtcbiAgICAgIHNka1Byb3ZpZGVyOiBhd2FpdCB0aGlzLnNka1Byb3ZpZGVyKGFjdGlvbiksXG4gICAgICB0b29sa2l0U3RhY2tOYW1lOiB0aGlzLnRvb2xraXRTdGFja05hbWUsXG4gICAgICBpb0hlbHBlcjogYXNJb0hlbHBlcih0aGlzLmlvSG9zdCwgYWN0aW9uKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW52b2tlRGVwbG95RnJvbVdhdGNoKFxuICAgIGFzc2VtYmx5OiBTdGFja0Fzc2VtYmx5LFxuICAgIG9wdGlvbnM6IFdhdGNoT3B0aW9ucyxcbiAgICBjbG91ZFdhdGNoTG9nTW9uaXRvcj86IENsb3VkV2F0Y2hMb2dFdmVudE1vbml0b3IsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHdhdGNoIGRlZmF1bHRzIGhvdHN3YXAgdG8gZW5hYmxlZFxuICAgIGNvbnN0IGhvdHN3YXAgPSBvcHRpb25zLmhvdHN3YXAgPz8gSG90c3dhcE1vZGUuSE9UU1dBUF9PTkxZO1xuICAgIGNvbnN0IGRlcGxveU9wdGlvbnM6IEV4dGVuZGVkRGVwbG95T3B0aW9ucyA9IHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbC5ORVZFUixcbiAgICAgIGNsb3VkV2F0Y2hMb2dNb25pdG9yLFxuICAgICAgaG90c3dhcCxcbiAgICAgIGV4dHJhVXNlckFnZW50OiBgY2RrLXdhdGNoL2hvdHN3YXAtJHtob3Rzd2FwID09PSBIb3Rzd2FwTW9kZS5GVUxMX0RFUExPWU1FTlQgPyAnb2ZmJyA6ICdvbid9YCxcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2RlcGxveShhc3NlbWJseSwgJ3dhdGNoJywgZGVwbG95T3B0aW9ucyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBqdXN0IGNvbnRpbnVlIC0gZGVwbG95IHdpbGwgc2hvdyB0aGUgZXJyb3JcbiAgICB9XG4gIH1cbn1cbiJdfQ==