@rudderstack/integrations-lib 0.2.13 → 0.2.14

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.
@@ -0,0 +1,741 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const axios_1 = __importDefault(require("axios"));
30
+ const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
31
+ const _1 = __importDefault(require("."));
32
+ const utils = __importStar(require("./utils"));
33
+ describe('sfmc', () => {
34
+ describe('getAccessToken', () => {
35
+ it('should return existing authObject when token is not expired', async () => {
36
+ const validAuthObject = {
37
+ clientId: 'test-client',
38
+ clientSecret: 'test-secret',
39
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
40
+ access_token: 'valid-token',
41
+ expiration: process.hrtime()[0] + 3600,
42
+ };
43
+ const sfmcClient = new _1.default(validAuthObject);
44
+ sfmcClient.authObject = validAuthObject;
45
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
46
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
47
+ const result = await sfmcClient.getAccessToken();
48
+ expect(result).toBe(validAuthObject);
49
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
50
+ expect(requestTokenSpy).not.toHaveBeenCalled();
51
+ });
52
+ // Handles case when authObject is initially empty or null
53
+ it('should request new token when authObject is empty', async () => {
54
+ const emptyAuthObject = {
55
+ clientId: 'test-client',
56
+ clientSecret: 'test-secret',
57
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
58
+ };
59
+ const newAuthObject = {
60
+ ...emptyAuthObject,
61
+ access_token: 'new-token',
62
+ expires_in: 12345,
63
+ };
64
+ const sfmcClient = new _1.default(emptyAuthObject);
65
+ sfmcClient.authObject = emptyAuthObject;
66
+ jest.spyOn(utils, 'isExpired').mockReturnValue(true);
67
+ // jest.spyOn(axios, 'getToken').mockResolvedValue(newAuthObject);
68
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
69
+ mockAdapter
70
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.auth.marketingcloudapis.com/v2/token')
71
+ .reply(200, newAuthObject);
72
+ jest.spyOn(process, 'hrtime').mockImplementation(() => [0, 0]);
73
+ const result = await sfmcClient.getAccessToken();
74
+ expect(result).toEqual({ ...newAuthObject, expiration: 12345 });
75
+ expect(utils.isExpired).toHaveBeenCalledWith(emptyAuthObject);
76
+ expect(utils.getToken).toHaveBeenCalledWith(emptyAuthObject);
77
+ });
78
+ it('should throw error when authObject has invalid clientId', () => {
79
+ const invalidAuthObject = {
80
+ clientId: null,
81
+ clientSecret: 'test-secret',
82
+ subDomain: 'test',
83
+ };
84
+ try {
85
+ const sfmcInstance = new _1.default(invalidAuthObject);
86
+ sfmcInstance.getAccessToken();
87
+ }
88
+ catch (e) {
89
+ expect(e).toEqual(new Error('clientId is missing or invalid'));
90
+ }
91
+ });
92
+ it('should handle concurrent token refresh requests correctly', async () => {
93
+ const emptyAuthObject = {
94
+ clientId: 'test-client',
95
+ clientSecret: 'test-secret',
96
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
97
+ };
98
+ const newAuthObject = {
99
+ ...emptyAuthObject,
100
+ access_token: 'new-token',
101
+ expires_in: 12345,
102
+ };
103
+ const sfmcClient = new _1.default(emptyAuthObject);
104
+ sfmcClient.authObject = emptyAuthObject;
105
+ jest.spyOn(utils, 'isExpired').mockReturnValue(true);
106
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
107
+ mockAdapter
108
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.auth.marketingcloudapis.com/v2/token')
109
+ .reply(200, newAuthObject);
110
+ jest.spyOn(process, 'hrtime').mockImplementation(() => [0, 0]);
111
+ let result = await sfmcClient.getAccessToken();
112
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
113
+ result = await sfmcClient.getAccessToken();
114
+ expect(result).toEqual({ ...newAuthObject, expiration: 12345 });
115
+ expect(utils.isExpired).toHaveBeenCalledWith(emptyAuthObject);
116
+ expect(utils.isExpired).toHaveBeenCalledWith(emptyAuthObject);
117
+ });
118
+ it('should throw error with original message when token request fails', async () => {
119
+ const emptyAuthObject = {
120
+ clientId: 'test-client',
121
+ clientSecret: 'test-secret',
122
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
123
+ };
124
+ const sfmcClient = new _1.default(emptyAuthObject);
125
+ sfmcClient.authObject = emptyAuthObject;
126
+ jest.spyOn(utils, 'isExpired').mockReturnValue(true);
127
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
128
+ mockAdapter
129
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.auth.marketingcloudapis.com/v2/token')
130
+ .reply(400, new Error('Bad Request'));
131
+ try {
132
+ await sfmcClient.getAccessToken();
133
+ }
134
+ catch (e) {
135
+ expect(e).toEqual(new Error('Unable to generate token, with error:Error: Request failed with status code 400'));
136
+ }
137
+ });
138
+ });
139
+ describe('getDestinationFields', () => {
140
+ it('should return data extension fields', async () => {
141
+ const validAuthObject = {
142
+ clientId: 'test-client',
143
+ clientSecret: 'test-secret',
144
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
145
+ access_token: 'valid-token',
146
+ expiration: process.hrtime()[0] + 3600,
147
+ };
148
+ const sfmcClient = new _1.default(validAuthObject);
149
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
150
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
151
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
152
+ const validResponse = {
153
+ name: 'Test DE',
154
+ categoryID: '12345',
155
+ fields: [
156
+ {
157
+ name: 'field1',
158
+ type: 'Text',
159
+ },
160
+ ],
161
+ };
162
+ mockAdapter
163
+ .onGet('https://abcdefghijklmnopqrstuvwxyz01.rest.marketingcloudapis.com/data/v1/customobjects/test-de-id/fields')
164
+ .reply(200, validResponse);
165
+ const result = await sfmcClient.getDestinationFields('test-de-id');
166
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
167
+ expect(requestTokenSpy).not.toHaveBeenCalled();
168
+ expect(result).toStrictEqual(validResponse);
169
+ });
170
+ it('should handle failure scenario', async () => {
171
+ const validAuthObject = {
172
+ clientId: 'test-client',
173
+ clientSecret: 'test-secret',
174
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
175
+ access_token: 'valid-token',
176
+ expiration: process.hrtime()[0] + 3600,
177
+ };
178
+ const sfmcClient = new _1.default(validAuthObject);
179
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
180
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
181
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
182
+ mockAdapter
183
+ .onGet('https://abcdefghijklmnopqrstuvwxyz01.rest.marketingcloudapis.com/data/v1/customobjects/test-de-id/fields')
184
+ .reply(401, {
185
+ documentation: 'https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm',
186
+ errorcode: 0,
187
+ message: 'Not Authorized',
188
+ });
189
+ try {
190
+ await sfmcClient.getDestinationFields('test-de-id');
191
+ }
192
+ catch (e) {
193
+ expect(e).toEqual(new Error('Not Authorized'));
194
+ }
195
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
196
+ expect(requestTokenSpy).not.toHaveBeenCalled();
197
+ });
198
+ });
199
+ describe('getContactAttributes', () => {
200
+ it('should return contact attributes', async () => {
201
+ const validAuthObject = {
202
+ clientId: 'test-client',
203
+ clientSecret: 'test-secret',
204
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
205
+ access_token: 'valid-token',
206
+ expiration: process.hrtime()[0] + 3600,
207
+ };
208
+ const sfmcClient = new _1.default(validAuthObject);
209
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
210
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
211
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
212
+ const validResponse = {
213
+ data: {
214
+ items: [
215
+ {
216
+ isReadOnly: true,
217
+ attributes: [
218
+ {
219
+ isReadOnly: true,
220
+ fullyQualifiedName: 'test.name',
221
+ dataType: 'string',
222
+ },
223
+ ],
224
+ },
225
+ ],
226
+ },
227
+ };
228
+ mockAdapter
229
+ .onGet('https://abcdefghijklmnopqrstuvwxyz01.rest.marketingcloudapis.com/contacts/v1/attributeSetDefinitions')
230
+ .reply(200, validResponse);
231
+ const result = await sfmcClient.getContactAttributes();
232
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
233
+ expect(requestTokenSpy).not.toHaveBeenCalled();
234
+ expect(result).toStrictEqual(validResponse);
235
+ });
236
+ it('should handle failure scenario', async () => {
237
+ const validAuthObject = {
238
+ clientId: 'test-client',
239
+ clientSecret: 'test-secret',
240
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
241
+ access_token: 'valid-token',
242
+ expiration: process.hrtime()[0] + 3600,
243
+ };
244
+ const sfmcClient = new _1.default(validAuthObject);
245
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
246
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
247
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
248
+ mockAdapter
249
+ .onGet('https://abcdefghijklmnopqrstuvwxyz01.rest.marketingcloudapis.com/contacts/v1/attributeSetDefinitions')
250
+ .reply(401, {
251
+ documentation: 'https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm',
252
+ errorcode: 0,
253
+ message: 'Not Authorized',
254
+ });
255
+ try {
256
+ await sfmcClient.getContactAttributes();
257
+ }
258
+ catch (e) {
259
+ expect(e).toEqual(new Error('Not Authorized'));
260
+ }
261
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
262
+ expect(requestTokenSpy).not.toHaveBeenCalled();
263
+ });
264
+ });
265
+ describe('createDataExtension', () => {
266
+ it('should create new data extension', async () => {
267
+ const validAuthObject = {
268
+ clientId: 'test-client',
269
+ clientSecret: 'test-secret',
270
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
271
+ access_token: 'valid-token',
272
+ expiration: process.hrtime()[0] + 3600,
273
+ };
274
+ const sfmcClient = new _1.default(validAuthObject);
275
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
276
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
277
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
278
+ const validResponse = {
279
+ id: '4baf4cf1-8cc9-ef11-ba6e-f40343d380c8',
280
+ name: 'rudderstackTesting0295',
281
+ key: 'rudderstackTesting0295',
282
+ isActive: true,
283
+ isSendable: false,
284
+ isTestable: false,
285
+ status: 0,
286
+ categoryId: 12345,
287
+ ownerId: 735444531,
288
+ isObjectDeletable: true,
289
+ isFieldAdditionAllowed: true,
290
+ isFieldModificationAllowed: true,
291
+ createdDate: '2025-01-02T22:41:12.5018415-06:00',
292
+ createdById: 735444531,
293
+ modifiedDate: '2025-01-02T22:41:12.5018415-06:00',
294
+ modifiedById: 735444531,
295
+ ownerName: 'RudderstackIntegration app user',
296
+ rowCount: 0,
297
+ dataRetentionProperties: {
298
+ isDeleteAtEndOfRetentionPeriod: true,
299
+ isRowBasedRetention: false,
300
+ isResetRetentionPeriodOnImport: false,
301
+ rowBasedThreshold: 1000000000,
302
+ },
303
+ fields: [
304
+ {
305
+ name: 'key1',
306
+ id: '300ba233-b7e0-4732-ba85-1bc01208fc1b',
307
+ type: 'Text',
308
+ maskType: 'None',
309
+ storageType: 'Plain',
310
+ length: 254,
311
+ ordinal: 0,
312
+ isNullable: false,
313
+ isPrimaryKey: true,
314
+ isTemplateField: false,
315
+ isInheritable: false,
316
+ isOverridable: true,
317
+ isHidden: false,
318
+ isReadOnly: false,
319
+ mustOverride: false,
320
+ },
321
+ {
322
+ name: 'key2',
323
+ id: '75a38f98-e865-43ce-9702-5b317ba29d92',
324
+ type: 'EmailAddress',
325
+ maskType: 'None',
326
+ storageType: 'Plain',
327
+ length: 254,
328
+ ordinal: 0,
329
+ isNullable: true,
330
+ isPrimaryKey: false,
331
+ isTemplateField: false,
332
+ isInheritable: false,
333
+ isOverridable: true,
334
+ isHidden: false,
335
+ isReadOnly: false,
336
+ mustOverride: false,
337
+ },
338
+ ],
339
+ fieldCount: 2,
340
+ };
341
+ mockAdapter
342
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.rest.marketingcloudapis.com/data/v1/customobjects')
343
+ .reply(200, validResponse);
344
+ const result = await sfmcClient.createDataExtension({
345
+ name: 'test-de',
346
+ categoryID: '12345',
347
+ dataRetentionProperties: {
348
+ isDeleteAtEndOfRetentionPeriod: true,
349
+ isRowBasedRetention: false,
350
+ isResetRetentionPeriodOnImport: false,
351
+ },
352
+ fields: [
353
+ {
354
+ name: 'key1',
355
+ type: 'Text',
356
+ length: 254,
357
+ isNullable: false,
358
+ isPrimaryKey: true,
359
+ isHidden: false,
360
+ isReadOnly: false,
361
+ isOverridable: true,
362
+ isTemplateField: false,
363
+ isInheritable: false,
364
+ mustOverride: false,
365
+ ordinal: 0,
366
+ },
367
+ {
368
+ name: 'key2',
369
+ type: 'EmailAddress',
370
+ length: 254,
371
+ isNullable: true,
372
+ isPrimaryKey: false,
373
+ isHidden: false,
374
+ isReadOnly: false,
375
+ isOverridable: true,
376
+ isTemplateField: false,
377
+ isInheritable: false,
378
+ mustOverride: false,
379
+ ordinal: 0,
380
+ },
381
+ ],
382
+ });
383
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
384
+ expect(requestTokenSpy).not.toHaveBeenCalled();
385
+ expect(result).toStrictEqual(validResponse);
386
+ });
387
+ it('should handle failure scenario', async () => {
388
+ const validAuthObject = {
389
+ clientId: 'test-client',
390
+ clientSecret: 'test-secret',
391
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
392
+ access_token: 'valid-token',
393
+ expiration: process.hrtime()[0] + 3600,
394
+ };
395
+ const sfmcClient = new _1.default(validAuthObject);
396
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
397
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
398
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
399
+ mockAdapter
400
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.rest.marketingcloudapis.com/data/v1/customobjects')
401
+ .reply(401, {
402
+ documentation: 'https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm',
403
+ errorcode: 0,
404
+ message: 'Not Authorized',
405
+ });
406
+ try {
407
+ await sfmcClient.createDataExtension({
408
+ name: 'test-de',
409
+ categoryID: '12345',
410
+ fields: [
411
+ {
412
+ name: 'key1',
413
+ type: 'Text',
414
+ length: 254,
415
+ isNullable: false,
416
+ isPrimaryKey: true,
417
+ isHidden: false,
418
+ isReadOnly: false,
419
+ isOverridable: true,
420
+ isTemplateField: false,
421
+ isInheritable: false,
422
+ mustOverride: false,
423
+ ordinal: 0,
424
+ },
425
+ ],
426
+ });
427
+ }
428
+ catch (e) {
429
+ expect(e).toEqual(new Error('Not Authorized'));
430
+ }
431
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
432
+ expect(requestTokenSpy).not.toHaveBeenCalled();
433
+ });
434
+ });
435
+ describe('getBusinessUnits', () => {
436
+ it('should get all the business units', async () => {
437
+ const validAuthObject = {
438
+ clientId: 'test-client',
439
+ clientSecret: 'test-secret',
440
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
441
+ access_token: 'valid-token',
442
+ expiration: process.hrtime()[0] + 3600,
443
+ };
444
+ const sfmcClient = new _1.default(validAuthObject);
445
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
446
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
447
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
448
+ const validResponse = `<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><soap:Header><wsa:Action>RetrieveResponse</wsa:Action><wsa:MessageID>urn:uuid:0bed602b-63c4-4bb4-9582-2b27c8f2b1da</wsa:MessageID><wsa:RelatesTo>urn:uuid:45dcc251-a037-4172-99ce-666a6b3b872c</wsa:RelatesTo><wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To><wsse:Security><wsu:Timestamp wsu:Id="Timestamp-d0308ae2-4adf-4578-8d85-faa720a966ce"><wsu:Created>2025-01-09T05:50:10Z</wsu:Created><wsu:Expires>2025-01-09T05:55:10Z</wsu:Expires></wsu:Timestamp></wsse:Security></soap:Header><soap:Body><RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"><OverallStatus>OK</OverallStatus><RequestID>ab947caa-34bd-4e5b-84c1-54ab1e633a6f</RequestID><Results xsi:type="BusinessUnit"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>id</Name><Value>534003210</Value></PartnerProperties><PartnerProperties><Name>name</Name><Value>Lansdowne Stadium LP</Value></PartnerProperties><ObjectID xsi:nil="true" /><AccountType>None</AccountType><Subscription xsi:nil="true" /></Results><Results xsi:type="BusinessUnit"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>id</Name><Value>534003210</Value></PartnerProperties><PartnerProperties><Name>name</Name><Value>Lansdowne Stadium LP</Value></PartnerProperties><ObjectID xsi:nil="true" /><AccountType>None</AccountType><Subscription xsi:nil="true" /></Results></RetrieveResponseMsg></soap:Body></soap:Envelope>`;
449
+ mockAdapter
450
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.soap.marketingcloudapis.com/Service.asmx')
451
+ .reply(200, validResponse);
452
+ const result = await sfmcClient.getBusinessUnits();
453
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
454
+ expect(requestTokenSpy).not.toHaveBeenCalled();
455
+ expect(result).toStrictEqual([
456
+ { ID: 'Lansdowne Stadium LP', Name: 534003210 },
457
+ { ID: 'Lansdowne Stadium LP', Name: 534003210 },
458
+ ]);
459
+ });
460
+ it('should handle failure scenario', async () => {
461
+ const validAuthObject = {
462
+ clientId: 'test-client',
463
+ clientSecret: 'test-secret',
464
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
465
+ access_token: 'valid-token',
466
+ expiration: process.hrtime()[0] + 3600,
467
+ };
468
+ const sfmcClient = new _1.default(validAuthObject);
469
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
470
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
471
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
472
+ mockAdapter
473
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.soap.marketingcloudapis.com/Service.asmx')
474
+ .reply(500, `<?xml version="1.0" encoding="utf-8"?>
475
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
476
+ <soap:Header>
477
+ <wsa:Action>http://schemas.xmlsoap.org/ws/2004/08/addressing/fault</wsa:Action>
478
+ <wsa:MessageID>urn:uuid:15d3e286-97f5-4f5c-b0fa-d58673621568</wsa:MessageID>
479
+ <wsa:RelatesTo>urn:uuid:b38ee85b-8f6b-4edc-9ab9-23ab6e5a51e3</wsa:RelatesTo>
480
+ <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
481
+ <wsse:Security>
482
+ <wsu:Timestamp wsu:Id="Timestamp-dc02f8e8-af74-4799-b5e9-9e9c0299278f">
483
+ <wsu:Created>2025-01-03T04:59:45Z</wsu:Created>
484
+ <wsu:Expires>2025-01-03T05:04:45Z</wsu:Expires>
485
+ </wsu:Timestamp>
486
+ </wsse:Security>
487
+ </soap:Header>
488
+ <soap:Body>
489
+ <soap:Fault>
490
+ <faultcode xmlns:q0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">q0:Security</faultcode>
491
+ <faultstring>Login Failed</faultstring>
492
+ <faultactor>https://mcvgkqz3c1chrbsz586k90s41hp8.soap.marketingcloudapis.com/Service.asmx</faultactor>
493
+ </soap:Fault>
494
+ </soap:Body>
495
+ </soap:Envelope>`);
496
+ try {
497
+ await sfmcClient.getBusinessUnits();
498
+ }
499
+ catch (e) {
500
+ expect(e).toEqual(new Error('Request failed with status code 500'));
501
+ }
502
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
503
+ expect(requestTokenSpy).not.toHaveBeenCalled();
504
+ });
505
+ });
506
+ describe('getDataFolders', () => {
507
+ it('should get all the data folders', async () => {
508
+ const validAuthObject = {
509
+ clientId: 'test-client',
510
+ clientSecret: 'test-secret',
511
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
512
+ access_token: 'valid-token',
513
+ expiration: process.hrtime()[0] + 3600,
514
+ };
515
+ const sfmcClient = new _1.default(validAuthObject);
516
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
517
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
518
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
519
+ const validResponse = `<?xml version="1.0" encoding="utf-8"?>
520
+ <soap:Envelope
521
+ xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
522
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
523
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
524
+ xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
525
+ xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
526
+ xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
527
+ <soap:Header>
528
+ <wsa:Action>RetrieveResponse</wsa:Action>
529
+ <wsa:MessageID>urn:uuid:1cf4fd72-93a9-4360-a75c-988dc708eb7c</wsa:MessageID>
530
+ <wsa:RelatesTo>urn:uuid:527a13a5-a798-4438-b23d-b7fd084ac953</wsa:RelatesTo>
531
+ <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
532
+ <wsse:Security>
533
+ <wsu:Timestamp wsu:Id="Timestamp-9d7c5707-e8ec-4db8-b55e-7cbd2ce22fa3">
534
+ <wsu:Created>2025-01-03T05:54:16Z</wsu:Created>
535
+ <wsu:Expires>2025-01-03T05:59:16Z</wsu:Expires>
536
+ </wsu:Timestamp>
537
+ </wsse:Security>
538
+ </soap:Header>
539
+ <soap:Body>
540
+ <RetrieveResponseMsg
541
+ xmlns="http://exacttarget.com/wsdl/partnerAPI">
542
+ <OverallStatus>OK</OverallStatus>
543
+ <RequestID>5d91708b-25d1-4b27-80a0-dc84ef0aac0c</RequestID>
544
+ <Results xsi:type="DataFolder">
545
+ <Client>
546
+ <ID>534003210</ID>
547
+ </Client>
548
+ <PartnerKey xsi:nil="true" />
549
+ <ID>11546</ID>
550
+ <ObjectID>4f591ca1-8236-47b8-92fe-cf0dcf7cffb5</ObjectID>
551
+ <Name>my emails</Name>
552
+ <Description />
553
+ <ContentType>email</ContentType>
554
+ </Results>
555
+ <Results xsi:type="DataFolder">
556
+ <Client>
557
+ <ID>534003210</ID>
558
+ </Client>
559
+ <PartnerKey xsi:nil="true" />
560
+ <ID>11547</ID>
561
+ <ObjectID>695dd7c6-d764-479d-9e77-36d141cdd342</ObjectID>
562
+ <Name>simple automated emails</Name>
563
+ <Description />
564
+ <ContentType>automated_email</ContentType>
565
+ </Results>
566
+ </RetrieveResponseMsg>
567
+ </soap:Body>
568
+ </soap:Envelope>`;
569
+ mockAdapter
570
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.soap.marketingcloudapis.com/Service.asmx')
571
+ .reply(200, validResponse);
572
+ const result = await sfmcClient.getDataFolders();
573
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
574
+ expect(requestTokenSpy).not.toHaveBeenCalled();
575
+ expect(result).toStrictEqual([
576
+ {
577
+ Client: {
578
+ ID: 534003210,
579
+ },
580
+ ContentType: 'email',
581
+ Description: '',
582
+ ID: 11546,
583
+ Name: 'my emails',
584
+ ObjectID: '4f591ca1-8236-47b8-92fe-cf0dcf7cffb5',
585
+ PartnerKey: '',
586
+ },
587
+ {
588
+ Client: {
589
+ ID: 534003210,
590
+ },
591
+ ContentType: 'automated_email',
592
+ Description: '',
593
+ ID: 11547,
594
+ Name: 'simple automated emails',
595
+ ObjectID: '695dd7c6-d764-479d-9e77-36d141cdd342',
596
+ PartnerKey: '',
597
+ },
598
+ ]);
599
+ });
600
+ it('should handle failure scenario', async () => {
601
+ const validAuthObject = {
602
+ clientId: 'test-client',
603
+ clientSecret: 'test-secret',
604
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
605
+ access_token: 'valid-token',
606
+ expiration: process.hrtime()[0] + 3600,
607
+ };
608
+ const sfmcClient = new _1.default(validAuthObject);
609
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
610
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
611
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
612
+ mockAdapter
613
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.soap.marketingcloudapis.com/Service.asmx')
614
+ .reply(500, `<?xml version="1.0" encoding="utf-8"?>
615
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
616
+ <soap:Header>
617
+ <wsa:Action>http://schemas.xmlsoap.org/ws/2004/08/addressing/fault</wsa:Action>
618
+ <wsa:MessageID>urn:uuid:15d3e286-97f5-4f5c-b0fa-d58673621568</wsa:MessageID>
619
+ <wsa:RelatesTo>urn:uuid:b38ee85b-8f6b-4edc-9ab9-23ab6e5a51e3</wsa:RelatesTo>
620
+ <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
621
+ <wsse:Security>
622
+ <wsu:Timestamp wsu:Id="Timestamp-dc02f8e8-af74-4799-b5e9-9e9c0299278f">
623
+ <wsu:Created>2025-01-03T04:59:45Z</wsu:Created>
624
+ <wsu:Expires>2025-01-03T05:04:45Z</wsu:Expires>
625
+ </wsu:Timestamp>
626
+ </wsse:Security>
627
+ </soap:Header>
628
+ <soap:Body>
629
+ <soap:Fault>
630
+ <faultcode xmlns:q0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">q0:Security</faultcode>
631
+ <faultstring>Login Failed</faultstring>
632
+ <faultactor>https://mcvgkqz3c1chrbsz586k90s41hp8.soap.marketingcloudapis.com/Service.asmx</faultactor>
633
+ </soap:Fault>
634
+ </soap:Body>
635
+ </soap:Envelope>`);
636
+ try {
637
+ await sfmcClient.getDataFolders();
638
+ }
639
+ catch (e) {
640
+ expect(e).toEqual(new Error('Request failed with status code 500'));
641
+ }
642
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
643
+ expect(requestTokenSpy).not.toHaveBeenCalled();
644
+ });
645
+ });
646
+ describe('getDataExtensions', () => {
647
+ it('should get all the data extensions', async () => {
648
+ const validAuthObject = {
649
+ clientId: 'test-client',
650
+ clientSecret: 'test-secret',
651
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
652
+ access_token: 'valid-token',
653
+ expiration: process.hrtime()[0] + 3600,
654
+ };
655
+ const sfmcClient = new _1.default(validAuthObject);
656
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
657
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
658
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
659
+ const validResponse = `<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><soap:Header><wsa:Action>RetrieveResponse</wsa:Action><wsa:MessageID>urn:uuid:0214d595-39f2-42bb-b18f-782e3aec9125</wsa:MessageID><wsa:RelatesTo>urn:uuid:8c9f1fe6-584a-492f-ad1e-b62887e6b27d</wsa:RelatesTo><wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To><wsse:Security><wsu:Timestamp wsu:Id="Timestamp-749c5b90-7c3e-405e-a891-4cab9aa319d5"><wsu:Created>2025-01-09T10:01:15Z</wsu:Created><wsu:Expires>2025-01-09T10:06:15Z</wsu:Expires></wsu:Timestamp></wsse:Security></soap:Header><soap:Body><RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"><OverallStatus>OK</OverallStatus><RequestID>26123846-4046-430b-89dc-9e5c2eb587fd</RequestID><Results xsi:type="DataExtension"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>ObjectId</Name><Value>b30e26db-5e59-ef11-ba6d-f40343ce89d8</Value></PartnerProperties><PartnerProperties><Name>NAME</Name><Value>rudderstackTesting13342</Value></PartnerProperties><PartnerProperties><Name>CategoryId</Name><Value>12345</Value></PartnerProperties><ObjectID xsi:nil="true" /></Results><Results xsi:type="DataExtension"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>ObjectId</Name><Value>191c5b2a-57b8-ef11-ba6e-f40343d380c8</Value></PartnerProperties><PartnerProperties><Name>NAME</Name><Value>TestFromSDK1234</Value></PartnerProperties><PartnerProperties><Name>CategoryId</Name><Value>12345</Value></PartnerProperties><ObjectID xsi:nil="true" /></Results><Results xsi:type="DataExtension"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>ObjectId</Name><Value>503856e3-5ab8-ef11-ba6e-f40343d380c8</Value></PartnerProperties><PartnerProperties><Name>NAME</Name><Value>rudderstackTesting121120</Value></PartnerProperties><PartnerProperties><Name>CategoryId</Name><Value>12345</Value></PartnerProperties><ObjectID xsi:nil="true" /></Results><Results xsi:type="DataExtension"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>ObjectId</Name><Value>1742f6f1-79b8-ef11-ba6e-f40343d380c8</Value></PartnerProperties><PartnerProperties><Name>NAME</Name><Value>rudderstackTesting12442</Value></PartnerProperties><PartnerProperties><Name>CategoryId</Name><Value>12345</Value></PartnerProperties><ObjectID xsi:nil="true" /></Results><Results xsi:type="DataExtension"><PartnerKey xsi:nil="true" /><PartnerProperties><Name>ObjectId</Name><Value>4baf4cf1-8cc9-ef11-ba6e-f40343d380c8</Value></PartnerProperties><PartnerProperties><Name>NAME</Name><Value>rudderstackTesting0295</Value></PartnerProperties><PartnerProperties><Name>CategoryId</Name><Value>12345</Value></PartnerProperties><ObjectID xsi:nil="true" /></Results></RetrieveResponseMsg></soap:Body></soap:Envelope>`;
660
+ mockAdapter
661
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.soap.marketingcloudapis.com/Service.asmx')
662
+ .reply(200, validResponse);
663
+ const result = await sfmcClient.getDataExtensions('valid-folder-id');
664
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
665
+ expect(requestTokenSpy).not.toHaveBeenCalled();
666
+ expect(result).toStrictEqual([
667
+ {
668
+ CategoryId: 12345,
669
+ Name: 'rudderstackTesting13342',
670
+ ObjectId: 'b30e26db-5e59-ef11-ba6d-f40343ce89d8',
671
+ },
672
+ {
673
+ CategoryId: 12345,
674
+ Name: 'TestFromSDK1234',
675
+ ObjectId: '191c5b2a-57b8-ef11-ba6e-f40343d380c8',
676
+ },
677
+ {
678
+ CategoryId: 12345,
679
+ Name: 'rudderstackTesting121120',
680
+ ObjectId: '503856e3-5ab8-ef11-ba6e-f40343d380c8',
681
+ },
682
+ {
683
+ CategoryId: 12345,
684
+ Name: 'rudderstackTesting12442',
685
+ ObjectId: '1742f6f1-79b8-ef11-ba6e-f40343d380c8',
686
+ },
687
+ {
688
+ CategoryId: 12345,
689
+ Name: 'rudderstackTesting0295',
690
+ ObjectId: '4baf4cf1-8cc9-ef11-ba6e-f40343d380c8',
691
+ },
692
+ ]);
693
+ });
694
+ it('should handle failure scenario', async () => {
695
+ const validAuthObject = {
696
+ clientId: 'test-client',
697
+ clientSecret: 'test-secret',
698
+ subDomain: 'abcdefghijklmnopqrstuvwxyz01',
699
+ access_token: 'valid-token',
700
+ expiration: process.hrtime()[0] + 3600,
701
+ };
702
+ const sfmcClient = new _1.default(validAuthObject);
703
+ jest.spyOn(utils, 'isExpired').mockReturnValue(false);
704
+ const requestTokenSpy = jest.spyOn(utils, 'getToken');
705
+ const mockAdapter = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
706
+ mockAdapter
707
+ .onPost('https://abcdefghijklmnopqrstuvwxyz01.soap.marketingcloudapis.com/Service.asmx')
708
+ .reply(500, `<?xml version="1.0" encoding="utf-8"?>
709
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
710
+ <soap:Header>
711
+ <wsa:Action>http://schemas.xmlsoap.org/ws/2004/08/addressing/fault</wsa:Action>
712
+ <wsa:MessageID>urn:uuid:15d3e286-97f5-4f5c-b0fa-d58673621568</wsa:MessageID>
713
+ <wsa:RelatesTo>urn:uuid:b38ee85b-8f6b-4edc-9ab9-23ab6e5a51e3</wsa:RelatesTo>
714
+ <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
715
+ <wsse:Security>
716
+ <wsu:Timestamp wsu:Id="Timestamp-dc02f8e8-af74-4799-b5e9-9e9c0299278f">
717
+ <wsu:Created>2025-01-03T04:59:45Z</wsu:Created>
718
+ <wsu:Expires>2025-01-03T05:04:45Z</wsu:Expires>
719
+ </wsu:Timestamp>
720
+ </wsse:Security>
721
+ </soap:Header>
722
+ <soap:Body>
723
+ <soap:Fault>
724
+ <faultcode xmlns:q0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">q0:Security</faultcode>
725
+ <faultstring>Login Failed</faultstring>
726
+ <faultactor>https://mcvgkqz3c1chrbsz586k90s41hp8.soap.marketingcloudapis.com/Service.asmx</faultactor>
727
+ </soap:Fault>
728
+ </soap:Body>
729
+ </soap:Envelope>`);
730
+ try {
731
+ await sfmcClient.getDataExtensions();
732
+ }
733
+ catch (e) {
734
+ expect(e).toEqual(new Error('Request failed with status code 500'));
735
+ }
736
+ expect(utils.isExpired).toHaveBeenCalledWith(validAuthObject);
737
+ expect(requestTokenSpy).not.toHaveBeenCalled();
738
+ });
739
+ });
740
+ });
741
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZGtzL3NmbWMvaW5kZXgudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLDRFQUFrRDtBQUNsRCx5Q0FBcUI7QUFDckIsK0NBQWlDO0FBRWpDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO0lBQ3BCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLEVBQUU7UUFDOUIsRUFBRSxDQUFDLDZEQUE2RCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzNFLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO1lBRXhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN0RCxNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUVqRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDOUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBQ0gsMERBQTBEO1FBQzFELEVBQUUsQ0FBQyxtREFBbUQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNqRSxNQUFNLGVBQWUsR0FBRztnQkFDdEIsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLFlBQVksRUFBRSxhQUFhO2dCQUMzQixTQUFTLEVBQUUsOEJBQThCO2FBQzFDLENBQUM7WUFFRixNQUFNLGFBQWEsR0FBRztnQkFDcEIsR0FBRyxlQUFlO2dCQUNsQixZQUFZLEVBQUUsV0FBVztnQkFDekIsVUFBVSxFQUFFLEtBQUs7YUFDbEIsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO1lBRXhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyRCxrRUFBa0U7WUFDbEUsTUFBTSxXQUFXLEdBQUcsSUFBSSw0QkFBZ0IsQ0FBQyxlQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLFdBQVc7aUJBQ1IsTUFBTSxDQUFDLDJFQUEyRSxDQUFDO2lCQUNuRixLQUFLLENBQUMsR0FBRyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDakQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsYUFBYSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDOUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUNILEVBQUUsQ0FBQyx5REFBeUQsRUFBRSxHQUFHLEVBQUU7WUFDakUsTUFBTSxpQkFBaUIsR0FBRztnQkFDeEIsUUFBUSxFQUFFLElBQUk7Z0JBQ2QsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSxNQUFNO2FBQ2xCLENBQUM7WUFDRixJQUFJO2dCQUNGLE1BQU0sWUFBWSxHQUFHLElBQUksVUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0JBQ2pELFlBQVksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUMvQjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDO2FBQ2hFO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxFQUFFLENBQUMsMkRBQTJELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDekUsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixZQUFZLEVBQUUsYUFBYTtnQkFDM0IsU0FBUyxFQUFFLDhCQUE4QjthQUMxQyxDQUFDO1lBRUYsTUFBTSxhQUFhLEdBQUc7Z0JBQ3BCLEdBQUcsZUFBZTtnQkFDbEIsWUFBWSxFQUFFLFdBQVc7Z0JBQ3pCLFVBQVUsRUFBRSxLQUFLO2FBQ2xCLENBQUM7WUFFRixNQUFNLFVBQVUsR0FBRyxJQUFJLFVBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM3QyxVQUFVLENBQUMsVUFBVSxHQUFHLGVBQWUsQ0FBQztZQUV4QyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckQsTUFBTSxXQUFXLEdBQUcsSUFBSSw0QkFBZ0IsQ0FBQyxlQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLFdBQVc7aUJBQ1IsTUFBTSxDQUFDLDJFQUEyRSxDQUFDO2lCQUNuRixLQUFLLENBQUMsR0FBRyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0QsSUFBSSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMzQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxhQUFhLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDaEUsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO1FBQ0gsRUFBRSxDQUFDLG1FQUFtRSxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2pGLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7YUFDMUMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO1lBRXhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyRCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsV0FBVztpQkFDUixNQUFNLENBQUMsMkVBQTJFLENBQUM7aUJBQ25GLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUN4QyxJQUFJO2dCQUNGLE1BQU0sVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ25DO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDZixJQUFJLEtBQUssQ0FDUCxpRkFBaUYsQ0FDbEYsQ0FDRixDQUFDO2FBQ0g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxFQUFFLENBQUMscUNBQXFDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbkQsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixZQUFZLEVBQUUsYUFBYTtnQkFDM0IsU0FBUyxFQUFFLDhCQUE4QjtnQkFDekMsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSTthQUN2QyxDQUFDO1lBRUYsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXRELE1BQU0sV0FBVyxHQUFHLElBQUksNEJBQWdCLENBQUMsZUFBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQztZQUNqRixNQUFNLGFBQWEsR0FBRztnQkFDcEIsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsVUFBVSxFQUFFLE9BQU87Z0JBQ25CLE1BQU0sRUFBRTtvQkFDTjt3QkFDRSxJQUFJLEVBQUUsUUFBUTt3QkFDZCxJQUFJLEVBQUUsTUFBTTtxQkFDYjtpQkFDRjthQUNGLENBQUM7WUFDRixXQUFXO2lCQUNSLEtBQUssQ0FDSiwwR0FBMEcsQ0FDM0c7aUJBQ0EsS0FBSyxDQUFDLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUM3QixNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNuRSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlDLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRTdDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsV0FBVztpQkFDUixLQUFLLENBQ0osMEdBQTBHLENBQzNHO2lCQUNBLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsYUFBYSxFQUNYLDJGQUEyRjtnQkFDN0YsU0FBUyxFQUFFLENBQUM7Z0JBQ1osT0FBTyxFQUFFLGdCQUFnQjthQUMxQixDQUFDLENBQUM7WUFDTCxJQUFJO2dCQUNGLE1BQU0sVUFBVSxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQ3JEO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7YUFDaEQ7WUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxFQUFFLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDaEQsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixZQUFZLEVBQUUsYUFBYTtnQkFDM0IsU0FBUyxFQUFFLDhCQUE4QjtnQkFDekMsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSTthQUN2QyxDQUFDO1lBRUYsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXRELE1BQU0sV0FBVyxHQUFHLElBQUksNEJBQWdCLENBQUMsZUFBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQztZQUNqRixNQUFNLGFBQWEsR0FBRztnQkFDcEIsSUFBSSxFQUFFO29CQUNKLEtBQUssRUFBRTt3QkFDTDs0QkFDRSxVQUFVLEVBQUUsSUFBSTs0QkFDaEIsVUFBVSxFQUFFO2dDQUNWO29DQUNFLFVBQVUsRUFBRSxJQUFJO29DQUNoQixrQkFBa0IsRUFBRSxXQUFXO29DQUMvQixRQUFRLEVBQUUsUUFBUTtpQ0FDbkI7NkJBQ0Y7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDO1lBQ0YsV0FBVztpQkFDUixLQUFLLENBQ0osc0dBQXNHLENBQ3ZHO2lCQUNBLEtBQUssQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUN2RCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlDLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRTdDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsV0FBVztpQkFDUixLQUFLLENBQ0osc0dBQXNHLENBQ3ZHO2lCQUNBLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsYUFBYSxFQUNYLDJGQUEyRjtnQkFDN0YsU0FBUyxFQUFFLENBQUM7Z0JBQ1osT0FBTyxFQUFFLGdCQUFnQjthQUMxQixDQUFDLENBQUM7WUFDTCxJQUFJO2dCQUNGLE1BQU0sVUFBVSxDQUFDLG9CQUFvQixFQUFFLENBQUM7YUFDekM7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQzthQUNoRDtZQUNELE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDOUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDSCxRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO1FBQ25DLEVBQUUsQ0FBQyxrQ0FBa0MsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNoRCxNQUFNLGVBQWUsR0FBRztnQkFDdEIsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLFlBQVksRUFBRSxhQUFhO2dCQUMzQixTQUFTLEVBQUUsOEJBQThCO2dCQUN6QyxZQUFZLEVBQUUsYUFBYTtnQkFDM0IsVUFBVSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJO2FBQ3ZDLENBQUM7WUFFRixNQUFNLFVBQVUsR0FBRyxJQUFJLFVBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUU3QyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFFdEQsTUFBTSxXQUFXLEdBQUcsSUFBSSw0QkFBZ0IsQ0FBQyxlQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLE1BQU0sYUFBYSxHQUFHO2dCQUNwQixFQUFFLEVBQUUsc0NBQXNDO2dCQUMxQyxJQUFJLEVBQUUsd0JBQXdCO2dCQUM5QixHQUFHLEVBQUUsd0JBQXdCO2dCQUM3QixRQUFRLEVBQUUsSUFBSTtnQkFDZCxVQUFVLEVBQUUsS0FBSztnQkFDakIsVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLE1BQU0sRUFBRSxDQUFDO2dCQUNULFVBQVUsRUFBRSxLQUFLO2dCQUNqQixPQUFPLEVBQUUsU0FBUztnQkFDbEIsaUJBQWlCLEVBQUUsSUFBSTtnQkFDdkIsc0JBQXNCLEVBQUUsSUFBSTtnQkFDNUIsMEJBQTBCLEVBQUUsSUFBSTtnQkFDaEMsV0FBVyxFQUFFLG1DQUFtQztnQkFDaEQsV0FBVyxFQUFFLFNBQVM7Z0JBQ3RCLFlBQVksRUFBRSxtQ0FBbUM7Z0JBQ2pELFlBQVksRUFBRSxTQUFTO2dCQUN2QixTQUFTLEVBQUUsaUNBQWlDO2dCQUM1QyxRQUFRLEVBQUUsQ0FBQztnQkFDWCx1QkFBdUIsRUFBRTtvQkFDdkIsOEJBQThCLEVBQUUsSUFBSTtvQkFDcEMsbUJBQW1CLEVBQUUsS0FBSztvQkFDMUIsOEJBQThCLEVBQUUsS0FBSztvQkFDckMsaUJBQWlCLEVBQUUsVUFBVTtpQkFDOUI7Z0JBQ0QsTUFBTSxFQUFFO29CQUNOO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLEVBQUUsRUFBRSxzQ0FBc0M7d0JBQzFDLElBQUksRUFBRSxNQUFNO3dCQUNaLFFBQVEsRUFBRSxNQUFNO3dCQUNoQixXQUFXLEVBQUUsT0FBTzt3QkFDcEIsTUFBTSxFQUFFLEdBQUc7d0JBQ1gsT0FBTyxFQUFFLENBQUM7d0JBQ1YsVUFBVSxFQUFFLEtBQUs7d0JBQ2pCLFlBQVksRUFBRSxJQUFJO3dCQUNsQixlQUFlLEVBQUUsS0FBSzt3QkFDdEIsYUFBYSxFQUFFLEtBQUs7d0JBQ3BCLGFBQWEsRUFBRSxJQUFJO3dCQUNuQixRQUFRLEVBQUUsS0FBSzt3QkFDZixVQUFVLEVBQUUsS0FBSzt3QkFDakIsWUFBWSxFQUFFLEtBQUs7cUJBQ3BCO29CQUNEO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLEVBQUUsRUFBRSxzQ0FBc0M7d0JBQzFDLElBQUksRUFBRSxjQUFjO3dCQUNwQixRQUFRLEVBQUUsTUFBTTt3QkFDaEIsV0FBVyxFQUFFLE9BQU87d0JBQ3BCLE1BQU0sRUFBRSxHQUFHO3dCQUNYLE9BQU8sRUFBRSxDQUFDO3dCQUNWLFVBQVUsRUFBRSxJQUFJO3dCQUNoQixZQUFZLEVBQUUsS0FBSzt3QkFDbkIsZUFBZSxFQUFFLEtBQUs7d0JBQ3RCLGFBQWEsRUFBRSxLQUFLO3dCQUNwQixhQUFhLEVBQUUsSUFBSTt3QkFDbkIsUUFBUSxFQUFFLEtBQUs7d0JBQ2YsVUFBVSxFQUFFLEtBQUs7d0JBQ2pCLFlBQVksRUFBRSxLQUFLO3FCQUNwQjtpQkFDRjtnQkFDRCxVQUFVLEVBQUUsQ0FBQzthQUNkLENBQUM7WUFDRixXQUFXO2lCQUNSLE1BQU0sQ0FDTCx3RkFBd0YsQ0FDekY7aUJBQ0EsS0FBSyxDQUFDLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUM3QixNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQztnQkFDbEQsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsVUFBVSxFQUFFLE9BQU87Z0JBQ25CLHVCQUF1QixFQUFFO29CQUN2Qiw4QkFBOEIsRUFBRSxJQUFJO29CQUNwQyxtQkFBbUIsRUFBRSxLQUFLO29CQUMxQiw4QkFBOEIsRUFBRSxLQUFLO2lCQUN0QztnQkFDRCxNQUFNLEVBQUU7b0JBQ047d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLE1BQU07d0JBQ1osTUFBTSxFQUFFLEdBQUc7d0JBQ1gsVUFBVSxFQUFFLEtBQUs7d0JBQ2pCLFlBQVksRUFBRSxJQUFJO3dCQUNsQixRQUFRLEVBQUUsS0FBSzt3QkFDZixVQUFVLEVBQUUsS0FBSzt3QkFDakIsYUFBYSxFQUFFLElBQUk7d0JBQ25CLGVBQWUsRUFBRSxLQUFLO3dCQUN0QixhQUFhLEVBQUUsS0FBSzt3QkFDcEIsWUFBWSxFQUFFLEtBQUs7d0JBQ25CLE9BQU8sRUFBRSxDQUFDO3FCQUNYO29CQUNEO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxjQUFjO3dCQUNwQixNQUFNLEVBQUUsR0FBRzt3QkFDWCxVQUFVLEVBQUUsSUFBSTt3QkFDaEIsWUFBWSxFQUFFLEtBQUs7d0JBQ25CLFFBQVEsRUFBRSxLQUFLO3dCQUNmLFVBQVUsRUFBRSxLQUFLO3dCQUNqQixhQUFhLEVBQUUsSUFBSTt3QkFDbkIsZUFBZSxFQUFFLEtBQUs7d0JBQ3RCLGFBQWEsRUFBRSxLQUFLO3dCQUNwQixZQUFZLEVBQUUsS0FBSzt3QkFDbkIsT0FBTyxFQUFFLENBQUM7cUJBQ1g7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlDLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRTdDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsV0FBVztpQkFDUixNQUFNLENBQ0wsd0ZBQXdGLENBQ3pGO2lCQUNBLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsYUFBYSxFQUNYLDJGQUEyRjtnQkFDN0YsU0FBUyxFQUFFLENBQUM7Z0JBQ1osT0FBTyxFQUFFLGdCQUFnQjthQUMxQixDQUFDLENBQUM7WUFDTCxJQUFJO2dCQUNGLE1BQU0sVUFBVSxDQUFDLG1CQUFtQixDQUFDO29CQUNuQyxJQUFJLEVBQUUsU0FBUztvQkFDZixVQUFVLEVBQUUsT0FBTztvQkFDbkIsTUFBTSxFQUFFO3dCQUNOOzRCQUNFLElBQUksRUFBRSxNQUFNOzRCQUNaLElBQUksRUFBRSxNQUFNOzRCQUNaLE1BQU0sRUFBRSxHQUFHOzRCQUNYLFVBQVUsRUFBRSxLQUFLOzRCQUNqQixZQUFZLEVBQUUsSUFBSTs0QkFDbEIsUUFBUSxFQUFFLEtBQUs7NEJBQ2YsVUFBVSxFQUFFLEtBQUs7NEJBQ2pCLGFBQWEsRUFBRSxJQUFJOzRCQUNuQixlQUFlLEVBQUUsS0FBSzs0QkFDdEIsYUFBYSxFQUFFLEtBQUs7NEJBQ3BCLFlBQVksRUFBRSxLQUFLOzRCQUNuQixPQUFPLEVBQUUsQ0FBQzt5QkFDWDtxQkFDRjtpQkFDRixDQUFDLENBQUM7YUFDSjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO2FBQ2hEO1lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUNILFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxHQUFHLEVBQUU7UUFDaEMsRUFBRSxDQUFDLG1DQUFtQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2pELE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRTdDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsTUFBTSxhQUFhLEdBQUcsNnpEQUE2ekQsQ0FBQztZQUNwMUQsV0FBVztpQkFDUixNQUFNLENBQUMsK0VBQStFLENBQUM7aUJBQ3ZGLEtBQUssQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNuRCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDO2dCQUMzQixFQUFFLEVBQUUsRUFBRSxzQkFBc0IsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO2dCQUMvQyxFQUFFLEVBQUUsRUFBRSxzQkFBc0IsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO2FBQ2hELENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlDLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRTdDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsV0FBVztpQkFDUixNQUFNLENBQUMsK0VBQStFLENBQUM7aUJBQ3ZGLEtBQUssQ0FDSixHQUFHLEVBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztpQkFxQk8sQ0FDUixDQUFDO1lBQ0osSUFBSTtnQkFDRixNQUFNLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2FBQ3JDO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDLENBQUM7YUFDckU7WUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtRQUM5QixFQUFFLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDL0MsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixZQUFZLEVBQUUsYUFBYTtnQkFDM0IsU0FBUyxFQUFFLDhCQUE4QjtnQkFDekMsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSTthQUN2QyxDQUFDO1lBRUYsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXRELE1BQU0sV0FBVyxHQUFHLElBQUksNEJBQWdCLENBQUMsZUFBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQztZQUNqRixNQUFNLGFBQWEsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozt5QkFpREgsQ0FBQztZQUNwQixXQUFXO2lCQUNSLE1BQU0sQ0FBQywrRUFBK0UsQ0FBQztpQkFDdkYsS0FBSyxDQUFDLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUM3QixNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNqRCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDO2dCQUMzQjtvQkFDRSxNQUFNLEVBQUU7d0JBQ04sRUFBRSxFQUFFLFNBQVM7cUJBQ2Q7b0JBQ0QsV0FBVyxFQUFFLE9BQU87b0JBQ3BCLFdBQVcsRUFBRSxFQUFFO29CQUNmLEVBQUUsRUFBRSxLQUFLO29CQUNULElBQUksRUFBRSxXQUFXO29CQUNqQixRQUFRLEVBQUUsc0NBQXNDO29CQUNoRCxVQUFVLEVBQUUsRUFBRTtpQkFDZjtnQkFDRDtvQkFDRSxNQUFNLEVBQUU7d0JBQ04sRUFBRSxFQUFFLFNBQVM7cUJBQ2Q7b0JBQ0QsV0FBVyxFQUFFLGlCQUFpQjtvQkFDOUIsV0FBVyxFQUFFLEVBQUU7b0JBQ2YsRUFBRSxFQUFFLEtBQUs7b0JBQ1QsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsUUFBUSxFQUFFLHNDQUFzQztvQkFDaEQsVUFBVSxFQUFFLEVBQUU7aUJBQ2Y7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLElBQUksRUFBRTtZQUM5QyxNQUFNLGVBQWUsR0FBRztnQkFDdEIsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLFlBQVksRUFBRSxhQUFhO2dCQUMzQixTQUFTLEVBQUUsOEJBQThCO2dCQUN6QyxZQUFZLEVBQUUsYUFBYTtnQkFDM0IsVUFBVSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJO2FBQ3ZDLENBQUM7WUFFRixNQUFNLFVBQVUsR0FBRyxJQUFJLFVBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUU3QyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFFdEQsTUFBTSxXQUFXLEdBQUcsSUFBSSw0QkFBZ0IsQ0FBQyxlQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLFdBQVc7aUJBQ1IsTUFBTSxDQUFDLCtFQUErRSxDQUFDO2lCQUN2RixLQUFLLENBQ0osR0FBRyxFQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7MkJBcUJpQixDQUNsQixDQUFDO1lBQ0osSUFBSTtnQkFDRixNQUFNLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUNuQztZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQyxDQUFDO2FBQ3JFO1lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUNILFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUU7UUFDakMsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2xELE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRTdDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDakYsTUFBTSxhQUFhLEdBQUcsZ2pHQUFnakcsQ0FBQztZQUN2a0csV0FBVztpQkFDUixNQUFNLENBQUMsK0VBQStFLENBQUM7aUJBQ3ZGLEtBQUssQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNyRSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDO2dCQUMzQjtvQkFDRSxVQUFVLEVBQUUsS0FBSztvQkFDakIsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsUUFBUSxFQUFFLHNDQUFzQztpQkFDakQ7Z0JBQ0Q7b0JBQ0UsVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLElBQUksRUFBRSxpQkFBaUI7b0JBQ3ZCLFFBQVEsRUFBRSxzQ0FBc0M7aUJBQ2pEO2dCQUNEO29CQUNFLFVBQVUsRUFBRSxLQUFLO29CQUNqQixJQUFJLEVBQUUsMEJBQTBCO29CQUNoQyxRQUFRLEVBQUUsc0NBQXNDO2lCQUNqRDtnQkFDRDtvQkFDRSxVQUFVLEVBQUUsS0FBSztvQkFDakIsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsUUFBUSxFQUFFLHNDQUFzQztpQkFDakQ7Z0JBQ0Q7b0JBQ0UsVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLElBQUksRUFBRSx3QkFBd0I7b0JBQzlCLFFBQVEsRUFBRSxzQ0FBc0M7aUJBQ2pEO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDOUMsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixZQUFZLEVBQUUsYUFBYTtnQkFDM0IsU0FBUyxFQUFFLDhCQUE4QjtnQkFDekMsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSTthQUN2QyxDQUFDO1lBRUYsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXRELE1BQU0sV0FBVyxHQUFHLElBQUksNEJBQWdCLENBQUMsZUFBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQztZQUNqRixXQUFXO2lCQUNSLE1BQU0sQ0FBQywrRUFBK0UsQ0FBQztpQkFDdkYsS0FBSyxDQUNKLEdBQUcsRUFDSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzJCQXFCaUIsQ0FDbEIsQ0FBQztZQUNKLElBQUk7Z0JBQ0YsTUFBTSxVQUFVLENBQUMsaUJBQWlCLEVBQUUsQ0FBQzthQUN0QztZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQyxDQUFDO2FBQ3JFO1lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCBBeGlvc01vY2tBZGFwdGVyIGZyb20gJ2F4aW9zLW1vY2stYWRhcHRlcic7XG5pbXBvcnQgU0ZNQyBmcm9tICcuJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5kZXNjcmliZSgnc2ZtYycsICgpID0+IHtcbiAgZGVzY3JpYmUoJ2dldEFjY2Vzc1Rva2VuJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGV4aXN0aW5nIGF1dGhPYmplY3Qgd2hlbiB0b2tlbiBpcyBub3QgZXhwaXJlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkQXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6ICd0ZXN0LWNsaWVudCcsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMScsXG4gICAgICAgIGFjY2Vzc190b2tlbjogJ3ZhbGlkLXRva2VuJyxcbiAgICAgICAgZXhwaXJhdGlvbjogcHJvY2Vzcy5ocnRpbWUoKVswXSArIDM2MDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZm1jQ2xpZW50ID0gbmV3IFNGTUModmFsaWRBdXRoT2JqZWN0KTtcbiAgICAgIHNmbWNDbGllbnQuYXV0aE9iamVjdCA9IHZhbGlkQXV0aE9iamVjdDtcblxuICAgICAgamVzdC5zcHlPbih1dGlscywgJ2lzRXhwaXJlZCcpLm1vY2tSZXR1cm5WYWx1ZShmYWxzZSk7XG4gICAgICBjb25zdCByZXF1ZXN0VG9rZW5TcHkgPSBqZXN0LnNweU9uKHV0aWxzLCAnZ2V0VG9rZW4nKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNmbWNDbGllbnQuZ2V0QWNjZXNzVG9rZW4oKTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSh2YWxpZEF1dGhPYmplY3QpO1xuICAgICAgZXhwZWN0KHV0aWxzLmlzRXhwaXJlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgodmFsaWRBdXRoT2JqZWN0KTtcbiAgICAgIGV4cGVjdChyZXF1ZXN0VG9rZW5TcHkpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG4gICAgLy8gSGFuZGxlcyBjYXNlIHdoZW4gYXV0aE9iamVjdCBpcyBpbml0aWFsbHkgZW1wdHkgb3IgbnVsbFxuICAgIGl0KCdzaG91bGQgcmVxdWVzdCBuZXcgdG9rZW4gd2hlbiBhdXRoT2JqZWN0IGlzIGVtcHR5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZW1wdHlBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG5ld0F1dGhPYmplY3QgPSB7XG4gICAgICAgIC4uLmVtcHR5QXV0aE9iamVjdCxcbiAgICAgICAgYWNjZXNzX3Rva2VuOiAnbmV3LXRva2VuJyxcbiAgICAgICAgZXhwaXJlc19pbjogMTIzNDUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZm1jQ2xpZW50ID0gbmV3IFNGTUMoZW1wdHlBdXRoT2JqZWN0KTtcbiAgICAgIHNmbWNDbGllbnQuYXV0aE9iamVjdCA9IGVtcHR5QXV0aE9iamVjdDtcblxuICAgICAgamVzdC5zcHlPbih1dGlscywgJ2lzRXhwaXJlZCcpLm1vY2tSZXR1cm5WYWx1ZSh0cnVlKTtcbiAgICAgIC8vIGplc3Quc3B5T24oYXhpb3MsICdnZXRUb2tlbicpLm1vY2tSZXNvbHZlZFZhbHVlKG5ld0F1dGhPYmplY3QpO1xuICAgICAgY29uc3QgbW9ja0FkYXB0ZXIgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gICAgICBtb2NrQWRhcHRlclxuICAgICAgICAub25Qb3N0KCdodHRwczovL2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEuYXV0aC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tL3YyL3Rva2VuJylcbiAgICAgICAgLnJlcGx5KDIwMCwgbmV3QXV0aE9iamVjdCk7XG4gICAgICBqZXN0LnNweU9uKHByb2Nlc3MsICdocnRpbWUnKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gWzAsIDBdKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNmbWNDbGllbnQuZ2V0QWNjZXNzVG9rZW4oKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoeyAuLi5uZXdBdXRoT2JqZWN0LCBleHBpcmF0aW9uOiAxMjM0NSB9KTtcbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGVtcHR5QXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QodXRpbHMuZ2V0VG9rZW4pLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGVtcHR5QXV0aE9iamVjdCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGF1dGhPYmplY3QgaGFzIGludmFsaWQgY2xpZW50SWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkQXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6IG51bGwsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAndGVzdCcsXG4gICAgICB9O1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc2ZtY0luc3RhbmNlID0gbmV3IFNGTUMoaW52YWxpZEF1dGhPYmplY3QpO1xuICAgICAgICBzZm1jSW5zdGFuY2UuZ2V0QWNjZXNzVG9rZW4oKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZXhwZWN0KGUpLnRvRXF1YWwobmV3IEVycm9yKCdjbGllbnRJZCBpcyBtaXNzaW5nIG9yIGludmFsaWQnKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgY29uY3VycmVudCB0b2tlbiByZWZyZXNoIHJlcXVlc3RzIGNvcnJlY3RseScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGVtcHR5QXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6ICd0ZXN0LWNsaWVudCcsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBuZXdBdXRoT2JqZWN0ID0ge1xuICAgICAgICAuLi5lbXB0eUF1dGhPYmplY3QsXG4gICAgICAgIGFjY2Vzc190b2tlbjogJ25ldy10b2tlbicsXG4gICAgICAgIGV4cGlyZXNfaW46IDEyMzQ1LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2ZtY0NsaWVudCA9IG5ldyBTRk1DKGVtcHR5QXV0aE9iamVjdCk7XG4gICAgICBzZm1jQ2xpZW50LmF1dGhPYmplY3QgPSBlbXB0eUF1dGhPYmplY3Q7XG5cbiAgICAgIGplc3Quc3B5T24odXRpbHMsICdpc0V4cGlyZWQnKS5tb2NrUmV0dXJuVmFsdWUodHJ1ZSk7XG4gICAgICBjb25zdCBtb2NrQWRhcHRlciA9IG5ldyBBeGlvc01vY2tBZGFwdGVyKGF4aW9zLCB7IG9uTm9NYXRjaDogJ3Rocm93RXhjZXB0aW9uJyB9KTtcbiAgICAgIG1vY2tBZGFwdGVyXG4gICAgICAgIC5vblBvc3QoJ2h0dHBzOi8vYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMS5hdXRoLm1hcmtldGluZ2Nsb3VkYXBpcy5jb20vdjIvdG9rZW4nKVxuICAgICAgICAucmVwbHkoMjAwLCBuZXdBdXRoT2JqZWN0KTtcbiAgICAgIGplc3Quc3B5T24ocHJvY2VzcywgJ2hydGltZScpLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiBbMCwgMF0pO1xuICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHNmbWNDbGllbnQuZ2V0QWNjZXNzVG9rZW4oKTtcbiAgICAgIGplc3Quc3B5T24odXRpbHMsICdpc0V4cGlyZWQnKS5tb2NrUmV0dXJuVmFsdWUoZmFsc2UpO1xuICAgICAgcmVzdWx0ID0gYXdhaXQgc2ZtY0NsaWVudC5nZXRBY2Nlc3NUb2tlbigpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbCh7IC4uLm5ld0F1dGhPYmplY3QsIGV4cGlyYXRpb246IDEyMzQ1IH0pO1xuICAgICAgZXhwZWN0KHV0aWxzLmlzRXhwaXJlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoZW1wdHlBdXRoT2JqZWN0KTtcbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGVtcHR5QXV0aE9iamVjdCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aXRoIG9yaWdpbmFsIG1lc3NhZ2Ugd2hlbiB0b2tlbiByZXF1ZXN0IGZhaWxzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZW1wdHlBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNmbWNDbGllbnQgPSBuZXcgU0ZNQyhlbXB0eUF1dGhPYmplY3QpO1xuICAgICAgc2ZtY0NsaWVudC5hdXRoT2JqZWN0ID0gZW1wdHlBdXRoT2JqZWN0O1xuXG4gICAgICBqZXN0LnNweU9uKHV0aWxzLCAnaXNFeHBpcmVkJykubW9ja1JldHVyblZhbHVlKHRydWUpO1xuICAgICAgY29uc3QgbW9ja0FkYXB0ZXIgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gICAgICBtb2NrQWRhcHRlclxuICAgICAgICAub25Qb3N0KCdodHRwczovL2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEuYXV0aC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tL3YyL3Rva2VuJylcbiAgICAgICAgLnJlcGx5KDQwMCwgbmV3IEVycm9yKCdCYWQgUmVxdWVzdCcpKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNmbWNDbGllbnQuZ2V0QWNjZXNzVG9rZW4oKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZXhwZWN0KGUpLnRvRXF1YWwoXG4gICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ1VuYWJsZSB0byBnZW5lcmF0ZSB0b2tlbiwgd2l0aCBlcnJvcjpFcnJvcjogUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSA0MDAnLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnZ2V0RGVzdGluYXRpb25GaWVsZHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZGF0YSBleHRlbnNpb24gZmllbGRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgICAgYWNjZXNzX3Rva2VuOiAndmFsaWQtdG9rZW4nLFxuICAgICAgICBleHBpcmF0aW9uOiBwcm9jZXNzLmhydGltZSgpWzBdICsgMzYwMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNmbWNDbGllbnQgPSBuZXcgU0ZNQyh2YWxpZEF1dGhPYmplY3QpO1xuXG4gICAgICBqZXN0LnNweU9uKHV0aWxzLCAnaXNFeHBpcmVkJykubW9ja1JldHVyblZhbHVlKGZhbHNlKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RUb2tlblNweSA9IGplc3Quc3B5T24odXRpbHMsICdnZXRUb2tlbicpO1xuXG4gICAgICBjb25zdCBtb2NrQWRhcHRlciA9IG5ldyBBeGlvc01vY2tBZGFwdGVyKGF4aW9zLCB7IG9uTm9NYXRjaDogJ3Rocm93RXhjZXB0aW9uJyB9KTtcbiAgICAgIGNvbnN0IHZhbGlkUmVzcG9uc2UgPSB7XG4gICAgICAgIG5hbWU6ICdUZXN0IERFJyxcbiAgICAgICAgY2F0ZWdvcnlJRDogJzEyMzQ1JyxcbiAgICAgICAgZmllbGRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ2ZpZWxkMScsXG4gICAgICAgICAgICB0eXBlOiAnVGV4dCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBtb2NrQWRhcHRlclxuICAgICAgICAub25HZXQoXG4gICAgICAgICAgJ2h0dHBzOi8vYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMS5yZXN0Lm1hcmtldGluZ2Nsb3VkYXBpcy5jb20vZGF0YS92MS9jdXN0b21vYmplY3RzL3Rlc3QtZGUtaWQvZmllbGRzJyxcbiAgICAgICAgKVxuICAgICAgICAucmVwbHkoMjAwLCB2YWxpZFJlc3BvbnNlKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNmbWNDbGllbnQuZ2V0RGVzdGluYXRpb25GaWVsZHMoJ3Rlc3QtZGUtaWQnKTtcbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHZhbGlkQXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QocmVxdWVzdFRva2VuU3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9TdHJpY3RFcXVhbCh2YWxpZFJlc3BvbnNlKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBmYWlsdXJlIHNjZW5hcmlvJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgICAgYWNjZXNzX3Rva2VuOiAndmFsaWQtdG9rZW4nLFxuICAgICAgICBleHBpcmF0aW9uOiBwcm9jZXNzLmhydGltZSgpWzBdICsgMzYwMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNmbWNDbGllbnQgPSBuZXcgU0ZNQyh2YWxpZEF1dGhPYmplY3QpO1xuXG4gICAgICBqZXN0LnNweU9uKHV0aWxzLCAnaXNFeHBpcmVkJykubW9ja1JldHVyblZhbHVlKGZhbHNlKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RUb2tlblNweSA9IGplc3Quc3B5T24odXRpbHMsICdnZXRUb2tlbicpO1xuXG4gICAgICBjb25zdCBtb2NrQWRhcHRlciA9IG5ldyBBeGlvc01vY2tBZGFwdGVyKGF4aW9zLCB7IG9uTm9NYXRjaDogJ3Rocm93RXhjZXB0aW9uJyB9KTtcbiAgICAgIG1vY2tBZGFwdGVyXG4gICAgICAgIC5vbkdldChcbiAgICAgICAgICAnaHR0cHM6Ly9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxLnJlc3QubWFya2V0aW5nY2xvdWRhcGlzLmNvbS9kYXRhL3YxL2N1c3RvbW9iamVjdHMvdGVzdC1kZS1pZC9maWVsZHMnLFxuICAgICAgICApXG4gICAgICAgIC5yZXBseSg0MDEsIHtcbiAgICAgICAgICBkb2N1bWVudGF0aW9uOlxuICAgICAgICAgICAgJ2h0dHBzOi8vZGV2ZWxvcGVyLnNhbGVzZm9yY2UuY29tL2RvY3MvYXRsYXMuZW4tdXMubWMtYXBpcy5tZXRhL21jLWFwaXMvZXJyb3ItaGFuZGxpbmcuaHRtJyxcbiAgICAgICAgICBlcnJvcmNvZGU6IDAsXG4gICAgICAgICAgbWVzc2FnZTogJ05vdCBBdXRob3JpemVkJyxcbiAgICAgICAgfSk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZm1jQ2xpZW50LmdldERlc3RpbmF0aW9uRmllbGRzKCd0ZXN0LWRlLWlkJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGV4cGVjdChlKS50b0VxdWFsKG5ldyBFcnJvcignTm90IEF1dGhvcml6ZWQnKSk7XG4gICAgICB9XG4gICAgICBleHBlY3QodXRpbHMuaXNFeHBpcmVkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh2YWxpZEF1dGhPYmplY3QpO1xuICAgICAgZXhwZWN0KHJlcXVlc3RUb2tlblNweSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbiAgICB9KTtcbiAgfSk7XG4gIGRlc2NyaWJlKCdnZXRDb250YWN0QXR0cmlidXRlcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb250YWN0IGF0dHJpYnV0ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZEF1dGhPYmplY3QgPSB7XG4gICAgICAgIGNsaWVudElkOiAndGVzdC1jbGllbnQnLFxuICAgICAgICBjbGllbnRTZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgIHN1YkRvbWFpbjogJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEnLFxuICAgICAgICBhY2Nlc3NfdG9rZW46ICd2YWxpZC10b2tlbicsXG4gICAgICAgIGV4cGlyYXRpb246IHByb2Nlc3MuaHJ0aW1lKClbMF0gKyAzNjAwLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2ZtY0NsaWVudCA9IG5ldyBTRk1DKHZhbGlkQXV0aE9iamVjdCk7XG5cbiAgICAgIGplc3Quc3B5T24odXRpbHMsICdpc0V4cGlyZWQnKS5tb2NrUmV0dXJuVmFsdWUoZmFsc2UpO1xuICAgICAgY29uc3QgcmVxdWVzdFRva2VuU3B5ID0gamVzdC5zcHlPbih1dGlscywgJ2dldFRva2VuJyk7XG5cbiAgICAgIGNvbnN0IG1vY2tBZGFwdGVyID0gbmV3IEF4aW9zTW9ja0FkYXB0ZXIoYXhpb3MsIHsgb25Ob01hdGNoOiAndGhyb3dFeGNlcHRpb24nIH0pO1xuICAgICAgY29uc3QgdmFsaWRSZXNwb25zZSA9IHtcbiAgICAgICAgZGF0YToge1xuICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlzUmVhZE9ubHk6IHRydWUsXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBpc1JlYWRPbmx5OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgZnVsbHlRdWFsaWZpZWROYW1lOiAndGVzdC5uYW1lJyxcbiAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG1vY2tBZGFwdGVyXG4gICAgICAgIC5vbkdldChcbiAgICAgICAgICAnaHR0cHM6Ly9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxLnJlc3QubWFya2V0aW5nY2xvdWRhcGlzLmNvbS9jb250YWN0cy92MS9hdHRyaWJ1dGVTZXREZWZpbml0aW9ucycsXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDIwMCwgdmFsaWRSZXNwb25zZSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzZm1jQ2xpZW50LmdldENvbnRhY3RBdHRyaWJ1dGVzKCk7XG4gICAgICBleHBlY3QodXRpbHMuaXNFeHBpcmVkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh2YWxpZEF1dGhPYmplY3QpO1xuICAgICAgZXhwZWN0KHJlcXVlc3RUb2tlblNweSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvU3RyaWN0RXF1YWwodmFsaWRSZXNwb25zZSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZmFpbHVyZSBzY2VuYXJpbycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkQXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6ICd0ZXN0LWNsaWVudCcsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMScsXG4gICAgICAgIGFjY2Vzc190b2tlbjogJ3ZhbGlkLXRva2VuJyxcbiAgICAgICAgZXhwaXJhdGlvbjogcHJvY2Vzcy5ocnRpbWUoKVswXSArIDM2MDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZm1jQ2xpZW50ID0gbmV3IFNGTUModmFsaWRBdXRoT2JqZWN0KTtcblxuICAgICAgamVzdC5zcHlPbih1dGlscywgJ2lzRXhwaXJlZCcpLm1vY2tSZXR1cm5WYWx1ZShmYWxzZSk7XG4gICAgICBjb25zdCByZXF1ZXN0VG9rZW5TcHkgPSBqZXN0LnNweU9uKHV0aWxzLCAnZ2V0VG9rZW4nKTtcblxuICAgICAgY29uc3QgbW9ja0FkYXB0ZXIgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gICAgICBtb2NrQWRhcHRlclxuICAgICAgICAub25HZXQoXG4gICAgICAgICAgJ2h0dHBzOi8vYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMS5yZXN0Lm1hcmtldGluZ2Nsb3VkYXBpcy5jb20vY29udGFjdHMvdjEvYXR0cmlidXRlU2V0RGVmaW5pdGlvbnMnLFxuICAgICAgICApXG4gICAgICAgIC5yZXBseSg0MDEsIHtcbiAgICAgICAgICBkb2N1bWVudGF0aW9uOlxuICAgICAgICAgICAgJ2h0dHBzOi8vZGV2ZWxvcGVyLnNhbGVzZm9yY2UuY29tL2RvY3MvYXRsYXMuZW4tdXMubWMtYXBpcy5tZXRhL21jLWFwaXMvZXJyb3ItaGFuZGxpbmcuaHRtJyxcbiAgICAgICAgICBlcnJvcmNvZGU6IDAsXG4gICAgICAgICAgbWVzc2FnZTogJ05vdCBBdXRob3JpemVkJyxcbiAgICAgICAgfSk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZm1jQ2xpZW50LmdldENvbnRhY3RBdHRyaWJ1dGVzKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGV4cGVjdChlKS50b0VxdWFsKG5ldyBFcnJvcignTm90IEF1dGhvcml6ZWQnKSk7XG4gICAgICB9XG4gICAgICBleHBlY3QodXRpbHMuaXNFeHBpcmVkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh2YWxpZEF1dGhPYmplY3QpO1xuICAgICAgZXhwZWN0KHJlcXVlc3RUb2tlblNweSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbiAgICB9KTtcbiAgfSk7XG4gIGRlc2NyaWJlKCdjcmVhdGVEYXRhRXh0ZW5zaW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIG5ldyBkYXRhIGV4dGVuc2lvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkQXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6ICd0ZXN0LWNsaWVudCcsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMScsXG4gICAgICAgIGFjY2Vzc190b2tlbjogJ3ZhbGlkLXRva2VuJyxcbiAgICAgICAgZXhwaXJhdGlvbjogcHJvY2Vzcy5ocnRpbWUoKVswXSArIDM2MDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZm1jQ2xpZW50ID0gbmV3IFNGTUModmFsaWRBdXRoT2JqZWN0KTtcblxuICAgICAgamVzdC5zcHlPbih1dGlscywgJ2lzRXhwaXJlZCcpLm1vY2tSZXR1cm5WYWx1ZShmYWxzZSk7XG4gICAgICBjb25zdCByZXF1ZXN0VG9rZW5TcHkgPSBqZXN0LnNweU9uKHV0aWxzLCAnZ2V0VG9rZW4nKTtcblxuICAgICAgY29uc3QgbW9ja0FkYXB0ZXIgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gICAgICBjb25zdCB2YWxpZFJlc3BvbnNlID0ge1xuICAgICAgICBpZDogJzRiYWY0Y2YxLThjYzktZWYxMS1iYTZlLWY0MDM0M2QzODBjOCcsXG4gICAgICAgIG5hbWU6ICdydWRkZXJzdGFja1Rlc3RpbmcwMjk1JyxcbiAgICAgICAga2V5OiAncnVkZGVyc3RhY2tUZXN0aW5nMDI5NScsXG4gICAgICAgIGlzQWN0aXZlOiB0cnVlLFxuICAgICAgICBpc1NlbmRhYmxlOiBmYWxzZSxcbiAgICAgICAgaXNUZXN0YWJsZTogZmFsc2UsXG4gICAgICAgIHN0YXR1czogMCxcbiAgICAgICAgY2F0ZWdvcnlJZDogMTIzNDUsXG4gICAgICAgIG93bmVySWQ6IDczNTQ0NDUzMSxcbiAgICAgICAgaXNPYmplY3REZWxldGFibGU6IHRydWUsXG4gICAgICAgIGlzRmllbGRBZGRpdGlvbkFsbG93ZWQ6IHRydWUsXG4gICAgICAgIGlzRmllbGRNb2RpZmljYXRpb25BbGxvd2VkOiB0cnVlLFxuICAgICAgICBjcmVhdGVkRGF0ZTogJzIwMjUtMDEtMDJUMjI6NDE6MTIuNTAxODQxNS0wNjowMCcsXG4gICAgICAgIGNyZWF0ZWRCeUlkOiA3MzU0NDQ1MzEsXG4gICAgICAgIG1vZGlmaWVkRGF0ZTogJzIwMjUtMDEtMDJUMjI6NDE6MTIuNTAxODQxNS0wNjowMCcsXG4gICAgICAgIG1vZGlmaWVkQnlJZDogNzM1NDQ0NTMxLFxuICAgICAgICBvd25lck5hbWU6ICdSdWRkZXJzdGFja0ludGVncmF0aW9uIGFwcCB1c2VyJyxcbiAgICAgICAgcm93Q291bnQ6IDAsXG4gICAgICAgIGRhdGFSZXRlbnRpb25Qcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgaXNEZWxldGVBdEVuZE9mUmV0ZW50aW9uUGVyaW9kOiB0cnVlLFxuICAgICAgICAgIGlzUm93QmFzZWRSZXRlbnRpb246IGZhbHNlLFxuICAgICAgICAgIGlzUmVzZXRSZXRlbnRpb25QZXJpb2RPbkltcG9ydDogZmFsc2UsXG4gICAgICAgICAgcm93QmFzZWRUaHJlc2hvbGQ6IDEwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIGZpZWxkczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdrZXkxJyxcbiAgICAgICAgICAgIGlkOiAnMzAwYmEyMzMtYjdlMC00NzMyLWJhODUtMWJjMDEyMDhmYzFiJyxcbiAgICAgICAgICAgIHR5cGU6ICdUZXh0JyxcbiAgICAgICAgICAgIG1hc2tUeXBlOiAnTm9uZScsXG4gICAgICAgICAgICBzdG9yYWdlVHlwZTogJ1BsYWluJyxcbiAgICAgICAgICAgIGxlbmd0aDogMjU0LFxuICAgICAgICAgICAgb3JkaW5hbDogMCxcbiAgICAgICAgICAgIGlzTnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgaXNQcmltYXJ5S2V5OiB0cnVlLFxuICAgICAgICAgICAgaXNUZW1wbGF0ZUZpZWxkOiBmYWxzZSxcbiAgICAgICAgICAgIGlzSW5oZXJpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgaXNPdmVycmlkYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGlzSGlkZGVuOiBmYWxzZSxcbiAgICAgICAgICAgIGlzUmVhZE9ubHk6IGZhbHNlLFxuICAgICAgICAgICAgbXVzdE92ZXJyaWRlOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdrZXkyJyxcbiAgICAgICAgICAgIGlkOiAnNzVhMzhmOTgtZTg2NS00M2NlLTk3MDItNWIzMTdiYTI5ZDkyJyxcbiAgICAgICAgICAgIHR5cGU6ICdFbWFpbEFkZHJlc3MnLFxuICAgICAgICAgICAgbWFza1R5cGU6ICdOb25lJyxcbiAgICAgICAgICAgIHN0b3JhZ2VUeXBlOiAnUGxhaW4nLFxuICAgICAgICAgICAgbGVuZ3RoOiAyNTQsXG4gICAgICAgICAgICBvcmRpbmFsOiAwLFxuICAgICAgICAgICAgaXNOdWxsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGlzUHJpbWFyeUtleTogZmFsc2UsXG4gICAgICAgICAgICBpc1RlbXBsYXRlRmllbGQ6IGZhbHNlLFxuICAgICAgICAgICAgaXNJbmhlcml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICBpc092ZXJyaWRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgaXNIaWRkZW46IGZhbHNlLFxuICAgICAgICAgICAgaXNSZWFkT25seTogZmFsc2UsXG4gICAgICAgICAgICBtdXN0T3ZlcnJpZGU6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZpZWxkQ291bnQ6IDIsXG4gICAgICB9O1xuICAgICAgbW9ja0FkYXB0ZXJcbiAgICAgICAgLm9uUG9zdChcbiAgICAgICAgICAnaHR0cHM6Ly9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxLnJlc3QubWFya2V0aW5nY2xvdWRhcGlzLmNvbS9kYXRhL3YxL2N1c3RvbW9iamVjdHMnLFxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDAsIHZhbGlkUmVzcG9uc2UpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2ZtY0NsaWVudC5jcmVhdGVEYXRhRXh0ZW5zaW9uKHtcbiAgICAgICAgbmFtZTogJ3Rlc3QtZGUnLFxuICAgICAgICBjYXRlZ29yeUlEOiAnMTIzNDUnLFxuICAgICAgICBkYXRhUmV0ZW50aW9uUHJvcGVydGllczoge1xuICAgICAgICAgIGlzRGVsZXRlQXRFbmRPZlJldGVudGlvblBlcmlvZDogdHJ1ZSxcbiAgICAgICAgICBpc1Jvd0Jhc2VkUmV0ZW50aW9uOiBmYWxzZSxcbiAgICAgICAgICBpc1Jlc2V0UmV0ZW50aW9uUGVyaW9kT25JbXBvcnQ6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBmaWVsZHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAna2V5MScsXG4gICAgICAgICAgICB0eXBlOiAnVGV4dCcsXG4gICAgICAgICAgICBsZW5ndGg6IDI1NCxcbiAgICAgICAgICAgIGlzTnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgaXNQcmltYXJ5S2V5OiB0cnVlLFxuICAgICAgICAgICAgaXNIaWRkZW46IGZhbHNlLFxuICAgICAgICAgICAgaXNSZWFkT25seTogZmFsc2UsXG4gICAgICAgICAgICBpc092ZXJyaWRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgaXNUZW1wbGF0ZUZpZWxkOiBmYWxzZSxcbiAgICAgICAgICAgIGlzSW5oZXJpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgbXVzdE92ZXJyaWRlOiBmYWxzZSxcbiAgICAgICAgICAgIG9yZGluYWw6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAna2V5MicsXG4gICAgICAgICAgICB0eXBlOiAnRW1haWxBZGRyZXNzJyxcbiAgICAgICAgICAgIGxlbmd0aDogMjU0LFxuICAgICAgICAgICAgaXNOdWxsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGlzUHJpbWFyeUtleTogZmFsc2UsXG4gICAgICAgICAgICBpc0hpZGRlbjogZmFsc2UsXG4gICAgICAgICAgICBpc1JlYWRPbmx5OiBmYWxzZSxcbiAgICAgICAgICAgIGlzT3ZlcnJpZGFibGU6IHRydWUsXG4gICAgICAgICAgICBpc1RlbXBsYXRlRmllbGQ6IGZhbHNlLFxuICAgICAgICAgICAgaXNJbmhlcml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICBtdXN0T3ZlcnJpZGU6IGZhbHNlLFxuICAgICAgICAgICAgb3JkaW5hbDogMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgICBleHBlY3QodXRpbHMuaXNFeHBpcmVkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh2YWxpZEF1dGhPYmplY3QpO1xuICAgICAgZXhwZWN0KHJlcXVlc3RUb2tlblNweSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvU3RyaWN0RXF1YWwodmFsaWRSZXNwb25zZSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZmFpbHVyZSBzY2VuYXJpbycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkQXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6ICd0ZXN0LWNsaWVudCcsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMScsXG4gICAgICAgIGFjY2Vzc190b2tlbjogJ3ZhbGlkLXRva2VuJyxcbiAgICAgICAgZXhwaXJhdGlvbjogcHJvY2Vzcy5ocnRpbWUoKVswXSArIDM2MDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZm1jQ2xpZW50ID0gbmV3IFNGTUModmFsaWRBdXRoT2JqZWN0KTtcblxuICAgICAgamVzdC5zcHlPbih1dGlscywgJ2lzRXhwaXJlZCcpLm1vY2tSZXR1cm5WYWx1ZShmYWxzZSk7XG4gICAgICBjb25zdCByZXF1ZXN0VG9rZW5TcHkgPSBqZXN0LnNweU9uKHV0aWxzLCAnZ2V0VG9rZW4nKTtcblxuICAgICAgY29uc3QgbW9ja0FkYXB0ZXIgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gICAgICBtb2NrQWRhcHRlclxuICAgICAgICAub25Qb3N0KFxuICAgICAgICAgICdodHRwczovL2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEucmVzdC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tL2RhdGEvdjEvY3VzdG9tb2JqZWN0cycsXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDQwMSwge1xuICAgICAgICAgIGRvY3VtZW50YXRpb246XG4gICAgICAgICAgICAnaHR0cHM6Ly9kZXZlbG9wZXIuc2FsZXNmb3JjZS5jb20vZG9jcy9hdGxhcy5lbi11cy5tYy1hcGlzLm1ldGEvbWMtYXBpcy9lcnJvci1oYW5kbGluZy5odG0nLFxuICAgICAgICAgIGVycm9yY29kZTogMCxcbiAgICAgICAgICBtZXNzYWdlOiAnTm90IEF1dGhvcml6ZWQnLFxuICAgICAgICB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNmbWNDbGllbnQuY3JlYXRlRGF0YUV4dGVuc2lvbih7XG4gICAgICAgICAgbmFtZTogJ3Rlc3QtZGUnLFxuICAgICAgICAgIGNhdGVnb3J5SUQ6ICcxMjM0NScsXG4gICAgICAgICAgZmllbGRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG5hbWU6ICdrZXkxJyxcbiAgICAgICAgICAgICAgdHlwZTogJ1RleHQnLFxuICAgICAgICAgICAgICBsZW5ndGg6IDI1NCxcbiAgICAgICAgICAgICAgaXNOdWxsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIGlzUHJpbWFyeUtleTogdHJ1ZSxcbiAgICAgICAgICAgICAgaXNIaWRkZW46IGZhbHNlLFxuICAgICAgICAgICAgICBpc1JlYWRPbmx5OiBmYWxzZSxcbiAgICAgICAgICAgICAgaXNPdmVycmlkYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgaXNUZW1wbGF0ZUZpZWxkOiBmYWxzZSxcbiAgICAgICAgICAgICAgaXNJbmhlcml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIG11c3RPdmVycmlkZTogZmFsc2UsXG4gICAgICAgICAgICAgIG9yZGluYWw6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBleHBlY3QoZSkudG9FcXVhbChuZXcgRXJyb3IoJ05vdCBBdXRob3JpemVkJykpO1xuICAgICAgfVxuICAgICAgZXhwZWN0KHV0aWxzLmlzRXhwaXJlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgodmFsaWRBdXRoT2JqZWN0KTtcbiAgICAgIGV4cGVjdChyZXF1ZXN0VG9rZW5TcHkpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnZ2V0QnVzaW5lc3NVbml0cycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGdldCBhbGwgdGhlIGJ1c2luZXNzIHVuaXRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgICAgYWNjZXNzX3Rva2VuOiAndmFsaWQtdG9rZW4nLFxuICAgICAgICBleHBpcmF0aW9uOiBwcm9jZXNzLmhydGltZSgpWzBdICsgMzYwMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNmbWNDbGllbnQgPSBuZXcgU0ZNQyh2YWxpZEF1dGhPYmplY3QpO1xuXG4gICAgICBqZXN0LnNweU9uKHV0aWxzLCAnaXNFeHBpcmVkJykubW9ja1JldHVyblZhbHVlKGZhbHNlKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RUb2tlblNweSA9IGplc3Quc3B5T24odXRpbHMsICdnZXRUb2tlbicpO1xuXG4gICAgICBjb25zdCBtb2NrQWRhcHRlciA9IG5ldyBBeGlvc01vY2tBZGFwdGVyKGF4aW9zLCB7IG9uTm9NYXRjaDogJ3Rocm93RXhjZXB0aW9uJyB9KTtcbiAgICAgIGNvbnN0IHZhbGlkUmVzcG9uc2UgPSBgPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwidXRmLThcIj8+PHNvYXA6RW52ZWxvcGUgeG1sbnM6c29hcD1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvXCIgeG1sbnM6eHNpPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VcIiB4bWxuczp4c2Q9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYVwiIHhtbG5zOndzYT1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiIHhtbG5zOndzc2U9XCJodHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXdzc2VjdXJpdHktc2VjZXh0LTEuMC54c2RcIiB4bWxuczp3c3U9XCJodHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXdzc2VjdXJpdHktdXRpbGl0eS0xLjAueHNkXCI+PHNvYXA6SGVhZGVyPjx3c2E6QWN0aW9uPlJldHJpZXZlUmVzcG9uc2U8L3dzYTpBY3Rpb24+PHdzYTpNZXNzYWdlSUQ+dXJuOnV1aWQ6MGJlZDYwMmItNjNjNC00YmI0LTk1ODItMmIyN2M4ZjJiMWRhPC93c2E6TWVzc2FnZUlEPjx3c2E6UmVsYXRlc1RvPnVybjp1dWlkOjQ1ZGNjMjUxLWEwMzctNDE3Mi05OWNlLTY2NmE2YjNiODcyYzwvd3NhOlJlbGF0ZXNUbz48d3NhOlRvPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvd3NhOlRvPjx3c3NlOlNlY3VyaXR5Pjx3c3U6VGltZXN0YW1wIHdzdTpJZD1cIlRpbWVzdGFtcC1kMDMwOGFlMi00YWRmLTQ1NzgtOGQ4NS1mYWE3MjBhOTY2Y2VcIj48d3N1OkNyZWF0ZWQ+MjAyNS0wMS0wOVQwNTo1MDoxMFo8L3dzdTpDcmVhdGVkPjx3c3U6RXhwaXJlcz4yMDI1LTAxLTA5VDA1OjU1OjEwWjwvd3N1OkV4cGlyZXM+PC93c3U6VGltZXN0YW1wPjwvd3NzZTpTZWN1cml0eT48L3NvYXA6SGVhZGVyPjxzb2FwOkJvZHk+PFJldHJpZXZlUmVzcG9uc2VNc2cgeG1sbnM9XCJodHRwOi8vZXhhY3R0YXJnZXQuY29tL3dzZGwvcGFydG5lckFQSVwiPjxPdmVyYWxsU3RhdHVzPk9LPC9PdmVyYWxsU3RhdHVzPjxSZXF1ZXN0SUQ+YWI5NDdjYWEtMzRiZC00ZTViLTg0YzEtNTRhYjFlNjMzYTZmPC9SZXF1ZXN0SUQ+PFJlc3VsdHMgeHNpOnR5cGU9XCJCdXNpbmVzc1VuaXRcIj48UGFydG5lcktleSB4c2k6bmlsPVwidHJ1ZVwiIC8+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPmlkPC9OYW1lPjxWYWx1ZT41MzQwMDMyMTA8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPm5hbWU8L05hbWU+PFZhbHVlPkxhbnNkb3duZSBTdGFkaXVtIExQPC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxPYmplY3RJRCB4c2k6bmlsPVwidHJ1ZVwiIC8+PEFjY291bnRUeXBlPk5vbmU8L0FjY291bnRUeXBlPjxTdWJzY3JpcHRpb24geHNpOm5pbD1cInRydWVcIiAvPjwvUmVzdWx0cz48UmVzdWx0cyB4c2k6dHlwZT1cIkJ1c2luZXNzVW5pdFwiPjxQYXJ0bmVyS2V5IHhzaTpuaWw9XCJ0cnVlXCIgLz48UGFydG5lclByb3BlcnRpZXM+PE5hbWU+aWQ8L05hbWU+PFZhbHVlPjUzNDAwMzIxMDwvVmFsdWU+PC9QYXJ0bmVyUHJvcGVydGllcz48UGFydG5lclByb3BlcnRpZXM+PE5hbWU+bmFtZTwvTmFtZT48VmFsdWU+TGFuc2Rvd25lIFN0YWRpdW0gTFA8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PE9iamVjdElEIHhzaTpuaWw9XCJ0cnVlXCIgLz48QWNjb3VudFR5cGU+Tm9uZTwvQWNjb3VudFR5cGU+PFN1YnNjcmlwdGlvbiB4c2k6bmlsPVwidHJ1ZVwiIC8+PC9SZXN1bHRzPjwvUmV0cmlldmVSZXNwb25zZU1zZz48L3NvYXA6Qm9keT48L3NvYXA6RW52ZWxvcGU+YDtcbiAgICAgIG1vY2tBZGFwdGVyXG4gICAgICAgIC5vblBvc3QoJ2h0dHBzOi8vYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMS5zb2FwLm1hcmtldGluZ2Nsb3VkYXBpcy5jb20vU2VydmljZS5hc214JylcbiAgICAgICAgLnJlcGx5KDIwMCwgdmFsaWRSZXNwb25zZSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzZm1jQ2xpZW50LmdldEJ1c2luZXNzVW5pdHMoKTtcbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHZhbGlkQXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QocmVxdWVzdFRva2VuU3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9TdHJpY3RFcXVhbChbXG4gICAgICAgIHsgSUQ6ICdMYW5zZG93bmUgU3RhZGl1bSBMUCcsIE5hbWU6IDUzNDAwMzIxMCB9LFxuICAgICAgICB7IElEOiAnTGFuc2Rvd25lIFN0YWRpdW0gTFAnLCBOYW1lOiA1MzQwMDMyMTAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgaGFuZGxlIGZhaWx1cmUgc2NlbmFyaW8nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZEF1dGhPYmplY3QgPSB7XG4gICAgICAgIGNsaWVudElkOiAndGVzdC1jbGllbnQnLFxuICAgICAgICBjbGllbnRTZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgIHN1YkRvbWFpbjogJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEnLFxuICAgICAgICBhY2Nlc3NfdG9rZW46ICd2YWxpZC10b2tlbicsXG4gICAgICAgIGV4cGlyYXRpb246IHByb2Nlc3MuaHJ0aW1lKClbMF0gKyAzNjAwLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2ZtY0NsaWVudCA9IG5ldyBTRk1DKHZhbGlkQXV0aE9iamVjdCk7XG5cbiAgICAgIGplc3Quc3B5T24odXRpbHMsICdpc0V4cGlyZWQnKS5tb2NrUmV0dXJuVmFsdWUoZmFsc2UpO1xuICAgICAgY29uc3QgcmVxdWVzdFRva2VuU3B5ID0gamVzdC5zcHlPbih1dGlscywgJ2dldFRva2VuJyk7XG5cbiAgICAgIGNvbnN0IG1vY2tBZGFwdGVyID0gbmV3IEF4aW9zTW9ja0FkYXB0ZXIoYXhpb3MsIHsgb25Ob01hdGNoOiAndGhyb3dFeGNlcHRpb24nIH0pO1xuICAgICAgbW9ja0FkYXB0ZXJcbiAgICAgICAgLm9uUG9zdCgnaHR0cHM6Ly9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxLnNvYXAubWFya2V0aW5nY2xvdWRhcGlzLmNvbS9TZXJ2aWNlLmFzbXgnKVxuICAgICAgICAucmVwbHkoXG4gICAgICAgICAgNTAwLFxuICAgICAgICAgIGA8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJ1dGYtOFwiPz5cbjxzb2FwOkVudmVsb3BlIHhtbG5zOnNvYXA9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VudmVsb3BlL1wiIHhtbG5zOnhzaT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlXCIgeG1sbnM6eHNkPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWFcIiB4bWxuczp3c2E9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmdcIiB4bWxuczp3c3NlPVwiaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXNlY2V4dC0xLjAueHNkXCIgeG1sbnM6d3N1PVwiaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXV0aWxpdHktMS4wLnhzZFwiPlxuICAgIDxzb2FwOkhlYWRlcj5cbiAgICAgICAgPHdzYTpBY3Rpb24+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL2ZhdWx0PC93c2E6QWN0aW9uPlxuICAgICAgICA8d3NhOk1lc3NhZ2VJRD51cm46dXVpZDoxNWQzZTI4Ni05N2Y1LTRmNWMtYjBmYS1kNTg2NzM2MjE1Njg8L3dzYTpNZXNzYWdlSUQ+XG4gICAgICAgIDx3c2E6UmVsYXRlc1RvPnVybjp1dWlkOmIzOGVlODViLThmNmItNGVkYy05YWI5LTIzYWI2ZTVhNTFlMzwvd3NhOlJlbGF0ZXNUbz5cbiAgICAgICAgPHdzYTpUbz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L3dzYTpUbz5cbiAgICAgICAgPHdzc2U6U2VjdXJpdHk+XG4gICAgICAgICAgICA8d3N1OlRpbWVzdGFtcCB3c3U6SWQ9XCJUaW1lc3RhbXAtZGMwMmY4ZTgtYWY3NC00Nzk5LWI1ZTktOWU5YzAyOTkyNzhmXCI+XG4gICAgICAgICAgICAgICAgPHdzdTpDcmVhdGVkPjIwMjUtMDEtMDNUMDQ6NTk6NDVaPC93c3U6Q3JlYXRlZD5cbiAgICAgICAgICAgICAgICA8d3N1OkV4cGlyZXM+MjAyNS0wMS0wM1QwNTowNDo0NVo8L3dzdTpFeHBpcmVzPlxuICAgICAgICAgICAgPC93c3U6VGltZXN0YW1wPlxuICAgICAgICA8L3dzc2U6U2VjdXJpdHk+XG4gICAgPC9zb2FwOkhlYWRlcj5cbiAgICA8c29hcDpCb2R5PlxuICAgICAgICA8c29hcDpGYXVsdD5cbiAgICAgICAgICAgIDxmYXVsdGNvZGUgeG1sbnM6cTA9XCJodHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXdzc2VjdXJpdHktc2VjZXh0LTEuMC54c2RcIj5xMDpTZWN1cml0eTwvZmF1bHRjb2RlPlxuICAgICAgICAgICAgPGZhdWx0c3RyaW5nPkxvZ2luIEZhaWxlZDwvZmF1bHRzdHJpbmc+XG4gICAgICAgICAgICA8ZmF1bHRhY3Rvcj5odHRwczovL21jdmdrcXozYzFjaHJic3o1ODZrOTBzNDFocDguc29hcC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tL1NlcnZpY2UuYXNteDwvZmF1bHRhY3Rvcj5cbiAgICAgICAgPC9zb2FwOkZhdWx0PlxuICAgIDwvc29hcDpCb2R5PlxuPC9zb2FwOkVudmVsb3BlPmAsXG4gICAgICAgICk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZm1jQ2xpZW50LmdldEJ1c2luZXNzVW5pdHMoKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZXhwZWN0KGUpLnRvRXF1YWwobmV3IEVycm9yKCdSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlIDUwMCcpKTtcbiAgICAgIH1cbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHZhbGlkQXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QocmVxdWVzdFRva2VuU3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJ2dldERhdGFGb2xkZXJzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2V0IGFsbCB0aGUgZGF0YSBmb2xkZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgICAgYWNjZXNzX3Rva2VuOiAndmFsaWQtdG9rZW4nLFxuICAgICAgICBleHBpcmF0aW9uOiBwcm9jZXNzLmhydGltZSgpWzBdICsgMzYwMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNmbWNDbGllbnQgPSBuZXcgU0ZNQyh2YWxpZEF1dGhPYmplY3QpO1xuXG4gICAgICBqZXN0LnNweU9uKHV0aWxzLCAnaXNFeHBpcmVkJykubW9ja1JldHVyblZhbHVlKGZhbHNlKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RUb2tlblNweSA9IGplc3Quc3B5T24odXRpbHMsICdnZXRUb2tlbicpO1xuXG4gICAgICBjb25zdCBtb2NrQWRhcHRlciA9IG5ldyBBeGlvc01vY2tBZGFwdGVyKGF4aW9zLCB7IG9uTm9NYXRjaDogJ3Rocm93RXhjZXB0aW9uJyB9KTtcbiAgICAgIGNvbnN0IHZhbGlkUmVzcG9uc2UgPSBgPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwidXRmLThcIj8+XG4gICAgICAgIDxzb2FwOkVudmVsb3BlXG4gICAgICAgICAgeG1sbnM6c29hcD1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvXCJcbiAgICAgICAgICB4bWxuczp4c2k9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZVwiXG4gICAgICAgICAgeG1sbnM6eHNkPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWFcIlxuICAgICAgICAgIHhtbG5zOndzYT1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiXG4gICAgICAgICAgeG1sbnM6d3NzZT1cImh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS1zZWNleHQtMS4wLnhzZFwiXG4gICAgICAgICAgeG1sbnM6d3N1PVwiaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXV0aWxpdHktMS4wLnhzZFwiPlxuICAgICAgICAgIDxzb2FwOkhlYWRlcj5cbiAgICAgICAgICAgIDx3c2E6QWN0aW9uPlJldHJpZXZlUmVzcG9uc2U8L3dzYTpBY3Rpb24+XG4gICAgICAgICAgICA8d3NhOk1lc3NhZ2VJRD51cm46dXVpZDoxY2Y0ZmQ3Mi05M2E5LTQzNjAtYTc1Yy05ODhkYzcwOGViN2M8L3dzYTpNZXNzYWdlSUQ+XG4gICAgICAgICAgICA8d3NhOlJlbGF0ZXNUbz51cm46dXVpZDo1MjdhMTNhNS1hNzk4LTQ0MzgtYjIzZC1iN2ZkMDg0YWM5NTM8L3dzYTpSZWxhdGVzVG8+XG4gICAgICAgICAgICA8d3NhOlRvPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvd3NhOlRvPlxuICAgICAgICAgICAgPHdzc2U6U2VjdXJpdHk+XG4gICAgICAgICAgICAgIDx3c3U6VGltZXN0YW1wIHdzdTpJZD1cIlRpbWVzdGFtcC05ZDdjNTcwNy1lOGVjLTRkYjgtYjU1ZS03Y2JkMmNlMjJmYTNcIj5cbiAgICAgICAgICAgICAgICA8d3N1OkNyZWF0ZWQ+MjAyNS0wMS0wM1QwNTo1NDoxNlo8L3dzdTpDcmVhdGVkPlxuICAgICAgICAgICAgICAgIDx3c3U6RXhwaXJlcz4yMDI1LTAxLTAzVDA1OjU5OjE2Wjwvd3N1OkV4cGlyZXM+XG4gICAgICAgICAgICAgIDwvd3N1OlRpbWVzdGFtcD5cbiAgICAgICAgICAgIDwvd3NzZTpTZWN1cml0eT5cbiAgICAgICAgICA8L3NvYXA6SGVhZGVyPlxuICAgICAgICAgIDxzb2FwOkJvZHk+XG4gICAgICAgICAgICA8UmV0cmlldmVSZXNwb25zZU1zZ1xuICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly9leGFjdHRhcmdldC5jb20vd3NkbC9wYXJ0bmVyQVBJXCI+XG4gICAgICAgICAgICAgIDxPdmVyYWxsU3RhdHVzPk9LPC9PdmVyYWxsU3RhdHVzPlxuICAgICAgICAgICAgICA8UmVxdWVzdElEPjVkOTE3MDhiLTI1ZDEtNGIyNy04MGEwLWRjODRlZjBhYWMwYzwvUmVxdWVzdElEPlxuICAgICAgICAgICAgICA8UmVzdWx0cyB4c2k6dHlwZT1cIkRhdGFGb2xkZXJcIj5cbiAgICAgICAgICAgICAgICA8Q2xpZW50PlxuICAgICAgICAgICAgICAgICAgPElEPjUzNDAwMzIxMDwvSUQ+XG4gICAgICAgICAgICAgICAgPC9DbGllbnQ+XG4gICAgICAgICAgICAgICAgPFBhcnRuZXJLZXkgeHNpOm5pbD1cInRydWVcIiAvPlxuICAgICAgICAgICAgICAgIDxJRD4xMTU0NjwvSUQ+XG4gICAgICAgICAgICAgICAgPE9iamVjdElEPjRmNTkxY2ExLTgyMzYtNDdiOC05MmZlLWNmMGRjZjdjZmZiNTwvT2JqZWN0SUQ+XG4gICAgICAgICAgICAgICAgPE5hbWU+bXkgZW1haWxzPC9OYW1lPlxuICAgICAgICAgICAgICAgIDxEZXNjcmlwdGlvbiAvPlxuICAgICAgICAgICAgICAgIDxDb250ZW50VHlwZT5lbWFpbDwvQ29udGVudFR5cGU+XG4gICAgICAgICAgICAgIDwvUmVzdWx0cz5cbiAgICAgICAgICAgICAgPFJlc3VsdHMgeHNpOnR5cGU9XCJEYXRhRm9sZGVyXCI+XG4gICAgICAgICAgICAgICAgPENsaWVudD5cbiAgICAgICAgICAgICAgICAgIDxJRD41MzQwMDMyMTA8L0lEPlxuICAgICAgICAgICAgICAgIDwvQ2xpZW50PlxuICAgICAgICAgICAgICAgIDxQYXJ0bmVyS2V5IHhzaTpuaWw9XCJ0cnVlXCIgLz5cbiAgICAgICAgICAgICAgICA8SUQ+MTE1NDc8L0lEPlxuICAgICAgICAgICAgICAgIDxPYmplY3RJRD42OTVkZDdjNi1kNzY0LTQ3OWQtOWU3Ny0zNmQxNDFjZGQzNDI8L09iamVjdElEPlxuICAgICAgICAgICAgICAgIDxOYW1lPnNpbXBsZSBhdXRvbWF0ZWQgZW1haWxzPC9OYW1lPlxuICAgICAgICAgICAgICAgIDxEZXNjcmlwdGlvbiAvPlxuICAgICAgICAgICAgICAgIDxDb250ZW50VHlwZT5hdXRvbWF0ZWRfZW1haWw8L0NvbnRlbnRUeXBlPlxuICAgICAgICAgICAgICA8L1Jlc3VsdHM+XG4gICAgICAgICAgICA8L1JldHJpZXZlUmVzcG9uc2VNc2c+XG4gICAgICAgICAgPC9zb2FwOkJvZHk+XG4gICAgICAgIDwvc29hcDpFbnZlbG9wZT5gO1xuICAgICAgbW9ja0FkYXB0ZXJcbiAgICAgICAgLm9uUG9zdCgnaHR0cHM6Ly9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxLnNvYXAubWFya2V0aW5nY2xvdWRhcGlzLmNvbS9TZXJ2aWNlLmFzbXgnKVxuICAgICAgICAucmVwbHkoMjAwLCB2YWxpZFJlc3BvbnNlKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNmbWNDbGllbnQuZ2V0RGF0YUZvbGRlcnMoKTtcbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHZhbGlkQXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QocmVxdWVzdFRva2VuU3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9TdHJpY3RFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICBDbGllbnQ6IHtcbiAgICAgICAgICAgIElEOiA1MzQwMDMyMTAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBDb250ZW50VHlwZTogJ2VtYWlsJyxcbiAgICAgICAgICBEZXNjcmlwdGlvbjogJycsXG4gICAgICAgICAgSUQ6IDExNTQ2LFxuICAgICAgICAgIE5hbWU6ICdteSBlbWFpbHMnLFxuICAgICAgICAgIE9iamVjdElEOiAnNGY1OTFjYTEtODIzNi00N2I4LTkyZmUtY2YwZGNmN2NmZmI1JyxcbiAgICAgICAgICBQYXJ0bmVyS2V5OiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIENsaWVudDoge1xuICAgICAgICAgICAgSUQ6IDUzNDAwMzIxMCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIENvbnRlbnRUeXBlOiAnYXV0b21hdGVkX2VtYWlsJyxcbiAgICAgICAgICBEZXNjcmlwdGlvbjogJycsXG4gICAgICAgICAgSUQ6IDExNTQ3LFxuICAgICAgICAgIE5hbWU6ICdzaW1wbGUgYXV0b21hdGVkIGVtYWlscycsXG4gICAgICAgICAgT2JqZWN0SUQ6ICc2OTVkZDdjNi1kNzY0LTQ3OWQtOWU3Ny0zNmQxNDFjZGQzNDInLFxuICAgICAgICAgIFBhcnRuZXJLZXk6ICcnLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZmFpbHVyZSBzY2VuYXJpbycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkQXV0aE9iamVjdCA9IHtcbiAgICAgICAgY2xpZW50SWQ6ICd0ZXN0LWNsaWVudCcsXG4gICAgICAgIGNsaWVudFNlY3JldDogJ3Rlc3Qtc2VjcmV0JyxcbiAgICAgICAgc3ViRG9tYWluOiAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMScsXG4gICAgICAgIGFjY2Vzc190b2tlbjogJ3ZhbGlkLXRva2VuJyxcbiAgICAgICAgZXhwaXJhdGlvbjogcHJvY2Vzcy5ocnRpbWUoKVswXSArIDM2MDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZm1jQ2xpZW50ID0gbmV3IFNGTUModmFsaWRBdXRoT2JqZWN0KTtcblxuICAgICAgamVzdC5zcHlPbih1dGlscywgJ2lzRXhwaXJlZCcpLm1vY2tSZXR1cm5WYWx1ZShmYWxzZSk7XG4gICAgICBjb25zdCByZXF1ZXN0VG9rZW5TcHkgPSBqZXN0LnNweU9uKHV0aWxzLCAnZ2V0VG9rZW4nKTtcblxuICAgICAgY29uc3QgbW9ja0FkYXB0ZXIgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gICAgICBtb2NrQWRhcHRlclxuICAgICAgICAub25Qb3N0KCdodHRwczovL2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEuc29hcC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tL1NlcnZpY2UuYXNteCcpXG4gICAgICAgIC5yZXBseShcbiAgICAgICAgICA1MDAsXG4gICAgICAgICAgYDw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cInV0Zi04XCI/PlxuICAgICAgICAgIDxzb2FwOkVudmVsb3BlIHhtbG5zOnNvYXA9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VudmVsb3BlL1wiIHhtbG5zOnhzaT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlXCIgeG1sbnM6eHNkPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWFcIiB4bWxuczp3c2E9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmdcIiB4bWxuczp3c3NlPVwiaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXNlY2V4dC0xLjAueHNkXCIgeG1sbnM6d3N1PVwiaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXV0aWxpdHktMS4wLnhzZFwiPlxuICAgICAgICAgICAgICA8c29hcDpIZWFkZXI+XG4gICAgICAgICAgICAgICAgICA8d3NhOkFjdGlvbj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmcvZmF1bHQ8L3dzYTpBY3Rpb24+XG4gICAgICAgICAgICAgICAgICA8d3NhOk1lc3NhZ2VJRD51cm46dXVpZDoxNWQzZTI4Ni05N2Y1LTRmNWMtYjBmYS1kNTg2NzM2MjE1Njg8L3dzYTpNZXNzYWdlSUQ+XG4gICAgICAgICAgICAgICAgICA8d3NhOlJlbGF0ZXNUbz51cm46dXVpZDpiMzhlZTg1Yi04ZjZiLTRlZGMtOWFiOS0yM2FiNmU1YTUxZTM8L3dzYTpSZWxhdGVzVG8+XG4gICAgICAgICAgICAgICAgICA8d3NhOlRvPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvd3NhOlRvPlxuICAgICAgICAgICAgICAgICAgPHdzc2U6U2VjdXJpdHk+XG4gICAgICAgICAgICAgICAgICAgICAgPHdzdTpUaW1lc3RhbXAgd3N1OklkPVwiVGltZXN0YW1wLWRjMDJmOGU4LWFmNzQtNDc5OS1iNWU5LTllOWMwMjk5Mjc4ZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8d3N1OkNyZWF0ZWQ+MjAyNS0wMS0wM1QwNDo1OTo0NVo8L3dzdTpDcmVhdGVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8d3N1OkV4cGlyZXM+MjAyNS0wMS0wM1QwNTowNDo0NVo8L3dzdTpFeHBpcmVzPlxuICAgICAgICAgICAgICAgICAgICAgIDwvd3N1OlRpbWVzdGFtcD5cbiAgICAgICAgICAgICAgICAgIDwvd3NzZTpTZWN1cml0eT5cbiAgICAgICAgICAgICAgPC9zb2FwOkhlYWRlcj5cbiAgICAgICAgICAgICAgPHNvYXA6Qm9keT5cbiAgICAgICAgICAgICAgICAgIDxzb2FwOkZhdWx0PlxuICAgICAgICAgICAgICAgICAgICAgIDxmYXVsdGNvZGUgeG1sbnM6cTA9XCJodHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXdzc2VjdXJpdHktc2VjZXh0LTEuMC54c2RcIj5xMDpTZWN1cml0eTwvZmF1bHRjb2RlPlxuICAgICAgICAgICAgICAgICAgICAgIDxmYXVsdHN0cmluZz5Mb2dpbiBGYWlsZWQ8L2ZhdWx0c3RyaW5nPlxuICAgICAgICAgICAgICAgICAgICAgIDxmYXVsdGFjdG9yPmh0dHBzOi8vbWN2Z2txejNjMWNocmJzejU4Nms5MHM0MWhwOC5zb2FwLm1hcmtldGluZ2Nsb3VkYXBpcy5jb20vU2VydmljZS5hc214PC9mYXVsdGFjdG9yPlxuICAgICAgICAgICAgICAgICAgPC9zb2FwOkZhdWx0PlxuICAgICAgICAgICAgICA8L3NvYXA6Qm9keT5cbiAgICAgICAgICA8L3NvYXA6RW52ZWxvcGU+YCxcbiAgICAgICAgKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNmbWNDbGllbnQuZ2V0RGF0YUZvbGRlcnMoKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZXhwZWN0KGUpLnRvRXF1YWwobmV3IEVycm9yKCdSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlIDUwMCcpKTtcbiAgICAgIH1cbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHZhbGlkQXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QocmVxdWVzdFRva2VuU3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJ2dldERhdGFFeHRlbnNpb25zJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2V0IGFsbCB0aGUgZGF0YSBleHRlbnNpb25zJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRBdXRoT2JqZWN0ID0ge1xuICAgICAgICBjbGllbnRJZDogJ3Rlc3QtY2xpZW50JyxcbiAgICAgICAgY2xpZW50U2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICBzdWJEb21haW46ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxJyxcbiAgICAgICAgYWNjZXNzX3Rva2VuOiAndmFsaWQtdG9rZW4nLFxuICAgICAgICBleHBpcmF0aW9uOiBwcm9jZXNzLmhydGltZSgpWzBdICsgMzYwMCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNmbWNDbGllbnQgPSBuZXcgU0ZNQyh2YWxpZEF1dGhPYmplY3QpO1xuXG4gICAgICBqZXN0LnNweU9uKHV0aWxzLCAnaXNFeHBpcmVkJykubW9ja1JldHVyblZhbHVlKGZhbHNlKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RUb2tlblNweSA9IGplc3Quc3B5T24odXRpbHMsICdnZXRUb2tlbicpO1xuXG4gICAgICBjb25zdCBtb2NrQWRhcHRlciA9IG5ldyBBeGlvc01vY2tBZGFwdGVyKGF4aW9zLCB7IG9uTm9NYXRjaDogJ3Rocm93RXhjZXB0aW9uJyB9KTtcbiAgICAgIGNvbnN0IHZhbGlkUmVzcG9uc2UgPSBgPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwidXRmLThcIj8+PHNvYXA6RW52ZWxvcGUgeG1sbnM6c29hcD1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvXCIgeG1sbnM6eHNpPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VcIiB4bWxuczp4c2Q9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYVwiIHhtbG5zOndzYT1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiIHhtbG5zOndzc2U9XCJodHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXdzc2VjdXJpdHktc2VjZXh0LTEuMC54c2RcIiB4bWxuczp3c3U9XCJodHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXdzc2VjdXJpdHktdXRpbGl0eS0xLjAueHNkXCI+PHNvYXA6SGVhZGVyPjx3c2E6QWN0aW9uPlJldHJpZXZlUmVzcG9uc2U8L3dzYTpBY3Rpb24+PHdzYTpNZXNzYWdlSUQ+dXJuOnV1aWQ6MDIxNGQ1OTUtMzlmMi00MmJiLWIxOGYtNzgyZTNhZWM5MTI1PC93c2E6TWVzc2FnZUlEPjx3c2E6UmVsYXRlc1RvPnVybjp1dWlkOjhjOWYxZmU2LTU4NGEtNDkyZi1hZDFlLWI2Mjg4N2U2YjI3ZDwvd3NhOlJlbGF0ZXNUbz48d3NhOlRvPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvd3NhOlRvPjx3c3NlOlNlY3VyaXR5Pjx3c3U6VGltZXN0YW1wIHdzdTpJZD1cIlRpbWVzdGFtcC03NDljNWI5MC03YzNlLTQwNWUtYTg5MS00Y2FiOWFhMzE5ZDVcIj48d3N1OkNyZWF0ZWQ+MjAyNS0wMS0wOVQxMDowMToxNVo8L3dzdTpDcmVhdGVkPjx3c3U6RXhwaXJlcz4yMDI1LTAxLTA5VDEwOjA2OjE1Wjwvd3N1OkV4cGlyZXM+PC93c3U6VGltZXN0YW1wPjwvd3NzZTpTZWN1cml0eT48L3NvYXA6SGVhZGVyPjxzb2FwOkJvZHk+PFJldHJpZXZlUmVzcG9uc2VNc2cgeG1sbnM9XCJodHRwOi8vZXhhY3R0YXJnZXQuY29tL3dzZGwvcGFydG5lckFQSVwiPjxPdmVyYWxsU3RhdHVzPk9LPC9PdmVyYWxsU3RhdHVzPjxSZXF1ZXN0SUQ+MjYxMjM4NDYtNDA0Ni00MzBiLTg5ZGMtOWU1YzJlYjU4N2ZkPC9SZXF1ZXN0SUQ+PFJlc3VsdHMgeHNpOnR5cGU9XCJEYXRhRXh0ZW5zaW9uXCI+PFBhcnRuZXJLZXkgeHNpOm5pbD1cInRydWVcIiAvPjxQYXJ0bmVyUHJvcGVydGllcz48TmFtZT5PYmplY3RJZDwvTmFtZT48VmFsdWU+YjMwZTI2ZGItNWU1OS1lZjExLWJhNmQtZjQwMzQzY2U4OWQ4PC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxQYXJ0bmVyUHJvcGVydGllcz48TmFtZT5OQU1FPC9OYW1lPjxWYWx1ZT5ydWRkZXJzdGFja1Rlc3RpbmcxMzM0MjwvVmFsdWU+PC9QYXJ0bmVyUHJvcGVydGllcz48UGFydG5lclByb3BlcnRpZXM+PE5hbWU+Q2F0ZWdvcnlJZDwvTmFtZT48VmFsdWU+MTIzNDU8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PE9iamVjdElEIHhzaTpuaWw9XCJ0cnVlXCIgLz48L1Jlc3VsdHM+PFJlc3VsdHMgeHNpOnR5cGU9XCJEYXRhRXh0ZW5zaW9uXCI+PFBhcnRuZXJLZXkgeHNpOm5pbD1cInRydWVcIiAvPjxQYXJ0bmVyUHJvcGVydGllcz48TmFtZT5PYmplY3RJZDwvTmFtZT48VmFsdWU+MTkxYzViMmEtNTdiOC1lZjExLWJhNmUtZjQwMzQzZDM4MGM4PC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxQYXJ0bmVyUHJvcGVydGllcz48TmFtZT5OQU1FPC9OYW1lPjxWYWx1ZT5UZXN0RnJvbVNESzEyMzQ8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPkNhdGVnb3J5SWQ8L05hbWU+PFZhbHVlPjEyMzQ1PC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxPYmplY3RJRCB4c2k6bmlsPVwidHJ1ZVwiIC8+PC9SZXN1bHRzPjxSZXN1bHRzIHhzaTp0eXBlPVwiRGF0YUV4dGVuc2lvblwiPjxQYXJ0bmVyS2V5IHhzaTpuaWw9XCJ0cnVlXCIgLz48UGFydG5lclByb3BlcnRpZXM+PE5hbWU+T2JqZWN0SWQ8L05hbWU+PFZhbHVlPjUwMzg1NmUzLTVhYjgtZWYxMS1iYTZlLWY0MDM0M2QzODBjODwvVmFsdWU+PC9QYXJ0bmVyUHJvcGVydGllcz48UGFydG5lclByb3BlcnRpZXM+PE5hbWU+TkFNRTwvTmFtZT48VmFsdWU+cnVkZGVyc3RhY2tUZXN0aW5nMTIxMTIwPC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxQYXJ0bmVyUHJvcGVydGllcz48TmFtZT5DYXRlZ29yeUlkPC9OYW1lPjxWYWx1ZT4xMjM0NTwvVmFsdWU+PC9QYXJ0bmVyUHJvcGVydGllcz48T2JqZWN0SUQgeHNpOm5pbD1cInRydWVcIiAvPjwvUmVzdWx0cz48UmVzdWx0cyB4c2k6dHlwZT1cIkRhdGFFeHRlbnNpb25cIj48UGFydG5lcktleSB4c2k6bmlsPVwidHJ1ZVwiIC8+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPk9iamVjdElkPC9OYW1lPjxWYWx1ZT4xNzQyZjZmMS03OWI4LWVmMTEtYmE2ZS1mNDAzNDNkMzgwYzg8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPk5BTUU8L05hbWU+PFZhbHVlPnJ1ZGRlcnN0YWNrVGVzdGluZzEyNDQyPC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxQYXJ0bmVyUHJvcGVydGllcz48TmFtZT5DYXRlZ29yeUlkPC9OYW1lPjxWYWx1ZT4xMjM0NTwvVmFsdWU+PC9QYXJ0bmVyUHJvcGVydGllcz48T2JqZWN0SUQgeHNpOm5pbD1cInRydWVcIiAvPjwvUmVzdWx0cz48UmVzdWx0cyB4c2k6dHlwZT1cIkRhdGFFeHRlbnNpb25cIj48UGFydG5lcktleSB4c2k6bmlsPVwidHJ1ZVwiIC8+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPk9iamVjdElkPC9OYW1lPjxWYWx1ZT40YmFmNGNmMS04Y2M5LWVmMTEtYmE2ZS1mNDAzNDNkMzgwYzg8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPk5BTUU8L05hbWU+PFZhbHVlPnJ1ZGRlcnN0YWNrVGVzdGluZzAyOTU8L1ZhbHVlPjwvUGFydG5lclByb3BlcnRpZXM+PFBhcnRuZXJQcm9wZXJ0aWVzPjxOYW1lPkNhdGVnb3J5SWQ8L05hbWU+PFZhbHVlPjEyMzQ1PC9WYWx1ZT48L1BhcnRuZXJQcm9wZXJ0aWVzPjxPYmplY3RJRCB4c2k6bmlsPVwidHJ1ZVwiIC8+PC9SZXN1bHRzPjwvUmV0cmlldmVSZXNwb25zZU1zZz48L3NvYXA6Qm9keT48L3NvYXA6RW52ZWxvcGU+YDtcbiAgICAgIG1vY2tBZGFwdGVyXG4gICAgICAgIC5vblBvc3QoJ2h0dHBzOi8vYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMS5zb2FwLm1hcmtldGluZ2Nsb3VkYXBpcy5jb20vU2VydmljZS5hc214JylcbiAgICAgICAgLnJlcGx5KDIwMCwgdmFsaWRSZXNwb25zZSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzZm1jQ2xpZW50LmdldERhdGFFeHRlbnNpb25zKCd2YWxpZC1mb2xkZXItaWQnKTtcbiAgICAgIGV4cGVjdCh1dGlscy5pc0V4cGlyZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHZhbGlkQXV0aE9iamVjdCk7XG4gICAgICBleHBlY3QocmVxdWVzdFRva2VuU3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9TdHJpY3RFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICBDYXRlZ29yeUlkOiAxMjM0NSxcbiAgICAgICAgICBOYW1lOiAncnVkZGVyc3RhY2tUZXN0aW5nMTMzNDInLFxuICAgICAgICAgIE9iamVjdElkOiAnYjMwZTI2ZGItNWU1OS1lZjExLWJhNmQtZjQwMzQzY2U4OWQ4JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIENhdGVnb3J5SWQ6IDEyMzQ1LFxuICAgICAgICAgIE5hbWU6ICdUZXN0RnJvbVNESzEyMzQnLFxuICAgICAgICAgIE9iamVjdElkOiAnMTkxYzViMmEtNTdiOC1lZjExLWJhNmUtZjQwMzQzZDM4MGM4JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIENhdGVnb3J5SWQ6IDEyMzQ1LFxuICAgICAgICAgIE5hbWU6ICdydWRkZXJzdGFja1Rlc3RpbmcxMjExMjAnLFxuICAgICAgICAgIE9iamVjdElkOiAnNTAzODU2ZTMtNWFiOC1lZjExLWJhNmUtZjQwMzQzZDM4MGM4JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIENhdGVnb3J5SWQ6IDEyMzQ1LFxuICAgICAgICAgIE5hbWU6ICdydWRkZXJzdGFja1Rlc3RpbmcxMjQ0MicsXG4gICAgICAgICAgT2JqZWN0SWQ6ICcxNzQyZjZmMS03OWI4LWVmMTEtYmE2ZS1mNDAzNDNkMzgwYzgnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgQ2F0ZWdvcnlJZDogMTIzNDUsXG4gICAgICAgICAgTmFtZTogJ3J1ZGRlcnN0YWNrVGVzdGluZzAyOTUnLFxuICAgICAgICAgIE9iamVjdElkOiAnNGJhZjRjZjEtOGNjOS1lZjExLWJhNmUtZjQwMzQzZDM4MGM4JyxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgaGFuZGxlIGZhaWx1cmUgc2NlbmFyaW8nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZEF1dGhPYmplY3QgPSB7XG4gICAgICAgIGNsaWVudElkOiAndGVzdC1jbGllbnQnLFxuICAgICAgICBjbGllbnRTZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgIHN1YkRvbWFpbjogJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEnLFxuICAgICAgICBhY2Nlc3NfdG9rZW46ICd2YWxpZC10b2tlbicsXG4gICAgICAgIGV4cGlyYXRpb246IHByb2Nlc3MuaHJ0aW1lKClbMF0gKyAzNjAwLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2ZtY0NsaWVudCA9IG5ldyBTRk1DKHZhbGlkQXV0aE9iamVjdCk7XG5cbiAgICAgIGplc3Quc3B5T24odXRpbHMsICdpc0V4cGlyZWQnKS5tb2NrUmV0dXJuVmFsdWUoZmFsc2UpO1xuICAgICAgY29uc3QgcmVxdWVzdFRva2VuU3B5ID0gamVzdC5zcHlPbih1dGlscywgJ2dldFRva2VuJyk7XG5cbiAgICAgIGNvbnN0IG1vY2tBZGFwdGVyID0gbmV3IEF4aW9zTW9ja0FkYXB0ZXIoYXhpb3MsIHsgb25Ob01hdGNoOiAndGhyb3dFeGNlcHRpb24nIH0pO1xuICAgICAgbW9ja0FkYXB0ZXJcbiAgICAgICAgLm9uUG9zdCgnaHR0cHM6Ly9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxLnNvYXAubWFya2V0aW5nY2xvdWRhcGlzLmNvbS9TZXJ2aWNlLmFzbXgnKVxuICAgICAgICAucmVwbHkoXG4gICAgICAgICAgNTAwLFxuICAgICAgICAgIGA8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJ1dGYtOFwiPz5cbiAgICAgICAgICA8c29hcDpFbnZlbG9wZSB4bWxuczpzb2FwPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZlbG9wZS9cIiB4bWxuczp4c2k9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZVwiIHhtbG5zOnhzZD1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hXCIgeG1sbnM6d3NhPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCIgeG1sbnM6d3NzZT1cImh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS1zZWNleHQtMS4wLnhzZFwiIHhtbG5zOndzdT1cImh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS11dGlsaXR5LTEuMC54c2RcIj5cbiAgICAgICAgICAgICAgPHNvYXA6SGVhZGVyPlxuICAgICAgICAgICAgICAgICAgPHdzYTpBY3Rpb24+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL2ZhdWx0PC93c2E6QWN0aW9uPlxuICAgICAgICAgICAgICAgICAgPHdzYTpNZXNzYWdlSUQ+dXJuOnV1aWQ6MTVkM2UyODYtOTdmNS00ZjVjLWIwZmEtZDU4NjczNjIxNTY4PC93c2E6TWVzc2FnZUlEPlxuICAgICAgICAgICAgICAgICAgPHdzYTpSZWxhdGVzVG8+dXJuOnV1aWQ6YjM4ZWU4NWItOGY2Yi00ZWRjLTlhYjktMjNhYjZlNWE1MWUzPC93c2E6UmVsYXRlc1RvPlxuICAgICAgICAgICAgICAgICAgPHdzYTpUbz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L3dzYTpUbz5cbiAgICAgICAgICAgICAgICAgIDx3c3NlOlNlY3VyaXR5PlxuICAgICAgICAgICAgICAgICAgICAgIDx3c3U6VGltZXN0YW1wIHdzdTpJZD1cIlRpbWVzdGFtcC1kYzAyZjhlOC1hZjc0LTQ3OTktYjVlOS05ZTljMDI5OTI3OGZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzdTpDcmVhdGVkPjIwMjUtMDEtMDNUMDQ6NTk6NDVaPC93c3U6Q3JlYXRlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzdTpFeHBpcmVzPjIwMjUtMDEtMDNUMDU6MDQ6NDVaPC93c3U6RXhwaXJlcz5cbiAgICAgICAgICAgICAgICAgICAgICA8L3dzdTpUaW1lc3RhbXA+XG4gICAgICAgICAgICAgICAgICA8L3dzc2U6U2VjdXJpdHk+XG4gICAgICAgICAgICAgIDwvc29hcDpIZWFkZXI+XG4gICAgICAgICAgICAgIDxzb2FwOkJvZHk+XG4gICAgICAgICAgICAgICAgICA8c29hcDpGYXVsdD5cbiAgICAgICAgICAgICAgICAgICAgICA8ZmF1bHRjb2RlIHhtbG5zOnEwPVwiaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXNlY2V4dC0xLjAueHNkXCI+cTA6U2VjdXJpdHk8L2ZhdWx0Y29kZT5cbiAgICAgICAgICAgICAgICAgICAgICA8ZmF1bHRzdHJpbmc+TG9naW4gRmFpbGVkPC9mYXVsdHN0cmluZz5cbiAgICAgICAgICAgICAgICAgICAgICA8ZmF1bHRhY3Rvcj5odHRwczovL21jdmdrcXozYzFjaHJic3o1ODZrOTBzNDFocDguc29hcC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tL1NlcnZpY2UuYXNteDwvZmF1bHRhY3Rvcj5cbiAgICAgICAgICAgICAgICAgIDwvc29hcDpGYXVsdD5cbiAgICAgICAgICAgICAgPC9zb2FwOkJvZHk+XG4gICAgICAgICAgPC9zb2FwOkVudmVsb3BlPmAsXG4gICAgICAgICk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZm1jQ2xpZW50LmdldERhdGFFeHRlbnNpb25zKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGV4cGVjdChlKS50b0VxdWFsKG5ldyBFcnJvcignUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSA1MDAnKSk7XG4gICAgICB9XG4gICAgICBleHBlY3QodXRpbHMuaXNFeHBpcmVkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh2YWxpZEF1dGhPYmplY3QpO1xuICAgICAgZXhwZWN0KHJlcXVlc3RUb2tlblNweSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==