oxygen-cli 1.37.8 → 1.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/core/OxygenCore.js +8 -2
- package/build/core/OxygenEvents.js +4 -2
- package/build/lib/cli-util.js +26 -6
- package/build/lib/cli.js +12 -2
- package/build/lib/util.js +2 -2
- package/build/model/suite-result.js +2 -1
- package/build/ox_modules/module-web.js +12 -7
- package/build/ox_reporters/reporter-rp.js +376 -0
- package/build/reporter/ReportAggregator.js +110 -43
- package/build/reporter/ReporterBase.js +2 -2
- package/build/reporter/WebSocketReporter.js +136 -0
- package/build/runners/oxygen/index.js +37 -22
- package/package.json +3 -1
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
require("source-map-support/register");
|
|
9
|
+
|
|
10
|
+
var _ReporterBase = _interopRequireDefault(require("../reporter/ReporterBase"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
const RPClient = require('@oxygenhq/rp-client-javascript');
|
|
15
|
+
|
|
16
|
+
const LAUNCH_MODES = {
|
|
17
|
+
DEFAULT: 'DEFAULT',
|
|
18
|
+
DEBUG: 'DEBUG'
|
|
19
|
+
};
|
|
20
|
+
const TEST_ITEM_TYPES = {
|
|
21
|
+
SUITE: 'SUITE',
|
|
22
|
+
TEST: 'TEST',
|
|
23
|
+
STEP: 'STEP'
|
|
24
|
+
};
|
|
25
|
+
const MAX_NAME_LENGTH = 128;
|
|
26
|
+
|
|
27
|
+
class ReportPortalReporter extends _ReporterBase.default {
|
|
28
|
+
constructor(options, reporterOpts, aggregator) {
|
|
29
|
+
super(options);
|
|
30
|
+
this.reporterOpts = reporterOpts || options.rp;
|
|
31
|
+
this.reportSteps = reporterOpts.reportSteps || false;
|
|
32
|
+
this.reportLogs = reporterOpts.reportLogs || false;
|
|
33
|
+
this.cbSuiteToRpIdHash = {};
|
|
34
|
+
this.cbCaseToRpIdHash = {};
|
|
35
|
+
this.cbStepToRpIdHash = {};
|
|
36
|
+
|
|
37
|
+
if (!this.reporterOpts || !this.reporterOpts.apiKey || !this.reporterOpts.endpoint || !this.reporterOpts.project) {
|
|
38
|
+
throw new Error('ReportPortal options are missing in oxygen.conf file.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.aggregator = aggregator;
|
|
42
|
+
this.rpClient = new RPClient({
|
|
43
|
+
launch: this.reporterOpts.launch || this.options.name,
|
|
44
|
+
...this.reporterOpts
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async init() {
|
|
49
|
+
try {
|
|
50
|
+
await this.rpClient.checkConnect();
|
|
51
|
+
} catch (e) {
|
|
52
|
+
throw new Error(`RP - Error connecting to the server: ${e.message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async generate(results) {}
|
|
57
|
+
|
|
58
|
+
async onRunnerStart({
|
|
59
|
+
rid,
|
|
60
|
+
opts,
|
|
61
|
+
caps
|
|
62
|
+
}) {
|
|
63
|
+
const {
|
|
64
|
+
tempId,
|
|
65
|
+
promise
|
|
66
|
+
} = this.rpClient.startLaunch({
|
|
67
|
+
mode: this.reporterOpts.mode || LAUNCH_MODES.DEFAULT,
|
|
68
|
+
debug: false
|
|
69
|
+
});
|
|
70
|
+
this.tempLaunchId = tempId;
|
|
71
|
+
promise.then(response => {}, error => {
|
|
72
|
+
console.dir(`RP - Error at the start of launch: ${error}`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async onRunnerEnd({
|
|
77
|
+
rid,
|
|
78
|
+
result
|
|
79
|
+
}) {
|
|
80
|
+
const {
|
|
81
|
+
promise
|
|
82
|
+
} = await this.rpClient.finishLaunch(this.tempLaunchId, {
|
|
83
|
+
status: result.status.toLowerCase()
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await this.promiseWithTimeout(promise);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.dir(`RP - Failed to end launch: ${e}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async onSuiteStart({
|
|
94
|
+
rid,
|
|
95
|
+
suiteId,
|
|
96
|
+
suite: suiteDef
|
|
97
|
+
}) {
|
|
98
|
+
const startTestItemReq = {
|
|
99
|
+
name: suiteDef.name || this.options.name,
|
|
100
|
+
type: TEST_ITEM_TYPES.SUITE
|
|
101
|
+
};
|
|
102
|
+
const {
|
|
103
|
+
tempId,
|
|
104
|
+
promise
|
|
105
|
+
} = this.rpClient.startTestItem(startTestItemReq, this.tempLaunchId);
|
|
106
|
+
this.cbSuiteToRpIdHash[suiteId] = tempId;
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
await this.promiseWithTimeout(promise);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
console.dir(`RP - Failed to start suite item: ${e}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async onSuiteEnd({
|
|
116
|
+
rid,
|
|
117
|
+
suiteId,
|
|
118
|
+
result
|
|
119
|
+
}) {
|
|
120
|
+
if (!this.cbSuiteToRpIdHash[suiteId]) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const rpSuiteId = this.cbSuiteToRpIdHash[suiteId];
|
|
125
|
+
const finishTestItemReq = {
|
|
126
|
+
status: result.status.toLowerCase()
|
|
127
|
+
};
|
|
128
|
+
const {
|
|
129
|
+
promise
|
|
130
|
+
} = this.rpClient.finishTestItem(rpSuiteId, finishTestItemReq);
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
await this.promiseWithTimeout(promise);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.dir(`RP - Failed to finish suite item: ${e}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async onCaseStart({
|
|
140
|
+
rid,
|
|
141
|
+
suiteId,
|
|
142
|
+
caseId,
|
|
143
|
+
'case': caseDef
|
|
144
|
+
}) {
|
|
145
|
+
const startTestItemReq = {
|
|
146
|
+
name: caseDef.name,
|
|
147
|
+
type: TEST_ITEM_TYPES.TEST,
|
|
148
|
+
codeRef: caseDef.path
|
|
149
|
+
};
|
|
150
|
+
const rpSuiteId = this.cbSuiteToRpIdHash[suiteId];
|
|
151
|
+
|
|
152
|
+
if (!rpSuiteId) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const {
|
|
157
|
+
tempId,
|
|
158
|
+
promise
|
|
159
|
+
} = this.rpClient.startTestItem(startTestItemReq, this.tempLaunchId, rpSuiteId);
|
|
160
|
+
this.cbCaseToRpIdHash[caseId] = tempId;
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
await this.promiseWithTimeout(promise);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.dir(`RP - Failed to start test item: ${e}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async onCaseEnd({
|
|
170
|
+
rid,
|
|
171
|
+
suiteId,
|
|
172
|
+
caseId,
|
|
173
|
+
result
|
|
174
|
+
}) {
|
|
175
|
+
const rpTestId = this.cbCaseToRpIdHash[caseId];
|
|
176
|
+
|
|
177
|
+
if (!rpTestId) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const status = result.status.toLowerCase();
|
|
182
|
+
|
|
183
|
+
if (status === 'failed' && result.failure) {
|
|
184
|
+
const rpFile = result.screenshot ? {
|
|
185
|
+
name: 'screenshot',
|
|
186
|
+
type: 'image/png',
|
|
187
|
+
content: result.screenshot
|
|
188
|
+
} : undefined;
|
|
189
|
+
const logReq = {
|
|
190
|
+
message: result.failure.message,
|
|
191
|
+
level: 'error'
|
|
192
|
+
};
|
|
193
|
+
const {
|
|
194
|
+
promise: sendLogPromise
|
|
195
|
+
} = rpFile ? this.rpClient.sendLogWithFile(rpTestId, logReq, rpFile) : this.rpClient.sendLog(rpTestId, logReq);
|
|
196
|
+
await this.promiseWithTimeout(sendLogPromise);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const finishTestItemReq = {
|
|
200
|
+
status: result.status.toLowerCase()
|
|
201
|
+
};
|
|
202
|
+
const {
|
|
203
|
+
promise
|
|
204
|
+
} = this.rpClient.finishTestItem(rpTestId, finishTestItemReq);
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
await this.promiseWithTimeout(promise);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
console.dir(`RP - Failed to finish test item: ${e}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async onStepStart({
|
|
214
|
+
rid,
|
|
215
|
+
caseId,
|
|
216
|
+
step
|
|
217
|
+
}) {
|
|
218
|
+
if (!this.reportSteps) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const rpCaseId = this.cbCaseToRpIdHash[caseId];
|
|
223
|
+
|
|
224
|
+
if (!rpCaseId) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const stepName = this._getStepName(step);
|
|
229
|
+
|
|
230
|
+
const startTestItemReq = {
|
|
231
|
+
name: stepName,
|
|
232
|
+
type: TEST_ITEM_TYPES.STEP,
|
|
233
|
+
codeRef: step.location,
|
|
234
|
+
testCaseId: rpCaseId,
|
|
235
|
+
hasStats: false
|
|
236
|
+
};
|
|
237
|
+
const {
|
|
238
|
+
tempId,
|
|
239
|
+
promise
|
|
240
|
+
} = this.rpClient.startTestItem(startTestItemReq, this.tempLaunchId, rpCaseId);
|
|
241
|
+
this.cbStepToRpIdHash[step.id] = tempId;
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
await this.promiseWithTimeout(promise);
|
|
245
|
+
} catch (e) {
|
|
246
|
+
console.dir(`RP - Failed to start step item: ${e}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async onStepEnd({
|
|
251
|
+
rid,
|
|
252
|
+
step: result
|
|
253
|
+
}) {
|
|
254
|
+
if (!this.reportSteps) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const rpStepId = this.cbStepToRpIdHash[result.id];
|
|
259
|
+
|
|
260
|
+
if (!rpStepId) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const status = result.status.toLowerCase();
|
|
265
|
+
|
|
266
|
+
if (status === 'failed' && result.failure) {
|
|
267
|
+
const rpFile = result.screenshot ? {
|
|
268
|
+
name: 'screenshot',
|
|
269
|
+
type: 'image/png',
|
|
270
|
+
content: result.screenshot
|
|
271
|
+
} : undefined;
|
|
272
|
+
const logReq = {
|
|
273
|
+
message: result.failure.message,
|
|
274
|
+
level: 'error',
|
|
275
|
+
file: rpFile
|
|
276
|
+
};
|
|
277
|
+
const {
|
|
278
|
+
promise: sendLogPromise
|
|
279
|
+
} = this.rpClient.sendLog(rpStepId, logReq, rpFile);
|
|
280
|
+
await this.promiseWithTimeout(sendLogPromise);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const finishTestItemReq = {
|
|
284
|
+
status: result.status.toLowerCase()
|
|
285
|
+
};
|
|
286
|
+
const {
|
|
287
|
+
promise
|
|
288
|
+
} = this.rpClient.finishTestItem(rpStepId, finishTestItemReq);
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
await this.promiseWithTimeout(promise);
|
|
292
|
+
} catch (e) {
|
|
293
|
+
console.dir(`RP - Failed to finish step item: ${e}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async onLog({
|
|
298
|
+
suiteId,
|
|
299
|
+
caseId,
|
|
300
|
+
stepId,
|
|
301
|
+
level,
|
|
302
|
+
msg,
|
|
303
|
+
time,
|
|
304
|
+
src
|
|
305
|
+
}) {
|
|
306
|
+
if (!this.reportLogs) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (!this.tempLaunchId) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const rpParentId = stepId ? this.cbStepToRpIdHash[stepId] : caseId ? this.cbCaseToRpIdHash[caseId] : suiteId ? this.cbSuiteToRpIdHash[suiteId] : undefined;
|
|
315
|
+
|
|
316
|
+
const rpLevel = this._getRpLevel(level);
|
|
317
|
+
|
|
318
|
+
const logReq = {
|
|
319
|
+
message: msg,
|
|
320
|
+
level: rpLevel,
|
|
321
|
+
time: time
|
|
322
|
+
};
|
|
323
|
+
const {
|
|
324
|
+
promise
|
|
325
|
+
} = this.rpClient.sendLog(rpParentId || this.tempLaunchId, logReq);
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
await this.promiseWithTimeout(promise);
|
|
329
|
+
} catch (e) {
|
|
330
|
+
console.dir(`RP - Failed to create log item: ${e}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
_getRpLevel(oxLevel) {
|
|
335
|
+
if (oxLevel) {
|
|
336
|
+
return oxLevel.toLowerCase();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return 'info';
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
_getStepName(step) {
|
|
343
|
+
let name;
|
|
344
|
+
|
|
345
|
+
if (step.name === 'transaction' && step.args.length > 0) {
|
|
346
|
+
name = step.args[0];
|
|
347
|
+
} else if (step.signature) {
|
|
348
|
+
name = step.signature;
|
|
349
|
+
} else if (step.module) {
|
|
350
|
+
name = `${step.module}.${step.name}`;
|
|
351
|
+
} else {
|
|
352
|
+
name = step.name;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
356
|
+
name = name.substring(0, MAX_NAME_LENGTH - 3) + '...';
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return name;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
promiseWithTimeout(promise, timeout = 10 * 1000) {
|
|
363
|
+
return new Promise((resolve, reject) => {
|
|
364
|
+
if (!promise || !promise.then) {
|
|
365
|
+
reject();
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
promise.then(resolve, reject);
|
|
369
|
+
setTimeout(reject, timeout);
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
exports.default = ReportPortalReporter;
|
|
376
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9veF9yZXBvcnRlcnMvcmVwb3J0ZXItcnAuanMiXSwibmFtZXMiOlsiUlBDbGllbnQiLCJyZXF1aXJlIiwiTEFVTkNIX01PREVTIiwiREVGQVVMVCIsIkRFQlVHIiwiVEVTVF9JVEVNX1RZUEVTIiwiU1VJVEUiLCJURVNUIiwiU1RFUCIsIk1BWF9OQU1FX0xFTkdUSCIsIlJlcG9ydFBvcnRhbFJlcG9ydGVyIiwiUmVwb3J0ZXJCYXNlIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwicmVwb3J0ZXJPcHRzIiwiYWdncmVnYXRvciIsInJwIiwicmVwb3J0U3RlcHMiLCJyZXBvcnRMb2dzIiwiY2JTdWl0ZVRvUnBJZEhhc2giLCJjYkNhc2VUb1JwSWRIYXNoIiwiY2JTdGVwVG9ScElkSGFzaCIsImFwaUtleSIsImVuZHBvaW50IiwicHJvamVjdCIsIkVycm9yIiwicnBDbGllbnQiLCJsYXVuY2giLCJuYW1lIiwiaW5pdCIsImNoZWNrQ29ubmVjdCIsImUiLCJtZXNzYWdlIiwiZ2VuZXJhdGUiLCJyZXN1bHRzIiwib25SdW5uZXJTdGFydCIsInJpZCIsIm9wdHMiLCJjYXBzIiwidGVtcElkIiwicHJvbWlzZSIsInN0YXJ0TGF1bmNoIiwibW9kZSIsImRlYnVnIiwidGVtcExhdW5jaElkIiwidGhlbiIsInJlc3BvbnNlIiwiZXJyb3IiLCJjb25zb2xlIiwiZGlyIiwib25SdW5uZXJFbmQiLCJyZXN1bHQiLCJmaW5pc2hMYXVuY2giLCJzdGF0dXMiLCJ0b0xvd2VyQ2FzZSIsInByb21pc2VXaXRoVGltZW91dCIsIm9uU3VpdGVTdGFydCIsInN1aXRlSWQiLCJzdWl0ZSIsInN1aXRlRGVmIiwic3RhcnRUZXN0SXRlbVJlcSIsInR5cGUiLCJzdGFydFRlc3RJdGVtIiwib25TdWl0ZUVuZCIsInJwU3VpdGVJZCIsImZpbmlzaFRlc3RJdGVtUmVxIiwiZmluaXNoVGVzdEl0ZW0iLCJvbkNhc2VTdGFydCIsImNhc2VJZCIsImNhc2VEZWYiLCJjb2RlUmVmIiwicGF0aCIsIm9uQ2FzZUVuZCIsInJwVGVzdElkIiwiZmFpbHVyZSIsInJwRmlsZSIsInNjcmVlbnNob3QiLCJjb250ZW50IiwidW5kZWZpbmVkIiwibG9nUmVxIiwibGV2ZWwiLCJzZW5kTG9nUHJvbWlzZSIsInNlbmRMb2dXaXRoRmlsZSIsInNlbmRMb2ciLCJvblN0ZXBTdGFydCIsInN0ZXAiLCJycENhc2VJZCIsInN0ZXBOYW1lIiwiX2dldFN0ZXBOYW1lIiwibG9jYXRpb24iLCJ0ZXN0Q2FzZUlkIiwiaGFzU3RhdHMiLCJpZCIsIm9uU3RlcEVuZCIsInJwU3RlcElkIiwiZmlsZSIsIm9uTG9nIiwic3RlcElkIiwibXNnIiwidGltZSIsInNyYyIsInJwUGFyZW50SWQiLCJycExldmVsIiwiX2dldFJwTGV2ZWwiLCJveExldmVsIiwiYXJncyIsImxlbmd0aCIsInNpZ25hdHVyZSIsIm1vZHVsZSIsInN1YnN0cmluZyIsInRpbWVvdXQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInNldFRpbWVvdXQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQVlBOzs7O0FBQ0EsTUFBTUEsUUFBUSxHQUFHQyxPQUFPLENBQUMsZ0NBQUQsQ0FBeEI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHO0FBQ2pCQyxFQUFBQSxPQUFPLEVBQUUsU0FEUTtBQUVqQkMsRUFBQUEsS0FBSyxFQUFFO0FBRlUsQ0FBckI7QUFJQSxNQUFNQyxlQUFlLEdBQUc7QUFDcEJDLEVBQUFBLEtBQUssRUFBRSxPQURhO0FBRXBCQyxFQUFBQSxJQUFJLEVBQUUsTUFGYztBQUdwQkMsRUFBQUEsSUFBSSxFQUFFO0FBSGMsQ0FBeEI7QUFLQSxNQUFNQyxlQUFlLEdBQUcsR0FBeEI7O0FBRWUsTUFBTUMsb0JBQU4sU0FBbUNDLHFCQUFuQyxDQUFnRDtBQUMzREMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLFlBQVYsRUFBd0JDLFVBQXhCLEVBQW9DO0FBQzNDLFVBQU1GLE9BQU47QUFDQSxTQUFLQyxZQUFMLEdBQW9CQSxZQUFZLElBQUlELE9BQU8sQ0FBQ0csRUFBNUM7QUFDQSxTQUFLQyxXQUFMLEdBQW1CSCxZQUFZLENBQUNHLFdBQWIsSUFBNEIsS0FBL0M7QUFDQSxTQUFLQyxVQUFMLEdBQWtCSixZQUFZLENBQUNJLFVBQWIsSUFBMkIsS0FBN0M7QUFDQSxTQUFLQyxpQkFBTCxHQUF5QixFQUF6QjtBQUNBLFNBQUtDLGdCQUFMLEdBQXdCLEVBQXhCO0FBQ0EsU0FBS0MsZ0JBQUwsR0FBd0IsRUFBeEI7O0FBQ0EsUUFDSSxDQUFDLEtBQUtQLFlBQU4sSUFDRyxDQUFDLEtBQUtBLFlBQUwsQ0FBa0JRLE1BRHRCLElBRUcsQ0FBQyxLQUFLUixZQUFMLENBQWtCUyxRQUZ0QixJQUdHLENBQUMsS0FBS1QsWUFBTCxDQUFrQlUsT0FKMUIsRUFLRTtBQUNFLFlBQU0sSUFBSUMsS0FBSixDQUFVLHVEQUFWLENBQU47QUFDSDs7QUFDRCxTQUFLVixVQUFMLEdBQWtCQSxVQUFsQjtBQUNBLFNBQUtXLFFBQUwsR0FBZ0IsSUFBSTFCLFFBQUosQ0FBYTtBQUN6QjJCLE1BQUFBLE1BQU0sRUFBRSxLQUFLYixZQUFMLENBQWtCYSxNQUFsQixJQUE0QixLQUFLZCxPQUFMLENBQWFlLElBRHhCO0FBRXpCLFNBQUcsS0FBS2Q7QUFGaUIsS0FBYixDQUFoQjtBQUlIOztBQUVTLFFBQUplLElBQUksR0FBRztBQUNULFFBQUk7QUFDQSxZQUFNLEtBQUtILFFBQUwsQ0FBY0ksWUFBZCxFQUFOO0FBQ0gsS0FGRCxDQUdBLE9BQU9DLENBQVAsRUFBVTtBQUNOLFlBQU0sSUFBSU4sS0FBSixDQUFXLHdDQUF1Q00sQ0FBQyxDQUFDQyxPQUFRLEVBQTVELENBQU47QUFDSDtBQUNKOztBQUNhLFFBQVJDLFFBQVEsQ0FBQ0MsT0FBRCxFQUFVLENBQ3ZCOztBQUVrQixRQUFiQyxhQUFhLENBQUM7QUFBRUMsSUFBQUEsR0FBRjtBQUFPQyxJQUFBQSxJQUFQO0FBQWFDLElBQUFBO0FBQWIsR0FBRCxFQUFzQjtBQUNyQyxVQUFNO0FBQUVDLE1BQUFBLE1BQUY7QUFBVUMsTUFBQUE7QUFBVixRQUFzQixLQUFLZCxRQUFMLENBQWNlLFdBQWQsQ0FBMEI7QUFDbERDLE1BQUFBLElBQUksRUFBRSxLQUFLNUIsWUFBTCxDQUFrQjRCLElBQWxCLElBQTBCeEMsWUFBWSxDQUFDQyxPQURLO0FBRWxEd0MsTUFBQUEsS0FBSyxFQUFFO0FBRjJDLEtBQTFCLENBQTVCO0FBSUEsU0FBS0MsWUFBTCxHQUFvQkwsTUFBcEI7QUFDQUMsSUFBQUEsT0FBTyxDQUFDSyxJQUFSLENBQWNDLFFBQUQsSUFBYyxDQUMxQixDQURELEVBQ0lDLEtBQUQsSUFBVztBQUNWQyxNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxzQ0FBcUNGLEtBQU0sRUFBeEQ7QUFDSCxLQUhEO0FBSUg7O0FBQ2dCLFFBQVhHLFdBQVcsQ0FBQztBQUFFZCxJQUFBQSxHQUFGO0FBQU9lLElBQUFBO0FBQVAsR0FBRCxFQUFrQjtBQUUvQixVQUFNO0FBQUVYLE1BQUFBO0FBQUYsUUFBYyxNQUFNLEtBQUtkLFFBQUwsQ0FBYzBCLFlBQWQsQ0FBMkIsS0FBS1IsWUFBaEMsRUFBOEM7QUFDcEVTLE1BQUFBLE1BQU0sRUFBRUYsTUFBTSxDQUFDRSxNQUFQLENBQWNDLFdBQWQ7QUFENEQsS0FBOUMsQ0FBMUI7O0FBR0EsUUFBSTtBQUNBLFlBQU0sS0FBS0Msa0JBQUwsQ0FBd0JmLE9BQXhCLENBQU47QUFDSCxLQUZELENBR0EsT0FBT1QsQ0FBUCxFQUFVO0FBQ05pQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSw4QkFBNkJsQixDQUFFLEVBQTVDO0FBQ0g7QUFDSjs7QUFDaUIsUUFBWnlCLFlBQVksQ0FBQztBQUFFcEIsSUFBQUEsR0FBRjtBQUFPcUIsSUFBQUEsT0FBUDtBQUFnQkMsSUFBQUEsS0FBSyxFQUFFQztBQUF2QixHQUFELEVBQW9DO0FBQ2xELFVBQU1DLGdCQUFnQixHQUFHO0FBQ3JCaEMsTUFBQUEsSUFBSSxFQUFFK0IsUUFBUSxDQUFDL0IsSUFBVCxJQUFpQixLQUFLZixPQUFMLENBQWFlLElBRGY7QUFFckJpQyxNQUFBQSxJQUFJLEVBQUV4RCxlQUFlLENBQUNDO0FBRkQsS0FBekI7QUFJQSxVQUFNO0FBQUVpQyxNQUFBQSxNQUFGO0FBQVVDLE1BQUFBO0FBQVYsUUFBc0IsS0FBS2QsUUFBTCxDQUFjb0MsYUFBZCxDQUE0QkYsZ0JBQTVCLEVBQThDLEtBQUtoQixZQUFuRCxDQUE1QjtBQUNBLFNBQUt6QixpQkFBTCxDQUF1QnNDLE9BQXZCLElBQWtDbEIsTUFBbEM7O0FBQ0EsUUFBSTtBQUNBLFlBQU0sS0FBS2dCLGtCQUFMLENBQXdCZixPQUF4QixDQUFOO0FBQ0gsS0FGRCxDQUdBLE9BQU9ULENBQVAsRUFBVTtBQUNOaUIsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQWEsb0NBQW1DbEIsQ0FBRSxFQUFsRDtBQUNIO0FBQ0o7O0FBQ2UsUUFBVmdDLFVBQVUsQ0FBQztBQUFFM0IsSUFBQUEsR0FBRjtBQUFPcUIsSUFBQUEsT0FBUDtBQUFnQk4sSUFBQUE7QUFBaEIsR0FBRCxFQUEyQjtBQUN2QyxRQUFJLENBQUMsS0FBS2hDLGlCQUFMLENBQXVCc0MsT0FBdkIsQ0FBTCxFQUFzQztBQUNsQztBQUNIOztBQUNELFVBQU1PLFNBQVMsR0FBRyxLQUFLN0MsaUJBQUwsQ0FBdUJzQyxPQUF2QixDQUFsQjtBQUNBLFVBQU1RLGlCQUFpQixHQUFHO0FBQ3RCWixNQUFBQSxNQUFNLEVBQUVGLE1BQU0sQ0FBQ0UsTUFBUCxDQUFjQyxXQUFkO0FBRGMsS0FBMUI7QUFHQSxVQUFNO0FBQUVkLE1BQUFBO0FBQUYsUUFBYyxLQUFLZCxRQUFMLENBQWN3QyxjQUFkLENBQTZCRixTQUE3QixFQUF3Q0MsaUJBQXhDLENBQXBCOztBQUNBLFFBQUk7QUFDQSxZQUFNLEtBQUtWLGtCQUFMLENBQXdCZixPQUF4QixDQUFOO0FBQ0gsS0FGRCxDQUdBLE9BQU9ULENBQVAsRUFBVTtBQUNOaUIsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQWEscUNBQW9DbEIsQ0FBRSxFQUFuRDtBQUNIO0FBQ0o7O0FBQ2dCLFFBQVhvQyxXQUFXLENBQUM7QUFBRS9CLElBQUFBLEdBQUY7QUFBT3FCLElBQUFBLE9BQVA7QUFBZ0JXLElBQUFBLE1BQWhCO0FBQXdCLFlBQVFDO0FBQWhDLEdBQUQsRUFBNEM7QUFDekQsVUFBTVQsZ0JBQWdCLEdBQUc7QUFDckJoQyxNQUFBQSxJQUFJLEVBQUV5QyxPQUFPLENBQUN6QyxJQURPO0FBRXJCaUMsTUFBQUEsSUFBSSxFQUFFeEQsZUFBZSxDQUFDRSxJQUZEO0FBR3JCK0QsTUFBQUEsT0FBTyxFQUFFRCxPQUFPLENBQUNFO0FBSEksS0FBekI7QUFLQSxVQUFNUCxTQUFTLEdBQUcsS0FBSzdDLGlCQUFMLENBQXVCc0MsT0FBdkIsQ0FBbEI7O0FBQ0EsUUFBSSxDQUFDTyxTQUFMLEVBQWdCO0FBQ1o7QUFDSDs7QUFDRCxVQUFNO0FBQUV6QixNQUFBQSxNQUFGO0FBQVVDLE1BQUFBO0FBQVYsUUFBc0IsS0FBS2QsUUFBTCxDQUFjb0MsYUFBZCxDQUE0QkYsZ0JBQTVCLEVBQThDLEtBQUtoQixZQUFuRCxFQUFpRW9CLFNBQWpFLENBQTVCO0FBQ0EsU0FBSzVDLGdCQUFMLENBQXNCZ0QsTUFBdEIsSUFBZ0M3QixNQUFoQzs7QUFDQSxRQUFJO0FBQ0EsWUFBTSxLQUFLZ0Isa0JBQUwsQ0FBd0JmLE9BQXhCLENBQU47QUFDSCxLQUZELENBR0EsT0FBT1QsQ0FBUCxFQUFVO0FBQ05pQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxtQ0FBa0NsQixDQUFFLEVBQWpEO0FBQ0g7QUFDSjs7QUFDYyxRQUFUeUMsU0FBUyxDQUFDO0FBQUVwQyxJQUFBQSxHQUFGO0FBQU9xQixJQUFBQSxPQUFQO0FBQWdCVyxJQUFBQSxNQUFoQjtBQUF3QmpCLElBQUFBO0FBQXhCLEdBQUQsRUFBbUM7QUFDOUMsVUFBTXNCLFFBQVEsR0FBRyxLQUFLckQsZ0JBQUwsQ0FBc0JnRCxNQUF0QixDQUFqQjs7QUFDQSxRQUFJLENBQUNLLFFBQUwsRUFBZTtBQUNYO0FBQ0g7O0FBQ0QsVUFBTXBCLE1BQU0sR0FBR0YsTUFBTSxDQUFDRSxNQUFQLENBQWNDLFdBQWQsRUFBZjs7QUFDQSxRQUFJRCxNQUFNLEtBQUssUUFBWCxJQUF1QkYsTUFBTSxDQUFDdUIsT0FBbEMsRUFBMkM7QUFDdkMsWUFBTUMsTUFBTSxHQUFHeEIsTUFBTSxDQUFDeUIsVUFBUCxHQUNmO0FBQ0loRCxRQUFBQSxJQUFJLEVBQUUsWUFEVjtBQUVJaUMsUUFBQUEsSUFBSSxFQUFFLFdBRlY7QUFHSWdCLFFBQUFBLE9BQU8sRUFBRTFCLE1BQU0sQ0FBQ3lCO0FBSHBCLE9BRGUsR0FLWEUsU0FMSjtBQU1BLFlBQU1DLE1BQU0sR0FBRztBQUNYL0MsUUFBQUEsT0FBTyxFQUFFbUIsTUFBTSxDQUFDdUIsT0FBUCxDQUFlMUMsT0FEYjtBQUVYZ0QsUUFBQUEsS0FBSyxFQUFFO0FBRkksT0FBZjtBQUlBLFlBQU07QUFBRXhDLFFBQUFBLE9BQU8sRUFBRXlDO0FBQVgsVUFBOEJOLE1BQU0sR0FDdEMsS0FBS2pELFFBQUwsQ0FBY3dELGVBQWQsQ0FBOEJULFFBQTlCLEVBQXdDTSxNQUF4QyxFQUFnREosTUFBaEQsQ0FEc0MsR0FFcEMsS0FBS2pELFFBQUwsQ0FBY3lELE9BQWQsQ0FBc0JWLFFBQXRCLEVBQWdDTSxNQUFoQyxDQUZOO0FBSUEsWUFBTSxLQUFLeEIsa0JBQUwsQ0FBd0IwQixjQUF4QixDQUFOO0FBQ0g7O0FBQ0QsVUFBTWhCLGlCQUFpQixHQUFHO0FBQ3RCWixNQUFBQSxNQUFNLEVBQUVGLE1BQU0sQ0FBQ0UsTUFBUCxDQUFjQyxXQUFkO0FBRGMsS0FBMUI7QUFHQSxVQUFNO0FBQUVkLE1BQUFBO0FBQUYsUUFBYyxLQUFLZCxRQUFMLENBQWN3QyxjQUFkLENBQTZCTyxRQUE3QixFQUF1Q1IsaUJBQXZDLENBQXBCOztBQUNBLFFBQUk7QUFDQSxZQUFNLEtBQUtWLGtCQUFMLENBQXdCZixPQUF4QixDQUFOO0FBQ0gsS0FGRCxDQUdBLE9BQU9ULENBQVAsRUFBVTtBQUNOaUIsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQWEsb0NBQW1DbEIsQ0FBRSxFQUFsRDtBQUNIO0FBQ0o7O0FBQ2dCLFFBQVhxRCxXQUFXLENBQUM7QUFBRWhELElBQUFBLEdBQUY7QUFBT2dDLElBQUFBLE1BQVA7QUFBZWlCLElBQUFBO0FBQWYsR0FBRCxFQUF3QjtBQUNyQyxRQUFJLENBQUMsS0FBS3BFLFdBQVYsRUFBdUI7QUFDbkI7QUFDSDs7QUFDRCxVQUFNcUUsUUFBUSxHQUFHLEtBQUtsRSxnQkFBTCxDQUFzQmdELE1BQXRCLENBQWpCOztBQUNBLFFBQUksQ0FBQ2tCLFFBQUwsRUFBZTtBQUNYO0FBQ0g7O0FBQ0QsVUFBTUMsUUFBUSxHQUFHLEtBQUtDLFlBQUwsQ0FBa0JILElBQWxCLENBQWpCOztBQUNBLFVBQU16QixnQkFBZ0IsR0FBRztBQUNyQmhDLE1BQUFBLElBQUksRUFBRTJELFFBRGU7QUFFckIxQixNQUFBQSxJQUFJLEVBQUV4RCxlQUFlLENBQUNHLElBRkQ7QUFPckI4RCxNQUFBQSxPQUFPLEVBQUVlLElBQUksQ0FBQ0ksUUFQTztBQVFyQkMsTUFBQUEsVUFBVSxFQUFFSixRQVJTO0FBU3JCSyxNQUFBQSxRQUFRLEVBQUU7QUFUVyxLQUF6QjtBQVdBLFVBQU07QUFBRXBELE1BQUFBLE1BQUY7QUFBVUMsTUFBQUE7QUFBVixRQUFzQixLQUFLZCxRQUFMLENBQWNvQyxhQUFkLENBQTRCRixnQkFBNUIsRUFBOEMsS0FBS2hCLFlBQW5ELEVBQWlFMEMsUUFBakUsQ0FBNUI7QUFDQSxTQUFLakUsZ0JBQUwsQ0FBc0JnRSxJQUFJLENBQUNPLEVBQTNCLElBQWlDckQsTUFBakM7O0FBQ0EsUUFBSTtBQUNBLFlBQU0sS0FBS2dCLGtCQUFMLENBQXdCZixPQUF4QixDQUFOO0FBQ0gsS0FGRCxDQUdBLE9BQU9ULENBQVAsRUFBVTtBQUNOaUIsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQWEsbUNBQWtDbEIsQ0FBRSxFQUFqRDtBQUNIO0FBQ0o7O0FBQ2MsUUFBVDhELFNBQVMsQ0FBQztBQUFFekQsSUFBQUEsR0FBRjtBQUFPaUQsSUFBQUEsSUFBSSxFQUFFbEM7QUFBYixHQUFELEVBQXdCO0FBQ25DLFFBQUksQ0FBQyxLQUFLbEMsV0FBVixFQUF1QjtBQUNuQjtBQUNIOztBQUNELFVBQU02RSxRQUFRLEdBQUcsS0FBS3pFLGdCQUFMLENBQXNCOEIsTUFBTSxDQUFDeUMsRUFBN0IsQ0FBakI7O0FBQ0EsUUFBSSxDQUFDRSxRQUFMLEVBQWU7QUFDWDtBQUNIOztBQUNELFVBQU16QyxNQUFNLEdBQUdGLE1BQU0sQ0FBQ0UsTUFBUCxDQUFjQyxXQUFkLEVBQWY7O0FBQ0EsUUFBSUQsTUFBTSxLQUFLLFFBQVgsSUFBdUJGLE1BQU0sQ0FBQ3VCLE9BQWxDLEVBQTJDO0FBQ3ZDLFlBQU1DLE1BQU0sR0FBR3hCLE1BQU0sQ0FBQ3lCLFVBQVAsR0FDZjtBQUNJaEQsUUFBQUEsSUFBSSxFQUFFLFlBRFY7QUFFSWlDLFFBQUFBLElBQUksRUFBRSxXQUZWO0FBR0lnQixRQUFBQSxPQUFPLEVBQUUxQixNQUFNLENBQUN5QjtBQUhwQixPQURlLEdBS1hFLFNBTEo7QUFNQSxZQUFNQyxNQUFNLEdBQUc7QUFDWC9DLFFBQUFBLE9BQU8sRUFBRW1CLE1BQU0sQ0FBQ3VCLE9BQVAsQ0FBZTFDLE9BRGI7QUFFWGdELFFBQUFBLEtBQUssRUFBRSxPQUZJO0FBR1hlLFFBQUFBLElBQUksRUFBRXBCO0FBSEssT0FBZjtBQUtBLFlBQU07QUFBRW5DLFFBQUFBLE9BQU8sRUFBRXlDO0FBQVgsVUFBOEIsS0FBS3ZELFFBQUwsQ0FBY3lELE9BQWQsQ0FBc0JXLFFBQXRCLEVBQWdDZixNQUFoQyxFQUF3Q0osTUFBeEMsQ0FBcEM7QUFDQSxZQUFNLEtBQUtwQixrQkFBTCxDQUF3QjBCLGNBQXhCLENBQU47QUFDSDs7QUFDRCxVQUFNaEIsaUJBQWlCLEdBQUc7QUFDdEJaLE1BQUFBLE1BQU0sRUFBRUYsTUFBTSxDQUFDRSxNQUFQLENBQWNDLFdBQWQ7QUFEYyxLQUExQjtBQUdBLFVBQU07QUFBRWQsTUFBQUE7QUFBRixRQUFjLEtBQUtkLFFBQUwsQ0FBY3dDLGNBQWQsQ0FBNkI0QixRQUE3QixFQUF1QzdCLGlCQUF2QyxDQUFwQjs7QUFDQSxRQUFJO0FBQ0EsWUFBTSxLQUFLVixrQkFBTCxDQUF3QmYsT0FBeEIsQ0FBTjtBQUNILEtBRkQsQ0FHQSxPQUFPVCxDQUFQLEVBQVU7QUFDTmlCLE1BQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLG9DQUFtQ2xCLENBQUUsRUFBbEQ7QUFDSDtBQUNKOztBQUNVLFFBQUxpRSxLQUFLLENBQUM7QUFBRXZDLElBQUFBLE9BQUY7QUFBV1csSUFBQUEsTUFBWDtBQUFtQjZCLElBQUFBLE1BQW5CO0FBQTJCakIsSUFBQUEsS0FBM0I7QUFBa0NrQixJQUFBQSxHQUFsQztBQUF1Q0MsSUFBQUEsSUFBdkM7QUFBNkNDLElBQUFBO0FBQTdDLEdBQUQsRUFBcUQ7QUFDNUQsUUFBSSxDQUFDLEtBQUtsRixVQUFWLEVBQXNCO0FBQ2xCO0FBQ0g7O0FBRUQsUUFBSSxDQUFDLEtBQUswQixZQUFWLEVBQXdCO0FBQ3BCO0FBQ0g7O0FBQ0QsVUFBTXlELFVBQVUsR0FBR0osTUFBTSxHQUNyQixLQUFLNUUsZ0JBQUwsQ0FBc0I0RSxNQUF0QixDQURxQixHQUVuQjdCLE1BQU0sR0FBRyxLQUFLaEQsZ0JBQUwsQ0FBc0JnRCxNQUF0QixDQUFILEdBQ05YLE9BQU8sR0FBRyxLQUFLdEMsaUJBQUwsQ0FBdUJzQyxPQUF2QixDQUFILEdBQ1BxQixTQUpOOztBQUtBLFVBQU13QixPQUFPLEdBQUcsS0FBS0MsV0FBTCxDQUFpQnZCLEtBQWpCLENBQWhCOztBQUNBLFVBQU1ELE1BQU0sR0FBRztBQUNYL0MsTUFBQUEsT0FBTyxFQUFFa0UsR0FERTtBQUVYbEIsTUFBQUEsS0FBSyxFQUFFc0IsT0FGSTtBQUdYSCxNQUFBQSxJQUFJLEVBQUVBO0FBSEssS0FBZjtBQUtBLFVBQU07QUFBRTNELE1BQUFBO0FBQUYsUUFBYyxLQUFLZCxRQUFMLENBQWN5RCxPQUFkLENBQXNCa0IsVUFBVSxJQUFJLEtBQUt6RCxZQUF6QyxFQUF1RG1DLE1BQXZELENBQXBCOztBQUNBLFFBQUk7QUFDQSxZQUFNLEtBQUt4QixrQkFBTCxDQUF3QmYsT0FBeEIsQ0FBTjtBQUNILEtBRkQsQ0FHQSxPQUFPVCxDQUFQLEVBQVU7QUFDTmlCLE1BQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLG1DQUFrQ2xCLENBQUUsRUFBakQ7QUFDSDtBQUNKOztBQUNEd0UsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVU7QUFDakIsUUFBSUEsT0FBSixFQUFhO0FBQ1QsYUFBT0EsT0FBTyxDQUFDbEQsV0FBUixFQUFQO0FBQ0g7O0FBQ0QsV0FBTyxNQUFQO0FBQ0g7O0FBZ0JEa0MsRUFBQUEsWUFBWSxDQUFDSCxJQUFELEVBQU87QUFDZixRQUFJekQsSUFBSjs7QUFFQSxRQUFJeUQsSUFBSSxDQUFDekQsSUFBTCxLQUFjLGFBQWQsSUFBK0J5RCxJQUFJLENBQUNvQixJQUFMLENBQVVDLE1BQVYsR0FBbUIsQ0FBdEQsRUFBeUQ7QUFDckQ5RSxNQUFBQSxJQUFJLEdBQUd5RCxJQUFJLENBQUNvQixJQUFMLENBQVUsQ0FBVixDQUFQO0FBQ0gsS0FGRCxNQUdLLElBQUlwQixJQUFJLENBQUNzQixTQUFULEVBQW9CO0FBQ3JCL0UsTUFBQUEsSUFBSSxHQUFHeUQsSUFBSSxDQUFDc0IsU0FBWjtBQUNILEtBRkksTUFHQSxJQUFJdEIsSUFBSSxDQUFDdUIsTUFBVCxFQUFpQjtBQUNsQmhGLE1BQUFBLElBQUksR0FBSSxHQUFFeUQsSUFBSSxDQUFDdUIsTUFBTyxJQUFHdkIsSUFBSSxDQUFDekQsSUFBSyxFQUFuQztBQUNILEtBRkksTUFHQTtBQUNEQSxNQUFBQSxJQUFJLEdBQUd5RCxJQUFJLENBQUN6RCxJQUFaO0FBQ0g7O0FBSUQsUUFBSUEsSUFBSSxDQUFDOEUsTUFBTCxHQUFjakcsZUFBbEIsRUFBbUM7QUFDL0JtQixNQUFBQSxJQUFJLEdBQUdBLElBQUksQ0FBQ2lGLFNBQUwsQ0FBZSxDQUFmLEVBQWtCcEcsZUFBZSxHQUFDLENBQWxDLElBQXVDLEtBQTlDO0FBQ0g7O0FBQ0QsV0FBT21CLElBQVA7QUFDSDs7QUFDRDJCLEVBQUFBLGtCQUFrQixDQUFDZixPQUFELEVBQVVzRSxPQUFPLEdBQUcsS0FBSyxJQUF6QixFQUErQjtBQUM3QyxXQUFPLElBQUlDLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDcEMsVUFBSSxDQUFDekUsT0FBRCxJQUFZLENBQUNBLE9BQU8sQ0FBQ0ssSUFBekIsRUFBK0I7QUFDM0JvRSxRQUFBQSxNQUFNO0FBQ1Q7O0FBQ0R6RSxNQUFBQSxPQUFPLENBQUNLLElBQVIsQ0FBYW1FLE9BQWIsRUFBc0JDLE1BQXRCO0FBQ0FDLE1BQUFBLFVBQVUsQ0FBQ0QsTUFBRCxFQUFTSCxPQUFULENBQVY7QUFDSCxLQU5NLENBQVA7QUFPSDs7QUE1UjBEIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQ29weXJpZ2h0IChDKSAyMDE1LXByZXNlbnQgQ2xvdWRCZWF0IExpbWl0ZWRcclxuICpcclxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcclxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcclxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cclxuICovXHJcblxyXG4vKlxyXG4gKiBPeHlnZW4gUmVwb3J0ZXIgZm9yIFJlcG9ydFBvcnRhbFxyXG4gKi9cclxuaW1wb3J0IFJlcG9ydGVyQmFzZSBmcm9tICcuLi9yZXBvcnRlci9SZXBvcnRlckJhc2UnO1xyXG5jb25zdCBSUENsaWVudCA9IHJlcXVpcmUoJ0BveHlnZW5ocS9ycC1jbGllbnQtamF2YXNjcmlwdCcpO1xyXG5jb25zdCBMQVVOQ0hfTU9ERVMgPSB7XHJcbiAgICBERUZBVUxUOiAnREVGQVVMVCcsXHJcbiAgICBERUJVRzogJ0RFQlVHJyxcclxufTtcclxuY29uc3QgVEVTVF9JVEVNX1RZUEVTID0ge1xyXG4gICAgU1VJVEU6ICdTVUlURScsXHJcbiAgICBURVNUOiAnVEVTVCcsXHJcbiAgICBTVEVQOiAnU1RFUCcsXHJcbn07XHJcbmNvbnN0IE1BWF9OQU1FX0xFTkdUSCA9IDEyODtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlcG9ydFBvcnRhbFJlcG9ydGVyIGV4dGVuZHMgUmVwb3J0ZXJCYXNlIHtcclxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMsIHJlcG9ydGVyT3B0cywgYWdncmVnYXRvcikge1xyXG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xyXG4gICAgICAgIHRoaXMucmVwb3J0ZXJPcHRzID0gcmVwb3J0ZXJPcHRzIHx8IG9wdGlvbnMucnA7XHJcbiAgICAgICAgdGhpcy5yZXBvcnRTdGVwcyA9IHJlcG9ydGVyT3B0cy5yZXBvcnRTdGVwcyB8fCBmYWxzZTtcclxuICAgICAgICB0aGlzLnJlcG9ydExvZ3MgPSByZXBvcnRlck9wdHMucmVwb3J0TG9ncyB8fCBmYWxzZTtcclxuICAgICAgICB0aGlzLmNiU3VpdGVUb1JwSWRIYXNoID0ge307XHJcbiAgICAgICAgdGhpcy5jYkNhc2VUb1JwSWRIYXNoID0ge307XHJcbiAgICAgICAgdGhpcy5jYlN0ZXBUb1JwSWRIYXNoID0ge307XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAhdGhpcy5yZXBvcnRlck9wdHNcclxuICAgICAgICAgICAgfHwgIXRoaXMucmVwb3J0ZXJPcHRzLmFwaUtleVxyXG4gICAgICAgICAgICB8fCAhdGhpcy5yZXBvcnRlck9wdHMuZW5kcG9pbnRcclxuICAgICAgICAgICAgfHwgIXRoaXMucmVwb3J0ZXJPcHRzLnByb2plY3RcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXBvcnRQb3J0YWwgb3B0aW9ucyBhcmUgbWlzc2luZyBpbiBveHlnZW4uY29uZiBmaWxlLicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmFnZ3JlZ2F0b3IgPSBhZ2dyZWdhdG9yO1xyXG4gICAgICAgIHRoaXMucnBDbGllbnQgPSBuZXcgUlBDbGllbnQoe1xyXG4gICAgICAgICAgICBsYXVuY2g6IHRoaXMucmVwb3J0ZXJPcHRzLmxhdW5jaCB8fCB0aGlzLm9wdGlvbnMubmFtZSxcclxuICAgICAgICAgICAgLi4udGhpcy5yZXBvcnRlck9wdHNcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBpbml0KCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucnBDbGllbnQuY2hlY2tDb25uZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUlAgLSBFcnJvciBjb25uZWN0aW5nIHRvIHRoZSBzZXJ2ZXI6ICR7ZS5tZXNzYWdlfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGFzeW5jIGdlbmVyYXRlKHJlc3VsdHMpIHtcclxuICAgIH1cclxuICAgIC8vIEV2ZW50c1xyXG4gICAgYXN5bmMgb25SdW5uZXJTdGFydCh7IHJpZCwgb3B0cywgY2FwcyB9KSB7XHJcbiAgICAgICAgY29uc3QgeyB0ZW1wSWQsIHByb21pc2UgfSA9IHRoaXMucnBDbGllbnQuc3RhcnRMYXVuY2goe1xyXG4gICAgICAgICAgICBtb2RlOiB0aGlzLnJlcG9ydGVyT3B0cy5tb2RlIHx8IExBVU5DSF9NT0RFUy5ERUZBVUxULFxyXG4gICAgICAgICAgICBkZWJ1ZzogZmFsc2UsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy50ZW1wTGF1bmNoSWQgPSB0ZW1wSWQ7XHJcbiAgICAgICAgcHJvbWlzZS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICBjb25zb2xlLmRpcihgUlAgLSBFcnJvciBhdCB0aGUgc3RhcnQgb2YgbGF1bmNoOiAke2Vycm9yfWApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgYXN5bmMgb25SdW5uZXJFbmQoeyByaWQsIHJlc3VsdCB9KSB7XHJcbiAgICAgICAgLy8gYXdhaXQgdGhpcy5ycENsaWVudC5nZXRQcm9taXNlRmluaXNoQWxsSXRlbXModGhpcy50ZW1wTGF1bmNoSWQpO1xyXG4gICAgICAgIGNvbnN0IHsgcHJvbWlzZSB9ID0gYXdhaXQgdGhpcy5ycENsaWVudC5maW5pc2hMYXVuY2godGhpcy50ZW1wTGF1bmNoSWQsIHtcclxuICAgICAgICAgICAgc3RhdHVzOiByZXN1bHQuc3RhdHVzLnRvTG93ZXJDYXNlKCksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm9taXNlV2l0aFRpbWVvdXQocHJvbWlzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZGlyKGBSUCAtIEZhaWxlZCB0byBlbmQgbGF1bmNoOiAke2V9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgYXN5bmMgb25TdWl0ZVN0YXJ0KHsgcmlkLCBzdWl0ZUlkLCBzdWl0ZTogc3VpdGVEZWYgfSkge1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0VGVzdEl0ZW1SZXEgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6IHN1aXRlRGVmLm5hbWUgfHwgdGhpcy5vcHRpb25zLm5hbWUsXHJcbiAgICAgICAgICAgIHR5cGU6IFRFU1RfSVRFTV9UWVBFUy5TVUlURSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGNvbnN0IHsgdGVtcElkLCBwcm9taXNlIH0gPSB0aGlzLnJwQ2xpZW50LnN0YXJ0VGVzdEl0ZW0oc3RhcnRUZXN0SXRlbVJlcSwgdGhpcy50ZW1wTGF1bmNoSWQpO1xyXG4gICAgICAgIHRoaXMuY2JTdWl0ZVRvUnBJZEhhc2hbc3VpdGVJZF0gPSB0ZW1wSWQ7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm9taXNlV2l0aFRpbWVvdXQocHJvbWlzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZGlyKGBSUCAtIEZhaWxlZCB0byBzdGFydCBzdWl0ZSBpdGVtOiAke2V9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgYXN5bmMgb25TdWl0ZUVuZCh7IHJpZCwgc3VpdGVJZCwgcmVzdWx0IH0pIHtcclxuICAgICAgICBpZiAoIXRoaXMuY2JTdWl0ZVRvUnBJZEhhc2hbc3VpdGVJZF0pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBycFN1aXRlSWQgPSB0aGlzLmNiU3VpdGVUb1JwSWRIYXNoW3N1aXRlSWRdO1xyXG4gICAgICAgIGNvbnN0IGZpbmlzaFRlc3RJdGVtUmVxID0ge1xyXG4gICAgICAgICAgICBzdGF0dXM6IHJlc3VsdC5zdGF0dXMudG9Mb3dlckNhc2UoKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGNvbnN0IHsgcHJvbWlzZSB9ID0gdGhpcy5ycENsaWVudC5maW5pc2hUZXN0SXRlbShycFN1aXRlSWQsIGZpbmlzaFRlc3RJdGVtUmVxKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb21pc2VXaXRoVGltZW91dChwcm9taXNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5kaXIoYFJQIC0gRmFpbGVkIHRvIGZpbmlzaCBzdWl0ZSBpdGVtOiAke2V9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgYXN5bmMgb25DYXNlU3RhcnQoeyByaWQsIHN1aXRlSWQsIGNhc2VJZCwgJ2Nhc2UnOiBjYXNlRGVmIH0pIHtcclxuICAgICAgICBjb25zdCBzdGFydFRlc3RJdGVtUmVxID0ge1xyXG4gICAgICAgICAgICBuYW1lOiBjYXNlRGVmLm5hbWUsXHJcbiAgICAgICAgICAgIHR5cGU6IFRFU1RfSVRFTV9UWVBFUy5URVNULFxyXG4gICAgICAgICAgICBjb2RlUmVmOiBjYXNlRGVmLnBhdGgsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBjb25zdCBycFN1aXRlSWQgPSB0aGlzLmNiU3VpdGVUb1JwSWRIYXNoW3N1aXRlSWRdO1xyXG4gICAgICAgIGlmICghcnBTdWl0ZUlkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgeyB0ZW1wSWQsIHByb21pc2UgfSA9IHRoaXMucnBDbGllbnQuc3RhcnRUZXN0SXRlbShzdGFydFRlc3RJdGVtUmVxLCB0aGlzLnRlbXBMYXVuY2hJZCwgcnBTdWl0ZUlkKTtcclxuICAgICAgICB0aGlzLmNiQ2FzZVRvUnBJZEhhc2hbY2FzZUlkXSA9IHRlbXBJZDtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb21pc2VXaXRoVGltZW91dChwcm9taXNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5kaXIoYFJQIC0gRmFpbGVkIHRvIHN0YXJ0IHRlc3QgaXRlbTogJHtlfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGFzeW5jIG9uQ2FzZUVuZCh7IHJpZCwgc3VpdGVJZCwgY2FzZUlkLCByZXN1bHQgfSkge1xyXG4gICAgICAgIGNvbnN0IHJwVGVzdElkID0gdGhpcy5jYkNhc2VUb1JwSWRIYXNoW2Nhc2VJZF07XHJcbiAgICAgICAgaWYgKCFycFRlc3RJZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3VsdC5zdGF0dXMudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICBpZiAoc3RhdHVzID09PSAnZmFpbGVkJyAmJiByZXN1bHQuZmFpbHVyZSkge1xyXG4gICAgICAgICAgICBjb25zdCBycEZpbGUgPSByZXN1bHQuc2NyZWVuc2hvdCA/XHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdzY3JlZW5zaG90JyxcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdpbWFnZS9wbmcnLFxyXG4gICAgICAgICAgICAgICAgY29udGVudDogcmVzdWx0LnNjcmVlbnNob3QsXHJcbiAgICAgICAgICAgIH0gOiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGxvZ1JlcSA9IHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHJlc3VsdC5mYWlsdXJlLm1lc3NhZ2UsXHJcbiAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJ1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCB7IHByb21pc2U6IHNlbmRMb2dQcm9taXNlIH0gPSBycEZpbGUgP1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ycENsaWVudC5zZW5kTG9nV2l0aEZpbGUocnBUZXN0SWQsIGxvZ1JlcSwgcnBGaWxlKVxyXG4gICAgICAgICAgICAgICAgOiB0aGlzLnJwQ2xpZW50LnNlbmRMb2cocnBUZXN0SWQsIGxvZ1JlcSk7XHJcblxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb21pc2VXaXRoVGltZW91dChzZW5kTG9nUHJvbWlzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGZpbmlzaFRlc3RJdGVtUmVxID0ge1xyXG4gICAgICAgICAgICBzdGF0dXM6IHJlc3VsdC5zdGF0dXMudG9Mb3dlckNhc2UoKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGNvbnN0IHsgcHJvbWlzZSB9ID0gdGhpcy5ycENsaWVudC5maW5pc2hUZXN0SXRlbShycFRlc3RJZCwgZmluaXNoVGVzdEl0ZW1SZXEpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucHJvbWlzZVdpdGhUaW1lb3V0KHByb21pc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmRpcihgUlAgLSBGYWlsZWQgdG8gZmluaXNoIHRlc3QgaXRlbTogJHtlfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGFzeW5jIG9uU3RlcFN0YXJ0KHsgcmlkLCBjYXNlSWQsIHN0ZXAgfSkge1xyXG4gICAgICAgIGlmICghdGhpcy5yZXBvcnRTdGVwcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJwQ2FzZUlkID0gdGhpcy5jYkNhc2VUb1JwSWRIYXNoW2Nhc2VJZF07XHJcbiAgICAgICAgaWYgKCFycENhc2VJZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHN0ZXBOYW1lID0gdGhpcy5fZ2V0U3RlcE5hbWUoc3RlcCk7XHJcbiAgICAgICAgY29uc3Qgc3RhcnRUZXN0SXRlbVJlcSA9IHtcclxuICAgICAgICAgICAgbmFtZTogc3RlcE5hbWUsXHJcbiAgICAgICAgICAgIHR5cGU6IFRFU1RfSVRFTV9UWVBFUy5TVEVQLFxyXG4gICAgICAgICAgICAvLyBcImNvZGVSZWZcIiArIFwicGFyYW1ldGVyc1wiIHVzZWQgYnkgUlAgbGliIHRvIGdlbmVyYXRlIHRlc3RDYXNlSWQgaWYgdGVzdENhc2VJZCBpcyBub3QgZGVmaW5lZFxyXG4gICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3JlcG9ydHBvcnRhbC9jbGllbnQtamF2YXNjcmlwdC9ibG9iLzQ4NmVmNzBjNjM4YTlhMjMyNjcyOTBjNjJkZjFmYWY5MDBmN2RmNmEvbGliL3JlcG9ydC1wb3J0YWwtY2xpZW50LmpzI0w0OTdcclxuICAgICAgICAgICAgLy8gdGhpcyBpcyBkaXNhYmxlZCBmb3Igbm93LiBub3Qgc3VyZSBpZiBhY3R1YWxseSBuZWVkZWQuLi5cclxuICAgICAgICAgICAgLy9wYXJhbWV0ZXJzOiB0aGlzLl9nZXRScEFyZ3Moc3RlcC5hcmdzKSxcclxuICAgICAgICAgICAgY29kZVJlZjogc3RlcC5sb2NhdGlvbixcclxuICAgICAgICAgICAgdGVzdENhc2VJZDogcnBDYXNlSWQsXHJcbiAgICAgICAgICAgIGhhc1N0YXRzOiBmYWxzZSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGNvbnN0IHsgdGVtcElkLCBwcm9taXNlIH0gPSB0aGlzLnJwQ2xpZW50LnN0YXJ0VGVzdEl0ZW0oc3RhcnRUZXN0SXRlbVJlcSwgdGhpcy50ZW1wTGF1bmNoSWQsIHJwQ2FzZUlkKTtcclxuICAgICAgICB0aGlzLmNiU3RlcFRvUnBJZEhhc2hbc3RlcC5pZF0gPSB0ZW1wSWQ7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm9taXNlV2l0aFRpbWVvdXQocHJvbWlzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZGlyKGBSUCAtIEZhaWxlZCB0byBzdGFydCBzdGVwIGl0ZW06ICR7ZX1gKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBhc3luYyBvblN0ZXBFbmQoeyByaWQsIHN0ZXA6IHJlc3VsdCB9KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnJlcG9ydFN0ZXBzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcnBTdGVwSWQgPSB0aGlzLmNiU3RlcFRvUnBJZEhhc2hbcmVzdWx0LmlkXTtcclxuICAgICAgICBpZiAoIXJwU3RlcElkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gcmVzdWx0LnN0YXR1cy50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIGlmIChzdGF0dXMgPT09ICdmYWlsZWQnICYmIHJlc3VsdC5mYWlsdXJlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJwRmlsZSA9IHJlc3VsdC5zY3JlZW5zaG90ID9cclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ3NjcmVlbnNob3QnLFxyXG4gICAgICAgICAgICAgICAgdHlwZTogJ2ltYWdlL3BuZycsXHJcbiAgICAgICAgICAgICAgICBjb250ZW50OiByZXN1bHQuc2NyZWVuc2hvdCxcclxuICAgICAgICAgICAgfSA6IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgY29uc3QgbG9nUmVxID0ge1xyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogcmVzdWx0LmZhaWx1cmUubWVzc2FnZSxcclxuICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxyXG4gICAgICAgICAgICAgICAgZmlsZTogcnBGaWxlLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCB7IHByb21pc2U6IHNlbmRMb2dQcm9taXNlIH0gPSB0aGlzLnJwQ2xpZW50LnNlbmRMb2cocnBTdGVwSWQsIGxvZ1JlcSwgcnBGaWxlKTtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm9taXNlV2l0aFRpbWVvdXQoc2VuZExvZ1Byb21pc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBmaW5pc2hUZXN0SXRlbVJlcSA9IHtcclxuICAgICAgICAgICAgc3RhdHVzOiByZXN1bHQuc3RhdHVzLnRvTG93ZXJDYXNlKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICBjb25zdCB7IHByb21pc2UgfSA9IHRoaXMucnBDbGllbnQuZmluaXNoVGVzdEl0ZW0ocnBTdGVwSWQsIGZpbmlzaFRlc3RJdGVtUmVxKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb21pc2VXaXRoVGltZW91dChwcm9taXNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5kaXIoYFJQIC0gRmFpbGVkIHRvIGZpbmlzaCBzdGVwIGl0ZW06ICR7ZX1gKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBhc3luYyBvbkxvZyh7IHN1aXRlSWQsIGNhc2VJZCwgc3RlcElkLCBsZXZlbCwgbXNnLCB0aW1lLCBzcmMgfSkge1xyXG4gICAgICAgIGlmICghdGhpcy5yZXBvcnRMb2dzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gT3h5Z2VuIG1pZ2h0IHN0YXJ0IGdlbmVyYXRpbmcgbG9ncyBiZWZvcmUgb25SdW5uZXJTdGFydCBldmVudCwgaWdub3JlIHRoZW1cclxuICAgICAgICBpZiAoIXRoaXMudGVtcExhdW5jaElkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcnBQYXJlbnRJZCA9IHN0ZXBJZCA/XHJcbiAgICAgICAgICAgIHRoaXMuY2JTdGVwVG9ScElkSGFzaFtzdGVwSWRdXHJcbiAgICAgICAgICAgIDogY2FzZUlkID8gdGhpcy5jYkNhc2VUb1JwSWRIYXNoW2Nhc2VJZF1cclxuICAgICAgICAgICAgOiBzdWl0ZUlkID8gdGhpcy5jYlN1aXRlVG9ScElkSGFzaFtzdWl0ZUlkXVxyXG4gICAgICAgICAgICA6IHVuZGVmaW5lZDtcclxuICAgICAgICBjb25zdCBycExldmVsID0gdGhpcy5fZ2V0UnBMZXZlbChsZXZlbCk7XHJcbiAgICAgICAgY29uc3QgbG9nUmVxID0ge1xyXG4gICAgICAgICAgICBtZXNzYWdlOiBtc2csXHJcbiAgICAgICAgICAgIGxldmVsOiBycExldmVsLFxyXG4gICAgICAgICAgICB0aW1lOiB0aW1lLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgY29uc3QgeyBwcm9taXNlIH0gPSB0aGlzLnJwQ2xpZW50LnNlbmRMb2cocnBQYXJlbnRJZCB8fCB0aGlzLnRlbXBMYXVuY2hJZCwgbG9nUmVxKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb21pc2VXaXRoVGltZW91dChwcm9taXNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5kaXIoYFJQIC0gRmFpbGVkIHRvIGNyZWF0ZSBsb2cgaXRlbTogJHtlfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIF9nZXRScExldmVsKG94TGV2ZWwpIHtcclxuICAgICAgICBpZiAob3hMZXZlbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gb3hMZXZlbC50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gJ2luZm8nO1xyXG4gICAgfVxyXG4gICAgLypfZ2V0UnBBcmdzKGNiQXJncykge1xyXG4gICAgICAgIGlmICghY2JBcmdzIHx8ICFjYkFyZ3MubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJwQXJncyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGk9MDsgaSA8IGNiQXJncy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBhcmcgPSBjYkFyZ3NbaV07XHJcbiAgICAgICAgICAgIGxldCBhcmdTdHIgPSB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fCBhcmcgaW5zdGFuY2VvZiBTdHJpbmcgPyBhcmcgOiBKU09OLnN0cmluZ2lmeShhcmcpO1xyXG4gICAgICAgICAgICBycEFyZ3MucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBrZXk6IGBhcmcke2l9YCxcclxuICAgICAgICAgICAgICAgIHZhbHVlOiBhcmdTdHJcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBycEFyZ3M7XHJcbiAgICB9Ki9cclxuICAgIF9nZXRTdGVwTmFtZShzdGVwKSB7XHJcbiAgICAgICAgbGV0IG5hbWU7XHJcblxyXG4gICAgICAgIGlmIChzdGVwLm5hbWUgPT09ICd0cmFuc2FjdGlvbicgJiYgc3RlcC5hcmdzLmxlbmd0aCA+IDApIHsgIC8vIEZJWE1FOiBzdGVwcyBuZWVkIHRvIGJlIG5lc3RlZCB1bmRlciB0cmFuc2FjdGlvbnNcclxuICAgICAgICAgICAgbmFtZSA9IHN0ZXAuYXJnc1swXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoc3RlcC5zaWduYXR1cmUpIHtcclxuICAgICAgICAgICAgbmFtZSA9IHN0ZXAuc2lnbmF0dXJlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChzdGVwLm1vZHVsZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRTogaXMgdGhpcyBldmVyIHJlYWNoZWQ/IFwic3RlcC5zaWduYXR1cmVcIiBzZWVtcyB0byBhbHdheXMgZXhpc3RcclxuICAgICAgICAgICAgbmFtZSA9IGAke3N0ZXAubW9kdWxlfS4ke3N0ZXAubmFtZX1gO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbmFtZSA9IHN0ZXAubmFtZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG1heGltdW0gYWxsb3dlZCBuYW1lIGxlbmd0aCBpbiBSUCBpcyAxMDI0IGJ5dGVzXHJcbiAgICAgICAgLy8gd2UgdHJ1bmNhdGUgaXQgZXZlbiBsb3dlciBzbyBpdCB3aWxsIGRpc3BsYXkgbmljZWx5XHJcbiAgICAgICAgaWYgKG5hbWUubGVuZ3RoID4gTUFYX05BTUVfTEVOR1RIKSB7XHJcbiAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygwLCBNQVhfTkFNRV9MRU5HVEgtMykgKyAnLi4uJztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5hbWU7XHJcbiAgICB9XHJcbiAgICBwcm9taXNlV2l0aFRpbWVvdXQocHJvbWlzZSwgdGltZW91dCA9IDEwICogMTAwMCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghcHJvbWlzZSB8fCAhcHJvbWlzZS50aGVuKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcclxuICAgICAgICAgICAgc2V0VGltZW91dChyZWplY3QsIHRpbWVvdXQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG4iXX0=
|