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