@rudderstack/integrations-lib 0.1.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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/build/constants.d.ts +96 -0
  4. package/build/constants.d.ts.map +1 -0
  5. package/build/constants.js +180 -0
  6. package/build/errors/aborted_error.d.ts +5 -0
  7. package/build/errors/aborted_error.d.ts.map +1 -0
  8. package/build/errors/aborted_error.js +16 -0
  9. package/build/errors/base.d.ts +8 -0
  10. package/build/errors/base.d.ts.map +1 -0
  11. package/build/errors/base.js +14 -0
  12. package/build/errors/configuration_error.d.ts +5 -0
  13. package/build/errors/configuration_error.d.ts.map +1 -0
  14. package/build/errors/configuration_error.js +17 -0
  15. package/build/errors/index.d.ts +17 -0
  16. package/build/errors/index.d.ts.map +1 -0
  17. package/build/errors/index.js +33 -0
  18. package/build/errors/instrumentation_error.d.ts +5 -0
  19. package/build/errors/instrumentation_error.d.ts.map +1 -0
  20. package/build/errors/instrumentation_error.js +16 -0
  21. package/build/errors/invalid_auth_token_error.d.ts +5 -0
  22. package/build/errors/invalid_auth_token_error.d.ts.map +1 -0
  23. package/build/errors/invalid_auth_token_error.js +17 -0
  24. package/build/errors/network_error.d.ts +7 -0
  25. package/build/errors/network_error.d.ts.map +1 -0
  26. package/build/errors/network_error.js +28 -0
  27. package/build/errors/network_instrumentation_error.d.ts +5 -0
  28. package/build/errors/network_instrumentation_error.d.ts.map +1 -0
  29. package/build/errors/network_instrumentation_error.js +17 -0
  30. package/build/errors/oauth_secret_error.d.ts +5 -0
  31. package/build/errors/oauth_secret_error.d.ts.map +1 -0
  32. package/build/errors/oauth_secret_error.js +16 -0
  33. package/build/errors/platform_error.d.ts +5 -0
  34. package/build/errors/platform_error.d.ts.map +1 -0
  35. package/build/errors/platform_error.js +15 -0
  36. package/build/errors/redis_error.d.ts +5 -0
  37. package/build/errors/redis_error.d.ts.map +1 -0
  38. package/build/errors/redis_error.js +16 -0
  39. package/build/errors/retryable_error.d.ts +5 -0
  40. package/build/errors/retryable_error.d.ts.map +1 -0
  41. package/build/errors/retryable_error.js +16 -0
  42. package/build/errors/throttled_error.d.ts +5 -0
  43. package/build/errors/throttled_error.d.ts.map +1 -0
  44. package/build/errors/throttled_error.js +16 -0
  45. package/build/errors/transformation_error.d.ts +5 -0
  46. package/build/errors/transformation_error.d.ts.map +1 -0
  47. package/build/errors/transformation_error.js +15 -0
  48. package/build/errors/unauthorized_error.d.ts +5 -0
  49. package/build/errors/unauthorized_error.d.ts.map +1 -0
  50. package/build/errors/unauthorized_error.js +17 -0
  51. package/build/errors/unhandled_status_code_error.d.ts +5 -0
  52. package/build/errors/unhandled_status_code_error.d.ts.map +1 -0
  53. package/build/errors/unhandled_status_code_error.js +17 -0
  54. package/build/errors/unsupported_event_error.d.ts +5 -0
  55. package/build/errors/unsupported_event_error.d.ts.map +1 -0
  56. package/build/errors/unsupported_event_error.js +16 -0
  57. package/build/index.d.ts +7 -0
  58. package/build/index.d.ts.map +1 -0
  59. package/build/index.js +23 -0
  60. package/build/logger.d.ts +7 -0
  61. package/build/logger.d.ts.map +1 -0
  62. package/build/logger.js +39 -0
  63. package/build/network/clients/axios.d.ts +38 -0
  64. package/build/network/clients/axios.d.ts.map +1 -0
  65. package/build/network/clients/axios.js +197 -0
  66. package/build/network/clients/axios.test.d.ts +2 -0
  67. package/build/network/clients/axios.test.d.ts.map +1 -0
  68. package/build/network/clients/axios.test.js +231 -0
  69. package/build/network/clients/types.d.ts +32 -0
  70. package/build/network/clients/types.d.ts.map +1 -0
  71. package/build/network/clients/types.js +3 -0
  72. package/build/network/factory.d.ts +30 -0
  73. package/build/network/factory.d.ts.map +1 -0
  74. package/build/network/factory.js +46 -0
  75. package/build/network/factory.test.d.ts +2 -0
  76. package/build/network/factory.test.d.ts.map +1 -0
  77. package/build/network/factory.test.js +50 -0
  78. package/build/network/index.d.ts +2 -0
  79. package/build/network/index.d.ts.map +1 -0
  80. package/build/network/index.js +18 -0
  81. package/build/tags.d.ts +56 -0
  82. package/build/tags.d.ts.map +1 -0
  83. package/build/tags.js +59 -0
  84. package/build/types.d.ts +275 -0
  85. package/build/types.d.ts.map +1 -0
  86. package/build/types.js +34 -0
  87. package/build/utils/index.d.ts +4 -0
  88. package/build/utils/index.d.ts.map +1 -0
  89. package/build/utils/index.js +20 -0
  90. package/build/utils/json.d.ts +51 -0
  91. package/build/utils/json.d.ts.map +1 -0
  92. package/build/utils/json.js +507 -0
  93. package/build/utils/json.test.d.ts +2 -0
  94. package/build/utils/json.test.d.ts.map +1 -0
  95. package/build/utils/json.test.js +588 -0
  96. package/build/utils/misc.d.ts +129 -0
  97. package/build/utils/misc.d.ts.map +1 -0
  98. package/build/utils/misc.js +362 -0
  99. package/build/utils/misc.test.d.ts +2 -0
  100. package/build/utils/misc.test.d.ts.map +1 -0
  101. package/build/utils/misc.test.js +2059 -0
  102. package/build/utils/sem.d.ts +29 -0
  103. package/build/utils/sem.d.ts.map +1 -0
  104. package/build/utils/sem.js +196 -0
  105. package/build/utils/sem.test.d.ts +2 -0
  106. package/build/utils/sem.test.d.ts.map +1 -0
  107. package/build/utils/sem.test.js +237 -0
  108. package/package.json +69 -0
@@ -0,0 +1,588 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const errors_1 = require("../errors");
4
+ const json_1 = require("./json");
5
+ describe('JSON utils', () => {
6
+ describe('construct payload happy paths', () => {
7
+ it('should construct payload with valid mapping JSON and message object containing all required source keys', () => {
8
+ const message = {
9
+ event: 'purchase',
10
+ properties: {
11
+ orderId: '12345',
12
+ totalAmount: 100,
13
+ products: [
14
+ { id: 'p1', name: 'Product 1', price: 50 },
15
+ { id: 'p2', name: 'Product 2', price: 50 },
16
+ ],
17
+ },
18
+ };
19
+ const mappingJson = [
20
+ {
21
+ sourceKeys: ['event'],
22
+ destKey: 'event',
23
+ required: true,
24
+ metadata: {},
25
+ },
26
+ {
27
+ sourceKeys: ['properties.orderId'],
28
+ destKey: 'orderId',
29
+ required: true,
30
+ metadata: {},
31
+ },
32
+ {
33
+ sourceKeys: ['properties.totalAmount'],
34
+ destKey: 'totalAmount',
35
+ required: true,
36
+ metadata: {},
37
+ },
38
+ {
39
+ sourceKeys: ['properties.products'],
40
+ destKey: 'products',
41
+ required: true,
42
+ metadata: {},
43
+ },
44
+ ];
45
+ const expectedPayload = {
46
+ event: 'purchase',
47
+ orderId: '12345',
48
+ totalAmount: 100,
49
+ products: [
50
+ { id: 'p1', name: 'Product 1', price: 50 },
51
+ { id: 'p2', name: 'Product 2', price: 50 },
52
+ ],
53
+ };
54
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
55
+ expect(payload).toEqual(expectedPayload);
56
+ });
57
+ it('should construct payload with valid mapping JSON and message object containing some optional source keys', () => {
58
+ const message = {
59
+ event: 'purchase',
60
+ properties: {
61
+ orderId: '12345',
62
+ totalAmount: 100,
63
+ },
64
+ };
65
+ const mappingJson = [
66
+ {
67
+ sourceKeys: ['event'],
68
+ destKey: 'event',
69
+ required: true,
70
+ metadata: {},
71
+ },
72
+ {
73
+ sourceKeys: ['properties.orderId'],
74
+ destKey: 'orderId',
75
+ required: true,
76
+ metadata: {},
77
+ },
78
+ {
79
+ sourceKeys: ['properties.totalAmount'],
80
+ destKey: 'totalAmount',
81
+ required: true,
82
+ metadata: {},
83
+ },
84
+ {
85
+ sourceKeys: ['properties.products'],
86
+ destKey: 'products',
87
+ required: false,
88
+ metadata: {},
89
+ },
90
+ ];
91
+ const expectedPayload = {
92
+ event: 'purchase',
93
+ orderId: '12345',
94
+ totalAmount: 100,
95
+ };
96
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
97
+ expect(payload).toEqual(expectedPayload);
98
+ });
99
+ it('should construct payload with valid mapping JSON and message object containing nested source keys', () => {
100
+ const message = {
101
+ event: 'purchase',
102
+ properties: {
103
+ order: {
104
+ id: '12345',
105
+ totalAmount: 100,
106
+ },
107
+ },
108
+ };
109
+ const mappingJson = [
110
+ {
111
+ sourceKeys: ['event'],
112
+ destKey: 'event',
113
+ required: true,
114
+ metadata: {},
115
+ },
116
+ {
117
+ sourceKeys: ['properties.order.id'],
118
+ destKey: 'orderId',
119
+ required: true,
120
+ metadata: {},
121
+ },
122
+ {
123
+ sourceKeys: ['properties.order.totalAmount'],
124
+ destKey: 'totalAmount',
125
+ required: true,
126
+ metadata: {},
127
+ },
128
+ ];
129
+ const expectedPayload = {
130
+ event: 'purchase',
131
+ orderId: '12345',
132
+ totalAmount: 100,
133
+ };
134
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
135
+ expect(payload).toEqual(expectedPayload);
136
+ });
137
+ it('should construct payload with valid mapping JSON and message object containing source keys with different data types', () => {
138
+ const message = {
139
+ event: 'purchase',
140
+ properties: {
141
+ orderId: 12345,
142
+ totalAmount: '100',
143
+ },
144
+ };
145
+ const mappingJson = [
146
+ {
147
+ sourceKeys: ['event'],
148
+ destKey: 'event',
149
+ required: true,
150
+ metadata: {},
151
+ },
152
+ {
153
+ sourceKeys: ['properties.orderId'],
154
+ destKey: 'orderId',
155
+ required: true,
156
+ metadata: {},
157
+ },
158
+ {
159
+ sourceKeys: ['properties.totalAmount'],
160
+ destKey: 'totalAmount',
161
+ required: true,
162
+ metadata: {},
163
+ },
164
+ ];
165
+ const expectedPayload = {
166
+ event: 'purchase',
167
+ orderId: 12345,
168
+ totalAmount: '100',
169
+ };
170
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
171
+ expect(payload).toEqual(expectedPayload);
172
+ });
173
+ it('should construct payload with valid mapping JSON and message object containing source keys with arrays of values', () => {
174
+ const message = {
175
+ event: 'purchase',
176
+ properties: {
177
+ products: [
178
+ { id: 'p1', name: 'Product 1', price: 50 },
179
+ { id: 'p2', name: 'Product 2', price: 50 },
180
+ ],
181
+ },
182
+ };
183
+ const mappingJson = [
184
+ {
185
+ sourceKeys: ['event'],
186
+ destKey: 'event',
187
+ required: true,
188
+ metadata: {},
189
+ },
190
+ {
191
+ sourceKeys: ['properties.products'],
192
+ destKey: 'products',
193
+ required: true,
194
+ metadata: {},
195
+ },
196
+ ];
197
+ const expectedPayload = {
198
+ event: 'purchase',
199
+ products: [
200
+ { id: 'p1', name: 'Product 1', price: 50 },
201
+ { id: 'p2', name: 'Product 2', price: 50 },
202
+ ],
203
+ };
204
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
205
+ expect(payload).toEqual(expectedPayload);
206
+ });
207
+ it('should construct payload with valid mapping JSON and message object containing source keys with for operations', () => {
208
+ const message = {
209
+ event: 'purchase',
210
+ properties: {
211
+ orderId: '12345',
212
+ price: 100,
213
+ quantity: 2,
214
+ addon1: 10,
215
+ addon2: 20,
216
+ },
217
+ };
218
+ const mappingJson = [
219
+ {
220
+ sourceKeys: ['event'],
221
+ destKey: 'event',
222
+ required: true,
223
+ metadata: {},
224
+ },
225
+ {
226
+ sourceKeys: ['properties.orderId'],
227
+ destKey: 'orderId',
228
+ required: true,
229
+ },
230
+ {
231
+ sourceKeys: [
232
+ {
233
+ operation: 'multiplication',
234
+ args: [
235
+ {
236
+ sourceKeys: 'properties.price',
237
+ },
238
+ {
239
+ sourceKeys: 'properties.quantity',
240
+ default: 1,
241
+ },
242
+ ],
243
+ },
244
+ ],
245
+ destKey: 'totalAmount',
246
+ required: true,
247
+ },
248
+ {
249
+ sourceKeys: [
250
+ {
251
+ operation: 'addition',
252
+ args: [
253
+ {
254
+ sourceKeys: 'properties.addon1',
255
+ },
256
+ {
257
+ sourceKeys: 'properties.addon2',
258
+ default: 1,
259
+ },
260
+ ],
261
+ },
262
+ ],
263
+ destKey: 'totalAddon',
264
+ required: true,
265
+ },
266
+ ];
267
+ const expectedPayload = {
268
+ event: 'purchase',
269
+ orderId: '12345',
270
+ totalAmount: 200,
271
+ totalAddon: 30,
272
+ };
273
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
274
+ expect(payload).toEqual(expectedPayload);
275
+ });
276
+ it('should construct payload with valid mapping JSON and message object containing source keys with metadata configs', () => {
277
+ const message = {
278
+ event: 'purchase',
279
+ properties: {
280
+ orderId: 12345,
281
+ totalAmount: '100',
282
+ item: 'Mobile',
283
+ products: [
284
+ { id: 'p1', name: 'Product 1', price: 50 },
285
+ { id: 'p2', name: 'Product 2', price: 50 },
286
+ ],
287
+ inventory: {
288
+ item1: 'item1',
289
+ item2: 'item2',
290
+ },
291
+ },
292
+ timeStamp: '2021-09-01T00:00:00.000Z',
293
+ };
294
+ const mappingJson = [
295
+ {
296
+ sourceKeys: ['event'],
297
+ destKey: 'event',
298
+ required: true,
299
+ metadata: {
300
+ type: 'toString',
301
+ },
302
+ },
303
+ {
304
+ sourceKeys: ['properties.orderId'],
305
+ destKey: 'orderId',
306
+ required: true,
307
+ metadata: {
308
+ type: 'toString',
309
+ },
310
+ },
311
+ {
312
+ sourceKeys: ['properties.totalAmount'],
313
+ destKey: 'totalAmount',
314
+ required: true,
315
+ metadata: {
316
+ type: 'toNumber',
317
+ },
318
+ },
319
+ {
320
+ sourceKeys: ['properties.products'],
321
+ destKey: 'products',
322
+ required: true,
323
+ },
324
+ {
325
+ sourceKeys: 'timeStamp',
326
+ required: true,
327
+ metadata: {
328
+ type: 'timestamp',
329
+ typeFormat: 'yyyy-MM-DDTHH:mm:ssZZ',
330
+ },
331
+ destKey: 'timestamp',
332
+ },
333
+ {
334
+ sourceKeys: ['random'],
335
+ destKey: 'random',
336
+ metadata: {
337
+ defaultValue: 'random',
338
+ },
339
+ },
340
+ {
341
+ sourceKeys: ['properties.inventory'],
342
+ destKey: 'inventory',
343
+ metadata: {
344
+ excludes: ['item2'],
345
+ },
346
+ },
347
+ {
348
+ sourceKeys: ['properties.item'],
349
+ destKey: 'itemName',
350
+ metadata: {
351
+ multikeyMap: [
352
+ {
353
+ sourceVal: ['Mobile', 'Telephone'],
354
+ destVal: 'mob',
355
+ },
356
+ ],
357
+ },
358
+ },
359
+ ];
360
+ const expectedPayload = {
361
+ event: 'purchase',
362
+ orderId: '12345',
363
+ totalAmount: 100,
364
+ products: [
365
+ { id: 'p1', name: 'Product 1', price: 50 },
366
+ { id: 'p2', name: 'Product 2', price: 50 },
367
+ ],
368
+ inventory: {
369
+ item1: 'item1',
370
+ },
371
+ itemName: 'mob',
372
+ random: 'random',
373
+ timestamp: '2021-09-01T00:00:00+0000',
374
+ };
375
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
376
+ expect(payload).toEqual(expectedPayload);
377
+ });
378
+ });
379
+ describe('construct payload edge cases', () => {
380
+ it('should return null when given an empty mappingJson', () => {
381
+ const message = {
382
+ event: 'purchase',
383
+ properties: {
384
+ revenue: 100,
385
+ currency: 'USD',
386
+ },
387
+ };
388
+ const mappingJson = [];
389
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
390
+ expect(payload).toBeNull();
391
+ });
392
+ it('should return null when given an invalid sourceKey', () => {
393
+ const message = {
394
+ event: 'purchase',
395
+ properties: {
396
+ revenue: 100,
397
+ currency: 'USD',
398
+ },
399
+ };
400
+ const sourceKey = 'invalidKey';
401
+ const value = json_1.JsonUtils.getFieldValueFromMessage(message, sourceKey);
402
+ expect(value).toBeNull();
403
+ });
404
+ it('should handle when metadata is invalid', () => {
405
+ const message = {
406
+ event: 'purchase',
407
+ properties: {
408
+ revenue: 100,
409
+ currency: 'USD',
410
+ products: [
411
+ {
412
+ name: 'Product 1',
413
+ price: 50,
414
+ quantity: 2,
415
+ },
416
+ {
417
+ name: 'Product 2',
418
+ price: 30,
419
+ quantity: 1,
420
+ },
421
+ ],
422
+ },
423
+ };
424
+ const mappingJson = [
425
+ {
426
+ sourceKeys: 'properties.revenue',
427
+ destKey: 'revenue',
428
+ required: true,
429
+ metadata: {
430
+ type: 'invalidType',
431
+ },
432
+ },
433
+ ];
434
+ const value = json_1.JsonUtils.constructPayload(message, mappingJson);
435
+ expect(value).toEqual({
436
+ revenue: 100,
437
+ });
438
+ });
439
+ it('should throw an InstrumentationError when a required value is missing', () => {
440
+ const message = {
441
+ event: 'purchase',
442
+ properties: {
443
+ revenue: 100,
444
+ currency: 'USD',
445
+ products: [
446
+ {
447
+ name: 'Product 1',
448
+ price: 50,
449
+ quantity: 2,
450
+ },
451
+ {
452
+ name: 'Product 2',
453
+ price: 30,
454
+ quantity: 1,
455
+ },
456
+ ],
457
+ },
458
+ };
459
+ const mappingJson = [
460
+ {
461
+ sourceKeys: 'event',
462
+ destKey: 'event',
463
+ required: true,
464
+ metadata: {},
465
+ },
466
+ {
467
+ sourceKeys: 'properties.revenue',
468
+ destKey: 'revenue',
469
+ required: true,
470
+ metadata: {},
471
+ },
472
+ {
473
+ sourceKeys: 'properties.currency',
474
+ destKey: 'currency',
475
+ required: true,
476
+ metadata: {},
477
+ },
478
+ {
479
+ sourceKeys: 'properties.products',
480
+ destKey: 'products',
481
+ required: true,
482
+ metadata: {},
483
+ },
484
+ {
485
+ sourceKeys: 'properties.invalidKey',
486
+ destKey: 'invalidKey',
487
+ required: true,
488
+ metadata: {},
489
+ },
490
+ ];
491
+ expect(() => {
492
+ json_1.JsonUtils.constructPayload(message, mappingJson);
493
+ }).toThrow(errors_1.InstrumentationError);
494
+ });
495
+ it('should construct the payload correctly with a valid mappingJson and message object when destination key is an empty string', () => {
496
+ const message = {
497
+ event: 'purchase',
498
+ properties: {
499
+ revenue: 100,
500
+ currency: 'USD',
501
+ products: [
502
+ {
503
+ name: 'Product 1',
504
+ price: 50,
505
+ quantity: 2,
506
+ },
507
+ {
508
+ name: 'Product 2',
509
+ price: 30,
510
+ quantity: 1,
511
+ },
512
+ ],
513
+ },
514
+ };
515
+ const mappingJson = [
516
+ {
517
+ sourceKeys: 'event',
518
+ required: true,
519
+ metadata: {},
520
+ },
521
+ {
522
+ sourceKeys: 'properties.revenue',
523
+ required: true,
524
+ metadata: {},
525
+ },
526
+ {
527
+ sourceKeys: 'properties.currency',
528
+ required: true,
529
+ metadata: {},
530
+ },
531
+ {
532
+ sourceKeys: 'properties.products',
533
+ required: true,
534
+ metadata: {},
535
+ },
536
+ ];
537
+ // Not a correct payload as the destination keys are empty strings or not present
538
+ const expectedPayload = {
539
+ '': [
540
+ {
541
+ name: 'Product 1',
542
+ price: 50,
543
+ quantity: 2,
544
+ },
545
+ {
546
+ name: 'Product 2',
547
+ price: 30,
548
+ quantity: 1,
549
+ },
550
+ ],
551
+ };
552
+ const payload = json_1.JsonUtils.constructPayload(message, mappingJson);
553
+ expect(payload).toEqual(expectedPayload);
554
+ });
555
+ });
556
+ describe('json util other functions', () => {
557
+ it('should retrieve the field value correctly from the message using a valid sourceKey', () => {
558
+ const message = {
559
+ event: 'purchase',
560
+ properties: {
561
+ revenue: 100,
562
+ currency: 'USD',
563
+ },
564
+ traits: {
565
+ firstName: 'John',
566
+ lastName: 'Doe',
567
+ },
568
+ };
569
+ const sourceKey = 'firstName';
570
+ const expectedValue = 'John';
571
+ const value = json_1.JsonUtils.getFieldValueFromMessage(message, sourceKey);
572
+ expect(value).toEqual(expectedValue);
573
+ });
574
+ it('should return null when given an invalid sourceKey', () => {
575
+ const message = {
576
+ event: 'purchase',
577
+ properties: {
578
+ revenue: 100,
579
+ currency: 'USD',
580
+ },
581
+ };
582
+ const sourceKey = 'invalidKey';
583
+ const value = json_1.JsonUtils.getFieldValueFromMessage(message, sourceKey);
584
+ expect(value).toBeNull();
585
+ });
586
+ });
587
+ });
588
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2pzb24udGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNDQUFpRDtBQUNqRCxpQ0FBbUM7QUFDbkMsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7SUFDMUIsUUFBUSxDQUFDLCtCQUErQixFQUFFLEdBQUcsRUFBRTtRQUM3QyxFQUFFLENBQUMseUdBQXlHLEVBQUUsR0FBRyxFQUFFO1lBQ2pILE1BQU0sT0FBTyxHQUFHO2dCQUNkLEtBQUssRUFBRSxVQUFVO2dCQUNqQixVQUFVLEVBQUU7b0JBQ1YsT0FBTyxFQUFFLE9BQU87b0JBQ2hCLFdBQVcsRUFBRSxHQUFHO29CQUNoQixRQUFRLEVBQUU7d0JBQ1IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTt3QkFDMUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtxQkFDM0M7aUJBQ0Y7YUFDRixDQUFDO1lBRUYsTUFBTSxXQUFXLEdBQUc7Z0JBQ2xCO29CQUNFLFVBQVUsRUFBRSxDQUFDLE9BQU8sQ0FBQztvQkFDckIsT0FBTyxFQUFFLE9BQU87b0JBQ2hCLFFBQVEsRUFBRSxJQUFJO29CQUNkLFFBQVEsRUFBRSxFQUFFO2lCQUNiO2dCQUNEO29CQUNFLFVBQVUsRUFBRSxDQUFDLG9CQUFvQixDQUFDO29CQUNsQyxPQUFPLEVBQUUsU0FBUztvQkFDbEIsUUFBUSxFQUFFLElBQUk7b0JBQ2QsUUFBUSxFQUFFLEVBQUU7aUJBQ2I7Z0JBQ0Q7b0JBQ0UsVUFBVSxFQUFFLENBQUMsd0JBQXdCLENBQUM7b0JBQ3RDLE9BQU8sRUFBRSxhQUFhO29CQUN0QixRQUFRLEVBQUUsSUFBSTtvQkFDZCxRQUFRLEVBQUUsRUFBRTtpQkFDYjtnQkFDRDtvQkFD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LE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxFQUFFO1lBQzVELE1BQU0sT0FBTyxHQUFHO2dCQUNkLEtBQUssRUFBRSxVQUFVO2dCQUNqQixVQUFVLEVBQUU7b0JBQ1YsT0FBTyxFQUFFLEdBQUc7b0JBQ1osUUFBUSxFQUFFLEtBQUs7aUJBQ2hCO2FBQ0YsQ0FBQztZQUVGLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQztZQUUvQixNQUFNLEtBQUssR0FBRyxnQkFBUyxDQUFDLHdCQUF3QixDQUFDLE9BQWMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUM1RSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5zdHJ1bWVudGF0aW9uRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMnO1xuaW1wb3J0IHsgSnNvblV0aWxzIH0gZnJvbSAnLi9qc29uJztcbmRlc2NyaWJlKCdKU09OIHV0aWxzJywgKCkgPT4ge1xuICBkZXNjcmliZSgnY29uc3RydWN0IHBheWxvYWQgaGFwcHkgcGF0aHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgcGF5bG9hZCB3aXRoIHZhbGlkIG1hcHBpbmcgSlNPTiBhbmQgbWVzc2FnZSBvYmplY3QgY29udGFpbmluZyBhbGwgcmVxdWlyZWQgc291cmNlIGtleXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIG9yZGVySWQ6ICcxMjM0NScsXG4gICAgICAgICAgdG90YWxBbW91bnQ6IDEwMCxcbiAgICAgICAgICBwcm9kdWN0czogW1xuICAgICAgICAgICAgeyBpZDogJ3AxJywgbmFtZTogJ1Byb2R1Y3QgMScsIHByaWNlOiA1MCB9LFxuICAgICAgICAgICAgeyBpZDogJ3AyJywgbmFtZTogJ1Byb2R1Y3QgMicsIHByaWNlOiA1MCB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYXBwaW5nSnNvbiA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6IFsnZXZlbnQnXSxcbiAgICAgICAgICBkZXN0S2V5OiAnZXZlbnQnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6IFsncHJvcGVydGllcy5vcmRlcklkJ10sXG4gICAgICAgICAgZGVzdEtleTogJ29yZGVySWQnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6IFsncHJvcGVydGllcy50b3RhbEFtb3VudCddLFxuICAgICAgICAgIGRlc3RLZXk6ICd0b3RhbEFtb3VudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLnByb2R1Y3RzJ10sXG4gICAgICAgICAgZGVzdEtleTogJ3Byb2R1Y3RzJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBleHBlY3RlZFBheWxvYWQgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBvcmRlcklkOiAnMTIzNDUnLFxuICAgICAgICB0b3RhbEFtb3VudDogMTAwLFxuICAgICAgICBwcm9kdWN0czogW1xuICAgICAgICAgIHsgaWQ6ICdwMScsIG5hbWU6ICdQcm9kdWN0IDEnLCBwcmljZTogNTAgfSxcbiAgICAgICAgICB7IGlkOiAncDInLCBuYW1lOiAnUHJvZHVjdCAyJywgcHJpY2U6IDUwIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0gSnNvblV0aWxzLmNvbnN0cnVjdFBheWxvYWQobWVzc2FnZSBhcyBhbnksIG1hcHBpbmdKc29uKTtcbiAgICAgIGV4cGVjdChwYXlsb2FkKS50b0VxdWFsKGV4cGVjdGVkUGF5bG9hZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBwYXlsb2FkIHdpdGggdmFsaWQgbWFwcGluZyBKU09OIGFuZCBtZXNzYWdlIG9iamVjdCBjb250YWluaW5nIHNvbWUgb3B0aW9uYWwgc291cmNlIGtleXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIG9yZGVySWQ6ICcxMjM0NScsXG4gICAgICAgICAgdG90YWxBbW91bnQ6IDEwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hcHBpbmdKc29uID0gW1xuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydldmVudCddLFxuICAgICAgICAgIGRlc3RLZXk6ICdldmVudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLm9yZGVySWQnXSxcbiAgICAgICAgICBkZXN0S2V5OiAnb3JkZXJJZCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLnRvdGFsQW1vdW50J10sXG4gICAgICAgICAgZGVzdEtleTogJ3RvdGFsQW1vdW50JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ3Byb3BlcnRpZXMucHJvZHVjdHMnXSxcbiAgICAgICAgICBkZXN0S2V5OiAncHJvZHVjdHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBleHBlY3RlZFBheWxvYWQgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBvcmRlcklkOiAnMTIzNDUnLFxuICAgICAgICB0b3RhbEFtb3VudDogMTAwLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IEpzb25VdGlscy5jb25zdHJ1Y3RQYXlsb2FkKG1lc3NhZ2UgYXMgYW55LCBtYXBwaW5nSnNvbik7XG4gICAgICBleHBlY3QocGF5bG9hZCkudG9FcXVhbChleHBlY3RlZFBheWxvYWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgcGF5bG9hZCB3aXRoIHZhbGlkIG1hcHBpbmcgSlNPTiBhbmQgbWVzc2FnZSBvYmplY3QgY29udGFpbmluZyBuZXN0ZWQgc291cmNlIGtleXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIG9yZGVyOiB7XG4gICAgICAgICAgICBpZDogJzEyMzQ1JyxcbiAgICAgICAgICAgIHRvdGFsQW1vdW50OiAxMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hcHBpbmdKc29uID0gW1xuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydldmVudCddLFxuICAgICAgICAgIGRlc3RLZXk6ICdldmVudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLm9yZGVyLmlkJ10sXG4gICAgICAgICAgZGVzdEtleTogJ29yZGVySWQnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6IFsncHJvcGVydGllcy5vcmRlci50b3RhbEFtb3VudCddLFxuICAgICAgICAgIGRlc3RLZXk6ICd0b3RhbEFtb3VudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWRQYXlsb2FkID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgb3JkZXJJZDogJzEyMzQ1JyxcbiAgICAgICAgdG90YWxBbW91bnQ6IDEwMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSBKc29uVXRpbHMuY29uc3RydWN0UGF5bG9hZChtZXNzYWdlIGFzIGFueSwgbWFwcGluZ0pzb24pO1xuICAgICAgZXhwZWN0KHBheWxvYWQpLnRvRXF1YWwoZXhwZWN0ZWRQYXlsb2FkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IHBheWxvYWQgd2l0aCB2YWxpZCBtYXBwaW5nIEpTT04gYW5kIG1lc3NhZ2Ugb2JqZWN0IGNvbnRhaW5pbmcgc291cmNlIGtleXMgd2l0aCBkaWZmZXJlbnQgZGF0YSB0eXBlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgb3JkZXJJZDogMTIzNDUsXG4gICAgICAgICAgdG90YWxBbW91bnQ6ICcxMDAnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFwcGluZ0pzb24gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ2V2ZW50J10sXG4gICAgICAgICAgZGVzdEtleTogJ2V2ZW50JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ3Byb3BlcnRpZXMub3JkZXJJZCddLFxuICAgICAgICAgIGRlc3RLZXk6ICdvcmRlcklkJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ3Byb3BlcnRpZXMudG90YWxBbW91bnQnXSxcbiAgICAgICAgICBkZXN0S2V5OiAndG90YWxBbW91bnQnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IGV4cGVjdGVkUGF5bG9hZCA9IHtcbiAgICAgICAgZXZlbnQ6ICdwdXJjaGFzZScsXG4gICAgICAgIG9yZGVySWQ6IDEyMzQ1LFxuICAgICAgICB0b3RhbEFtb3VudDogJzEwMCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0gSnNvblV0aWxzLmNvbnN0cnVjdFBheWxvYWQobWVzc2FnZSBhcyBhbnksIG1hcHBpbmdKc29uKTtcbiAgICAgIGV4cGVjdChwYXlsb2FkKS50b0VxdWFsKGV4cGVjdGVkUGF5bG9hZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBwYXlsb2FkIHdpdGggdmFsaWQgbWFwcGluZyBKU09OIGFuZCBtZXNzYWdlIG9iamVjdCBjb250YWluaW5nIHNvdXJjZSBrZXlzIHdpdGggYXJyYXlzIG9mIHZhbHVlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgcHJvZHVjdHM6IFtcbiAgICAgICAgICAgIHsgaWQ6ICdwMScsIG5hbWU6ICdQcm9kdWN0IDEnLCBwcmljZTogNTAgfSxcbiAgICAgICAgICAgIHsgaWQ6ICdwMicsIG5hbWU6ICdQcm9kdWN0IDInLCBwcmljZTogNTAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFwcGluZ0pzb24gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ2V2ZW50J10sXG4gICAgICAgICAgZGVzdEtleTogJ2V2ZW50JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ3Byb3BlcnRpZXMucHJvZHVjdHMnXSxcbiAgICAgICAgICBkZXN0S2V5OiAncHJvZHVjdHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IGV4cGVjdGVkUGF5bG9hZCA9IHtcbiAgICAgICAgZXZlbnQ6ICdwdXJjaGFzZScsXG4gICAgICAgIHByb2R1Y3RzOiBbXG4gICAgICAgICAgeyBpZDogJ3AxJywgbmFtZTogJ1Byb2R1Y3QgMScsIHByaWNlOiA1MCB9LFxuICAgICAgICAgIHsgaWQ6ICdwMicsIG5hbWU6ICdQcm9kdWN0IDInLCBwcmljZTogNTAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSBKc29uVXRpbHMuY29uc3RydWN0UGF5bG9hZChtZXNzYWdlIGFzIGFueSwgbWFwcGluZ0pzb24pO1xuICAgICAgZXhwZWN0KHBheWxvYWQpLnRvRXF1YWwoZXhwZWN0ZWRQYXlsb2FkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IHBheWxvYWQgd2l0aCB2YWxpZCBtYXBwaW5nIEpTT04gYW5kIG1lc3NhZ2Ugb2JqZWN0IGNvbnRhaW5pbmcgc291cmNlIGtleXMgd2l0aCBmb3Igb3BlcmF0aW9ucycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgb3JkZXJJZDogJzEyMzQ1JyxcbiAgICAgICAgICBwcmljZTogMTAwLFxuICAgICAgICAgIHF1YW50aXR5OiAyLFxuICAgICAgICAgIGFkZG9uMTogMTAsXG4gICAgICAgICAgYWRkb24yOiAyMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hcHBpbmdKc29uID0gW1xuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydldmVudCddLFxuICAgICAgICAgIGRlc3RLZXk6ICdldmVudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLm9yZGVySWQnXSxcbiAgICAgICAgICBkZXN0S2V5OiAnb3JkZXJJZCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG9wZXJhdGlvbjogJ211bHRpcGxpY2F0aW9uJyxcbiAgICAgICAgICAgICAgYXJnczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHNvdXJjZUtleXM6ICdwcm9wZXJ0aWVzLnByaWNlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHNvdXJjZUtleXM6ICdwcm9wZXJ0aWVzLnF1YW50aXR5JyxcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDEsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXN0S2V5OiAndG90YWxBbW91bnQnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBvcGVyYXRpb246ICdhZGRpdGlvbicsXG4gICAgICAgICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBzb3VyY2VLZXlzOiAncHJvcGVydGllcy5hZGRvbjEnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgc291cmNlS2V5czogJ3Byb3BlcnRpZXMuYWRkb24yJyxcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDEsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkZXN0S2V5OiAndG90YWxBZGRvbicsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBleHBlY3RlZFBheWxvYWQgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBvcmRlcklkOiAnMTIzNDUnLFxuICAgICAgICB0b3RhbEFtb3VudDogMjAwLFxuICAgICAgICB0b3RhbEFkZG9uOiAzMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSBKc29uVXRpbHMuY29uc3RydWN0UGF5bG9hZChtZXNzYWdlIGFzIGFueSwgbWFwcGluZ0pzb24pO1xuICAgICAgZXhwZWN0KHBheWxvYWQpLnRvRXF1YWwoZXhwZWN0ZWRQYXlsb2FkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IHBheWxvYWQgd2l0aCB2YWxpZCBtYXBwaW5nIEpTT04gYW5kIG1lc3NhZ2Ugb2JqZWN0IGNvbnRhaW5pbmcgc291cmNlIGtleXMgd2l0aCBtZXRhZGF0YSBjb25maWdzJywgKCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgICAgZXZlbnQ6ICdwdXJjaGFzZScsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBvcmRlcklkOiAxMjM0NSxcbiAgICAgICAgICB0b3RhbEFtb3VudDogJzEwMCcsXG4gICAgICAgICAgaXRlbTogJ01vYmlsZScsXG4gICAgICAgICAgcHJvZHVjdHM6IFtcbiAgICAgICAgICAgIHsgaWQ6ICdwMScsIG5hbWU6ICdQcm9kdWN0IDEnLCBwcmljZTogNTAgfSxcbiAgICAgICAgICAgIHsgaWQ6ICdwMicsIG5hbWU6ICdQcm9kdWN0IDInLCBwcmljZTogNTAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGludmVudG9yeToge1xuICAgICAgICAgICAgaXRlbTE6ICdpdGVtMScsXG4gICAgICAgICAgICBpdGVtMjogJ2l0ZW0yJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB0aW1lU3RhbXA6ICcyMDIxLTA5LTAxVDAwOjAwOjAwLjAwMFonLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFwcGluZ0pzb24gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ2V2ZW50J10sXG4gICAgICAgICAgZGVzdEtleTogJ2V2ZW50JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgdHlwZTogJ3RvU3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLm9yZGVySWQnXSxcbiAgICAgICAgICBkZXN0S2V5OiAnb3JkZXJJZCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHR5cGU6ICd0b1N0cmluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6IFsncHJvcGVydGllcy50b3RhbEFtb3VudCddLFxuICAgICAgICAgIGRlc3RLZXk6ICd0b3RhbEFtb3VudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHR5cGU6ICd0b051bWJlcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6IFsncHJvcGVydGllcy5wcm9kdWN0cyddLFxuICAgICAgICAgIGRlc3RLZXk6ICdwcm9kdWN0cycsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiAndGltZVN0YW1wJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgdHlwZTogJ3RpbWVzdGFtcCcsXG4gICAgICAgICAgICB0eXBlRm9ybWF0OiAneXl5eS1NTS1ERFRISDptbTpzc1paJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGRlc3RLZXk6ICd0aW1lc3RhbXAnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydyYW5kb20nXSxcbiAgICAgICAgICBkZXN0S2V5OiAncmFuZG9tJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAncmFuZG9tJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogWydwcm9wZXJ0aWVzLmludmVudG9yeSddLFxuICAgICAgICAgIGRlc3RLZXk6ICdpbnZlbnRvcnknLFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICBleGNsdWRlczogWydpdGVtMiddLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiBbJ3Byb3BlcnRpZXMuaXRlbSddLFxuICAgICAgICAgIGRlc3RLZXk6ICdpdGVtTmFtZScsXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIG11bHRpa2V5TWFwOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzb3VyY2VWYWw6IFsnTW9iaWxlJywgJ1RlbGVwaG9uZSddLFxuICAgICAgICAgICAgICAgIGRlc3RWYWw6ICdtb2InLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWRQYXlsb2FkID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgb3JkZXJJZDogJzEyMzQ1JyxcbiAgICAgICAgdG90YWxBbW91bnQ6IDEwMCxcbiAgICAgICAgcHJvZHVjdHM6IFtcbiAgICAgICAgICB7IGlkOiAncDEnLCBuYW1lOiAnUHJvZHVjdCAxJywgcHJpY2U6IDUwIH0sXG4gICAgICAgICAgeyBpZDogJ3AyJywgbmFtZTogJ1Byb2R1Y3QgMicsIHByaWNlOiA1MCB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnZlbnRvcnk6IHtcbiAgICAgICAgICBpdGVtMTogJ2l0ZW0xJyxcbiAgICAgICAgfSxcbiAgICAgICAgaXRlbU5hbWU6ICdtb2InLFxuICAgICAgICByYW5kb206ICdyYW5kb20nLFxuICAgICAgICB0aW1lc3RhbXA6ICcyMDIxLTA5LTAxVDAwOjAwOjAwKzAwMDAnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IEpzb25VdGlscy5jb25zdHJ1Y3RQYXlsb2FkKG1lc3NhZ2UgYXMgYW55LCBtYXBwaW5nSnNvbik7XG4gICAgICBleHBlY3QocGF5bG9hZCkudG9FcXVhbChleHBlY3RlZFBheWxvYWQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY29uc3RydWN0IHBheWxvYWQgZWRnZSBjYXNlcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBudWxsIHdoZW4gZ2l2ZW4gYW4gZW1wdHkgbWFwcGluZ0pzb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIHJldmVudWU6IDEwMCxcbiAgICAgICAgICBjdXJyZW5jeTogJ1VTRCcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYXBwaW5nSnNvbiA9IFtdO1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0gSnNvblV0aWxzLmNvbnN0cnVjdFBheWxvYWQobWVzc2FnZSBhcyBhbnksIG1hcHBpbmdKc29uKTtcbiAgICAgIGV4cGVjdChwYXlsb2FkKS50b0JlTnVsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbnVsbCB3aGVuIGdpdmVuIGFuIGludmFsaWQgc291cmNlS2V5JywgKCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgICAgZXZlbnQ6ICdwdXJjaGFzZScsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICByZXZlbnVlOiAxMDAsXG4gICAgICAgICAgY3VycmVuY3k6ICdVU0QnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc291cmNlS2V5ID0gJ2ludmFsaWRLZXknO1xuXG4gICAgICBjb25zdCB2YWx1ZSA9IEpzb25VdGlscy5nZXRGaWVsZFZhbHVlRnJvbU1lc3NhZ2UobWVzc2FnZSBhcyBhbnksIHNvdXJjZUtleSk7XG4gICAgICBleHBlY3QodmFsdWUpLnRvQmVOdWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSB3aGVuIG1ldGFkYXRhIGlzIGludmFsaWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIHJldmVudWU6IDEwMCxcbiAgICAgICAgICBjdXJyZW5jeTogJ1VTRCcsXG4gICAgICAgICAgcHJvZHVjdHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmFtZTogJ1Byb2R1Y3QgMScsXG4gICAgICAgICAgICAgIHByaWNlOiA1MCxcbiAgICAgICAgICAgICAgcXVhbnRpdHk6IDIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBuYW1lOiAnUHJvZHVjdCAyJyxcbiAgICAgICAgICAgICAgcHJpY2U6IDMwLFxuICAgICAgICAgICAgICBxdWFudGl0eTogMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hcHBpbmdKc29uID0gW1xuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogJ3Byb3BlcnRpZXMucmV2ZW51ZScsXG4gICAgICAgICAgZGVzdEtleTogJ3JldmVudWUnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICB0eXBlOiAnaW52YWxpZFR5cGUnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCB2YWx1ZSA9IEpzb25VdGlscy5jb25zdHJ1Y3RQYXlsb2FkKG1lc3NhZ2UgYXMgYW55LCBtYXBwaW5nSnNvbik7XG5cbiAgICAgIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCh7XG4gICAgICAgIHJldmVudWU6IDEwMCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBJbnN0cnVtZW50YXRpb25FcnJvciB3aGVuIGEgcmVxdWlyZWQgdmFsdWUgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgcmV2ZW51ZTogMTAwLFxuICAgICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgICBwcm9kdWN0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBuYW1lOiAnUHJvZHVjdCAxJyxcbiAgICAgICAgICAgICAgcHJpY2U6IDUwLFxuICAgICAgICAgICAgICBxdWFudGl0eTogMixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG5hbWU6ICdQcm9kdWN0IDInLFxuICAgICAgICAgICAgICBwcmljZTogMzAsXG4gICAgICAgICAgICAgIHF1YW50aXR5OiAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFwcGluZ0pzb24gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiAnZXZlbnQnLFxuICAgICAgICAgIGRlc3RLZXk6ICdldmVudCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogJ3Byb3BlcnRpZXMucmV2ZW51ZScsXG4gICAgICAgICAgZGVzdEtleTogJ3JldmVudWUnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6ICdwcm9wZXJ0aWVzLmN1cnJlbmN5JyxcbiAgICAgICAgICBkZXN0S2V5OiAnY3VycmVuY3knLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6ICdwcm9wZXJ0aWVzLnByb2R1Y3RzJyxcbiAgICAgICAgICBkZXN0S2V5OiAncHJvZHVjdHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHNvdXJjZUtleXM6ICdwcm9wZXJ0aWVzLmludmFsaWRLZXknLFxuICAgICAgICAgIGRlc3RLZXk6ICdpbnZhbGlkS2V5JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBKc29uVXRpbHMuY29uc3RydWN0UGF5bG9hZChtZXNzYWdlIGFzIGFueSwgbWFwcGluZ0pzb24pO1xuICAgICAgfSkudG9UaHJvdyhJbnN0cnVtZW50YXRpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCB0aGUgcGF5bG9hZCBjb3JyZWN0bHkgd2l0aCBhIHZhbGlkIG1hcHBpbmdKc29uIGFuZCBtZXNzYWdlIG9iamVjdCB3aGVuIGRlc3RpbmF0aW9uIGtleSBpcyBhbiBlbXB0eSBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBldmVudDogJ3B1cmNoYXNlJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIHJldmVudWU6IDEwMCxcbiAgICAgICAgICBjdXJyZW5jeTogJ1VTRCcsXG4gICAgICAgICAgcHJvZHVjdHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmFtZTogJ1Byb2R1Y3QgMScsXG4gICAgICAgICAgICAgIHByaWNlOiA1MCxcbiAgICAgICAgICAgICAgcXVhbnRpdHk6IDIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBuYW1lOiAnUHJvZHVjdCAyJyxcbiAgICAgICAgICAgICAgcHJpY2U6IDMwLFxuICAgICAgICAgICAgICBxdWFudGl0eTogMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hcHBpbmdKc29uID0gW1xuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogJ2V2ZW50JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiAncHJvcGVydGllcy5yZXZlbnVlJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBtZXRhZGF0YToge30sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VLZXlzOiAncHJvcGVydGllcy5jdXJyZW5jeScsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgbWV0YWRhdGE6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc291cmNlS2V5czogJ3Byb3BlcnRpZXMucHJvZHVjdHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG1ldGFkYXRhOiB7fSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIC8vIE5vdCBhIGNvcnJlY3QgcGF5bG9hZCBhcyB0aGUgZGVzdGluYXRpb24ga2V5cyBhcmUgZW1wdHkgc3RyaW5ncyBvciBub3QgcHJlc2VudFxuICAgICAgY29uc3QgZXhwZWN0ZWRQYXlsb2FkID0ge1xuICAgICAgICAnJzogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdQcm9kdWN0IDEnLFxuICAgICAgICAgICAgcHJpY2U6IDUwLFxuICAgICAgICAgICAgcXVhbnRpdHk6IDIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAnUHJvZHVjdCAyJyxcbiAgICAgICAgICAgIHByaWNlOiAzMCxcbiAgICAgICAgICAgIHF1YW50aXR5OiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0gSnNvblV0aWxzLmNvbnN0cnVjdFBheWxvYWQobWVzc2FnZSBhcyBhbnksIG1hcHBpbmdKc29uKTtcbiAgICAgIGV4cGVjdChwYXlsb2FkKS50b0VxdWFsKGV4cGVjdGVkUGF5bG9hZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdqc29uIHV0aWwgb3RoZXIgZnVuY3Rpb25zJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0cmlldmUgdGhlIGZpZWxkIHZhbHVlIGNvcnJlY3RseSBmcm9tIHRoZSBtZXNzYWdlIHVzaW5nIGEgdmFsaWQgc291cmNlS2V5JywgKCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgICAgZXZlbnQ6ICdwdXJjaGFzZScsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICByZXZlbnVlOiAxMDAsXG4gICAgICAgICAgY3VycmVuY3k6ICdVU0QnLFxuICAgICAgICB9LFxuICAgICAgICB0cmFpdHM6IHtcbiAgICAgICAgICBmaXJzdE5hbWU6ICdKb2huJyxcbiAgICAgICAgICBsYXN0TmFtZTogJ0RvZScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzb3VyY2VLZXkgPSAnZmlyc3ROYW1lJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWUgPSAnSm9obic7XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gSnNvblV0aWxzLmdldEZpZWxkVmFsdWVGcm9tTWVzc2FnZShtZXNzYWdlIGFzIGFueSwgc291cmNlS2V5KTtcbiAgICAgIGV4cGVjdCh2YWx1ZSkudG9FcXVhbChleHBlY3RlZFZhbHVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIG51bGwgd2hlbiBnaXZlbiBhbiBpbnZhbGlkIHNvdXJjZUtleScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgIGV2ZW50OiAncHVyY2hhc2UnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgcmV2ZW51ZTogMTAwLFxuICAgICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNvdXJjZUtleSA9ICdpbnZhbGlkS2V5JztcblxuICAgICAgY29uc3QgdmFsdWUgPSBKc29uVXRpbHMuZ2V0RmllbGRWYWx1ZUZyb21NZXNzYWdlKG1lc3NhZ2UgYXMgYW55LCBzb3VyY2VLZXkpO1xuICAgICAgZXhwZWN0KHZhbHVlKS50b0JlTnVsbCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19