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