@appium/driver-test-support 0.2.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/LICENSE +201 -0
- package/README.md +112 -0
- package/build/lib/e2e-suite.d.ts +77 -0
- package/build/lib/e2e-suite.d.ts.map +1 -0
- package/build/lib/e2e-suite.js +389 -0
- package/build/lib/helpers.d.ts +19 -0
- package/build/lib/helpers.d.ts.map +1 -0
- package/build/lib/helpers.js +49 -0
- package/build/lib/index.d.ts +7 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +47 -0
- package/build/lib/unit-suite.d.ts +12 -0
- package/build/lib/unit-suite.d.ts.map +1 -0
- package/build/lib/unit-suite.js +551 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/index.js +1 -0
- package/lib/e2e-suite.js +465 -0
- package/lib/helpers.js +68 -0
- package/lib/index.js +9 -0
- package/lib/unit-suite.js +632 -0
- package/package.json +70 -0
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.driverUnitTestSuite = driverUnitTestSuite;
|
|
9
|
+
|
|
10
|
+
require("source-map-support/register");
|
|
11
|
+
|
|
12
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
13
|
+
|
|
14
|
+
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
15
|
+
|
|
16
|
+
var _sinon = require("sinon");
|
|
17
|
+
|
|
18
|
+
var _chai = _interopRequireDefault(require("chai"));
|
|
19
|
+
|
|
20
|
+
const should = _chai.default.should();
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
expect
|
|
24
|
+
} = _chai.default;
|
|
25
|
+
|
|
26
|
+
function driverUnitTestSuite(DriverClass, defaultCaps = {}) {
|
|
27
|
+
const className = DriverClass.name ?? '(unknown driver)';
|
|
28
|
+
describe(`BaseDriver unit suite (as ${className})`, function () {
|
|
29
|
+
let d;
|
|
30
|
+
let w3cCaps;
|
|
31
|
+
let sandbox;
|
|
32
|
+
beforeEach(function () {
|
|
33
|
+
sandbox = (0, _sinon.createSandbox)();
|
|
34
|
+
d = new DriverClass();
|
|
35
|
+
w3cCaps = {
|
|
36
|
+
alwaysMatch: { ...defaultCaps,
|
|
37
|
+
platformName: 'Fake',
|
|
38
|
+
'appium:deviceName': 'Commodore 64'
|
|
39
|
+
},
|
|
40
|
+
firstMatch: [{}]
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
afterEach(async function () {
|
|
44
|
+
sandbox.restore();
|
|
45
|
+
await d.deleteSession();
|
|
46
|
+
});
|
|
47
|
+
describe('static property', function () {
|
|
48
|
+
describe('baseVersion', function () {
|
|
49
|
+
it('should exist', function () {
|
|
50
|
+
DriverClass.baseVersion.should.exist;
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('Log prefix', function () {
|
|
55
|
+
it('should setup log prefix', async function () {
|
|
56
|
+
const d = new DriverClass();
|
|
57
|
+
const previousPrefix = d.log.prefix;
|
|
58
|
+
await d.createSession({
|
|
59
|
+
alwaysMatch: { ...defaultCaps,
|
|
60
|
+
platformName: 'Fake',
|
|
61
|
+
'appium:deviceName': 'Commodore 64'
|
|
62
|
+
},
|
|
63
|
+
firstMatch: [{}]
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
expect(previousPrefix).not.to.eql(d.log.prefix);
|
|
68
|
+
} finally {
|
|
69
|
+
await d.deleteSession();
|
|
70
|
+
expect(previousPrefix).to.eql(d.log.prefix);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('should return an empty status object', async function () {
|
|
75
|
+
let status = await d.getStatus();
|
|
76
|
+
status.should.eql({});
|
|
77
|
+
});
|
|
78
|
+
it('should return a sessionId from createSession', async function () {
|
|
79
|
+
let [sessId] = await d.createSession(w3cCaps);
|
|
80
|
+
should.exist(sessId);
|
|
81
|
+
sessId.should.be.a('string');
|
|
82
|
+
sessId.length.should.be.above(5);
|
|
83
|
+
});
|
|
84
|
+
it('should not be able to start two sessions without closing the first', async function () {
|
|
85
|
+
await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
86
|
+
await d.createSession(_lodash.default.cloneDeep(w3cCaps)).should.be.rejectedWith('session');
|
|
87
|
+
});
|
|
88
|
+
it('should be able to delete a session', async function () {
|
|
89
|
+
let sessionId1 = await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
90
|
+
await d.deleteSession();
|
|
91
|
+
should.equal(d.sessionId, null);
|
|
92
|
+
let sessionId2 = await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
93
|
+
sessionId1.should.not.eql(sessionId2);
|
|
94
|
+
});
|
|
95
|
+
it('should get the current session', async function () {
|
|
96
|
+
let [, caps] = await d.createSession(w3cCaps);
|
|
97
|
+
caps.should.equal(await d.getSession());
|
|
98
|
+
});
|
|
99
|
+
it('should return sessions if no session exists', async function () {
|
|
100
|
+
let sessions = await d.getSessions();
|
|
101
|
+
sessions.length.should.equal(0);
|
|
102
|
+
});
|
|
103
|
+
it('should return sessions', async function () {
|
|
104
|
+
const caps = _lodash.default.cloneDeep(w3cCaps);
|
|
105
|
+
|
|
106
|
+
await d.createSession(caps);
|
|
107
|
+
let sessions = await d.getSessions();
|
|
108
|
+
sessions.length.should.equal(1);
|
|
109
|
+
sessions[0].should.include({
|
|
110
|
+
id: d.sessionId
|
|
111
|
+
});
|
|
112
|
+
sessions[0].capabilities.should.include({
|
|
113
|
+
deviceName: 'Commodore 64',
|
|
114
|
+
platformName: 'Fake'
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
it('should fulfill an unexpected driver quit promise', async function () {
|
|
118
|
+
sandbox.stub(d, 'getStatus').callsFake(async () => {
|
|
119
|
+
await _bluebird.default.delay(1000);
|
|
120
|
+
return 'good status';
|
|
121
|
+
});
|
|
122
|
+
let cmdPromise = d.executeCommand('getStatus');
|
|
123
|
+
await _bluebird.default.delay(10);
|
|
124
|
+
const p = new _bluebird.default((resolve, reject) => {
|
|
125
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
126
|
+
d.onUnexpectedShutdown(resolve);
|
|
127
|
+
});
|
|
128
|
+
d.startUnexpectedShutdown(new Error('We crashed'));
|
|
129
|
+
await cmdPromise.should.be.rejectedWith(/We crashed/);
|
|
130
|
+
await p;
|
|
131
|
+
});
|
|
132
|
+
it('should not allow commands in middle of unexpected shutdown', async function () {
|
|
133
|
+
sandbox.stub(d, 'deleteSession').callsFake(async function () {
|
|
134
|
+
await _bluebird.default.delay(100);
|
|
135
|
+
DriverClass.prototype.deleteSession.call(this);
|
|
136
|
+
});
|
|
137
|
+
await d.createSession(w3cCaps);
|
|
138
|
+
const p = new _bluebird.default((resolve, reject) => {
|
|
139
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
140
|
+
d.onUnexpectedShutdown(resolve);
|
|
141
|
+
});
|
|
142
|
+
d.startUnexpectedShutdown(new Error('We crashed'));
|
|
143
|
+
await p;
|
|
144
|
+
await d.executeCommand('getSession').should.be.rejectedWith(/shut down/);
|
|
145
|
+
});
|
|
146
|
+
it('should allow new commands after done shutting down', async function () {
|
|
147
|
+
sandbox.stub(d, 'deleteSession').callsFake(async function () {
|
|
148
|
+
await _bluebird.default.delay(100);
|
|
149
|
+
DriverClass.prototype.deleteSession.call(this);
|
|
150
|
+
});
|
|
151
|
+
await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
152
|
+
const p = new _bluebird.default((resolve, reject) => {
|
|
153
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
154
|
+
d.onUnexpectedShutdown(resolve);
|
|
155
|
+
});
|
|
156
|
+
d.startUnexpectedShutdown(new Error('We crashed'));
|
|
157
|
+
await p;
|
|
158
|
+
await d.executeCommand('getSession').should.be.rejectedWith(/shut down/);
|
|
159
|
+
await _bluebird.default.delay(500);
|
|
160
|
+
await d.executeCommand('createSession', null, null, _lodash.default.cloneDeep(w3cCaps));
|
|
161
|
+
await d.deleteSession();
|
|
162
|
+
});
|
|
163
|
+
it('should distinguish between W3C and JSONWP session', async function () {
|
|
164
|
+
await d.executeCommand('createSession', null, null, {
|
|
165
|
+
alwaysMatch: { ...defaultCaps,
|
|
166
|
+
platformName: 'Fake',
|
|
167
|
+
'appium:deviceName': 'Commodore 64'
|
|
168
|
+
},
|
|
169
|
+
firstMatch: [{}]
|
|
170
|
+
});
|
|
171
|
+
expect(d.protocol).to.equal('W3C');
|
|
172
|
+
});
|
|
173
|
+
describe('protocol detection', function () {
|
|
174
|
+
it('should use W3C if only W3C caps are provided', async function () {
|
|
175
|
+
await d.createSession({
|
|
176
|
+
alwaysMatch: _lodash.default.clone(defaultCaps),
|
|
177
|
+
firstMatch: [{}]
|
|
178
|
+
});
|
|
179
|
+
expect(d.protocol).to.equal('W3C');
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
it('should have a method to get driver for a session', async function () {
|
|
183
|
+
let [sessId] = await d.createSession(w3cCaps);
|
|
184
|
+
expect(d.driverForSession(sessId)).to.eql(d);
|
|
185
|
+
});
|
|
186
|
+
describe('command queue', function () {
|
|
187
|
+
let d;
|
|
188
|
+
let waitMs = 10;
|
|
189
|
+
beforeEach(function () {
|
|
190
|
+
d = new DriverClass();
|
|
191
|
+
sandbox.stub(d, 'getStatus').callsFake(async () => {
|
|
192
|
+
await _bluebird.default.delay(waitMs);
|
|
193
|
+
return Date.now();
|
|
194
|
+
});
|
|
195
|
+
sandbox.stub(d, 'getSessions').callsFake(async () => {
|
|
196
|
+
await _bluebird.default.delay(waitMs);
|
|
197
|
+
throw new Error('multipass');
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
afterEach(async function () {
|
|
201
|
+
await d.clearNewCommandTimeout();
|
|
202
|
+
});
|
|
203
|
+
it('should queue commands and.executeCommand/respond in the order received', async function () {
|
|
204
|
+
let numCmds = 10;
|
|
205
|
+
let cmds = [];
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < numCmds; i++) {
|
|
208
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let results = await _bluebird.default.all(cmds);
|
|
212
|
+
|
|
213
|
+
for (let i = 1; i < numCmds; i++) {
|
|
214
|
+
if (results[i] <= results[i - 1]) {
|
|
215
|
+
throw new Error('Got result out of order');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
it('should handle errors correctly when queuing', async function () {
|
|
220
|
+
let numCmds = 10;
|
|
221
|
+
let cmds = [];
|
|
222
|
+
|
|
223
|
+
for (let i = 0; i < numCmds; i++) {
|
|
224
|
+
if (i === 5) {
|
|
225
|
+
cmds.push(d.executeCommand('getSessions'));
|
|
226
|
+
} else {
|
|
227
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
let results = await Promise.allSettled(cmds);
|
|
232
|
+
|
|
233
|
+
for (let i = 1; i < 5; i++) {
|
|
234
|
+
if (results[i].value <= results[i - 1].value) {
|
|
235
|
+
throw new Error('Got result out of order');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
results[5].reason.message.should.contain('multipass');
|
|
240
|
+
|
|
241
|
+
for (let i = 7; i < numCmds; i++) {
|
|
242
|
+
if (results[i].value <= results[i - 1].value) {
|
|
243
|
+
throw new Error('Got result out of order');
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
it('should not care if queue empties for a bit', async function () {
|
|
248
|
+
let numCmds = 10;
|
|
249
|
+
let cmds = [];
|
|
250
|
+
|
|
251
|
+
for (let i = 0; i < numCmds; i++) {
|
|
252
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
let results = await _bluebird.default.all(cmds);
|
|
256
|
+
cmds = [];
|
|
257
|
+
|
|
258
|
+
for (let i = 0; i < numCmds; i++) {
|
|
259
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
results = await _bluebird.default.all(cmds);
|
|
263
|
+
|
|
264
|
+
for (let i = 1; i < numCmds; i++) {
|
|
265
|
+
if (results[i] <= results[i - 1]) {
|
|
266
|
+
throw new Error('Got result out of order');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
describe('timeouts', function () {
|
|
272
|
+
before(async function () {
|
|
273
|
+
await d.createSession(w3cCaps);
|
|
274
|
+
});
|
|
275
|
+
describe('command', function () {
|
|
276
|
+
it('should exist by default', function () {
|
|
277
|
+
d.newCommandTimeoutMs.should.equal(60000);
|
|
278
|
+
});
|
|
279
|
+
it('should be settable through `timeouts`', async function () {
|
|
280
|
+
await d.timeouts('command', 20);
|
|
281
|
+
d.newCommandTimeoutMs.should.equal(20);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
describe('implicit', function () {
|
|
285
|
+
it('should not exist by default', function () {
|
|
286
|
+
d.implicitWaitMs.should.equal(0);
|
|
287
|
+
});
|
|
288
|
+
it('should be settable through `timeouts`', async function () {
|
|
289
|
+
await d.timeouts('implicit', 20);
|
|
290
|
+
d.implicitWaitMs.should.equal(20);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
describe('timeouts (W3C)', function () {
|
|
295
|
+
beforeEach(async function () {
|
|
296
|
+
await d.createSession(w3cCaps);
|
|
297
|
+
});
|
|
298
|
+
afterEach(async function () {
|
|
299
|
+
await d.deleteSession();
|
|
300
|
+
});
|
|
301
|
+
it('should get timeouts that we set', async function () {
|
|
302
|
+
await d.timeouts(undefined, undefined, undefined, undefined, 1000);
|
|
303
|
+
await d.getTimeouts().should.eventually.have.property('implicit', 1000);
|
|
304
|
+
await d.timeouts('command', 2000);
|
|
305
|
+
await d.getTimeouts().should.eventually.deep.equal({
|
|
306
|
+
implicit: 1000,
|
|
307
|
+
command: 2000
|
|
308
|
+
});
|
|
309
|
+
await d.timeouts(undefined, undefined, undefined, undefined, 3000);
|
|
310
|
+
await d.getTimeouts().should.eventually.deep.equal({
|
|
311
|
+
implicit: 3000,
|
|
312
|
+
command: 2000
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
describe('reset compatibility', function () {
|
|
317
|
+
it('should not allow both fullReset and noReset to be true', async function () {
|
|
318
|
+
const newCaps = {
|
|
319
|
+
alwaysMatch: { ...defaultCaps,
|
|
320
|
+
platformName: 'Fake',
|
|
321
|
+
'appium:deviceName': 'Commodore 64',
|
|
322
|
+
'appium:fullReset': true,
|
|
323
|
+
'appium:noReset': true
|
|
324
|
+
},
|
|
325
|
+
firstMatch: [{}]
|
|
326
|
+
};
|
|
327
|
+
await d.createSession(newCaps).should.be.rejectedWith(/noReset.+fullReset/);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
describe('proxying', function () {
|
|
331
|
+
let sessId;
|
|
332
|
+
beforeEach(async function () {
|
|
333
|
+
[sessId] = await d.createSession(w3cCaps);
|
|
334
|
+
});
|
|
335
|
+
describe('#proxyActive', function () {
|
|
336
|
+
it('should exist', function () {
|
|
337
|
+
d.proxyActive.should.be.an.instanceof(Function);
|
|
338
|
+
});
|
|
339
|
+
it('should return false', function () {
|
|
340
|
+
d.proxyActive(sessId).should.be.false;
|
|
341
|
+
});
|
|
342
|
+
it('should throw an error when sessionId is wrong', function () {
|
|
343
|
+
(() => {
|
|
344
|
+
d.proxyActive('aaa');
|
|
345
|
+
}).should.throw;
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
describe('#getProxyAvoidList', function () {
|
|
349
|
+
it('should exist', function () {
|
|
350
|
+
d.getProxyAvoidList.should.be.an.instanceof(Function);
|
|
351
|
+
});
|
|
352
|
+
it('should return an array', function () {
|
|
353
|
+
d.getProxyAvoidList(sessId).should.be.an.instanceof(Array);
|
|
354
|
+
});
|
|
355
|
+
it('should throw an error when sessionId is wrong', function () {
|
|
356
|
+
(() => {
|
|
357
|
+
d.getProxyAvoidList('aaa');
|
|
358
|
+
}).should.throw;
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
describe('#canProxy', function () {
|
|
362
|
+
it('should have a #canProxy method', function () {
|
|
363
|
+
d.canProxy.should.be.an.instanceof(Function);
|
|
364
|
+
});
|
|
365
|
+
it('should return a boolean from #canProxy', function () {
|
|
366
|
+
d.canProxy(sessId).should.be.a('boolean');
|
|
367
|
+
});
|
|
368
|
+
it('should throw an error when sessionId is wrong', function () {
|
|
369
|
+
(() => {
|
|
370
|
+
d.canProxy();
|
|
371
|
+
}).should.throw;
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
describe('#proxyRouteIsAvoided', function () {
|
|
375
|
+
it('should validate form of avoidance list', function () {
|
|
376
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
377
|
+
avoidStub.returns([['POST', /\/foo/], ['GET']]);
|
|
378
|
+
(() => {
|
|
379
|
+
d.proxyRouteIsAvoided();
|
|
380
|
+
}).should.throw;
|
|
381
|
+
avoidStub.returns([['POST', /\/foo/], ['GET', /^foo/, 'bar']]);
|
|
382
|
+
(() => {
|
|
383
|
+
d.proxyRouteIsAvoided();
|
|
384
|
+
}).should.throw;
|
|
385
|
+
});
|
|
386
|
+
it('should reject bad http methods', function () {
|
|
387
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
388
|
+
avoidStub.returns([['POST', /^foo/], ['BAZETE', /^bar/]]);
|
|
389
|
+
(() => {
|
|
390
|
+
d.proxyRouteIsAvoided();
|
|
391
|
+
}).should.throw;
|
|
392
|
+
});
|
|
393
|
+
it('should reject non-regex routes', function () {
|
|
394
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
395
|
+
avoidStub.returns([['POST', /^foo/], ['GET', '/bar']]);
|
|
396
|
+
(() => {
|
|
397
|
+
d.proxyRouteIsAvoided();
|
|
398
|
+
}).should.throw;
|
|
399
|
+
});
|
|
400
|
+
it('should return true for routes in the avoid list', function () {
|
|
401
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
402
|
+
avoidStub.returns([['POST', /^\/foo/]]);
|
|
403
|
+
d.proxyRouteIsAvoided('foo', 'POST', '/foo/bar').should.be.true;
|
|
404
|
+
});
|
|
405
|
+
it('should strip away any wd/hub prefix', function () {
|
|
406
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
407
|
+
avoidStub.returns([['POST', /^\/foo/]]);
|
|
408
|
+
d.proxyRouteIsAvoided('foo', 'POST', '/foo/bar').should.be.true;
|
|
409
|
+
});
|
|
410
|
+
it('should return false for routes not in the avoid list', function () {
|
|
411
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
412
|
+
avoidStub.returns([['POST', /^\/foo/]]);
|
|
413
|
+
d.proxyRouteIsAvoided('foo', 'GET', '/foo/bar').should.be.false;
|
|
414
|
+
d.proxyRouteIsAvoided('foo', 'POST', '/boo').should.be.false;
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
describe('event timing framework', function () {
|
|
419
|
+
let beforeStartTime;
|
|
420
|
+
beforeEach(async function () {
|
|
421
|
+
beforeStartTime = Date.now();
|
|
422
|
+
d.shouldValidateCaps = false;
|
|
423
|
+
await d.executeCommand('createSession', null, null, {
|
|
424
|
+
alwaysMatch: { ...defaultCaps
|
|
425
|
+
},
|
|
426
|
+
firstMatch: [{}]
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
describe('#eventHistory', function () {
|
|
430
|
+
it('should have an eventHistory property', function () {
|
|
431
|
+
should.exist(d.eventHistory);
|
|
432
|
+
should.exist(d.eventHistory.commands);
|
|
433
|
+
});
|
|
434
|
+
it('should have a session start timing after session start', function () {
|
|
435
|
+
let {
|
|
436
|
+
newSessionRequested,
|
|
437
|
+
newSessionStarted
|
|
438
|
+
} = d.eventHistory;
|
|
439
|
+
newSessionRequested.should.have.length(1);
|
|
440
|
+
newSessionStarted.should.have.length(1);
|
|
441
|
+
newSessionRequested[0].should.be.a('number');
|
|
442
|
+
newSessionStarted[0].should.be.a('number');
|
|
443
|
+
(newSessionRequested[0] >= beforeStartTime).should.be.true;
|
|
444
|
+
(newSessionStarted[0] >= newSessionRequested[0]).should.be.true;
|
|
445
|
+
});
|
|
446
|
+
it('should include a commands list', async function () {
|
|
447
|
+
await d.executeCommand('getStatus', []);
|
|
448
|
+
d.eventHistory.commands.length.should.equal(2);
|
|
449
|
+
d.eventHistory.commands[1].cmd.should.equal('getStatus');
|
|
450
|
+
d.eventHistory.commands[1].startTime.should.be.a('number');
|
|
451
|
+
d.eventHistory.commands[1].endTime.should.be.a('number');
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
describe('#logEvent', function () {
|
|
455
|
+
it('should allow logging arbitrary events', function () {
|
|
456
|
+
d.logEvent('foo');
|
|
457
|
+
d.eventHistory.foo[0].should.be.a('number');
|
|
458
|
+
(d.eventHistory.foo[0] >= beforeStartTime).should.be.true;
|
|
459
|
+
});
|
|
460
|
+
it('should not allow reserved or oddly formed event names', function () {
|
|
461
|
+
(() => {
|
|
462
|
+
d.logEvent('commands');
|
|
463
|
+
}).should.throw();
|
|
464
|
+
(() => {
|
|
465
|
+
d.logEvent(1);
|
|
466
|
+
}).should.throw();
|
|
467
|
+
(() => {
|
|
468
|
+
d.logEvent({});
|
|
469
|
+
}).should.throw();
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
it('should allow logging the same event multiple times', function () {
|
|
473
|
+
d.logEvent('bar');
|
|
474
|
+
d.logEvent('bar');
|
|
475
|
+
d.eventHistory.bar.should.have.length(2);
|
|
476
|
+
d.eventHistory.bar[1].should.be.a('number');
|
|
477
|
+
(d.eventHistory.bar[1] >= d.eventHistory.bar[0]).should.be.true;
|
|
478
|
+
});
|
|
479
|
+
describe('getSession decoration', function () {
|
|
480
|
+
it('should decorate getSession response if opt-in cap is provided', async function () {
|
|
481
|
+
var _res$events, _res$events2;
|
|
482
|
+
|
|
483
|
+
let res = await d.getSession();
|
|
484
|
+
should.not.exist(res.events);
|
|
485
|
+
|
|
486
|
+
_lodash.default.set(d, 'caps.eventTimings', true);
|
|
487
|
+
|
|
488
|
+
res = await d.getSession();
|
|
489
|
+
should.exist(res.events);
|
|
490
|
+
should.exist((_res$events = res.events) === null || _res$events === void 0 ? void 0 : _res$events.newSessionRequested);
|
|
491
|
+
expect((_res$events2 = res.events) === null || _res$events2 === void 0 ? void 0 : _res$events2.newSessionRequested[0]).to.be.a('number');
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
describe('.reset', function () {
|
|
496
|
+
it('should reset as W3C if the original session was W3C', async function () {
|
|
497
|
+
const caps = {
|
|
498
|
+
alwaysMatch: {
|
|
499
|
+
'appium:app': 'Fake',
|
|
500
|
+
'appium:deviceName': 'Fake',
|
|
501
|
+
'appium:automationName': 'Fake',
|
|
502
|
+
platformName: 'Fake',
|
|
503
|
+
...defaultCaps
|
|
504
|
+
},
|
|
505
|
+
firstMatch: [{}]
|
|
506
|
+
};
|
|
507
|
+
await d.createSession(caps);
|
|
508
|
+
expect(d.protocol).to.equal('W3C');
|
|
509
|
+
await d.reset();
|
|
510
|
+
expect(d.protocol).to.equal('W3C');
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
describe('.isFeatureEnabled', function () {
|
|
515
|
+
let d;
|
|
516
|
+
beforeEach(function () {
|
|
517
|
+
d = new DriverClass();
|
|
518
|
+
});
|
|
519
|
+
it('should say a feature is enabled when it is explicitly allowed', function () {
|
|
520
|
+
d.allowInsecure = ['foo', 'bar'];
|
|
521
|
+
d.isFeatureEnabled('foo').should.be.true;
|
|
522
|
+
d.isFeatureEnabled('bar').should.be.true;
|
|
523
|
+
d.isFeatureEnabled('baz').should.be.false;
|
|
524
|
+
});
|
|
525
|
+
it('should say a feature is not enabled if it is not enabled', function () {
|
|
526
|
+
d.allowInsecure = [];
|
|
527
|
+
d.isFeatureEnabled('foo').should.be.false;
|
|
528
|
+
});
|
|
529
|
+
it('should prefer denyInsecure to allowInsecure', function () {
|
|
530
|
+
d.allowInsecure = ['foo', 'bar'];
|
|
531
|
+
d.denyInsecure = ['foo'];
|
|
532
|
+
d.isFeatureEnabled('foo').should.be.false;
|
|
533
|
+
d.isFeatureEnabled('bar').should.be.true;
|
|
534
|
+
d.isFeatureEnabled('baz').should.be.false;
|
|
535
|
+
});
|
|
536
|
+
it('should allow global setting for insecurity', function () {
|
|
537
|
+
d.relaxedSecurityEnabled = true;
|
|
538
|
+
d.isFeatureEnabled('foo').should.be.true;
|
|
539
|
+
d.isFeatureEnabled('bar').should.be.true;
|
|
540
|
+
d.isFeatureEnabled('baz').should.be.true;
|
|
541
|
+
});
|
|
542
|
+
it('global setting should be overrideable', function () {
|
|
543
|
+
d.relaxedSecurityEnabled = true;
|
|
544
|
+
d.denyInsecure = ['foo', 'bar'];
|
|
545
|
+
d.isFeatureEnabled('foo').should.be.false;
|
|
546
|
+
d.isFeatureEnabled('bar').should.be.false;
|
|
547
|
+
d.isFeatureEnabled('baz').should.be.true;
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzaG91bGQiLCJjaGFpIiwiZXhwZWN0IiwiZHJpdmVyVW5pdFRlc3RTdWl0ZSIsIkRyaXZlckNsYXNzIiwiZGVmYXVsdENhcHMiLCJjbGFzc05hbWUiLCJuYW1lIiwiZGVzY3JpYmUiLCJkIiwidzNjQ2FwcyIsInNhbmRib3giLCJiZWZvcmVFYWNoIiwiY3JlYXRlU2FuZGJveCIsImFsd2F5c01hdGNoIiwicGxhdGZvcm1OYW1lIiwiZmlyc3RNYXRjaCIsImFmdGVyRWFjaCIsInJlc3RvcmUiLCJkZWxldGVTZXNzaW9uIiwiaXQiLCJiYXNlVmVyc2lvbiIsImV4aXN0IiwicHJldmlvdXNQcmVmaXgiLCJsb2ciLCJwcmVmaXgiLCJjcmVhdGVTZXNzaW9uIiwibm90IiwidG8iLCJlcWwiLCJzdGF0dXMiLCJnZXRTdGF0dXMiLCJzZXNzSWQiLCJiZSIsImEiLCJsZW5ndGgiLCJhYm92ZSIsIl8iLCJjbG9uZURlZXAiLCJyZWplY3RlZFdpdGgiLCJzZXNzaW9uSWQxIiwiZXF1YWwiLCJzZXNzaW9uSWQiLCJzZXNzaW9uSWQyIiwiY2FwcyIsImdldFNlc3Npb24iLCJzZXNzaW9ucyIsImdldFNlc3Npb25zIiwiaW5jbHVkZSIsImlkIiwiY2FwYWJpbGl0aWVzIiwiZGV2aWNlTmFtZSIsInN0dWIiLCJjYWxsc0Zha2UiLCJCIiwiZGVsYXkiLCJjbWRQcm9taXNlIiwiZXhlY3V0ZUNvbW1hbmQiLCJwIiwicmVzb2x2ZSIsInJlamVjdCIsInNldFRpbWVvdXQiLCJFcnJvciIsIm9uVW5leHBlY3RlZFNodXRkb3duIiwic3RhcnRVbmV4cGVjdGVkU2h1dGRvd24iLCJwcm90b3R5cGUiLCJjYWxsIiwicHJvdG9jb2wiLCJjbG9uZSIsImRyaXZlckZvclNlc3Npb24iLCJ3YWl0TXMiLCJEYXRlIiwibm93IiwiY2xlYXJOZXdDb21tYW5kVGltZW91dCIsIm51bUNtZHMiLCJjbWRzIiwiaSIsInB1c2giLCJyZXN1bHRzIiwiYWxsIiwiUHJvbWlzZSIsImFsbFNldHRsZWQiLCJ2YWx1ZSIsInJlYXNvbiIsIm1lc3NhZ2UiLCJjb250YWluIiwiYmVmb3JlIiwibmV3Q29tbWFuZFRpbWVvdXRNcyIsInRpbWVvdXRzIiwiaW1wbGljaXRXYWl0TXMiLCJ1bmRlZmluZWQiLCJnZXRUaW1lb3V0cyIsImV2ZW50dWFsbHkiLCJoYXZlIiwicHJvcGVydHkiLCJkZWVwIiwiaW1wbGljaXQiLCJjb21tYW5kIiwibmV3Q2FwcyIsInByb3h5QWN0aXZlIiwiYW4iLCJpbnN0YW5jZW9mIiwiRnVuY3Rpb24iLCJmYWxzZSIsInRocm93IiwiZ2V0UHJveHlBdm9pZExpc3QiLCJBcnJheSIsImNhblByb3h5IiwiYXZvaWRTdHViIiwicmV0dXJucyIsInByb3h5Um91dGVJc0F2b2lkZWQiLCJ0cnVlIiwiYmVmb3JlU3RhcnRUaW1lIiwic2hvdWxkVmFsaWRhdGVDYXBzIiwiZXZlbnRIaXN0b3J5IiwiY29tbWFuZHMiLCJuZXdTZXNzaW9uUmVxdWVzdGVkIiwibmV3U2Vzc2lvblN0YXJ0ZWQiLCJjbWQiLCJzdGFydFRpbWUiLCJlbmRUaW1lIiwibG9nRXZlbnQiLCJmb28iLCJiYXIiLCJyZXMiLCJldmVudHMiLCJzZXQiLCJyZXNldCIsImFsbG93SW5zZWN1cmUiLCJpc0ZlYXR1cmVFbmFibGVkIiwiZGVueUluc2VjdXJlIiwicmVsYXhlZFNlY3VyaXR5RW5hYmxlZCJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91bml0LXN1aXRlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQge2NyZWF0ZVNhbmRib3h9IGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5cbmNvbnN0IHNob3VsZCA9IGNoYWkuc2hvdWxkKCk7XG5jb25zdCB7ZXhwZWN0fSA9IGNoYWk7XG5cbi8vIHdyYXAgdGhlc2UgdGVzdHMgaW4gYSBmdW5jdGlvbiBzbyB3ZSBjYW4gZXhwb3J0IHRoZSB0ZXN0cyBhbmQgcmUtdXNlIHRoZW1cbi8vIGZvciBhY3R1YWwgZHJpdmVyIGltcGxlbWVudGF0aW9uc1xuXG4vKipcbiAqIENyZWF0ZXMgdW5pdCB0ZXN0IHN1aXRlcyBmb3IgYSBkcml2ZXIuXG4gKiBAcGFyYW0ge0RyaXZlckNsYXNzfSBEcml2ZXJDbGFzc1xuICogQHBhcmFtIHtBcHBpdW1XM0NDYXBhYmlsaXRpZXN9IFtkZWZhdWx0Q2Fwc11cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZHJpdmVyVW5pdFRlc3RTdWl0ZShEcml2ZXJDbGFzcywgZGVmYXVsdENhcHMgPSB7fSkge1xuICAvLyB0byBkaXNwbGF5IHRoZSBkcml2ZXIgdW5kZXIgdGVzdCBpbiByZXBvcnRcbiAgY29uc3QgY2xhc3NOYW1lID0gRHJpdmVyQ2xhc3MubmFtZSA/PyAnKHVua25vd24gZHJpdmVyKSc7XG5cbiAgZGVzY3JpYmUoYEJhc2VEcml2ZXIgdW5pdCBzdWl0ZSAoYXMgJHtjbGFzc05hbWV9KWAsIGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHR5cGUge0luc3RhbmNlVHlwZTx0eXBlb2YgRHJpdmVyQ2xhc3M+fSAqL1xuICAgIGxldCBkO1xuICAgIC8qKiBAdHlwZSB7VzNDQ2FwYWJpbGl0aWVzfSAqL1xuICAgIGxldCB3M2NDYXBzO1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdzaW5vbicpLlNpbm9uU2FuZGJveH0gKi9cbiAgICBsZXQgc2FuZGJveDtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveCA9IGNyZWF0ZVNhbmRib3goKTtcbiAgICAgIGQgPSBuZXcgRHJpdmVyQ2xhc3MoKTtcbiAgICAgIHczY0NhcHMgPSB7XG4gICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgLi4uZGVmYXVsdENhcHMsXG4gICAgICAgICAgcGxhdGZvcm1OYW1lOiAnRmFrZScsXG4gICAgICAgICAgJ2FwcGl1bTpkZXZpY2VOYW1lJzogJ0NvbW1vZG9yZSA2NCcsXG4gICAgICAgIH0sXG4gICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICB9O1xuICAgIH0pO1xuICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICAgIGF3YWl0IGQuZGVsZXRlU2Vzc2lvbigpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3N0YXRpYyBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCdiYXNlVmVyc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBEcml2ZXJDbGFzcy5iYXNlVmVyc2lvbi5zaG91bGQuZXhpc3Q7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTG9nIHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc2V0dXAgbG9nIHByZWZpeCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZCA9IG5ldyBEcml2ZXJDbGFzcygpO1xuICAgICAgICBjb25zdCBwcmV2aW91c1ByZWZpeCA9IGQubG9nLnByZWZpeDtcbiAgICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHtcbiAgICAgICAgICBhbHdheXNNYXRjaDogey4uLmRlZmF1bHRDYXBzLCBwbGF0Zm9ybU5hbWU6ICdGYWtlJywgJ2FwcGl1bTpkZXZpY2VOYW1lJzogJ0NvbW1vZG9yZSA2NCd9LFxuICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICAgIH0pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGV4cGVjdChwcmV2aW91c1ByZWZpeCkubm90LnRvLmVxbChkLmxvZy5wcmVmaXgpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGQuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgICAgIGV4cGVjdChwcmV2aW91c1ByZWZpeCkudG8uZXFsKGQubG9nLnByZWZpeCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgc3RhdHVzIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzdGF0dXMgPSBhd2FpdCBkLmdldFN0YXR1cygpO1xuICAgICAgc3RhdHVzLnNob3VsZC5lcWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzZXNzaW9uSWQgZnJvbSBjcmVhdGVTZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IFtzZXNzSWRdID0gYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHczY0NhcHMpO1xuICAgICAgc2hvdWxkLmV4aXN0KHNlc3NJZCk7XG4gICAgICBzZXNzSWQuc2hvdWxkLmJlLmEoJ3N0cmluZycpO1xuICAgICAgc2Vzc0lkLmxlbmd0aC5zaG91bGQuYmUuYWJvdmUoNSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBiZSBhYmxlIHRvIHN0YXJ0IHR3byBzZXNzaW9ucyB3aXRob3V0IGNsb3NpbmcgdGhlIGZpcnN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKF8uY2xvbmVEZWVwKHczY0NhcHMpKTtcbiAgICAgIGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihfLmNsb25lRGVlcCh3M2NDYXBzKSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnc2Vzc2lvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIGRlbGV0ZSBhIHNlc3Npb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgc2Vzc2lvbklkMSA9IGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihfLmNsb25lRGVlcCh3M2NDYXBzKSk7XG4gICAgICBhd2FpdCBkLmRlbGV0ZVNlc3Npb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbChkLnNlc3Npb25JZCwgbnVsbCk7XG4gICAgICBsZXQgc2Vzc2lvbklkMiA9IGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihfLmNsb25lRGVlcCh3M2NDYXBzKSk7XG4gICAgICBzZXNzaW9uSWQxLnNob3VsZC5ub3QuZXFsKHNlc3Npb25JZDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgdGhlIGN1cnJlbnQgc2Vzc2lvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBbLCBjYXBzXSA9IGF3YWl0IGQuY3JlYXRlU2Vzc2lvbih3M2NDYXBzKTtcbiAgICAgIGNhcHMuc2hvdWxkLmVxdWFsKGF3YWl0IGQuZ2V0U2Vzc2lvbigpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHNlc3Npb25zIGlmIG5vIHNlc3Npb24gZXhpc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNlc3Npb25zID0gYXdhaXQgZC5nZXRTZXNzaW9ucygpO1xuICAgICAgc2Vzc2lvbnMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHNlc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY2FwcyA9IF8uY2xvbmVEZWVwKHczY0NhcHMpO1xuICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKGNhcHMpO1xuICAgICAgbGV0IHNlc3Npb25zID0gYXdhaXQgZC5nZXRTZXNzaW9ucygpO1xuXG4gICAgICBzZXNzaW9ucy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2Vzc2lvbnNbMF0uc2hvdWxkLmluY2x1ZGUoe1xuICAgICAgICBpZDogZC5zZXNzaW9uSWQsXG4gICAgICB9KTtcbiAgICAgIHNlc3Npb25zWzBdLmNhcGFiaWxpdGllcy5zaG91bGQuaW5jbHVkZSh7XG4gICAgICAgIGRldmljZU5hbWU6ICdDb21tb2RvcmUgNjQnLFxuICAgICAgICBwbGF0Zm9ybU5hbWU6ICdGYWtlJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmdWxmaWxsIGFuIHVuZXhwZWN0ZWQgZHJpdmVyIHF1aXQgcHJvbWlzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIG1ha2UgYSBjb21tYW5kIHRoYXQgd2lsbCB3YWl0IGEgYml0IHNvIHdlIGNhbiBjcmFzaCB3aGlsZSBpdCdzIHJ1bm5pbmdcbiAgICAgIHNhbmRib3guc3R1YihkLCAnZ2V0U3RhdHVzJykuY2FsbHNGYWtlKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDAwKTtcbiAgICAgICAgcmV0dXJuICdnb29kIHN0YXR1cyc7XG4gICAgICB9KTtcbiAgICAgIGxldCBjbWRQcm9taXNlID0gZC5leGVjdXRlQ29tbWFuZCgnZ2V0U3RhdHVzJyk7XG4gICAgICBhd2FpdCBCLmRlbGF5KDEwKTtcbiAgICAgIGNvbnN0IHAgPSBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdvblVuZXhwZWN0ZWRTaHV0ZG93biBldmVudCBpcyBleHBlY3RlZCB0byBiZSBmaXJlZCB3aXRoaW4gNSBzZWNvbmRzIHRpbWVvdXQnXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgNTAwMFxuICAgICAgICApO1xuICAgICAgICBkLm9uVW5leHBlY3RlZFNodXRkb3duKHJlc29sdmUpO1xuICAgICAgfSk7XG4gICAgICBkLnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKG5ldyBFcnJvcignV2UgY3Jhc2hlZCcpKTtcbiAgICAgIGF3YWl0IGNtZFByb21pc2Uuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvV2UgY3Jhc2hlZC8pO1xuICAgICAgYXdhaXQgcDtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGFsbG93IGNvbW1hbmRzIGluIG1pZGRsZSBvZiB1bmV4cGVjdGVkIHNodXRkb3duJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gbWFrZSBhIGNvbW1hbmQgdGhhdCB3aWxsIHdhaXQgYSBiaXQgc28gd2UgY2FuIGNyYXNoIHdoaWxlIGl0J3MgcnVubmluZ1xuICAgICAgc2FuZGJveC5zdHViKGQsICdkZWxldGVTZXNzaW9uJykuY2FsbHNGYWtlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDApO1xuICAgICAgICBEcml2ZXJDbGFzcy5wcm90b3R5cGUuZGVsZXRlU2Vzc2lvbi5jYWxsKHRoaXMpO1xuICAgICAgfSk7XG4gICAgICBhd2FpdCBkLmNyZWF0ZVNlc3Npb24odzNjQ2Fwcyk7XG4gICAgICBjb25zdCBwID0gbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnb25VbmV4cGVjdGVkU2h1dGRvd24gZXZlbnQgaXMgZXhwZWN0ZWQgdG8gYmUgZmlyZWQgd2l0aGluIDUgc2Vjb25kcyB0aW1lb3V0J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLFxuICAgICAgICAgIDUwMDBcbiAgICAgICAgKTtcbiAgICAgICAgZC5vblVuZXhwZWN0ZWRTaHV0ZG93bihyZXNvbHZlKTtcbiAgICAgIH0pO1xuICAgICAgZC5zdGFydFVuZXhwZWN0ZWRTaHV0ZG93bihuZXcgRXJyb3IoJ1dlIGNyYXNoZWQnKSk7XG4gICAgICBhd2FpdCBwO1xuICAgICAgYXdhaXQgZC5leGVjdXRlQ29tbWFuZCgnZ2V0U2Vzc2lvbicpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3NodXQgZG93bi8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhbGxvdyBuZXcgY29tbWFuZHMgYWZ0ZXIgZG9uZSBzaHV0dGluZyBkb3duJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gbWFrZSBhIGNvbW1hbmQgdGhhdCB3aWxsIHdhaXQgYSBiaXQgc28gd2UgY2FuIGNyYXNoIHdoaWxlIGl0J3MgcnVubmluZ1xuICAgICAgc2FuZGJveC5zdHViKGQsICdkZWxldGVTZXNzaW9uJykuY2FsbHNGYWtlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDApO1xuICAgICAgICBEcml2ZXJDbGFzcy5wcm90b3R5cGUuZGVsZXRlU2Vzc2lvbi5jYWxsKHRoaXMpO1xuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihfLmNsb25lRGVlcCh3M2NDYXBzKSk7XG4gICAgICBjb25zdCBwID0gbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnb25VbmV4cGVjdGVkU2h1dGRvd24gZXZlbnQgaXMgZXhwZWN0ZWQgdG8gYmUgZmlyZWQgd2l0aGluIDUgc2Vjb25kcyB0aW1lb3V0J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLFxuICAgICAgICAgIDUwMDBcbiAgICAgICAgKTtcbiAgICAgICAgZC5vblVuZXhwZWN0ZWRTaHV0ZG93bihyZXNvbHZlKTtcbiAgICAgIH0pO1xuICAgICAgZC5zdGFydFVuZXhwZWN0ZWRTaHV0ZG93bihuZXcgRXJyb3IoJ1dlIGNyYXNoZWQnKSk7XG4gICAgICBhd2FpdCBwO1xuXG4gICAgICBhd2FpdCBkLmV4ZWN1dGVDb21tYW5kKCdnZXRTZXNzaW9uJykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvc2h1dCBkb3duLyk7XG4gICAgICBhd2FpdCBCLmRlbGF5KDUwMCk7XG5cbiAgICAgIGF3YWl0IGQuZXhlY3V0ZUNvbW1hbmQoJ2NyZWF0ZVNlc3Npb24nLCBudWxsLCBudWxsLCBfLmNsb25lRGVlcCh3M2NDYXBzKSk7XG4gICAgICBhd2FpdCBkLmRlbGV0ZVNlc3Npb24oKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZGlzdGluZ3Vpc2ggYmV0d2VlbiBXM0MgYW5kIEpTT05XUCBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVGVzdCBXM0MgKGxlYXZlIGZpcnN0IDIgYXJncyBudWxsIGJlY2F1c2UgdGhvc2UgYXJlIHRoZSBKU09OV1AgYXJncylcbiAgICAgIGF3YWl0IGQuZXhlY3V0ZUNvbW1hbmQoJ2NyZWF0ZVNlc3Npb24nLCBudWxsLCBudWxsLCB7XG4gICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgLi4uZGVmYXVsdENhcHMsXG4gICAgICAgICAgcGxhdGZvcm1OYW1lOiAnRmFrZScsXG4gICAgICAgICAgJ2FwcGl1bTpkZXZpY2VOYW1lJzogJ0NvbW1vZG9yZSA2NCcsXG4gICAgICAgIH0sXG4gICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGQucHJvdG9jb2wpLnRvLmVxdWFsKCdXM0MnKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdwcm90b2NvbCBkZXRlY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHVzZSBXM0MgaWYgb25seSBXM0MgY2FwcyBhcmUgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGQuY3JlYXRlU2Vzc2lvbih7XG4gICAgICAgICAgYWx3YXlzTWF0Y2g6IF8uY2xvbmUoZGVmYXVsdENhcHMpLFxuICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICAgIH0pO1xuICAgICAgICBleHBlY3QoZC5wcm90b2NvbCkudG8uZXF1YWwoJ1czQycpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgYSBtZXRob2QgdG8gZ2V0IGRyaXZlciBmb3IgYSBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IFtzZXNzSWRdID0gYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHczY0NhcHMpO1xuICAgICAgZXhwZWN0KGQuZHJpdmVyRm9yU2Vzc2lvbihzZXNzSWQpKS50by5lcWwoZCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY29tbWFuZCBxdWV1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKiBAdHlwZSB7SW5zdGFuY2VUeXBlPERyaXZlckNsYXNzPn0gKi9cbiAgICAgIGxldCBkO1xuICAgICAgbGV0IHdhaXRNcyA9IDEwO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZCA9IG5ldyBEcml2ZXJDbGFzcygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoZCwgJ2dldFN0YXR1cycpLmNhbGxzRmFrZShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgQi5kZWxheSh3YWl0TXMpO1xuICAgICAgICAgIHJldHVybiBEYXRlLm5vdygpO1xuICAgICAgICB9KTtcbiAgICAgICAgc2FuZGJveC5zdHViKGQsICdnZXRTZXNzaW9ucycpLmNhbGxzRmFrZShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgQi5kZWxheSh3YWl0TXMpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbXVsdGlwYXNzJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGQuY2xlYXJOZXdDb21tYW5kVGltZW91dCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcXVldWUgY29tbWFuZHMgYW5kLmV4ZWN1dGVDb21tYW5kL3Jlc3BvbmQgaW4gdGhlIG9yZGVyIHJlY2VpdmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbnVtQ21kcyA9IDEwO1xuICAgICAgICBsZXQgY21kcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNtZHM7IGkrKykge1xuICAgICAgICAgIGNtZHMucHVzaChkLmV4ZWN1dGVDb21tYW5kKCdnZXRTdGF0dXMnKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBCLmFsbChjbWRzKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBudW1DbWRzOyBpKyspIHtcbiAgICAgICAgICBpZiAocmVzdWx0c1tpXSA8PSByZXN1bHRzW2kgLSAxXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdHb3QgcmVzdWx0IG91dCBvZiBvcmRlcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGVycm9ycyBjb3JyZWN0bHkgd2hlbiBxdWV1aW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbnVtQ21kcyA9IDEwO1xuICAgICAgICBsZXQgY21kcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNtZHM7IGkrKykge1xuICAgICAgICAgIGlmIChpID09PSA1KSB7XG4gICAgICAgICAgICBjbWRzLnB1c2goZC5leGVjdXRlQ29tbWFuZCgnZ2V0U2Vzc2lvbnMnKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNtZHMucHVzaChkLmV4ZWN1dGVDb21tYW5kKCdnZXRTdGF0dXMnKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHRzID0gLyoqIEB0eXBlIHtQcm9taXNlRnVsZmlsbGVkUmVzdWx0PGFueT5bXX0gKi8gKFxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcm9taXNlL25vLW5hdGl2ZVxuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChjbWRzKVxuICAgICAgICApO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IDU7IGkrKykge1xuICAgICAgICAgIGlmIChyZXN1bHRzW2ldLnZhbHVlIDw9IHJlc3VsdHNbaSAtIDFdLnZhbHVlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0dvdCByZXN1bHQgb3V0IG9mIG9yZGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8qKiBAdHlwZSB7UHJvbWlzZVJlamVjdGVkUmVzdWx0fSAqLyAoXG4gICAgICAgICAgLyoqIEB0eXBlIHt1bmtub3dufSAqLyAocmVzdWx0c1s1XSlcbiAgICAgICAgKS5yZWFzb24ubWVzc2FnZS5zaG91bGQuY29udGFpbignbXVsdGlwYXNzJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSA3OyBpIDwgbnVtQ21kczsgaSsrKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdHNbaV0udmFsdWUgPD0gcmVzdWx0c1tpIC0gMV0udmFsdWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignR290IHJlc3VsdCBvdXQgb2Ygb3JkZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBjYXJlIGlmIHF1ZXVlIGVtcHRpZXMgZm9yIGEgYml0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbnVtQ21kcyA9IDEwO1xuICAgICAgICBsZXQgY21kcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNtZHM7IGkrKykge1xuICAgICAgICAgIGNtZHMucHVzaChkLmV4ZWN1dGVDb21tYW5kKCdnZXRTdGF0dXMnKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBCLmFsbChjbWRzKTtcbiAgICAgICAgY21kcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNtZHM7IGkrKykge1xuICAgICAgICAgIGNtZHMucHVzaChkLmV4ZWN1dGVDb21tYW5kKCdnZXRTdGF0dXMnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0cyA9IGF3YWl0IEIuYWxsKGNtZHMpO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG51bUNtZHM7IGkrKykge1xuICAgICAgICAgIGlmIChyZXN1bHRzW2ldIDw9IHJlc3VsdHNbaSAtIDFdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0dvdCByZXN1bHQgb3V0IG9mIG9yZGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd0aW1lb3V0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGQuY3JlYXRlU2Vzc2lvbih3M2NDYXBzKTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJ2NvbW1hbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgZXhpc3QgYnkgZGVmYXVsdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkLm5ld0NvbW1hbmRUaW1lb3V0TXMuc2hvdWxkLmVxdWFsKDYwMDAwKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgYmUgc2V0dGFibGUgdGhyb3VnaCBgdGltZW91dHNgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGQudGltZW91dHMoJ2NvbW1hbmQnLCAyMCk7XG4gICAgICAgICAgZC5uZXdDb21tYW5kVGltZW91dE1zLnNob3VsZC5lcXVhbCgyMCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnaW1wbGljaXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgbm90IGV4aXN0IGJ5IGRlZmF1bHQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZC5pbXBsaWNpdFdhaXRNcy5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIGJlIHNldHRhYmxlIHRocm91Z2ggYHRpbWVvdXRzYCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBhd2FpdCBkLnRpbWVvdXRzKCdpbXBsaWNpdCcsIDIwKTtcbiAgICAgICAgICBkLmltcGxpY2l0V2FpdE1zLnNob3VsZC5lcXVhbCgyMCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndGltZW91dHMgKFczQyknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHczY0NhcHMpO1xuICAgICAgfSk7XG4gICAgICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBkLmRlbGV0ZVNlc3Npb24oKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBnZXQgdGltZW91dHMgdGhhdCB3ZSBzZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgYXdhaXQgZC50aW1lb3V0cyh1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIDEwMDApO1xuICAgICAgICBhd2FpdCBkLmdldFRpbWVvdXRzKCkuc2hvdWxkLmV2ZW50dWFsbHkuaGF2ZS5wcm9wZXJ0eSgnaW1wbGljaXQnLCAxMDAwKTtcbiAgICAgICAgYXdhaXQgZC50aW1lb3V0cygnY29tbWFuZCcsIDIwMDApO1xuICAgICAgICBhd2FpdCBkLmdldFRpbWVvdXRzKCkuc2hvdWxkLmV2ZW50dWFsbHkuZGVlcC5lcXVhbCh7XG4gICAgICAgICAgaW1wbGljaXQ6IDEwMDAsXG4gICAgICAgICAgY29tbWFuZDogMjAwMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgYXdhaXQgZC50aW1lb3V0cyh1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIDMwMDApO1xuICAgICAgICBhd2FpdCBkLmdldFRpbWVvdXRzKCkuc2hvdWxkLmV2ZW50dWFsbHkuZGVlcC5lcXVhbCh7XG4gICAgICAgICAgaW1wbGljaXQ6IDMwMDAsXG4gICAgICAgICAgY29tbWFuZDogMjAwMCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdyZXNldCBjb21wYXRpYmlsaXR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBub3QgYWxsb3cgYm90aCBmdWxsUmVzZXQgYW5kIG5vUmVzZXQgdG8gYmUgdHJ1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbmV3Q2FwcyA9IHtcbiAgICAgICAgICBhbHdheXNNYXRjaDoge1xuICAgICAgICAgICAgLi4uZGVmYXVsdENhcHMsXG4gICAgICAgICAgICBwbGF0Zm9ybU5hbWU6ICdGYWtlJyxcbiAgICAgICAgICAgICdhcHBpdW06ZGV2aWNlTmFtZSc6ICdDb21tb2RvcmUgNjQnLFxuICAgICAgICAgICAgJ2FwcGl1bTpmdWxsUmVzZXQnOiB0cnVlLFxuICAgICAgICAgICAgJ2FwcGl1bTpub1Jlc2V0JzogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihuZXdDYXBzKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9ub1Jlc2V0LitmdWxsUmVzZXQvKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Byb3h5aW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNlc3NJZDtcbiAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBbc2Vzc0lkXSA9IGF3YWl0IGQuY3JlYXRlU2Vzc2lvbih3M2NDYXBzKTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJyNwcm94eUFjdGl2ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkLnByb3h5QWN0aXZlLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEZ1bmN0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGQucHJveHlBY3RpdmUoc2Vzc0lkKS5zaG91bGQuYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gc2Vzc2lvbklkIGlzIHdyb25nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICBkLnByb3h5QWN0aXZlKCdhYWEnKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3c7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCcjZ2V0UHJveHlBdm9pZExpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgZXhpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZC5nZXRQcm94eUF2b2lkTGlzdC5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihGdW5jdGlvbik7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkLmdldFByb3h5QXZvaWRMaXN0KHNlc3NJZCkuc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoQXJyYXkpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIHNlc3Npb25JZCBpcyB3cm9uZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgZC5nZXRQcm94eUF2b2lkTGlzdCgnYWFhJyk7XG4gICAgICAgICAgfSkuc2hvdWxkLnRocm93O1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnI2NhblByb3h5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGhhdmUgYSAjY2FuUHJveHkgbWV0aG9kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGQuY2FuUHJveHkuc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoRnVuY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBib29sZWFuIGZyb20gI2NhblByb3h5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGQuY2FuUHJveHkoc2Vzc0lkKS5zaG91bGQuYmUuYSgnYm9vbGVhbicpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIHNlc3Npb25JZCBpcyB3cm9uZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgZC5jYW5Qcm94eSgpO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdztcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJyNwcm94eVJvdXRlSXNBdm9pZGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGZvcm0gb2YgYXZvaWRhbmNlIGxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgYXZvaWRTdHViID0gc2FuZGJveC5zdHViKGQsICdnZXRQcm94eUF2b2lkTGlzdCcpO1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICBhdm9pZFN0dWIucmV0dXJucyhbWydQT1NUJywgL1xcL2Zvby9dLCBbJ0dFVCddXSk7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgpO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdztcbiAgICAgICAgICBhdm9pZFN0dWIucmV0dXJucyhbXG4gICAgICAgICAgICBbJ1BPU1QnLCAvXFwvZm9vL10sXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICBbJ0dFVCcsIC9eZm9vLywgJ2JhciddLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICBkLnByb3h5Um91dGVJc0F2b2lkZWQoKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3c7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBiYWQgaHR0cCBtZXRob2RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGF2b2lkU3R1YiA9IHNhbmRib3guc3R1YihkLCAnZ2V0UHJveHlBdm9pZExpc3QnKTtcbiAgICAgICAgICBhdm9pZFN0dWIucmV0dXJucyhbXG4gICAgICAgICAgICBbJ1BPU1QnLCAvXmZvby9dLFxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgWydCQVpFVEUnLCAvXmJhci9dLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICBkLnByb3h5Um91dGVJc0F2b2lkZWQoKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3c7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBub24tcmVnZXggcm91dGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGF2b2lkU3R1YiA9IHNhbmRib3guc3R1YihkLCAnZ2V0UHJveHlBdm9pZExpc3QnKTtcbiAgICAgICAgICBhdm9pZFN0dWIucmV0dXJucyhbXG4gICAgICAgICAgICBbJ1BPU1QnLCAvXmZvby9dLFxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgWydHRVQnLCAnL2JhciddLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICBkLnByb3h5Um91dGVJc0F2b2lkZWQoKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3c7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciByb3V0ZXMgaW4gdGhlIGF2b2lkIGxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgYXZvaWRTdHViID0gc2FuZGJveC5zdHViKGQsICdnZXRQcm94eUF2b2lkTGlzdCcpO1xuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtbJ1BPU1QnLCAvXlxcL2Zvby9dXSk7XG4gICAgICAgICAgZC5wcm94eVJvdXRlSXNBdm9pZGVkKCdmb28nLCAnUE9TVCcsICcvZm9vL2JhcicpLnNob3VsZC5iZS50cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBzdHJpcCBhd2F5IGFueSB3ZC9odWIgcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGF2b2lkU3R1YiA9IHNhbmRib3guc3R1YihkLCAnZ2V0UHJveHlBdm9pZExpc3QnKTtcbiAgICAgICAgICBhdm9pZFN0dWIucmV0dXJucyhbWydQT1NUJywgL15cXC9mb28vXV0pO1xuICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgnZm9vJywgJ1BPU1QnLCAnL2Zvby9iYXInKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciByb3V0ZXMgbm90IGluIHRoZSBhdm9pZCBsaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGF2b2lkU3R1YiA9IHNhbmRib3guc3R1YihkLCAnZ2V0UHJveHlBdm9pZExpc3QnKTtcbiAgICAgICAgICBhdm9pZFN0dWIucmV0dXJucyhbWydQT1NUJywgL15cXC9mb28vXV0pO1xuICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgnZm9vJywgJ0dFVCcsICcvZm9vL2JhcicpLnNob3VsZC5iZS5mYWxzZTtcbiAgICAgICAgICBkLnByb3h5Um91dGVJc0F2b2lkZWQoJ2ZvbycsICdQT1NUJywgJy9ib28nKS5zaG91bGQuYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZXZlbnQgdGltaW5nIGZyYW1ld29yaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBiZWZvcmVTdGFydFRpbWU7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgZC5zaG91bGRWYWxpZGF0ZUNhcHMgPSBmYWxzZTtcbiAgICAgICAgYXdhaXQgZC5leGVjdXRlQ29tbWFuZCgnY3JlYXRlU2Vzc2lvbicsIG51bGwsIG51bGwsIHtcbiAgICAgICAgICBhbHdheXNNYXRjaDogey4uLmRlZmF1bHRDYXBzfSxcbiAgICAgICAgICBmaXJzdE1hdGNoOiBbe31dLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJyNldmVudEhpc3RvcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgaGF2ZSBhbiBldmVudEhpc3RvcnkgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2hvdWxkLmV4aXN0KGQuZXZlbnRIaXN0b3J5KTtcbiAgICAgICAgICBzaG91bGQuZXhpc3QoZC5ldmVudEhpc3RvcnkuY29tbWFuZHMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGhhdmUgYSBzZXNzaW9uIHN0YXJ0IHRpbWluZyBhZnRlciBzZXNzaW9uIHN0YXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxldCB7bmV3U2Vzc2lvblJlcXVlc3RlZCwgbmV3U2Vzc2lvblN0YXJ0ZWR9ID0gZC5ldmVudEhpc3Rvcnk7XG4gICAgICAgICAgbmV3U2Vzc2lvblJlcXVlc3RlZC5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgICAgbmV3U2Vzc2lvblN0YXJ0ZWQuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICAgIG5ld1Nlc3Npb25SZXF1ZXN0ZWRbMF0uc2hvdWxkLmJlLmEoJ251bWJlcicpO1xuICAgICAgICAgIG5ld1Nlc3Npb25TdGFydGVkWzBdLnNob3VsZC5iZS5hKCdudW1iZXInKTtcbiAgICAgICAgICAobmV3U2Vzc2lvblJlcXVlc3RlZFswXSA+PSBiZWZvcmVTdGFydFRpbWUpLnNob3VsZC5iZS50cnVlO1xuICAgICAgICAgIChuZXdTZXNzaW9uU3RhcnRlZFswXSA+PSBuZXdTZXNzaW9uUmVxdWVzdGVkWzBdKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBpbmNsdWRlIGEgY29tbWFuZHMgbGlzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBhd2FpdCBkLmV4ZWN1dGVDb21tYW5kKCdnZXRTdGF0dXMnLCBbXSk7XG4gICAgICAgICAgZC5ldmVudEhpc3RvcnkuY29tbWFuZHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgICBkLmV2ZW50SGlzdG9yeS5jb21tYW5kc1sxXS5jbWQuc2hvdWxkLmVxdWFsKCdnZXRTdGF0dXMnKTtcbiAgICAgICAgICBkLmV2ZW50SGlzdG9yeS5jb21tYW5kc1sxXS5zdGFydFRpbWUuc2hvdWxkLmJlLmEoJ251bWJlcicpO1xuICAgICAgICAgIGQuZXZlbnRIaXN0b3J5LmNvbW1hbmRzWzFdLmVuZFRpbWUuc2hvdWxkLmJlLmEoJ251bWJlcicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJyNsb2dFdmVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBhbGxvdyBsb2dnaW5nIGFyYml0cmFyeSBldmVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZC5sb2dFdmVudCgnZm9vJyk7XG4gICAgICAgICAgZC5ldmVudEhpc3RvcnkuZm9vWzBdLnNob3VsZC5iZS5hKCdudW1iZXInKTtcbiAgICAgICAgICAoZC5ldmVudEhpc3RvcnkuZm9vWzBdID49IGJlZm9yZVN0YXJ0VGltZSkuc2hvdWxkLmJlLnRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIG5vdCBhbGxvdyByZXNlcnZlZCBvciBvZGRseSBmb3JtZWQgZXZlbnQgbmFtZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIGQubG9nRXZlbnQoJ2NvbW1hbmRzJyk7XG4gICAgICAgICAgfSkuc2hvdWxkLnRocm93KCk7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIGQubG9nRXZlbnQoMSk7XG4gICAgICAgICAgfSkuc2hvdWxkLnRocm93KCk7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIGQubG9nRXZlbnQoe30pO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdygpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBhbGxvdyBsb2dnaW5nIHRoZSBzYW1lIGV2ZW50IG11bHRpcGxlIHRpbWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkLmxvZ0V2ZW50KCdiYXInKTtcbiAgICAgICAgZC5sb2dFdmVudCgnYmFyJyk7XG4gICAgICAgIGQuZXZlbnRIaXN0b3J5LmJhci5zaG91bGQuaGF2ZS5sZW5ndGgoMik7XG4gICAgICAgIGQuZXZlbnRIaXN0b3J5LmJhclsxXS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgIChkLmV2ZW50SGlzdG9yeS5iYXJbMV0gPj0gZC5ldmVudEhpc3RvcnkuYmFyWzBdKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJ2dldFNlc3Npb24gZGVjb3JhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBkZWNvcmF0ZSBnZXRTZXNzaW9uIHJlc3BvbnNlIGlmIG9wdC1pbiBjYXAgaXMgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbGV0IHJlcyA9IGF3YWl0IGQuZ2V0U2Vzc2lvbigpO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QocmVzLmV2ZW50cyk7XG5cbiAgICAgICAgICBfLnNldChkLCAnY2Fwcy5ldmVudFRpbWluZ3MnLCB0cnVlKTtcbiAgICAgICAgICByZXMgPSBhd2FpdCBkLmdldFNlc3Npb24oKTtcbiAgICAgICAgICBzaG91bGQuZXhpc3QocmVzLmV2ZW50cyk7XG4gICAgICAgICAgc2hvdWxkLmV4aXN0KHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25SZXF1ZXN0ZWQpO1xuICAgICAgICAgIGV4cGVjdChyZXMuZXZlbnRzPy5uZXdTZXNzaW9uUmVxdWVzdGVkWzBdKS50by5iZS5hKCdudW1iZXInKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnLnJlc2V0JywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXNldCBhcyBXM0MgaWYgdGhlIG9yaWdpbmFsIHNlc3Npb24gd2FzIFczQycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY2FwcyA9IHtcbiAgICAgICAgICBhbHdheXNNYXRjaDoge1xuICAgICAgICAgICAgJ2FwcGl1bTphcHAnOiAnRmFrZScsXG4gICAgICAgICAgICAnYXBwaXVtOmRldmljZU5hbWUnOiAnRmFrZScsXG4gICAgICAgICAgICAnYXBwaXVtOmF1dG9tYXRpb25OYW1lJzogJ0Zha2UnLFxuICAgICAgICAgICAgcGxhdGZvcm1OYW1lOiAnRmFrZScsXG4gICAgICAgICAgICAuLi5kZWZhdWx0Q2FwcyxcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKGNhcHMpO1xuICAgICAgICBleHBlY3QoZC5wcm90b2NvbCkudG8uZXF1YWwoJ1czQycpO1xuICAgICAgICBhd2FpdCBkLnJlc2V0KCk7XG4gICAgICAgIGV4cGVjdChkLnByb3RvY29sKS50by5lcXVhbCgnVzNDJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJy5pc0ZlYXR1cmVFbmFibGVkJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBkO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBkID0gbmV3IERyaXZlckNsYXNzKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNheSBhIGZlYXR1cmUgaXMgZW5hYmxlZCB3aGVuIGl0IGlzIGV4cGxpY2l0bHkgYWxsb3dlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGQuYWxsb3dJbnNlY3VyZSA9IFsnZm9vJywgJ2JhciddO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdmb28nKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnYmFyJykuc2hvdWxkLmJlLnRydWU7XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2JheicpLnNob3VsZC5iZS5mYWxzZTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2F5IGEgZmVhdHVyZSBpcyBub3QgZW5hYmxlZCBpZiBpdCBpcyBub3QgZW5hYmxlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGQuYWxsb3dJbnNlY3VyZSA9IFtdO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdmb28nKS5zaG91bGQuYmUuZmFsc2U7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByZWZlciBkZW55SW5zZWN1cmUgdG8gYWxsb3dJbnNlY3VyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGQuYWxsb3dJbnNlY3VyZSA9IFsnZm9vJywgJ2JhciddO1xuICAgICAgZC5kZW55SW5zZWN1cmUgPSBbJ2ZvbyddO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdmb28nKS5zaG91bGQuYmUuZmFsc2U7XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2JhcicpLnNob3VsZC5iZS50cnVlO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdiYXonKS5zaG91bGQuYmUuZmFsc2U7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFsbG93IGdsb2JhbCBzZXR0aW5nIGZvciBpbnNlY3VyaXR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgZC5yZWxheGVkU2VjdXJpdHlFbmFibGVkID0gdHJ1ZTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnZm9vJykuc2hvdWxkLmJlLnRydWU7XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2JhcicpLnNob3VsZC5iZS50cnVlO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdiYXonKS5zaG91bGQuYmUudHJ1ZTtcbiAgICB9KTtcblxuICAgIGl0KCdnbG9iYWwgc2V0dGluZyBzaG91bGQgYmUgb3ZlcnJpZGVhYmxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgZC5yZWxheGVkU2VjdXJpdHlFbmFibGVkID0gdHJ1ZTtcbiAgICAgIGQuZGVueUluc2VjdXJlID0gWydmb28nLCAnYmFyJ107XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2ZvbycpLnNob3VsZC5iZS5mYWxzZTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnYmFyJykuc2hvdWxkLmJlLmZhbHNlO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdiYXonKS5zaG91bGQuYmUudHJ1ZTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkRyaXZlckNsYXNzfSBEcml2ZXJDbGFzc1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLlczQ0NhcGFiaWxpdGllc30gVzNDQ2FwYWJpbGl0aWVzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQXBwaXVtVzNDQ2FwYWJpbGl0aWVzfSBBcHBpdW1XM0NDYXBhYmlsaXRpZXNcbiAqL1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUVBOztBQUVBLE1BQU1BLE1BQU0sR0FBR0MsYUFBQSxDQUFLRCxNQUFMLEVBQWY7O0FBQ0EsTUFBTTtFQUFDRTtBQUFELElBQVdELGFBQWpCOztBQVdPLFNBQVNFLG1CQUFULENBQTZCQyxXQUE3QixFQUEwQ0MsV0FBVyxHQUFHLEVBQXhELEVBQTREO0VBRWpFLE1BQU1DLFNBQVMsR0FBR0YsV0FBVyxDQUFDRyxJQUFaLElBQW9CLGtCQUF0QztFQUVBQyxRQUFRLENBQUUsNkJBQTRCRixTQUFVLEdBQXhDLEVBQTRDLFlBQVk7SUFFOUQsSUFBSUcsQ0FBSjtJQUVBLElBQUlDLE9BQUo7SUFFQSxJQUFJQyxPQUFKO0lBRUFDLFVBQVUsQ0FBQyxZQUFZO01BQ3JCRCxPQUFPLEdBQUcsSUFBQUUsb0JBQUEsR0FBVjtNQUNBSixDQUFDLEdBQUcsSUFBSUwsV0FBSixFQUFKO01BQ0FNLE9BQU8sR0FBRztRQUNSSSxXQUFXLEVBQUUsRUFDWCxHQUFHVCxXQURRO1VBRVhVLFlBQVksRUFBRSxNQUZIO1VBR1gscUJBQXFCO1FBSFYsQ0FETDtRQU1SQyxVQUFVLEVBQUUsQ0FBQyxFQUFEO01BTkosQ0FBVjtJQVFELENBWFMsQ0FBVjtJQVlBQyxTQUFTLENBQUMsa0JBQWtCO01BQzFCTixPQUFPLENBQUNPLE9BQVI7TUFDQSxNQUFNVCxDQUFDLENBQUNVLGFBQUYsRUFBTjtJQUNELENBSFEsQ0FBVDtJQUtBWCxRQUFRLENBQUMsaUJBQUQsRUFBb0IsWUFBWTtNQUN0Q0EsUUFBUSxDQUFDLGFBQUQsRUFBZ0IsWUFBWTtRQUNsQ1ksRUFBRSxDQUFDLGNBQUQsRUFBaUIsWUFBWTtVQUM3QmhCLFdBQVcsQ0FBQ2lCLFdBQVosQ0FBd0JyQixNQUF4QixDQUErQnNCLEtBQS9CO1FBQ0QsQ0FGQyxDQUFGO01BR0QsQ0FKTyxDQUFSO0lBS0QsQ0FOTyxDQUFSO0lBUUFkLFFBQVEsQ0FBQyxZQUFELEVBQWUsWUFBWTtNQUNqQ1ksRUFBRSxDQUFDLHlCQUFELEVBQTRCLGtCQUFrQjtRQUM5QyxNQUFNWCxDQUFDLEdBQUcsSUFBSUwsV0FBSixFQUFWO1FBQ0EsTUFBTW1CLGNBQWMsR0FBR2QsQ0FBQyxDQUFDZSxHQUFGLENBQU1DLE1BQTdCO1FBQ0EsTUFBTWhCLENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0I7VUFDcEJaLFdBQVcsRUFBRSxFQUFDLEdBQUdULFdBQUo7WUFBaUJVLFlBQVksRUFBRSxNQUEvQjtZQUF1QyxxQkFBcUI7VUFBNUQsQ0FETztVQUVwQkMsVUFBVSxFQUFFLENBQUMsRUFBRDtRQUZRLENBQWhCLENBQU47O1FBSUEsSUFBSTtVQUNGZCxNQUFNLENBQUNxQixjQUFELENBQU4sQ0FBdUJJLEdBQXZCLENBQTJCQyxFQUEzQixDQUE4QkMsR0FBOUIsQ0FBa0NwQixDQUFDLENBQUNlLEdBQUYsQ0FBTUMsTUFBeEM7UUFDRCxDQUZELFNBRVU7VUFDUixNQUFNaEIsQ0FBQyxDQUFDVSxhQUFGLEVBQU47VUFDQWpCLE1BQU0sQ0FBQ3FCLGNBQUQsQ0FBTixDQUF1QkssRUFBdkIsQ0FBMEJDLEdBQTFCLENBQThCcEIsQ0FBQyxDQUFDZSxHQUFGLENBQU1DLE1BQXBDO1FBQ0Q7TUFDRixDQWJDLENBQUY7SUFjRCxDQWZPLENBQVI7SUFpQkFMLEVBQUUsQ0FBQyxzQ0FBRCxFQUF5QyxrQkFBa0I7TUFDM0QsSUFBSVUsTUFBTSxHQUFHLE1BQU1yQixDQUFDLENBQUNzQixTQUFGLEVBQW5CO01BQ0FELE1BQU0sQ0FBQzlCLE1BQVAsQ0FBYzZCLEdBQWQsQ0FBa0IsRUFBbEI7SUFDRCxDQUhDLENBQUY7SUFLQVQsRUFBRSxDQUFDLDhDQUFELEVBQWlELGtCQUFrQjtNQUNuRSxJQUFJLENBQUNZLE1BQUQsSUFBVyxNQUFNdkIsQ0FBQyxDQUFDaUIsYUFBRixDQUFnQmhCLE9BQWhCLENBQXJCO01BQ0FWLE1BQU0sQ0FBQ3NCLEtBQVAsQ0FBYVUsTUFBYjtNQUNBQSxNQUFNLENBQUNoQyxNQUFQLENBQWNpQyxFQUFkLENBQWlCQyxDQUFqQixDQUFtQixRQUFuQjtNQUNBRixNQUFNLENBQUNHLE1BQVAsQ0FBY25DLE1BQWQsQ0FBcUJpQyxFQUFyQixDQUF3QkcsS0FBeEIsQ0FBOEIsQ0FBOUI7SUFDRCxDQUxDLENBQUY7SUFPQWhCLEVBQUUsQ0FBQyxvRUFBRCxFQUF1RSxrQkFBa0I7TUFDekYsTUFBTVgsQ0FBQyxDQUFDaUIsYUFBRixDQUFnQlcsZUFBQSxDQUFFQyxTQUFGLENBQVk1QixPQUFaLENBQWhCLENBQU47TUFDQSxNQUFNRCxDQUFDLENBQUNpQixhQUFGLENBQWdCVyxlQUFBLENBQUVDLFNBQUYsQ0FBWTVCLE9BQVosQ0FBaEIsRUFBc0NWLE1BQXRDLENBQTZDaUMsRUFBN0MsQ0FBZ0RNLFlBQWhELENBQTZELFNBQTdELENBQU47SUFDRCxDQUhDLENBQUY7SUFLQW5CLEVBQUUsQ0FBQyxvQ0FBRCxFQUF1QyxrQkFBa0I7TUFDekQsSUFBSW9CLFVBQVUsR0FBRyxNQUFNL0IsQ0FBQyxDQUFDaUIsYUFBRixDQUFnQlcsZUFBQSxDQUFFQyxTQUFGLENBQVk1QixPQUFaLENBQWhCLENBQXZCO01BQ0EsTUFBTUQsQ0FBQyxDQUFDVSxhQUFGLEVBQU47TUFDQW5CLE1BQU0sQ0FBQ3lDLEtBQVAsQ0FBYWhDLENBQUMsQ0FBQ2lDLFNBQWYsRUFBMEIsSUFBMUI7TUFDQSxJQUFJQyxVQUFVLEdBQUcsTUFBTWxDLENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0JXLGVBQUEsQ0FBRUMsU0FBRixDQUFZNUIsT0FBWixDQUFoQixDQUF2QjtNQUNBOEIsVUFBVSxDQUFDeEMsTUFBWCxDQUFrQjJCLEdBQWxCLENBQXNCRSxHQUF0QixDQUEwQmMsVUFBMUI7SUFDRCxDQU5DLENBQUY7SUFRQXZCLEVBQUUsQ0FBQyxnQ0FBRCxFQUFtQyxrQkFBa0I7TUFDckQsSUFBSSxHQUFHd0IsSUFBSCxJQUFXLE1BQU1uQyxDQUFDLENBQUNpQixhQUFGLENBQWdCaEIsT0FBaEIsQ0FBckI7TUFDQWtDLElBQUksQ0FBQzVDLE1BQUwsQ0FBWXlDLEtBQVosQ0FBa0IsTUFBTWhDLENBQUMsQ0FBQ29DLFVBQUYsRUFBeEI7SUFDRCxDQUhDLENBQUY7SUFLQXpCLEVBQUUsQ0FBQyw2Q0FBRCxFQUFnRCxrQkFBa0I7TUFDbEUsSUFBSTBCLFFBQVEsR0FBRyxNQUFNckMsQ0FBQyxDQUFDc0MsV0FBRixFQUFyQjtNQUNBRCxRQUFRLENBQUNYLE1BQVQsQ0FBZ0JuQyxNQUFoQixDQUF1QnlDLEtBQXZCLENBQTZCLENBQTdCO0lBQ0QsQ0FIQyxDQUFGO0lBS0FyQixFQUFFLENBQUMsd0JBQUQsRUFBMkIsa0JBQWtCO01BQzdDLE1BQU13QixJQUFJLEdBQUdQLGVBQUEsQ0FBRUMsU0FBRixDQUFZNUIsT0FBWixDQUFiOztNQUNBLE1BQU1ELENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0JrQixJQUFoQixDQUFOO01BQ0EsSUFBSUUsUUFBUSxHQUFHLE1BQU1yQyxDQUFDLENBQUNzQyxXQUFGLEVBQXJCO01BRUFELFFBQVEsQ0FBQ1gsTUFBVCxDQUFnQm5DLE1BQWhCLENBQXVCeUMsS0FBdkIsQ0FBNkIsQ0FBN0I7TUFDQUssUUFBUSxDQUFDLENBQUQsQ0FBUixDQUFZOUMsTUFBWixDQUFtQmdELE9BQW5CLENBQTJCO1FBQ3pCQyxFQUFFLEVBQUV4QyxDQUFDLENBQUNpQztNQURtQixDQUEzQjtNQUdBSSxRQUFRLENBQUMsQ0FBRCxDQUFSLENBQVlJLFlBQVosQ0FBeUJsRCxNQUF6QixDQUFnQ2dELE9BQWhDLENBQXdDO1FBQ3RDRyxVQUFVLEVBQUUsY0FEMEI7UUFFdENwQyxZQUFZLEVBQUU7TUFGd0IsQ0FBeEM7SUFJRCxDQWJDLENBQUY7SUFlQUssRUFBRSxDQUFDLGtEQUFELEVBQXFELGtCQUFrQjtNQUV2RVQsT0FBTyxDQUFDeUMsSUFBUixDQUFhM0MsQ0FBYixFQUFnQixXQUFoQixFQUE2QjRDLFNBQTdCLENBQXVDLFlBQVk7UUFDakQsTUFBTUMsaUJBQUEsQ0FBRUMsS0FBRixDQUFRLElBQVIsQ0FBTjtRQUNBLE9BQU8sYUFBUDtNQUNELENBSEQ7TUFJQSxJQUFJQyxVQUFVLEdBQUcvQyxDQUFDLENBQUNnRCxjQUFGLENBQWlCLFdBQWpCLENBQWpCO01BQ0EsTUFBTUgsaUJBQUEsQ0FBRUMsS0FBRixDQUFRLEVBQVIsQ0FBTjtNQUNBLE1BQU1HLENBQUMsR0FBRyxJQUFJSixpQkFBSixDQUFNLENBQUNLLE9BQUQsRUFBVUMsTUFBVixLQUFxQjtRQUNuQ0MsVUFBVSxDQUNSLE1BQ0VELE1BQU0sQ0FDSixJQUFJRSxLQUFKLENBQ0UsNkVBREYsQ0FESSxDQUZBLEVBT1IsSUFQUSxDQUFWO1FBU0FyRCxDQUFDLENBQUNzRCxvQkFBRixDQUF1QkosT0FBdkI7TUFDRCxDQVhTLENBQVY7TUFZQWxELENBQUMsQ0FBQ3VELHVCQUFGLENBQTBCLElBQUlGLEtBQUosQ0FBVSxZQUFWLENBQTFCO01BQ0EsTUFBTU4sVUFBVSxDQUFDeEQsTUFBWCxDQUFrQmlDLEVBQWxCLENBQXFCTSxZQUFyQixDQUFrQyxZQUFsQyxDQUFOO01BQ0EsTUFBTW1CLENBQU47SUFDRCxDQXZCQyxDQUFGO0lBeUJBdEMsRUFBRSxDQUFDLDREQUFELEVBQStELGtCQUFrQjtNQUVqRlQsT0FBTyxDQUFDeUMsSUFBUixDQUFhM0MsQ0FBYixFQUFnQixlQUFoQixFQUFpQzRDLFNBQWpDLENBQTJDLGtCQUFrQjtRQUMzRCxNQUFNQyxpQkFBQSxDQUFFQyxLQUFGLENBQVEsR0FBUixDQUFOO1FBQ0FuRCxXQUFXLENBQUM2RCxTQUFaLENBQXNCOUMsYUFBdEIsQ0FBb0MrQyxJQUFwQyxDQUF5QyxJQUF6QztNQUNELENBSEQ7TUFJQSxNQUFNekQsQ0FBQyxDQUFDaUIsYUFBRixDQUFnQmhCLE9BQWhCLENBQU47TUFDQSxNQUFNZ0QsQ0FBQyxHQUFHLElBQUlKLGlCQUFKLENBQU0sQ0FBQ0ssT0FBRCxFQUFVQyxNQUFWLEtBQXFCO1FBQ25DQyxVQUFVLENBQ1IsTUFDRUQsTUFBTSxDQUNKLElBQUlFLEtBQUosQ0FDRSw2RUFERixDQURJLENBRkEsRUFPUixJQVBRLENBQVY7UUFTQXJELENBQUMsQ0FBQ3NELG9CQUFGLENBQXVCSixPQUF2QjtNQUNELENBWFMsQ0FBVjtNQVlBbEQsQ0FBQyxDQUFDdUQsdUJBQUYsQ0FBMEIsSUFBSUYsS0FBSixDQUFVLFlBQVYsQ0FBMUI7TUFDQSxNQUFNSixDQUFOO01BQ0EsTUFBTWpELENBQUMsQ0FBQ2dELGNBQUYsQ0FBaUIsWUFBakIsRUFBK0J6RCxNQUEvQixDQUFzQ2lDLEVBQXRDLENBQXlDTSxZQUF6QyxDQUFzRCxXQUF0RCxDQUFOO0lBQ0QsQ0F0QkMsQ0FBRjtJQXdCQW5CLEVBQUUsQ0FBQyxvREFBRCxFQUF1RCxrQkFBa0I7TUFFekVULE9BQU8sQ0FBQ3lDLElBQVIsQ0FBYTNDLENBQWIsRUFBZ0IsZUFBaEIsRUFBaUM0QyxTQUFqQyxDQUEyQyxrQkFBa0I7UUFDM0QsTUFBTUMsaUJBQUEsQ0FBRUMsS0FBRixDQUFRLEdBQVIsQ0FBTjtRQUNBbkQsV0FBVyxDQUFDNkQsU0FBWixDQUFzQjlDLGFBQXRCLENBQW9DK0MsSUFBcEMsQ0FBeUMsSUFBekM7TUFDRCxDQUhEO01BS0EsTUFBTXpELENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0JXLGVBQUEsQ0FBRUMsU0FBRixDQUFZNUIsT0FBWixDQUFoQixDQUFOO01BQ0EsTUFBTWdELENBQUMsR0FBRyxJQUFJSixpQkFBSixDQUFNLENBQUNLLE9BQUQsRUFBVUMsTUFBVixLQUFxQjtRQUNuQ0MsVUFBVSxDQUNSLE1BQ0VELE1BQU0sQ0FDSixJQUFJRSxLQUFKLENBQ0UsNkVBREYsQ0FESSxDQUZBLEVBT1IsSUFQUSxDQUFWO1FBU0FyRCxDQUFDLENBQUNzRCxvQkFBRixDQUF1QkosT0FBdkI7TUFDRCxDQVhTLENBQVY7TUFZQWxELENBQUMsQ0FBQ3VELHVCQUFGLENBQTBCLElBQUlGLEtBQUosQ0FBVSxZQUFWLENBQTFCO01BQ0EsTUFBTUosQ0FBTjtNQUVBLE1BQU1qRCxDQUFDLENBQUNnRCxjQUFGLENBQWlCLFlBQWpCLEVBQStCekQsTUFBL0IsQ0FBc0NpQyxFQUF0QyxDQUF5Q00sWUFBekMsQ0FBc0QsV0FBdEQsQ0FBTjtNQUNBLE1BQU1lLGlCQUFBLENBQUVDLEtBQUYsQ0FBUSxHQUFSLENBQU47TUFFQSxNQUFNOUMsQ0FBQyxDQUFDZ0QsY0FBRixDQUFpQixlQUFqQixFQUFrQyxJQUFsQyxFQUF3QyxJQUF4QyxFQUE4Q3BCLGVBQUEsQ0FBRUMsU0FBRixDQUFZNUIsT0FBWixDQUE5QyxDQUFOO01BQ0EsTUFBTUQsQ0FBQyxDQUFDVSxhQUFGLEVBQU47SUFDRCxDQTVCQyxDQUFGO0lBOEJBQyxFQUFFLENBQUMsbURBQUQsRUFBc0Qsa0JBQWtCO01BRXhFLE1BQU1YLENBQUMsQ0FBQ2dELGNBQUYsQ0FBaUIsZUFBakIsRUFBa0MsSUFBbEMsRUFBd0MsSUFBeEMsRUFBOEM7UUFDbEQzQyxXQUFXLEVBQUUsRUFDWCxHQUFHVCxXQURRO1VBRVhVLFlBQVksRUFBRSxNQUZIO1VBR1gscUJBQXFCO1FBSFYsQ0FEcUM7UUFNbERDLFVBQVUsRUFBRSxDQUFDLEVBQUQ7TUFOc0MsQ0FBOUMsQ0FBTjtNQVNBZCxNQUFNLENBQUNPLENBQUMsQ0FBQzBELFFBQUgsQ0FBTixDQUFtQnZDLEVBQW5CLENBQXNCYSxLQUF0QixDQUE0QixLQUE1QjtJQUNELENBWkMsQ0FBRjtJQWNBakMsUUFBUSxDQUFDLG9CQUFELEVBQXVCLFlBQVk7TUFDekNZLEVBQUUsQ0FBQyw4Q0FBRCxFQUFpRCxrQkFBa0I7UUFDbkUsTUFBTVgsQ0FBQyxDQUFDaUIsYUFBRixDQUFnQjtVQUNwQlosV0FBVyxFQUFFdUIsZUFBQSxDQUFFK0IsS0FBRixDQUFRL0QsV0FBUixDQURPO1VBRXBCVyxVQUFVLEVBQUUsQ0FBQyxFQUFEO1FBRlEsQ0FBaEIsQ0FBTjtRQUlBZCxNQUFNLENBQUNPLENBQUMsQ0FBQzBELFFBQUgsQ0FBTixDQUFtQnZDLEVBQW5CLENBQXNCYSxLQUF0QixDQUE0QixLQUE1QjtNQUNELENBTkMsQ0FBRjtJQU9ELENBUk8sQ0FBUjtJQVVBckIsRUFBRSxDQUFDLGtEQUFELEVBQXFELGtCQUFrQjtNQUN2RSxJQUFJLENBQUNZLE1BQUQsSUFBVyxNQUFNdkIsQ0FBQyxDQUFDaUIsYUFBRixDQUFnQmhCLE9BQWhCLENBQXJCO01BQ0FSLE1BQU0sQ0FBQ08sQ0FBQyxDQUFDNEQsZ0JBQUYsQ0FBbUJyQyxNQUFuQixDQUFELENBQU4sQ0FBbUNKLEVBQW5DLENBQXNDQyxHQUF0QyxDQUEwQ3BCLENBQTFDO0lBQ0QsQ0FIQyxDQUFGO0lBS0FELFFBQVEsQ0FBQyxlQUFELEVBQWtCLFlBQVk7TUFFcEMsSUFBSUMsQ0FBSjtNQUNBLElBQUk2RCxNQUFNLEdBQUcsRUFBYjtNQUVBMUQsVUFBVSxDQUFDLFlBQVk7UUFDckJILENBQUMsR0FBRyxJQUFJTCxXQUFKLEVBQUo7UUFDQU8sT0FBTyxDQUFDeUMsSUFBUixDQUFhM0MsQ0FBYixFQUFnQixXQUFoQixFQUE2QjRDLFNBQTdCLENBQXVDLFlBQVk7VUFDakQsTUFBTUMsaUJBQUEsQ0FBRUMsS0FBRixDQUFRZSxNQUFSLENBQU47VUFDQSxPQUFPQyxJQUFJLENBQUNDLEdBQUwsRUFBUDtRQUNELENBSEQ7UUFJQTdELE9BQU8sQ0FBQ3lDLElBQVIsQ0FBYTNDLENBQWIsRUFBZ0IsYUFBaEIsRUFBK0I0QyxTQUEvQixDQUF5QyxZQUFZO1VBQ25ELE1BQU1DLGlCQUFBLENBQUVDLEtBQUYsQ0FBUWUsTUFBUixDQUFOO1VBQ0EsTUFBTSxJQUFJUixLQUFKLENBQVUsV0FBVixDQUFOO1FBQ0QsQ0FIRDtNQUlELENBVlMsQ0FBVjtNQVlBN0MsU0FBUyxDQUFDLGtCQUFrQjtRQUMxQixNQUFNUixDQUFDLENBQUNnRSxzQkFBRixFQUFOO01BQ0QsQ0FGUSxDQUFUO01BSUFyRCxFQUFFLENBQUMsd0VBQUQsRUFBMkUsa0JBQWtCO1FBQzdGLElBQUlzRCxPQUFPLEdBQUcsRUFBZDtRQUNBLElBQUlDLElBQUksR0FBRyxFQUFYOztRQUNBLEtBQUssSUFBSUMsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0YsT0FBcEIsRUFBNkJFLENBQUMsRUFBOUIsRUFBa0M7VUFDaENELElBQUksQ0FBQ0UsSUFBTCxDQUFVcEUsQ0FBQyxDQUFDZ0QsY0FBRixDQUFpQixXQUFqQixDQUFWO1FBQ0Q7O1FBQ0QsSUFBSXFCLE9BQU8sR0FBRyxNQUFNeEIsaUJBQUEsQ0FBRXlCLEdBQUYsQ0FBTUosSUFBTixDQUFwQjs7UUFDQSxLQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdGLE9BQXBCLEVBQTZCRSxDQUFDLEVBQTlCLEVBQWtDO1VBQ2hDLElBQUlFLE9BQU8sQ0FBQ0YsQ0FBRCxDQUFQLElBQWNFLE9BQU8sQ0FBQ0YsQ0FBQyxHQUFHLENBQUwsQ0FBekIsRUFBa0M7WUFDaEMsTUFBTSxJQUFJZCxLQUFKLENBQVUseUJBQVYsQ0FBTjtVQUNEO1FBQ0Y7TUFDRixDQVpDLENBQUY7TUFjQTFDLEVBQUUsQ0FBQyw2Q0FBRCxFQUFnRCxrQkFBa0I7UUFDbEUsSUFBSXNELE9BQU8sR0FBRyxFQUFkO1FBQ0EsSUFBSUMsSUFBSSxHQUFHLEVBQVg7O1FBQ0EsS0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHRixPQUFwQixFQUE2QkUsQ0FBQyxFQUE5QixFQUFrQztVQUNoQyxJQUFJQSxDQUFDLEtBQUssQ0FBVixFQUFhO1lBQ1hELElBQUksQ0FBQ0UsSUFBTCxDQUFVcEUsQ0FBQyxDQUFDZ0QsY0FBRixDQUFpQixhQUFqQixDQUFWO1VBQ0QsQ0FGRCxNQUVPO1lBQ0xrQixJQUFJLENBQUNFLElBQUwsQ0FBVXBFLENBQUMsQ0FBQ2dELGNBQUYsQ0FBaUIsV0FBakIsQ0FBVjtVQUNEO1FBQ0Y7O1FBQ0QsSUFBSXFCLE9BQU8sR0FFVCxNQUFNRSxPQUFPLENBQUNDLFVBQVIsQ0FBbUJOLElBQW5CLENBRlI7O1FBSUEsS0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHLENBQXBCLEVBQXVCQSxDQUFDLEVBQXhCLEVBQTRCO1VBQzFCLElBQUlFLE9BQU8sQ0FBQ0YsQ0FBRCxDQUFQLENBQVdNLEtBQVgsSUFBb0JKLE9BQU8sQ0FBQ0YsQ0FBQyxHQUFHLENBQUwsQ0FBUCxDQUFlTSxLQUF2QyxFQUE4QztZQUM1QyxNQUFNLElBQUlwQixLQUFKLENBQVUseUJBQVYsQ0FBTjtVQUNEO1FBQ0Y7O1FBRXlCZ0IsT0FBTyxDQUFDLENBQUQsQ0FESSxDQUVuQ0ssTUFGbUMsQ0FFNUJDLE9BRjRCLENBRXBCcEYsTUFGb0IsQ0FFYnFGLE9BRmEsQ0FFTCxXQUZLOztRQUdyQyxLQUFLLElBQUlULENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdGLE9BQXBCLEVBQTZCRSxDQUFDLEVBQTlCLEVBQWtDO1VBQ2hDLElBQUlFLE9BQU8sQ0FBQ0YsQ0FBRCxDQUFQLENBQVdNLEtBQVgsSUFBb0JKLE9BQU8sQ0FBQ0YsQ0FBQyxHQUFHLENBQUwsQ0FBUCxDQUFlTSxLQUF2QyxFQUE4QztZQUM1QyxNQUFNLElBQUlwQixLQUFKLENBQVUseUJBQVYsQ0FBTjtVQUNEO1FBQ0Y7TUFDRixDQTNCQyxDQUFGO01BNkJBMUMsRUFBRSxDQUFDLDRDQUFELEVBQStDLGtCQUFrQjtRQUNqRSxJQUFJc0QsT0FBTyxHQUFHLEVBQWQ7UUFDQSxJQUFJQyxJQUFJLEdBQUcsRUFBWDs7UUFDQSxLQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdGLE9BQXBCLEVBQTZCRSxDQUFDLEVBQTlCLEVBQWtDO1VBQ2hDRCxJQUFJLENBQUNFLElBQUwsQ0FBVXBFLENBQUMsQ0FBQ2dELGNBQUYsQ0FBaUIsV0FBakIsQ0FBVjtRQUNEOztRQUNELElBQUlxQixPQUFPLEdBQUcsTUFBTXhCLGlCQUFBLENBQUV5QixHQUFGLENBQU1KLElBQU4sQ0FBcEI7UUFDQUEsSUFBSSxHQUFHLEVBQVA7O1FBQ0EsS0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHRixPQUFwQixFQUE2QkUsQ0FBQyxFQUE5QixFQUFrQztVQUNoQ0QsSUFBSSxDQUFDRSxJQUFMLENBQVVwRSxDQUFDLENBQUNnRCxjQUFGLENBQWlCLFdBQWpCLENBQVY7UUFDRDs7UUFDRHFCLE9BQU8sR0FBRyxNQUFNeEIsaUJBQUEsQ0FBRXlCLEdBQUYsQ0FBTUosSUFBTixDQUFoQjs7UUFDQSxLQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdGLE9BQXBCLEVBQTZCRSxDQUFDLEVBQTlCLEVBQWtDO1VBQ2hDLElBQUlFLE9BQU8sQ0FBQ0YsQ0FBRCxDQUFQLElBQWNFLE9BQU8sQ0FBQ0YsQ0FBQyxHQUFHLENBQUwsQ0FBekIsRUFBa0M7WUFDaEMsTUFBTSxJQUFJZCxLQUFKLENBQVUseUJBQVYsQ0FBTjtVQUNEO1FBQ0Y7TUFDRixDQWpCQyxDQUFGO0lBa0JELENBbEZPLENBQVI7SUFvRkF0RCxRQUFRLENBQUMsVUFBRCxFQUFhLFlBQVk7TUFDL0I4RSxNQUFNLENBQUMsa0JBQWtCO1FBQ3ZCLE1BQU03RSxDQUFDLENBQUNpQixhQUFGLENBQWdCaEIsT0FBaEIsQ0FBTjtNQUNELENBRkssQ0FBTjtNQUdBRixRQUFRLENBQUMsU0FBRCxFQUFZLFlBQVk7UUFDOUJZLEVBQUUsQ0FBQyx5QkFBRCxFQUE0QixZQUFZO1VBQ3hDWCxDQUFDLENBQUM4RSxtQkFBRixDQUFzQnZGLE1BQXRCLENBQTZCeUMsS0FBN0IsQ0FBbUMsS0FBbkM7UUFDRCxDQUZDLENBQUY7UUFHQXJCLEVBQUUsQ0FBQyx1Q0FBRCxFQUEwQyxrQkFBa0I7VUFDNUQsTUFBTVgsQ0FBQyxDQUFDK0UsUUFBRixDQUFXLFNBQVgsRUFBc0IsRUFBdEIsQ0FBTjtVQUNBL0UsQ0FBQyxDQUFDOEUsbUJBQUYsQ0FBc0J2RixNQUF0QixDQUE2QnlDLEtBQTdCLENBQW1DLEVBQW5DO1FBQ0QsQ0FIQyxDQUFGO01BSUQsQ0FSTyxDQUFSO01BU0FqQyxRQUFRLENBQUMsVUFBRCxFQUFhLFlBQVk7UUFDL0JZLEVBQUUsQ0FBQyw2QkFBRCxFQUFnQyxZQUFZO1VBQzVDWCxDQUFDLENBQUNnRixjQUFGLENBQWlCekYsTUFBakIsQ0FBd0J5QyxLQUF4QixDQUE4QixDQUE5QjtRQUNELENBRkMsQ0FBRjtRQUdBckIsRUFBRSxDQUFDLHVDQUFELEVBQTBDLGtCQUFrQjtVQUM1RCxNQUFNWCxDQUFDLENBQUMrRSxRQUFGLENBQVcsVUFBWCxFQUF1QixFQUF2QixDQUFOO1VBQ0EvRSxDQUFDLENBQUNnRixjQUFGLENBQWlCekYsTUFBakIsQ0FBd0J5QyxLQUF4QixDQUE4QixFQUE5QjtRQUNELENBSEMsQ0FBRjtNQUlELENBUk8sQ0FBUjtJQVNELENBdEJPLENBQVI7SUF3QkFqQyxRQUFRLENBQUMsZ0JBQUQsRUFBbUIsWUFBWTtNQUNyQ0ksVUFBVSxDQUFDLGtCQUFrQjtRQUMzQixNQUFNSCxDQUFDLENBQUNpQixhQUFGLENBQWdCaEIsT0FBaEIsQ0FBTjtNQUNELENBRlMsQ0FBVjtNQUdBTyxTQUFTLENBQUMsa0JBQWtCO1FBQzFCLE1BQU1SLENBQUMsQ0FBQ1UsYUFBRixFQUFOO01BQ0QsQ0FGUSxDQUFUO01BR0FDLEVBQUUsQ0FBQyxpQ0FBRCxFQUFvQyxrQkFBa0I7UUFFdEQsTUFBTVgsQ0FBQyxDQUFDK0UsUUFBRixDQUFXRSxTQUFYLEVBQXNCQSxTQUF0QixFQUFpQ0EsU0FBakMsRUFBNENBLFNBQTVDLEVBQXVELElBQXZELENBQU47UUFDQSxNQUFNakYsQ0FBQyxDQUFDa0YsV0FBRixHQUFnQjNGLE1BQWhCLENBQXVCNEYsVUFBdkIsQ0FBa0NDLElBQWxDLENBQXVDQyxRQUF2QyxDQUFnRCxVQUFoRCxFQUE0RCxJQUE1RCxDQUFOO1FBQ0EsTUFBTXJGLENBQUMsQ0FBQytFLFFBQUYsQ0FBVyxTQUFYLEVBQXNCLElBQXRCLENBQU47UUFDQSxNQUFNL0UsQ0FBQyxDQUFDa0YsV0FBRixHQUFnQjNGLE1BQWhCLENBQXVCNEYsVUFBdkIsQ0FBa0NHLElBQWxDLENBQXVDdEQsS0FBdkMsQ0FBNkM7VUFDakR1RCxRQUFRLEVBQUUsSUFEdUM7VUFFakRDLE9BQU8sRUFBRTtRQUZ3QyxDQUE3QyxDQUFOO1FBS0EsTUFBTXhGLENBQUMsQ0FBQytFLFFBQUYsQ0FBV0UsU0FBWCxFQUFzQkEsU0FBdEIsRUFBaUNBLFNBQWpDLEVBQTRDQSxTQUE1QyxFQUF1RCxJQUF2RCxDQUFOO1FBQ0EsTUFBTWpGLENBQUMsQ0FBQ2tGLFdBQUYsR0FBZ0IzRixNQUFoQixDQUF1QjRGLFVBQXZCLENBQWtDRyxJQUFsQyxDQUF1Q3RELEtBQXZDLENBQTZDO1VBQ2pEdUQsUUFBUSxFQUFFLElBRHVDO1VBRWpEQyxPQUFPLEVBQUU7UUFGd0MsQ0FBN0MsQ0FBTjtNQUlELENBZkMsQ0FBRjtJQWdCRCxDQXZCTyxDQUFSO0lBeUJBekYsUUFBUSxDQUFDLHFCQUFELEVBQXdCLFlBQVk7TUFDMUNZLEVBQUUsQ0FBQyx3REFBRCxFQUEyRCxrQkFBa0I7UUFDN0UsTUFBTThFLE9BQU8sR0FBRztVQUNkcEYsV0FBVyxFQUFFLEVBQ1gsR0FBR1QsV0FEUTtZQUVYVSxZQUFZLEVBQUUsTUFGSDtZQUdYLHFCQUFxQixjQUhWO1lBSVgsb0JBQW9CLElBSlQ7WUFLWCxrQkFBa0I7VUFMUCxDQURDO1VBUWRDLFVBQVUsRUFBRSxDQUFDLEVBQUQ7UUFSRSxDQUFoQjtRQVVBLE1BQU1QLENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0J3RSxPQUFoQixFQUF5QmxHLE1BQXpCLENBQWdDaUMsRUFBaEMsQ0FBbUNNLFlBQW5DLENBQWdELG9CQUFoRCxDQUFOO01BQ0QsQ0FaQyxDQUFGO0lBYUQsQ0FkTyxDQUFSO0lBZ0JBL0IsUUFBUSxDQUFDLFVBQUQsRUFBYSxZQUFZO01BQy9CLElBQUl3QixNQUFKO01BQ0FwQixVQUFVLENBQUMsa0JBQWtCO1FBQzNCLENBQUNvQixNQUFELElBQVcsTUFBTXZCLENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0JoQixPQUFoQixDQUFqQjtNQUNELENBRlMsQ0FBVjtNQUdBRixRQUFRLENBQUMsY0FBRCxFQUFpQixZQUFZO1FBQ25DWSxFQUFFLENBQUMsY0FBRCxFQUFpQixZQUFZO1VBQzdCWCxDQUFDLENBQUMwRixXQUFGLENBQWNuRyxNQUFkLENBQXFCaUMsRUFBckIsQ0FBd0JtRSxFQUF4QixDQUEyQkMsVUFBM0IsQ0FBc0NDLFFBQXRDO1FBQ0QsQ0FGQyxDQUFGO1FBR0FsRixFQUFFLENBQUMscUJBQUQsRUFBd0IsWUFBWTtVQUNwQ1gsQ0FBQyxDQUFDMEYsV0FBRixDQUFjbkUsTUFBZCxFQUFzQmhDLE1BQXRCLENBQTZCaUMsRUFBN0IsQ0FBZ0NzRSxLQUFoQztRQUNELENBRkMsQ0FBRjtRQUdBbkYsRUFBRSxDQUFDLCtDQUFELEVBQWtELFlBQVk7VUFDOUQsQ0FBQyxNQUFNO1lBQ0xYLENBQUMsQ0FBQzBGLFdBQUYsQ0FBYyxLQUFkO1VBQ0QsQ0FGRCxFQUVHbkcsTUFGSCxDQUVVd0csS0FGVjtRQUdELENBSkMsQ0FBRjtNQUtELENBWk8sQ0FBUjtNQWNBaEcsUUFBUSxDQUFDLG9CQUFELEVBQXVCLFlBQVk7UUFDekNZLEVBQUUsQ0FBQyxjQUFELEVBQWlCLFlBQVk7VUFDN0JYLENBQUMsQ0FBQ2dHLGlCQUFGLENBQW9CekcsTUFBcEIsQ0FBMkJpQyxFQUEzQixDQUE4Qm1FLEVBQTlCLENBQWlDQyxVQUFqQyxDQUE0Q0MsUUFBNUM7UUFDRCxDQUZDLENBQUY7UUFHQWxGLEVBQUUsQ0FBQyx3QkFBRCxFQUEyQixZQUFZO1VBQ3ZDWCxDQUFDLENBQUNnRyxpQkFBRixDQUFvQnpFLE1BQXBCLEVBQTRCaEMsTUFBNUIsQ0FBbUNpQyxFQUFuQyxDQUFzQ21FLEVBQXRDLENBQXlDQyxVQUF6QyxDQUFvREssS0FBcEQ7UUFDRCxDQUZDLENBQUY7UUFHQXRGLEVBQUUsQ0FBQywrQ0FBRCxFQUFrRCxZQUFZO1VBQzlELENBQUMsTUFBTTtZQUNMWCxDQUFDLENBQUNnRyxpQkFBRixDQUFvQixLQUFwQjtVQUNELENBRkQsRUFFR3pHLE1BRkgsQ0FFVXdHLEtBRlY7UUFHRCxDQUpDLENBQUY7TUFLRCxDQVpPLENBQVI7TUFjQWhHLFFBQVEsQ0FBQyxXQUFELEVBQWMsWUFBWTtRQUNoQ1ksRUFBRSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7VUFDL0NYLENBQUMsQ0FBQ2tHLFFBQUYsQ0FBVzNHLE1BQVgsQ0FBa0JpQyxFQUFsQixDQUFxQm1FLEVBQXJCLENBQXdCQyxVQUF4QixDQUFtQ0MsUUFBbkM7UUFDRCxDQUZDLENBQUY7UUFHQWxGLEVBQUUsQ0FBQyx3Q0FBRCxFQUEyQyxZQUFZO1VBQ3ZEWCxDQUFDLENBQUNrRyxRQUFGLENBQVczRSxNQUFYLEVBQW1CaEMsTUFBbkIsQ0FBMEJpQyxFQUExQixDQUE2QkMsQ0FBN0IsQ0FBK0IsU0FBL0I7UUFDRCxDQUZDLENBQUY7UUFHQWQsRUFBRSxDQUFDLCtDQUFELEVBQWtELFlBQVk7VUFDOUQsQ0FBQyxNQUFNO1lBQ0xYLENBQUMsQ0FBQ2tHLFFBQUY7VUFDRCxDQUZELEVBRUczRyxNQUZILENBRVV3RyxLQUZWO1FBR0QsQ0FKQyxDQUFGO01BS0QsQ0FaTyxDQUFSO01BY0FoRyxRQUFRLENBQUMsc0JBQUQsRUFBeUIsWUFBWTtRQUMzQ1ksRUFBRSxDQUFDLHdDQUFELEVBQTJDLFlBQVk7VUFDdkQsTUFBTXdGLFNBQVMsR0FBR2pHLE9BQU8sQ0FBQ3lDLElBQVIsQ0FBYTNDLENBQWIsRUFBZ0IsbUJBQWhCLENBQWxCO1VBRUFtRyxTQUFTLENBQUNDLE9BQVYsQ0FBa0IsQ0FBQyxDQUFDLE1BQUQsRUFBUyxPQUFULENBQUQsRUFBb0IsQ0FBQyxLQUFELENBQXBCLENBQWxCO1VBQ0EsQ0FBQyxNQUFNO1lBRUxwRyxDQUFDLENBQUNxRyxtQkFBRjtVQUNELENBSEQsRUFHRzlHLE1BSEgsQ0FHVXdHLEtBSFY7VUFJQUksU0FBUyxDQUFDQyxPQUFWLENBQWtCLENBQ2hCLENBQUMsTUFBRCxFQUFTLE9BQVQsQ0FEZ0IsRUFHaEIsQ0FBQyxLQUFELEVBQVEsTUFBUixFQUFnQixLQUFoQixDQUhnQixDQUFsQjtVQUtBLENBQUMsTUFBTTtZQUVMcEcsQ0FBQyxDQUFDcUcsbUJBQUY7VUFDRCxDQUhELEVBR0c5RyxNQUhILENBR1V3RyxLQUhWO1FBSUQsQ0FqQkMsQ0FBRjtRQWtCQXBGLEVBQUUsQ0FBQyxnQ0FBRCxFQUFtQyxZQUFZO1VBQy9DLE1BQU13RixTQUFTLEdBQUdqRyxPQUFPLENBQUN5QyxJQUFSLENBQWEzQyxDQUFiLEVBQWdCLG1CQUFoQixDQUFsQjtVQUNBbUcsU0FBUyxDQUFDQyxPQUFWLENBQWtCLENBQ2hCLENBQUMsTUFBRCxFQUFTLE1BQVQsQ0FEZ0IsRUFHaEIsQ0FBQyxRQUFELEVBQVcsTUFBWCxDQUhnQixDQUFsQjtVQUtBLENBQUMsTUFBTTtZQUVMcEcsQ0FBQyxDQUFDcUcsbUJBQUY7VUFDRCxDQUhELEVBR0c5RyxNQUhILENBR1V3RyxLQUhWO1FBSUQsQ0FYQyxDQUFGO1FBWUFwRixFQUFFLENBQUMsZ0NBQUQsRUFBbUMsWUFBWTtVQUMvQyxNQUFNd0YsU0FBUyxHQUFHakcsT0FBTyxDQUFDeUMsSUFBUixDQUFhM0MsQ0FBYixFQUFnQixtQkFBaEIsQ0FBbEI7VUFDQW1HLFNBQVMsQ0FBQ0MsT0FBVixDQUFrQixDQUNoQixDQUFDLE1BQUQsRUFBUyxNQUFULENBRGdCLEVBR2hCLENBQUMsS0FBRCxFQUFRLE1BQVIsQ0FIZ0IsQ0FBbEI7VUFLQSxDQUFDLE1BQU07WUFFTHBHLENBQUMsQ0FBQ3FHLG1CQUFGO1VBQ0QsQ0FIRCxFQUdHOUcsTUFISCxDQUdVd0csS0FIVjtRQUlELENBWEMsQ0FBRjtRQVlBcEYsRUFBRSxDQUFDLGlEQUFELEVBQW9ELFlBQVk7VUFDaEUsTUFBTXdGLFNBQVMsR0FBR2pHLE9BQU8sQ0FBQ3lDLElBQVIsQ0FBYTNDLENBQWIsRUFBZ0IsbUJBQWhCLENBQWxCO1VBQ0FtRyxTQUFTLENBQUNDLE9BQVYsQ0FBa0IsQ0FBQyxDQUFDLE1BQUQsRUFBUyxRQUFULENBQUQsQ0FBbEI7VUFDQXBHLENBQUMsQ0FBQ3FHLG1CQUFGLENBQXNCLEtBQXRCLEVBQTZCLE1BQTdCLEVBQXFDLFVBQXJDLEVBQWlEOUcsTUFBakQsQ0FBd0RpQyxFQUF4RCxDQUEyRDhFLElBQTNEO1FBQ0QsQ0FKQyxDQUFGO1FBS0EzRixFQUFFLENBQUMscUNBQUQsRUFBd0MsWUFBWTtVQUNwRCxNQUFNd0YsU0FBUyxHQUFHakcsT0FBTyxDQUFDeUMsSUFBUixDQUFhM0MsQ0FBYixFQUFnQixtQkFBaEIsQ0FBbEI7VUFDQW1HLFNBQVMsQ0FBQ0MsT0FBVixDQUFrQixDQUFDLENBQUMsTUFBRCxFQUFTLFFBQVQsQ0FBRCxDQUFsQjtVQUNBcEcsQ0FBQyxDQUFDcUcsbUJBQUYsQ0FBc0IsS0FBdEIsRUFBNkIsTUFBN0IsRUFBcUMsVUFBckMsRUFBaUQ5RyxNQUFqRCxDQUF3RGlDLEVBQXhELENBQTJEOEUsSUFBM0Q7UUFDRCxDQUpDLENBQUY7UUFLQTNGLEVBQUUsQ0FBQyxzREFBRCxFQUF5RCxZQUFZO1VBQ3JFLE1BQU13RixTQUFTLEdBQUdqRyxPQUFPLENBQUN5QyxJQUFSLENBQWEzQyxDQUFiLEVBQWdCLG1CQUFoQixDQUFsQjtVQUNBbUcsU0FBUyxDQUFDQyxPQUFWLENBQWtCLENBQUMsQ0FBQyxNQUFELEVBQVMsUUFBVCxDQUFELENBQWxCO1VBQ0FwRyxDQUFDLENBQUNxRyxtQkFBRixDQUFzQixLQUF0QixFQUE2QixLQUE3QixFQUFvQyxVQUFwQyxFQUFnRDlHLE1BQWhELENBQXVEaUMsRUFBdkQsQ0FBMERzRSxLQUExRDtVQUNBOUYsQ0FBQyxDQUFDcUcsbUJBQUYsQ0FBc0IsS0FBdEIsRUFBNkIsTUFBN0IsRUFBcUMsTUFBckMsRUFBNkM5RyxNQUE3QyxDQUFvRGlDLEVBQXBELENBQXVEc0UsS0FBdkQ7UUFDRCxDQUxDLENBQUY7TUFNRCxDQTNETyxDQUFSO0lBNERELENBM0dPLENBQVI7SUE2R0EvRixRQUFRLENBQUMsd0JBQUQsRUFBMkIsWUFBWTtNQUM3QyxJQUFJd0csZUFBSjtNQUNBcEcsVUFBVSxDQUFDLGtCQUFrQjtRQUMzQm9HLGVBQWUsR0FBR3pDLElBQUksQ0FBQ0MsR0FBTCxFQUFsQjtRQUNBL0QsQ0FBQyxDQUFDd0csa0JBQUYsR0FBdUIsS0FBdkI7UUFDQSxNQUFNeEcsQ0FBQyxDQUFDZ0QsY0FBRixDQUFpQixlQUFqQixFQUFrQyxJQUFsQyxFQUF3QyxJQUF4QyxFQUE4QztVQUNsRDNDLFdBQVcsRUFBRSxFQUFDLEdBQUdUO1VBQUosQ0FEcUM7VUFFbERXLFVBQVUsRUFBRSxDQUFDLEVBQUQ7UUFGc0MsQ0FBOUMsQ0FBTjtNQUlELENBUFMsQ0FBVjtNQVFBUixRQUFRLENBQUMsZUFBRCxFQUFrQixZQUFZO1FBQ3BDWSxFQUFFLENBQUMsc0NBQUQsRUFBeUMsWUFBWTtVQUNyRHBCLE1BQU0sQ0FBQ3NCLEtBQVAsQ0FBYWIsQ0FBQyxDQUFDeUcsWUFBZjtVQUNBbEgsTUFBTSxDQUFDc0IsS0FBUCxDQUFhYixDQUFDLENBQUN5RyxZQUFGLENBQWVDLFFBQTVCO1FBQ0QsQ0FIQyxDQUFGO1FBS0EvRixFQUFFLENBQUMsd0RBQUQsRUFBMkQsWUFBWTtVQUN2RSxJQUFJO1lBQUNnRyxtQkFBRDtZQUFzQkM7VUFBdEIsSUFBMkM1RyxDQUFDLENBQUN5RyxZQUFqRDtVQUNBRSxtQkFBbUIsQ0FBQ3BILE1BQXBCLENBQTJCNkYsSUFBM0IsQ0FBZ0MxRCxNQUFoQyxDQUF1QyxDQUF2QztVQUNBa0YsaUJBQWlCLENBQUNySCxNQUFsQixDQUF5QjZGLElBQXpCLENBQThCMUQsTUFBOUIsQ0FBcUMsQ0FBckM7VUFDQWlGLG1CQUFtQixDQUFDLENBQUQsQ0FBbkIsQ0FBdUJwSCxNQUF2QixDQUE4QmlDLEVBQTlCLENBQWlDQyxDQUFqQyxDQUFtQyxRQUFuQztVQUNBbUYsaUJBQWlCLENBQUMsQ0FBRCxDQUFqQixDQUFxQnJILE1BQXJCLENBQTRCaUMsRUFBNUIsQ0FBK0JDLENBQS9CLENBQWlDLFFBQWpDO1VBQ0EsQ0FBQ2tGLG1CQUFtQixDQUFDLENBQUQsQ0FBbkIsSUFBMEJKLGVBQTNCLEVBQTRDaEgsTUFBNUMsQ0FBbURpQyxFQUFuRCxDQUFzRDhFLElBQXREO1VBQ0EsQ0FBQ00saUJBQWlCLENBQUMsQ0FBRCxDQUFqQixJQUF3QkQsbUJBQW1CLENBQUMsQ0FBRCxDQUE1QyxFQUFpRHBILE1BQWpELENBQXdEaUMsRUFBeEQsQ0FBMkQ4RSxJQUEzRDtRQUNELENBUkMsQ0FBRjtRQVVBM0YsRUFBRSxDQUFDLGdDQUFELEVBQW1DLGtCQUFrQjtVQUNyRCxNQUFNWCxDQUFDLENBQUNnRCxjQUFGLENBQWlCLFdBQWpCLEVBQThCLEVBQTlCLENBQU47VUFDQWhELENBQUMsQ0FBQ3lHLFlBQUYsQ0FBZUMsUUFBZixDQUF3QmhGLE1BQXhCLENBQStCbkMsTUFBL0IsQ0FBc0N5QyxLQUF0QyxDQUE0QyxDQUE1QztVQUNBaEMsQ0FBQyxDQUFDeUcsWUFBRixDQUFlQyxRQUFmLENBQXdCLENBQXhCLEVBQTJCRyxHQUEzQixDQUErQnRILE1BQS9CLENBQXNDeUMsS0FBdEMsQ0FBNEMsV0FBNUM7VUFDQWhDLENBQUMsQ0FBQ3lHLFlBQUYsQ0FBZUMsUUFBZixDQUF3QixDQUF4QixFQUEyQkksU0FBM0IsQ0FBcUN2SCxNQUFyQyxDQUE0Q2lDLEVBQTVDLENBQStDQyxDQUEvQyxDQUFpRCxRQUFqRDtVQUNBekIsQ0FBQyxDQUFDeUcsWUFBRixDQUFlQyxRQUFmLENBQXdCLENBQXhCLEVBQTJCSyxPQUEzQixDQUFtQ3hILE1BQW5DLENBQTBDaUMsRUFBMUMsQ0FBNkNDLENBQTdDLENBQStDLFFBQS9DO1FBQ0QsQ0FOQyxDQUFGO01BT0QsQ0F2Qk8sQ0FBUjtNQXdCQTFCLFFBQVEsQ0FBQyxXQUFELEVBQWMsWUFBWTtRQUNoQ1ksRUFBRSxDQUFDLHVDQUFELEVBQTBDLFlBQVk7VUFDdERYLENBQUMsQ0FBQ2dILFFBQUYsQ0FBVyxLQUFYO1VBQ0FoSCxDQUFDLENBQUN5RyxZQUFGLENBQWVRLEdBQWYsQ0FBbUIsQ0FBbkIsRUFBc0IxSCxNQUF0QixDQUE2QmlDLEVBQTdCLENBQWdDQyxDQUFoQyxDQUFrQyxRQUFsQztVQUNBLENBQUN6QixDQUFDLENBQUN5RyxZQUFGLENBQWVRLEdBQWYsQ0FBbUIsQ0FBbkIsS0FBeUJWLGVBQTFCLEVBQTJDaEgsTUFBM0MsQ0FBa0RpQyxFQUFsRCxDQUFxRDhFLElBQXJEO1FBQ0QsQ0FKQyxDQUFGO1FBS0EzRixFQUFFLENBQUMsdURBQUQsRUFBMEQsWUFBWTtVQUN0RSxDQUFDLE1BQU07WUFDTFgsQ0FBQyxDQUFDZ0gsUUFBRixDQUFXLFVBQVg7VUFDRCxDQUZELEVBRUd6SCxNQUZILENBRVV3RyxLQUZWO1VBR0EsQ0FBQyxNQUFNO1lBRUwvRixDQUFDLENBQUNnSCxRQUFGLENBQVcsQ0FBWDtVQUNELENBSEQsRUFHR3pILE1BSEgsQ0FHVXdHLEtBSFY7VUFJQSxDQUFDLE1BQU07WUFFTC9GLENBQUMsQ0FBQ2dILFFBQUYsQ0FBVyxFQUFYO1VBQ0QsQ0FIRCxFQUdHekgsTUFISCxDQUdVd0csS0FIVjtRQUlELENBWkMsQ0FBRjtNQWFELENBbkJPLENBQVI7TUFvQkFwRixFQUFFLENBQUMsb0RBQUQsRUFBdUQsWUFBWTtRQUNuRVgsQ0FBQyxDQUFDZ0gsUUFBRixDQUFXLEtBQVg7UUFDQWhILENBQUMsQ0FBQ2dILFFBQUYsQ0FBVyxLQUFYO1FBQ0FoSCxDQUFDLENBQUN5RyxZQUFGLENBQWVTLEdBQWYsQ0FBbUIzSCxNQUFuQixDQUEwQjZGLElBQTFCLENBQStCMUQsTUFBL0IsQ0FBc0MsQ0FBdEM7UUFDQTFCLENBQUMsQ0FBQ3lHLFlBQUYsQ0FBZVMsR0FBZixDQUFtQixDQUFuQixFQUFzQjNILE1BQXRCLENBQTZCaUMsRUFBN0IsQ0FBZ0NDLENBQWhDLENBQWtDLFFBQWxDO1FBQ0EsQ0FBQ3pCLENBQUMsQ0FBQ3lHLFlBQUYsQ0FBZVMsR0FBZixDQUFtQixDQUFuQixLQUF5QmxILENBQUMsQ0FBQ3lHLFlBQUYsQ0FBZVMsR0FBZixDQUFtQixDQUFuQixDQUExQixFQUFpRDNILE1BQWpELENBQXdEaUMsRUFBeEQsQ0FBMkQ4RSxJQUEzRDtNQUNELENBTkMsQ0FBRjtNQU9BdkcsUUFBUSxDQUFDLHVCQUFELEVBQTBCLFlBQVk7UUFDNUNZLEVBQUUsQ0FBQywrREFBRCxFQUFrRSxrQkFBa0I7VUFBQTs7VUFDcEYsSUFBSXdHLEdBQUcsR0FBRyxNQUFNbkgsQ0FBQyxDQUFDb0MsVUFBRixFQUFoQjtVQUNBN0MsTUFBTSxDQUFDMkIsR0FBUCxDQUFXTCxLQUFYLENBQWlCc0csR0FBRyxDQUFDQyxNQUFyQjs7VUFFQXhGLGVBQUEsQ0FBRXlGLEdBQUYsQ0FBTXJILENBQU4sRUFBUyxtQkFBVCxFQUE4QixJQUE5Qjs7VUFDQW1ILEdBQUcsR0FBRyxNQUFNbkgsQ0FBQyxDQUFDb0MsVUFBRixFQUFaO1VBQ0E3QyxNQUFNLENBQUNzQixLQUFQLENBQWFzRyxHQUFHLENBQUNDLE1BQWpCO1VBQ0E3SCxNQUFNLENBQUNzQixLQUFQLGdCQUFhc0csR0FBRyxDQUFDQyxNQUFqQixnREFBYSxZQUFZVCxtQkFBekI7VUFDQWxILE1BQU0saUJBQUMwSCxHQUFHLENBQUNDLE1BQUwsaURBQUMsYUFBWVQsbUJBQVosQ0FBZ0MsQ0FBaEMsQ0FBRCxDQUFOLENBQTJDeEYsRUFBM0MsQ0FBOENLLEVBQTlDLENBQWlEQyxDQUFqRCxDQUFtRCxRQUFuRDtRQUNELENBVEMsQ0FBRjtNQVVELENBWE8sQ0FBUjtJQVlELENBekVPLENBQVI7SUEwRUExQixRQUFRLENBQUMsUUFBRCxFQUFXLFlBQVk7TUFDN0JZLEVBQUUsQ0FBQyxxREFBRCxFQUF3RCxrQkFBa0I7UUFDMUUsTUFBTXdCLElBQUksR0FBRztVQUNYOUIsV0FBVyxFQUFFO1lBQ1gsY0FBYyxNQURIO1lBRVgscUJBQXFCLE1BRlY7WUFHWCx5QkFBeUIsTUFIZDtZQUlYQyxZQUFZLEVBQUUsTUFKSDtZQUtYLEdBQUdWO1VBTFEsQ0FERjtVQVNYVyxVQUFVLEVBQUUsQ0FBQyxFQUFEO1FBVEQsQ0FBYjtRQVdBLE1BQU1QLENBQUMsQ0FBQ2lCLGFBQUYsQ0FBZ0JrQixJQUFoQixDQUFOO1FBQ0ExQyxNQUFNLENBQUNPLENBQUMsQ0FBQzBELFFBQUgsQ0FBTixDQUFtQnZDLEVBQW5CLENBQXNCYSxLQUF0QixDQUE0QixLQUE1QjtRQUNBLE1BQU1oQyxDQUFDLENBQUNzSCxLQUFGLEVBQU47UUFDQTdILE1BQU0sQ0FBQ08sQ0FBQyxDQUFDMEQsUUFBSCxDQUFOLENBQW1CdkMsRUFBbkIsQ0FBc0JhLEtBQXRCLENBQTRCLEtBQTVCO01BQ0QsQ0FoQkMsQ0FBRjtJQWlCRCxDQWxCTyxDQUFSO0VBbUJELENBL2lCTyxDQUFSO0VBaWpCQWpDLFFBQVEsQ0FBQyxtQkFBRCxFQUFzQixZQUFZO0lBQ3hDLElBQUlDLENBQUo7SUFFQUcsVUFBVSxDQUFDLFlBQVk7TUFDckJILENBQUMsR0FBRyxJQUFJTCxXQUFKLEVBQUo7SUFDRCxDQUZTLENBQVY7SUFJQWdCLEVBQUUsQ0FBQywrREFBRCxFQUFrRSxZQUFZO01BQzlFWCxDQUFDLENBQUN1SCxhQUFGLEdBQWtCLENBQUMsS0FBRCxFQUFRLEtBQVIsQ0FBbEI7TUFDQXZILENBQUMsQ0FBQ3dILGdCQUFGLENBQW1CLEtBQW5CLEVBQTBCakksTUFBMUIsQ0FBaUNpQyxFQUFqQyxDQUFvQzhFLElBQXBDO01BQ0F0RyxDQUFDLENBQUN3SCxnQkFBRixDQUFtQixLQUFuQixFQUEwQmpJLE1BQTFCLENBQWlDaUMsRUFBakMsQ0FBb0M4RSxJQUFwQztNQUNBdEcsQ0FBQyxDQUFDd0gsZ0JBQUYsQ0FBbUIsS0FBbkIsRUFBMEJqSSxNQUExQixDQUFpQ2lDLEVBQWpDLENBQW9Dc0UsS0FBcEM7SUFDRCxDQUxDLENBQUY7SUFPQW5GLEVBQUUsQ0FBQywwREFBRCxFQUE2RCxZQUFZO01BQ3pFWCxDQUFDLENBQUN1SCxhQUFGLEdBQWtCLEVBQWxCO01BQ0F2SCxDQUFDLENBQUN3SCxnQkFBRixDQUFtQixLQUFuQixFQUEwQmpJLE1BQTFCLENBQWlDaUMsRUFBakMsQ0FBb0NzRSxLQUFwQztJQUNELENBSEMsQ0FBRjtJQUtBbkYsRUFBRSxDQUFDLDZDQUFELEVBQWdELFlBQVk7TUFDNURYLENBQUMsQ0FBQ3VILGFBQUYsR0FBa0IsQ0FBQyxLQUFELEVBQVEsS0FBUixDQUFsQjtNQUNBdkgsQ0FBQyxDQUFDeUgsWUFBRixHQUFpQixDQUFDLEtBQUQsQ0FBakI7TUFDQXpILENBQUMsQ0FBQ3dILGdCQUFGLENBQW1CLEtBQW5CLEVBQTBCakksTUFBMUIsQ0FBaUNpQyxFQUFqQyxDQUFvQ3NFLEtBQXBDO01BQ0E5RixDQUFDLENBQUN3SCxnQkFBRixDQUFtQixLQUFuQixFQUEwQmpJLE1BQTFCLENBQWlDaUMsRUFBakMsQ0FBb0M4RSxJQUFwQztNQUNBdEcsQ0FBQyxDQUFDd0gsZ0JBQUYsQ0FBbUIsS0FBbkIsRUFBMEJqSSxNQUExQixDQUFpQ2lDLEVBQWpDLENBQW9Dc0UsS0FBcEM7SUFDRCxDQU5DLENBQUY7SUFRQW5GLEVBQUUsQ0FBQyw0Q0FBRCxFQUErQyxZQUFZO01BQzNEWCxDQUFDLENBQUMwSCxzQkFBRixHQUEyQixJQUEzQjtNQUNBMUgsQ0FBQyxDQUFDd0gsZ0JBQUYsQ0FBbUIsS0FBbkIsRUFBMEJqSSxNQUExQixDQUFpQ2lDLEVBQWpDLENBQW9DOEUsSUFBcEM7TUFDQXRHLENBQUMsQ0FBQ3dILGdCQUFGLENBQW1CLEtBQW5CLEVBQTBCakksTUFBMUIsQ0FBaUNpQyxFQUFqQyxDQUFvQzhFLElBQXBDO01BQ0F0RyxDQUFDLENBQUN3SCxnQkFBRixDQUFtQixLQUFuQixFQUEwQmpJLE1BQTFCLENBQWlDaUMsRUFBakMsQ0FBb0M4RSxJQUFwQztJQUNELENBTEMsQ0FBRjtJQU9BM0YsRUFBRSxDQUFDLHVDQUFELEVBQTBDLFlBQVk7TUFDdERYLENBQUMsQ0FBQzBILHNCQUFGLEdBQTJCLElBQTNCO01BQ0ExSCxDQUFDLENBQUN5SCxZQUFGLEdBQWlCLENBQUMsS0FBRCxFQUFRLEtBQVIsQ0FBakI7TUFDQXpILENBQUMsQ0FBQ3dILGdCQUFGLENBQW1CLEtBQW5CLEVBQTBCakksTUFBMUIsQ0FBaUNpQyxFQUFqQyxDQUFvQ3NFLEtBQXBDO01BQ0E5RixDQUFDLENBQUN3SCxnQkFBRixDQUFtQixLQUFuQixFQUEwQmpJLE1BQTFCLENBQWlDaUMsRUFBakMsQ0FBb0NzRSxLQUFwQztNQUNBOUYsQ0FBQyxDQUFDd0gsZ0JBQUYsQ0FBbUIsS0FBbkIsRUFBMEJqSSxNQUExQixDQUFpQ2lDLEVBQWpDLENBQW9DOEUsSUFBcEM7SUFDRCxDQU5DLENBQUY7RUFPRCxDQXpDTyxDQUFSO0FBMENEIn0=
|