@rudderstack/integrations-lib 0.2.13 → 0.2.15
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.
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -1
- package/build/sdks/customerio_audience/index.d.ts +28 -0
- package/build/sdks/customerio_audience/index.d.ts.map +1 -0
- package/build/sdks/customerio_audience/index.js +64 -0
- package/build/sdks/customerio_audience/index.test.d.ts +2 -0
- package/build/sdks/customerio_audience/index.test.d.ts.map +1 -0
- package/build/sdks/customerio_audience/index.test.js +182 -0
- package/build/sdks/customerio_audience/type.d.ts +36 -0
- package/build/sdks/customerio_audience/type.d.ts.map +1 -0
- package/build/sdks/customerio_audience/type.js +3 -0
- package/build/sdks/customerio_audience/utils.d.ts +5 -0
- package/build/sdks/customerio_audience/utils.d.ts.map +1 -0
- package/build/sdks/customerio_audience/utils.js +11 -0
- package/build/sdks/index.d.ts +4 -0
- package/build/sdks/index.d.ts.map +1 -0
- package/build/sdks/index.js +11 -0
- package/build/sdks/sfmc/index.d.ts +47 -0
- package/build/sdks/sfmc/index.d.ts.map +1 -0
- package/build/sdks/sfmc/index.js +262 -0
- package/build/sdks/sfmc/index.test.d.ts +2 -0
- package/build/sdks/sfmc/index.test.d.ts.map +1 -0
- package/build/sdks/sfmc/index.test.js +741 -0
- package/build/sdks/sfmc/type.d.ts +111 -0
- package/build/sdks/sfmc/type.d.ts.map +1 -0
- package/build/sdks/sfmc/type.js +3 -0
- package/build/sdks/sfmc/utils.d.ts +25 -0
- package/build/sdks/sfmc/utils.d.ts.map +1 -0
- package/build/sdks/sfmc/utils.js +93 -0
- package/build/sdks/sfmc/utils.test.d.ts +2 -0
- package/build/sdks/sfmc/utils.test.d.ts.map +1 -0
- package/build/sdks/sfmc/utils.test.js +32 -0
- package/package.json +3 -2
|
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZGtzL3NmbWMvaW5kZXgudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLDRFQUFrRDtBQUNsRCx5Q0FBcUI7QUFDckIsK0NBQWlDO0FBRWpDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO0lBQ3BCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLEVBQUU7UUFDOUIsRUFBRSxDQUFDLDZEQUE2RCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzNFLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixRQUFRLEVBQUUsYUFBYTtnQkFDdkIsWUFBWSxFQUFFLGFBQWE7Z0JBQzNCLFNBQVMsRUFBRSw4QkFBOEI7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhO2dCQUMzQixVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7YUFDdkMsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO1lBRXhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN0RCxNQUFNLE1BQU0sR0FBRyxNQUFNLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUVqRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsb0JBQW9CLENBQUMsZUFBZSxD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QUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCBBeGlvc01vY2tBZGFwdGVyIGZyb20gJ2F4aW9zLW1vY2stYWRhcHRlcic7XG5pbXBvcnQgU0ZNQyBmcm9tICcuJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5kZXNjcmliZSgnc2ZtYycsICgpID0+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==
|