@cdktn/commons 0.25.0-pre.52 → 0.25.0-pre.54

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 (47) hide show
  1. package/build/config.d.ts +5 -0
  2. package/build/config.d.ts.map +1 -1
  3. package/build/config.js +26 -1
  4. package/build/config.test.js +23 -1
  5. package/build/construct-maker-target.d.ts +2 -0
  6. package/build/construct-maker-target.d.ts.map +1 -1
  7. package/build/construct-maker-target.js +3 -1
  8. package/build/debug.d.ts.map +1 -1
  9. package/build/debug.js +13 -15
  10. package/build/debug.test.js +9 -2
  11. package/build/errors.d.ts +3 -0
  12. package/build/errors.d.ts.map +1 -1
  13. package/build/errors.js +31 -23
  14. package/build/errors.test.d.ts +2 -0
  15. package/build/errors.test.d.ts.map +1 -0
  16. package/build/errors.test.js +24 -0
  17. package/build/identity.d.ts +3 -0
  18. package/build/identity.d.ts.map +1 -0
  19. package/build/identity.js +88 -0
  20. package/build/index.d.ts +3 -1
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +4 -2
  23. package/build/node-package-manager.d.ts +15 -0
  24. package/build/node-package-manager.d.ts.map +1 -0
  25. package/build/node-package-manager.js +88 -0
  26. package/build/node-package-manager.test.d.ts +2 -0
  27. package/build/node-package-manager.test.d.ts.map +1 -0
  28. package/build/node-package-manager.test.js +52 -0
  29. package/build/process-state.d.ts +2 -0
  30. package/build/process-state.d.ts.map +1 -0
  31. package/build/process-state.js +15 -0
  32. package/build/telemetry.d.ts +24 -0
  33. package/build/telemetry.d.ts.map +1 -0
  34. package/build/telemetry.js +721 -0
  35. package/build/telemetry.test.d.ts +2 -0
  36. package/build/telemetry.test.d.ts.map +1 -0
  37. package/build/telemetry.test.js +1501 -0
  38. package/build/terraform.d.ts +10 -1
  39. package/build/terraform.d.ts.map +1 -1
  40. package/build/terraform.js +43 -8
  41. package/build/terraform.test.d.ts +2 -0
  42. package/build/terraform.test.d.ts.map +1 -0
  43. package/build/terraform.test.js +136 -0
  44. package/package.json +3 -3
  45. package/build/checkpoint.d.ts +0 -19
  46. package/build/checkpoint.d.ts.map +0 -1
  47. package/build/checkpoint.js +0 -185
@@ -0,0 +1,1501 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ // Copyright (c) HashiCorp, Inc
37
+ // SPDX-License-Identifier: MPL-2.0
38
+ const Sentry = __importStar(require("@sentry/node"));
39
+ const fs = __importStar(require("fs-extra"));
40
+ const os = __importStar(require("os"));
41
+ const path = __importStar(require("path"));
42
+ const telemetry_1 = require("./telemetry");
43
+ const terraform_1 = require("./terraform");
44
+ const config_1 = require("./config");
45
+ const construct_maker_target_1 = require("./construct-maker-target");
46
+ const errors_1 = require("./errors");
47
+ const DEFAULT_TARGET_VERSIONS_AS_ATTRIBUTES = {
48
+ target_terraform: config_1.DEFAULT_TARGET_VERSIONS.terraform,
49
+ target_opentofu: config_1.DEFAULT_TARGET_VERSIONS.opentofu,
50
+ };
51
+ // Mirrors recordEnvelope in tools/sentry-sink.mjs: an envelope-format change
52
+ // is fixed in both.
53
+ function parseMetricItems(envelopeBodies) {
54
+ const items = [];
55
+ for (const body of envelopeBodies) {
56
+ const lines = body.split("\n").filter(Boolean);
57
+ for (let i = 0; i < lines.length - 1; i++) {
58
+ let header;
59
+ try {
60
+ header = JSON.parse(lines[i]);
61
+ }
62
+ catch (_a) {
63
+ continue;
64
+ }
65
+ if (header.type === "trace_metric") {
66
+ const payload = JSON.parse(lines[i + 1]);
67
+ items.push(...payload.items);
68
+ }
69
+ }
70
+ }
71
+ return items;
72
+ }
73
+ function attributeValues(item) {
74
+ return Object.fromEntries(Object.entries(item.attributes).map(([k, v]) => [k, v.value]));
75
+ }
76
+ // On every metric of a command; the exact set is pinned once, on
77
+ // cli.command.completed.
78
+ const COMMAND_ATTRIBUTES = [
79
+ "arch",
80
+ "binary",
81
+ "binary_version",
82
+ "ci",
83
+ "command",
84
+ "language",
85
+ "os",
86
+ "package_manager",
87
+ "server.address",
88
+ "target_opentofu",
89
+ "target_terraform",
90
+ "targets_declared",
91
+ "validate_installed_binary",
92
+ ];
93
+ // Each metric of that name as its value plus exactly the attributes it adds
94
+ // to the command's, so `toEqual` fails on any attribute that is not listed.
95
+ function metrics(items, name) {
96
+ return items
97
+ .filter((item) => item.name === name)
98
+ .map((item) => ({
99
+ value: item.value,
100
+ ...Object.fromEntries(Object.entries(attributeValues(item)).filter(([key]) => !key.startsWith("sentry.") && !COMMAND_ATTRIBUTES.includes(key))),
101
+ }));
102
+ }
103
+ describe("telemetry", () => {
104
+ let workdir;
105
+ let envelopeBodies;
106
+ const originalCwd = process.cwd();
107
+ const originalCheckpointDisable = process.env.CHECKPOINT_DISABLE;
108
+ const originalSentryEnvironment = process.env.SENTRY_ENVIRONMENT;
109
+ function initSentryWithCapturingTransport() {
110
+ Sentry.init({
111
+ dsn: "https://public@example.invalid/1",
112
+ release: "cdktn-cli-test",
113
+ environment: "production",
114
+ tracesSampleRate: 0,
115
+ serverName: "cdktn-cli",
116
+ // each test inits its own client; process-level integrations would
117
+ // pile up listeners across tests and are irrelevant to metrics
118
+ defaultIntegrations: false,
119
+ transport: (options) => Sentry.createTransport(options, async (request) => {
120
+ envelopeBodies.push(request.body);
121
+ return { statusCode: 200 };
122
+ }),
123
+ });
124
+ }
125
+ async function deliveredItems() {
126
+ expect(await Sentry.flush(2000)).toBe(true);
127
+ return parseMetricItems(envelopeBodies);
128
+ }
129
+ beforeEach(() => {
130
+ workdir = fs.mkdtempSync(path.join(os.tmpdir(), "cdktn-telemetry-"));
131
+ process.chdir(workdir);
132
+ envelopeBodies = [];
133
+ delete process.env.CHECKPOINT_DISABLE;
134
+ delete process.env.SENTRY_ENVIRONMENT;
135
+ // the probe is process-global (see terraform.ts); a seeded output keeps
136
+ // the binary attributes independent of the machine running the tests
137
+ (0, terraform_1.seedTerraformCliProbeForTests)(Promise.resolve("Terraform v1.9.0\non darwin_arm64\n"));
138
+ });
139
+ afterEach(async () => {
140
+ (0, telemetry_1.setUsageTelemetryEnabled)(undefined);
141
+ (0, telemetry_1.resetCommandTelemetry)();
142
+ (0, telemetry_1.setProjectTargetAttributes)(undefined);
143
+ (0, terraform_1.seedTerraformCliProbeForTests)();
144
+ await Sentry.close(1000);
145
+ process.chdir(originalCwd);
146
+ fs.removeSync(workdir);
147
+ if (originalCheckpointDisable === undefined) {
148
+ delete process.env.CHECKPOINT_DISABLE;
149
+ }
150
+ else {
151
+ process.env.CHECKPOINT_DISABLE = originalCheckpointDisable;
152
+ }
153
+ if (originalSentryEnvironment === undefined) {
154
+ delete process.env.SENTRY_ENVIRONMENT;
155
+ }
156
+ else {
157
+ process.env.SENTRY_ENVIRONMENT = originalSentryEnvironment;
158
+ }
159
+ });
160
+ describe("sendTelemetry delivery (real client + capturing transport)", () => {
161
+ it("stamps the command, language, binary and target attributes on every command metric", async () => {
162
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
163
+ language: "typescript",
164
+ sendUsageTelemetry: true,
165
+ targetVersions: { terraform: ">=1.9.0", opentofu: ">=1.8.0" },
166
+ validateInstalledBinary: true,
167
+ });
168
+ initSentryWithCapturingTransport();
169
+ await (0, telemetry_1.startCommandTelemetry)("synth");
170
+ await (0, telemetry_1.sendTelemetry)("synth", { totalTime: 1234, language: "typescript" });
171
+ await (0, telemetry_1.sendTelemetry)("synth", { error: true, synthOrigin: "watch" });
172
+ expect(await Sentry.flush(2000)).toBe(true);
173
+ const items = parseMetricItems(envelopeBodies);
174
+ expect(items.map((i) => i.name)).toEqual([
175
+ "cli.command.invoked",
176
+ "cli.command.completed",
177
+ "cli.synth.duration",
178
+ "cli.command.error",
179
+ ]);
180
+ const [invoked, completed, duration, error] = items;
181
+ for (const metric of items) {
182
+ expect(attributeValues(metric)).toMatchObject({
183
+ command: "synth",
184
+ os: process.platform,
185
+ arch: process.arch,
186
+ binary: "terraform",
187
+ binary_version: "1.9.0",
188
+ target_terraform: ">=1.9.0",
189
+ target_opentofu: ">=1.8.0",
190
+ targets_declared: true,
191
+ validate_installed_binary: true,
192
+ });
193
+ }
194
+ // the language comes from cdktf.json at start and from the payload
195
+ // at the end; the error metric has no payload and reuses the start read
196
+ expect(attributeValues(invoked).language).toBe("typescript");
197
+ expect(attributeValues(completed).language).toBe("typescript");
198
+ expect(duration.type).toBe("distribution");
199
+ expect(duration.value).toBe(1234);
200
+ expect(attributeValues(error)).toMatchObject({
201
+ error_type: "unexpected",
202
+ language: "typescript",
203
+ synth_origin: "watch",
204
+ });
205
+ });
206
+ it("uses the target attributes captured at command start over the current cwd", async () => {
207
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
208
+ targetVersions: { terraform: ">=1.0.0" },
209
+ });
210
+ initSentryWithCapturingTransport();
211
+ (0, telemetry_1.setProjectTargetAttributes)({
212
+ targets_declared: true,
213
+ validate_installed_binary: false,
214
+ target_opentofu: ">=1.7.0",
215
+ });
216
+ await (0, telemetry_1.startCommandTelemetry)("convert");
217
+ await (0, telemetry_1.sendTelemetry)("convert", {});
218
+ expect(await Sentry.flush(2000)).toBe(true);
219
+ const items = parseMetricItems(envelopeBodies);
220
+ expect(items.map((i) => i.name)).toEqual([
221
+ "cli.command.invoked",
222
+ "cli.command.completed",
223
+ ]);
224
+ for (const metric of items) {
225
+ expect(metric.attributes.target_opentofu.value).toBe(">=1.7.0");
226
+ expect(metric.attributes.target_terraform).toBeUndefined();
227
+ }
228
+ });
229
+ it.each([
230
+ ["Usage", "Usage"],
231
+ ["External", "External"],
232
+ ["Internal", "Internal"],
233
+ ["Something Else", "unexpected"],
234
+ ])("stamps error_type %p as %p on cli.command.error", async (errorType, expected) => {
235
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
236
+ sendUsageTelemetry: true,
237
+ });
238
+ initSentryWithCapturingTransport();
239
+ await (0, telemetry_1.sendTelemetry)("deploy", { error: true, errorType });
240
+ expect(await Sentry.flush(2000)).toBe(true);
241
+ const error = parseMetricItems(envelopeBodies).find((i) => i.name === "cli.command.error");
242
+ expect(error.attributes.error_type.value).toBe(expected);
243
+ expect(error.attributes.command.value).toBe("deploy");
244
+ });
245
+ it("forwards exactly the allow-listed attribute set and nothing else from the payload", async () => {
246
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
247
+ language: "typescript",
248
+ sendUsageTelemetry: true,
249
+ });
250
+ initSentryWithCapturingTransport();
251
+ await (0, telemetry_1.startCommandTelemetry)("synth");
252
+ await (0, telemetry_1.sendTelemetry)("synth", {
253
+ totalTime: 5,
254
+ language: "typescript",
255
+ synthOrigin: "watch",
256
+ stackMetadata: [{ stackName: "prod-vpc", backend: "s3" }],
257
+ requiredProviders: [{ aws: { source: "aws" } }],
258
+ stackName: "prod-vpc",
259
+ outdir: "/Users/x/secret",
260
+ resources: { aws: { secret_resource: 3 } },
261
+ });
262
+ expect(await Sentry.flush(2000)).toBe(true);
263
+ const items = parseMetricItems(envelopeBodies);
264
+ const invoked = items.find((i) => i.name === "cli.command.invoked");
265
+ const completed = items.find((i) => i.name === "cli.command.completed");
266
+ const keys = Object.keys(completed.attributes);
267
+ // the start metric carries the base set; the end-of-run scalars ride
268
+ // on completed only
269
+ expect(Object.keys(invoked.attributes).sort()).toEqual(keys.filter((key) => key !== "synth_origin").sort());
270
+ // the one place that fails when an attribute is added: extend it
271
+ // deliberately, together with the collected-data list in the docs
272
+ expect(keys.filter((key) => !key.startsWith("sentry.")).sort()).toEqual([
273
+ "arch",
274
+ "binary",
275
+ "binary_version",
276
+ "ci",
277
+ "command",
278
+ "language",
279
+ "os",
280
+ "package_manager",
281
+ // server.address is the fixed serverName from init
282
+ "server.address",
283
+ "synth_origin",
284
+ "target_opentofu",
285
+ "target_terraform",
286
+ "targets_declared",
287
+ "validate_installed_binary",
288
+ ]);
289
+ // stamped by the SDK from init; a patch bump may add more of them
290
+ expect(keys).toEqual(expect.arrayContaining(["sentry.release", "sentry.environment"]));
291
+ const bytes = envelopeBodies.join("\n");
292
+ expect(bytes).not.toContain("prod-vpc");
293
+ expect(bytes).not.toContain("/Users/x/secret");
294
+ expect(bytes).not.toContain("secret_resource");
295
+ });
296
+ });
297
+ describe("sendTelemetry payload mapping", () => {
298
+ beforeEach(() => {
299
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
300
+ sendUsageTelemetry: true,
301
+ });
302
+ initSentryWithCapturingTransport();
303
+ });
304
+ it("counts get targets per normalized provider/module and puts only totals on the command metric", async () => {
305
+ const provider = (constraint) => new construct_maker_target_1.ConstructsMakerProviderTarget(new config_1.TerraformProviderConstraint(constraint), config_1.Language.TYPESCRIPT).trackingPayload;
306
+ const module = (constraint) => new construct_maker_target_1.ConstructsMakerModuleTarget(new config_1.TerraformModuleConstraint(constraint), config_1.Language.TYPESCRIPT).trackingPayload;
307
+ await (0, telemetry_1.sendTelemetry)("get", {
308
+ targets: [
309
+ provider("registry.terraform.io/hashicorp/aws@~> 5.0"),
310
+ provider("Hashicorp/AWS@~> 6.0"),
311
+ provider("Kreuzwerker/Docker"),
312
+ module("terraform-aws-modules/vpc/aws@5.0.0"),
313
+ module("./modules/secret-name"),
314
+ ],
315
+ });
316
+ const items = await deliveredItems();
317
+ const totals = { provider_count: 3, module_count: 2 };
318
+ expect(metrics(items, "cli.command.completed")).toEqual([
319
+ { value: 1, ...totals },
320
+ ]);
321
+ expect(metrics(items, "cli.get.provider")).toEqual([
322
+ { value: 2, provider: "hashicorp/aws", ...totals },
323
+ { value: 1, provider: "kreuzwerker/docker", ...totals },
324
+ ]);
325
+ expect(metrics(items, "cli.get.module")).toEqual([
326
+ { value: 1, module: "local", ...totals },
327
+ { value: 1, module: "terraform-aws-modules/vpc/aws", ...totals },
328
+ ]);
329
+ expect(envelopeBodies.join("\n")).not.toContain("secret-name");
330
+ });
331
+ it("counts init providers per normalized provider and puts only the total on the command metric", async () => {
332
+ await (0, telemetry_1.sendTelemetry)("init", {
333
+ projectId: "should-not-be-sent",
334
+ addedProviders: [
335
+ "aws@~>5.0",
336
+ "hashicorp/random",
337
+ "registry.terraform.io/hashicorp/aws",
338
+ ],
339
+ });
340
+ const items = await deliveredItems();
341
+ expect(metrics(items, "cli.command.completed")).toEqual([
342
+ { value: 1, provider_count: 3 },
343
+ ]);
344
+ expect(metrics(items, "cli.init.provider")).toEqual([
345
+ { value: 2, provider: "hashicorp/aws", provider_count: 3 },
346
+ { value: 1, provider: "hashicorp/random", provider_count: 3 },
347
+ ]);
348
+ expect(envelopeBodies.join("\n")).not.toContain("should-not-be-sent");
349
+ });
350
+ it.each([
351
+ [
352
+ "get",
353
+ (sources) => ({
354
+ targets: sources.map((source) => ({ type: "provider", source })),
355
+ }),
356
+ "cli.get.provider",
357
+ { provider_count: 40, module_count: 0 },
358
+ ],
359
+ [
360
+ "init",
361
+ (sources) => ({ addedProviders: sources }),
362
+ "cli.init.provider",
363
+ { provider_count: 40 },
364
+ ],
365
+ ])("%s folds the providers past 32 into one truncated count", async (command, payload, metric, totals) => {
366
+ const sources = Array.from({ length: 40 }, (_, k) => `acme/p${String(k).padStart(2, "0")}`);
367
+ await (0, telemetry_1.sendTelemetry)(command, payload([...sources].reverse()));
368
+ const items = await deliveredItems();
369
+ expect(metrics(items, metric)).toEqual([
370
+ ...sources
371
+ .slice(0, 32)
372
+ .map((provider) => ({ value: 1, provider, ...totals })),
373
+ { value: 8, truncated: true, ...totals },
374
+ ]);
375
+ expect(metrics(items, "cli.command.completed")).toEqual([
376
+ { value: 1, ...totals },
377
+ ]);
378
+ });
379
+ it("counts the run as completed even when a per-source metric cannot be built", async () => {
380
+ await (0, telemetry_1.sendTelemetry)("get", {
381
+ targets: [null, { type: "provider", source: 7 }],
382
+ });
383
+ const items = await deliveredItems();
384
+ expect(metrics(items, "cli.command.completed")).toEqual([
385
+ { value: 1, provider_count: 1, module_count: 0 },
386
+ ]);
387
+ expect(metrics(items, "cli.get.provider")).toEqual([]);
388
+ });
389
+ });
390
+ describe("stack metrics", () => {
391
+ // one JSON-synthesized stack the way the library writes it: metadata
392
+ // carries the stack name and resource ids (imports/moved), overrides
393
+ // are keyed by schema type, module overrides by source
394
+ const stackMetadata = [
395
+ {
396
+ version: "0.21.0",
397
+ stackName: "SECRET-STACK-NAME",
398
+ backend: "s3",
399
+ overrides: {
400
+ stack: ["terraform.required_version"],
401
+ aws_s3_bucket: ["tags", "region"],
402
+ "module.../secret-path/vpc": ["providers"],
403
+ },
404
+ imports: { aws_s3_bucket: ["secret-resource-id"] },
405
+ moved: {
406
+ aws_s3_bucket: ["secret-resource-id"],
407
+ aws_iam_role: ["secret-resource-id"],
408
+ },
409
+ },
410
+ {
411
+ version: "0.21.0",
412
+ stackName: "SECRET-STACK-NAME-2",
413
+ backend: "remote",
414
+ cloud: "tfc",
415
+ },
416
+ ];
417
+ const requiredProviders = [
418
+ {
419
+ aws: { source: "aws", version: "~> 5.0" },
420
+ docker: {
421
+ source: "registry.terraform.io/kreuzwerker/docker",
422
+ version: "3.0.2",
423
+ },
424
+ google: { source: "hashicorp/google", version: "x".repeat(100) },
425
+ },
426
+ {
427
+ random: { source: "hashicorp/random" },
428
+ vault: {
429
+ source: "tfe.corp.example.com/acme-org/vault",
430
+ version: "~> 3.0",
431
+ },
432
+ },
433
+ ];
434
+ const noCounts = { override_count: 0, import_count: 0, moved_count: 0 };
435
+ beforeEach(() => {
436
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
437
+ sendUsageTelemetry: true,
438
+ terraformProviders: [
439
+ "aws@~>5.0",
440
+ { name: "docker", source: "kreuzwerker/docker", version: "3.0.2" },
441
+ ],
442
+ });
443
+ initSentryWithCapturingTransport();
444
+ });
445
+ it("delivers no stack, provider or override metric when the project opts out", async () => {
446
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
447
+ sendUsageTelemetry: false,
448
+ });
449
+ await (0, telemetry_1.sendTelemetry)("deploy", {
450
+ language: "typescript",
451
+ stackMetadata,
452
+ requiredProviders,
453
+ failedStackCount: 0,
454
+ });
455
+ expect(await deliveredItems()).toEqual([]);
456
+ });
457
+ it("counts stacks by backend, cloud and library version with their group sizes", async () => {
458
+ await (0, telemetry_1.sendTelemetry)("deploy", {
459
+ language: "typescript",
460
+ stackMetadata,
461
+ requiredProviders,
462
+ failedStackCount: 0,
463
+ });
464
+ const items = await deliveredItems();
465
+ expect(metrics(items, "cli.stack")).toEqual([
466
+ {
467
+ value: 1,
468
+ backend: "remote",
469
+ cloud: true,
470
+ library_version: "0.21.0",
471
+ ...noCounts,
472
+ },
473
+ {
474
+ value: 1,
475
+ backend: "s3",
476
+ cloud: false,
477
+ library_version: "0.21.0",
478
+ override_count: 4,
479
+ import_count: 1,
480
+ moved_count: 2,
481
+ },
482
+ ]);
483
+ for (const stack of items.filter((i) => i.name === "cli.stack")) {
484
+ expect(attributeValues(stack)).toMatchObject({
485
+ command: "deploy",
486
+ language: "typescript",
487
+ });
488
+ }
489
+ expect(items.some((i) => i.name === "cli.stack.failed")).toBe(false);
490
+ expect(items.some((i) => i.name === "cli.command.completed")).toBe(true);
491
+ });
492
+ it("counts overrides per resource type, reducing module sources to their kind", async () => {
493
+ await (0, telemetry_1.sendTelemetry)("synth", { stackMetadata, requiredProviders });
494
+ expect(metrics(await deliveredItems(), "cli.stack.override")).toEqual([
495
+ { value: 1, resource_type: "aws_s3_bucket", override_count: 2 },
496
+ { value: 1, resource_type: "module.local", override_count: 1 },
497
+ { value: 1, resource_type: "stack", override_count: 1 },
498
+ ]);
499
+ });
500
+ it("counts required providers by normalized source, validated constraint and binding", async () => {
501
+ await (0, telemetry_1.sendTelemetry)("diff", { stackMetadata, requiredProviders });
502
+ expect(metrics(await deliveredItems(), "cli.stack.provider")).toEqual([
503
+ {
504
+ value: 1,
505
+ provider: "hashicorp/aws",
506
+ version_constraint: "~> 5.0",
507
+ binding: "generated",
508
+ },
509
+ {
510
+ value: 1,
511
+ provider: "hashicorp/google",
512
+ version_constraint: "invalid",
513
+ binding: "prebuilt",
514
+ },
515
+ { value: 1, provider: "hashicorp/random", binding: "prebuilt" },
516
+ {
517
+ value: 1,
518
+ provider: "kreuzwerker/docker",
519
+ version_constraint: "3.0.2",
520
+ binding: "generated",
521
+ },
522
+ {
523
+ value: 1,
524
+ provider: "private-registry",
525
+ version_constraint: "~> 3.0",
526
+ binding: "prebuilt",
527
+ },
528
+ ]);
529
+ });
530
+ it("classifies bindings against the project the command started in, not the current cwd", async () => {
531
+ await (0, telemetry_1.startCommandTelemetry)("diff");
532
+ const elsewhere = path.join(workdir, "elsewhere");
533
+ fs.mkdirSync(elsewhere);
534
+ fs.writeJsonSync(path.join(elsewhere, "cdktf.json"), {
535
+ terraformProviders: ["google"],
536
+ });
537
+ process.chdir(elsewhere);
538
+ await (0, telemetry_1.sendTelemetry)("diff", { stackMetadata, requiredProviders });
539
+ expect(metrics(await deliveredItems(), "cli.stack.provider").map((p) => [
540
+ p.provider,
541
+ p.binding,
542
+ ])).toEqual([
543
+ ["hashicorp/aws", "generated"],
544
+ ["hashicorp/google", "prebuilt"],
545
+ ["hashicorp/random", "prebuilt"],
546
+ ["kreuzwerker/docker", "generated"],
547
+ ["private-registry", "prebuilt"],
548
+ ]);
549
+ });
550
+ it.each([3, 300])("sends the same stack events for %d alike stacks, with the stack count as their value", async (count) => {
551
+ await (0, telemetry_1.sendTelemetry)("deploy", {
552
+ stackMetadata: Array.from({ length: count }, (_, i) => ({
553
+ version: "0.21.0",
554
+ stackName: `stack-${i}`,
555
+ backend: "s3",
556
+ overrides: { aws_s3_bucket: ["tags"] },
557
+ })),
558
+ requiredProviders: Array.from({ length: count }, () => ({
559
+ aws: { source: "aws", version: "~> 5.0" },
560
+ random: { source: "hashicorp/random" },
561
+ })),
562
+ });
563
+ const items = await deliveredItems();
564
+ expect(metrics(items, "cli.stack")).toEqual([
565
+ {
566
+ value: count,
567
+ backend: "s3",
568
+ cloud: false,
569
+ library_version: "0.21.0",
570
+ override_count: count,
571
+ import_count: 0,
572
+ moved_count: 0,
573
+ },
574
+ ]);
575
+ expect(metrics(items, "cli.stack.provider")).toEqual([
576
+ {
577
+ value: count,
578
+ provider: "hashicorp/aws",
579
+ version_constraint: "~> 5.0",
580
+ binding: "generated",
581
+ },
582
+ { value: count, provider: "hashicorp/random", binding: "prebuilt" },
583
+ ]);
584
+ expect(metrics(items, "cli.stack.override")).toEqual([
585
+ {
586
+ value: count,
587
+ resource_type: "aws_s3_bucket",
588
+ override_count: count,
589
+ },
590
+ ]);
591
+ });
592
+ it("groups providers on what is sent: spellings and private hosts collapse, constraints do not", async () => {
593
+ await (0, telemetry_1.sendTelemetry)("synth", {
594
+ stackMetadata: [{}, {}, {}],
595
+ requiredProviders: [
596
+ {
597
+ aws: { source: "aws", version: "~>5.0" },
598
+ vault: { source: "tfe.leak-one.example/leak-org-one/vault" },
599
+ },
600
+ {
601
+ aws: { source: "Hashicorp/AWS", version: "~> 5.0" },
602
+ // a stack counts once per group, however many entries reach it
603
+ vault: { source: "registry.leak-two.example/leak-org-two/vault" },
604
+ consul: { source: "mirror.leak-three.example/leak-org-two/consul" },
605
+ },
606
+ {
607
+ aws: {
608
+ source: "registry.terraform.io/hashicorp/aws",
609
+ version: "~> 5.0",
610
+ },
611
+ aws6: { source: "aws", version: "~> 6.0" },
612
+ },
613
+ ],
614
+ });
615
+ expect(metrics(await deliveredItems(), "cli.stack.provider")).toEqual([
616
+ {
617
+ value: 3,
618
+ provider: "hashicorp/aws",
619
+ version_constraint: "~> 5.0",
620
+ binding: "generated",
621
+ },
622
+ { value: 2, provider: "private-registry", binding: "prebuilt" },
623
+ {
624
+ value: 1,
625
+ provider: "hashicorp/aws",
626
+ version_constraint: "~> 6.0",
627
+ binding: "generated",
628
+ },
629
+ ]);
630
+ expect(envelopeBodies.join("\n")).not.toContain("leak");
631
+ });
632
+ it("sums the group sizes of the stacks in a group and the paths of an override type", async () => {
633
+ await (0, telemetry_1.sendTelemetry)("synth", {
634
+ stackMetadata: [
635
+ {
636
+ backend: "local",
637
+ overrides: { aws_s3_bucket: ["a", "b", "c"], "bad key 1": ["x"] },
638
+ imports: { aws_s3_bucket: ["id"] },
639
+ },
640
+ {
641
+ backend: "local",
642
+ overrides: {
643
+ aws_s3_bucket: ["a"],
644
+ "bad key 2": ["x"],
645
+ "bad key 3": ["x", "y", "z"],
646
+ },
647
+ moved: { aws_s3_bucket: ["id", "id"] },
648
+ },
649
+ ],
650
+ });
651
+ const items = await deliveredItems();
652
+ expect(metrics(items, "cli.stack")).toEqual([
653
+ {
654
+ value: 2,
655
+ backend: "local",
656
+ cloud: false,
657
+ override_count: 9,
658
+ import_count: 1,
659
+ moved_count: 2,
660
+ },
661
+ ]);
662
+ expect(metrics(items, "cli.stack.override")).toEqual([
663
+ { value: 2, resource_type: "aws_s3_bucket", override_count: 4 },
664
+ { value: 2, resource_type: "other", override_count: 5 },
665
+ ]);
666
+ });
667
+ it("keeps the 32 most required providers and folds the rest into one truncated count", async () => {
668
+ const sources = Array.from({ length: 40 }, (_, k) => `acme/p${String(k).padStart(2, "0")}`);
669
+ // provider k is required by 40 - k stacks
670
+ const requiredByStack = sources.map((_, stack) => Object.fromEntries(sources
671
+ .slice(0, sources.length - stack)
672
+ .map((source, k) => [`p${k}`, { source }])));
673
+ await (0, telemetry_1.sendTelemetry)("synth", {
674
+ stackMetadata: sources.map(() => ({})),
675
+ requiredProviders: requiredByStack,
676
+ });
677
+ const providers = metrics(await deliveredItems(), "cli.stack.provider");
678
+ expect(providers).toEqual([
679
+ ...sources.slice(0, 32).map((provider, k) => ({
680
+ value: 40 - k,
681
+ provider,
682
+ binding: "prebuilt",
683
+ })),
684
+ { value: 36, truncated: true },
685
+ ]);
686
+ expect(providers.reduce((total, p) => total + p.value, 0)).toBe(820);
687
+ });
688
+ it("keeps the first 32 override types by name on a tie and folds the rest with their paths", async () => {
689
+ const types = Array.from({ length: 34 }, (_, k) => `aws_t${String(k).padStart(2, "0")}`);
690
+ const longer = {
691
+ aws_t32: ["a", "b"],
692
+ aws_t33: ["a", "b", "c"],
693
+ };
694
+ const paths = (type) => { var _a; return (_a = longer[type]) !== null && _a !== void 0 ? _a : ["a"]; };
695
+ await (0, telemetry_1.sendTelemetry)("synth", {
696
+ stackMetadata: [
697
+ {
698
+ overrides: Object.fromEntries([...types].reverse().map((type) => [type, paths(type)])),
699
+ },
700
+ ],
701
+ });
702
+ expect(metrics(await deliveredItems(), "cli.stack.override")).toEqual([
703
+ ...types.slice(0, 32).map((resource_type) => ({
704
+ value: 1,
705
+ resource_type,
706
+ override_count: 1,
707
+ })),
708
+ { value: 2, override_count: 5, truncated: true },
709
+ ]);
710
+ });
711
+ it("keeps the 8 largest stack groups and folds the rest with their group sizes", async () => {
712
+ // library version 0.k.0 is used by k + 1 stacks, each with one import
713
+ const stacksOfVersion = (k) => Array.from({ length: k + 1 }, () => ({
714
+ version: `0.${k}.0`,
715
+ backend: "s3",
716
+ imports: { aws_s3_bucket: ["id"] },
717
+ }));
718
+ await (0, telemetry_1.sendTelemetry)("synth", {
719
+ stackMetadata: Array.from({ length: 10 }, (_, k) => stacksOfVersion(k)).flat(),
720
+ });
721
+ const stacks = metrics(await deliveredItems(), "cli.stack");
722
+ expect(stacks).toEqual([
723
+ ...[9, 8, 7, 6, 5, 4, 3, 2].map((k) => ({
724
+ value: k + 1,
725
+ backend: "s3",
726
+ cloud: false,
727
+ library_version: `0.${k}.0`,
728
+ ...noCounts,
729
+ import_count: k + 1,
730
+ })),
731
+ { value: 3, truncated: true, ...noCounts, import_count: 3 },
732
+ ]);
733
+ expect(stacks.reduce((total, s) => total + s.value, 0)).toBe(55);
734
+ });
735
+ it("bounds the stack events of a run whatever the project's shape, in the envelope of the command metric", async () => {
736
+ const forty = Array.from({ length: 40 }, (_, k) => k);
737
+ await (0, telemetry_1.sendTelemetry)("deploy", {
738
+ stackMetadata: Array.from({ length: 300 }, (_, i) => ({
739
+ version: `1.${i}.0`,
740
+ overrides: Object.fromEntries(forty.map((k) => [`aws_type_${k}`, ["tags"]])),
741
+ })),
742
+ requiredProviders: Array.from({ length: 300 }, () => Object.fromEntries(forty.map((k) => [`p${k}`, { source: `acme/p${k}` }]))),
743
+ });
744
+ const items = await deliveredItems();
745
+ const count = (name) => metrics(items, name).length;
746
+ const total = (name) => metrics(items, name).reduce((sum, m) => sum + m.value, 0);
747
+ expect([
748
+ count("cli.stack"),
749
+ count("cli.stack.provider"),
750
+ count("cli.stack.override"),
751
+ ]).toEqual([9, 33, 33]);
752
+ expect(total("cli.stack")).toBe(300);
753
+ expect(total("cli.stack.provider")).toBe(300 * 40);
754
+ expect(count("cli.command.completed")).toBe(1);
755
+ expect(envelopeBodies).toHaveLength(1);
756
+ });
757
+ it("leaves the stacks to the command when its synth is nested: only the selected ones, under its name", async () => {
758
+ await (0, telemetry_1.startCommandTelemetry)("deploy");
759
+ await (0, telemetry_1.sendTelemetry)("synth", {
760
+ totalTime: 42,
761
+ stackMetadata,
762
+ requiredProviders,
763
+ });
764
+ await (0, telemetry_1.sendTelemetry)("deploy", {
765
+ stackMetadata: stackMetadata.slice(1),
766
+ requiredProviders: requiredProviders.slice(1),
767
+ });
768
+ const items = await deliveredItems();
769
+ expect(items
770
+ .filter((i) => i.name.startsWith("cli.stack"))
771
+ .map((i) => [i.name, attributeValues(i).command, i.value])).toEqual([
772
+ ["cli.stack", "deploy", 1],
773
+ ["cli.stack.provider", "deploy", 1],
774
+ ["cli.stack.provider", "deploy", 1],
775
+ ]);
776
+ expect(items.some((i) => i.name === "cli.synth.duration" &&
777
+ attributeValues(i).command === "synth")).toBe(true);
778
+ });
779
+ it("reports the stacks of a synth run under synth", async () => {
780
+ await (0, telemetry_1.startCommandTelemetry)("synth");
781
+ await (0, telemetry_1.sendTelemetry)("synth", { stackMetadata, requiredProviders });
782
+ const stacks = (await deliveredItems()).filter((i) => i.name === "cli.stack");
783
+ expect(stacks.map((i) => attributeValues(i).command)).toEqual([
784
+ "synth",
785
+ "synth",
786
+ ]);
787
+ });
788
+ it("reports the stacks once per process: a watch session's later deploys add only their failures", async () => {
789
+ await (0, telemetry_1.startCommandTelemetry)("watch");
790
+ await (0, telemetry_1.sendTelemetry)("deploy", { stackMetadata, requiredProviders });
791
+ await (0, telemetry_1.sendTelemetry)("deploy", {
792
+ stackMetadata,
793
+ requiredProviders,
794
+ failedStackCount: 1,
795
+ });
796
+ const items = await deliveredItems();
797
+ expect(metrics(items, "cli.stack")).toHaveLength(2);
798
+ expect(metrics(items, "cli.stack.provider")).toHaveLength(5);
799
+ expect(metrics(items, "cli.stack.override")).toHaveLength(3);
800
+ expect(metrics(items, "cli.stack.failed")).toEqual([{ value: 1 }]);
801
+ });
802
+ it("counts failed stacks and never serializes their failure messages", async () => {
803
+ await (0, telemetry_1.sendTelemetry)("destroy", {
804
+ stackMetadata,
805
+ requiredProviders,
806
+ failedStackCount: 2,
807
+ failedStacks: ["failed to destroy SECRET-STACK-NAME: /Users/x/state"],
808
+ });
809
+ expect(await Sentry.flush(2000)).toBe(true);
810
+ const items = parseMetricItems(envelopeBodies);
811
+ const failed = items.find((i) => i.name === "cli.stack.failed");
812
+ expect(failed.value).toBe(2);
813
+ expect(failed.attributes.command.value).toBe("destroy");
814
+ // the failure thrown next is counted as cli.command.error, not here
815
+ expect(items.some((i) => i.name === "cli.command.completed")).toBe(false);
816
+ expect(envelopeBodies.join("\n")).not.toContain("failed to destroy");
817
+ expect(envelopeBodies.join("\n")).not.toContain("/Users/x");
818
+ });
819
+ it("counts no completed run and no failed stack for a run that failed before any stack did", async () => {
820
+ await (0, telemetry_1.sendTelemetry)("deploy", {
821
+ stackMetadata,
822
+ requiredProviders,
823
+ failedStackCount: 0,
824
+ runFailed: true,
825
+ });
826
+ const items = await deliveredItems();
827
+ expect(metrics(items, "cli.stack")).toHaveLength(2);
828
+ expect(metrics(items, "cli.stack.failed")).toEqual([]);
829
+ expect(items.some((i) => i.name === "cli.command.completed")).toBe(false);
830
+ });
831
+ it("never serializes stack names, resource ids or module paths", async () => {
832
+ await (0, telemetry_1.sendTelemetry)("deploy", {
833
+ language: "typescript",
834
+ stackMetadata,
835
+ requiredProviders,
836
+ failedStackCount: 1,
837
+ });
838
+ const items = await deliveredItems();
839
+ // the scan below is over two stacks, three override types, five
840
+ // providers and the failed count
841
+ expect(items.filter((i) => i.name.startsWith("cli.stack"))).toHaveLength(11);
842
+ const bytes = envelopeBodies.join("\n");
843
+ expect(bytes).not.toContain("SECRET-STACK-NAME");
844
+ expect(bytes).not.toContain("secret-resource-id");
845
+ expect(bytes).not.toContain("secret-path");
846
+ expect(bytes).not.toContain("tfe.corp.example.com");
847
+ expect(bytes).not.toContain("acme-org");
848
+ });
849
+ // the metadata is read from disk, written by whatever library version
850
+ // the project has
851
+ it("tolerates malformed metadata entries and counts only the real stacks", async () => {
852
+ await (0, telemetry_1.sendTelemetry)("synth", {
853
+ stackMetadata: [null, "nope", { overrides: "nope", imports: [] }],
854
+ requiredProviders: [undefined, undefined, { aws: "nope" }],
855
+ });
856
+ const items = await deliveredItems();
857
+ expect(metrics(items, "cli.stack")).toEqual([
858
+ { value: 1, backend: "unknown", cloud: false, ...noCounts },
859
+ ]);
860
+ expect(metrics(items, "cli.stack.override")).toEqual([]);
861
+ expect(metrics(items, "cli.stack.provider")).toEqual([
862
+ { value: 1, provider: "hashicorp/aws", binding: "generated" },
863
+ ]);
864
+ expect(items.some((i) => i.name === "cli.command.completed")).toBe(true);
865
+ });
866
+ });
867
+ describe("attribute validation", () => {
868
+ beforeEach(() => {
869
+ initSentryWithCapturingTransport();
870
+ });
871
+ it("omits an unsupported language, read from cdktf.json at start or passed at the end", async () => {
872
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
873
+ language: "rust; DROP TABLE",
874
+ });
875
+ await (0, telemetry_1.startCommandTelemetry)("convert");
876
+ await (0, telemetry_1.sendTelemetry)("convert", { language: "cobol; DROP TABLE" });
877
+ expect(await Sentry.flush(2000)).toBe(true);
878
+ const items = parseMetricItems(envelopeBodies);
879
+ expect(items.map((i) => i.name)).toEqual([
880
+ "cli.command.invoked",
881
+ "cli.command.completed",
882
+ ]);
883
+ for (const item of items) {
884
+ expect(item.attributes).not.toHaveProperty("language");
885
+ }
886
+ expect(envelopeBodies.join("\n")).not.toContain("DROP TABLE");
887
+ });
888
+ it.each([
889
+ ["synth", { synthOrigin: "watch" }, "synth_origin", "watch"],
890
+ ["synth", { synthOrigin: "/Users/x" }, "synth_origin", undefined],
891
+ ["init", { isRemote: true }, "is_remote", true],
892
+ ["init", { template: "go" }, "template", "go"],
893
+ ["convert", { numberOfProviders: 2 }, "provider_count", 2],
894
+ ["convert", { numberOfModules: 1 }, "module_count", 1],
895
+ ["convert", { convertedLines: 42 }, "converted_lines", 42],
896
+ ["convert", { convertedLines: "42" }, "converted_lines", undefined],
897
+ ["convert", { convertedLines: NaN }, "converted_lines", undefined],
898
+ ])("%s: %j forwards %s as %j", async (command, payload, attribute, expected) => {
899
+ await (0, telemetry_1.sendTelemetry)(command, payload);
900
+ expect(await Sentry.flush(2000)).toBe(true);
901
+ const completed = parseMetricItems(envelopeBodies).find((i) => i.name === "cli.command.completed");
902
+ if (expected === undefined) {
903
+ expect(completed.attributes).not.toHaveProperty(attribute);
904
+ }
905
+ else {
906
+ expect(attributeValues(completed)[attribute]).toBe(expected);
907
+ }
908
+ });
909
+ it.each([
910
+ [">= 1.9.0", ">=1.9.0"],
911
+ ["~1.8", ">=1.8.0 <1.9.0-0"],
912
+ ["1.2.3 - 2.0.0", ">=1.2.3 <=2.0.0"],
913
+ [">=1.0.0 <2.0.0 || 1.2.3", ">=1.0.0 <2.0.0||1.2.3"],
914
+ ["latest /Users/x", "invalid"],
915
+ [">= 1.0.0-LEAK-TV-PRERELEASE.corp.example.com", "invalid"],
916
+ ["1.2.3-acme.internal", "invalid"],
917
+ ["1.2.3+LEAK-TV-BUILD.johns-macbook", "invalid"],
918
+ [">=1.0.0 <2.0.0 || 1.2.3-LEAK-OR.host", "invalid"],
919
+ [">=1.0.0 " + "||1.0.0 ".repeat(10), "invalid"],
920
+ ])("forwards the declared target %p as %p", (range, expected) => {
921
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
922
+ targetVersions: { terraform: range },
923
+ });
924
+ expect((0, telemetry_1.getProjectTargetAttributes)(workdir).target_terraform).toBe(expected);
925
+ });
926
+ it("reduces a backend outside the built-in kinds and override keys outside the type grammar to other", async () => {
927
+ await (0, telemetry_1.sendTelemetry)("synth", {
928
+ stackMetadata: [
929
+ {
930
+ version: "0.21.0+build." + "x".repeat(40),
931
+ backend: "s3 bucket=/Users/x/state",
932
+ overrides: {
933
+ aws_s3_bucket: ["tags"],
934
+ terraform_remote_state: ["backend"],
935
+ "module.terraform-aws-modules/vpc/aws": ["providers"],
936
+ "resource with spaces /Users/x": ["tags"],
937
+ AWS_S3_Bucket: ["tags"],
938
+ ["aws_" + "x".repeat(70)]: ["tags"],
939
+ },
940
+ },
941
+ { version: "dev-/Users/x", backend: "S3" },
942
+ { version: "dev-/Users/x" },
943
+ ],
944
+ });
945
+ const items = await deliveredItems();
946
+ // build metadata is stripped like binary_version; a version without a
947
+ // MAJOR.MINOR.PATCH prefix yields no attribute at all
948
+ expect(metrics(items, "cli.stack").map((stack) => [
949
+ stack.backend,
950
+ stack.library_version,
951
+ ])).toEqual([
952
+ ["other", "0.21.0"],
953
+ ["other", undefined],
954
+ ["unknown", undefined],
955
+ ]);
956
+ expect(metrics(items, "cli.stack.override").map((o) => [
957
+ o.resource_type,
958
+ o.override_count,
959
+ ])).toEqual([
960
+ ["aws_s3_bucket", 1],
961
+ ["module.terraform-aws-modules/vpc/aws", 1],
962
+ ["other", 3],
963
+ ["terraform_remote_state", 1],
964
+ ]);
965
+ expect(envelopeBodies.join("\n")).not.toContain("/Users/x");
966
+ });
967
+ });
968
+ describe("provider binding classification", () => {
969
+ beforeEach(() => {
970
+ initSentryWithCapturingTransport();
971
+ });
972
+ async function bindingOf(source) {
973
+ await (0, telemetry_1.sendTelemetry)("synth", {
974
+ stackMetadata: [{}],
975
+ requiredProviders: [{ provider: { source } }],
976
+ });
977
+ return metrics(await deliveredItems(), "cli.stack.provider").map((provider) => provider.binding);
978
+ }
979
+ it.each([
980
+ ["aws", "generated"],
981
+ ["Hashicorp/Random", "generated"],
982
+ ["kreuzwerker/docker", "generated"],
983
+ ["hashicorp/google", "generated"],
984
+ ["azurerm", "generated"],
985
+ ["hashicorp/null", "prebuilt"],
986
+ ["tfe.corp.example.com/acme-org/vault", "generated"],
987
+ // another private source is not the generated one, even though both
988
+ // reach the metric as "private-registry"
989
+ ["tfe.corp.example.com/other-org/vault", "prebuilt"],
990
+ ])("sends the required provider %s as %s for the project's terraformProviders", async (source, expected) => {
991
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
992
+ terraformProviders: [
993
+ "aws@~>5.0",
994
+ "hashicorp/random@3.6.0",
995
+ "registry.terraform.io/kreuzwerker/docker",
996
+ { name: "google", source: "hashicorp/google", version: "~> 5.0" },
997
+ { name: "azurerm" },
998
+ { version: "1.0.0" },
999
+ 42,
1000
+ "TFE.corp.example.com/acme-org/vault@~>3.0",
1001
+ ],
1002
+ });
1003
+ expect(await bindingOf(source)).toEqual([expected]);
1004
+ });
1005
+ it("sends every provider as prebuilt when terraformProviders is not a list", async () => {
1006
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1007
+ terraformProviders: "aws",
1008
+ });
1009
+ expect(await bindingOf("aws")).toEqual(["prebuilt"]);
1010
+ });
1011
+ });
1012
+ describe("source normalization", () => {
1013
+ beforeEach(() => {
1014
+ initSentryWithCapturingTransport();
1015
+ });
1016
+ it.each([
1017
+ ["aws", "hashicorp/aws"],
1018
+ ["aws@~>5.0", "hashicorp/aws"],
1019
+ ["Hashicorp/AWS@5.1.0", "hashicorp/aws"],
1020
+ ["registry.terraform.io/hashicorp/aws", "hashicorp/aws"],
1021
+ ["registry.opentofu.org/hashicorp/aws", "hashicorp/aws"],
1022
+ ["tfe.leak-host.example/leak-org/aws", "private-registry"],
1023
+ ["localhost:8080/leak-org/aws", "private-registry"],
1024
+ ["./leak-provider", "other"],
1025
+ ["../leak/provider", "other"],
1026
+ ["/abs/leak/provider", "other"],
1027
+ ["leak-a/b/c", "other"],
1028
+ ["", "other"],
1029
+ ["registry.terraform.io/leak-namespace", "other"],
1030
+ [`${"n".repeat(65)}/aws`, "other"],
1031
+ [`${"n".repeat(64)}/aws`, `${"n".repeat(64)}/aws`],
1032
+ [`${"n".repeat(64)}/${"t".repeat(64)}`, "other"],
1033
+ ])("sends the provider source %s as %s", async (source, expected) => {
1034
+ await (0, telemetry_1.sendTelemetry)("get", { targets: [{ type: "provider", source }] });
1035
+ expect(metrics(await deliveredItems(), "cli.get.provider").map((item) => item.provider)).toEqual([expected]);
1036
+ expect(envelopeBodies.join("\n")).not.toContain("leak");
1037
+ });
1038
+ it.each([
1039
+ ["terraform-aws-modules/vpc/aws", "terraform-aws-modules/vpc/aws"],
1040
+ ["Terraform-AWS-Modules/VPC/aws", "terraform-aws-modules/vpc/aws"],
1041
+ // one row per fallthrough: everything the grammar rejects is "other"
1042
+ ["Terraform-AWS-Modules/leak-vpc/aws?ref=v5.0.0", "other"],
1043
+ [`${"n".repeat(64)}/vpc/aws`, `${"n".repeat(64)}/vpc/aws`],
1044
+ [`${"n".repeat(65)}/vpc/aws`, "other"],
1045
+ ["app.terraform.io/leak-org/vpc/aws", "private-registry"],
1046
+ ["./modules/leak-vpc", "local"],
1047
+ ["../shared/leak-vpc", "local"],
1048
+ ["/abs/path/leak-vpc", "local"],
1049
+ ["git@github.com:leak-org/repo.git", "git"],
1050
+ ["github.com/leak-org/repo", "git"],
1051
+ ["bitbucket.org/leak-org/repo", "git"],
1052
+ ["https://leak-host.example/vpc.zip", "git"],
1053
+ ["s3-eu-west-1.amazonaws.com/leak-bucket/vpc.zip", "git"],
1054
+ ["www.googleapis.com/storage/v1/leak-bucket/vpc", "git"],
1055
+ // forced getters without a URL scheme behind them
1056
+ ["git::leak-host.example/leak-org/repo.git", "git"],
1057
+ ["hg::leak-host.example/leak-repo", "git"],
1058
+ ["s3::leak-bucket/vpc.zip", "git"],
1059
+ ["gcs::leak-bucket/vpc", "git"],
1060
+ ])("sends the module source %s as %s", async (source, expected) => {
1061
+ await (0, telemetry_1.sendTelemetry)("get", { targets: [{ type: "module", source }] });
1062
+ expect(metrics(await deliveredItems(), "cli.get.module").map((item) => item.module)).toEqual([expected]);
1063
+ expect(envelopeBodies.join("\n")).not.toContain("leak");
1064
+ });
1065
+ it.each([
1066
+ [">= 1.2, < 2.0", ">= 1.2, < 2.0"],
1067
+ ["~> 5.0", "~> 5.0"],
1068
+ ["= 1.0", "= 1.0"],
1069
+ ["!= 1.2.3", "!= 1.2.3"],
1070
+ ["1.2.3", "1.2.3"],
1071
+ [" >= 1.0 , < 2.0 ", ">= 1.0, < 2.0"],
1072
+ ["~>5.0,!=5.1.0", "~> 5.0, != 5.1.0"],
1073
+ [">= 1.0.0-leak-prerelease.corp", "invalid"],
1074
+ ["1.2.3+leak-build.host", "invalid"],
1075
+ ["~> 5.0 # /Users/leak", "invalid"],
1076
+ [">= 1.2 || < 2.0", "invalid"],
1077
+ // valid by the grammar, over the length a constraint may have
1078
+ [Array(12).fill("!= 1.0.0").join(", "), "invalid"],
1079
+ ])("sends the provider constraint %p as %p", async (version, expected) => {
1080
+ await (0, telemetry_1.sendTelemetry)("synth", {
1081
+ stackMetadata: [{}],
1082
+ requiredProviders: [{ aws: { source: "aws", version } }],
1083
+ });
1084
+ expect(metrics(await deliveredItems(), "cli.stack.provider").map((provider) => provider.version_constraint)).toEqual([expected]);
1085
+ expect(envelopeBodies.join("\n")).not.toContain("leak");
1086
+ });
1087
+ });
1088
+ describe("package manager", () => {
1089
+ beforeEach(() => {
1090
+ initSentryWithCapturingTransport();
1091
+ });
1092
+ afterEach(() => {
1093
+ jest.dontMock("./node-package-manager");
1094
+ });
1095
+ // a copy of the module whose node detector is replaced
1096
+ function telemetryWithNodeDetector(detect) {
1097
+ let copy;
1098
+ jest.isolateModules(() => {
1099
+ jest.doMock("./node-package-manager", () => ({
1100
+ detectNodePackageManager: detect,
1101
+ }));
1102
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
1103
+ copy = require("./telemetry");
1104
+ });
1105
+ return copy;
1106
+ }
1107
+ // one successful and one failed end, so every command metric is covered
1108
+ async function runMetrics(telemetry = { startCommandTelemetry: telemetry_1.startCommandTelemetry, sendTelemetry: telemetry_1.sendTelemetry }) {
1109
+ await telemetry.startCommandTelemetry("synth");
1110
+ await telemetry.sendTelemetry("synth", {});
1111
+ await telemetry.sendTelemetry("synth", { error: true });
1112
+ expect(await Sentry.flush(2000)).toBe(true);
1113
+ const items = parseMetricItems(envelopeBodies);
1114
+ expect(items.map((i) => i.name)).toEqual([
1115
+ "cli.command.invoked",
1116
+ "cli.command.completed",
1117
+ "cli.command.error",
1118
+ ]);
1119
+ return items;
1120
+ }
1121
+ it.each([
1122
+ ["no lockfile", "npm", {}],
1123
+ ["a pnpm lockfile", "pnpm", { "pnpm-lock.yaml": "" }],
1124
+ ["a yarn lockfile", "yarn", { "yarn.lock": "" }],
1125
+ ["a .yarnrc.yml", "yarn-berry", { ".yarnrc.yml": "" }],
1126
+ [
1127
+ "a declared npm",
1128
+ "npm",
1129
+ { "package.json": '{"packageManager":"npm@10.8.2"}' },
1130
+ ],
1131
+ [
1132
+ "a declared pnpm with a hash",
1133
+ "pnpm",
1134
+ { "package.json": '{"packageManager":"pnpm@10.26.0+sha512.LEAK"}' },
1135
+ ],
1136
+ [
1137
+ "a declared yarn 1",
1138
+ "yarn",
1139
+ { "package.json": '{"packageManager":"yarn@1.22.22"}' },
1140
+ ],
1141
+ [
1142
+ "a declared yarn 4",
1143
+ "yarn-berry",
1144
+ { "package.json": '{"packageManager":"yarn@4.1.0"}' },
1145
+ ],
1146
+ [
1147
+ "an unknown declared manager",
1148
+ "npm",
1149
+ { "package.json": '{"packageManager":"bun@1.1.0-LEAK"}' },
1150
+ ],
1151
+ ])("reports a typescript project with %s as %p on every command metric", async (_name, expected, files) => {
1152
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1153
+ language: "typescript",
1154
+ });
1155
+ for (const [name, content] of Object.entries(files)) {
1156
+ fs.writeFileSync(path.join(workdir, name), content);
1157
+ }
1158
+ for (const item of await runMetrics()) {
1159
+ expect(attributeValues(item).package_manager).toBe(expected);
1160
+ }
1161
+ const bytes = envelopeBodies.join("\n");
1162
+ expect(bytes).not.toContain("LEAK");
1163
+ expect(bytes).not.toContain("10.26.0");
1164
+ });
1165
+ it.each([
1166
+ ["python", { app: "pipenv run python main.py" }, {}, "pipenv"],
1167
+ ["python", { app: "python3 main.py" }, {}, "pip"],
1168
+ ["java", {}, { "build.gradle": "" }, "gradle"],
1169
+ ["java", {}, { "pom.xml": "" }, "maven"],
1170
+ ["csharp", {}, {}, "nuget"],
1171
+ ["go", {}, {}, "go"],
1172
+ ])("reports a %s project with %j and files %j as %p", async (language, config, files, expected) => {
1173
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1174
+ language,
1175
+ ...config,
1176
+ });
1177
+ for (const [name, content] of Object.entries(files)) {
1178
+ fs.writeFileSync(path.join(workdir, name), content);
1179
+ }
1180
+ for (const item of await runMetrics()) {
1181
+ expect(attributeValues(item).package_manager).toBe(expected);
1182
+ }
1183
+ });
1184
+ it.each([
1185
+ ["no cdktf.json", undefined],
1186
+ ["an unsupported language", { language: "rust" }],
1187
+ ["no language", { app: "pipenv run python main.py" }],
1188
+ ["a python project without an app command", { language: "python" }],
1189
+ ])("omits the attribute with %s", async (_name, cdktfJson) => {
1190
+ if (cdktfJson) {
1191
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), cdktfJson);
1192
+ }
1193
+ // lockfiles alone never identify a project
1194
+ fs.writeFileSync(path.join(workdir, "pnpm-lock.yaml"), "");
1195
+ fs.writeFileSync(path.join(workdir, "build.gradle"), "");
1196
+ for (const item of await runMetrics()) {
1197
+ expect(item.attributes).not.toHaveProperty("package_manager");
1198
+ }
1199
+ });
1200
+ it("keeps the value detected at start when the cwd changes before the end", async () => {
1201
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1202
+ language: "typescript",
1203
+ });
1204
+ fs.writeFileSync(path.join(workdir, "pnpm-lock.yaml"), "");
1205
+ const elsewhere = fs.mkdtempSync(path.join(os.tmpdir(), "cdktn-else-"));
1206
+ try {
1207
+ await (0, telemetry_1.startCommandTelemetry)("convert");
1208
+ process.chdir(elsewhere);
1209
+ await (0, telemetry_1.sendTelemetry)("convert", {});
1210
+ await (0, telemetry_1.sendTelemetry)("convert", { error: true });
1211
+ expect(await Sentry.flush(2000)).toBe(true);
1212
+ }
1213
+ finally {
1214
+ process.chdir(workdir);
1215
+ fs.removeSync(elsewhere);
1216
+ }
1217
+ const items = parseMetricItems(envelopeBodies);
1218
+ expect(items).toHaveLength(3);
1219
+ for (const item of items) {
1220
+ expect(attributeValues(item).package_manager).toBe("pnpm");
1221
+ }
1222
+ });
1223
+ it("forgets the value with the run", async () => {
1224
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), { language: "go" });
1225
+ await (0, telemetry_1.startCommandTelemetry)("synth");
1226
+ (0, telemetry_1.resetCommandTelemetry)();
1227
+ await (0, telemetry_1.sendTelemetry)("synth", {});
1228
+ expect(await Sentry.flush(2000)).toBe(true);
1229
+ const completed = parseMetricItems(envelopeBodies).find((i) => i.name === "cli.command.completed");
1230
+ expect(completed.attributes).not.toHaveProperty("package_manager");
1231
+ });
1232
+ it("omits a detector value outside the closed set", async () => {
1233
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1234
+ language: "typescript",
1235
+ });
1236
+ const telemetry = telemetryWithNodeDetector(() => "bun@1.1.0 /Users/x");
1237
+ for (const item of await runMetrics(telemetry)) {
1238
+ expect(item.attributes).not.toHaveProperty("package_manager");
1239
+ }
1240
+ expect(envelopeBodies.join("\n")).not.toContain("bun");
1241
+ });
1242
+ it("omits the attribute when detection throws", async () => {
1243
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1244
+ language: "typescript",
1245
+ });
1246
+ const telemetry = telemetryWithNodeDetector(() => {
1247
+ throw new Error("EACCES");
1248
+ });
1249
+ for (const item of await runMetrics(telemetry)) {
1250
+ expect(item.attributes).not.toHaveProperty("package_manager");
1251
+ }
1252
+ });
1253
+ it("normalizes to members of the closed set only", () => {
1254
+ for (const name of telemetry_1.PACKAGE_MANAGERS) {
1255
+ expect((0, telemetry_1.normalizePackageManager)(name)).toBe(name);
1256
+ }
1257
+ for (const value of [
1258
+ "bun",
1259
+ "NPM",
1260
+ "pnpm@10.26.0+sha512.abc",
1261
+ "/usr/local/bin/npm",
1262
+ "",
1263
+ 1,
1264
+ null,
1265
+ undefined,
1266
+ ["npm"],
1267
+ ]) {
1268
+ expect((0, telemetry_1.normalizePackageManager)(value)).toBeUndefined();
1269
+ }
1270
+ });
1271
+ });
1272
+ describe("run lifecycle", () => {
1273
+ beforeEach(() => {
1274
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1275
+ language: "python",
1276
+ sendUsageTelemetry: true,
1277
+ });
1278
+ initSentryWithCapturingTransport();
1279
+ });
1280
+ it("counts the run once as invoked at start, even when reporting is initialized again", async () => {
1281
+ await (0, telemetry_1.startCommandTelemetry)("init");
1282
+ // init runs get, which initializes reporting a second time
1283
+ await (0, telemetry_1.startCommandTelemetry)("get");
1284
+ expect(await Sentry.flush(2000)).toBe(true);
1285
+ const items = parseMetricItems(envelopeBodies);
1286
+ expect(items.map((i) => i.name)).toEqual(["cli.command.invoked"]);
1287
+ expect(attributeValues(items[0])).toMatchObject({
1288
+ command: "init",
1289
+ language: "python",
1290
+ });
1291
+ });
1292
+ it("counts only the run's own command as completed; a nested operation adds its own metrics", async () => {
1293
+ await (0, telemetry_1.startCommandTelemetry)("deploy");
1294
+ await (0, telemetry_1.sendTelemetry)("synth", { totalTime: 42, language: "python" });
1295
+ await (0, telemetry_1.sendTelemetry)("deploy", { language: "python" });
1296
+ expect(await Sentry.flush(2000)).toBe(true);
1297
+ const items = parseMetricItems(envelopeBodies);
1298
+ expect(items.map((i) => [i.name, attributeValues(i).command])).toEqual([
1299
+ ["cli.command.invoked", "deploy"],
1300
+ ["cli.synth.duration", "synth"],
1301
+ ["cli.command.completed", "deploy"],
1302
+ ]);
1303
+ });
1304
+ it("counts a failed run once as error, never as completed", async () => {
1305
+ await (0, telemetry_1.startCommandTelemetry)("synth");
1306
+ await (0, telemetry_1.sendTelemetry)("synth", { error: true, errorType: "External" });
1307
+ expect(await Sentry.flush(2000)).toBe(true);
1308
+ expect(parseMetricItems(envelopeBodies).map((i) => i.name)).toEqual([
1309
+ "cli.command.invoked",
1310
+ "cli.command.error",
1311
+ ]);
1312
+ });
1313
+ it("emits nothing at start when usage telemetry is off, and stays a no-op afterwards", async () => {
1314
+ (0, telemetry_1.setUsageTelemetryEnabled)(false);
1315
+ await (0, telemetry_1.startCommandTelemetry)("synth");
1316
+ (0, telemetry_1.setUsageTelemetryEnabled)(true);
1317
+ await (0, telemetry_1.startCommandTelemetry)("synth");
1318
+ await Sentry.flush(2000);
1319
+ expect(parseMetricItems(envelopeBodies)).toHaveLength(0);
1320
+ });
1321
+ });
1322
+ // the bundle has one copy of this module per entry point: bin/cmds/handlers.js
1323
+ // captures the decision and starts the run, bin/cdktn.js counts the failure
1324
+ describe("shared across module copies", () => {
1325
+ let second;
1326
+ beforeEach(() => {
1327
+ jest.isolateModules(() => {
1328
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
1329
+ second = require("./telemetry");
1330
+ });
1331
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1332
+ language: "go",
1333
+ sendUsageTelemetry: true,
1334
+ });
1335
+ initSentryWithCapturingTransport();
1336
+ });
1337
+ it("observes the captured decision and targets, the started command and its language from the other copy", async () => {
1338
+ // the project opts out; only the decision captured by the first copy
1339
+ // lets the second one emit
1340
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1341
+ language: "go",
1342
+ sendUsageTelemetry: false,
1343
+ });
1344
+ (0, telemetry_1.setUsageTelemetryEnabled)(true);
1345
+ (0, telemetry_1.setProjectTargetAttributes)({ target_opentofu: ">=1.7.0" });
1346
+ await (0, telemetry_1.startCommandTelemetry)("deploy");
1347
+ await second.startCommandTelemetry("synth");
1348
+ await second.sendTelemetry("synth", { language: "go" });
1349
+ await second.sendTelemetry("deploy", { error: true, errorType: "Usage" });
1350
+ expect(await Sentry.flush(2000)).toBe(true);
1351
+ const items = parseMetricItems(envelopeBodies);
1352
+ expect(items.map((i) => [i.name, attributeValues(i).command])).toEqual([
1353
+ ["cli.command.invoked", "deploy"],
1354
+ ["cli.command.error", "deploy"],
1355
+ ]);
1356
+ expect(attributeValues(items[1])).toMatchObject({
1357
+ language: "go",
1358
+ package_manager: "go",
1359
+ target_opentofu: ">=1.7.0",
1360
+ });
1361
+ expect(items[1].attributes).not.toHaveProperty("target_terraform");
1362
+ });
1363
+ });
1364
+ describe("sendTelemetry gating", () => {
1365
+ it.each([
1366
+ { env: undefined, captured: undefined, flag: undefined, emits: true },
1367
+ { env: undefined, captured: undefined, flag: true, emits: true },
1368
+ { env: undefined, captured: undefined, flag: false, emits: false },
1369
+ // convert chdirs into a throwaway project that opts out
1370
+ { env: undefined, captured: true, flag: false, emits: true },
1371
+ { env: undefined, captured: false, flag: true, emits: false },
1372
+ { env: "1", captured: undefined, flag: true, emits: false },
1373
+ { env: "1", captured: true, flag: true, emits: false },
1374
+ ])("CHECKPOINT_DISABLE=$env, captured=$captured, flag=$flag -> emits $emits", async ({ env, captured, flag, emits }) => {
1375
+ if (flag !== undefined) {
1376
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1377
+ sendUsageTelemetry: flag,
1378
+ });
1379
+ }
1380
+ initSentryWithCapturingTransport();
1381
+ (0, telemetry_1.setUsageTelemetryEnabled)(captured);
1382
+ if (env !== undefined) {
1383
+ process.env.CHECKPOINT_DISABLE = env;
1384
+ }
1385
+ await (0, telemetry_1.startCommandTelemetry)("convert");
1386
+ await (0, telemetry_1.sendTelemetry)("convert", {});
1387
+ await Sentry.flush(2000);
1388
+ const items = parseMetricItems(envelopeBodies);
1389
+ expect(items.some((i) => i.name === "cli.command.invoked")).toBe(emits);
1390
+ expect(items.some((i) => i.name === "cli.command.completed")).toBe(emits);
1391
+ if (!emits) {
1392
+ expect(items).toHaveLength(0);
1393
+ }
1394
+ });
1395
+ });
1396
+ describe("cli.error from the Errors factories", () => {
1397
+ afterEach(() => {
1398
+ errors_1.Errors.setScope("unknown");
1399
+ });
1400
+ // the scope is read when the error is built, not when the factory is
1401
+ // created: a factory-time binding reports every error as "unknown"
1402
+ it("counts constructed errors by type with the command set at call time", async () => {
1403
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1404
+ sendUsageTelemetry: true,
1405
+ });
1406
+ initSentryWithCapturingTransport();
1407
+ errors_1.Errors.setScope("deploy");
1408
+ errors_1.Errors.Usage("no stacks selected", undefined, { stackName: "secret" });
1409
+ errors_1.Errors.External("terraform exited with code 1");
1410
+ expect(await Sentry.flush(2000)).toBe(true);
1411
+ const errors = parseMetricItems(envelopeBodies).filter((i) => i.name === "cli.error");
1412
+ expect(errors).toHaveLength(2);
1413
+ expect(errors.map((e) => e.attributes.type.value)).toEqual([
1414
+ "Usage",
1415
+ "External",
1416
+ ]);
1417
+ for (const error of errors) {
1418
+ expect(error.attributes.command.value).toBe("deploy");
1419
+ expect(error.attributes).not.toHaveProperty("message");
1420
+ expect(error.attributes).not.toHaveProperty("stackName");
1421
+ }
1422
+ expect(JSON.stringify(errors)).not.toContain("secret");
1423
+ expect(JSON.stringify(errors)).not.toContain("no stacks selected");
1424
+ });
1425
+ });
1426
+ describe("binary attributes", () => {
1427
+ async function invokedAttributes(versionOutput) {
1428
+ (0, terraform_1.seedTerraformCliProbeForTests)(Promise.resolve(versionOutput));
1429
+ initSentryWithCapturingTransport();
1430
+ await (0, telemetry_1.startCommandTelemetry)("synth");
1431
+ expect(await Sentry.flush(2000)).toBe(true);
1432
+ return attributeValues(parseMetricItems(envelopeBodies)[0]);
1433
+ }
1434
+ it.each([
1435
+ ["Terraform v1.10.0-alpha20250101", "terraform", "1.10.0"],
1436
+ [
1437
+ "OpenTofu v1.2.3-LEAK-HOST.corp.example.com+LEAK-BUILD/Users/x",
1438
+ "opentofu",
1439
+ "1.2.3",
1440
+ ],
1441
+ ])("reduces the probed version of %p to its release", async (versionOutput, binary, release) => {
1442
+ expect(await invokedAttributes(versionOutput)).toMatchObject({
1443
+ binary,
1444
+ binary_version: release,
1445
+ });
1446
+ expect(envelopeBodies.join("\n")).not.toContain("LEAK");
1447
+ });
1448
+ it("sends no version for an unrecognised product: a wrapper's output has no product version line", async () => {
1449
+ const attributes = await invokedAttributes("connected to 10.0.0.1 as LEAK-USER (wrapper 3.4.5)\nTerraform v1.9.0\n");
1450
+ expect(attributes.binary).toBe("unknown");
1451
+ expect(attributes).not.toHaveProperty("binary_version");
1452
+ expect(envelopeBodies.join("\n")).not.toContain("LEAK-USER");
1453
+ });
1454
+ });
1455
+ describe("getProjectTargetAttributes", () => {
1456
+ it("reads declared targets and the validation flag", () => {
1457
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), {
1458
+ targetVersions: { opentofu: "~1.8" },
1459
+ validateInstalledBinary: true,
1460
+ });
1461
+ expect((0, telemetry_1.getProjectTargetAttributes)(workdir)).toEqual({
1462
+ targets_declared: true,
1463
+ validate_installed_binary: true,
1464
+ target_opentofu: ">=1.8.0 <1.9.0-0",
1465
+ });
1466
+ });
1467
+ it.each([
1468
+ [{}],
1469
+ [{ targetVersions: "nope" }],
1470
+ [{ targetVersions: [] }],
1471
+ [undefined],
1472
+ ])("falls back to the defaults for a cdktf.json of %j", (config) => {
1473
+ if (config) {
1474
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), config);
1475
+ }
1476
+ expect((0, telemetry_1.getProjectTargetAttributes)(workdir)).toEqual({
1477
+ targets_declared: false,
1478
+ validate_installed_binary: false,
1479
+ ...DEFAULT_TARGET_VERSIONS_AS_ATTRIBUTES,
1480
+ });
1481
+ });
1482
+ });
1483
+ describe("getUsageTelemetryConsent", () => {
1484
+ it.each([
1485
+ // init templates render the flag as a string; a boolean-only check
1486
+ // would opt every freshly init'ed project out
1487
+ [{ sendUsageTelemetry: "true" }, true],
1488
+ [{ sendUsageTelemetry: "false" }, false],
1489
+ [{}, undefined],
1490
+ // malformed is unset, not an opt-out
1491
+ [{ sendUsageTelemetry: "yes" }, undefined],
1492
+ ])("reads %j as %p", (config, expected) => {
1493
+ fs.writeJsonSync(path.join(workdir, "cdktf.json"), config);
1494
+ expect((0, telemetry_1.getUsageTelemetryConsent)(workdir)).toBe(expected);
1495
+ });
1496
+ it("returns undefined when no cdktf.json exists", () => {
1497
+ expect((0, telemetry_1.getUsageTelemetryConsent)(workdir)).toBeUndefined();
1498
+ });
1499
+ });
1500
+ });
1501
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVsZW1ldHJ5LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdGVsZW1ldHJ5LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLHFEQUF1QztBQUN2Qyw2Q0FBK0I7QUFDL0IsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUM3QiwyQ0FVcUI7QUFDckIsMkNBQTREO0FBQzVELHFDQUtrQjtBQUNsQixxRUFHa0M7QUFDbEMscUNBQWtDO0FBRWxDLE1BQU0scUNBQXFDLEdBQUc7SUFDNUMsZ0JBQWdCLEVBQUUsZ0NBQXVCLENBQUMsU0FBUztJQUNuRCxlQUFlLEVBQUUsZ0NBQXVCLENBQUMsUUFBUTtDQUNsRCxDQUFDO0FBYUYsNkVBQTZFO0FBQzdFLG9CQUFvQjtBQUNwQixTQUFTLGdCQUFnQixDQUFDLGNBQXdCO0lBQ2hELE1BQU0sS0FBSyxHQUFpQixFQUFFLENBQUM7SUFDL0IsS0FBSyxNQUFNLElBQUksSUFBSSxjQUFjLEVBQUUsQ0FBQztRQUNsQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMxQyxJQUFJLE1BQU0sQ0FBQztZQUNYLElBQUksQ0FBQztnQkFDSCxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoQyxDQUFDO1lBQUMsV0FBTSxDQUFDO2dCQUNQLFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGNBQWMsRUFBRSxDQUFDO2dCQUNu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RCxNQUFNLENBQUMsSUFBQSxvQ0FBd0IsRUFBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgSGFzaGlDb3JwLCBJbmNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNUEwtMi4wXG5pbXBvcnQgKiBhcyBTZW50cnkgZnJvbSBcIkBzZW50cnkvbm9kZVwiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzLWV4dHJhXCI7XG5pbXBvcnQgKiBhcyBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7XG4gIHNlbmRUZWxlbWV0cnksXG4gIHN0YXJ0Q29tbWFuZFRlbGVtZXRyeSxcbiAgcmVzZXRDb21tYW5kVGVsZW1ldHJ5LFxuICBnZXRQcm9qZWN0VGFyZ2V0QXR0cmlidXRlcyxcbiAgZ2V0VXNhZ2VUZWxlbWV0cnlDb25zZW50LFxuICBub3JtYWxpemVQYWNrYWdlTWFuYWdlcixcbiAgUEFDS0FHRV9NQU5BR0VSUyxcbiAgc2V0UHJvamVjdFRhcmdldEF0dHJpYnV0ZXMsXG4gIHNldFVzYWdlVGVsZW1ldHJ5RW5hYmxlZCxcbn0gZnJvbSBcIi4vdGVsZW1ldHJ5XCI7XG5pbXBvcnQgeyBzZWVkVGVycmFmb3JtQ2xpUHJvYmVGb3JUZXN0cyB9IGZyb20gXCIuL3RlcnJhZm9ybVwiO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9UQVJHRVRfVkVSU0lPTlMsXG4gIExhbmd1YWdlLFxuICBUZXJyYWZvcm1Nb2R1bGVDb25zdHJhaW50LFxuICBUZXJyYWZvcm1Qcm92aWRlckNvbnN0cmFpbnQsXG59IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0c01ha2VyTW9kdWxlVGFyZ2V0LFxuICBDb25zdHJ1Y3RzTWFrZXJQcm92aWRlclRhcmdldCxcbn0gZnJvbSBcIi4vY29uc3RydWN0LW1ha2VyLXRhcmdldFwiO1xuaW1wb3J0IHsgRXJyb3JzIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5cbmNvbnN0IERFRkFVTFRfVEFSR0VUX1ZFUlNJT05TX0FTX0FUVFJJQlVURVMgPSB7XG4gIHRhcmdldF90ZXJyYWZvcm06IERFRkFVTFRfVEFSR0VUX1ZFUlNJT05TLnRlcnJhZm9ybSxcbiAgdGFyZ2V0X29wZW50b2Z1OiBERUZBVUxUX1RBUkdFVF9WRVJTSU9OUy5vcGVudG9mdSxcbn07XG5cbi8vIEEgcmVhbCBjbGllbnQgd2l0aCBhIGNhcHR1cmluZyB0cmFuc3BvcnQgcHJvdmVzIHRoZSBtZXRyaWMgZW52ZWxvcGVcbi8vIHJlYWNoZXMgdGhlIHRyYW5zcG9ydCBhbmQgc3Vydml2ZXMgYSBib3VuZGVkIGZsdXNoOyBhIG1vY2tlZCBAc2VudHJ5L25vZGVcbi8vIHdvdWxkIHBhc3MgZXZlbiBpZiBtZXRyaWNzIHdlcmUgZHJvcHBlZCBiZWZvcmUgZXhpdC5cblxudHlwZSBNZXRyaWNJdGVtID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgdmFsdWU6IG51bWJlcjtcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgeyB2YWx1ZTogdW5rbm93bjsgdHlwZTogc3RyaW5nIH0+O1xufTtcblxuLy8gTWlycm9ycyByZWNvcmRFbnZlbG9wZSBpbiB0b29scy9zZW50cnktc2luay5tanM6IGFuIGVudmVsb3BlLWZvcm1hdCBjaGFuZ2Vcbi8vIGlzIGZpeGVkIGluIGJvdGguXG5mdW5jdGlvbiBwYXJzZU1ldHJpY0l0ZW1zKGVudmVsb3BlQm9kaWVzOiBzdHJpbmdbXSk6IE1ldHJpY0l0ZW1bXSB7XG4gIGNvbnN0IGl0ZW1zOiBNZXRyaWNJdGVtW10gPSBbXTtcbiAgZm9yIChjb25zdCBib2R5IG9mIGVudmVsb3BlQm9kaWVzKSB7XG4gICAgY29uc3QgbGluZXMgPSBib2R5LnNwbGl0KFwiXFxuXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgbGV0IGhlYWRlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGhlYWRlciA9IEpTT04ucGFyc2UobGluZXNbaV0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGhlYWRlci50eXBlID09PSBcInRyYWNlX21ldHJpY1wiKSB7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBKU09OLnBhcnNlKGxpbmVzW2kgKyAxXSk7XG4gICAgICAgIGl0ZW1zLnB1c2goLi4ucGF5bG9hZC5pdGVtcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBpdGVtcztcbn1cblxuZnVuY3Rpb24gYXR0cmlidXRlVmFsdWVzKGl0ZW06IE1ldHJpY0l0ZW0pIHtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBPYmplY3QuZW50cmllcyhpdGVtLmF0dHJpYnV0ZXMpLm1hcCgoW2ssIHZdKSA9PiBbaywgdi52YWx1ZV0pLFxuICApO1xufVxuXG4vLyBPbiBldmVyeSBtZXRyaWMgb2YgYSBjb21tYW5kOyB0aGUgZXhhY3Qgc2V0IGlzIHBpbm5lZCBvbmNlLCBvblxuLy8gY2xpLmNvbW1hbmQuY29tcGxldGVkLlxuY29uc3QgQ09NTUFORF9BVFRSSUJVVEVTID0gW1xuICBcImFyY2hcIixcbiAgXCJiaW5hcnlcIixcbiAgXCJiaW5hcnlfdmVyc2lvblwiLFxuICBcImNpXCIsXG4gIFwiY29tbWFuZFwiLFxuICBcImxhbmd1YWdlXCIsXG4gIFwib3NcIixcbiAgXCJwYWNrYWdlX21hbmFnZXJcIixcbiAgXCJzZXJ2ZXIuYWRkcmVzc1wiLFxuICBcInRhcmdldF9vcGVudG9mdVwiLFxuICBcInRhcmdldF90ZXJyYWZvcm1cIixcbiAgXCJ0YXJnZXRzX2RlY2xhcmVkXCIsXG4gIFwidmFsaWRhdGVfaW5zdGFsbGVkX2JpbmFyeVwiLFxuXTtcblxuLy8gRWFjaCBtZXRyaWMgb2YgdGhhdCBuYW1lIGFzIGl0cyB2YWx1ZSBwbHVzIGV4YWN0bHkgdGhlIGF0dHJpYnV0ZXMgaXQgYWRkc1xuLy8gdG8gdGhlIGNvbW1hbmQncywgc28gYHRvRXF1YWxgIGZhaWxzIG9uIGFueSBhdHRyaWJ1dGUgdGhhdCBpcyBub3QgbGlzdGVkLlxuZnVuY3Rpb24gbWV0cmljcyhpdGVtczogTWV0cmljSXRlbVtdLCBuYW1lOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10ge1xuICByZXR1cm4gaXRlbXNcbiAgICAuZmlsdGVyKChpdGVtKSA9PiBpdGVtLm5hbWUgPT09IG5hbWUpXG4gICAgLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgIHZhbHVlOiBpdGVtLnZhbHVlLFxuICAgICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVWYWx1ZXMoaXRlbSkpLmZpbHRlcihcbiAgICAgICAgICAoW2tleV0pID0+XG4gICAgICAgICAgICAha2V5LnN0YXJ0c1dpdGgoXCJzZW50cnkuXCIpICYmICFDT01NQU5EX0FUVFJJQlVURVMuaW5jbHVkZXMoa2V5KSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgfSkpO1xufVxuXG5kZXNjcmliZShcInRlbGVtZXRyeVwiLCAoKSA9PiB7XG4gIGxldCB3b3JrZGlyOiBzdHJpbmc7XG4gIGxldCBlbnZlbG9wZUJvZGllczogc3RyaW5nW107XG4gIGNvbnN0IG9yaWdpbmFsQ3dkID0gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3Qgb3JpZ2luYWxDaGVja3BvaW50RGlzYWJsZSA9IHByb2Nlc3MuZW52LkNIRUNLUE9JTlRfRElTQUJMRTtcbiAgY29uc3Qgb3JpZ2luYWxTZW50cnlFbnZpcm9ubWVudCA9IHByb2Nlc3MuZW52LlNFTlRSWV9FTlZJUk9OTUVOVDtcblxuICBmdW5jdGlvbiBpbml0U2VudHJ5V2l0aENhcHR1cmluZ1RyYW5zcG9ydCgpIHtcbiAgICBTZW50cnkuaW5pdCh7XG4gICAgICBkc246IFwiaHR0cHM6Ly9wdWJsaWNAZXhhbXBsZS5pbnZhbGlkLzFcIixcbiAgICAgIHJlbGVhc2U6IFwiY2RrdG4tY2xpLXRlc3RcIixcbiAgICAgIGVudmlyb25tZW50OiBcInByb2R1Y3Rpb25cIixcbiAgICAgIHRyYWNlc1NhbXBsZVJhdGU6IDAsXG4gICAgICBzZXJ2ZXJOYW1lOiBcImNka3RuLWNsaVwiLFxuICAgICAgLy8gZWFjaCB0ZXN0IGluaXRzIGl0cyBvd24gY2xpZW50OyBwcm9jZXNzLWxldmVsIGludGVncmF0aW9ucyB3b3VsZFxuICAgICAgLy8gcGlsZSB1cCBsaXN0ZW5lcnMgYWNyb3NzIHRlc3RzIGFuZCBhcmUgaXJyZWxldmFudCB0byBtZXRyaWNzXG4gICAgICBkZWZhdWx0SW50ZWdyYXRpb25zOiBmYWxzZSxcbiAgICAgIHRyYW5zcG9ydDogKG9wdGlvbnMpID0+XG4gICAgICAgIFNlbnRyeS5jcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgICBlbnZlbG9wZUJvZGllcy5wdXNoKHJlcXVlc3QuYm9keSBhcyBzdHJpbmcpO1xuICAgICAgICAgIHJldHVybiB7IHN0YXR1c0NvZGU6IDIwMCB9O1xuICAgICAgICB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRlbGl2ZXJlZEl0ZW1zKCk6IFByb21pc2U8TWV0cmljSXRlbVtdPiB7XG4gICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcbiAgICByZXR1cm4gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcyk7XG4gIH1cblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICB3b3JrZGlyID0gZnMubWtkdGVtcFN5bmMocGF0aC5qb2luKG9zLnRtcGRpcigpLCBcImNka3RuLXRlbGVtZXRyeS1cIikpO1xuICAgIHByb2Nlc3MuY2hkaXIod29ya2Rpcik7XG4gICAgZW52ZWxvcGVCb2RpZXMgPSBbXTtcbiAgICBkZWxldGUgcHJvY2Vzcy5lbnYuQ0hFQ0tQT0lOVF9ESVNBQkxFO1xuICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5TRU5UUllfRU5WSVJPTk1FTlQ7XG4gICAgLy8gdGhlIHByb2JlIGlzIHByb2Nlc3MtZ2xvYmFsIChzZWUgdGVycmFmb3JtLnRzKTsgYSBzZWVkZWQgb3V0cHV0IGtlZXBzXG4gICAgLy8gdGhlIGJpbmFyeSBhdHRyaWJ1dGVzIGluZGVwZW5kZW50IG9mIHRoZSBtYWNoaW5lIHJ1bm5pbmcgdGhlIHRlc3RzXG4gICAgc2VlZFRlcnJhZm9ybUNsaVByb2JlRm9yVGVzdHMoXG4gICAgICBQcm9taXNlLnJlc29sdmUoXCJUZXJyYWZvcm0gdjEuOS4wXFxub24gZGFyd2luX2FybTY0XFxuXCIpLFxuICAgICk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChhc3luYyAoKSA9PiB7XG4gICAgc2V0VXNhZ2VUZWxlbWV0cnlFbmFibGVkKHVuZGVmaW5lZCk7XG4gICAgcmVzZXRDb21tYW5kVGVsZW1ldHJ5KCk7XG4gICAgc2V0UHJvamVjdFRhcmdldEF0dHJpYnV0ZXModW5kZWZpbmVkKTtcbiAgICBzZWVkVGVycmFmb3JtQ2xpUHJvYmVGb3JUZXN0cygpO1xuICAgIGF3YWl0IFNlbnRyeS5jbG9zZSgxMDAwKTtcbiAgICBwcm9jZXNzLmNoZGlyKG9yaWdpbmFsQ3dkKTtcbiAgICBmcy5yZW1vdmVTeW5jKHdvcmtkaXIpO1xuICAgIGlmIChvcmlnaW5hbENoZWNrcG9pbnREaXNhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5DSEVDS1BPSU5UX0RJU0FCTEU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2Nlc3MuZW52LkNIRUNLUE9JTlRfRElTQUJMRSA9IG9yaWdpbmFsQ2hlY2twb2ludERpc2FibGU7XG4gICAgfVxuICAgIGlmIChvcmlnaW5hbFNlbnRyeUVudmlyb25tZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5TRU5UUllfRU5WSVJPTk1FTlQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2Nlc3MuZW52LlNFTlRSWV9FTlZJUk9OTUVOVCA9IG9yaWdpbmFsU2VudHJ5RW52aXJvbm1lbnQ7XG4gICAgfVxuICB9KTtcblxuICBkZXNjcmliZShcInNlbmRUZWxlbWV0cnkgZGVsaXZlcnkgKHJlYWwgY2xpZW50ICsgY2FwdHVyaW5nIHRyYW5zcG9ydClcIiwgKCkgPT4ge1xuICAgIGl0KFwic3RhbXBzIHRoZSBjb21tYW5kLCBsYW5ndWFnZSwgYmluYXJ5IGFuZCB0YXJnZXQgYXR0cmlidXRlcyBvbiBldmVyeSBjb21tYW5kIG1ldHJpY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgICBzZW5kVXNhZ2VUZWxlbWV0cnk6IHRydWUsXG4gICAgICAgIHRhcmdldFZlcnNpb25zOiB7IHRlcnJhZm9ybTogXCI+PTEuOS4wXCIsIG9wZW50b2Z1OiBcIj49MS44LjBcIiB9LFxuICAgICAgICB2YWxpZGF0ZUluc3RhbGxlZEJpbmFyeTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgaW5pdFNlbnRyeVdpdGhDYXB0dXJpbmdUcmFuc3BvcnQoKTtcblxuICAgICAgYXdhaXQgc3RhcnRDb21tYW5kVGVsZW1ldHJ5KFwic3ludGhcIik7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwic3ludGhcIiwgeyB0b3RhbFRpbWU6IDEyMzQsIGxhbmd1YWdlOiBcInR5cGVzY3JpcHRcIiB9KTtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7IGVycm9yOiB0cnVlLCBzeW50aE9yaWdpbjogXCJ3YXRjaFwiIH0pO1xuICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBwYXJzZU1ldHJpY0l0ZW1zKGVudmVsb3BlQm9kaWVzKTtcbiAgICAgIGV4cGVjdChpdGVtcy5tYXAoKGkpID0+IGkubmFtZSkpLnRvRXF1YWwoW1xuICAgICAgICBcImNsaS5jb21tYW5kLmludm9rZWRcIixcbiAgICAgICAgXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIixcbiAgICAgICAgXCJjbGkuc3ludGguZHVyYXRpb25cIixcbiAgICAgICAgXCJjbGkuY29tbWFuZC5lcnJvclwiLFxuICAgICAgXSk7XG4gICAgICBjb25zdCBbaW52b2tlZCwgY29tcGxldGVkLCBkdXJhdGlvbiwgZXJyb3JdID0gaXRlbXM7XG5cbiAgICAgIGZvciAoY29uc3QgbWV0cmljIG9mIGl0ZW1zKSB7XG4gICAgICAgIGV4cGVjdChhdHRyaWJ1dGVWYWx1ZXMobWV0cmljKSkudG9NYXRjaE9iamVjdCh7XG4gICAgICAgICAgY29tbWFuZDogXCJzeW50aFwiLFxuICAgICAgICAgIG9zOiBwcm9jZXNzLnBsYXRmb3JtLFxuICAgICAgICAgIGFyY2g6IHByb2Nlc3MuYXJjaCxcbiAgICAgICAgICBiaW5hcnk6IFwidGVycmFmb3JtXCIsXG4gICAgICAgICAgYmluYXJ5X3ZlcnNpb246IFwiMS45LjBcIixcbiAgICAgICAgICB0YXJnZXRfdGVycmFmb3JtOiBcIj49MS45LjBcIixcbiAgICAgICAgICB0YXJnZXRfb3BlbnRvZnU6IFwiPj0xLjguMFwiLFxuICAgICAgICAgIHRhcmdldHNfZGVjbGFyZWQ6IHRydWUsXG4gICAgICAgICAgdmFsaWRhdGVfaW5zdGFsbGVkX2JpbmFyeTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyB0aGUgbGFuZ3VhZ2UgY29tZXMgZnJvbSBjZGt0Zi5qc29uIGF0IHN0YXJ0IGFuZCBmcm9tIHRoZSBwYXlsb2FkXG4gICAgICAvLyBhdCB0aGUgZW5kOyB0aGUgZXJyb3IgbWV0cmljIGhhcyBubyBwYXlsb2FkIGFuZCByZXVzZXMgdGhlIHN0YXJ0IHJlYWRcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVWYWx1ZXMoaW52b2tlZCkubGFuZ3VhZ2UpLnRvQmUoXCJ0eXBlc2NyaXB0XCIpO1xuICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhjb21wbGV0ZWQpLmxhbmd1YWdlKS50b0JlKFwidHlwZXNjcmlwdFwiKTtcbiAgICAgIGV4cGVjdChkdXJhdGlvbi50eXBlKS50b0JlKFwiZGlzdHJpYnV0aW9uXCIpO1xuICAgICAgZXhwZWN0KGR1cmF0aW9uLnZhbHVlKS50b0JlKDEyMzQpO1xuICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhlcnJvcikpLnRvTWF0Y2hPYmplY3Qoe1xuICAgICAgICBlcnJvcl90eXBlOiBcInVuZXhwZWN0ZWRcIixcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgICBzeW50aF9vcmlnaW46IFwid2F0Y2hcIixcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJ1c2VzIHRoZSB0YXJnZXQgYXR0cmlidXRlcyBjYXB0dXJlZCBhdCBjb21tYW5kIHN0YXJ0IG92ZXIgdGhlIGN1cnJlbnQgY3dkXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICB0YXJnZXRWZXJzaW9uczogeyB0ZXJyYWZvcm06IFwiPj0xLjAuMFwiIH0sXG4gICAgICB9KTtcbiAgICAgIGluaXRTZW50cnlXaXRoQ2FwdHVyaW5nVHJhbnNwb3J0KCk7XG4gICAgICBzZXRQcm9qZWN0VGFyZ2V0QXR0cmlidXRlcyh7XG4gICAgICAgIHRhcmdldHNfZGVjbGFyZWQ6IHRydWUsXG4gICAgICAgIHZhbGlkYXRlX2luc3RhbGxlZF9iaW5hcnk6IGZhbHNlLFxuICAgICAgICB0YXJnZXRfb3BlbnRvZnU6IFwiPj0xLjcuMFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcImNvbnZlcnRcIik7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiY29udmVydFwiLCB7fSk7XG4gICAgICBleHBlY3QoYXdhaXQgU2VudHJ5LmZsdXNoKDIwMDApKS50b0JlKHRydWUpO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpO1xuICAgICAgZXhwZWN0KGl0ZW1zLm1hcCgoaSkgPT4gaS5uYW1lKSkudG9FcXVhbChbXG4gICAgICAgIFwiY2xpLmNvbW1hbmQuaW52b2tlZFwiLFxuICAgICAgICBcImNsaS5jb21tYW5kLmNvbXBsZXRlZFwiLFxuICAgICAgXSk7XG4gICAgICBmb3IgKGNvbnN0IG1ldHJpYyBvZiBpdGVtcykge1xuICAgICAgICBleHBlY3QobWV0cmljLmF0dHJpYnV0ZXMudGFyZ2V0X29wZW50b2Z1LnZhbHVlKS50b0JlKFwiPj0xLjcuMFwiKTtcbiAgICAgICAgZXhwZWN0KG1ldHJpYy5hdHRyaWJ1dGVzLnRhcmdldF90ZXJyYWZvcm0pLnRvQmVVbmRlZmluZWQoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW1wiVXNhZ2VcIiwgXCJVc2FnZVwiXSxcbiAgICAgIFtcIkV4dGVybmFsXCIsIFwiRXh0ZXJuYWxcIl0sXG4gICAgICBbXCJJbnRlcm5hbFwiLCBcIkludGVybmFsXCJdLFxuICAgICAgW1wiU29tZXRoaW5nIEVsc2VcIiwgXCJ1bmV4cGVjdGVkXCJdLFxuICAgIF0pKFxuICAgICAgXCJzdGFtcHMgZXJyb3JfdHlwZSAlcCBhcyAlcCBvbiBjbGkuY29tbWFuZC5lcnJvclwiLFxuICAgICAgYXN5bmMgKGVycm9yVHlwZSwgZXhwZWN0ZWQpID0+IHtcbiAgICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgICAgc2VuZFVzYWdlVGVsZW1ldHJ5OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgaW5pdFNlbnRyeVdpdGhDYXB0dXJpbmdUcmFuc3BvcnQoKTtcblxuICAgICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiZGVwbG95XCIsIHsgZXJyb3I6IHRydWUsIGVycm9yVHlwZSB9KTtcbiAgICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgICBjb25zdCBlcnJvciA9IHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpLmZpbmQoXG4gICAgICAgICAgKGkpID0+IGkubmFtZSA9PT0gXCJjbGkuY29tbWFuZC5lcnJvclwiLFxuICAgICAgICApITtcbiAgICAgICAgZXhwZWN0KGVycm9yLmF0dHJpYnV0ZXMuZXJyb3JfdHlwZS52YWx1ZSkudG9CZShleHBlY3RlZCk7XG4gICAgICAgIGV4cGVjdChlcnJvci5hdHRyaWJ1dGVzLmNvbW1hbmQudmFsdWUpLnRvQmUoXCJkZXBsb3lcIik7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICBpdChcImZvcndhcmRzIGV4YWN0bHkgdGhlIGFsbG93LWxpc3RlZCBhdHRyaWJ1dGUgc2V0IGFuZCBub3RoaW5nIGVsc2UgZnJvbSB0aGUgcGF5bG9hZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgICBzZW5kVXNhZ2VUZWxlbWV0cnk6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIGluaXRTZW50cnlXaXRoQ2FwdHVyaW5nVHJhbnNwb3J0KCk7XG5cbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcInN5bnRoXCIpO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHtcbiAgICAgICAgdG90YWxUaW1lOiA1LFxuICAgICAgICBsYW5ndWFnZTogXCJ0eXBlc2NyaXB0XCIsXG4gICAgICAgIHN5bnRoT3JpZ2luOiBcIndhdGNoXCIsXG4gICAgICAgIHN0YWNrTWV0YWRhdGE6IFt7IHN0YWNrTmFtZTogXCJwcm9kLXZwY1wiLCBiYWNrZW5kOiBcInMzXCIgfV0sXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzOiBbeyBhd3M6IHsgc291cmNlOiBcImF3c1wiIH0gfV0sXG4gICAgICAgIHN0YWNrTmFtZTogXCJwcm9kLXZwY1wiLFxuICAgICAgICBvdXRkaXI6IFwiL1VzZXJzL3gvc2VjcmV0XCIsXG4gICAgICAgIHJlc291cmNlczogeyBhd3M6IHsgc2VjcmV0X3Jlc291cmNlOiAzIH0gfSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBwYXJzZU1ldHJpY0l0ZW1zKGVudmVsb3BlQm9kaWVzKTtcbiAgICAgIGNvbnN0IGludm9rZWQgPSBpdGVtcy5maW5kKChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLmNvbW1hbmQuaW52b2tlZFwiKSE7XG4gICAgICBjb25zdCBjb21wbGV0ZWQgPSBpdGVtcy5maW5kKChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLmNvbW1hbmQuY29tcGxldGVkXCIpITtcbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhjb21wbGV0ZWQuYXR0cmlidXRlcyk7XG4gICAgICAvLyB0aGUgc3RhcnQgbWV0cmljIGNhcnJpZXMgdGhlIGJhc2Ugc2V0OyB0aGUgZW5kLW9mLXJ1biBzY2FsYXJzIHJpZGVcbiAgICAgIC8vIG9uIGNvbXBsZXRlZCBvbmx5XG4gICAgICBleHBlY3QoT2JqZWN0LmtleXMoaW52b2tlZC5hdHRyaWJ1dGVzKS5zb3J0KCkpLnRvRXF1YWwoXG4gICAgICAgIGtleXMuZmlsdGVyKChrZXkpID0+IGtleSAhPT0gXCJzeW50aF9vcmlnaW5cIikuc29ydCgpLFxuICAgICAgKTtcbiAgICAgIC8vIHRoZSBvbmUgcGxhY2UgdGhhdCBmYWlscyB3aGVuIGFuIGF0dHJpYnV0ZSBpcyBhZGRlZDogZXh0ZW5kIGl0XG4gICAgICAvLyBkZWxpYmVyYXRlbHksIHRvZ2V0aGVyIHdpdGggdGhlIGNvbGxlY3RlZC1kYXRhIGxpc3QgaW4gdGhlIGRvY3NcbiAgICAgIGV4cGVjdChrZXlzLmZpbHRlcigoa2V5KSA9PiAha2V5LnN0YXJ0c1dpdGgoXCJzZW50cnkuXCIpKS5zb3J0KCkpLnRvRXF1YWwoW1xuICAgICAgICBcImFyY2hcIixcbiAgICAgICAgXCJiaW5hcnlcIixcbiAgICAgICAgXCJiaW5hcnlfdmVyc2lvblwiLFxuICAgICAgICBcImNpXCIsXG4gICAgICAgIFwiY29tbWFuZFwiLFxuICAgICAgICBcImxhbmd1YWdlXCIsXG4gICAgICAgIFwib3NcIixcbiAgICAgICAgXCJwYWNrYWdlX21hbmFnZXJcIixcbiAgICAgICAgLy8gc2VydmVyLmFkZHJlc3MgaXMgdGhlIGZpeGVkIHNlcnZlck5hbWUgZnJvbSBpbml0XG4gICAgICAgIFwic2VydmVyLmFkZHJlc3NcIixcbiAgICAgICAgXCJzeW50aF9vcmlnaW5cIixcbiAgICAgICAgXCJ0YXJnZXRfb3BlbnRvZnVcIixcbiAgICAgICAgXCJ0YXJnZXRfdGVycmFmb3JtXCIsXG4gICAgICAgIFwidGFyZ2V0c19kZWNsYXJlZFwiLFxuICAgICAgICBcInZhbGlkYXRlX2luc3RhbGxlZF9iaW5hcnlcIixcbiAgICAgIF0pO1xuICAgICAgLy8gc3RhbXBlZCBieSB0aGUgU0RLIGZyb20gaW5pdDsgYSBwYXRjaCBidW1wIG1heSBhZGQgbW9yZSBvZiB0aGVtXG4gICAgICBleHBlY3Qoa2V5cykudG9FcXVhbChcbiAgICAgICAgZXhwZWN0LmFycmF5Q29udGFpbmluZyhbXCJzZW50cnkucmVsZWFzZVwiLCBcInNlbnRyeS5lbnZpcm9ubWVudFwiXSksXG4gICAgICApO1xuICAgICAgY29uc3QgYnl0ZXMgPSBlbnZlbG9wZUJvZGllcy5qb2luKFwiXFxuXCIpO1xuICAgICAgZXhwZWN0KGJ5dGVzKS5ub3QudG9Db250YWluKFwicHJvZC12cGNcIik7XG4gICAgICBleHBlY3QoYnl0ZXMpLm5vdC50b0NvbnRhaW4oXCIvVXNlcnMveC9zZWNyZXRcIik7XG4gICAgICBleHBlY3QoYnl0ZXMpLm5vdC50b0NvbnRhaW4oXCJzZWNyZXRfcmVzb3VyY2VcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwic2VuZFRlbGVtZXRyeSBwYXlsb2FkIG1hcHBpbmdcIiwgKCkgPT4ge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgIHNlbmRVc2FnZVRlbGVtZXRyeTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgaW5pdFNlbnRyeVdpdGhDYXB0dXJpbmdUcmFuc3BvcnQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwiY291bnRzIGdldCB0YXJnZXRzIHBlciBub3JtYWxpemVkIHByb3ZpZGVyL21vZHVsZSBhbmQgcHV0cyBvbmx5IHRvdGFscyBvbiB0aGUgY29tbWFuZCBtZXRyaWNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvdmlkZXIgPSAoY29uc3RyYWludDogc3RyaW5nKSA9PlxuICAgICAgICBuZXcgQ29uc3RydWN0c01ha2VyUHJvdmlkZXJUYXJnZXQoXG4gICAgICAgICAgbmV3IFRlcnJhZm9ybVByb3ZpZGVyQ29uc3RyYWludChjb25zdHJhaW50KSxcbiAgICAgICAgICBMYW5ndWFnZS5UWVBFU0NSSVBULFxuICAgICAgICApLnRyYWNraW5nUGF5bG9hZDtcbiAgICAgIGNvbnN0IG1vZHVsZSA9IChjb25zdHJhaW50OiBzdHJpbmcpID0+XG4gICAgICAgIG5ldyBDb25zdHJ1Y3RzTWFrZXJNb2R1bGVUYXJnZXQoXG4gICAgICAgICAgbmV3IFRlcnJhZm9ybU1vZHVsZUNvbnN0cmFpbnQoY29uc3RyYWludCksXG4gICAgICAgICAgTGFuZ3VhZ2UuVFlQRVNDUklQVCxcbiAgICAgICAgKS50cmFja2luZ1BheWxvYWQ7XG5cbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJnZXRcIiwge1xuICAgICAgICB0YXJnZXRzOiBbXG4gICAgICAgICAgcHJvdmlkZXIoXCJyZWdpc3RyeS50ZXJyYWZvcm0uaW8vaGFzaGljb3JwL2F3c0B+PiA1LjBcIiksXG4gICAgICAgICAgcHJvdmlkZXIoXCJIYXNoaWNvcnAvQVdTQH4+IDYuMFwiKSxcbiAgICAgICAgICBwcm92aWRlcihcIktyZXV6d2Vya2VyL0RvY2tlclwiKSxcbiAgICAgICAgICBtb2R1bGUoXCJ0ZXJyYWZvcm0tYXdzLW1vZHVsZXMvdnBjL2F3c0A1LjAuMFwiKSxcbiAgICAgICAgICBtb2R1bGUoXCIuL21vZHVsZXMvc2VjcmV0LW5hbWVcIiksXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBhd2FpdCBkZWxpdmVyZWRJdGVtcygpO1xuICAgICAgY29uc3QgdG90YWxzID0geyBwcm92aWRlcl9jb3VudDogMywgbW9kdWxlX2NvdW50OiAyIH07XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAxLCAuLi50b3RhbHMgfSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIFwiY2xpLmdldC5wcm92aWRlclwiKSkudG9FcXVhbChbXG4gICAgICAgIHsgdmFsdWU6IDIsIHByb3ZpZGVyOiBcImhhc2hpY29ycC9hd3NcIiwgLi4udG90YWxzIH0sXG4gICAgICAgIHsgdmFsdWU6IDEsIHByb3ZpZGVyOiBcImtyZXV6d2Vya2VyL2RvY2tlclwiLCAuLi50b3RhbHMgfSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIFwiY2xpLmdldC5tb2R1bGVcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAxLCBtb2R1bGU6IFwibG9jYWxcIiwgLi4udG90YWxzIH0sXG4gICAgICAgIHsgdmFsdWU6IDEsIG1vZHVsZTogXCJ0ZXJyYWZvcm0tYXdzLW1vZHVsZXMvdnBjL2F3c1wiLCAuLi50b3RhbHMgfSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KGVudmVsb3BlQm9kaWVzLmpvaW4oXCJcXG5cIikpLm5vdC50b0NvbnRhaW4oXCJzZWNyZXQtbmFtZVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwiY291bnRzIGluaXQgcHJvdmlkZXJzIHBlciBub3JtYWxpemVkIHByb3ZpZGVyIGFuZCBwdXRzIG9ubHkgdGhlIHRvdGFsIG9uIHRoZSBjb21tYW5kIG1ldHJpY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiaW5pdFwiLCB7XG4gICAgICAgIHByb2plY3RJZDogXCJzaG91bGQtbm90LWJlLXNlbnRcIixcbiAgICAgICAgYWRkZWRQcm92aWRlcnM6IFtcbiAgICAgICAgICBcImF3c0B+PjUuMFwiLFxuICAgICAgICAgIFwiaGFzaGljb3JwL3JhbmRvbVwiLFxuICAgICAgICAgIFwicmVnaXN0cnkudGVycmFmb3JtLmlvL2hhc2hpY29ycC9hd3NcIixcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCk7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAxLCBwcm92aWRlcl9jb3VudDogMyB9LFxuICAgICAgXSk7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuaW5pdC5wcm92aWRlclwiKSkudG9FcXVhbChbXG4gICAgICAgIHsgdmFsdWU6IDIsIHByb3ZpZGVyOiBcImhhc2hpY29ycC9hd3NcIiwgcHJvdmlkZXJfY291bnQ6IDMgfSxcbiAgICAgICAgeyB2YWx1ZTogMSwgcHJvdmlkZXI6IFwiaGFzaGljb3JwL3JhbmRvbVwiLCBwcm92aWRlcl9jb3VudDogMyB9LFxuICAgICAgXSk7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKSkubm90LnRvQ29udGFpbihcInNob3VsZC1ub3QtYmUtc2VudFwiKTtcbiAgICB9KTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW1xuICAgICAgICBcImdldFwiLFxuICAgICAgICAoc291cmNlczogc3RyaW5nW10pID0+ICh7XG4gICAgICAgICAgdGFyZ2V0czogc291cmNlcy5tYXAoKHNvdXJjZSkgPT4gKHsgdHlwZTogXCJwcm92aWRlclwiLCBzb3VyY2UgfSkpLFxuICAgICAgICB9KSxcbiAgICAgICAgXCJjbGkuZ2V0LnByb3ZpZGVyXCIsXG4gICAgICAgIHsgcHJvdmlkZXJfY291bnQ6IDQwLCBtb2R1bGVfY291bnQ6IDAgfSxcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgIFwiaW5pdFwiLFxuICAgICAgICAoc291cmNlczogc3RyaW5nW10pID0+ICh7IGFkZGVkUHJvdmlkZXJzOiBzb3VyY2VzIH0pLFxuICAgICAgICBcImNsaS5pbml0LnByb3ZpZGVyXCIsXG4gICAgICAgIHsgcHJvdmlkZXJfY291bnQ6IDQwIH0sXG4gICAgICBdLFxuICAgIF0pKFxuICAgICAgXCIlcyBmb2xkcyB0aGUgcHJvdmlkZXJzIHBhc3QgMzIgaW50byBvbmUgdHJ1bmNhdGVkIGNvdW50XCIsXG4gICAgICBhc3luYyAoY29tbWFuZCwgcGF5bG9hZCwgbWV0cmljLCB0b3RhbHMpID0+IHtcbiAgICAgICAgY29uc3Qgc291cmNlcyA9IEFycmF5LmZyb20oXG4gICAgICAgICAgeyBsZW5ndGg6IDQwIH0sXG4gICAgICAgICAgKF8sIGspID0+IGBhY21lL3Ake1N0cmluZyhrKS5wYWRTdGFydCgyLCBcIjBcIil9YCxcbiAgICAgICAgKTtcblxuICAgICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KGNvbW1hbmQsIHBheWxvYWQoWy4uLnNvdXJjZXNdLnJldmVyc2UoKSkpO1xuXG4gICAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgZGVsaXZlcmVkSXRlbXMoKTtcbiAgICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIG1ldHJpYykpLnRvRXF1YWwoW1xuICAgICAgICAgIC4uLnNvdXJjZXNcbiAgICAgICAgICAgIC5zbGljZSgwLCAzMilcbiAgICAgICAgICAgIC5tYXAoKHByb3ZpZGVyKSA9PiAoeyB2YWx1ZTogMSwgcHJvdmlkZXIsIC4uLnRvdGFscyB9KSksXG4gICAgICAgICAgeyB2YWx1ZTogOCwgdHJ1bmNhdGVkOiB0cnVlLCAuLi50b3RhbHMgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5jb21tYW5kLmNvbXBsZXRlZFwiKSkudG9FcXVhbChbXG4gICAgICAgICAgeyB2YWx1ZTogMSwgLi4udG90YWxzIH0sXG4gICAgICAgIF0pO1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgaXQoXCJjb3VudHMgdGhlIHJ1biBhcyBjb21wbGV0ZWQgZXZlbiB3aGVuIGEgcGVyLXNvdXJjZSBtZXRyaWMgY2Fubm90IGJlIGJ1aWx0XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJnZXRcIiwge1xuICAgICAgICB0YXJnZXRzOiBbbnVsbCwgeyB0eXBlOiBcInByb3ZpZGVyXCIsIHNvdXJjZTogNyB9XSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCk7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAxLCBwcm92aWRlcl9jb3VudDogMSwgbW9kdWxlX2NvdW50OiAwIH0sXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5nZXQucHJvdmlkZXJcIikpLnRvRXF1YWwoW10pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcInN0YWNrIG1ldHJpY3NcIiwgKCkgPT4ge1xuICAgIC8vIG9uZSBKU09OLXN5bnRoZXNpemVkIHN0YWNrIHRoZSB3YXkgdGhlIGxpYnJhcnkgd3JpdGVzIGl0OiBtZXRhZGF0YVxuICAgIC8vIGNhcnJpZXMgdGhlIHN0YWNrIG5hbWUgYW5kIHJlc291cmNlIGlkcyAoaW1wb3J0cy9tb3ZlZCksIG92ZXJyaWRlc1xuICAgIC8vIGFyZSBrZXllZCBieSBzY2hlbWEgdHlwZSwgbW9kdWxlIG92ZXJyaWRlcyBieSBzb3VyY2VcbiAgICBjb25zdCBzdGFja01ldGFkYXRhID0gW1xuICAgICAge1xuICAgICAgICB2ZXJzaW9uOiBcIjAuMjEuMFwiLFxuICAgICAgICBzdGFja05hbWU6IFwiU0VDUkVULVNUQUNLLU5BTUVcIixcbiAgICAgICAgYmFja2VuZDogXCJzM1wiLFxuICAgICAgICBvdmVycmlkZXM6IHtcbiAgICAgICAgICBzdGFjazogW1widGVycmFmb3JtLnJlcXVpcmVkX3ZlcnNpb25cIl0sXG4gICAgICAgICAgYXdzX3MzX2J1Y2tldDogW1widGFnc1wiLCBcInJlZ2lvblwiXSxcbiAgICAgICAgICBcIm1vZHVsZS4uLi9zZWNyZXQtcGF0aC92cGNcIjogW1wicHJvdmlkZXJzXCJdLFxuICAgICAgICB9LFxuICAgICAgICBpbXBvcnRzOiB7IGF3c19zM19idWNrZXQ6IFtcInNlY3JldC1yZXNvdXJjZS1pZFwiXSB9LFxuICAgICAgICBtb3ZlZDoge1xuICAgICAgICAgIGF3c19zM19idWNrZXQ6IFtcInNlY3JldC1yZXNvdXJjZS1pZFwiXSxcbiAgICAgICAgICBhd3NfaWFtX3JvbGU6IFtcInNlY3JldC1yZXNvdXJjZS1pZFwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHZlcnNpb246IFwiMC4yMS4wXCIsXG4gICAgICAgIHN0YWNrTmFtZTogXCJTRUNSRVQtU1RBQ0stTkFNRS0yXCIsXG4gICAgICAgIGJhY2tlbmQ6IFwicmVtb3RlXCIsXG4gICAgICAgIGNsb3VkOiBcInRmY1wiLFxuICAgICAgfSxcbiAgICBdO1xuICAgIGNvbnN0IHJlcXVpcmVkUHJvdmlkZXJzID0gW1xuICAgICAge1xuICAgICAgICBhd3M6IHsgc291cmNlOiBcImF3c1wiLCB2ZXJzaW9uOiBcIn4+IDUuMFwiIH0sXG4gICAgICAgIGRvY2tlcjoge1xuICAgICAgICAgIHNvdXJjZTogXCJyZWdpc3RyeS50ZXJyYWZvcm0uaW8va3JldXp3ZXJrZXIvZG9ja2VyXCIsXG4gICAgICAgICAgdmVyc2lvbjogXCIzLjAuMlwiLFxuICAgICAgICB9LFxuICAgICAgICBnb29nbGU6IHsgc291cmNlOiBcImhhc2hpY29ycC9nb29nbGVcIiwgdmVyc2lvbjogXCJ4XCIucmVwZWF0KDEwMCkgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHJhbmRvbTogeyBzb3VyY2U6IFwiaGFzaGljb3JwL3JhbmRvbVwiIH0sXG4gICAgICAgIHZhdWx0OiB7XG4gICAgICAgICAgc291cmNlOiBcInRmZS5jb3JwLmV4YW1wbGUuY29tL2FjbWUtb3JnL3ZhdWx0XCIsXG4gICAgICAgICAgdmVyc2lvbjogXCJ+PiAzLjBcIixcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCBub0NvdW50cyA9IHsgb3ZlcnJpZGVfY291bnQ6IDAsIGltcG9ydF9jb3VudDogMCwgbW92ZWRfY291bnQ6IDAgfTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgIHNlbmRVc2FnZVRlbGVtZXRyeTogdHJ1ZSxcbiAgICAgICAgdGVycmFmb3JtUHJvdmlkZXJzOiBbXG4gICAgICAgICAgXCJhd3NAfj41LjBcIixcbiAgICAgICAgICB7IG5hbWU6IFwiZG9ja2VyXCIsIHNvdXJjZTogXCJrcmV1endlcmtlci9kb2NrZXJcIiwgdmVyc2lvbjogXCIzLjAuMlwiIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICAgIGluaXRTZW50cnlXaXRoQ2FwdHVyaW5nVHJhbnNwb3J0KCk7XG4gICAgfSk7XG5cbiAgICBpdChcImRlbGl2ZXJzIG5vIHN0YWNrLCBwcm92aWRlciBvciBvdmVycmlkZSBtZXRyaWMgd2hlbiB0aGUgcHJvamVjdCBvcHRzIG91dFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgc2VuZFVzYWdlVGVsZW1ldHJ5OiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiZGVwbG95XCIsIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgICBzdGFja01ldGFkYXRhLFxuICAgICAgICByZXF1aXJlZFByb3ZpZGVycyxcbiAgICAgICAgZmFpbGVkU3RhY2tDb3VudDogMCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSkudG9FcXVhbChbXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImNvdW50cyBzdGFja3MgYnkgYmFja2VuZCwgY2xvdWQgYW5kIGxpYnJhcnkgdmVyc2lvbiB3aXRoIHRoZWlyIGdyb3VwIHNpemVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJkZXBsb3lcIiwge1xuICAgICAgICBsYW5ndWFnZTogXCJ0eXBlc2NyaXB0XCIsXG4gICAgICAgIHN0YWNrTWV0YWRhdGEsXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzLFxuICAgICAgICBmYWlsZWRTdGFja0NvdW50OiAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgZGVsaXZlcmVkSXRlbXMoKTtcbiAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFja1wiKSkudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgICBiYWNrZW5kOiBcInJlbW90ZVwiLFxuICAgICAgICAgIGNsb3VkOiB0cnVlLFxuICAgICAgICAgIGxpYnJhcnlfdmVyc2lvbjogXCIwLjIxLjBcIixcbiAgICAgICAgICAuLi5ub0NvdW50cyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICAgIGJhY2tlbmQ6IFwiczNcIixcbiAgICAgICAgICBjbG91ZDogZmFsc2UsXG4gICAgICAgICAgbGlicmFyeV92ZXJzaW9uOiBcIjAuMjEuMFwiLFxuICAgICAgICAgIG92ZXJyaWRlX2NvdW50OiA0LFxuICAgICAgICAgIGltcG9ydF9jb3VudDogMSxcbiAgICAgICAgICBtb3ZlZF9jb3VudDogMixcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgICAgZm9yIChjb25zdCBzdGFjayBvZiBpdGVtcy5maWx0ZXIoKGkpID0+IGkubmFtZSA9PT0gXCJjbGkuc3RhY2tcIikpIHtcbiAgICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhzdGFjaykpLnRvTWF0Y2hPYmplY3Qoe1xuICAgICAgICAgIGNvbW1hbmQ6IFwiZGVwbG95XCIsXG4gICAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGV4cGVjdChpdGVtcy5zb21lKChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLnN0YWNrLmZhaWxlZFwiKSkudG9CZShmYWxzZSk7XG4gICAgICBleHBlY3QoaXRlbXMuc29tZSgoaSkgPT4gaS5uYW1lID09PSBcImNsaS5jb21tYW5kLmNvbXBsZXRlZFwiKSkudG9CZSh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KFwiY291bnRzIG92ZXJyaWRlcyBwZXIgcmVzb3VyY2UgdHlwZSwgcmVkdWNpbmcgbW9kdWxlIHNvdXJjZXMgdG8gdGhlaXIga2luZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwic3ludGhcIiwgeyBzdGFja01ldGFkYXRhLCByZXF1aXJlZFByb3ZpZGVycyB9KTtcblxuICAgICAgZXhwZWN0KG1ldHJpY3MoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSwgXCJjbGkuc3RhY2sub3ZlcnJpZGVcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAxLCByZXNvdXJjZV90eXBlOiBcImF3c19zM19idWNrZXRcIiwgb3ZlcnJpZGVfY291bnQ6IDIgfSxcbiAgICAgICAgeyB2YWx1ZTogMSwgcmVzb3VyY2VfdHlwZTogXCJtb2R1bGUubG9jYWxcIiwgb3ZlcnJpZGVfY291bnQ6IDEgfSxcbiAgICAgICAgeyB2YWx1ZTogMSwgcmVzb3VyY2VfdHlwZTogXCJzdGFja1wiLCBvdmVycmlkZV9jb3VudDogMSB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImNvdW50cyByZXF1aXJlZCBwcm92aWRlcnMgYnkgbm9ybWFsaXplZCBzb3VyY2UsIHZhbGlkYXRlZCBjb25zdHJhaW50IGFuZCBiaW5kaW5nXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJkaWZmXCIsIHsgc3RhY2tNZXRhZGF0YSwgcmVxdWlyZWRQcm92aWRlcnMgfSk7XG5cbiAgICAgIGV4cGVjdChtZXRyaWNzKGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCksIFwiY2xpLnN0YWNrLnByb3ZpZGVyXCIpKS50b0VxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICAgIHByb3ZpZGVyOiBcImhhc2hpY29ycC9hd3NcIixcbiAgICAgICAgICB2ZXJzaW9uX2NvbnN0cmFpbnQ6IFwifj4gNS4wXCIsXG4gICAgICAgICAgYmluZGluZzogXCJnZW5lcmF0ZWRcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICAgIHByb3ZpZGVyOiBcImhhc2hpY29ycC9nb29nbGVcIixcbiAgICAgICAgICB2ZXJzaW9uX2NvbnN0cmFpbnQ6IFwiaW52YWxpZFwiLFxuICAgICAgICAgIGJpbmRpbmc6IFwicHJlYnVpbHRcIixcbiAgICAgICAgfSxcbiAgICAgICAgeyB2YWx1ZTogMSwgcHJvdmlkZXI6IFwiaGFzaGljb3JwL3JhbmRvbVwiLCBiaW5kaW5nOiBcInByZWJ1aWx0XCIgfSxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICAgIHByb3ZpZGVyOiBcImtyZXV6d2Vya2VyL2RvY2tlclwiLFxuICAgICAgICAgIHZlcnNpb25fY29uc3RyYWludDogXCIzLjAuMlwiLFxuICAgICAgICAgIGJpbmRpbmc6IFwiZ2VuZXJhdGVkXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgICBwcm92aWRlcjogXCJwcml2YXRlLXJlZ2lzdHJ5XCIsXG4gICAgICAgICAgdmVyc2lvbl9jb25zdHJhaW50OiBcIn4+IDMuMFwiLFxuICAgICAgICAgIGJpbmRpbmc6IFwicHJlYnVpbHRcIixcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJjbGFzc2lmaWVzIGJpbmRpbmdzIGFnYWluc3QgdGhlIHByb2plY3QgdGhlIGNvbW1hbmQgc3RhcnRlZCBpbiwgbm90IHRoZSBjdXJyZW50IGN3ZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzdGFydENvbW1hbmRUZWxlbWV0cnkoXCJkaWZmXCIpO1xuICAgICAgY29uc3QgZWxzZXdoZXJlID0gcGF0aC5qb2luKHdvcmtkaXIsIFwiZWxzZXdoZXJlXCIpO1xuICAgICAgZnMubWtkaXJTeW5jKGVsc2V3aGVyZSk7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbihlbHNld2hlcmUsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICB0ZXJyYWZvcm1Qcm92aWRlcnM6IFtcImdvb2dsZVwiXSxcbiAgICAgIH0pO1xuICAgICAgcHJvY2Vzcy5jaGRpcihlbHNld2hlcmUpO1xuXG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiZGlmZlwiLCB7IHN0YWNrTWV0YWRhdGEsIHJlcXVpcmVkUHJvdmlkZXJzIH0pO1xuXG4gICAgICBleHBlY3QoXG4gICAgICAgIG1ldHJpY3MoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSwgXCJjbGkuc3RhY2sucHJvdmlkZXJcIikubWFwKChwKSA9PiBbXG4gICAgICAgICAgcC5wcm92aWRlcixcbiAgICAgICAgICBwLmJpbmRpbmcsXG4gICAgICAgIF0pLFxuICAgICAgKS50b0VxdWFsKFtcbiAgICAgICAgW1wiaGFzaGljb3JwL2F3c1wiLCBcImdlbmVyYXRlZFwiXSxcbiAgICAgICAgW1wiaGFzaGljb3JwL2dvb2dsZVwiLCBcInByZWJ1aWx0XCJdLFxuICAgICAgICBbXCJoYXNoaWNvcnAvcmFuZG9tXCIsIFwicHJlYnVpbHRcIl0sXG4gICAgICAgIFtcImtyZXV6d2Vya2VyL2RvY2tlclwiLCBcImdlbmVyYXRlZFwiXSxcbiAgICAgICAgW1wicHJpdmF0ZS1yZWdpc3RyeVwiLCBcInByZWJ1aWx0XCJdLFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdC5lYWNoKFszLCAzMDBdKShcbiAgICAgIFwic2VuZHMgdGhlIHNhbWUgc3RhY2sgZXZlbnRzIGZvciAlZCBhbGlrZSBzdGFja3MsIHdpdGggdGhlIHN0YWNrIGNvdW50IGFzIHRoZWlyIHZhbHVlXCIsXG4gICAgICBhc3luYyAoY291bnQpID0+IHtcbiAgICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7XG4gICAgICAgICAgc3RhY2tNZXRhZGF0YTogQXJyYXkuZnJvbSh7IGxlbmd0aDogY291bnQgfSwgKF8sIGkpID0+ICh7XG4gICAgICAgICAgICB2ZXJzaW9uOiBcIjAuMjEuMFwiLFxuICAgICAgICAgICAgc3RhY2tOYW1lOiBgc3RhY2stJHtpfWAsXG4gICAgICAgICAgICBiYWNrZW5kOiBcInMzXCIsXG4gICAgICAgICAgICBvdmVycmlkZXM6IHsgYXdzX3MzX2J1Y2tldDogW1widGFnc1wiXSB9LFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgICByZXF1aXJlZFByb3ZpZGVyczogQXJyYXkuZnJvbSh7IGxlbmd0aDogY291bnQgfSwgKCkgPT4gKHtcbiAgICAgICAgICAgIGF3czogeyBzb3VyY2U6IFwiYXdzXCIsIHZlcnNpb246IFwifj4gNS4wXCIgfSxcbiAgICAgICAgICAgIHJhbmRvbTogeyBzb3VyY2U6IFwiaGFzaGljb3JwL3JhbmRvbVwiIH0sXG4gICAgICAgICAgfSkpLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCk7XG4gICAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFja1wiKSkudG9FcXVhbChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFsdWU6IGNvdW50LFxuICAgICAgICAgICAgYmFja2VuZDogXCJzM1wiLFxuICAgICAgICAgICAgY2xvdWQ6IGZhbHNlLFxuICAgICAgICAgICAgbGlicmFyeV92ZXJzaW9uOiBcIjAuMjEuMFwiLFxuICAgICAgICAgICAgb3ZlcnJpZGVfY291bnQ6IGNvdW50LFxuICAgICAgICAgICAgaW1wb3J0X2NvdW50OiAwLFxuICAgICAgICAgICAgbW92ZWRfY291bnQ6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFjay5wcm92aWRlclwiKSkudG9FcXVhbChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFsdWU6IGNvdW50LFxuICAgICAgICAgICAgcHJvdmlkZXI6IFwiaGFzaGljb3JwL2F3c1wiLFxuICAgICAgICAgICAgdmVyc2lvbl9jb25zdHJhaW50OiBcIn4+IDUuMFwiLFxuICAgICAgICAgICAgYmluZGluZzogXCJnZW5lcmF0ZWRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgdmFsdWU6IGNvdW50LCBwcm92aWRlcjogXCJoYXNoaWNvcnAvcmFuZG9tXCIsIGJpbmRpbmc6IFwicHJlYnVpbHRcIiB9LFxuICAgICAgICBdKTtcbiAgICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIFwiY2xpLnN0YWNrLm92ZXJyaWRlXCIpKS50b0VxdWFsKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YWx1ZTogY291bnQsXG4gICAgICAgICAgICByZXNvdXJjZV90eXBlOiBcImF3c19zM19idWNrZXRcIixcbiAgICAgICAgICAgIG92ZXJyaWRlX2NvdW50OiBjb3VudCxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGl0KFwiZ3JvdXBzIHByb3ZpZGVycyBvbiB3aGF0IGlzIHNlbnQ6IHNwZWxsaW5ncyBhbmQgcHJpdmF0ZSBob3N0cyBjb2xsYXBzZSwgY29uc3RyYWludHMgZG8gbm90XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGE6IFt7fSwge30sIHt9XSxcbiAgICAgICAgcmVxdWlyZWRQcm92aWRlcnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhd3M6IHsgc291cmNlOiBcImF3c1wiLCB2ZXJzaW9uOiBcIn4+NS4wXCIgfSxcbiAgICAgICAgICAgIHZhdWx0OiB7IHNvdXJjZTogXCJ0ZmUubGVhay1vbmUuZXhhbXBsZS9sZWFrLW9yZy1vbmUvdmF1bHRcIiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYXdzOiB7IHNvdXJjZTogXCJIYXNoaWNvcnAvQVdTXCIsIHZlcnNpb246IFwifj4gNS4wXCIgfSxcbiAgICAgICAgICAgIC8vIGEgc3RhY2sgY291bnRzIG9uY2UgcGVyIGdyb3VwLCBob3dldmVyIG1hbnkgZW50cmllcyByZWFjaCBpdFxuICAgICAgICAgICAgdmF1bHQ6IHsgc291cmNlOiBcInJlZ2lzdHJ5LmxlYWstdHdvLmV4YW1wbGUvbGVhay1vcmctdHdvL3ZhdWx0XCIgfSxcbiAgICAgICAgICAgIGNvbnN1bDogeyBzb3VyY2U6IFwibWlycm9yLmxlYWstdGhyZWUuZXhhbXBsZS9sZWFrLW9yZy10d28vY29uc3VsXCIgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGF3czoge1xuICAgICAgICAgICAgICBzb3VyY2U6IFwicmVnaXN0cnkudGVycmFmb3JtLmlvL2hhc2hpY29ycC9hd3NcIixcbiAgICAgICAgICAgICAgdmVyc2lvbjogXCJ+PiA1LjBcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhd3M2OiB7IHNvdXJjZTogXCJhd3NcIiwgdmVyc2lvbjogXCJ+PiA2LjBcIiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG1ldHJpY3MoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSwgXCJjbGkuc3RhY2sucHJvdmlkZXJcIikpLnRvRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IDMsXG4gICAgICAgICAgcHJvdmlkZXI6IFwiaGFzaGljb3JwL2F3c1wiLFxuICAgICAgICAgIHZlcnNpb25fY29uc3RyYWludDogXCJ+PiA1LjBcIixcbiAgICAgICAgICBiaW5kaW5nOiBcImdlbmVyYXRlZFwiLFxuICAgICAgICB9LFxuICAgICAgICB7IHZhbHVlOiAyLCBwcm92aWRlcjogXCJwcml2YXRlLXJlZ2lzdHJ5XCIsIGJpbmRpbmc6IFwicHJlYnVpbHRcIiB9LFxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgICAgcHJvdmlkZXI6IFwiaGFzaGljb3JwL2F3c1wiLFxuICAgICAgICAgIHZlcnNpb25fY29uc3RyYWludDogXCJ+PiA2LjBcIixcbiAgICAgICAgICBiaW5kaW5nOiBcImdlbmVyYXRlZFwiLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKSkubm90LnRvQ29udGFpbihcImxlYWtcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInN1bXMgdGhlIGdyb3VwIHNpemVzIG9mIHRoZSBzdGFja3MgaW4gYSBncm91cCBhbmQgdGhlIHBhdGhzIG9mIGFuIG92ZXJyaWRlIHR5cGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHtcbiAgICAgICAgc3RhY2tNZXRhZGF0YTogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGJhY2tlbmQ6IFwibG9jYWxcIixcbiAgICAgICAgICAgIG92ZXJyaWRlczogeyBhd3NfczNfYnVja2V0OiBbXCJhXCIsIFwiYlwiLCBcImNcIl0sIFwiYmFkIGtleSAxXCI6IFtcInhcIl0gfSxcbiAgICAgICAgICAgIGltcG9ydHM6IHsgYXdzX3MzX2J1Y2tldDogW1wiaWRcIl0gfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGJhY2tlbmQ6IFwibG9jYWxcIixcbiAgICAgICAgICAgIG92ZXJyaWRlczoge1xuICAgICAgICAgICAgICBhd3NfczNfYnVja2V0OiBbXCJhXCJdLFxuICAgICAgICAgICAgICBcImJhZCBrZXkgMlwiOiBbXCJ4XCJdLFxuICAgICAgICAgICAgICBcImJhZCBrZXkgM1wiOiBbXCJ4XCIsIFwieVwiLCBcInpcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbW92ZWQ6IHsgYXdzX3MzX2J1Y2tldDogW1wiaWRcIiwgXCJpZFwiXSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBhd2FpdCBkZWxpdmVyZWRJdGVtcygpO1xuICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIFwiY2xpLnN0YWNrXCIpKS50b0VxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICAgIGJhY2tlbmQ6IFwibG9jYWxcIixcbiAgICAgICAgICBjbG91ZDogZmFsc2UsXG4gICAgICAgICAgb3ZlcnJpZGVfY291bnQ6IDksXG4gICAgICAgICAgaW1wb3J0X2NvdW50OiAxLFxuICAgICAgICAgIG1vdmVkX2NvdW50OiAyLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuc3RhY2sub3ZlcnJpZGVcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAyLCByZXNvdXJjZV90eXBlOiBcImF3c19zM19idWNrZXRcIiwgb3ZlcnJpZGVfY291bnQ6IDQgfSxcbiAgICAgICAgeyB2YWx1ZTogMiwgcmVzb3VyY2VfdHlwZTogXCJvdGhlclwiLCBvdmVycmlkZV9jb3VudDogNSB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImtlZXBzIHRoZSAzMiBtb3N0IHJlcXVpcmVkIHByb3ZpZGVycyBhbmQgZm9sZHMgdGhlIHJlc3QgaW50byBvbmUgdHJ1bmNhdGVkIGNvdW50XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICB7IGxlbmd0aDogNDAgfSxcbiAgICAgICAgKF8sIGspID0+IGBhY21lL3Ake1N0cmluZyhrKS5wYWRTdGFydCgyLCBcIjBcIil9YCxcbiAgICAgICk7XG4gICAgICAvLyBwcm92aWRlciBrIGlzIHJlcXVpcmVkIGJ5IDQwIC0gayBzdGFja3NcbiAgICAgIGNvbnN0IHJlcXVpcmVkQnlTdGFjayA9IHNvdXJjZXMubWFwKChfLCBzdGFjaykgPT5cbiAgICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIHNvdXJjZXNcbiAgICAgICAgICAgIC5zbGljZSgwLCBzb3VyY2VzLmxlbmd0aCAtIHN0YWNrKVxuICAgICAgICAgICAgLm1hcCgoc291cmNlLCBrKSA9PiBbYHAke2t9YCwgeyBzb3VyY2UgfV0pLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHtcbiAgICAgICAgc3RhY2tNZXRhZGF0YTogc291cmNlcy5tYXAoKCkgPT4gKHt9KSksXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzOiByZXF1aXJlZEJ5U3RhY2ssXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJvdmlkZXJzID0gbWV0cmljcyhhd2FpdCBkZWxpdmVyZWRJdGVtcygpLCBcImNsaS5zdGFjay5wcm92aWRlclwiKTtcbiAgICAgIGV4cGVjdChwcm92aWRlcnMpLnRvRXF1YWwoW1xuICAgICAgICAuLi5zb3VyY2VzLnNsaWNlKDAsIDMyKS5tYXAoKHByb3ZpZGVyLCBrKSA9PiAoe1xuICAgICAgICAgIHZhbHVlOiA0MCAtIGssXG4gICAgICAgICAgcHJvdmlkZXIsXG4gICAgICAgICAgYmluZGluZzogXCJwcmVidWlsdFwiLFxuICAgICAgICB9KSksXG4gICAgICAgIHsgdmFsdWU6IDM2LCB0cnVuY2F0ZWQ6IHRydWUgfSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHByb3ZpZGVycy5yZWR1Y2UoKHRvdGFsLCBwKSA9PiB0b3RhbCArIHAudmFsdWUsIDApKS50b0JlKDgyMCk7XG4gICAgfSk7XG5cbiAgICBpdChcImtlZXBzIHRoZSBmaXJzdCAzMiBvdmVycmlkZSB0eXBlcyBieSBuYW1lIG9uIGEgdGllIGFuZCBmb2xkcyB0aGUgcmVzdCB3aXRoIHRoZWlyIHBhdGhzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR5cGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgeyBsZW5ndGg6IDM0IH0sXG4gICAgICAgIChfLCBrKSA9PiBgYXdzX3Qke1N0cmluZyhrKS5wYWRTdGFydCgyLCBcIjBcIil9YCxcbiAgICAgICk7XG4gICAgICBjb25zdCBsb25nZXI6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHtcbiAgICAgICAgYXdzX3QzMjogW1wiYVwiLCBcImJcIl0sXG4gICAgICAgIGF3c190MzM6IFtcImFcIiwgXCJiXCIsIFwiY1wiXSxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXRocyA9ICh0eXBlOiBzdHJpbmcpID0+IGxvbmdlclt0eXBlXSA/PyBbXCJhXCJdO1xuXG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwic3ludGhcIiwge1xuICAgICAgICBzdGFja01ldGFkYXRhOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgb3ZlcnJpZGVzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICAgIFsuLi50eXBlc10ucmV2ZXJzZSgpLm1hcCgodHlwZSkgPT4gW3R5cGUsIHBhdGhzKHR5cGUpXSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG1ldHJpY3MoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSwgXCJjbGkuc3RhY2sub3ZlcnJpZGVcIikpLnRvRXF1YWwoW1xuICAgICAgICAuLi50eXBlcy5zbGljZSgwLCAzMikubWFwKChyZXNvdXJjZV90eXBlKSA9PiAoe1xuICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICAgIHJlc291cmNlX3R5cGUsXG4gICAgICAgICAgb3ZlcnJpZGVfY291bnQ6IDEsXG4gICAgICAgIH0pKSxcbiAgICAgICAgeyB2YWx1ZTogMiwgb3ZlcnJpZGVfY291bnQ6IDUsIHRydW5jYXRlZDogdHJ1ZSB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImtlZXBzIHRoZSA4IGxhcmdlc3Qgc3RhY2sgZ3JvdXBzIGFuZCBmb2xkcyB0aGUgcmVzdCB3aXRoIHRoZWlyIGdyb3VwIHNpemVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGxpYnJhcnkgdmVyc2lvbiAwLmsuMCBpcyB1c2VkIGJ5IGsgKyAxIHN0YWNrcywgZWFjaCB3aXRoIG9uZSBpbXBvcnRcbiAgICAgIGNvbnN0IHN0YWNrc09mVmVyc2lvbiA9IChrOiBudW1iZXIpID0+XG4gICAgICAgIEFycmF5LmZyb20oeyBsZW5ndGg6IGsgKyAxIH0sICgpID0+ICh7XG4gICAgICAgICAgdmVyc2lvbjogYDAuJHtrfS4wYCxcbiAgICAgICAgICBiYWNrZW5kOiBcInMzXCIsXG4gICAgICAgICAgaW1wb3J0czogeyBhd3NfczNfYnVja2V0OiBbXCJpZFwiXSB9LFxuICAgICAgICB9KSk7XG5cbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGE6IEFycmF5LmZyb20oeyBsZW5ndGg6IDEwIH0sIChfLCBrKSA9PlxuICAgICAgICAgIHN0YWNrc09mVmVyc2lvbihrKSxcbiAgICAgICAgKS5mbGF0KCksXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3RhY2tzID0gbWV0cmljcyhhd2FpdCBkZWxpdmVyZWRJdGVtcygpLCBcImNsaS5zdGFja1wiKTtcbiAgICAgIGV4cGVjdChzdGFja3MpLnRvRXF1YWwoW1xuICAgICAgICAuLi5bOSwgOCwgNywgNiwgNSwgNCwgMywgMl0ubWFwKChrKSA9PiAoe1xuICAgICAgICAgIHZhbHVlOiBrICsgMSxcbiAgICAgICAgICBiYWNrZW5kOiBcInMzXCIsXG4gICAgICAgICAgY2xvdWQ6IGZhbHNlLFxuICAgICAgICAgIGxpYnJhcnlfdmVyc2lvbjogYDAuJHtrfS4wYCxcbiAgICAgICAgICAuLi5ub0NvdW50cyxcbiAgICAgICAgICBpbXBvcnRfY291bnQ6IGsgKyAxLFxuICAgICAgICB9KSksXG4gICAgICAgIHsgdmFsdWU6IDMsIHRydW5jYXRlZDogdHJ1ZSwgLi4ubm9Db3VudHMsIGltcG9ydF9jb3VudDogMyB9LFxuICAgICAgXSk7XG4gICAgICBleHBlY3Qoc3RhY2tzLnJlZHVjZSgodG90YWwsIHMpID0+IHRvdGFsICsgcy52YWx1ZSwgMCkpLnRvQmUoNTUpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJib3VuZHMgdGhlIHN0YWNrIGV2ZW50cyBvZiBhIHJ1biB3aGF0ZXZlciB0aGUgcHJvamVjdCdzIHNoYXBlLCBpbiB0aGUgZW52ZWxvcGUgb2YgdGhlIGNvbW1hbmQgbWV0cmljXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcnR5ID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogNDAgfSwgKF8sIGspID0+IGspO1xuXG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiZGVwbG95XCIsIHtcbiAgICAgICAgc3RhY2tNZXRhZGF0YTogQXJyYXkuZnJvbSh7IGxlbmd0aDogMzAwIH0sIChfLCBpKSA9PiAoe1xuICAgICAgICAgIHZlcnNpb246IGAxLiR7aX0uMGAsXG4gICAgICAgICAgb3ZlcnJpZGVzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICBmb3J0eS5tYXAoKGspID0+IFtgYXdzX3R5cGVfJHtrfWAsIFtcInRhZ3NcIl1dKSxcbiAgICAgICAgICApLFxuICAgICAgICB9KSksXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiAzMDAgfSwgKCkgPT5cbiAgICAgICAgICBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICBmb3J0eS5tYXAoKGspID0+IFtgcCR7a31gLCB7IHNvdXJjZTogYGFjbWUvcCR7a31gIH1dKSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgZGVsaXZlcmVkSXRlbXMoKTtcbiAgICAgIGNvbnN0IGNvdW50ID0gKG5hbWU6IHN0cmluZykgPT4gbWV0cmljcyhpdGVtcywgbmFtZSkubGVuZ3RoO1xuICAgICAgY29uc3QgdG90YWwgPSAobmFtZTogc3RyaW5nKSA9PlxuICAgICAgICBtZXRyaWNzKGl0ZW1zLCBuYW1lKS5yZWR1Y2UoKHN1bSwgbSkgPT4gc3VtICsgbS52YWx1ZSwgMCk7XG4gICAgICBleHBlY3QoW1xuICAgICAgICBjb3VudChcImNsaS5zdGFja1wiKSxcbiAgICAgICAgY291bnQoXCJjbGkuc3RhY2sucHJvdmlkZXJcIiksXG4gICAgICAgIGNvdW50KFwiY2xpLnN0YWNrLm92ZXJyaWRlXCIpLFxuICAgICAgXSkudG9FcXVhbChbOSwgMzMsIDMzXSk7XG4gICAgICBleHBlY3QodG90YWwoXCJjbGkuc3RhY2tcIikpLnRvQmUoMzAwKTtcbiAgICAgIGV4cGVjdCh0b3RhbChcImNsaS5zdGFjay5wcm92aWRlclwiKSkudG9CZSgzMDAgKiA0MCk7XG4gICAgICBleHBlY3QoY291bnQoXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIikpLnRvQmUoMSk7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICB9KTtcblxuICAgIGl0KFwibGVhdmVzIHRoZSBzdGFja3MgdG8gdGhlIGNvbW1hbmQgd2hlbiBpdHMgc3ludGggaXMgbmVzdGVkOiBvbmx5IHRoZSBzZWxlY3RlZCBvbmVzLCB1bmRlciBpdHMgbmFtZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzdGFydENvbW1hbmRUZWxlbWV0cnkoXCJkZXBsb3lcIik7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwic3ludGhcIiwge1xuICAgICAgICB0b3RhbFRpbWU6IDQyLFxuICAgICAgICBzdGFja01ldGFkYXRhLFxuICAgICAgICByZXF1aXJlZFByb3ZpZGVycyxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGE6IHN0YWNrTWV0YWRhdGEuc2xpY2UoMSksXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzOiByZXF1aXJlZFByb3ZpZGVycy5zbGljZSgxKSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCk7XG4gICAgICBleHBlY3QoXG4gICAgICAgIGl0ZW1zXG4gICAgICAgICAgLmZpbHRlcigoaSkgPT4gaS5uYW1lLnN0YXJ0c1dpdGgoXCJjbGkuc3RhY2tcIikpXG4gICAgICAgICAgLm1hcCgoaSkgPT4gW2kubmFtZSwgYXR0cmlidXRlVmFsdWVzKGkpLmNvbW1hbmQsIGkudmFsdWVdKSxcbiAgICAgICkudG9FcXVhbChbXG4gICAgICAgIFtcImNsaS5zdGFja1wiLCBcImRlcGxveVwiLCAxXSxcbiAgICAgICAgW1wiY2xpLnN0YWNrLnByb3ZpZGVyXCIsIFwiZGVwbG95XCIsIDFdLFxuICAgICAgICBbXCJjbGkuc3RhY2sucHJvdmlkZXJcIiwgXCJkZXBsb3lcIiwgMV0sXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChcbiAgICAgICAgaXRlbXMuc29tZShcbiAgICAgICAgICAoaSkgPT5cbiAgICAgICAgICAgIGkubmFtZSA9PT0gXCJjbGkuc3ludGguZHVyYXRpb25cIiAmJlxuICAgICAgICAgICAgYXR0cmlidXRlVmFsdWVzKGkpLmNvbW1hbmQgPT09IFwic3ludGhcIixcbiAgICAgICAgKSxcbiAgICAgICkudG9CZSh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KFwicmVwb3J0cyB0aGUgc3RhY2tzIG9mIGEgc3ludGggcnVuIHVuZGVyIHN5bnRoXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcInN5bnRoXCIpO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHsgc3RhY2tNZXRhZGF0YSwgcmVxdWlyZWRQcm92aWRlcnMgfSk7XG5cbiAgICAgIGNvbnN0IHN0YWNrcyA9IChhd2FpdCBkZWxpdmVyZWRJdGVtcygpKS5maWx0ZXIoXG4gICAgICAgIChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLnN0YWNrXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHN0YWNrcy5tYXAoKGkpID0+IGF0dHJpYnV0ZVZhbHVlcyhpKS5jb21tYW5kKSkudG9FcXVhbChbXG4gICAgICAgIFwic3ludGhcIixcbiAgICAgICAgXCJzeW50aFwiLFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcInJlcG9ydHMgdGhlIHN0YWNrcyBvbmNlIHBlciBwcm9jZXNzOiBhIHdhdGNoIHNlc3Npb24ncyBsYXRlciBkZXBsb3lzIGFkZCBvbmx5IHRoZWlyIGZhaWx1cmVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcIndhdGNoXCIpO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7IHN0YWNrTWV0YWRhdGEsIHJlcXVpcmVkUHJvdmlkZXJzIH0pO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGEsXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzLFxuICAgICAgICBmYWlsZWRTdGFja0NvdW50OiAxLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgZGVsaXZlcmVkSXRlbXMoKTtcbiAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFja1wiKSkudG9IYXZlTGVuZ3RoKDIpO1xuICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIFwiY2xpLnN0YWNrLnByb3ZpZGVyXCIpKS50b0hhdmVMZW5ndGgoNSk7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuc3RhY2sub3ZlcnJpZGVcIikpLnRvSGF2ZUxlbmd0aCgzKTtcbiAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFjay5mYWlsZWRcIikpLnRvRXF1YWwoW3sgdmFsdWU6IDEgfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJjb3VudHMgZmFpbGVkIHN0YWNrcyBhbmQgbmV2ZXIgc2VyaWFsaXplcyB0aGVpciBmYWlsdXJlIG1lc3NhZ2VzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJkZXN0cm95XCIsIHtcbiAgICAgICAgc3RhY2tNZXRhZGF0YSxcbiAgICAgICAgcmVxdWlyZWRQcm92aWRlcnMsXG4gICAgICAgIGZhaWxlZFN0YWNrQ291bnQ6IDIsXG4gICAgICAgIGZhaWxlZFN0YWNrczogW1wiZmFpbGVkIHRvIGRlc3Ryb3kgU0VDUkVULVNUQUNLLU5BTUU6IC9Vc2Vycy94L3N0YXRlXCJdLFxuICAgICAgfSk7XG4gICAgICBleHBlY3QoYXdhaXQgU2VudHJ5LmZsdXNoKDIwMDApKS50b0JlKHRydWUpO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpO1xuICAgICAgY29uc3QgZmFpbGVkID0gaXRlbXMuZmluZCgoaSkgPT4gaS5uYW1lID09PSBcImNsaS5zdGFjay5mYWlsZWRcIikhO1xuICAgICAgZXhwZWN0KGZhaWxlZC52YWx1ZSkudG9CZSgyKTtcbiAgICAgIGV4cGVjdChmYWlsZWQuYXR0cmlidXRlcy5jb21tYW5kLnZhbHVlKS50b0JlKFwiZGVzdHJveVwiKTtcbiAgICAgIC8vIHRoZSBmYWlsdXJlIHRocm93biBuZXh0IGlzIGNvdW50ZWQgYXMgY2xpLmNvbW1hbmQuZXJyb3IsIG5vdCBoZXJlXG4gICAgICBleHBlY3QoaXRlbXMuc29tZSgoaSkgPT4gaS5uYW1lID09PSBcImNsaS5jb21tYW5kLmNvbXBsZXRlZFwiKSkudG9CZShmYWxzZSk7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKSkubm90LnRvQ29udGFpbihcImZhaWxlZCB0byBkZXN0cm95XCIpO1xuICAgICAgZXhwZWN0KGVudmVsb3BlQm9kaWVzLmpvaW4oXCJcXG5cIikpLm5vdC50b0NvbnRhaW4oXCIvVXNlcnMveFwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwiY291bnRzIG5vIGNvbXBsZXRlZCBydW4gYW5kIG5vIGZhaWxlZCBzdGFjayBmb3IgYSBydW4gdGhhdCBmYWlsZWQgYmVmb3JlIGFueSBzdGFjayBkaWRcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGEsXG4gICAgICAgIHJlcXVpcmVkUHJvdmlkZXJzLFxuICAgICAgICBmYWlsZWRTdGFja0NvdW50OiAwLFxuICAgICAgICBydW5GYWlsZWQ6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBhd2FpdCBkZWxpdmVyZWRJdGVtcygpO1xuICAgICAgZXhwZWN0KG1ldHJpY3MoaXRlbXMsIFwiY2xpLnN0YWNrXCIpKS50b0hhdmVMZW5ndGgoMik7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuc3RhY2suZmFpbGVkXCIpKS50b0VxdWFsKFtdKTtcbiAgICAgIGV4cGVjdChpdGVtcy5zb21lKChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLmNvbW1hbmQuY29tcGxldGVkXCIpKS50b0JlKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KFwibmV2ZXIgc2VyaWFsaXplcyBzdGFjayBuYW1lcywgcmVzb3VyY2UgaWRzIG9yIG1vZHVsZSBwYXRoc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiZGVwbG95XCIsIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgICBzdGFja01ldGFkYXRhLFxuICAgICAgICByZXF1aXJlZFByb3ZpZGVycyxcbiAgICAgICAgZmFpbGVkU3RhY2tDb3VudDogMSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCk7XG4gICAgICAvLyB0aGUgc2NhbiBiZWxvdyBpcyBvdmVyIHR3byBzdGFja3MsIHRocmVlIG92ZXJyaWRlIHR5cGVzLCBmaXZlXG4gICAgICAvLyBwcm92aWRlcnMgYW5kIHRoZSBmYWlsZWQgY291bnRcbiAgICAgIGV4cGVjdChpdGVtcy5maWx0ZXIoKGkpID0+IGkubmFtZS5zdGFydHNXaXRoKFwiY2xpLnN0YWNrXCIpKSkudG9IYXZlTGVuZ3RoKFxuICAgICAgICAxMSxcbiAgICAgICk7XG4gICAgICBjb25zdCBieXRlcyA9IGVudmVsb3BlQm9kaWVzLmpvaW4oXCJcXG5cIik7XG4gICAgICBleHBlY3QoYnl0ZXMpLm5vdC50b0NvbnRhaW4oXCJTRUNSRVQtU1RBQ0stTkFNRVwiKTtcbiAgICAgIGV4cGVjdChieXRlcykubm90LnRvQ29udGFpbihcInNlY3JldC1yZXNvdXJjZS1pZFwiKTtcbiAgICAgIGV4cGVjdChieXRlcykubm90LnRvQ29udGFpbihcInNlY3JldC1wYXRoXCIpO1xuICAgICAgZXhwZWN0KGJ5dGVzKS5ub3QudG9Db250YWluKFwidGZlLmNvcnAuZXhhbXBsZS5jb21cIik7XG4gICAgICBleHBlY3QoYnl0ZXMpLm5vdC50b0NvbnRhaW4oXCJhY21lLW9yZ1wiKTtcbiAgICB9KTtcblxuICAgIC8vIHRoZSBtZXRhZGF0YSBpcyByZWFkIGZyb20gZGlzaywgd3JpdHRlbiBieSB3aGF0ZXZlciBsaWJyYXJ5IHZlcnNpb25cbiAgICAvLyB0aGUgcHJvamVjdCBoYXNcbiAgICBpdChcInRvbGVyYXRlcyBtYWxmb3JtZWQgbWV0YWRhdGEgZW50cmllcyBhbmQgY291bnRzIG9ubHkgdGhlIHJlYWwgc3RhY2tzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGE6IFtudWxsLCBcIm5vcGVcIiwgeyBvdmVycmlkZXM6IFwibm9wZVwiLCBpbXBvcnRzOiBbXSB9XSxcbiAgICAgICAgcmVxdWlyZWRQcm92aWRlcnM6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgeyBhd3M6IFwibm9wZVwiIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgZGVsaXZlcmVkSXRlbXMoKTtcbiAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFja1wiKSkudG9FcXVhbChbXG4gICAgICAgIHsgdmFsdWU6IDEsIGJhY2tlbmQ6IFwidW5rbm93blwiLCBjbG91ZDogZmFsc2UsIC4uLm5vQ291bnRzIH0sXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFjay5vdmVycmlkZVwiKSkudG9FcXVhbChbXSk7XG4gICAgICBleHBlY3QobWV0cmljcyhpdGVtcywgXCJjbGkuc3RhY2sucHJvdmlkZXJcIikpLnRvRXF1YWwoW1xuICAgICAgICB7IHZhbHVlOiAxLCBwcm92aWRlcjogXCJoYXNoaWNvcnAvYXdzXCIsIGJpbmRpbmc6IFwiZ2VuZXJhdGVkXCIgfSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KGl0ZW1zLnNvbWUoKGkpID0+IGkubmFtZSA9PT0gXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIikpLnRvQmUodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiYXR0cmlidXRlIHZhbGlkYXRpb25cIiwgKCkgPT4ge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgaW5pdFNlbnRyeVdpdGhDYXB0dXJpbmdUcmFuc3BvcnQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwib21pdHMgYW4gdW5zdXBwb3J0ZWQgbGFuZ3VhZ2UsIHJlYWQgZnJvbSBjZGt0Zi5qc29uIGF0IHN0YXJ0IG9yIHBhc3NlZCBhdCB0aGUgZW5kXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICBsYW5ndWFnZTogXCJydXN0OyBEUk9QIFRBQkxFXCIsXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgc3RhcnRDb21tYW5kVGVsZW1ldHJ5KFwiY29udmVydFwiKTtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJjb252ZXJ0XCIsIHsgbGFuZ3VhZ2U6IFwiY29ib2w7IERST1AgVEFCTEVcIiB9KTtcbiAgICAgIGV4cGVjdChhd2FpdCBTZW50cnkuZmx1c2goMjAwMCkpLnRvQmUodHJ1ZSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcyk7XG4gICAgICBleHBlY3QoaXRlbXMubWFwKChpKSA9PiBpLm5hbWUpKS50b0VxdWFsKFtcbiAgICAgICAgXCJjbGkuY29tbWFuZC5pbnZva2VkXCIsXG4gICAgICAgIFwiY2xpLmNvbW1hbmQuY29tcGxldGVkXCIsXG4gICAgICBdKTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBleHBlY3QoaXRlbS5hdHRyaWJ1dGVzKS5ub3QudG9IYXZlUHJvcGVydHkoXCJsYW5ndWFnZVwiKTtcbiAgICAgIH1cbiAgICAgIGV4cGVjdChlbnZlbG9wZUJvZGllcy5qb2luKFwiXFxuXCIpKS5ub3QudG9Db250YWluKFwiRFJPUCBUQUJMRVwiKTtcbiAgICB9KTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW1wic3ludGhcIiwgeyBzeW50aE9yaWdpbjogXCJ3YXRjaFwiIH0sIFwic3ludGhfb3JpZ2luXCIsIFwid2F0Y2hcIl0sXG4gICAgICBbXCJzeW50aFwiLCB7IHN5bnRoT3JpZ2luOiBcIi9Vc2Vycy94XCIgfSwgXCJzeW50aF9vcmlnaW5cIiwgdW5kZWZpbmVkXSxcbiAgICAgIFtcImluaXRcIiwgeyBpc1JlbW90ZTogdHJ1ZSB9LCBcImlzX3JlbW90ZVwiLCB0cnVlXSxcbiAgICAgIFtcImluaXRcIiwgeyB0ZW1wbGF0ZTogXCJnb1wiIH0sIFwidGVtcGxhdGVcIiwgXCJnb1wiXSxcbiAgICAgIFtcImNvbnZlcnRcIiwgeyBudW1iZXJPZlByb3ZpZGVyczogMiB9LCBcInByb3ZpZGVyX2NvdW50XCIsIDJdLFxuICAgICAgW1wiY29udmVydFwiLCB7IG51bWJlck9mTW9kdWxlczogMSB9LCBcIm1vZHVsZV9jb3VudFwiLCAxXSxcbiAgICAgIFtcImNvbnZlcnRcIiwgeyBjb252ZXJ0ZWRMaW5lczogNDIgfSwgXCJjb252ZXJ0ZWRfbGluZXNcIiwgNDJdLFxuICAgICAgW1wiY29udmVydFwiLCB7IGNvbnZlcnRlZExpbmVzOiBcIjQyXCIgfSwgXCJjb252ZXJ0ZWRfbGluZXNcIiwgdW5kZWZpbmVkXSxcbiAgICAgIFtcImNvbnZlcnRcIiwgeyBjb252ZXJ0ZWRMaW5lczogTmFOIH0sIFwiY29udmVydGVkX2xpbmVzXCIsIHVuZGVmaW5lZF0sXG4gICAgXSkoXG4gICAgICBcIiVzOiAlaiBmb3J3YXJkcyAlcyBhcyAlalwiLFxuICAgICAgYXN5bmMgKGNvbW1hbmQsIHBheWxvYWQsIGF0dHJpYnV0ZSwgZXhwZWN0ZWQpID0+IHtcbiAgICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShjb21tYW5kLCBwYXlsb2FkKTtcbiAgICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgICBjb25zdCBjb21wbGV0ZWQgPSBwYXJzZU1ldHJpY0l0ZW1zKGVudmVsb3BlQm9kaWVzKS5maW5kKFxuICAgICAgICAgIChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLmNvbW1hbmQuY29tcGxldGVkXCIsXG4gICAgICAgICkhO1xuICAgICAgICBpZiAoZXhwZWN0ZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGV4cGVjdChjb21wbGV0ZWQuYXR0cmlidXRlcykubm90LnRvSGF2ZVByb3BlcnR5KGF0dHJpYnV0ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhjb21wbGV0ZWQpW2F0dHJpYnV0ZV0pLnRvQmUoZXhwZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG5cbiAgICBpdC5lYWNoKFtcbiAgICAgIFtcIj49IDEuOS4wXCIsIFwiPj0xLjkuMFwiXSxcbiAgICAgIFtcIn4xLjhcIiwgXCI+PTEuOC4wIDwxLjkuMC0wXCJdLFxuICAgICAgW1wiMS4yLjMgLSAyLjAuMFwiLCBcIj49MS4yLjMgPD0yLjAuMFwiXSxcbiAgICAgIFtcIj49MS4wLjAgPDIuMC4wIHx8IDEuMi4zXCIsIFwiPj0xLjAuMCA8Mi4wLjB8fDEuMi4zXCJdLFxuICAgICAgW1wibGF0ZXN0IC9Vc2Vycy94XCIsIFwiaW52YWxpZFwiXSxcbiAgICAgIFtcIj49IDEuMC4wLUxFQUstVFYtUFJFUkVMRUFTRS5jb3JwLmV4YW1wbGUuY29tXCIsIFwiaW52YWxpZFwiXSxcbiAgICAgIFtcIjEuMi4zLWFjbWUuaW50ZXJuYWxcIiwgXCJpbnZhbGlkXCJdLFxuICAgICAgW1wiMS4yLjMrTEVBSy1UVi1CVUlMRC5qb2hucy1tYWNib29rXCIsIFwiaW52YWxpZFwiXSxcbiAgICAgIFtcIj49MS4wLjAgPDIuMC4wIHx8IDEuMi4zLUxFQUstT1IuaG9zdFwiLCBcImludmFsaWRcIl0sXG4gICAgICBbXCI+PTEuMC4wIFwiICsgXCJ8fDEuMC4wIFwiLnJlcGVhdCgxMCksIFwiaW52YWxpZFwiXSxcbiAgICBdKShcImZvcndhcmRzIHRoZSBkZWNsYXJlZCB0YXJnZXQgJXAgYXMgJXBcIiwgKHJhbmdlLCBleHBlY3RlZCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgIHRhcmdldFZlcnNpb25zOiB7IHRlcnJhZm9ybTogcmFuZ2UgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KGdldFByb2plY3RUYXJnZXRBdHRyaWJ1dGVzKHdvcmtkaXIpLnRhcmdldF90ZXJyYWZvcm0pLnRvQmUoXG4gICAgICAgIGV4cGVjdGVkLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KFwicmVkdWNlcyBhIGJhY2tlbmQgb3V0c2lkZSB0aGUgYnVpbHQtaW4ga2luZHMgYW5kIG92ZXJyaWRlIGtleXMgb3V0c2lkZSB0aGUgdHlwZSBncmFtbWFyIHRvIG90aGVyXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7XG4gICAgICAgIHN0YWNrTWV0YWRhdGE6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2ZXJzaW9uOiBcIjAuMjEuMCtidWlsZC5cIiArIFwieFwiLnJlcGVhdCg0MCksXG4gICAgICAgICAgICBiYWNrZW5kOiBcInMzIGJ1Y2tldD0vVXNlcnMveC9zdGF0ZVwiLFxuICAgICAgICAgICAgb3ZlcnJpZGVzOiB7XG4gICAgICAgICAgICAgIGF3c19zM19idWNrZXQ6IFtcInRhZ3NcIl0sXG4gICAgICAgICAgICAgIHRlcnJhZm9ybV9yZW1vdGVfc3RhdGU6IFtcImJhY2tlbmRcIl0sXG4gICAgICAgICAgICAgIFwibW9kdWxlLnRlcnJhZm9ybS1hd3MtbW9kdWxlcy92cGMvYXdzXCI6IFtcInByb3ZpZGVyc1wiXSxcbiAgICAgICAgICAgICAgXCJyZXNvdXJjZSB3aXRoIHNwYWNlcyAvVXNlcnMveFwiOiBbXCJ0YWdzXCJdLFxuICAgICAgICAgICAgICBBV1NfUzNfQnVja2V0OiBbXCJ0YWdzXCJdLFxuICAgICAgICAgICAgICBbXCJhd3NfXCIgKyBcInhcIi5yZXBlYXQoNzApXTogW1widGFnc1wiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHZlcnNpb246IFwiZGV2LS9Vc2Vycy94XCIsIGJhY2tlbmQ6IFwiUzNcIiB9LFxuICAgICAgICAgIHsgdmVyc2lvbjogXCJkZXYtL1VzZXJzL3hcIiB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgZGVsaXZlcmVkSXRlbXMoKTtcbiAgICAgIC8vIGJ1aWxkIG1ldGFkYXRhIGlzIHN0cmlwcGVkIGxpa2UgYmluYXJ5X3ZlcnNpb247IGEgdmVyc2lvbiB3aXRob3V0IGFcbiAgICAgIC8vIE1BSk9SLk1JTk9SLlBBVENIIHByZWZpeCB5aWVsZHMgbm8gYXR0cmlidXRlIGF0IGFsbFxuICAgICAgZXhwZWN0KFxuICAgICAgICBtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFja1wiKS5tYXAoKHN0YWNrKSA9PiBbXG4gICAgICAgICAgc3RhY2suYmFja2VuZCxcbiAgICAgICAgICBzdGFjay5saWJyYXJ5X3ZlcnNpb24sXG4gICAgICAgIF0pLFxuICAgICAgKS50b0VxdWFsKFtcbiAgICAgICAgW1wib3RoZXJcIiwgXCIwLjIxLjBcIl0sXG4gICAgICAgIFtcIm90aGVyXCIsIHVuZGVmaW5lZF0sXG4gICAgICAgIFtcInVua25vd25cIiwgdW5kZWZpbmVkXSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KFxuICAgICAgICBtZXRyaWNzKGl0ZW1zLCBcImNsaS5zdGFjay5vdmVycmlkZVwiKS5tYXAoKG8pID0+IFtcbiAgICAgICAgICBvLnJlc291cmNlX3R5cGUsXG4gICAgICAgICAgby5vdmVycmlkZV9jb3VudCxcbiAgICAgICAgXSksXG4gICAgICApLnRvRXF1YWwoW1xuICAgICAgICBbXCJhd3NfczNfYnVja2V0XCIsIDFdLFxuICAgICAgICBbXCJtb2R1bGUudGVycmFmb3JtLWF3cy1tb2R1bGVzL3ZwYy9hd3NcIiwgMV0sXG4gICAgICAgIFtcIm90aGVyXCIsIDNdLFxuICAgICAgICBbXCJ0ZXJyYWZvcm1fcmVtb3RlX3N0YXRlXCIsIDFdLFxuICAgICAgXSk7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKSkubm90LnRvQ29udGFpbihcIi9Vc2Vycy94XCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcInByb3ZpZGVyIGJpbmRpbmcgY2xhc3NpZmljYXRpb25cIiwgKCkgPT4ge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgaW5pdFNlbnRyeVdpdGhDYXB0dXJpbmdUcmFuc3BvcnQoKTtcbiAgICB9KTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIGJpbmRpbmdPZihzb3VyY2U6IHN0cmluZykge1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHtcbiAgICAgICAgc3RhY2tNZXRhZGF0YTogW3t9XSxcbiAgICAgICAgcmVxdWlyZWRQcm92aWRlcnM6IFt7IHByb3ZpZGVyOiB7IHNvdXJjZSB9IH1dLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbWV0cmljcyhhd2FpdCBkZWxpdmVyZWRJdGVtcygpLCBcImNsaS5zdGFjay5wcm92aWRlclwiKS5tYXAoXG4gICAgICAgIChwcm92aWRlcikgPT4gcHJvdmlkZXIuYmluZGluZyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaXQuZWFjaChbXG4gICAgICBbXCJhd3NcIiwgXCJnZW5lcmF0ZWRcIl0sXG4gICAgICBbXCJIYXNoaWNvcnAvUmFuZG9tXCIsIFwiZ2VuZXJhdGVkXCJdLFxuICAgICAgW1wia3JldXp3ZXJrZXIvZG9ja2VyXCIsIFwiZ2VuZXJhdGVkXCJdLFxuICAgICAgW1wiaGFzaGljb3JwL2dvb2dsZVwiLCBcImdlbmVyYXRlZFwiXSxcbiAgICAgIFtcImF6dXJlcm1cIiwgXCJnZW5lcmF0ZWRcIl0sXG4gICAgICBbXCJoYXNoaWNvcnAvbnVsbFwiLCBcInByZWJ1aWx0XCJdLFxuICAgICAgW1widGZlLmNvcnAuZXhhbXBsZS5jb20vYWNtZS1vcmcvdmF1bHRcIiwgXCJnZW5lcmF0ZWRcIl0sXG4gICAgICAvLyBhbm90aGVyIHByaXZhdGUgc291cmNlIGlzIG5vdCB0aGUgZ2VuZXJhdGVkIG9uZSwgZXZlbiB0aG91Z2ggYm90aFxuICAgICAgLy8gcmVhY2ggdGhlIG1ldHJpYyBhcyBcInByaXZhdGUtcmVnaXN0cnlcIlxuICAgICAgW1widGZlLmNvcnAuZXhhbXBsZS5jb20vb3RoZXItb3JnL3ZhdWx0XCIsIFwicHJlYnVpbHRcIl0sXG4gICAgXSkoXG4gICAgICBcInNlbmRzIHRoZSByZXF1aXJlZCBwcm92aWRlciAlcyBhcyAlcyBmb3IgdGhlIHByb2plY3QncyB0ZXJyYWZvcm1Qcm92aWRlcnNcIixcbiAgICAgIGFzeW5jIChzb3VyY2UsIGV4cGVjdGVkKSA9PiB7XG4gICAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICAgIHRlcnJhZm9ybVByb3ZpZGVyczogW1xuICAgICAgICAgICAgXCJhd3NAfj41LjBcIixcbiAgICAgICAgICAgIFwiaGFzaGljb3JwL3JhbmRvbUAzLjYuMFwiLFxuICAgICAgICAgICAgXCJyZWdpc3RyeS50ZXJyYWZvcm0uaW8va3JldXp3ZXJrZXIvZG9ja2VyXCIsXG4gICAgICAgICAgICB7IG5hbWU6IFwiZ29vZ2xlXCIsIHNvdXJjZTogXCJoYXNoaWNvcnAvZ29vZ2xlXCIsIHZlcnNpb246IFwifj4gNS4wXCIgfSxcbiAgICAgICAgICAgIHsgbmFtZTogXCJhenVyZXJtXCIgfSxcbiAgICAgICAgICAgIHsgdmVyc2lvbjogXCIxLjAuMFwiIH0sXG4gICAgICAgICAgICA0MixcbiAgICAgICAgICAgIFwiVEZFLmNvcnAuZXhhbXBsZS5jb20vYWNtZS1vcmcvdmF1bHRAfj4zLjBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QoYXdhaXQgYmluZGluZ09mKHNvdXJjZSkpLnRvRXF1YWwoW2V4cGVjdGVkXSk7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICBpdChcInNlbmRzIGV2ZXJ5IHByb3ZpZGVyIGFzIHByZWJ1aWx0IHdoZW4gdGVycmFmb3JtUHJvdmlkZXJzIGlzIG5vdCBhIGxpc3RcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgIHRlcnJhZm9ybVByb3ZpZGVyczogXCJhd3NcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoYXdhaXQgYmluZGluZ09mKFwiYXdzXCIpKS50b0VxdWFsKFtcInByZWJ1aWx0XCJdKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJzb3VyY2Ugbm9ybWFsaXphdGlvblwiLCAoKSA9PiB7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBpbml0U2VudHJ5V2l0aENhcHR1cmluZ1RyYW5zcG9ydCgpO1xuICAgIH0pO1xuXG4gICAgaXQuZWFjaChbXG4gICAgICBbXCJhd3NcIiwgXCJoYXNoaWNvcnAvYXdzXCJdLFxuICAgICAgW1wiYXdzQH4+NS4wXCIsIFwiaGFzaGljb3JwL2F3c1wiXSxcbiAgICAgIFtcIkhhc2hpY29ycC9BV1NANS4xLjBcIiwgXCJoYXNoaWNvcnAvYXdzXCJdLFxuICAgICAgW1wicmVnaXN0cnkudGVycmFmb3JtLmlvL2hhc2hpY29ycC9hd3NcIiwgXCJoYXNoaWNvcnAvYXdzXCJdLFxuICAgICAgW1wicmVnaXN0cnkub3BlbnRvZnUub3JnL2hhc2hpY29ycC9hd3NcIiwgXCJoYXNoaWNvcnAvYXdzXCJdLFxuICAgICAgW1widGZlLmxlYWstaG9zdC5leGFtcGxlL2xlYWstb3JnL2F3c1wiLCBcInByaXZhdGUtcmVnaXN0cnlcIl0sXG4gICAgICBbXCJsb2NhbGhvc3Q6ODA4MC9sZWFrLW9yZy9hd3NcIiwgXCJwcml2YXRlLXJlZ2lzdHJ5XCJdLFxuICAgICAgW1wiLi9sZWFrLXByb3ZpZGVyXCIsIFwib3RoZXJcIl0sXG4gICAgICBbXCIuLi9sZWFrL3Byb3ZpZGVyXCIsIFwib3RoZXJcIl0sXG4gICAgICBbXCIvYWJzL2xlYWsvcHJvdmlkZXJcIiwgXCJvdGhlclwiXSxcbiAgICAgIFtcImxlYWstYS9iL2NcIiwgXCJvdGhlclwiXSxcbiAgICAgIFtcIlwiLCBcIm90aGVyXCJdLFxuICAgICAgW1wicmVnaXN0cnkudGVycmFmb3JtLmlvL2xlYWstbmFtZXNwYWNlXCIsIFwib3RoZXJcIl0sXG4gICAgICBbYCR7XCJuXCIucmVwZWF0KDY1KX0vYXdzYCwgXCJvdGhlclwiXSxcbiAgICAgIFtgJHtcIm5cIi5yZXBlYXQoNjQpfS9hd3NgLCBgJHtcIm5cIi5yZXBlYXQoNjQpfS9hd3NgXSxcbiAgICAgIFtgJHtcIm5cIi5yZXBlYXQoNjQpfS8ke1widFwiLnJlcGVhdCg2NCl9YCwgXCJvdGhlclwiXSxcbiAgICBdKShcInNlbmRzIHRoZSBwcm92aWRlciBzb3VyY2UgJXMgYXMgJXNcIiwgYXN5bmMgKHNvdXJjZSwgZXhwZWN0ZWQpID0+IHtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJnZXRcIiwgeyB0YXJnZXRzOiBbeyB0eXBlOiBcInByb3ZpZGVyXCIsIHNvdXJjZSB9XSB9KTtcblxuICAgICAgZXhwZWN0KFxuICAgICAgICBtZXRyaWNzKGF3YWl0IGRlbGl2ZXJlZEl0ZW1zKCksIFwiY2xpLmdldC5wcm92aWRlclwiKS5tYXAoXG4gICAgICAgICAgKGl0ZW0pID0+IGl0ZW0ucHJvdmlkZXIsXG4gICAgICAgICksXG4gICAgICApLnRvRXF1YWwoW2V4cGVjdGVkXSk7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKSkubm90LnRvQ29udGFpbihcImxlYWtcIik7XG4gICAgfSk7XG5cbiAgICBpdC5lYWNoKFtcbiAgICAgIFtcInRlcnJhZm9ybS1hd3MtbW9kdWxlcy92cGMvYXdzXCIsIFwidGVycmFmb3JtLWF3cy1tb2R1bGVzL3ZwYy9hd3NcIl0sXG4gICAgICBbXCJUZXJyYWZvcm0tQVdTLU1vZHVsZXMvVlBDL2F3c1wiLCBcInRlcnJhZm9ybS1hd3MtbW9kdWxlcy92cGMvYXdzXCJdLFxuICAgICAgLy8gb25lIHJvdyBwZXIgZmFsbHRocm91Z2g6IGV2ZXJ5dGhpbmcgdGhlIGdyYW1tYXIgcmVqZWN0cyBpcyBcIm90aGVyXCJcbiAgICAgIFtcIlRlcnJhZm9ybS1BV1MtTW9kdWxlcy9sZWFrLXZwYy9hd3M/cmVmPXY1LjAuMFwiLCBcIm90aGVyXCJdLFxuICAgICAgW2Ake1wiblwiLnJlcGVhdCg2NCl9L3ZwYy9hd3NgLCBgJHtcIm5cIi5yZXBlYXQoNjQpfS92cGMvYXdzYF0sXG4gICAgICBbYCR7XCJuXCIucmVwZWF0KDY1KX0vdnBjL2F3c2AsIFwib3RoZXJcIl0sXG4gICAgICBbXCJhcHAudGVycmFmb3JtLmlvL2xlYWstb3JnL3ZwYy9hd3NcIiwgXCJwcml2YXRlLXJlZ2lzdHJ5XCJdLFxuICAgICAgW1wiLi9tb2R1bGVzL2xlYWstdnBjXCIsIFwibG9jYWxcIl0sXG4gICAgICBbXCIuLi9zaGFyZWQvbGVhay12cGNcIiwgXCJsb2NhbFwiXSxcbiAgICAgIFtcIi9hYnMvcGF0aC9sZWFrLXZwY1wiLCBcImxvY2FsXCJdLFxuICAgICAgW1wiZ2l0QGdpdGh1Yi5jb206bGVhay1vcmcvcmVwby5naXRcIiwgXCJnaXRcIl0sXG4gICAgICBbXCJnaXRodWIuY29tL2xlYWstb3JnL3JlcG9cIiwgXCJnaXRcIl0sXG4gICAgICBbXCJiaXRidWNrZXQub3JnL2xlYWstb3JnL3JlcG9cIiwgXCJnaXRcIl0sXG4gICAgICBbXCJodHRwczovL2xlYWstaG9zdC5leGFtcGxlL3ZwYy56aXBcIiwgXCJnaXRcIl0sXG4gICAgICBbXCJzMy1ldS13ZXN0LTEuYW1hem9uYXdzLmNvbS9sZWFrLWJ1Y2tldC92cGMuemlwXCIsIFwiZ2l0XCJdLFxuICAgICAgW1wid3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvbGVhay1idWNrZXQvdnBjXCIsIFwiZ2l0XCJdLFxuICAgICAgLy8gZm9yY2VkIGdldHRlcnMgd2l0aG91dCBhIFVSTCBzY2hlbWUgYmVoaW5kIHRoZW1cbiAgICAgIFtcImdpdDo6bGVhay1ob3N0LmV4YW1wbGUvbGVhay1vcmcvcmVwby5naXRcIiwgXCJnaXRcIl0sXG4gICAgICBbXCJoZzo6bGVhay1ob3N0LmV4YW1wbGUvbGVhay1yZXBvXCIsIFwiZ2l0XCJdLFxuICAgICAgW1wiczM6OmxlYWstYnVja2V0L3ZwYy56aXBcIiwgXCJnaXRcIl0sXG4gICAgICBbXCJnY3M6OmxlYWstYnVja2V0L3ZwY1wiLCBcImdpdFwiXSxcbiAgICBdKShcInNlbmRzIHRoZSBtb2R1bGUgc291cmNlICVzIGFzICVzXCIsIGFzeW5jIChzb3VyY2UsIGV4cGVjdGVkKSA9PiB7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiZ2V0XCIsIHsgdGFyZ2V0czogW3sgdHlwZTogXCJtb2R1bGVcIiwgc291cmNlIH1dIH0pO1xuXG4gICAgICBleHBlY3QoXG4gICAgICAgIG1ldHJpY3MoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSwgXCJjbGkuZ2V0Lm1vZHVsZVwiKS5tYXAoXG4gICAgICAgICAgKGl0ZW0pID0+IGl0ZW0ubW9kdWxlLFxuICAgICAgICApLFxuICAgICAgKS50b0VxdWFsKFtleHBlY3RlZF0pO1xuICAgICAgZXhwZWN0KGVudmVsb3BlQm9kaWVzLmpvaW4oXCJcXG5cIikpLm5vdC50b0NvbnRhaW4oXCJsZWFrXCIpO1xuICAgIH0pO1xuXG4gICAgaXQuZWFjaChbXG4gICAgICBbXCI+PSAxLjIsIDwgMi4wXCIsIFwiPj0gMS4yLCA8IDIuMFwiXSxcbiAgICAgIFtcIn4+IDUuMFwiLCBcIn4+IDUuMFwiXSxcbiAgICAgIFtcIj0gMS4wXCIsIFwiPSAxLjBcIl0sXG4gICAgICBbXCIhPSAxLjIuM1wiLCBcIiE9IDEuMi4zXCJdLFxuICAgICAgW1wiMS4yLjNcIiwgXCIxLjIuM1wiXSxcbiAgICAgIFtcIiAgPj0gMS4wICwgIDwgMi4wICBcIiwgXCI+PSAxLjAsIDwgMi4wXCJdLFxuICAgICAgW1wifj41LjAsIT01LjEuMFwiLCBcIn4+IDUuMCwgIT0gNS4xLjBcIl0sXG4gICAgICBbXCI+PSAxLjAuMC1sZWFrLXByZXJlbGVhc2UuY29ycFwiLCBcImludmFsaWRcIl0sXG4gICAgICBbXCIxLjIuMytsZWFrLWJ1aWxkLmhvc3RcIiwgXCJpbnZhbGlkXCJdLFxuICAgICAgW1wifj4gNS4wICMgL1VzZXJzL2xlYWtcIiwgXCJpbnZhbGlkXCJdLFxuICAgICAgW1wiPj0gMS4yIHx8IDwgMi4wXCIsIFwiaW52YWxpZFwiXSxcbiAgICAgIC8vIHZhbGlkIGJ5IHRoZSBncmFtbWFyLCBvdmVyIHRoZSBsZW5ndGggYSBjb25zdHJhaW50IG1heSBoYXZlXG4gICAgICBbQXJyYXkoMTIpLmZpbGwoXCIhPSAxLjAuMFwiKS5qb2luKFwiLCBcIiksIFwiaW52YWxpZFwiXSxcbiAgICBdKShcInNlbmRzIHRoZSBwcm92aWRlciBjb25zdHJhaW50ICVwIGFzICVwXCIsIGFzeW5jICh2ZXJzaW9uLCBleHBlY3RlZCkgPT4ge1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHtcbiAgICAgICAgc3RhY2tNZXRhZGF0YTogW3t9XSxcbiAgICAgICAgcmVxdWlyZWRQcm92aWRlcnM6IFt7IGF3czogeyBzb3VyY2U6IFwiYXdzXCIsIHZlcnNpb24gfSB9XSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoXG4gICAgICAgIG1ldHJpY3MoYXdhaXQgZGVsaXZlcmVkSXRlbXMoKSwgXCJjbGkuc3RhY2sucHJvdmlkZXJcIikubWFwKFxuICAgICAgICAgIChwcm92aWRlcikgPT4gcHJvdmlkZXIudmVyc2lvbl9jb25zdHJhaW50LFxuICAgICAgICApLFxuICAgICAgKS50b0VxdWFsKFtleHBlY3RlZF0pO1xuICAgICAgZXhwZWN0KGVudmVsb3BlQm9kaWVzLmpvaW4oXCJcXG5cIikpLm5vdC50b0NvbnRhaW4oXCJsZWFrXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcInBhY2thZ2UgbWFuYWdlclwiLCAoKSA9PiB7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBpbml0U2VudHJ5V2l0aENhcHR1cmluZ1RyYW5zcG9ydCgpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIGplc3QuZG9udE1vY2soXCIuL25vZGUtcGFja2FnZS1tYW5hZ2VyXCIpO1xuICAgIH0pO1xuXG4gICAgLy8gYSBjb3B5IG9mIHRoZSBtb2R1bGUgd2hvc2Ugbm9kZSBkZXRlY3RvciBpcyByZXBsYWNlZFxuICAgIGZ1bmN0aW9uIHRlbGVtZXRyeVdpdGhOb2RlRGV0ZWN0b3IoZGV0ZWN0OiAoKSA9PiBzdHJpbmcpIHtcbiAgICAgIGxldCBjb3B5ITogdHlwZW9mIGltcG9ydChcIi4vdGVsZW1ldHJ5XCIpO1xuICAgICAgamVzdC5pc29sYXRlTW9kdWxlcygoKSA9PiB7XG4gICAgICAgIGplc3QuZG9Nb2NrKFwiLi9ub2RlLXBhY2thZ2UtbWFuYWdlclwiLCAoKSA9PiAoe1xuICAgICAgICAgIGRldGVjdE5vZGVQYWNrYWdlTWFuYWdlcjogZGV0ZWN0LFxuICAgICAgICB9KSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgICAgIGNvcHkgPSByZXF1aXJlKFwiLi90ZWxlbWV0cnlcIik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjb3B5O1xuICAgIH1cblxuICAgIC8vIG9uZSBzdWNjZXNzZnVsIGFuZCBvbmUgZmFpbGVkIGVuZCwgc28gZXZlcnkgY29tbWFuZCBtZXRyaWMgaXMgY292ZXJlZFxuICAgIGFzeW5jIGZ1bmN0aW9uIHJ1bk1ldHJpY3MoXG4gICAgICB0ZWxlbWV0cnk6IFBpY2s8XG4gICAgICAgIHR5cGVvZiBpbXBvcnQoXCIuL3RlbGVtZXRyeVwiKSxcbiAgICAgICAgXCJzdGFydENvbW1hbmRUZWxlbWV0cnlcIiB8IFwic2VuZFRlbGVtZXRyeVwiXG4gICAgICA+ID0geyBzdGFydENvbW1hbmRUZWxlbWV0cnksIHNlbmRUZWxlbWV0cnkgfSxcbiAgICApOiBQcm9taXNlPE1ldHJpY0l0ZW1bXT4ge1xuICAgICAgYXdhaXQgdGVsZW1ldHJ5LnN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcInN5bnRoXCIpO1xuICAgICAgYXdhaXQgdGVsZW1ldHJ5LnNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7fSk7XG4gICAgICBhd2FpdCB0ZWxlbWV0cnkuc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHsgZXJyb3I6IHRydWUgfSk7XG4gICAgICBleHBlY3QoYXdhaXQgU2VudHJ5LmZsdXNoKDIwMDApKS50b0JlKHRydWUpO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpO1xuICAgICAgZXhwZWN0KGl0ZW1zLm1hcCgoaSkgPT4gaS5uYW1lKSkudG9FcXVhbChbXG4gICAgICAgIFwiY2xpLmNvbW1hbmQuaW52b2tlZFwiLFxuICAgICAgICBcImNsaS5jb21tYW5kLmNvbXBsZXRlZFwiLFxuICAgICAgICBcImNsaS5jb21tYW5kLmVycm9yXCIsXG4gICAgICBdKTtcbiAgICAgIHJldHVybiBpdGVtcztcbiAgICB9XG5cbiAgICBpdC5lYWNoKFtcbiAgICAgIFtcIm5vIGxvY2tmaWxlXCIsIFwibnBtXCIsIHt9XSxcbiAgICAgIFtcImEgcG5wbSBsb2NrZmlsZVwiLCBcInBucG1cIiwgeyBcInBucG0tbG9jay55YW1sXCI6IFwiXCIgfV0sXG4gICAgICBbXCJhIHlhcm4gbG9ja2ZpbGVcIiwgXCJ5YXJuXCIsIHsgXCJ5YXJuLmxvY2tcIjogXCJcIiB9XSxcbiAgICAgIFtcImEgLnlhcm5yYy55bWxcIiwgXCJ5YXJuLWJlcnJ5XCIsIHsgXCIueWFybnJjLnltbFwiOiBcIlwiIH1dLFxuICAgICAgW1xuICAgICAgICBcImEgZGVjbGFyZWQgbnBtXCIsXG4gICAgICAgIFwibnBtXCIsXG4gICAgICAgIHsgXCJwYWNrYWdlLmpzb25cIjogJ3tcInBhY2thZ2VNYW5hZ2VyXCI6XCJucG1AMTAuOC4yXCJ9JyB9LFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgXCJhIGRlY2xhcmVkIHBucG0gd2l0aCBhIGhhc2hcIixcbiAgICAgICAgXCJwbnBtXCIsXG4gICAgICAgIHsgXCJwYWNrYWdlLmpzb25cIjogJ3tcInBhY2thZ2VNYW5hZ2VyXCI6XCJwbnBtQDEwLjI2LjArc2hhNTEyLkxFQUtcIn0nIH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICBcImEgZGVjbGFyZWQgeWFybiAxXCIsXG4gICAgICAgIFwieWFyblwiLFxuICAgICAgICB7IFwicGFja2FnZS5qc29uXCI6ICd7XCJwYWNrYWdlTWFuYWdlclwiOlwieWFybkAxLjIyLjIyXCJ9JyB9LFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgXCJhIGRlY2xhcmVkIHlhcm4gNFwiLFxuICAgICAgICBcInlhcm4tYmVycnlcIixcbiAgICAgICAgeyBcInBhY2thZ2UuanNvblwiOiAne1wicGFja2FnZU1hbmFnZXJcIjpcInlhcm5ANC4xLjBcIn0nIH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICBcImFuIHVua25vd24gZGVjbGFyZWQgbWFuYWdlclwiLFxuICAgICAgICBcIm5wbVwiLFxuICAgICAgICB7IFwicGFja2FnZS5qc29uXCI6ICd7XCJwYWNrYWdlTWFuYWdlclwiOlwiYnVuQDEuMS4wLUxFQUtcIn0nIH0sXG4gICAgICBdLFxuICAgIF0pKFxuICAgICAgXCJyZXBvcnRzIGEgdHlwZXNjcmlwdCBwcm9qZWN0IHdpdGggJXMgYXMgJXAgb24gZXZlcnkgY29tbWFuZCBtZXRyaWNcIixcbiAgICAgIGFzeW5jIChfbmFtZSwgZXhwZWN0ZWQsIGZpbGVzKSA9PiB7XG4gICAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICAgIGxhbmd1YWdlOiBcInR5cGVzY3JpcHRcIixcbiAgICAgICAgfSk7XG4gICAgICAgIGZvciAoY29uc3QgW25hbWUsIGNvbnRlbnRdIG9mIE9iamVjdC5lbnRyaWVzKGZpbGVzKSkge1xuICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHdvcmtkaXIsIG5hbWUpLCBjb250ZW50IGFzIHN0cmluZyk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXdhaXQgcnVuTWV0cmljcygpKSB7XG4gICAgICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhpdGVtKS5wYWNrYWdlX21hbmFnZXIpLnRvQmUoZXhwZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKTtcbiAgICAgICAgZXhwZWN0KGJ5dGVzKS5ub3QudG9Db250YWluKFwiTEVBS1wiKTtcbiAgICAgICAgZXhwZWN0KGJ5dGVzKS5ub3QudG9Db250YWluKFwiMTAuMjYuMFwiKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW1wicHl0aG9uXCIsIHsgYXBwOiBcInBpcGVudiBydW4gcHl0aG9uIG1haW4ucHlcIiB9LCB7fSwgXCJwaXBlbnZcIl0sXG4gICAgICBbXCJweXRob25cIiwgeyBhcHA6IFwicHl0aG9uMyBtYWluLnB5XCIgfSwge30sIFwicGlwXCJdLFxuICAgICAgW1wiamF2YVwiLCB7fSwgeyBcImJ1aWxkLmdyYWRsZVwiOiBcIlwiIH0sIFwiZ3JhZGxlXCJdLFxuICAgICAgW1wiamF2YVwiLCB7fSwgeyBcInBvbS54bWxcIjogXCJcIiB9LCBcIm1hdmVuXCJdLFxuICAgICAgW1wiY3NoYXJwXCIsIHt9LCB7fSwgXCJudWdldFwiXSxcbiAgICAgIFtcImdvXCIsIHt9LCB7fSwgXCJnb1wiXSxcbiAgICBdKShcbiAgICAgIFwicmVwb3J0cyBhICVzIHByb2plY3Qgd2l0aCAlaiBhbmQgZmlsZXMgJWogYXMgJXBcIixcbiAgICAgIGFzeW5jIChsYW5ndWFnZSwgY29uZmlnLCBmaWxlcywgZXhwZWN0ZWQpID0+IHtcbiAgICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgICAgbGFuZ3VhZ2UsXG4gICAgICAgICAgLi4uY29uZmlnLFxuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChjb25zdCBbbmFtZSwgY29udGVudF0gb2YgT2JqZWN0LmVudHJpZXMoZmlsZXMpKSB7XG4gICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4od29ya2RpciwgbmFtZSksIGNvbnRlbnQgYXMgc3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBhd2FpdCBydW5NZXRyaWNzKCkpIHtcbiAgICAgICAgICBleHBlY3QoYXR0cmlidXRlVmFsdWVzKGl0ZW0pLnBhY2thZ2VfbWFuYWdlcikudG9CZShleHBlY3RlZCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW1wibm8gY2RrdGYuanNvblwiLCB1bmRlZmluZWRdLFxuICAgICAgW1wiYW4gdW5zdXBwb3J0ZWQgbGFuZ3VhZ2VcIiwgeyBsYW5ndWFnZTogXCJydXN0XCIgfV0sXG4gICAgICBbXCJubyBsYW5ndWFnZVwiLCB7IGFwcDogXCJwaXBlbnYgcnVuIHB5dGhvbiBtYWluLnB5XCIgfV0sXG4gICAgICBbXCJhIHB5dGhvbiBwcm9qZWN0IHdpdGhvdXQgYW4gYXBwIGNvbW1hbmRcIiwgeyBsYW5ndWFnZTogXCJweXRob25cIiB9XSxcbiAgICBdKShcIm9taXRzIHRoZSBhdHRyaWJ1dGUgd2l0aCAlc1wiLCBhc3luYyAoX25hbWUsIGNka3RmSnNvbikgPT4ge1xuICAgICAgaWYgKGNka3RmSnNvbikge1xuICAgICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIGNka3RmSnNvbik7XG4gICAgICB9XG4gICAgICAvLyBsb2NrZmlsZXMgYWxvbmUgbmV2ZXIgaWRlbnRpZnkgYSBwcm9qZWN0XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbih3b3JrZGlyLCBcInBucG0tbG9jay55YW1sXCIpLCBcIlwiKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiYnVpbGQuZ3JhZGxlXCIpLCBcIlwiKTtcblxuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGF3YWl0IHJ1bk1ldHJpY3MoKSkge1xuICAgICAgICBleHBlY3QoaXRlbS5hdHRyaWJ1dGVzKS5ub3QudG9IYXZlUHJvcGVydHkoXCJwYWNrYWdlX21hbmFnZXJcIik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdChcImtlZXBzIHRoZSB2YWx1ZSBkZXRlY3RlZCBhdCBzdGFydCB3aGVuIHRoZSBjd2QgY2hhbmdlcyBiZWZvcmUgdGhlIGVuZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgfSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbih3b3JrZGlyLCBcInBucG0tbG9jay55YW1sXCIpLCBcIlwiKTtcbiAgICAgIGNvbnN0IGVsc2V3aGVyZSA9IGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihvcy50bXBkaXIoKSwgXCJjZGt0bi1lbHNlLVwiKSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcImNvbnZlcnRcIik7XG4gICAgICAgIHByb2Nlc3MuY2hkaXIoZWxzZXdoZXJlKTtcbiAgICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImNvbnZlcnRcIiwge30pO1xuICAgICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwiY29udmVydFwiLCB7IGVycm9yOiB0cnVlIH0pO1xuICAgICAgICBleHBlY3QoYXdhaXQgU2VudHJ5LmZsdXNoKDIwMDApKS50b0JlKHRydWUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgcHJvY2Vzcy5jaGRpcih3b3JrZGlyKTtcbiAgICAgICAgZnMucmVtb3ZlU3luYyhlbHNld2hlcmUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpdGVtcyA9IHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpO1xuICAgICAgZXhwZWN0KGl0ZW1zKS50b0hhdmVMZW5ndGgoMyk7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhpdGVtKS5wYWNrYWdlX21hbmFnZXIpLnRvQmUoXCJwbnBtXCIpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoXCJmb3JnZXRzIHRoZSB2YWx1ZSB3aXRoIHRoZSBydW5cIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7IGxhbmd1YWdlOiBcImdvXCIgfSk7XG5cbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcInN5bnRoXCIpO1xuICAgICAgcmVzZXRDb21tYW5kVGVsZW1ldHJ5KCk7XG4gICAgICBhd2FpdCBzZW5kVGVsZW1ldHJ5KFwic3ludGhcIiwge30pO1xuICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgY29uc3QgY29tcGxldGVkID0gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcykuZmluZChcbiAgICAgICAgKGkpID0+IGkubmFtZSA9PT0gXCJjbGkuY29tbWFuZC5jb21wbGV0ZWRcIixcbiAgICAgICkhO1xuICAgICAgZXhwZWN0KGNvbXBsZXRlZC5hdHRyaWJ1dGVzKS5ub3QudG9IYXZlUHJvcGVydHkoXCJwYWNrYWdlX21hbmFnZXJcIik7XG4gICAgfSk7XG5cbiAgICBpdChcIm9taXRzIGEgZGV0ZWN0b3IgdmFsdWUgb3V0c2lkZSB0aGUgY2xvc2VkIHNldFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB0ZWxlbWV0cnkgPSB0ZWxlbWV0cnlXaXRoTm9kZURldGVjdG9yKCgpID0+IFwiYnVuQDEuMS4wIC9Vc2Vycy94XCIpO1xuXG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXdhaXQgcnVuTWV0cmljcyh0ZWxlbWV0cnkpKSB7XG4gICAgICAgIGV4cGVjdChpdGVtLmF0dHJpYnV0ZXMpLm5vdC50b0hhdmVQcm9wZXJ0eShcInBhY2thZ2VfbWFuYWdlclwiKTtcbiAgICAgIH1cbiAgICAgIGV4cGVjdChlbnZlbG9wZUJvZGllcy5qb2luKFwiXFxuXCIpKS5ub3QudG9Db250YWluKFwiYnVuXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJvbWl0cyB0aGUgYXR0cmlidXRlIHdoZW4gZGV0ZWN0aW9uIHRocm93c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwidHlwZXNjcmlwdFwiLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB0ZWxlbWV0cnkgPSB0ZWxlbWV0cnlXaXRoTm9kZURldGVjdG9yKCgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRUFDQ0VTXCIpO1xuICAgICAgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBhd2FpdCBydW5NZXRyaWNzKHRlbGVtZXRyeSkpIHtcbiAgICAgICAgZXhwZWN0KGl0ZW0uYXR0cmlidXRlcykubm90LnRvSGF2ZVByb3BlcnR5KFwicGFja2FnZV9tYW5hZ2VyXCIpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoXCJub3JtYWxpemVzIHRvIG1lbWJlcnMgb2YgdGhlIGNsb3NlZCBzZXQgb25seVwiLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgUEFDS0FHRV9NQU5BR0VSUykge1xuICAgICAgICBleHBlY3Qobm9ybWFsaXplUGFja2FnZU1hbmFnZXIobmFtZSkpLnRvQmUobmFtZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIFtcbiAgICAgICAgXCJidW5cIixcbiAgICAgICAgXCJOUE1cIixcbiAgICAgICAgXCJwbnBtQDEwLjI2LjArc2hhNTEyLmFiY1wiLFxuICAgICAgICBcIi91c3IvbG9jYWwvYmluL25wbVwiLFxuICAgICAgICBcIlwiLFxuICAgICAgICAxLFxuICAgICAgICBudWxsLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIFtcIm5wbVwiXSxcbiAgICAgIF0pIHtcbiAgICAgICAgZXhwZWN0KG5vcm1hbGl6ZVBhY2thZ2VNYW5hZ2VyKHZhbHVlKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcInJ1biBsaWZlY3ljbGVcIiwgKCkgPT4ge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgIGxhbmd1YWdlOiBcInB5dGhvblwiLFxuICAgICAgICBzZW5kVXNhZ2VUZWxlbWV0cnk6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIGluaXRTZW50cnlXaXRoQ2FwdHVyaW5nVHJhbnNwb3J0KCk7XG4gICAgfSk7XG5cbiAgICBpdChcImNvdW50cyB0aGUgcnVuIG9uY2UgYXMgaW52b2tlZCBhdCBzdGFydCwgZXZlbiB3aGVuIHJlcG9ydGluZyBpcyBpbml0aWFsaXplZCBhZ2FpblwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzdGFydENvbW1hbmRUZWxlbWV0cnkoXCJpbml0XCIpO1xuICAgICAgLy8gaW5pdCBydW5zIGdldCwgd2hpY2ggaW5pdGlhbGl6ZXMgcmVwb3J0aW5nIGEgc2Vjb25kIHRpbWVcbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcImdldFwiKTtcbiAgICAgIGV4cGVjdChhd2FpdCBTZW50cnkuZmx1c2goMjAwMCkpLnRvQmUodHJ1ZSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcyk7XG4gICAgICBleHBlY3QoaXRlbXMubWFwKChpKSA9PiBpLm5hbWUpKS50b0VxdWFsKFtcImNsaS5jb21tYW5kLmludm9rZWRcIl0pO1xuICAgICAgZXhwZWN0KGF0dHJpYnV0ZVZhbHVlcyhpdGVtc1swXSkpLnRvTWF0Y2hPYmplY3Qoe1xuICAgICAgICBjb21tYW5kOiBcImluaXRcIixcbiAgICAgICAgbGFuZ3VhZ2U6IFwicHl0aG9uXCIsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KFwiY291bnRzIG9ubHkgdGhlIHJ1bidzIG93biBjb21tYW5kIGFzIGNvbXBsZXRlZDsgYSBuZXN0ZWQgb3BlcmF0aW9uIGFkZHMgaXRzIG93biBtZXRyaWNzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcImRlcGxveVwiKTtcbiAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7IHRvdGFsVGltZTogNDIsIGxhbmd1YWdlOiBcInB5dGhvblwiIH0pO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7IGxhbmd1YWdlOiBcInB5dGhvblwiIH0pO1xuICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBwYXJzZU1ldHJpY0l0ZW1zKGVudmVsb3BlQm9kaWVzKTtcbiAgICAgIGV4cGVjdChpdGVtcy5tYXAoKGkpID0+IFtpLm5hbWUsIGF0dHJpYnV0ZVZhbHVlcyhpKS5jb21tYW5kXSkpLnRvRXF1YWwoW1xuICAgICAgICBbXCJjbGkuY29tbWFuZC5pbnZva2VkXCIsIFwiZGVwbG95XCJdLFxuICAgICAgICBbXCJjbGkuc3ludGguZHVyYXRpb25cIiwgXCJzeW50aFwiXSxcbiAgICAgICAgW1wiY2xpLmNvbW1hbmQuY29tcGxldGVkXCIsIFwiZGVwbG95XCJdLFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImNvdW50cyBhIGZhaWxlZCBydW4gb25jZSBhcyBlcnJvciwgbmV2ZXIgYXMgY29tcGxldGVkXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcInN5bnRoXCIpO1xuICAgICAgYXdhaXQgc2VuZFRlbGVtZXRyeShcInN5bnRoXCIsIHsgZXJyb3I6IHRydWUsIGVycm9yVHlwZTogXCJFeHRlcm5hbFwiIH0pO1xuICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgZXhwZWN0KHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpLm1hcCgoaSkgPT4gaS5uYW1lKSkudG9FcXVhbChbXG4gICAgICAgIFwiY2xpLmNvbW1hbmQuaW52b2tlZFwiLFxuICAgICAgICBcImNsaS5jb21tYW5kLmVycm9yXCIsXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZW1pdHMgbm90aGluZyBhdCBzdGFydCB3aGVuIHVzYWdlIHRlbGVtZXRyeSBpcyBvZmYsIGFuZCBzdGF5cyBhIG5vLW9wIGFmdGVyd2FyZHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgc2V0VXNhZ2VUZWxlbWV0cnlFbmFibGVkKGZhbHNlKTtcblxuICAgICAgYXdhaXQgc3RhcnRDb21tYW5kVGVsZW1ldHJ5KFwic3ludGhcIik7XG4gICAgICBzZXRVc2FnZVRlbGVtZXRyeUVuYWJsZWQodHJ1ZSk7XG4gICAgICBhd2FpdCBzdGFydENvbW1hbmRUZWxlbWV0cnkoXCJzeW50aFwiKTtcbiAgICAgIGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKTtcblxuICAgICAgZXhwZWN0KHBhcnNlTWV0cmljSXRlbXMoZW52ZWxvcGVCb2RpZXMpKS50b0hhdmVMZW5ndGgoMCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIHRoZSBidW5kbGUgaGFzIG9uZSBjb3B5IG9mIHRoaXMgbW9kdWxlIHBlciBlbnRyeSBwb2ludDogYmluL2NtZHMvaGFuZGxlcnMuanNcbiAgLy8gY2FwdHVyZXMgdGhlIGRlY2lzaW9uIGFuZCBzdGFydHMgdGhlIHJ1biwgYmluL2Nka3RuLmpzIGNvdW50cyB0aGUgZmFpbHVyZVxuICBkZXNjcmliZShcInNoYXJlZCBhY3Jvc3MgbW9kdWxlIGNvcGllc1wiLCAoKSA9PiB7XG4gICAgdHlwZSBUZWxlbWV0cnkgPSB0eXBlb2YgaW1wb3J0KFwiLi90ZWxlbWV0cnlcIik7XG4gICAgbGV0IHNlY29uZDogVGVsZW1ldHJ5O1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBqZXN0Lmlzb2xhdGVNb2R1bGVzKCgpID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAgICAgc2Vjb25kID0gcmVxdWlyZShcIi4vdGVsZW1ldHJ5XCIpO1xuICAgICAgfSk7XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwiZ29cIixcbiAgICAgICAgc2VuZFVzYWdlVGVsZW1ldHJ5OiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBpbml0U2VudHJ5V2l0aENhcHR1cmluZ1RyYW5zcG9ydCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJvYnNlcnZlcyB0aGUgY2FwdHVyZWQgZGVjaXNpb24gYW5kIHRhcmdldHMsIHRoZSBzdGFydGVkIGNvbW1hbmQgYW5kIGl0cyBsYW5ndWFnZSBmcm9tIHRoZSBvdGhlciBjb3B5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIHRoZSBwcm9qZWN0IG9wdHMgb3V0OyBvbmx5IHRoZSBkZWNpc2lvbiBjYXB0dXJlZCBieSB0aGUgZmlyc3QgY29weVxuICAgICAgLy8gbGV0cyB0aGUgc2Vjb25kIG9uZSBlbWl0XG4gICAgICBmcy53cml0ZUpzb25TeW5jKHBhdGguam9pbih3b3JrZGlyLCBcImNka3RmLmpzb25cIiksIHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwiZ29cIixcbiAgICAgICAgc2VuZFVzYWdlVGVsZW1ldHJ5OiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgc2V0VXNhZ2VUZWxlbWV0cnlFbmFibGVkKHRydWUpO1xuICAgICAgc2V0UHJvamVjdFRhcmdldEF0dHJpYnV0ZXMoeyB0YXJnZXRfb3BlbnRvZnU6IFwiPj0xLjcuMFwiIH0pO1xuICAgICAgYXdhaXQgc3RhcnRDb21tYW5kVGVsZW1ldHJ5KFwiZGVwbG95XCIpO1xuICAgICAgYXdhaXQgc2Vjb25kLnN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcInN5bnRoXCIpO1xuICAgICAgYXdhaXQgc2Vjb25kLnNlbmRUZWxlbWV0cnkoXCJzeW50aFwiLCB7IGxhbmd1YWdlOiBcImdvXCIgfSk7XG4gICAgICBhd2FpdCBzZWNvbmQuc2VuZFRlbGVtZXRyeShcImRlcGxveVwiLCB7IGVycm9yOiB0cnVlLCBlcnJvclR5cGU6IFwiVXNhZ2VcIiB9KTtcbiAgICAgIGV4cGVjdChhd2FpdCBTZW50cnkuZmx1c2goMjAwMCkpLnRvQmUodHJ1ZSk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcyk7XG4gICAgICBleHBlY3QoaXRlbXMubWFwKChpKSA9PiBbaS5uYW1lLCBhdHRyaWJ1dGVWYWx1ZXMoaSkuY29tbWFuZF0pKS50b0VxdWFsKFtcbiAgICAgICAgW1wiY2xpLmNvbW1hbmQuaW52b2tlZFwiLCBcImRlcGxveVwiXSxcbiAgICAgICAgW1wiY2xpLmNvbW1hbmQuZXJyb3JcIiwgXCJkZXBsb3lcIl0sXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVWYWx1ZXMoaXRlbXNbMV0pKS50b01hdGNoT2JqZWN0KHtcbiAgICAgICAgbGFuZ3VhZ2U6IFwiZ29cIixcbiAgICAgICAgcGFja2FnZV9tYW5hZ2VyOiBcImdvXCIsXG4gICAgICAgIHRhcmdldF9vcGVudG9mdTogXCI+PTEuNy4wXCIsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChpdGVtc1sxXS5hdHRyaWJ1dGVzKS5ub3QudG9IYXZlUHJvcGVydHkoXCJ0YXJnZXRfdGVycmFmb3JtXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcInNlbmRUZWxlbWV0cnkgZ2F0aW5nXCIsICgpID0+IHtcbiAgICBpdC5lYWNoKFtcbiAgICAgIHsgZW52OiB1bmRlZmluZWQsIGNhcHR1cmVkOiB1bmRlZmluZWQsIGZsYWc6IHVuZGVmaW5lZCwgZW1pdHM6IHRydWUgfSxcbiAgICAgIHsgZW52OiB1bmRlZmluZWQsIGNhcHR1cmVkOiB1bmRlZmluZWQsIGZsYWc6IHRydWUsIGVtaXRzOiB0cnVlIH0sXG4gICAgICB7IGVudjogdW5kZWZpbmVkLCBjYXB0dXJlZDogdW5kZWZpbmVkLCBmbGFnOiBmYWxzZSwgZW1pdHM6IGZhbHNlIH0sXG4gICAgICAvLyBjb252ZXJ0IGNoZGlycyBpbnRvIGEgdGhyb3dhd2F5IHByb2plY3QgdGhhdCBvcHRzIG91dFxuICAgICAgeyBlbnY6IHVuZGVmaW5lZCwgY2FwdHVyZWQ6IHRydWUsIGZsYWc6IGZhbHNlLCBlbWl0czogdHJ1ZSB9LFxuICAgICAgeyBlbnY6IHVuZGVmaW5lZCwgY2FwdHVyZWQ6IGZhbHNlLCBmbGFnOiB0cnVlLCBlbWl0czogZmFsc2UgfSxcbiAgICAgIHsgZW52OiBcIjFcIiwgY2FwdHVyZWQ6IHVuZGVmaW5lZCwgZmxhZzogdHJ1ZSwgZW1pdHM6IGZhbHNlIH0sXG4gICAgICB7IGVudjogXCIxXCIsIGNhcHR1cmVkOiB0cnVlLCBmbGFnOiB0cnVlLCBlbWl0czogZmFsc2UgfSxcbiAgICBdKShcbiAgICAgIFwiQ0hFQ0tQT0lOVF9ESVNBQkxFPSRlbnYsIGNhcHR1cmVkPSRjYXB0dXJlZCwgZmxhZz0kZmxhZyAtPiBlbWl0cyAkZW1pdHNcIixcbiAgICAgIGFzeW5jICh7IGVudiwgY2FwdHVyZWQsIGZsYWcsIGVtaXRzIH0pID0+IHtcbiAgICAgICAgaWYgKGZsYWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICAgICAgc2VuZFVzYWdlVGVsZW1ldHJ5OiBmbGFnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGluaXRTZW50cnlXaXRoQ2FwdHVyaW5nVHJhbnNwb3J0KCk7XG4gICAgICAgIHNldFVzYWdlVGVsZW1ldHJ5RW5hYmxlZChjYXB0dXJlZCk7XG4gICAgICAgIGlmIChlbnYgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHByb2Nlc3MuZW52LkNIRUNLUE9JTlRfRElTQUJMRSA9IGVudjtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHN0YXJ0Q29tbWFuZFRlbGVtZXRyeShcImNvbnZlcnRcIik7XG4gICAgICAgIGF3YWl0IHNlbmRUZWxlbWV0cnkoXCJjb252ZXJ0XCIsIHt9KTtcbiAgICAgICAgYXdhaXQgU2VudHJ5LmZsdXNoKDIwMDApO1xuXG4gICAgICAgIGNvbnN0IGl0ZW1zID0gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcyk7XG4gICAgICAgIGV4cGVjdChpdGVtcy5zb21lKChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLmNvbW1hbmQuaW52b2tlZFwiKSkudG9CZShlbWl0cyk7XG4gICAgICAgIGV4cGVjdChpdGVtcy5zb21lKChpKSA9PiBpLm5hbWUgPT09IFwiY2xpLmNvbW1hbmQuY29tcGxldGVkXCIpKS50b0JlKFxuICAgICAgICAgIGVtaXRzLFxuICAgICAgICApO1xuICAgICAgICBpZiAoIWVtaXRzKSB7XG4gICAgICAgICAgZXhwZWN0KGl0ZW1zKS50b0hhdmVMZW5ndGgoMCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJjbGkuZXJyb3IgZnJvbSB0aGUgRXJyb3JzIGZhY3Rvcmllc1wiLCAoKSA9PiB7XG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIEVycm9ycy5zZXRTY29wZShcInVua25vd25cIik7XG4gICAgfSk7XG5cbiAgICAvLyB0aGUgc2NvcGUgaXMgcmVhZCB3aGVuIHRoZSBlcnJvciBpcyBidWlsdCwgbm90IHdoZW4gdGhlIGZhY3RvcnkgaXNcbiAgICAvLyBjcmVhdGVkOiBhIGZhY3RvcnktdGltZSBiaW5kaW5nIHJlcG9ydHMgZXZlcnkgZXJyb3IgYXMgXCJ1bmtub3duXCJcbiAgICBpdChcImNvdW50cyBjb25zdHJ1Y3RlZCBlcnJvcnMgYnkgdHlwZSB3aXRoIHRoZSBjb21tYW5kIHNldCBhdCBjYWxsIHRpbWVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCB7XG4gICAgICAgIHNlbmRVc2FnZVRlbGVtZXRyeTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgaW5pdFNlbnRyeVdpdGhDYXB0dXJpbmdUcmFuc3BvcnQoKTtcblxuICAgICAgRXJyb3JzLnNldFNjb3BlKFwiZGVwbG95XCIpO1xuICAgICAgRXJyb3JzLlVzYWdlKFwibm8gc3RhY2tzIHNlbGVjdGVkXCIsIHVuZGVmaW5lZCwgeyBzdGFja05hbWU6IFwic2VjcmV0XCIgfSk7XG4gICAgICBFcnJvcnMuRXh0ZXJuYWwoXCJ0ZXJyYWZvcm0gZXhpdGVkIHdpdGggY29kZSAxXCIpO1xuICAgICAgZXhwZWN0KGF3YWl0IFNlbnRyeS5mbHVzaCgyMDAwKSkudG9CZSh0cnVlKTtcblxuICAgICAgY29uc3QgZXJyb3JzID0gcGFyc2VNZXRyaWNJdGVtcyhlbnZlbG9wZUJvZGllcykuZmlsdGVyKFxuICAgICAgICAoaSkgPT4gaS5uYW1lID09PSBcImNsaS5lcnJvclwiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChlcnJvcnMubWFwKChlKSA9PiBlLmF0dHJpYnV0ZXMudHlwZS52YWx1ZSkpLnRvRXF1YWwoW1xuICAgICAgICBcIlVzYWdlXCIsXG4gICAgICAgIFwiRXh0ZXJuYWxcIixcbiAgICAgIF0pO1xuICAgICAgZm9yIChjb25zdCBlcnJvciBvZiBlcnJvcnMpIHtcbiAgICAgICAgZXhwZWN0KGVycm9yLmF0dHJpYnV0ZXMuY29tbWFuZC52YWx1ZSkudG9CZShcImRlcGxveVwiKTtcbiAgICAgICAgZXhwZWN0KGVycm9yLmF0dHJpYnV0ZXMpLm5vdC50b0hhdmVQcm9wZXJ0eShcIm1lc3NhZ2VcIik7XG4gICAgICAgIGV4cGVjdChlcnJvci5hdHRyaWJ1dGVzKS5ub3QudG9IYXZlUHJvcGVydHkoXCJzdGFja05hbWVcIik7XG4gICAgICB9XG4gICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoZXJyb3JzKSkubm90LnRvQ29udGFpbihcInNlY3JldFwiKTtcbiAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShlcnJvcnMpKS5ub3QudG9Db250YWluKFwibm8gc3RhY2tzIHNlbGVjdGVkXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcImJpbmFyeSBhdHRyaWJ1dGVzXCIsICgpID0+IHtcbiAgICBhc3luYyBmdW5jdGlvbiBpbnZva2VkQXR0cmlidXRlcyh2ZXJzaW9uT3V0cHV0OiBzdHJpbmcpIHtcbiAgICAgIHNlZWRUZXJyYWZvcm1DbGlQcm9iZUZvclRlc3RzKFByb21pc2UucmVzb2x2ZSh2ZXJzaW9uT3V0cHV0KSk7XG4gICAgICBpbml0U2VudHJ5V2l0aENhcHR1cmluZ1RyYW5zcG9ydCgpO1xuICAgICAgYXdhaXQgc3RhcnRDb21tYW5kVGVsZW1ldHJ5KFwic3ludGhcIik7XG4gICAgICBleHBlY3QoYXdhaXQgU2VudHJ5LmZsdXNoKDIwMDApKS50b0JlKHRydWUpO1xuICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlcyhwYXJzZU1ldHJpY0l0ZW1zKGVudmVsb3BlQm9kaWVzKVswXSk7XG4gICAgfVxuXG4gICAgaXQuZWFjaChbXG4gICAgICBbXCJUZXJyYWZvcm0gdjEuMTAuMC1hbHBoYTIwMjUwMTAxXCIsIFwidGVycmFmb3JtXCIsIFwiMS4xMC4wXCJdLFxuICAgICAgW1xuICAgICAgICBcIk9wZW5Ub2Z1IHYxLjIuMy1MRUFLLUhPU1QuY29ycC5leGFtcGxlLmNvbStMRUFLLUJVSUxEL1VzZXJzL3hcIixcbiAgICAgICAgXCJvcGVudG9mdVwiLFxuICAgICAgICBcIjEuMi4zXCIsXG4gICAgICBdLFxuICAgIF0pKFxuICAgICAgXCJyZWR1Y2VzIHRoZSBwcm9iZWQgdmVyc2lvbiBvZiAlcCB0byBpdHMgcmVsZWFzZVwiLFxuICAgICAgYXN5bmMgKHZlcnNpb25PdXRwdXQsIGJpbmFyeSwgcmVsZWFzZSkgPT4ge1xuICAgICAgICBleHBlY3QoYXdhaXQgaW52b2tlZEF0dHJpYnV0ZXModmVyc2lvbk91dHB1dCkpLnRvTWF0Y2hPYmplY3Qoe1xuICAgICAgICAgIGJpbmFyeSxcbiAgICAgICAgICBiaW5hcnlfdmVyc2lvbjogcmVsZWFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGV4cGVjdChlbnZlbG9wZUJvZGllcy5qb2luKFwiXFxuXCIpKS5ub3QudG9Db250YWluKFwiTEVBS1wiKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGl0KFwic2VuZHMgbm8gdmVyc2lvbiBmb3IgYW4gdW5yZWNvZ25pc2VkIHByb2R1Y3Q6IGEgd3JhcHBlcidzIG91dHB1dCBoYXMgbm8gcHJvZHVjdCB2ZXJzaW9uIGxpbmVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGF3YWl0IGludm9rZWRBdHRyaWJ1dGVzKFxuICAgICAgICBcImNvbm5lY3RlZCB0byAxMC4wLjAuMSBhcyBMRUFLLVVTRVIgKHdyYXBwZXIgMy40LjUpXFxuVGVycmFmb3JtIHYxLjkuMFxcblwiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzLmJpbmFyeSkudG9CZShcInVua25vd25cIik7XG4gICAgICBleHBlY3QoYXR0cmlidXRlcykubm90LnRvSGF2ZVByb3BlcnR5KFwiYmluYXJ5X3ZlcnNpb25cIik7XG4gICAgICBleHBlY3QoZW52ZWxvcGVCb2RpZXMuam9pbihcIlxcblwiKSkubm90LnRvQ29udGFpbihcIkxFQUstVVNFUlwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJnZXRQcm9qZWN0VGFyZ2V0QXR0cmlidXRlc1wiLCAoKSA9PiB7XG4gICAgaXQoXCJyZWFkcyBkZWNsYXJlZCB0YXJnZXRzIGFuZCB0aGUgdmFsaWRhdGlvbiBmbGFnXCIsICgpID0+IHtcbiAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwge1xuICAgICAgICB0YXJnZXRWZXJzaW9uczogeyBvcGVudG9mdTogXCJ+MS44XCIgfSxcbiAgICAgICAgdmFsaWRhdGVJbnN0YWxsZWRCaW5hcnk6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChnZXRQcm9qZWN0VGFyZ2V0QXR0cmlidXRlcyh3b3JrZGlyKSkudG9FcXVhbCh7XG4gICAgICAgIHRhcmdldHNfZGVjbGFyZWQ6IHRydWUsXG4gICAgICAgIHZhbGlkYXRlX2luc3RhbGxlZF9iaW5hcnk6IHRydWUsXG4gICAgICAgIHRhcmdldF9vcGVudG9mdTogXCI+PTEuOC4wIDwxLjkuMC0wXCIsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW3t9XSxcbiAgICAgIFt7IHRhcmdldFZlcnNpb25zOiBcIm5vcGVcIiB9XSxcbiAgICAgIFt7IHRhcmdldFZlcnNpb25zOiBbXSB9XSxcbiAgICAgIFt1bmRlZmluZWRdLFxuICAgIF0pKFwiZmFsbHMgYmFjayB0byB0aGUgZGVmYXVsdHMgZm9yIGEgY2RrdGYuanNvbiBvZiAlalwiLCAoY29uZmlnKSA9PiB7XG4gICAgICBpZiAoY29uZmlnKSB7XG4gICAgICAgIGZzLndyaXRlSnNvblN5bmMocGF0aC5qb2luKHdvcmtkaXIsIFwiY2RrdGYuanNvblwiKSwgY29uZmlnKTtcbiAgICAgIH1cbiAgICAgIGV4cGVjdChnZXRQcm9qZWN0VGFyZ2V0QXR0cmlidXRlcyh3b3JrZGlyKSkudG9FcXVhbCh7XG4gICAgICAgIHRhcmdldHNfZGVjbGFyZWQ6IGZhbHNlLFxuICAgICAgICB2YWxpZGF0ZV9pbnN0YWxsZWRfYmluYXJ5OiBmYWxzZSxcbiAgICAgICAgLi4uREVGQVVMVF9UQVJHRVRfVkVSU0lPTlNfQVNfQVRUUklCVVRFUyxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcImdldFVzYWdlVGVsZW1ldHJ5Q29uc2VudFwiLCAoKSA9PiB7XG4gICAgaXQuZWFjaChbXG4gICAgICAvLyBpbml0IHRlbXBsYXRlcyByZW5kZXIgdGhlIGZsYWcgYXMgYSBzdHJpbmc7IGEgYm9vbGVhbi1vbmx5IGNoZWNrXG4gICAgICAvLyB3b3VsZCBvcHQgZXZlcnkgZnJlc2hseSBpbml0J2VkIHByb2plY3Qgb3V0XG4gICAgICBbeyBzZW5kVXNhZ2VUZWxlbWV0cnk6IFwidHJ1ZVwiIH0sIHRydWVdLFxuICAgICAgW3sgc2VuZFVzYWdlVGVsZW1ldHJ5OiBcImZhbHNlXCIgfSwgZmFsc2VdLFxuICAgICAgW3t9LCB1bmRlZmluZWRdLFxuICAgICAgLy8gbWFsZm9ybWVkIGlzIHVuc2V0LCBub3QgYW4gb3B0LW91dFxuICAgICAgW3sgc2VuZFVzYWdlVGVsZW1ldHJ5OiBcInllc1wiIH0sIHVuZGVmaW5lZF0sXG4gICAgXSkoXCJyZWFkcyAlaiBhcyAlcFwiLCAoY29uZmlnLCBleHBlY3RlZCkgPT4ge1xuICAgICAgZnMud3JpdGVKc29uU3luYyhwYXRoLmpvaW4od29ya2RpciwgXCJjZGt0Zi5qc29uXCIpLCBjb25maWcpO1xuICAgICAgZXhwZWN0KGdldFVzYWdlVGVsZW1ldHJ5Q29uc2VudCh3b3JrZGlyKSkudG9CZShleHBlY3RlZCk7XG4gICAgfSk7XG5cbiAgICBpdChcInJldHVybnMgdW5kZWZpbmVkIHdoZW4gbm8gY2RrdGYuanNvbiBleGlzdHNcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KGdldFVzYWdlVGVsZW1ldHJ5Q29uc2VudCh3b3JrZGlyKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19