@microsoft/terraform-cdk-constructs 1.5.0 → 1.6.0

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 (67) hide show
  1. package/.jsii +14639 -12797
  2. package/API.md +5771 -3185
  3. package/lib/azure-actiongroup/lib/action-group.js +1 -1
  4. package/lib/azure-activitylogalert/lib/activity-log-alert.js +1 -1
  5. package/lib/azure-aks/lib/aks-cluster.js +1 -1
  6. package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +1 -1
  7. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.js +1 -1
  8. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.js +1 -1
  9. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.js +1 -1
  10. package/lib/azure-dnsresolver/lib/dns-resolver.js +1 -1
  11. package/lib/azure-dnsresolver/lib/inbound-endpoint.js +1 -1
  12. package/lib/azure-dnsresolver/lib/outbound-endpoint.js +1 -1
  13. package/lib/azure-dnszone/lib/dns-zone.js +1 -1
  14. package/lib/azure-metricalert/lib/metric-alert.js +1 -1
  15. package/lib/azure-networkinterface/lib/network-interface.js +1 -1
  16. package/lib/azure-networksecuritygroup/lib/network-security-group.js +1 -1
  17. package/lib/azure-policyassignment/lib/policy-assignment.js +1 -1
  18. package/lib/azure-policydefinition/lib/policy-definition.js +1 -1
  19. package/lib/azure-privatednszone/lib/private-dns-zone.js +1 -1
  20. package/lib/azure-privatednszonelink/lib/private-dns-zone-link.js +1 -1
  21. package/lib/azure-publicipaddress/lib/public-ip-address.js +1 -1
  22. package/lib/azure-resourcegroup/lib/resource-group.js +1 -1
  23. package/lib/azure-roleassignment/lib/role-assignment.js +1 -1
  24. package/lib/azure-roledefinition/lib/role-definition.js +1 -1
  25. package/lib/azure-storageaccount/lib/storage-account.js +1 -1
  26. package/lib/azure-subnet/lib/subnet.js +1 -1
  27. package/lib/azure-virtualmachine/lib/virtual-machine.js +1 -1
  28. package/lib/azure-virtualnetwork/lib/virtual-network.js +1 -1
  29. package/lib/azure-virtualnetworkgateway/lib/virtual-network-gateway.js +1 -1
  30. package/lib/azure-virtualnetworkgatewayconnection/index.d.ts +6 -0
  31. package/lib/azure-virtualnetworkgatewayconnection/index.js +23 -0
  32. package/lib/azure-virtualnetworkgatewayconnection/lib/index.d.ts +8 -0
  33. package/lib/azure-virtualnetworkgatewayconnection/lib/index.js +25 -0
  34. package/lib/azure-virtualnetworkgatewayconnection/lib/virtual-network-gateway-connection-schemas.d.ts +32 -0
  35. package/lib/azure-virtualnetworkgatewayconnection/lib/virtual-network-gateway-connection-schemas.js +322 -0
  36. package/lib/azure-virtualnetworkgatewayconnection/lib/virtual-network-gateway-connection.d.ts +333 -0
  37. package/lib/azure-virtualnetworkgatewayconnection/lib/virtual-network-gateway-connection.js +310 -0
  38. package/lib/azure-virtualnetworkgatewayconnection/test/virtual-network-gateway-connection.integ.d.ts +12 -0
  39. package/lib/azure-virtualnetworkgatewayconnection/test/virtual-network-gateway-connection.integ.js +216 -0
  40. package/lib/azure-virtualnetworkgatewayconnection/test/virtual-network-gateway-connection.spec.d.ts +8 -0
  41. package/lib/azure-virtualnetworkgatewayconnection/test/virtual-network-gateway-connection.spec.js +706 -0
  42. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.js +1 -1
  43. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr.js +1 -1
  44. package/lib/azure-virtualnetworkmanager/lib/ipam-pool.js +1 -1
  45. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.js +1 -1
  46. package/lib/azure-virtualnetworkmanager/lib/network-group.js +1 -1
  47. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.js +1 -1
  48. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.js +1 -1
  49. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.js +1 -1
  50. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.js +1 -1
  51. package/lib/azure-vmss/lib/virtual-machine-scale-set.js +1 -1
  52. package/lib/core-azure/lib/azapi/azapi-resource.js +2 -2
  53. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +2 -2
  54. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +5 -5
  55. package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +1 -1
  56. package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +5 -5
  57. package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +3 -3
  58. package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +3 -3
  59. package/lib/core-azure/lib/azapi/schema-mapper/schema-mapper.js +1 -1
  60. package/lib/core-azure/lib/version-manager/api-version-manager.js +1 -1
  61. package/lib/core-azure/lib/version-manager/interfaces/version-interfaces.js +7 -7
  62. package/lib/index.d.ts +2 -0
  63. package/lib/index.js +4 -2
  64. package/lib/testing/index.js +2 -2
  65. package/lib/testing/lib/cleanup.js +1 -1
  66. package/lib/testing/lib/metadata.js +1 -1
  67. package/package.json +1 -1
@@ -0,0 +1,706 @@
1
+ "use strict";
2
+ /**
3
+ * Comprehensive tests for the Virtual Network Gateway Connection implementation
4
+ *
5
+ * This test suite validates the VirtualNetworkGatewayConnection class using the AzapiResource framework.
6
+ * Tests cover automatic version resolution, explicit version pinning, schema validation,
7
+ * property transformation, and resource creation for all connection types.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const cdktf_1 = require("cdktf");
11
+ const cdktf = require("cdktf");
12
+ const virtual_network_gateway_connection_1 = require("../lib/virtual-network-gateway-connection");
13
+ describe("VirtualNetworkGatewayConnection - Implementation", () => {
14
+ let app;
15
+ let stack;
16
+ beforeEach(() => {
17
+ app = cdktf_1.Testing.app();
18
+ stack = new cdktf.TerraformStack(app, "TestStack");
19
+ });
20
+ describe("Constructor and Basic Properties", () => {
21
+ it("should create IPsec connection with automatic latest version resolution", () => {
22
+ const props = {
23
+ name: "test-s2s-connection",
24
+ location: "eastus",
25
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
26
+ connectionType: "IPsec",
27
+ virtualNetworkGateway1: {
28
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
29
+ },
30
+ localNetworkGateway2: {
31
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
32
+ },
33
+ sharedKey: "mySecureKey123!",
34
+ };
35
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TestConnection", props);
36
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
37
+ expect(connection.props).toBe(props);
38
+ expect(connection.name).toBe("test-s2s-connection");
39
+ expect(connection.location).toBe("eastus");
40
+ });
41
+ it("should create Vnet2Vnet connection with explicit version pinning", () => {
42
+ const props = {
43
+ name: "test-vnet-connection",
44
+ location: "westus",
45
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
46
+ apiVersion: "2024-01-01",
47
+ connectionType: "Vnet2Vnet",
48
+ virtualNetworkGateway1: {
49
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
50
+ },
51
+ virtualNetworkGateway2: {
52
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng2",
53
+ },
54
+ sharedKey: "mySecureKey123!",
55
+ tags: { environment: "test" },
56
+ };
57
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TestConnection", props);
58
+ expect(connection.resolvedApiVersion).toBe("2024-01-01");
59
+ expect(connection.tags).toEqual({ environment: "test" });
60
+ });
61
+ it("should create ExpressRoute connection with all optional properties", () => {
62
+ const props = {
63
+ name: "test-er-connection",
64
+ location: "centralus",
65
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
66
+ connectionType: "ExpressRoute",
67
+ virtualNetworkGateway1: {
68
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/er-gateway",
69
+ },
70
+ peer: {
71
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/expressRouteCircuits/circuit",
72
+ },
73
+ authorizationKey: "auth-key-123",
74
+ enableBgp: true,
75
+ routingWeight: 10,
76
+ tags: {
77
+ environment: "production",
78
+ project: "networking",
79
+ },
80
+ ignoreChanges: ["tags"],
81
+ };
82
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TestConnection", props);
83
+ expect(connection.props.connectionType).toBe("ExpressRoute");
84
+ expect(connection.props.enableBgp).toBe(true);
85
+ expect(connection.props.tags).toEqual(props.tags);
86
+ });
87
+ it("should use default name when name is not provided", () => {
88
+ const props = {
89
+ name: "default-name",
90
+ location: "eastus",
91
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
92
+ connectionType: "IPsec",
93
+ virtualNetworkGateway1: {
94
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
95
+ },
96
+ localNetworkGateway2: {
97
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
98
+ },
99
+ sharedKey: "key",
100
+ };
101
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TestConnection", props);
102
+ expect(connection.name).toBe("default-name");
103
+ });
104
+ });
105
+ describe("Resource Type and API Versions", () => {
106
+ it("should have correct resource type", () => {
107
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TestConnection", {
108
+ name: "test-connection",
109
+ location: "eastus",
110
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
111
+ connectionType: "IPsec",
112
+ virtualNetworkGateway1: {
113
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
114
+ },
115
+ localNetworkGateway2: {
116
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
117
+ },
118
+ sharedKey: "key",
119
+ });
120
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
121
+ });
122
+ it("should support all registered API versions", () => {
123
+ const versions = ["2024-01-01", "2024-05-01"];
124
+ versions.forEach((version) => {
125
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, `Connection-${version.replace(/-/g, "")}`, {
126
+ name: `conn-${version}`,
127
+ location: "eastus",
128
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
129
+ apiVersion: version,
130
+ connectionType: "IPsec",
131
+ virtualNetworkGateway1: {
132
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
133
+ },
134
+ localNetworkGateway2: {
135
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
136
+ },
137
+ sharedKey: "key",
138
+ });
139
+ expect(connection.resolvedApiVersion).toBe(version);
140
+ });
141
+ });
142
+ it("should use latest version as default", () => {
143
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TestConnection", {
144
+ name: "test-connection",
145
+ location: "eastus",
146
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
147
+ connectionType: "IPsec",
148
+ virtualNetworkGateway1: {
149
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
150
+ },
151
+ localNetworkGateway2: {
152
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
153
+ },
154
+ sharedKey: "key",
155
+ });
156
+ expect(connection.resolvedApiVersion).toBe("2024-05-01");
157
+ });
158
+ });
159
+ describe("IPsec Connection Type", () => {
160
+ it("should create IPsec connection with minimal properties", () => {
161
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "IPsecMinimal", {
162
+ name: "ipsec-minimal",
163
+ location: "eastus",
164
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
165
+ connectionType: "IPsec",
166
+ virtualNetworkGateway1: {
167
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
168
+ },
169
+ localNetworkGateway2: {
170
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
171
+ },
172
+ sharedKey: "mySecureKey123!",
173
+ });
174
+ expect(connection.props.connectionType).toBe("IPsec");
175
+ expect(connection.props.localNetworkGateway2).toBeDefined();
176
+ expect(connection.props.sharedKey).toBe("mySecureKey123!");
177
+ });
178
+ it("should create IPsec connection with custom IPsec policies", () => {
179
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "IPsecCustom", {
180
+ name: "ipsec-custom",
181
+ location: "eastus",
182
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
183
+ connectionType: "IPsec",
184
+ virtualNetworkGateway1: {
185
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
186
+ },
187
+ localNetworkGateway2: {
188
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
189
+ },
190
+ sharedKey: "mySecureKey123!",
191
+ connectionProtocol: "IKEv2",
192
+ ipsecPolicies: [
193
+ {
194
+ dhGroup: "DHGroup14",
195
+ ikeEncryption: "AES256",
196
+ ikeIntegrity: "SHA256",
197
+ ipsecEncryption: "AES256",
198
+ ipsecIntegrity: "SHA256",
199
+ pfsGroup: "PFS2048",
200
+ saLifeTimeSeconds: 3600,
201
+ saDataSizeKilobytes: 102400000,
202
+ },
203
+ ],
204
+ usePolicyBasedTrafficSelectors: true,
205
+ });
206
+ expect(connection.props.connectionProtocol).toBe("IKEv2");
207
+ expect(connection.props.ipsecPolicies).toHaveLength(1);
208
+ expect(connection.props.usePolicyBasedTrafficSelectors).toBe(true);
209
+ });
210
+ it("should create IPsec connection with IKEv1 protocol", () => {
211
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "IPsecIKEv1", {
212
+ name: "ipsec-ikev1",
213
+ location: "eastus",
214
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
215
+ connectionType: "IPsec",
216
+ virtualNetworkGateway1: {
217
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
218
+ },
219
+ localNetworkGateway2: {
220
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
221
+ },
222
+ sharedKey: "mySecureKey123!",
223
+ connectionProtocol: "IKEv1",
224
+ });
225
+ expect(connection.props.connectionProtocol).toBe("IKEv1");
226
+ });
227
+ });
228
+ describe("Vnet2Vnet Connection Type", () => {
229
+ it("should create Vnet2Vnet connection with minimal properties", () => {
230
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "Vnet2VnetMinimal", {
231
+ name: "vnet2vnet-minimal",
232
+ location: "eastus",
233
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
234
+ connectionType: "Vnet2Vnet",
235
+ virtualNetworkGateway1: {
236
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
237
+ },
238
+ virtualNetworkGateway2: {
239
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng2",
240
+ },
241
+ sharedKey: "mySecureKey123!",
242
+ });
243
+ expect(connection.props.connectionType).toBe("Vnet2Vnet");
244
+ expect(connection.props.virtualNetworkGateway2).toBeDefined();
245
+ expect(connection.props.sharedKey).toBe("mySecureKey123!");
246
+ });
247
+ it("should create Vnet2Vnet connection with BGP enabled", () => {
248
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "Vnet2VnetBGP", {
249
+ name: "vnet2vnet-bgp",
250
+ location: "eastus",
251
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
252
+ connectionType: "Vnet2Vnet",
253
+ virtualNetworkGateway1: {
254
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
255
+ },
256
+ virtualNetworkGateway2: {
257
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng2",
258
+ },
259
+ sharedKey: "mySecureKey123!",
260
+ enableBgp: true,
261
+ routingWeight: 5,
262
+ });
263
+ expect(connection.props.enableBgp).toBe(true);
264
+ expect(connection.props.routingWeight).toBe(5);
265
+ });
266
+ });
267
+ describe("ExpressRoute Connection Type", () => {
268
+ it("should create ExpressRoute connection with minimal properties", () => {
269
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "ExpressRouteMinimal", {
270
+ name: "er-minimal",
271
+ location: "eastus",
272
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
273
+ connectionType: "ExpressRoute",
274
+ virtualNetworkGateway1: {
275
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/er-gateway",
276
+ },
277
+ peer: {
278
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/expressRouteCircuits/circuit",
279
+ },
280
+ });
281
+ expect(connection.props.connectionType).toBe("ExpressRoute");
282
+ expect(connection.props.peer).toBeDefined();
283
+ });
284
+ it("should create ExpressRoute connection with authorization key", () => {
285
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "ExpressRouteAuth", {
286
+ name: "er-auth",
287
+ location: "eastus",
288
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
289
+ connectionType: "ExpressRoute",
290
+ virtualNetworkGateway1: {
291
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/er-gateway",
292
+ },
293
+ peer: {
294
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/expressRouteCircuits/circuit",
295
+ },
296
+ authorizationKey: "my-auth-key-123",
297
+ });
298
+ expect(connection.props.authorizationKey).toBe("my-auth-key-123");
299
+ });
300
+ });
301
+ describe("Connection Mode Configuration", () => {
302
+ it("should create connection with Default mode", () => {
303
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "DefaultMode", {
304
+ name: "conn-default",
305
+ location: "eastus",
306
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
307
+ connectionType: "IPsec",
308
+ virtualNetworkGateway1: {
309
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
310
+ },
311
+ localNetworkGateway2: {
312
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
313
+ },
314
+ sharedKey: "key",
315
+ connectionMode: "Default",
316
+ });
317
+ expect(connection.props.connectionMode).toBe("Default");
318
+ });
319
+ it("should create connection with ResponderOnly mode", () => {
320
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "ResponderMode", {
321
+ name: "conn-responder",
322
+ location: "eastus",
323
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
324
+ connectionType: "IPsec",
325
+ virtualNetworkGateway1: {
326
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
327
+ },
328
+ localNetworkGateway2: {
329
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
330
+ },
331
+ sharedKey: "key",
332
+ connectionMode: "ResponderOnly",
333
+ });
334
+ expect(connection.props.connectionMode).toBe("ResponderOnly");
335
+ });
336
+ it("should create connection with InitiatorOnly mode", () => {
337
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "InitiatorMode", {
338
+ name: "conn-initiator",
339
+ location: "eastus",
340
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
341
+ connectionType: "IPsec",
342
+ virtualNetworkGateway1: {
343
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
344
+ },
345
+ localNetworkGateway2: {
346
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
347
+ },
348
+ sharedKey: "key",
349
+ connectionMode: "InitiatorOnly",
350
+ });
351
+ expect(connection.props.connectionMode).toBe("InitiatorOnly");
352
+ });
353
+ });
354
+ describe("NAT Rules Configuration", () => {
355
+ it("should create connection with egress NAT rules", () => {
356
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "EgressNAT", {
357
+ name: "conn-egress-nat",
358
+ location: "eastus",
359
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
360
+ connectionType: "IPsec",
361
+ virtualNetworkGateway1: {
362
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
363
+ },
364
+ localNetworkGateway2: {
365
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
366
+ },
367
+ sharedKey: "key",
368
+ egressNatRules: [
369
+ {
370
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1/natRules/rule1",
371
+ },
372
+ ],
373
+ });
374
+ expect(connection.props.egressNatRules).toHaveLength(1);
375
+ });
376
+ it("should create connection with ingress NAT rules", () => {
377
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "IngressNAT", {
378
+ name: "conn-ingress-nat",
379
+ location: "eastus",
380
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
381
+ connectionType: "IPsec",
382
+ virtualNetworkGateway1: {
383
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
384
+ },
385
+ localNetworkGateway2: {
386
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
387
+ },
388
+ sharedKey: "key",
389
+ ingressNatRules: [
390
+ {
391
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1/natRules/rule1",
392
+ },
393
+ ],
394
+ });
395
+ expect(connection.props.ingressNatRules).toHaveLength(1);
396
+ });
397
+ });
398
+ describe("Tags Management", () => {
399
+ it("should create connection with tags", () => {
400
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "TaggedConnection", {
401
+ name: "conn-tagged",
402
+ location: "eastus",
403
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
404
+ connectionType: "IPsec",
405
+ virtualNetworkGateway1: {
406
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
407
+ },
408
+ localNetworkGateway2: {
409
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
410
+ },
411
+ sharedKey: "key",
412
+ tags: {
413
+ environment: "production",
414
+ cost_center: "engineering",
415
+ },
416
+ });
417
+ expect(connection.props.tags).toEqual({
418
+ environment: "production",
419
+ cost_center: "engineering",
420
+ });
421
+ });
422
+ it("should support adding tags", () => {
423
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "AddTag", {
424
+ name: "conn-add-tag",
425
+ location: "eastus",
426
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
427
+ connectionType: "IPsec",
428
+ virtualNetworkGateway1: {
429
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
430
+ },
431
+ localNetworkGateway2: {
432
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
433
+ },
434
+ sharedKey: "key",
435
+ tags: { environment: "test" },
436
+ });
437
+ connection.addTag("newTag", "newValue");
438
+ expect(connection.props.tags.newTag).toBe("newValue");
439
+ expect(connection.props.tags.environment).toBe("test");
440
+ });
441
+ it("should support removing tags", () => {
442
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "RemoveTag", {
443
+ name: "conn-remove-tag",
444
+ location: "eastus",
445
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
446
+ connectionType: "IPsec",
447
+ virtualNetworkGateway1: {
448
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
449
+ },
450
+ localNetworkGateway2: {
451
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
452
+ },
453
+ sharedKey: "key",
454
+ tags: {
455
+ environment: "test",
456
+ temporary: "true",
457
+ },
458
+ });
459
+ connection.removeTag("temporary");
460
+ expect(connection.props.tags.temporary).toBeUndefined();
461
+ expect(connection.props.tags.environment).toBe("test");
462
+ });
463
+ });
464
+ describe("Terraform Outputs", () => {
465
+ it("should create Terraform outputs", () => {
466
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "OutputTest", {
467
+ name: "conn-outputs",
468
+ location: "eastus",
469
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
470
+ connectionType: "IPsec",
471
+ virtualNetworkGateway1: {
472
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
473
+ },
474
+ localNetworkGateway2: {
475
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
476
+ },
477
+ sharedKey: "key",
478
+ });
479
+ expect(connection.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
480
+ expect(connection.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
481
+ expect(connection.locationOutput).toBeInstanceOf(cdktf.TerraformOutput);
482
+ expect(connection.tagsOutput).toBeInstanceOf(cdktf.TerraformOutput);
483
+ });
484
+ it("should have correct id format", () => {
485
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "IdFormat", {
486
+ name: "conn-id",
487
+ location: "eastus",
488
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
489
+ connectionType: "IPsec",
490
+ virtualNetworkGateway1: {
491
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
492
+ },
493
+ localNetworkGateway2: {
494
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
495
+ },
496
+ sharedKey: "key",
497
+ });
498
+ expect(connection.id).toMatch(/^\$\{.*\.id\}$/);
499
+ expect(connection.resourceId).toBe(connection.id);
500
+ });
501
+ });
502
+ describe("Version Compatibility", () => {
503
+ it("should work with all supported API versions", () => {
504
+ const versions = ["2024-01-01", "2024-05-01"];
505
+ versions.forEach((version) => {
506
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, `Conn-${version.replace(/-/g, "")}`, {
507
+ name: `conn-${version}`,
508
+ location: "eastus",
509
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
510
+ apiVersion: version,
511
+ connectionType: "IPsec",
512
+ virtualNetworkGateway1: {
513
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
514
+ },
515
+ localNetworkGateway2: {
516
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
517
+ },
518
+ sharedKey: "key",
519
+ });
520
+ expect(connection.resolvedApiVersion).toBe(version);
521
+ });
522
+ });
523
+ });
524
+ describe("Ignore Changes Configuration", () => {
525
+ it("should apply ignore changes lifecycle rules", () => {
526
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "IgnoreChanges", {
527
+ name: "conn-ignore",
528
+ location: "eastus",
529
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
530
+ connectionType: "IPsec",
531
+ virtualNetworkGateway1: {
532
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
533
+ },
534
+ localNetworkGateway2: {
535
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
536
+ },
537
+ sharedKey: "key",
538
+ ignoreChanges: ["tags"],
539
+ });
540
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
541
+ expect(connection.props.ignoreChanges).toEqual(["tags"]);
542
+ });
543
+ it("should handle empty ignore changes array", () => {
544
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "EmptyIgnore", {
545
+ name: "conn-empty-ignore",
546
+ location: "eastus",
547
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
548
+ connectionType: "IPsec",
549
+ virtualNetworkGateway1: {
550
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
551
+ },
552
+ localNetworkGateway2: {
553
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
554
+ },
555
+ sharedKey: "key",
556
+ ignoreChanges: [],
557
+ });
558
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
559
+ });
560
+ });
561
+ describe("CDK Terraform Integration", () => {
562
+ it("should synthesize to valid Terraform configuration", () => {
563
+ new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "SynthTest", {
564
+ name: "conn-synth",
565
+ location: "eastus",
566
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
567
+ connectionType: "IPsec",
568
+ virtualNetworkGateway1: {
569
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
570
+ },
571
+ localNetworkGateway2: {
572
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
573
+ },
574
+ sharedKey: "key",
575
+ tags: { test: "synthesis" },
576
+ });
577
+ const synthesized = cdktf_1.Testing.synth(stack);
578
+ expect(synthesized).toBeDefined();
579
+ const stackConfig = JSON.parse(synthesized);
580
+ expect(stackConfig.resource).toBeDefined();
581
+ });
582
+ it("should handle multiple connections in the same stack", () => {
583
+ const conn1 = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "Conn1", {
584
+ name: "conn-1",
585
+ location: "eastus",
586
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
587
+ connectionType: "IPsec",
588
+ virtualNetworkGateway1: {
589
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
590
+ },
591
+ localNetworkGateway2: {
592
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
593
+ },
594
+ sharedKey: "key",
595
+ });
596
+ const conn2 = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "Conn2", {
597
+ name: "conn-2",
598
+ location: "westus",
599
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
600
+ apiVersion: "2024-01-01",
601
+ connectionType: "Vnet2Vnet",
602
+ virtualNetworkGateway1: {
603
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
604
+ },
605
+ virtualNetworkGateway2: {
606
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng2",
607
+ },
608
+ sharedKey: "key",
609
+ });
610
+ expect(conn1.resolvedApiVersion).toBe("2024-05-01");
611
+ expect(conn2.resolvedApiVersion).toBe("2024-01-01");
612
+ const synthesized = cdktf_1.Testing.synth(stack);
613
+ expect(synthesized).toBeDefined();
614
+ });
615
+ });
616
+ describe("DPD Timeout Configuration", () => {
617
+ it("should create connection with custom DPD timeout", () => {
618
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(stack, "CustomDPD", {
619
+ name: "conn-dpd",
620
+ location: "eastus",
621
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
622
+ connectionType: "IPsec",
623
+ virtualNetworkGateway1: {
624
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
625
+ },
626
+ localNetworkGateway2: {
627
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
628
+ },
629
+ sharedKey: "key",
630
+ dpdTimeoutSeconds: 45,
631
+ });
632
+ expect(connection.props.dpdTimeoutSeconds).toBe(45);
633
+ });
634
+ });
635
+ describe("Gateway Reference Structure Validation", () => {
636
+ it("should create IPsec connection successfully (fix applied)", () => {
637
+ const testApp = cdktf_1.Testing.app();
638
+ const testStack = new cdktf.TerraformStack(testApp, "IPsecTestStack");
639
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(testStack, "IPsecPropertiesTest", {
640
+ name: "ipsec-props",
641
+ location: "eastus",
642
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
643
+ connectionType: "IPsec",
644
+ virtualNetworkGateway1: {
645
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
646
+ },
647
+ localNetworkGateway2: {
648
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/localNetworkGateways/lng",
649
+ },
650
+ sharedKey: "key",
651
+ });
652
+ // Verify the connection was created successfully
653
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
654
+ expect(connection.props.connectionType).toBe("IPsec");
655
+ // Synthesize to ensure no errors
656
+ const synthesized = cdktf_1.Testing.synth(testStack);
657
+ expect(synthesized).toBeDefined();
658
+ });
659
+ it("should create Vnet2Vnet connection successfully (fix applied)", () => {
660
+ const testApp = cdktf_1.Testing.app();
661
+ const testStack = new cdktf.TerraformStack(testApp, "Vnet2VnetTestStack");
662
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(testStack, "Vnet2VnetPropertiesTest", {
663
+ name: "vnet2vnet-props",
664
+ location: "eastus",
665
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
666
+ connectionType: "Vnet2Vnet",
667
+ virtualNetworkGateway1: {
668
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng1",
669
+ },
670
+ virtualNetworkGateway2: {
671
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/vng2",
672
+ },
673
+ sharedKey: "key",
674
+ });
675
+ // Verify the connection was created successfully
676
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
677
+ expect(connection.props.connectionType).toBe("Vnet2Vnet");
678
+ // Synthesize to ensure no errors
679
+ const synthesized = cdktf_1.Testing.synth(testStack);
680
+ expect(synthesized).toBeDefined();
681
+ });
682
+ it("should create ExpressRoute connection successfully (fix applied)", () => {
683
+ const testApp = cdktf_1.Testing.app();
684
+ const testStack = new cdktf.TerraformStack(testApp, "ExpressRouteTestStack");
685
+ const connection = new virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection(testStack, "ExpressRoutePropertiesTest", {
686
+ name: "er-props",
687
+ location: "eastus",
688
+ resourceGroupId: "/subscriptions/sub-id/resourceGroups/test-rg",
689
+ connectionType: "ExpressRoute",
690
+ virtualNetworkGateway1: {
691
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworkGateways/er-gateway",
692
+ },
693
+ peer: {
694
+ id: "/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/expressRouteCircuits/circuit",
695
+ },
696
+ });
697
+ // Verify the connection was created successfully
698
+ expect(connection).toBeInstanceOf(virtual_network_gateway_connection_1.VirtualNetworkGatewayConnection);
699
+ expect(connection.props.connectionType).toBe("ExpressRoute");
700
+ // Synthesize to ensure no errors
701
+ const synthesized = cdktf_1.Testing.synth(testStack);
702
+ expect(synthesized).toBeDefined();
703
+ });
704
+ });
705
+ });
706
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1uZXR3b3JrLWdhdGV3YXktY29ubmVjdGlvbi5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2F6dXJlLXZpcnR1YWxuZXR3b3JrZ2F0ZXdheWNvbm5lY3Rpb24vdGVzdC92aXJ0dWFsLW5ldHdvcmstZ2F0ZXdheS1jb25uZWN0aW9uLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRzs7QUFFSCxpQ0FBZ0M7QUFDaEMsK0JBQStCO0FBQy9CLGtHQUdtRDtBQUVuRCxRQUFRLENBQUMsa0RBQWtELEVBQUUsR0FBRyxFQUFFO0lBQ2hFLElBQUksR0FBYyxDQUFDO0lBQ25CLElBQUksS0FBMkIsQ0FBQztJQUVoQyxVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsR0FBRyxHQUFHLGVBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyRCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsRUFBRSxDQUFDLHlFQUF5RSxFQUFFLEdBQUcsRUFBRTtZQUNqRixNQUFNLEtBQUssR0FBeUM7Z0JBQ2xELElBQUksRUFBRSxxQkFBcUI7Z0JBQzNCLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixlQUFlLEVBQUUsOENBQThDO2dCQUMvRCxjQUFjLEVBQUUsT0FBTztnQkFDdkIsc0JBQXNCLEVBQUU7b0JBQ3RCLEVBQUUsRUFBRSxpR0FBaUc7aUJBQ3RHO2dCQUNELG9CQUFvQixFQUFFO29CQUNwQixFQUFFLEVBQUUsOEZBQThGO2lCQUNuRztnQkFDRCxTQUFTLEVBQUUsaUJBQWlCO2FBQzdCLENBQUM7WUFFRixNQUFNLFVBQVUsR0FBRyxJQUFJLG9FQUErQixDQUNwRCxLQUFLLEVBQ0wsZ0JBQWdCLEVBQ2hCLEtBQUssQ0FDTixD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dXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tcHJlaGVuc2l2ZSB0ZXN0cyBmb3IgdGhlIFZpcnR1YWwgTmV0d29yayBHYXRld2F5IENvbm5lY3Rpb24gaW1wbGVtZW50YXRpb25cbiAqXG4gKiBUaGlzIHRlc3Qgc3VpdGUgdmFsaWRhdGVzIHRoZSBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uIGNsYXNzIHVzaW5nIHRoZSBBemFwaVJlc291cmNlIGZyYW1ld29yay5cbiAqIFRlc3RzIGNvdmVyIGF1dG9tYXRpYyB2ZXJzaW9uIHJlc29sdXRpb24sIGV4cGxpY2l0IHZlcnNpb24gcGlubmluZywgc2NoZW1hIHZhbGlkYXRpb24sXG4gKiBwcm9wZXJ0eSB0cmFuc2Zvcm1hdGlvbiwgYW5kIHJlc291cmNlIGNyZWF0aW9uIGZvciBhbGwgY29ubmVjdGlvbiB0eXBlcy5cbiAqL1xuXG5pbXBvcnQgeyBUZXN0aW5nIH0gZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgKiBhcyBjZGt0ZiBmcm9tIFwiY2RrdGZcIjtcbmltcG9ydCB7XG4gIFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24sXG4gIFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb25Qcm9wcyxcbn0gZnJvbSBcIi4uL2xpYi92aXJ0dWFsLW5ldHdvcmstZ2F0ZXdheS1jb25uZWN0aW9uXCI7XG5cbmRlc2NyaWJlKFwiVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbiAtIEltcGxlbWVudGF0aW9uXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDb25zdHJ1Y3RvciBhbmQgQmFzaWMgUHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIElQc2VjIGNvbm5lY3Rpb24gd2l0aCBhdXRvbWF0aWMgbGF0ZXN0IHZlcnNpb24gcmVzb2x1dGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtczJzLWNvbm5lY3Rpb25cIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJJUHNlY1wiLFxuICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgfSxcbiAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2xvY2FsTmV0d29ya0dhdGV3YXlzL2xuZ1wiLFxuICAgICAgICB9LFxuICAgICAgICBzaGFyZWRLZXk6IFwibXlTZWN1cmVLZXkxMjMhXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RDb25uZWN0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24pO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMpLnRvQmUocHJvcHMpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ubmFtZSkudG9CZShcInRlc3QtczJzLWNvbm5lY3Rpb25cIik7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5sb2NhdGlvbikudG9CZShcImVhc3R1c1wiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBWbmV0MlZuZXQgY29ubmVjdGlvbiB3aXRoIGV4cGxpY2l0IHZlcnNpb24gcGlubmluZ1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3Qtdm5ldC1jb25uZWN0aW9uXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcIndlc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDI0LTAxLTAxXCIsXG4gICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIlZuZXQyVm5ldFwiLFxuICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgfSxcbiAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcyXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHNoYXJlZEtleTogXCJteVNlY3VyZUtleTEyMyFcIixcbiAgICAgICAgdGFnczogeyBlbnZpcm9ubWVudDogXCJ0ZXN0XCIgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdENvbm5lY3Rpb25cIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDI0LTAxLTAxXCIpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24udGFncykudG9FcXVhbCh7IGVudmlyb25tZW50OiBcInRlc3RcIiB9KTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBFeHByZXNzUm91dGUgY29ubmVjdGlvbiB3aXRoIGFsbCBvcHRpb25hbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1lci1jb25uZWN0aW9uXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImNlbnRyYWx1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiRXhwcmVzc1JvdXRlXCIsXG4gICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvZXItZ2F0ZXdheVwiLFxuICAgICAgICB9LFxuICAgICAgICBwZWVyOiB7XG4gICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9leHByZXNzUm91dGVDaXJjdWl0cy9jaXJjdWl0XCIsXG4gICAgICAgIH0sXG4gICAgICAgIGF1dGhvcml6YXRpb25LZXk6IFwiYXV0aC1rZXktMTIzXCIsXG4gICAgICAgIGVuYWJsZUJncDogdHJ1ZSxcbiAgICAgICAgcm91dGluZ1dlaWdodDogMTAsXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICBlbnZpcm9ubWVudDogXCJwcm9kdWN0aW9uXCIsXG4gICAgICAgICAgcHJvamVjdDogXCJuZXR3b3JraW5nXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGlnbm9yZUNoYW5nZXM6IFtcInRhZ3NcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RDb25uZWN0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvblR5cGUpLnRvQmUoXCJFeHByZXNzUm91dGVcIik7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy5lbmFibGVCZ3ApLnRvQmUodHJ1ZSk7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy50YWdzKS50b0VxdWFsKHByb3BzLnRhZ3MpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgdXNlIGRlZmF1bHQgbmFtZSB3aGVuIG5hbWUgaXMgbm90IHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwiZGVmYXVsdC1uYW1lXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGxvY2FsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgfSxcbiAgICAgICAgc2hhcmVkS2V5OiBcImtleVwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0Q29ubmVjdGlvblwiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLm5hbWUpLnRvQmUoXCJkZWZhdWx0LW5hbWVcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUmVzb3VyY2UgVHlwZSBhbmQgQVBJIFZlcnNpb25zXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYXZlIGNvcnJlY3QgcmVzb3VyY2UgdHlwZVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RDb25uZWN0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtY29ubmVjdGlvblwiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxvY2FsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2xvY2FsTmV0d29ya0dhdGV3YXlzL2xuZ1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcImtleVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBhbGwgcmVnaXN0ZXJlZCBBUEkgdmVyc2lvbnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgdmVyc2lvbnMgPSBbXCIyMDI0LTAxLTAxXCIsIFwiMjAyNC0wNS0wMVwiXTtcblxuICAgICAgdmVyc2lvbnMuZm9yRWFjaCgodmVyc2lvbikgPT4ge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgYENvbm5lY3Rpb24tJHt2ZXJzaW9uLnJlcGxhY2UoLy0vZywgXCJcIil9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiBgY29ubi0ke3ZlcnNpb259YCxcbiAgICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgICBhcGlWZXJzaW9uOiB2ZXJzaW9uLFxuICAgICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2xvY2FsTmV0d29ya0dhdGV3YXlzL2xuZ1wiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIGV4cGVjdChjb25uZWN0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZSh2ZXJzaW9uKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgdXNlIGxhdGVzdCB2ZXJzaW9uIGFzIGRlZmF1bHRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0Q29ubmVjdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LWNvbm5lY3Rpb25cIixcbiAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJJUHNlY1wiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDUtMDFcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiSVBzZWMgQ29ubmVjdGlvbiBUeXBlXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgSVBzZWMgY29ubmVjdGlvbiB3aXRoIG1pbmltYWwgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIklQc2VjTWluaW1hbFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJpcHNlYy1taW5pbWFsXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwibXlTZWN1cmVLZXkxMjMhXCIsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy5jb25uZWN0aW9uVHlwZSkudG9CZShcIklQc2VjXCIpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMubG9jYWxOZXR3b3JrR2F0ZXdheTIpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy5zaGFyZWRLZXkpLnRvQmUoXCJteVNlY3VyZUtleTEyMyFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgSVBzZWMgY29ubmVjdGlvbiB3aXRoIGN1c3RvbSBJUHNlYyBwb2xpY2llc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIklQc2VjQ3VzdG9tXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImlwc2VjLWN1c3RvbVwiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxvY2FsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2xvY2FsTmV0d29ya0dhdGV3YXlzL2xuZ1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcIm15U2VjdXJlS2V5MTIzIVwiLFxuICAgICAgICAgIGNvbm5lY3Rpb25Qcm90b2NvbDogXCJJS0V2MlwiLFxuICAgICAgICAgIGlwc2VjUG9saWNpZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGhHcm91cDogXCJESEdyb3VwMTRcIixcbiAgICAgICAgICAgICAgaWtlRW5jcnlwdGlvbjogXCJBRVMyNTZcIixcbiAgICAgICAgICAgICAgaWtlSW50ZWdyaXR5OiBcIlNIQTI1NlwiLFxuICAgICAgICAgICAgICBpcHNlY0VuY3J5cHRpb246IFwiQUVTMjU2XCIsXG4gICAgICAgICAgICAgIGlwc2VjSW50ZWdyaXR5OiBcIlNIQTI1NlwiLFxuICAgICAgICAgICAgICBwZnNHcm91cDogXCJQRlMyMDQ4XCIsXG4gICAgICAgICAgICAgIHNhTGlmZVRpbWVTZWNvbmRzOiAzNjAwLFxuICAgICAgICAgICAgICBzYURhdGFTaXplS2lsb2J5dGVzOiAxMDI0MDAwMDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdXNlUG9saWN5QmFzZWRUcmFmZmljU2VsZWN0b3JzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvblByb3RvY29sKS50b0JlKFwiSUtFdjJcIik7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy5pcHNlY1BvbGljaWVzKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy51c2VQb2xpY3lCYXNlZFRyYWZmaWNTZWxlY3RvcnMpLnRvQmUodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgSVBzZWMgY29ubmVjdGlvbiB3aXRoIElLRXYxIHByb3RvY29sXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiSVBzZWNJS0V2MVwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJpcHNlYy1pa2V2MVwiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxvY2FsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2xvY2FsTmV0d29ya0dhdGV3YXlzL2xuZ1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcIm15U2VjdXJlS2V5MTIzIVwiLFxuICAgICAgICAgIGNvbm5lY3Rpb25Qcm90b2NvbDogXCJJS0V2MVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvblByb3RvY29sKS50b0JlKFwiSUtFdjFcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiVm5ldDJWbmV0IENvbm5lY3Rpb24gVHlwZVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFZuZXQyVm5ldCBjb25uZWN0aW9uIHdpdGggbWluaW1hbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVm5ldDJWbmV0TWluaW1hbFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ2bmV0MnZuZXQtbWluaW1hbFwiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIlZuZXQyVm5ldFwiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcIm15U2VjdXJlS2V5MTIzIVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvblR5cGUpLnRvQmUoXCJWbmV0MlZuZXRcIik7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy52aXJ0dWFsTmV0d29ya0dhdGV3YXkyKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuc2hhcmVkS2V5KS50b0JlKFwibXlTZWN1cmVLZXkxMjMhXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFZuZXQyVm5ldCBjb25uZWN0aW9uIHdpdGggQkdQIGVuYWJsZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJWbmV0MlZuZXRCR1BcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidm5ldDJ2bmV0LWJncFwiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIlZuZXQyVm5ldFwiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcIm15U2VjdXJlS2V5MTIzIVwiLFxuICAgICAgICAgIGVuYWJsZUJncDogdHJ1ZSxcbiAgICAgICAgICByb3V0aW5nV2VpZ2h0OiA1LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuZW5hYmxlQmdwKS50b0JlKHRydWUpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMucm91dGluZ1dlaWdodCkudG9CZSg1KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJFeHByZXNzUm91dGUgQ29ubmVjdGlvbiBUeXBlXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgRXhwcmVzc1JvdXRlIGNvbm5lY3Rpb24gd2l0aCBtaW5pbWFsIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJFeHByZXNzUm91dGVNaW5pbWFsXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImVyLW1pbmltYWxcIixcbiAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJFeHByZXNzUm91dGVcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvZXItZ2F0ZXdheVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcGVlcjoge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9leHByZXNzUm91dGVDaXJjdWl0cy9jaXJjdWl0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnByb3BzLmNvbm5lY3Rpb25UeXBlKS50b0JlKFwiRXhwcmVzc1JvdXRlXCIpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMucGVlcikudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBFeHByZXNzUm91dGUgY29ubmVjdGlvbiB3aXRoIGF1dGhvcml6YXRpb24ga2V5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiRXhwcmVzc1JvdXRlQXV0aFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJlci1hdXRoXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiRXhwcmVzc1JvdXRlXCIsXG4gICAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL2VyLWdhdGV3YXlcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBlZXI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvZXhwcmVzc1JvdXRlQ2lyY3VpdHMvY2lyY3VpdFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYXV0aG9yaXphdGlvbktleTogXCJteS1hdXRoLWtleS0xMjNcIixcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnByb3BzLmF1dGhvcml6YXRpb25LZXkpLnRvQmUoXCJteS1hdXRoLWtleS0xMjNcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQ29ubmVjdGlvbiBNb2RlIENvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBjb25uZWN0aW9uIHdpdGggRGVmYXVsdCBtb2RlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiRGVmYXVsdE1vZGVcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY29ubi1kZWZhdWx0XCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgY29ubmVjdGlvbk1vZGU6IFwiRGVmYXVsdFwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvbk1vZGUpLnRvQmUoXCJEZWZhdWx0XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGNvbm5lY3Rpb24gd2l0aCBSZXNwb25kZXJPbmx5IG1vZGVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJSZXNwb25kZXJNb2RlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImNvbm4tcmVzcG9uZGVyXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgY29ubmVjdGlvbk1vZGU6IFwiUmVzcG9uZGVyT25seVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvbk1vZGUpLnRvQmUoXCJSZXNwb25kZXJPbmx5XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGNvbm5lY3Rpb24gd2l0aCBJbml0aWF0b3JPbmx5IG1vZGVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJJbml0aWF0b3JNb2RlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImNvbm4taW5pdGlhdG9yXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgY29ubmVjdGlvbk1vZGU6IFwiSW5pdGlhdG9yT25seVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvbk1vZGUpLnRvQmUoXCJJbml0aWF0b3JPbmx5XCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIk5BVCBSdWxlcyBDb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgY29ubmVjdGlvbiB3aXRoIGVncmVzcyBOQVQgcnVsZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJFZ3Jlc3NOQVRcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY29ubi1lZ3Jlc3MtbmF0XCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgZWdyZXNzTmF0UnVsZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzEvbmF0UnVsZXMvcnVsZTFcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnByb3BzLmVncmVzc05hdFJ1bGVzKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgY29ubmVjdGlvbiB3aXRoIGluZ3Jlc3MgTkFUIHJ1bGVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiSW5ncmVzc05BVFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJjb25uLWluZ3Jlc3MtbmF0XCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgaW5ncmVzc05hdFJ1bGVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxL25hdFJ1bGVzL3J1bGUxXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy5pbmdyZXNzTmF0UnVsZXMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUYWdzIE1hbmFnZW1lbnRcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBjb25uZWN0aW9uIHdpdGggdGFnc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRhZ2dlZENvbm5lY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY29ubi10YWdnZWRcIixcbiAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJJUHNlY1wiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgICB0YWdzOiB7XG4gICAgICAgICAgICBlbnZpcm9ubWVudDogXCJwcm9kdWN0aW9uXCIsXG4gICAgICAgICAgICBjb3N0X2NlbnRlcjogXCJlbmdpbmVlcmluZ1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy50YWdzKS50b0VxdWFsKHtcbiAgICAgICAgZW52aXJvbm1lbnQ6IFwicHJvZHVjdGlvblwiLFxuICAgICAgICBjb3N0X2NlbnRlcjogXCJlbmdpbmVlcmluZ1wiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGFkZGluZyB0YWdzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihzdGFjaywgXCJBZGRUYWdcIiwge1xuICAgICAgICBuYW1lOiBcImNvbm4tYWRkLXRhZ1wiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICB9LFxuICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgdGFnczogeyBlbnZpcm9ubWVudDogXCJ0ZXN0XCIgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25uZWN0aW9uLmFkZFRhZyhcIm5ld1RhZ1wiLCBcIm5ld1ZhbHVlXCIpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMudGFncyEubmV3VGFnKS50b0JlKFwibmV3VmFsdWVcIik7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy50YWdzIS5lbnZpcm9ubWVudCkudG9CZShcInRlc3RcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IHJlbW92aW5nIHRhZ3NcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJSZW1vdmVUYWdcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY29ubi1yZW1vdmUtdGFnXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgdGFnczoge1xuICAgICAgICAgICAgZW52aXJvbm1lbnQ6IFwidGVzdFwiLFxuICAgICAgICAgICAgdGVtcG9yYXJ5OiBcInRydWVcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgY29ubmVjdGlvbi5yZW1vdmVUYWcoXCJ0ZW1wb3JhcnlcIik7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy50YWdzIS50ZW1wb3JhcnkpLnRvQmVVbmRlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnByb3BzLnRhZ3MhLmVudmlyb25tZW50KS50b0JlKFwidGVzdFwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUZXJyYWZvcm0gT3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiT3V0cHV0VGVzdFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJjb25uLW91dHB1dHNcIixcbiAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJJUHNlY1wiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLmlkT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ubmFtZU91dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLmxvY2F0aW9uT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24udGFnc091dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgY29ycmVjdCBpZCBmb3JtYXRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJJZEZvcm1hdFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJjb25uLWlkXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5pZCkudG9NYXRjaCgvXlxcJFxcey4qXFwuaWRcXH0kLyk7XG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5yZXNvdXJjZUlkKS50b0JlKGNvbm5lY3Rpb24uaWQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlZlcnNpb24gQ29tcGF0aWJpbGl0eVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgd29yayB3aXRoIGFsbCBzdXBwb3J0ZWQgQVBJIHZlcnNpb25zXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHZlcnNpb25zID0gW1wiMjAyNC0wMS0wMVwiLCBcIjIwMjQtMDUtMDFcIl07XG5cbiAgICAgIHZlcnNpb25zLmZvckVhY2goKHZlcnNpb24pID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgIGBDb25uLSR7dmVyc2lvbi5yZXBsYWNlKC8tL2csIFwiXCIpfWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYGNvbm4tJHt2ZXJzaW9ufWAsXG4gICAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgICAgYXBpVmVyc2lvbjogdmVyc2lvbixcbiAgICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBleHBlY3QoY29ubmVjdGlvbi5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUodmVyc2lvbik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJJZ25vcmUgQ2hhbmdlcyBDb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhcHBseSBpZ25vcmUgY2hhbmdlcyBsaWZlY3ljbGUgcnVsZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJJZ25vcmVDaGFuZ2VzXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImNvbm4taWdub3JlXCIsXG4gICAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkxOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbG9jYWxOZXR3b3JrR2F0ZXdheTI6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZWRLZXk6IFwia2V5XCIsXG4gICAgICAgICAgaWdub3JlQ2hhbmdlczogW1widGFnc1wiXSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25uZWN0aW9uKS50b0JlSW5zdGFuY2VPZihWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKTtcbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvRXF1YWwoW1widGFnc1wiXSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgZW1wdHkgaWdub3JlIGNoYW5nZXMgYXJyYXlcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJFbXB0eUlnbm9yZVwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJjb25uLWVtcHR5LWlnbm9yZVwiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzFcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxvY2FsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2xvY2FsTmV0d29ya0dhdGV3YXlzL2xuZ1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcImtleVwiLFxuICAgICAgICAgIGlnbm9yZUNoYW5nZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNESyBUZXJyYWZvcm0gSW50ZWdyYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN5bnRoZXNpemUgdG8gdmFsaWQgVGVycmFmb3JtIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oc3RhY2ssIFwiU3ludGhUZXN0XCIsIHtcbiAgICAgICAgbmFtZTogXCJjb25uLXN5bnRoXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiSVBzZWNcIixcbiAgICAgICAgdmlydHVhbE5ldHdvcmtHYXRld2F5MToge1xuICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGxvY2FsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgfSxcbiAgICAgICAgc2hhcmVkS2V5OiBcImtleVwiLFxuICAgICAgICB0YWdzOiB7IHRlc3Q6IFwic3ludGhlc2lzXCIgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgZXhwZWN0KHN5bnRoZXNpemVkKS50b0JlRGVmaW5lZCgpO1xuXG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIG11bHRpcGxlIGNvbm5lY3Rpb25zIGluIHRoZSBzYW1lIHN0YWNrXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbm4xID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oc3RhY2ssIFwiQ29ubjFcIiwge1xuICAgICAgICBuYW1lOiBcImNvbm4tMVwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIklQc2VjXCIsXG4gICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICB9LFxuICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvbG9jYWxOZXR3b3JrR2F0ZXdheXMvbG5nXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb25uMiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKHN0YWNrLCBcIkNvbm4yXCIsIHtcbiAgICAgICAgbmFtZTogXCJjb25uLTJcIixcbiAgICAgICAgbG9jYXRpb246IFwid2VzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjQtMDEtMDFcIixcbiAgICAgICAgY29ubmVjdGlvblR5cGU6IFwiVm5ldDJWbmV0XCIsXG4gICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMVwiLFxuICAgICAgICB9LFxuICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya0dhdGV3YXlzL3ZuZzJcIixcbiAgICAgICAgfSxcbiAgICAgICAgc2hhcmVkS2V5OiBcImtleVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25uMS5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDI0LTA1LTAxXCIpO1xuICAgICAgZXhwZWN0KGNvbm4yLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDEtMDFcIik7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiRFBEIFRpbWVvdXQgQ29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGNvbm5lY3Rpb24gd2l0aCBjdXN0b20gRFBEIHRpbWVvdXRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJDdXN0b21EUERcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY29ubi1kcGRcIixcbiAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJJUHNlY1wiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgICBkcGRUaW1lb3V0U2Vjb25kczogNDUsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29ubmVjdGlvbi5wcm9wcy5kcGRUaW1lb3V0U2Vjb25kcykudG9CZSg0NSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiR2F0ZXdheSBSZWZlcmVuY2UgU3RydWN0dXJlIFZhbGlkYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBJUHNlYyBjb25uZWN0aW9uIHN1Y2Nlc3NmdWxseSAoZml4IGFwcGxpZWQpXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBUZXN0aW5nLmFwcCgpO1xuICAgICAgY29uc3QgdGVzdFN0YWNrID0gbmV3IGNka3RmLlRlcnJhZm9ybVN0YWNrKHRlc3RBcHAsIFwiSVBzZWNUZXN0U3RhY2tcIik7XG5cbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgdGVzdFN0YWNrLFxuICAgICAgICBcIklQc2VjUHJvcGVydGllc1Rlc3RcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiaXBzZWMtcHJvcHNcIixcbiAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICByZXNvdXJjZUdyb3VwSWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgICBjb25uZWN0aW9uVHlwZTogXCJJUHNlY1wiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsb2NhbE5ldHdvcmtHYXRld2F5Mjoge1xuICAgICAgICAgICAgaWQ6IFwiL3N1YnNjcmlwdGlvbnMvc3ViLWlkL3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9sb2NhbE5ldHdvcmtHYXRld2F5cy9sbmdcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNoYXJlZEtleTogXCJrZXlcIixcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGUgY29ubmVjdGlvbiB3YXMgY3JlYXRlZCBzdWNjZXNzZnVsbHlcbiAgICAgIGV4cGVjdChjb25uZWN0aW9uKS50b0JlSW5zdGFuY2VPZihWaXJ0dWFsTmV0d29ya0dhdGV3YXlDb25uZWN0aW9uKTtcbiAgICAgIGV4cGVjdChjb25uZWN0aW9uLnByb3BzLmNvbm5lY3Rpb25UeXBlKS50b0JlKFwiSVBzZWNcIik7XG5cbiAgICAgIC8vIFN5bnRoZXNpemUgdG8gZW5zdXJlIG5vIGVycm9yc1xuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHRlc3RTdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgVm5ldDJWbmV0IGNvbm5lY3Rpb24gc3VjY2Vzc2Z1bGx5IChmaXggYXBwbGllZClcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgICBjb25zdCB0ZXN0U3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2sodGVzdEFwcCwgXCJWbmV0MlZuZXRUZXN0U3RhY2tcIik7XG5cbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgVmlydHVhbE5ldHdvcmtHYXRld2F5Q29ubmVjdGlvbihcbiAgICAgICAgdGVzdFN0YWNrLFxuICAgICAgICBcIlZuZXQyVm5ldFByb3BlcnRpZXNUZXN0XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInZuZXQydm5ldC1wcm9wc1wiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIlZuZXQyVm5ldFwiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy92bmcxXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB2aXJ0dWFsTmV0d29ya0dhdGV3YXkyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3JrR2F0ZXdheXMvdm5nMlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2hhcmVkS2V5OiBcImtleVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgLy8gVmVyaWZ5IHRoZSBjb25uZWN0aW9uIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseVxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24pO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvblR5cGUpLnRvQmUoXCJWbmV0MlZuZXRcIik7XG5cbiAgICAgIC8vIFN5bnRoZXNpemUgdG8gZW5zdXJlIG5vIGVycm9yc1xuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHRlc3RTdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgRXhwcmVzc1JvdXRlIGNvbm5lY3Rpb24gc3VjY2Vzc2Z1bGx5IChmaXggYXBwbGllZClcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgICBjb25zdCB0ZXN0U3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soXG4gICAgICAgIHRlc3RBcHAsXG4gICAgICAgIFwiRXhwcmVzc1JvdXRlVGVzdFN0YWNrXCIsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24oXG4gICAgICAgIHRlc3RTdGFjayxcbiAgICAgICAgXCJFeHByZXNzUm91dGVQcm9wZXJ0aWVzVGVzdFwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJlci1wcm9wc1wiLFxuICAgICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICAgIHJlc291cmNlR3JvdXBJZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgIGNvbm5lY3Rpb25UeXBlOiBcIkV4cHJlc3NSb3V0ZVwiLFxuICAgICAgICAgIHZpcnR1YWxOZXR3b3JrR2F0ZXdheTE6IHtcbiAgICAgICAgICAgIGlkOiBcIi9zdWJzY3JpcHRpb25zL3N1Yi1pZC9yZXNvdXJjZUdyb3Vwcy9yZy9wcm92aWRlcnMvTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtHYXRld2F5cy9lci1nYXRld2F5XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwZWVyOiB7XG4gICAgICAgICAgICBpZDogXCIvc3Vic2NyaXB0aW9ucy9zdWItaWQvcmVzb3VyY2VHcm91cHMvcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL2V4cHJlc3NSb3V0ZUNpcmN1aXRzL2NpcmN1aXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgLy8gVmVyaWZ5IHRoZSBjb25uZWN0aW9uIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseVxuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFZpcnR1YWxOZXR3b3JrR2F0ZXdheUNvbm5lY3Rpb24pO1xuICAgICAgZXhwZWN0KGNvbm5lY3Rpb24ucHJvcHMuY29ubmVjdGlvblR5cGUpLnRvQmUoXCJFeHByZXNzUm91dGVcIik7XG5cbiAgICAgIC8vIFN5bnRoZXNpemUgdG8gZW5zdXJlIG5vIGVycm9yc1xuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHRlc3RTdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=