appium-chromedriver 5.0.1 → 5.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/chromedriver.js +79 -67
- package/build/lib/utils.js +11 -2
- package/config/mapping.json +4 -0
- package/lib/chromedriver.js +77 -69
- package/lib/utils.js +15 -1
- package/package.json +6 -8
|
@@ -37,8 +37,6 @@ var _storageClient = _interopRequireDefault(require("./storage-client"));
|
|
|
37
37
|
|
|
38
38
|
var _protocolHelpers = require("./protocol-helpers");
|
|
39
39
|
|
|
40
|
-
const log = _support.logger.getLogger('Chromedriver');
|
|
41
|
-
|
|
42
40
|
const NEW_CD_VERSION_FORMAT_MAJOR_VERSION = 73;
|
|
43
41
|
const DEFAULT_HOST = '127.0.0.1';
|
|
44
42
|
const MIN_CD_VERSION_WITH_W3C_SUPPORT = 75;
|
|
@@ -69,6 +67,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
69
67
|
details,
|
|
70
68
|
isAutodownloadEnabled = false
|
|
71
69
|
} = args;
|
|
70
|
+
this._log = _support.logger.getLogger((0, _utils.generateLogPrefix)(this));
|
|
72
71
|
this.proxyHost = host;
|
|
73
72
|
this.proxyPort = port;
|
|
74
73
|
this.adb = adb;
|
|
@@ -83,7 +82,8 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
83
82
|
this.state = Chromedriver.STATE_STOPPED;
|
|
84
83
|
this.jwproxy = new _baseDriver.JWProxy({
|
|
85
84
|
server: this.proxyHost,
|
|
86
|
-
port: this.proxyPort
|
|
85
|
+
port: this.proxyPort,
|
|
86
|
+
log: this._log
|
|
87
87
|
});
|
|
88
88
|
this.verbose = verbose;
|
|
89
89
|
this.logPath = logPath;
|
|
@@ -96,25 +96,29 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
96
96
|
this.desiredProtocol = _baseDriver.PROTOCOLS.MJSONWP;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
get log() {
|
|
100
|
+
return this._log;
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
async getDriversMapping() {
|
|
100
104
|
let mapping = _lodash.default.cloneDeep(_utils.CHROMEDRIVER_CHROME_MAPPING);
|
|
101
105
|
|
|
102
106
|
if (this.mappingPath) {
|
|
103
|
-
log.debug(`Attempting to use Chromedriver->Chrome mapping from '${this.mappingPath}'`);
|
|
107
|
+
this.log.debug(`Attempting to use Chromedriver->Chrome mapping from '${this.mappingPath}'`);
|
|
104
108
|
|
|
105
109
|
if (!(await _support.fs.exists(this.mappingPath))) {
|
|
106
|
-
log.warn(`No file found at '${this.mappingPath}'`);
|
|
107
|
-
log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
110
|
+
this.log.warn(`No file found at '${this.mappingPath}'`);
|
|
111
|
+
this.log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
108
112
|
} else {
|
|
109
113
|
try {
|
|
110
114
|
mapping = JSON.parse(await _support.fs.readFile(this.mappingPath, 'utf8'));
|
|
111
115
|
} catch (err) {
|
|
112
|
-
log.warn(`Error parsing mapping from '${this.mappingPath}': ${err.message}`);
|
|
113
|
-
log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
116
|
+
this.log.warn(`Error parsing mapping from '${this.mappingPath}': ${err.message}`);
|
|
117
|
+
this.log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
} else {
|
|
117
|
-
log.debug('Using the static Chromedriver->Chrome mapping');
|
|
121
|
+
this.log.debug('Using the static Chromedriver->Chrome mapping');
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
for (const [cdVersion, chromeVersion] of _lodash.default.toPairs(mapping)) {
|
|
@@ -123,7 +127,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
123
127
|
if (coercedVersion) {
|
|
124
128
|
mapping[cdVersion] = coercedVersion.version;
|
|
125
129
|
} else {
|
|
126
|
-
log.info(`'${chromeVersion}' is not a valid version number. Skipping it`);
|
|
130
|
+
this.log.info(`'${chromeVersion}' is not a valid version number. Skipping it`);
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
133
|
|
|
@@ -131,9 +135,14 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
async getChromedrivers(mapping) {
|
|
134
|
-
const executables = await _support.fs.glob(
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
const executables = await _support.fs.glob('*', {
|
|
139
|
+
cwd: this.executableDir,
|
|
140
|
+
strict: false,
|
|
141
|
+
nodir: true,
|
|
142
|
+
absolute: true
|
|
143
|
+
});
|
|
144
|
+
this.log.debug(`Found ${_support.util.pluralize('executable', executables.length, true)} ` + `in '${this.executableDir}'`);
|
|
145
|
+
const cds = (await (0, _asyncbox.asyncmap)(executables, async executable => {
|
|
137
146
|
const logError = ({
|
|
138
147
|
message,
|
|
139
148
|
stdout = null,
|
|
@@ -149,7 +158,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
149
158
|
errMsg += `\nStderr: ${stderr}`;
|
|
150
159
|
}
|
|
151
160
|
|
|
152
|
-
log.warn(errMsg);
|
|
161
|
+
this.log.warn(errMsg);
|
|
153
162
|
return null;
|
|
154
163
|
};
|
|
155
164
|
|
|
@@ -205,14 +214,14 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
205
214
|
})).filter(cd => !!cd).sort((a, b) => (0, _compareVersions.default)(b.version, a.version));
|
|
206
215
|
|
|
207
216
|
if (_lodash.default.isEmpty(cds)) {
|
|
208
|
-
log.info(`No Chromedrivers were found in '${this.executableDir}'`);
|
|
217
|
+
this.log.info(`No Chromedrivers were found in '${this.executableDir}'`);
|
|
209
218
|
return cds;
|
|
210
219
|
}
|
|
211
220
|
|
|
212
|
-
log.debug(`The following Chromedriver executables were found:`);
|
|
221
|
+
this.log.debug(`The following Chromedriver executables were found:`);
|
|
213
222
|
|
|
214
223
|
for (const cd of cds) {
|
|
215
|
-
log.debug(` '${cd.executable}' (version '${cd.version}', minimum Chrome version '${cd.minChromeVersion ? cd.minChromeVersion : 'Unknown'}')`);
|
|
224
|
+
this.log.debug(` '${cd.executable}' (version '${cd.version}', minimum Chrome version '${cd.minChromeVersion ? cd.minChromeVersion : 'Unknown'}')`);
|
|
216
225
|
}
|
|
217
226
|
|
|
218
227
|
return cds;
|
|
@@ -224,7 +233,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
224
233
|
if ((_this$details = this.details) !== null && _this$details !== void 0 && _this$details.info) {
|
|
225
234
|
var _this$details2, _this$details2$info;
|
|
226
235
|
|
|
227
|
-
log.debug(`Browser version in the supplied details: ${(_this$details2 = this.details) === null || _this$details2 === void 0 ? void 0 : (_this$details2$info = _this$details2.info) === null || _this$details2$info === void 0 ? void 0 : _this$details2$info.Browser}`);
|
|
236
|
+
this.log.debug(`Browser version in the supplied details: ${(_this$details2 = this.details) === null || _this$details2 === void 0 ? void 0 : (_this$details2$info = _this$details2.info) === null || _this$details2$info === void 0 ? void 0 : _this$details2$info.Browser}`);
|
|
228
237
|
}
|
|
229
238
|
|
|
230
239
|
const versionMatch = VERSION_PATTERN.exec((_this$details3 = this.details) === null || _this$details3 === void 0 ? void 0 : (_this$details3$info = _this$details3.info) === null || _this$details3$info === void 0 ? void 0 : _this$details3$info.Browser);
|
|
@@ -288,7 +297,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
288
297
|
await _support.fs.writeFile(this.mappingPath, JSON.stringify(newMapping, null, 2), 'utf8');
|
|
289
298
|
shouldUpdateStaticMapping = false;
|
|
290
299
|
} catch (e) {
|
|
291
|
-
log.warn(`Cannot store the updated chromedrivers mapping into '${this.mappingPath}'. ` + `This may reduce the performance of further executions. Original error: ${e.message}`);
|
|
300
|
+
this.log.warn(`Cannot store the updated chromedrivers mapping into '${this.mappingPath}'. ` + `This may reduce the performance of further executions. Original error: ${e.message}`);
|
|
292
301
|
}
|
|
293
302
|
}
|
|
294
303
|
|
|
@@ -305,7 +314,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
305
314
|
const mapping = await this.getDriversMapping();
|
|
306
315
|
|
|
307
316
|
if (!_lodash.default.isEmpty(mapping)) {
|
|
308
|
-
log.debug(`The most recent known Chrome version: ${_lodash.default.values(mapping)[0]}`);
|
|
317
|
+
this.log.debug(`The most recent known Chrome version: ${_lodash.default.values(mapping)[0]}`);
|
|
309
318
|
}
|
|
310
319
|
|
|
311
320
|
let didStorageSync = false;
|
|
@@ -313,7 +322,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
313
322
|
const syncChromedrivers = async chromeVersion => {
|
|
314
323
|
didStorageSync = true;
|
|
315
324
|
const retrievedMapping = await this.storageClient.retrieveMapping();
|
|
316
|
-
log.debug('Got chromedrivers mapping from the storage: ' + JSON.stringify(retrievedMapping, null, 2));
|
|
325
|
+
this.log.debug('Got chromedrivers mapping from the storage: ' + JSON.stringify(retrievedMapping, null, 2));
|
|
317
326
|
const driverKeys = await this.storageClient.syncDrivers({
|
|
318
327
|
minBrowserVersion: chromeVersion.major
|
|
319
328
|
});
|
|
@@ -357,21 +366,21 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
357
366
|
}
|
|
358
367
|
|
|
359
368
|
if (!_lodash.default.isEmpty(missingVersions)) {
|
|
360
|
-
log.info(`Found ${_support.util.pluralize('Chromedriver', _lodash.default.size(missingVersions), true)}, ` + `which ${_lodash.default.size(missingVersions) === 1 ? 'is' : 'are'} missing in the list of known versions: ` + JSON.stringify(missingVersions));
|
|
369
|
+
this.log.info(`Found ${_support.util.pluralize('Chromedriver', _lodash.default.size(missingVersions), true)}, ` + `which ${_lodash.default.size(missingVersions) === 1 ? 'is' : 'are'} missing in the list of known versions: ` + JSON.stringify(missingVersions));
|
|
361
370
|
await this.updateDriversMapping(Object.assign(mapping, missingVersions));
|
|
362
371
|
}
|
|
363
372
|
|
|
364
373
|
if (this.disableBuildCheck) {
|
|
365
374
|
if (_lodash.default.isEmpty(cds)) {
|
|
366
|
-
log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` + `'chromedriverDisableBuildCheck' capability is set to 'true'`);
|
|
375
|
+
this.log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` + `'chromedriverDisableBuildCheck' capability is set to 'true'`);
|
|
367
376
|
}
|
|
368
377
|
|
|
369
378
|
const {
|
|
370
379
|
version,
|
|
371
380
|
executable
|
|
372
381
|
} = cds[0];
|
|
373
|
-
log.warn(`Chrome build check disabled. Using most recent Chromedriver version (${version}, at '${executable}')`);
|
|
374
|
-
log.warn(`If this is wrong, set 'chromedriverDisableBuildCheck' capability to 'false'`);
|
|
382
|
+
this.log.warn(`Chrome build check disabled. Using most recent Chromedriver version (${version}, at '${executable}')`);
|
|
383
|
+
this.log.warn(`If this is wrong, set 'chromedriverDisableBuildCheck' capability to 'false'`);
|
|
375
384
|
return executable;
|
|
376
385
|
}
|
|
377
386
|
|
|
@@ -379,18 +388,18 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
379
388
|
|
|
380
389
|
if (!chromeVersion) {
|
|
381
390
|
if (_lodash.default.isEmpty(cds)) {
|
|
382
|
-
log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` + `the current Chrome version cannot be determined`);
|
|
391
|
+
this.log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` + `the current Chrome version cannot be determined`);
|
|
383
392
|
}
|
|
384
393
|
|
|
385
394
|
const {
|
|
386
395
|
version,
|
|
387
396
|
executable
|
|
388
397
|
} = cds[0];
|
|
389
|
-
log.warn(`Unable to discover Chrome version. Using Chromedriver ${version} at '${executable}'`);
|
|
398
|
+
this.log.warn(`Unable to discover Chrome version. Using Chromedriver ${version} at '${executable}'`);
|
|
390
399
|
return executable;
|
|
391
400
|
}
|
|
392
401
|
|
|
393
|
-
log.debug(`Found Chrome bundle '${this.bundleId}' version '${chromeVersion}'`);
|
|
402
|
+
this.log.debug(`Found Chrome bundle '${this.bundleId}' version '${chromeVersion}'`);
|
|
394
403
|
const matchingDrivers = cds.filter(({
|
|
395
404
|
minChromeVersion
|
|
396
405
|
}) => {
|
|
@@ -410,8 +419,8 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
410
419
|
continue;
|
|
411
420
|
}
|
|
412
421
|
} catch (e) {
|
|
413
|
-
log.warn(`Cannot synchronize local chromedrivers with the remote storage at ${_utils.CD_CDN}: ` + e.message);
|
|
414
|
-
log.debug(e.stack);
|
|
422
|
+
this.log.warn(`Cannot synchronize local chromedrivers with the remote storage at ${_utils.CD_CDN}: ` + e.message);
|
|
423
|
+
this.log.debug(e.stack);
|
|
415
424
|
}
|
|
416
425
|
}
|
|
417
426
|
|
|
@@ -420,8 +429,8 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
420
429
|
}
|
|
421
430
|
|
|
422
431
|
const binPath = matchingDrivers[0].executable;
|
|
423
|
-
log.debug(`Found ${_support.util.pluralize('executable', matchingDrivers.length, true)} ` + `capable of automating Chrome '${chromeVersion}'.\nChoosing the most recent, '${binPath}'.`);
|
|
424
|
-
log.debug('If a specific version is required, specify it with the `chromedriverExecutable`' + 'desired capability.');
|
|
432
|
+
this.log.debug(`Found ${_support.util.pluralize('executable', matchingDrivers.length, true)} ` + `capable of automating Chrome '${chromeVersion}'.\nChoosing the most recent, '${binPath}'.`);
|
|
433
|
+
this.log.debug('If a specific version is required, specify it with the `chromedriverExecutable`' + 'desired capability.');
|
|
425
434
|
return binPath;
|
|
426
435
|
} while (true);
|
|
427
436
|
}
|
|
@@ -438,21 +447,21 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
438
447
|
}
|
|
439
448
|
|
|
440
449
|
this.executableVerified = true;
|
|
441
|
-
log.info(`Set chromedriver binary as: ${this.chromedriver}`);
|
|
450
|
+
this.log.info(`Set chromedriver binary as: ${this.chromedriver}`);
|
|
442
451
|
}
|
|
443
452
|
|
|
444
453
|
syncProtocol(cdVersion = null) {
|
|
445
454
|
const coercedVersion = _semver.default.coerce(cdVersion);
|
|
446
455
|
|
|
447
456
|
if (!coercedVersion || coercedVersion.major < MIN_CD_VERSION_WITH_W3C_SUPPORT) {
|
|
448
|
-
log.debug(`Chromedriver v. ${cdVersion} does not fully support ${_baseDriver.PROTOCOLS.W3C} protocol. ` + `Defaulting to ${_baseDriver.PROTOCOLS.MJSONWP}`);
|
|
457
|
+
this.log.debug(`Chromedriver v. ${cdVersion} does not fully support ${_baseDriver.PROTOCOLS.W3C} protocol. ` + `Defaulting to ${_baseDriver.PROTOCOLS.MJSONWP}`);
|
|
449
458
|
return;
|
|
450
459
|
}
|
|
451
460
|
|
|
452
461
|
const chromeOptions = (0, _protocolHelpers.getCapValue)(this.capabilities, 'chromeOptions', {});
|
|
453
462
|
|
|
454
463
|
if (chromeOptions.w3c === false) {
|
|
455
|
-
log.info(`Chromedriver v. ${cdVersion} supports ${_baseDriver.PROTOCOLS.W3C} protocol, ` + `but ${_baseDriver.PROTOCOLS.MJSONWP} one has been explicitly requested`);
|
|
464
|
+
this.log.info(`Chromedriver v. ${cdVersion} supports ${_baseDriver.PROTOCOLS.W3C} protocol, ` + `but ${_baseDriver.PROTOCOLS.MJSONWP} one has been explicitly requested`);
|
|
456
465
|
return;
|
|
457
466
|
}
|
|
458
467
|
|
|
@@ -508,25 +517,25 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
508
517
|
|
|
509
518
|
if (match) {
|
|
510
519
|
webviewVersion = match[1];
|
|
511
|
-
log.debug(`Webview version: '${webviewVersion}'`);
|
|
520
|
+
this.log.debug(`Webview version: '${webviewVersion}'`);
|
|
512
521
|
}
|
|
513
522
|
|
|
514
523
|
match = /Starting ChromeDriver ([.\d]+)/.exec(out);
|
|
515
524
|
|
|
516
525
|
if (match) {
|
|
517
|
-
log.debug(`Chromedriver version: '${match[1]}'`);
|
|
526
|
+
this.log.debug(`Chromedriver version: '${match[1]}'`);
|
|
518
527
|
this.syncProtocol(match[1]);
|
|
519
528
|
}
|
|
520
529
|
|
|
521
530
|
if (this.verbose) {
|
|
522
531
|
for (let line of (stdout || '').trim().split('\n')) {
|
|
523
532
|
if (!line.trim().length) continue;
|
|
524
|
-
log.debug(`[STDOUT] ${line}`);
|
|
533
|
+
this.log.debug(`[STDOUT] ${line}`);
|
|
525
534
|
}
|
|
526
535
|
|
|
527
536
|
for (let line of (stderr || '').trim().split('\n')) {
|
|
528
537
|
if (!line.trim().length) continue;
|
|
529
|
-
log.error(`[STDERR] ${line}`);
|
|
538
|
+
this.log.error(`[STDERR] ${line}`);
|
|
530
539
|
}
|
|
531
540
|
}
|
|
532
541
|
});
|
|
@@ -534,17 +543,17 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
534
543
|
processIsAlive = false;
|
|
535
544
|
|
|
536
545
|
if (this.state !== Chromedriver.STATE_STOPPED && this.state !== Chromedriver.STATE_STOPPING && this.state !== Chromedriver.STATE_RESTARTING) {
|
|
537
|
-
|
|
538
|
-
log.error(msg);
|
|
546
|
+
const msg = `Chromedriver exited unexpectedly with code ${code}, signal ${signal}`;
|
|
547
|
+
this.log.error(msg);
|
|
539
548
|
this.changeState(Chromedriver.STATE_STOPPED);
|
|
540
549
|
}
|
|
541
550
|
});
|
|
542
|
-
log.info(`Spawning chromedriver with: ${this.chromedriver}
|
|
551
|
+
this.log.info(`Spawning chromedriver with: ${this.chromedriver} ${args.join(' ')}`);
|
|
543
552
|
await this.proc.start(startDetector);
|
|
544
553
|
await this.waitForOnline();
|
|
545
554
|
await this.startSession();
|
|
546
555
|
} catch (e) {
|
|
547
|
-
log.debug(e);
|
|
556
|
+
this.log.debug(e);
|
|
548
557
|
this.emit(Chromedriver.EVENT_ERROR, e);
|
|
549
558
|
|
|
550
559
|
if (processIsAlive) {
|
|
@@ -572,20 +581,16 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
572
581
|
}
|
|
573
582
|
|
|
574
583
|
message += e.message;
|
|
575
|
-
log.errorAndThrow(message);
|
|
584
|
+
this.log.errorAndThrow(message);
|
|
576
585
|
}
|
|
577
586
|
}
|
|
578
587
|
|
|
579
588
|
sessionId() {
|
|
580
|
-
|
|
581
|
-
return null;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
return this.jwproxy.sessionId;
|
|
589
|
+
return this.state === Chromedriver.STATE_ONLINE ? this.jwproxy.sessionId : null;
|
|
585
590
|
}
|
|
586
591
|
|
|
587
592
|
async restart() {
|
|
588
|
-
log.info('Restarting chromedriver');
|
|
593
|
+
this.log.info('Restarting chromedriver');
|
|
589
594
|
|
|
590
595
|
if (this.state !== Chromedriver.STATE_ONLINE) {
|
|
591
596
|
throw new Error("Can't restart when we're not online");
|
|
@@ -624,8 +629,9 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
624
629
|
} : {
|
|
625
630
|
desiredCapabilities: this.capabilities
|
|
626
631
|
};
|
|
627
|
-
log.info(`Starting ${this.desiredProtocol} Chromedriver session with capabilities: ` + JSON.stringify(sessionCaps, null, 2));
|
|
632
|
+
this.log.info(`Starting ${this.desiredProtocol} Chromedriver session with capabilities: ` + JSON.stringify(sessionCaps, null, 2));
|
|
628
633
|
await this.jwproxy.command('/session', 'POST', sessionCaps);
|
|
634
|
+
this.log.prefix = (0, _utils.generateLogPrefix)(this, this.jwproxy.sessionId);
|
|
629
635
|
this.changeState(Chromedriver.STATE_ONLINE);
|
|
630
636
|
}
|
|
631
637
|
|
|
@@ -634,21 +640,27 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
634
640
|
this.changeState(Chromedriver.STATE_STOPPING);
|
|
635
641
|
}
|
|
636
642
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
this.
|
|
643
|
+
const runSafeStep = async f => {
|
|
644
|
+
try {
|
|
645
|
+
return await f();
|
|
646
|
+
} catch (e) {
|
|
647
|
+
this.log.warn(e.message);
|
|
648
|
+
this.log.debug(e.stack);
|
|
643
649
|
}
|
|
644
|
-
}
|
|
645
|
-
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
await runSafeStep(() => this.jwproxy.command('', 'DELETE'));
|
|
653
|
+
await runSafeStep(() => this.proc.stop('SIGTERM', 20000));
|
|
654
|
+
this.log.prefix = (0, _utils.generateLogPrefix)(this);
|
|
655
|
+
|
|
656
|
+
if (emitStates) {
|
|
657
|
+
this.changeState(Chromedriver.STATE_STOPPED);
|
|
646
658
|
}
|
|
647
659
|
}
|
|
648
660
|
|
|
649
661
|
changeState(state) {
|
|
650
662
|
this.state = state;
|
|
651
|
-
log.debug(`Changed state to '${state}'`);
|
|
663
|
+
this.log.debug(`Changed state to '${state}'`);
|
|
652
664
|
this.emit(Chromedriver.EVENT_CHANGED, {
|
|
653
665
|
state
|
|
654
666
|
});
|
|
@@ -664,13 +676,13 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
664
676
|
|
|
665
677
|
async killAll() {
|
|
666
678
|
let cmd = _support.system.isWindows() ? `wmic process where "commandline like '%chromedriver.exe%--port=${this.proxyPort}%'" delete` : `pkill -15 -f "${this.chromedriver}.*--port=${this.proxyPort}"`;
|
|
667
|
-
log.debug(`Killing any old chromedrivers, running: ${cmd}`);
|
|
679
|
+
this.log.debug(`Killing any old chromedrivers, running: ${cmd}`);
|
|
668
680
|
|
|
669
681
|
try {
|
|
670
682
|
await _bluebird.default.promisify(_child_process.default.exec)(cmd);
|
|
671
|
-
log.debug('Successfully cleaned up old chromedrivers');
|
|
683
|
+
this.log.debug('Successfully cleaned up old chromedrivers');
|
|
672
684
|
} catch (err) {
|
|
673
|
-
log.warn('No old chromedrivers seem to exist');
|
|
685
|
+
this.log.warn('No old chromedrivers seem to exist');
|
|
674
686
|
}
|
|
675
687
|
|
|
676
688
|
if (this.adb) {
|
|
@@ -678,9 +690,9 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
678
690
|
const udid = udidIndex > -1 ? this.adb.executable.defaultArgs[udidIndex + 1] : null;
|
|
679
691
|
|
|
680
692
|
if (udid) {
|
|
681
|
-
log.debug(`Cleaning this device's adb forwarded port socket connections: ${udid}`);
|
|
693
|
+
this.log.debug(`Cleaning this device's adb forwarded port socket connections: ${udid}`);
|
|
682
694
|
} else {
|
|
683
|
-
log.debug(`Cleaning any old adb forwarded port socket connections`);
|
|
695
|
+
this.log.debug(`Cleaning any old adb forwarded port socket connections`);
|
|
684
696
|
}
|
|
685
697
|
|
|
686
698
|
try {
|
|
@@ -696,7 +708,7 @@ class Chromedriver extends _events.default.EventEmitter {
|
|
|
696
708
|
}
|
|
697
709
|
}
|
|
698
710
|
} catch (err) {
|
|
699
|
-
log.warn(`Unable to clean forwarded ports. Error: '${err.message}'. Continuing.`);
|
|
711
|
+
this.log.warn(`Unable to clean forwarded ports. Error: '${err.message}'. Continuing.`);
|
|
700
712
|
}
|
|
701
713
|
}
|
|
702
714
|
}
|
|
@@ -724,4 +736,4 @@ var _default = Chromedriver;
|
|
|
724
736
|
exports.default = _default;require('source-map-support').install();
|
|
725
737
|
|
|
726
738
|
|
|
727
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9jaHJvbWVkcml2ZXIuanMiXSwibmFtZXMiOlsibG9nIiwibG9nZ2VyIiwiZ2V0TG9nZ2VyIiwiTkVXX0NEX1ZFUlNJT05fRk9STUFUX01BSk9SX1ZFUlNJT04iLCJERUZBVUxUX0hPU1QiLCJNSU5fQ0RfVkVSU0lPTl9XSVRIX1czQ19TVVBQT1JUIiwiREVGQVVMVF9QT1JUIiwiQ0hST01FX0JVTkRMRV9JRCIsIldFQlZJRVdfU0hFTExfQlVORExFX0lEIiwiV0VCVklFV19CVU5ETEVfSURTIiwiQ0hST01FRFJJVkVSX1RVVE9SSUFMIiwiVkVSU0lPTl9QQVRURVJOIiwiQ0RfVkVSU0lPTl9USU1FT1VUIiwiQ2hyb21lZHJpdmVyIiwiZXZlbnRzIiwiRXZlbnRFbWl0dGVyIiwiY29uc3RydWN0b3IiLCJhcmdzIiwiaG9zdCIsInBvcnQiLCJ1c2VTeXN0ZW1FeGVjdXRhYmxlIiwiZXhlY3V0YWJsZSIsImV4ZWN1dGFibGVEaXIiLCJidW5kbGVJZCIsIm1hcHBpbmdQYXRoIiwiY21kQXJncyIsImFkYiIsInZlcmJvc2UiLCJsb2dQYXRoIiwiZGlzYWJsZUJ1aWxkQ2hlY2siLCJkZXRhaWxzIiwiaXNBdXRvZG93bmxvYWRFbmFibGVkIiwicHJveHlIb3N0IiwicHJveHlQb3J0IiwicHJvYyIsImNocm9tZWRyaXZlciIsImV4ZWN1dGFibGVWZXJpZmllZCIsInN0YXRlIiwiU1RBVEVfU1RPUFBFRCIsImp3cHJveHkiLCJKV1Byb3h5Iiwic2VydmVyIiwic3RvcmFnZUNsaWVudCIsIkNocm9tZWRyaXZlclN0b3JhZ2VDbGllbnQiLCJjaHJvbWVkcml2ZXJEaXIiLCJjYXBhYmlsaXRpZXMiLCJkZXNpcmVkUHJvdG9jb2wiLCJQUk9UT0NPTFMiLCJNSlNPTldQIiwiZ2V0RHJpdmVyc01hcHBpbmciLCJtYXBwaW5nIiwiXyIsImNsb25lRGVlcCIsIkNIUk9NRURSSVZFUl9DSFJPTUVfTUFQUElORyIsImRlYnVnIiwiZnMiLCJleGlzdHMiLCJ3YXJuIiwiaW5mbyIsIkpTT04iLCJwYXJzZSIsInJlYWRGaWxlIiwiZXJyIiwibWVzc2FnZSIsImNkVmVyc2lvbiIsImNocm9tZVZlcnNpb24iLCJ0b1BhaXJzIiwiY29lcmNlZFZlcnNpb24iLCJzZW12ZXIiLCJjb2VyY2UiLCJ2ZXJzaW9uIiwiZ2V0Q2hyb21lZHJpdmVycyIsImV4ZWN1dGFibGVzIiwiZ2xvYiIsInV0aWwiLCJwbHVyYWxpemUiLCJsZW5ndGgiLCJjZHMiLCJtYXBDaHJvbWVkcml2ZXIiLCJsb2dFcnJvciIsInN0ZG91dCIsInN0ZGVyciIsImVyck1zZyIsInBhdGgiLCJiYXNlbmFtZSIsInRpbWVvdXQiLCJpbmNsdWRlcyIsIm1hdGNoIiwiZXhlYyIsIm1pbkNocm9tZVZlcnNpb24iLCJtYWpvciIsIm1pbm9yIiwiZmlsdGVyIiwiY2QiLCJzb3J0IiwiYSIsImIiLCJpc0VtcHR5IiwiZ2V0Q2hyb21lVmVyc2lvbiIsIkJyb3dzZXIiLCJ2ZXJzaW9uTWF0Y2giLCJhcGlMZXZlbCIsImdldEFwaUxldmVsIiwidXBkYXRlRHJpdmVyc01hcHBpbmciLCJuZXdNYXBwaW5nIiwic2hvdWxkVXBkYXRlU3RhdGljTWFwcGluZyIsIndyaXRlRmlsZSIsInN0cmluZ2lmeSIsImUiLCJPYmplY3QiLCJhc3NpZ24iLCJnZXRDb21wYXRpYmxlQ2hyb21lZHJpdmVyIiwidmFsdWVzIiwiZGlkU3RvcmFnZVN5bmMiLCJzeW5jQ2hyb21lZHJpdmVycyIsInJldHJpZXZlZE1hcHBpbmciLCJyZXRyaWV2ZU1hcHBpbmciLCJkcml2ZXJLZXlzIiwic3luY0RyaXZlcnMiLCJtaW5Ccm93c2VyVmVyc2lvbiIsInN5bmNocm9uaXplZERyaXZlcnNNYXBwaW5nIiwicmVkdWNlIiwiYWNjIiwieCIsIm1pc3NpbmdWZXJzaW9ucyIsImNvZXJjZWRWZXIiLCJzaXplIiwiZXJyb3JBbmRUaHJvdyIsIm1hdGNoaW5nRHJpdmVycyIsIm1pbkNocm9tZVZlcnNpb25TIiwiZ3RlIiwiQ0RfQ0ROIiwic3RhY2siLCJhdXRvZG93bmxvYWRTdWdnZXN0aW9uIiwiRXJyb3IiLCJiaW5QYXRoIiwiaW5pdENocm9tZWRyaXZlclBhdGgiLCJzeW5jUHJvdG9jb2wiLCJXM0MiLCJjaHJvbWVPcHRpb25zIiwidzNjIiwic3RhcnQiLCJjYXBzIiwiZW1pdFN0YXJ0aW5nU3RhdGUiLCJsb2dnaW5nUHJlZnMiLCJicm93c2VyIiwiY2hhbmdlU3RhdGUiLCJTVEFURV9TVEFSVElORyIsImFkYlBvcnQiLCJwdXNoIiwiaXNBcnJheSIsInN0YXJ0RGV0ZWN0b3IiLCJzdGFydHNXaXRoIiwicHJvY2Vzc0lzQWxpdmUiLCJ3ZWJ2aWV3VmVyc2lvbiIsImtpbGxBbGwiLCJTdWJQcm9jZXNzIiwib24iLCJvdXQiLCJsaW5lIiwidHJpbSIsInNwbGl0IiwiZXJyb3IiLCJjb2RlIiwic2lnbmFsIiwiU1RBVEVfU1RPUFBJTkciLCJTVEFURV9SRVNUQVJUSU5HIiwibXNnIiwiam9pbiIsIndhaXRGb3JPbmxpbmUiLCJzdGFydFNlc3Npb24iLCJlbWl0IiwiRVZFTlRfRVJST1IiLCJzdG9wIiwidmVyc2lvbnNTdXBwb3J0ZWRCeURyaXZlciIsInNlc3Npb25JZCIsIlNUQVRFX09OTElORSIsInJlc3RhcnQiLCJjaHJvbWVkcml2ZXJTdG9wcGVkIiwiZ2V0U3RhdHVzIiwiY29tbWFuZCIsInNlc3Npb25DYXBzIiwiYWx3YXlzTWF0Y2giLCJkZXNpcmVkQ2FwYWJpbGl0aWVzIiwiZW1pdFN0YXRlcyIsIkVWRU5UX0NIQU5HRUQiLCJzZW5kQ29tbWFuZCIsInVybCIsIm1ldGhvZCIsImJvZHkiLCJwcm94eVJlcSIsInJlcSIsInJlcyIsInByb3h5UmVxUmVzIiwiY21kIiwic3lzdGVtIiwiaXNXaW5kb3dzIiwiQiIsInByb21pc2lmeSIsImNwIiwidWRpZEluZGV4IiwiZGVmYXVsdEFyZ3MiLCJmaW5kSW5kZXgiLCJpdGVtIiwidWRpZCIsImNvbm4iLCJnZXRGb3J3YXJkTGlzdCIsInBhcmFtcyIsInJlbW92ZVBvcnRGb3J3YXJkIiwicmVwbGFjZSIsImhhc1dvcmtpbmdX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RSxPQUFWLENBQWtCLE9BQWxCLEVBQTJCLEVBQTNCLENBQTNCLENBQU47QUFDRDtBQUNGO0FBQ0YsT0FaRCxDQVlFLE9BQU9uSixHQUFQLEVBQVk7QUFDWjlELFFBQUFBLEdBQUcsQ0FBQ3lELElBQUosQ0FBVSw0Q0FBMkNLLEdBQUcsQ0FBQ0MsT0FBUSxnQkFBakU7QUFDRDtBQUNGO0FBQ0Y7O0FBRXNCLFFBQWpCbUosaUJBQWlCLEdBQUk7QUFHekIsUUFBSTtBQUNGLFlBQU0sS0FBSzNLLE9BQUwsQ0FBYTZJLE9BQWIsQ0FBcUIsTUFBckIsRUFBNkIsS0FBN0IsQ0FBTjtBQUNBLGFBQU8sSUFBUDtBQUNELEtBSEQsQ0FHRSxPQUFPeEUsQ0FBUCxFQUFVO0FBQ1YsYUFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUEvbkI0Qzs7O0FBa29CL0MvRixZQUFZLENBQUMrSixXQUFiLEdBQTJCLG9CQUEzQjtBQUNBL0osWUFBWSxDQUFDNEssYUFBYixHQUE2QixjQUE3QjtBQUNBNUssWUFBWSxDQUFDeUIsYUFBYixHQUE2QixTQUE3QjtBQUNBekIsWUFBWSxDQUFDc0ksY0FBYixHQUE4QixVQUE5QjtBQUNBdEksWUFBWSxDQUFDbUssWUFBYixHQUE0QixRQUE1QjtBQUNBbkssWUFBWSxDQUFDd0osY0FBYixHQUE4QixVQUE5QjtBQUNBeEosWUFBWSxDQUFDeUosZ0JBQWIsR0FBZ0MsWUFBaEM7ZUFHZXpKLFkiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bWFpblxuXG5pbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5pbXBvcnQgeyBKV1Byb3h5LCBQUk9UT0NPTFMgfSBmcm9tICdAYXBwaXVtL2Jhc2UtZHJpdmVyJztcbmltcG9ydCBjcCBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IHN5c3RlbSwgZnMsIGxvZ2dlciwgdXRpbCB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyByZXRyeUludGVydmFsLCBhc3luY21hcCB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IFN1YlByb2Nlc3MsIGV4ZWMgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHtcbiAgZ2V0Q2hyb21lVmVyc2lvbiwgZ2V0Q2hyb21lZHJpdmVyRGlyLCBDSFJPTUVEUklWRVJfQ0hST01FX01BUFBJTkcsXG4gIGdldENocm9tZWRyaXZlckJpbmFyeVBhdGgsIENEX0NETixcbn0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgc2VtdmVyIGZyb20gJ3NlbXZlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgY29tcGFyZVZlcnNpb25zIGZyb20gJ2NvbXBhcmUtdmVyc2lvbnMnO1xuaW1wb3J0IENocm9tZWRyaXZlclN0b3JhZ2VDbGllbnQgZnJvbSAnLi9zdG9yYWdlLWNsaWVudCc7XG5pbXBvcnQgeyB0b1czY0NhcE5hbWVzLCBnZXRDYXBWYWx1ZSB9IGZyb20gJy4vcHJvdG9jb2wtaGVscGVycyc7XG5cblxuY29uc3QgbG9nID0gbG9nZ2VyLmdldExvZ2dlcignQ2hyb21lZHJpdmVyJyk7XG5cbmNvbnN0IE5FV19DRF9WRVJTSU9OX0ZPUk1BVF9NQUpPUl9WRVJTSU9OID0gNzM7XG5jb25zdCBERUZBVUxUX0hPU1QgPSAnMTI3LjAuMC4xJztcbmNvbnN0IE1JTl9DRF9WRVJTSU9OX1dJVEhfVzNDX1NVUFBPUlQgPSA3NTtcbmNvbnN0IERFRkFVTFRfUE9SVCA9IDk1MTU7XG5jb25zdCBDSFJPTUVfQlVORExFX0lEID0gJ2NvbS5hbmRyb2lkLmNocm9tZSc7XG5jb25zdCBXRUJWSUVXX1NIRUxMX0JVTkRMRV9JRCA9ICdvcmcuY2hyb21pdW0ud2Vidmlld19zaGVsbCc7XG5jb25zdCBXRUJWSUVXX0JVTkRMRV9JRFMgPSBbXG4gICdjb20uZ29vZ2xlLmFuZHJvaWQud2VidmlldycsXG4gICdjb20uYW5kcm9pZC53ZWJ2aWV3Jyxcbl07XG5jb25zdCBDSFJPTUVEUklWRVJfVFVUT1JJQUwgPSAnaHR0cHM6Ly9naXRodWIuY29tL2FwcGl1bS9hcHBpdW0vYmxvYi9tYXN0ZXIvZG9jcy9lbi93cml0aW5nLXJ1bm5pbmctYXBwaXVtL3dlYi9jaHJvbWVkcml2ZXIubWQnO1xuY29uc3QgVkVSU0lPTl9QQVRURVJOID0gLyhbXFxkLl0rKS87XG5cbmNvbnN0IENEX1ZFUlNJT05fVElNRU9VVCA9IDUwMDA7XG5cbmNsYXNzIENocm9tZWRyaXZlciBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXIge1xuICBjb25zdHJ1Y3RvciAoYXJncyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIGhvc3QgPSBERUZBVUxUX0hPU1QsXG4gICAgICBwb3J0ID0gREVGQVVMVF9QT1JULFxuICAgICAgdXNlU3lzdGVtRXhlY3V0YWJsZSA9IGZhbHNlLFxuICAgICAgZXhlY3V0YWJsZSxcbiAgICAgIGV4ZWN1dGFibGVEaXIgPSBnZXRDaHJvbWVkcml2ZXJEaXIoKSxcbiAgICAgIGJ1bmRsZUlkLFxuICAgICAgbWFwcGluZ1BhdGgsXG4gICAgICBjbWRBcmdzLFxuICAgICAgYWRiLFxuICAgICAgdmVyYm9zZSxcbiAgICAgIGxvZ1BhdGgsXG4gICAgICBkaXNhYmxlQnVpbGRDaGVjayxcbiAgICAgIGRldGFpbHMsXG4gICAgICBpc0F1dG9kb3dubG9hZEVuYWJsZWQgPSBmYWxzZSxcbiAgICB9ID0gYXJncztcblxuICAgIHRoaXMucHJveHlIb3N0ID0gaG9zdDtcbiAgICB0aGlzLnByb3h5UG9ydCA9IHBvcnQ7XG4gICAgdGhpcy5hZGIgPSBhZGI7XG4gICAgdGhpcy5jbWRBcmdzID0gY21kQXJncztcbiAgICB0aGlzLnByb2MgPSBudWxsO1xuICAgIHRoaXMudXNlU3lzdGVtRXhlY3V0YWJsZSA9IHVzZVN5c3RlbUV4ZWN1dGFibGU7XG4gICAgdGhpcy5jaHJvbWVkcml2ZXIgPSBleGVjdXRhYmxlO1xuICAgIHRoaXMuZXhlY3V0YWJsZURpciA9IGV4ZWN1dGFibGVEaXI7XG4gICAgdGhpcy5tYXBwaW5nUGF0aCA9IG1hcHBpbmdQYXRoO1xuICAgIHRoaXMuYnVuZGxlSWQgPSBidW5kbGVJZDtcbiAgICB0aGlzLmV4ZWN1dGFibGVWZXJpZmllZCA9IGZhbHNlO1xuICAgIHRoaXMuc3RhdGUgPSBDaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBFRDtcbiAgICB0aGlzLmp3cHJveHkgPSBuZXcgSldQcm94eSh7XG4gICAgICBzZXJ2ZXI6IHRoaXMucHJveHlIb3N0LFxuICAgICAgcG9ydDogdGhpcy5wcm94eVBvcnRcbiAgICB9KTtcbiAgICB0aGlzLnZlcmJvc2UgPSB2ZXJib3NlO1xuICAgIHRoaXMubG9nUGF0aCA9IGxvZ1BhdGg7XG4gICAgdGhpcy5kaXNhYmxlQnVpbGRDaGVjayA9ICEhZGlzYWJsZUJ1aWxkQ2hlY2s7XG4gICAgdGhpcy5zdG9yYWdlQ2xpZW50ID0gaXNBdXRvZG93bmxvYWRFbmFibGVkXG4gICAgICA/IG5ldyBDaHJvbWVkcml2ZXJTdG9yYWdlQ2xpZW50KHsgY2hyb21lZHJpdmVyRGlyOiB0aGlzLmV4ZWN1dGFibGVEaXIgfSlcbiAgICAgIDogbnVsbDtcbiAgICB0aGlzLmRldGFpbHMgPSBkZXRhaWxzO1xuICAgIHRoaXMuY2FwYWJpbGl0aWVzID0ge307XG4gICAgdGhpcy5kZXNpcmVkUHJvdG9jb2wgPSBQUk9UT0NPTFMuTUpTT05XUDtcbiAgfVxuXG4gIGFzeW5jIGdldERyaXZlcnNNYXBwaW5nICgpIHtcbiAgICBsZXQgbWFwcGluZyA9IF8uY2xvbmVEZWVwKENIUk9NRURSSVZFUl9DSFJPTUVfTUFQUElORyk7XG4gICAgaWYgKHRoaXMubWFwcGluZ1BhdGgpIHtcbiAgICAgIGxvZy5kZWJ1ZyhgQXR0ZW1wdGluZyB0byB1c2UgQ2hyb21lZHJpdmVyLT5DaHJvbWUgbWFwcGluZyBmcm9tICcke3RoaXMubWFwcGluZ1BhdGh9J2ApO1xuICAgICAgaWYgKCFhd2FpdCBmcy5leGlzdHModGhpcy5tYXBwaW5nUGF0aCkpIHtcbiAgICAgICAgbG9nLndhcm4oYE5vIGZpbGUgZm91bmQgYXQgJyR7dGhpcy5tYXBwaW5nUGF0aH0nYCk7XG4gICAgICAgIGxvZy5pbmZvKCdEZWZhdWx0aW5nIHRvIHRoZSBzdGF0aWMgQ2hyb21lZHJpdmVyLT5DaHJvbWUgbWFwcGluZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtYXBwaW5nID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZSh0aGlzLm1hcHBpbmdQYXRoLCAndXRmOCcpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgbG9nLndhcm4oYEVycm9yIHBhcnNpbmcgbWFwcGluZyBmcm9tICcke3RoaXMubWFwcGluZ1BhdGh9JzogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgICBsb2cuaW5mbygnRGVmYXVsdGluZyB0byB0aGUgc3RhdGljIENocm9tZWRyaXZlci0+Q2hyb21lIG1hcHBpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsb2cuZGVidWcoJ1VzaW5nIHRoZSBzdGF0aWMgQ2hyb21lZHJpdmVyLT5DaHJvbWUgbWFwcGluZycpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSB2YWx1ZXMgZm9yIG1pbmltdW0gY2hyb21lIHZlcnNpb24gYXJlIHNlbXZlciBjb21wbGlhbnRcbiAgICBmb3IgKGNvbnN0IFtjZFZlcnNpb24sIGNocm9tZVZlcnNpb25dIG9mIF8udG9QYWlycyhtYXBwaW5nKSkge1xuICAgICAgY29uc3QgY29lcmNlZFZlcnNpb24gPSBzZW12ZXIuY29lcmNlKGNocm9tZVZlcnNpb24pO1xuICAgICAgaWYgKGNvZXJjZWRWZXJzaW9uKSB7XG4gICAgICAgIG1hcHBpbmdbY2RWZXJzaW9uXSA9IGNvZXJjZWRWZXJzaW9uLnZlcnNpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2cuaW5mbyhgJyR7Y2hyb21lVmVyc2lvbn0nIGlzIG5vdCBhIHZhbGlkIHZlcnNpb24gbnVtYmVyLiBTa2lwcGluZyBpdGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWFwcGluZztcbiAgfVxuXG4gIGFzeW5jIGdldENocm9tZWRyaXZlcnMgKG1hcHBpbmcpIHtcbiAgICAvLyBnbyB0aHJvdWdoIHRoZSB2ZXJzaW9ucyBhdmFpbGFibGVcbiAgICBjb25zdCBleGVjdXRhYmxlcyA9IGF3YWl0IGZzLmdsb2IoYCR7dGhpcy5leGVjdXRhYmxlRGlyfS8qYCk7XG4gICAgbG9nLmRlYnVnKGBGb3VuZCAke3V0aWwucGx1cmFsaXplKCdleGVjdXRhYmxlJywgZXhlY3V0YWJsZXMubGVuZ3RoLCB0cnVlKX0gYCArXG4gICAgICBgaW4gJyR7dGhpcy5leGVjdXRhYmxlRGlyfSdgKTtcbiAgICBjb25zdCBjZHMgPSAoYXdhaXQgYXN5bmNtYXAoZXhlY3V0YWJsZXMsIGFzeW5jIGZ1bmN0aW9uIG1hcENocm9tZWRyaXZlciAoZXhlY3V0YWJsZSkge1xuICAgICAgY29uc3QgbG9nRXJyb3IgPSAoe21lc3NhZ2UsIHN0ZG91dCA9IG51bGwsIHN0ZGVyciA9IG51bGx9KSA9PiB7XG4gICAgICAgIGxldCBlcnJNc2cgPSBgQ2Fubm90IHJldHJpZXZlIHZlcnNpb24gbnVtYmVyIGZyb20gJyR7cGF0aC5iYXNlbmFtZShleGVjdXRhYmxlKX0nIENocm9tZWRyaXZlciBiaW5hcnkuIGAgK1xuICAgICAgICAgIGBNYWtlIHN1cmUgaXQgcmV0dXJucyBhIHZhbGlkIHZlcnNpb24gc3RyaW5nIGluIHJlc3BvbnNlIHRvICctLXZlcnNpb24nIGNvbW1hbmQgbGluZSBhcmd1bWVudC4gJHttZXNzYWdlfWA7XG4gICAgICAgIGlmIChzdGRvdXQpIHtcbiAgICAgICAgICBlcnJNc2cgKz0gYFxcblN0ZG91dDogJHtzdGRvdXR9YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgZXJyTXNnICs9IGBcXG5TdGRlcnI6ICR7c3RkZXJyfWA7XG4gICAgICAgIH1cbiAgICAgICAgbG9nLndhcm4oZXJyTXNnKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICBsZXQgc3Rkb3V0O1xuICAgICAgbGV0IHN0ZGVycjtcbiAgICAgIHRyeSB7XG4gICAgICAgICh7c3Rkb3V0LCBzdGRlcnJ9ID0gYXdhaXQgZXhlYyhleGVjdXRhYmxlLCBbJy0tdmVyc2lvbiddLCB7XG4gICAgICAgICAgdGltZW91dDogQ0RfVkVSU0lPTl9USU1FT1VULFxuICAgICAgICB9KSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKCEoZXJyLm1lc3NhZ2UgfHwgJycpLmluY2x1ZGVzKCd0aW1lZCBvdXQnKSAmJiAhKGVyci5zdGRvdXQgfHwgJycpLmluY2x1ZGVzKCdTdGFydGluZyBDaHJvbWVEcml2ZXInKSkge1xuICAgICAgICAgIHJldHVybiBsb2dFcnJvcihlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdGhpcyBoYXMgdGltZWQgb3V0LCBpdCBoYXMgYWN0dWFsbHkgc3RhcnRlZCBDaHJvbWVkcml2ZXIsXG4gICAgICAgIC8vIGluIHdoaWNoIGNhc2UgdGhlcmUgd2lsbCBhbHNvIGJlIHRoZSB2ZXJzaW9uIHN0cmluZyBpbiB0aGUgb3V0cHV0XG4gICAgICAgIHN0ZG91dCA9IGVyci5zdGRvdXQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1hdGNoID0gL0Nocm9tZURyaXZlclxccytcXCg/dj8oW1xcZC5dKylcXCk/L2kuZXhlYyhzdGRvdXQpOyAvLyBodHRwczovL3JlZ2V4MTAxLmNvbS9yL3pwajV3QS8xXG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIHJldHVybiBsb2dFcnJvcih7bWVzc2FnZTogJ0Nhbm5vdCBwYXJzZSB0aGUgdmVyc2lvbiBzdHJpbmcnLCBzdGRvdXQsIHN0ZGVycn0pO1xuICAgICAgfVxuICAgICAgbGV0IHZlcnNpb24gPSBtYXRjaFsxXTtcbiAgICAgIGxldCBtaW5DaHJvbWVWZXJzaW9uID0gbWFwcGluZ1t2ZXJzaW9uXTtcbiAgICAgIGNvbnN0IGNvZXJjZWRWZXJzaW9uID0gc2VtdmVyLmNvZXJjZSh2ZXJzaW9uKTtcbiAgICAgIGlmIChjb2VyY2VkVmVyc2lvbikge1xuICAgICAgICAvLyBiZWZvcmUgMjAxOS0wMy0wNiB2ZXJzaW9ucyB3ZXJlIG9mIHRoZSBmb3JtIG1ham9yLm1pbm9yXG4gICAgICAgIGlmIChjb2VyY2VkVmVyc2lvbi5tYWpvciA8IE5FV19DRF9WRVJTSU9OX0ZPUk1BVF9NQUpPUl9WRVJTSU9OKSB7XG4gICAgICAgICAgdmVyc2lvbiA9IGAke2NvZXJjZWRWZXJzaW9uLm1ham9yfS4ke2NvZXJjZWRWZXJzaW9uLm1pbm9yfWA7XG4gICAgICAgICAgbWluQ2hyb21lVmVyc2lvbiA9IG1hcHBpbmdbdmVyc2lvbl07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtaW5DaHJvbWVWZXJzaW9uICYmIGNvZXJjZWRWZXJzaW9uLm1ham9yID49IE5FV19DRF9WRVJTSU9OX0ZPUk1BVF9NQUpPUl9WRVJTSU9OKSB7XG4gICAgICAgICAgLy8gQXNzdW1lIHRoZSBtYWpvciBDaHJvbWUgdmVyc2lvbiBpcyB0aGUgc2FtZSBhcyB0aGUgY29ycmVzcG9uZGluZyBkcml2ZXIgbWFqb3IgdmVyc2lvblxuICAgICAgICAgIG1pbkNocm9tZVZlcnNpb24gPSBgJHtjb2VyY2VkVmVyc2lvbi5tYWpvcn1gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleGVjdXRhYmxlLFxuICAgICAgICB2ZXJzaW9uLFxuICAgICAgICBtaW5DaHJvbWVWZXJzaW9uLFxuICAgICAgfTtcbiAgICB9KSlcbiAgICAgIC5maWx0ZXIoKGNkKSA9PiAhIWNkKVxuICAgICAgLnNvcnQoKGEsIGIpID0+IGNvbXBhcmVWZXJzaW9ucyhiLnZlcnNpb24sIGEudmVyc2lvbikpO1xuICAgIGlmIChfLmlzRW1wdHkoY2RzKSkge1xuICAgICAgbG9nLmluZm8oYE5vIENocm9tZWRyaXZlcnMgd2VyZSBmb3VuZCBpbiAnJHt0aGlzLmV4ZWN1dGFibGVEaXJ9J2ApO1xuICAgICAgcmV0dXJuIGNkcztcbiAgICB9XG4gICAgbG9nLmRlYnVnKGBUaGUgZm9sbG93aW5nIENocm9tZWRyaXZlciBleGVjdXRhYmxlcyB3ZXJlIGZvdW5kOmApO1xuICAgIGZvciAoY29uc3QgY2Qgb2YgY2RzKSB7XG4gICAgICBsb2cuZGVidWcoYCAgICAnJHtjZC5leGVjdXRhYmxlfScgKHZlcnNpb24gJyR7Y2QudmVyc2lvbn0nLCBtaW5pbXVtIENocm9tZSB2ZXJzaW9uICcke2NkLm1pbkNocm9tZVZlcnNpb24gPyBjZC5taW5DaHJvbWVWZXJzaW9uIDogJ1Vua25vd24nfScpYCk7XG4gICAgfVxuICAgIHJldHVybiBjZHM7XG4gIH1cblxuICBhc3luYyBnZXRDaHJvbWVWZXJzaW9uICgpIHtcbiAgICAvLyBUcnkgdG8gcmV0cmlldmUgdGhlIHZlcnNpb24gZnJvbSBgZGV0YWlsc2AgcHJvcGVydHkgaWYgaXQgaXMgc2V0XG4gICAgLy8gVGhlIGBpbmZvYCBpdGVtIG11c3QgY29udGFpbiB0aGUgb3V0cHV0IG9mIC9qc29uL3ZlcnNpb24gQ0RQIGNvbW1hbmRcbiAgICAvLyB3aGVyZSBgQnJvd3NlcmAgZmllbGQgbG9va3MgbGlrZSBgQ2hyb21lLzcyLjAuMzYwMS4wYGBcbiAgICBpZiAodGhpcy5kZXRhaWxzPy5pbmZvKSB7XG4gICAgICBsb2cuZGVidWcoYEJyb3dzZXIgdmVyc2lvbiBpbiB0aGUgc3VwcGxpZWQgZGV0YWlsczogJHt0aGlzLmRldGFpbHM/LmluZm8/LkJyb3dzZXJ9YCk7XG4gICAgfVxuICAgIGNvbnN0IHZlcnNpb25NYXRjaCA9IFZFUlNJT05fUEFUVEVSTi5leGVjKHRoaXMuZGV0YWlscz8uaW5mbz8uQnJvd3Nlcik7XG4gICAgaWYgKHZlcnNpb25NYXRjaCkge1xuICAgICAgY29uc3QgY29lcmNlZFZlcnNpb24gPSBzZW12ZXIuY29lcmNlKHZlcnNpb25NYXRjaFsxXSk7XG4gICAgICBpZiAoY29lcmNlZFZlcnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZWRWZXJzaW9uO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBjaHJvbWVWZXJzaW9uO1xuXG4gICAgLy8gaW4gY2FzZSBvZiBXZWJWaWV3IEJyb3dzZXIgVGVzdGVyLCBzaW1wbHkgdHJ5IHRvIGZpbmQgdGhlIHVuZGVybHlpbmcgd2Vidmlld1xuICAgIGlmICh0aGlzLmJ1bmRsZUlkID09PSBXRUJWSUVXX1NIRUxMX0JVTkRMRV9JRCkge1xuICAgICAgZm9yIChjb25zdCBidW5kbGVJZCBvZiBXRUJWSUVXX0JVTkRMRV9JRFMpIHtcbiAgICAgICAgY2hyb21lVmVyc2lvbiA9IGF3YWl0IGdldENocm9tZVZlcnNpb24odGhpcy5hZGIsIGJ1bmRsZUlkKTtcbiAgICAgICAgaWYgKGNocm9tZVZlcnNpb24pIHtcbiAgICAgICAgICB0aGlzLmJ1bmRsZUlkID0gYnVuZGxlSWQ7XG4gICAgICAgICAgcmV0dXJuIHNlbXZlci5jb2VyY2UoY2hyb21lVmVyc2lvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIG9uIEFuZHJvaWQgNy05IHdlYnZpZXdzIGFyZSBiYWNrZWQgYnkgdGhlIG1haW4gQ2hyb21lLCBub3QgdGhlIHN5c3RlbSB3ZWJ2aWV3XG4gICAgaWYgKHRoaXMuYWRiKSB7XG4gICAgICBjb25zdCBhcGlMZXZlbCA9IGF3YWl0IHRoaXMuYWRiLmdldEFwaUxldmVsKCk7XG4gICAgICBpZiAoYXBpTGV2ZWwgPj0gMjQgJiYgYXBpTGV2ZWwgPD0gMjggJiZcbiAgICAgICAgICBbV0VCVklFV19TSEVMTF9CVU5ETEVfSUQsIC4uLldFQlZJRVdfQlVORExFX0lEU10uaW5jbHVkZXModGhpcy5idW5kbGVJZCkpIHtcbiAgICAgICAgdGhpcy5idW5kbGVJZCA9IENIUk9NRV9CVU5ETEVfSUQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHJ5IG91dCB3ZWJ2aWV3cyB3aGVuIG5vIGJ1bmRsZSBpZCBpcyBzZW50IGluXG4gICAgaWYgKCF0aGlzLmJ1bmRsZUlkKSB7XG4gICAgICAvLyBkZWZhdWx0IHRvIHRoZSBnZW5lcmljIENocm9tZSBidW5kbGVcbiAgICAgIHRoaXMuYnVuZGxlSWQgPSBDSFJPTUVfQlVORExFX0lEO1xuXG4gICAgICAvLyB3ZSBoYXZlIGEgd2VidmlldyBvZiBzb21lIHNvcnQsIHNvIHRyeSB0byBmaW5kIHRoZSBidW5kbGUgdmVyc2lvblxuICAgICAgZm9yIChjb25zdCBidW5kbGVJZCBvZiBXRUJWSUVXX0JVTkRMRV9JRFMpIHtcbiAgICAgICAgY2hyb21lVmVyc2lvbiA9IGF3YWl0IGdldENocm9tZVZlcnNpb24odGhpcy5hZGIsIGJ1bmRsZUlkKTtcbiAgICAgICAgaWYgKGNocm9tZVZlcnNpb24pIHtcbiAgICAgICAgICB0aGlzLmJ1bmRsZUlkID0gYnVuZGxlSWQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiB3ZSBkbyBub3QgaGF2ZSBhIGNocm9tZSB2ZXJzaW9uLCBpdCBtdXN0IG5vdCBiZSBhIHdlYnZpZXdcbiAgICBpZiAoIWNocm9tZVZlcnNpb24pIHtcbiAgICAgIGNocm9tZVZlcnNpb24gPSBhd2FpdCBnZXRDaHJvbWVWZXJzaW9uKHRoaXMuYWRiLCB0aGlzLmJ1bmRsZUlkKTtcbiAgICB9XG5cbiAgICAvLyBtYWtlIHN1cmUgaXQgaXMgc2VtdmVyLCBzbyBsYXRlciBjaGVja3Mgd29uJ3QgZmFpbFxuICAgIHJldHVybiBjaHJvbWVWZXJzaW9uID8gc2VtdmVyLmNvZXJjZShjaHJvbWVWZXJzaW9uKSA6IG51bGw7XG4gIH1cblxuICBhc3luYyB1cGRhdGVEcml2ZXJzTWFwcGluZyAobmV3TWFwcGluZykge1xuICAgIGxldCBzaG91bGRVcGRhdGVTdGF0aWNNYXBwaW5nID0gdHJ1ZTtcbiAgICBpZiAoYXdhaXQgZnMuZXhpc3RzKHRoaXMubWFwcGluZ1BhdGgpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUodGhpcy5tYXBwaW5nUGF0aCwgSlNPTi5zdHJpbmdpZnkobmV3TWFwcGluZywgbnVsbCwgMiksICd1dGY4Jyk7XG4gICAgICAgIHNob3VsZFVwZGF0ZVN0YXRpY01hcHBpbmcgPSBmYWxzZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nLndhcm4oYENhbm5vdCBzdG9yZSB0aGUgdXBkYXRlZCBjaHJvbWVkcml2ZXJzIG1hcHBpbmcgaW50byAnJHt0aGlzLm1hcHBpbmdQYXRofScuIGAgK1xuICAgICAgICAgIGBUaGlzIG1heSByZWR1Y2UgdGhlIHBlcmZvcm1hbmNlIG9mIGZ1cnRoZXIgZXhlY3V0aW9ucy4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hvdWxkVXBkYXRlU3RhdGljTWFwcGluZykge1xuICAgICAgT2JqZWN0LmFzc2lnbihDSFJPTUVEUklWRVJfQ0hST01FX01BUFBJTkcsIG5ld01hcHBpbmcpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENvbXBhdGlibGVDaHJvbWVkcml2ZXIgKCkge1xuICAgIGlmICghdGhpcy5hZGIpIHtcbiAgICAgIHJldHVybiBhd2FpdCBnZXRDaHJvbWVkcml2ZXJCaW5hcnlQYXRoKCk7XG4gICAgfVxuXG4gICAgY29uc3QgbWFwcGluZyA9IGF3YWl0IHRoaXMuZ2V0RHJpdmVyc01hcHBpbmcoKTtcbiAgICBpZiAoIV8uaXNFbXB0eShtYXBwaW5nKSkge1xuICAgICAgbG9nLmRlYnVnKGBUaGUgbW9zdCByZWNlbnQga25vd24gQ2hyb21lIHZlcnNpb246ICR7Xy52YWx1ZXMobWFwcGluZylbMF19YCk7XG4gICAgfVxuXG4gICAgbGV0IGRpZFN0b3JhZ2VTeW5jID0gZmFsc2U7XG4gICAgY29uc3Qgc3luY0Nocm9tZWRyaXZlcnMgPSBhc3luYyAoY2hyb21lVmVyc2lvbikgPT4ge1xuICAgICAgZGlkU3RvcmFnZVN5bmMgPSB0cnVlO1xuICAgICAgY29uc3QgcmV0cmlldmVkTWFwcGluZyA9IGF3YWl0IHRoaXMuc3RvcmFnZUNsaWVudC5yZXRyaWV2ZU1hcHBpbmcoKTtcbiAgICAgIGxvZy5kZWJ1ZygnR290IGNocm9tZWRyaXZlcnMgbWFwcGluZyBmcm9tIHRoZSBzdG9yYWdlOiAnICtcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkocmV0cmlldmVkTWFwcGluZywgbnVsbCwgMikpO1xuICAgICAgY29uc3QgZHJpdmVyS2V5cyA9IGF3YWl0IHRoaXMuc3RvcmFnZUNsaWVudC5zeW5jRHJpdmVycyh7XG4gICAgICAgIG1pbkJyb3dzZXJWZXJzaW9uOiBjaHJvbWVWZXJzaW9uLm1ham9yLFxuICAgICAgfSk7XG4gICAgICBpZiAoXy5pc0VtcHR5KGRyaXZlcktleXMpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN5bmNocm9uaXplZERyaXZlcnNNYXBwaW5nID0gZHJpdmVyS2V5cy5yZWR1Y2UoKGFjYywgeCkgPT4ge1xuICAgICAgICBjb25zdCB7dmVyc2lvbiwgbWluQnJvd3NlclZlcnNpb259ID0gcmV0cmlldmVkTWFwcGluZ1t4XTtcbiAgICAgICAgYWNjW3ZlcnNpb25dID0gbWluQnJvd3NlclZlcnNpb247XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCB7fSk7XG4gICAgICBPYmplY3QuYXNzaWduKG1hcHBpbmcsIHN5bmNocm9uaXplZERyaXZlcnNNYXBwaW5nKTtcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlRHJpdmVyc01hcHBpbmcobWFwcGluZyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgZG8ge1xuICAgICAgY29uc3QgY2RzID0gYXdhaXQgdGhpcy5nZXRDaHJvbWVkcml2ZXJzKG1hcHBpbmcpO1xuXG4gICAgICBjb25zdCBtaXNzaW5nVmVyc2lvbnMgPSB7fTtcbiAgICAgIGZvciAoY29uc3Qge3ZlcnNpb24sIG1pbkNocm9tZVZlcnNpb259IG9mIGNkcykge1xuICAgICAgICBpZiAoIW1pbkNocm9tZVZlcnNpb24gfHwgbWFwcGluZ1t2ZXJzaW9uXSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvZXJjZWRWZXIgPSBzZW12ZXIuY29lcmNlKHZlcnNpb24pO1xuICAgICAgICBpZiAoIWNvZXJjZWRWZXIgfHwgY29lcmNlZFZlci5tYWpvciA8IE5FV19DRF9WRVJTSU9OX0ZPUk1BVF9NQUpPUl9WRVJTSU9OKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBtaXNzaW5nVmVyc2lvbnNbdmVyc2lvbl0gPSBtaW5DaHJvbWVWZXJzaW9uO1xuICAgICAgfVxuICAgICAgaWYgKCFfLmlzRW1wdHkobWlzc2luZ1ZlcnNpb25zKSkge1xuICAgICAgICBsb2cuaW5mbyhgRm91bmQgJHt1dGlsLnBsdXJhbGl6ZSgnQ2hyb21lZHJpdmVyJywgXy5zaXplKG1pc3NpbmdWZXJzaW9ucyksIHRydWUpfSwgYCArXG4gICAgICAgICAgYHdoaWNoICR7Xy5zaXplKG1pc3NpbmdWZXJzaW9ucykgPT09IDEgPyAnaXMnIDogJ2FyZSd9IG1pc3NpbmcgaW4gdGhlIGxpc3Qgb2Yga25vd24gdmVyc2lvbnM6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG1pc3NpbmdWZXJzaW9ucykpO1xuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZURyaXZlcnNNYXBwaW5nKE9iamVjdC5hc3NpZ24obWFwcGluZywgbWlzc2luZ1ZlcnNpb25zKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmRpc2FibGVCdWlsZENoZWNrKSB7XG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2RzKSkge1xuICAgICAgICAgIGxvZy5lcnJvckFuZFRocm93KGBUaGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSBDaHJvbWVkcml2ZXIgZXhlY3V0YWJsZSBhdmFpbGFibGUgZm9yIHVzZSBpZiBgICtcbiAgICAgICAgICAgIGAnY2hyb21lZHJpdmVyRGlzYWJsZUJ1aWxkQ2hlY2snIGNhcGFiaWxpdHkgaXMgc2V0IHRvICd0cnVlJ2ApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHt2ZXJzaW9uLCBleGVjdXRhYmxlfSA9IGNkc1swXTtcbiAgICAgICAgbG9nLndhcm4oYENocm9tZSBidWlsZCBjaGVjayBkaXNhYmxlZC4gVXNpbmcgbW9zdCByZWNlbnQgQ2hyb21lZHJpdmVyIHZlcnNpb24gKCR7dmVyc2lvbn0sIGF0ICcke2V4ZWN1dGFibGV9JylgKTtcbiAgICAgICAgbG9nLndhcm4oYElmIHRoaXMgaXMgd3JvbmcsIHNldCAnY2hyb21lZHJpdmVyRGlzYWJsZUJ1aWxkQ2hlY2snIGNhcGFiaWxpdHkgdG8gJ2ZhbHNlJ2ApO1xuICAgICAgICByZXR1cm4gZXhlY3V0YWJsZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hyb21lVmVyc2lvbiA9IGF3YWl0IHRoaXMuZ2V0Q2hyb21lVmVyc2lvbigpO1xuICAgICAgaWYgKCFjaHJvbWVWZXJzaW9uKSB7XG4gICAgICAgIC8vIHVuYWJsZSB0byBnZXQgdGhlIGNocm9tZSB2ZXJzaW9uXG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2RzKSkge1xuICAgICAgICAgIGxvZy5lcnJvckFuZFRocm93KGBUaGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSBDaHJvbWVkcml2ZXIgZXhlY3V0YWJsZSBhdmFpbGFibGUgZm9yIHVzZSBpZiBgICtcbiAgICAgICAgICAgIGB0aGUgY3VycmVudCBDaHJvbWUgdmVyc2lvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZGApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHt2ZXJzaW9uLCBleGVjdXRhYmxlfSA9IGNkc1swXTtcbiAgICAgICAgbG9nLndhcm4oYFVuYWJsZSB0byBkaXNjb3ZlciBDaHJvbWUgdmVyc2lvbi4gVXNpbmcgQ2hyb21lZHJpdmVyICR7dmVyc2lvbn0gYXQgJyR7ZXhlY3V0YWJsZX0nYCk7XG4gICAgICAgIHJldHVybiBleGVjdXRhYmxlO1xuICAgICAgfVxuICAgICAgbG9nLmRlYnVnKGBGb3VuZCBDaHJvbWUgYnVuZGxlICcke3RoaXMuYnVuZGxlSWR9JyB2ZXJzaW9uICcke2Nocm9tZVZlcnNpb259J2ApO1xuXG4gICAgICBjb25zdCBtYXRjaGluZ0RyaXZlcnMgPSBjZHMuZmlsdGVyKCh7bWluQ2hyb21lVmVyc2lvbn0pID0+IHtcbiAgICAgICAgY29uc3QgbWluQ2hyb21lVmVyc2lvblMgPSBtaW5DaHJvbWVWZXJzaW9uICYmIHNlbXZlci5jb2VyY2UobWluQ2hyb21lVmVyc2lvbik7XG4gICAgICAgIGlmICghbWluQ2hyb21lVmVyc2lvblMpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hyb21lVmVyc2lvbi5tYWpvciA+IE5FV19DRF9WRVJTSU9OX0ZPUk1BVF9NQUpPUl9WRVJTSU9OXG4gICAgICAgICAgPyBtaW5DaHJvbWVWZXJzaW9uUy5tYWpvciA9PT0gY2hyb21lVmVyc2lvbi5tYWpvclxuICAgICAgICAgIDogc2VtdmVyLmd0ZShjaHJvbWVWZXJzaW9uLCBtaW5DaHJvbWVWZXJzaW9uUyk7XG4gICAgICB9KTtcbiAgICAgIGlmIChfLmlzRW1wdHkobWF0Y2hpbmdEcml2ZXJzKSkge1xuICAgICAgICBpZiAodGhpcy5zdG9yYWdlQ2xpZW50ICYmICFkaWRTdG9yYWdlU3luYykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoYXdhaXQgc3luY0Nocm9tZWRyaXZlcnMoY2hyb21lVmVyc2lvbikpIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgbG9nLndhcm4oYENhbm5vdCBzeW5jaHJvbml6ZSBsb2NhbCBjaHJvbWVkcml2ZXJzIHdpdGggdGhlIHJlbW90ZSBzdG9yYWdlIGF0ICR7Q0RfQ0ROfTogYCArXG4gICAgICAgICAgICAgIGUubWVzc2FnZSk7XG4gICAgICAgICAgICBsb2cuZGVidWcoZS5zdGFjayk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGF1dG9kb3dubG9hZFN1Z2dlc3Rpb24gPVxuICAgICAgICAgICdZb3UgY291bGQgYWxzbyB0cnkgdG8gZW5hYmxlIGF1dG9tYXRlZCBjaHJvbWVkcml2ZXJzIGRvd25sb2FkIHNlcnZlciBmZWF0dXJlJztcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBDaHJvbWVkcml2ZXIgZm91bmQgdGhhdCBjYW4gYXV0b21hdGUgQ2hyb21lICcke2Nocm9tZVZlcnNpb259Jy4gYCArXG4gICAgICAgICAgKCF0aGlzLnN0b3JhZ2VDbGllbnQgPyBgJHthdXRvZG93bmxvYWRTdWdnZXN0aW9ufS4gYCA6ICcnKSArXG4gICAgICAgICAgYFNlZSAke0NIUk9NRURSSVZFUl9UVVRPUklBTH0gZm9yIG1vcmUgZGV0YWlsc2ApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBiaW5QYXRoID0gbWF0Y2hpbmdEcml2ZXJzWzBdLmV4ZWN1dGFibGU7XG4gICAgICBsb2cuZGVidWcoYEZvdW5kICR7dXRpbC5wbHVyYWxpemUoJ2V4ZWN1dGFibGUnLCBtYXRjaGluZ0RyaXZlcnMubGVuZ3RoLCB0cnVlKX0gYCArXG4gICAgICAgIGBjYXBhYmxlIG9mIGF1dG9tYXRpbmcgQ2hyb21lICcke2Nocm9tZVZlcnNpb259Jy5cXG5DaG9vc2luZyB0aGUgbW9zdCByZWNlbnQsICcke2JpblBhdGh9Jy5gKTtcbiAgICAgIGxvZy5kZWJ1ZygnSWYgYSBzcGVjaWZpYyB2ZXJzaW9uIGlzIHJlcXVpcmVkLCBzcGVjaWZ5IGl0IHdpdGggdGhlIGBjaHJvbWVkcml2ZXJFeGVjdXRhYmxlYCcgK1xuICAgICAgICAnZGVzaXJlZCBjYXBhYmlsaXR5LicpO1xuICAgICAgcmV0dXJuIGJpblBhdGg7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgIH0gd2hpbGUgKHRydWUpO1xuICB9XG5cbiAgYXN5bmMgaW5pdENocm9tZWRyaXZlclBhdGggKCkge1xuICAgIGlmICh0aGlzLmV4ZWN1dGFibGVWZXJpZmllZCkgcmV0dXJuOyAvL2VzbGludC1kaXNhYmxlLWxpbmUgY3VybHlcblxuICAgIC8vIHRoZSBleGVjdXRhYmxlIG1pZ2h0IGJlIHNldCAoaWYgcGFzc2VkIGluKVxuICAgIC8vIG9yIHdlIG1pZ2h0IHdhbnQgdG8gdXNlIHRoZSBiYXNpYyBvbmUgaW5zdGFsbGVkIHdpdGggdGhpcyBkcml2ZXJcbiAgICAvLyBvciB3ZSB3YW50IHRvIGZpZ3VyZSBvdXQgdGhlIGJlc3Qgb25lXG4gICAgaWYgKCF0aGlzLmNocm9tZWRyaXZlcikge1xuICAgICAgdGhpcy5jaHJvbWVkcml2ZXIgPSB0aGlzLnVzZVN5c3RlbUV4ZWN1dGFibGVcbiAgICAgICAgPyBhd2FpdCBnZXRDaHJvbWVkcml2ZXJCaW5hcnlQYXRoKClcbiAgICAgICAgOiBhd2FpdCB0aGlzLmdldENvbXBhdGlibGVDaHJvbWVkcml2ZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoIWF3YWl0IGZzLmV4aXN0cyh0aGlzLmNocm9tZWRyaXZlcikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVHJ5aW5nIHRvIHVzZSBhIGNocm9tZWRyaXZlciBiaW5hcnkgYXQgdGhlIHBhdGggYCArXG4gICAgICAgICAgICAgICAgICAgICAgYCR7dGhpcy5jaHJvbWVkcml2ZXJ9LCBidXQgaXQgZG9lc24ndCBleGlzdCFgKTtcbiAgICB9XG4gICAgdGhpcy5leGVjdXRhYmxlVmVyaWZpZWQgPSB0cnVlO1xuICAgIGxvZy5pbmZvKGBTZXQgY2hyb21lZHJpdmVyIGJpbmFyeSBhczogJHt0aGlzLmNocm9tZWRyaXZlcn1gKTtcbiAgfVxuXG4gIHN5bmNQcm90b2NvbCAoY2RWZXJzaW9uID0gbnVsbCkge1xuICAgIGNvbnN0IGNvZXJjZWRWZXJzaW9uID0gc2VtdmVyLmNvZXJjZShjZFZlcnNpb24pO1xuICAgIGlmICghY29lcmNlZFZlcnNpb24gfHwgY29lcmNlZFZlcnNpb24ubWFqb3IgPCBNSU5fQ0RfVkVSU0lPTl9XSVRIX1czQ19TVVBQT1JUKSB7XG4gICAgICBsb2cuZGVidWcoYENocm9tZWRyaXZlciB2LiAke2NkVmVyc2lvbn0gZG9lcyBub3QgZnVsbHkgc3VwcG9ydCAke1BST1RPQ09MUy5XM0N9IHByb3RvY29sLiBgICtcbiAgICAgICAgYERlZmF1bHRpbmcgdG8gJHtQUk9UT0NPTFMuTUpTT05XUH1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2hyb21lT3B0aW9ucyA9IGdldENhcFZhbHVlKHRoaXMuY2FwYWJpbGl0aWVzLCAnY2hyb21lT3B0aW9ucycsIHt9KTtcbiAgICBpZiAoY2hyb21lT3B0aW9ucy53M2MgPT09IGZhbHNlKSB7XG4gICAgICBsb2cuaW5mbyhgQ2hyb21lZHJpdmVyIHYuICR7Y2RWZXJzaW9ufSBzdXBwb3J0cyAke1BST1RPQ09MUy5XM0N9IHByb3RvY29sLCBgICtcbiAgICAgICAgYGJ1dCAke1BST1RPQ09MUy5NSlNPTldQfSBvbmUgaGFzIGJlZW4gZXhwbGljaXRseSByZXF1ZXN0ZWRgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5kZXNpcmVkUHJvdG9jb2wgPSBQUk9UT0NPTFMuVzNDO1xuICAgIC8vIGdpdmVuIGNhcHMgbWlnaHQgbm90IGJlIHByb3Blcmx5IHByZWZpeGVkXG4gICAgLy8gc28gd2UgdHJ5IHRvIGZpeCB0aGVtIGluIG9yZGVyIHRvIHByb3Blcmx5IGluaXRcbiAgICAvLyB0aGUgbmV3IFczQyBzZXNzaW9uXG4gICAgdGhpcy5jYXBhYmlsaXRpZXMgPSB0b1czY0NhcE5hbWVzKHRoaXMuY2FwYWJpbGl0aWVzKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0IChjYXBzLCBlbWl0U3RhcnRpbmdTdGF0ZSA9IHRydWUpIHtcbiAgICB0aGlzLmNhcGFiaWxpdGllcyA9IF8uY2xvbmVEZWVwKGNhcHMpO1xuXG4gICAgLy8gc2V0IHRoZSBsb2dnaW5nIHByZWZlcmVuY2VzIHRvIEFMTCB0aGUgY29uc29sZSBsb2dzXG4gICAgdGhpcy5jYXBhYmlsaXRpZXMubG9nZ2luZ1ByZWZzID0gXy5jbG9uZURlZXAoZ2V0Q2FwVmFsdWUoY2FwcywgJ2xvZ2dpbmdQcmVmcycsIHt9KSk7XG4gICAgaWYgKF8uaXNFbXB0eSh0aGlzLmNhcGFiaWxpdGllcy5sb2dnaW5nUHJlZnMuYnJvd3NlcikpIHtcbiAgICAgIHRoaXMuY2FwYWJpbGl0aWVzLmxvZ2dpbmdQcmVmcy5icm93c2VyID0gJ0FMTCc7XG4gICAgfVxuXG4gICAgaWYgKGVtaXRTdGFydGluZ1N0YXRlKSB7XG4gICAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9TVEFSVElORyk7XG4gICAgfVxuXG4gICAgY29uc3QgYXJncyA9IFtgLS1wb3J0PSR7dGhpcy5wcm94eVBvcnR9YF07XG4gICAgaWYgKHRoaXMuYWRiICYmIHRoaXMuYWRiLmFkYlBvcnQpIHtcbiAgICAgIGFyZ3MucHVzaChgLS1hZGItcG9ydD0ke3RoaXMuYWRiLmFkYlBvcnR9YCk7XG4gICAgfVxuICAgIGlmIChfLmlzQXJyYXkodGhpcy5jbWRBcmdzKSkge1xuICAgICAgYXJncy5wdXNoKC4uLnRoaXMuY21kQXJncyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmxvZ1BhdGgpIHtcbiAgICAgIGFyZ3MucHVzaChgLS1sb2ctcGF0aD0ke3RoaXMubG9nUGF0aH1gKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZGlzYWJsZUJ1aWxkQ2hlY2spIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1kaXNhYmxlLWJ1aWxkLWNoZWNrJyk7XG4gICAgfVxuICAgIGFyZ3MucHVzaCgnLS12ZXJib3NlJyk7XG4gICAgLy8gd2hhdCBhcmUgdGhlIHByb2Nlc3Mgc3Rkb3V0L3N0ZGVyciBjb25kaXRpb25zIHdoZXJlaW4gd2Uga25vdyB0aGF0XG4gICAgLy8gdGhlIHByb2Nlc3MgaGFzIHN0YXJ0ZWQgdG8gb3VyIHNhdGlzZmFjdGlvbj9cbiAgICBjb25zdCBzdGFydERldGVjdG9yID0gKHN0ZG91dCkgPT4gc3Rkb3V0LnN0YXJ0c1dpdGgoJ1N0YXJ0aW5nICcpO1xuXG4gICAgbGV0IHByb2Nlc3NJc0FsaXZlID0gZmFsc2U7XG4gICAgbGV0IHdlYnZpZXdWZXJzaW9uO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXRDaHJvbWVkcml2ZXJQYXRoKCk7XG4gICAgICBhd2FpdCB0aGlzLmtpbGxBbGwoKTtcblxuICAgICAgLy8gc2V0IHVwIG91ciBzdWJwcm9jZXNzIG9iamVjdFxuICAgICAgdGhpcy5wcm9jID0gbmV3IFN1YlByb2Nlc3ModGhpcy5jaHJvbWVkcml2ZXIsIGFyZ3MpO1xuICAgICAgcHJvY2Vzc0lzQWxpdmUgPSB0cnVlO1xuXG4gICAgICAvLyBoYW5kbGUgbG9nIG91dHB1dFxuICAgICAgdGhpcy5wcm9jLm9uKCdvdXRwdXQnLCAoc3Rkb3V0LCBzdGRlcnIpID0+IHtcbiAgICAgICAgLy8gaWYgdGhlIGNkIG91dHB1dCBpcyBub3QgcHJpbnRlZCwgZmluZCB0aGUgY2hyb21lIHZlcnNpb24gYW5kIHByaW50XG4gICAgICAgIC8vIHdpbGwgZ2V0IGEgcmVzcG9uc2UgbGlrZVxuICAgICAgICAvLyAgIERldlRvb2xzIHJlc3BvbnNlOiB7XG4gICAgICAgIC8vICAgICAgXCJBbmRyb2lkLVBhY2thZ2VcIjogXCJpby5hcHBpdW0uc2FtcGxlYXBwXCIsXG4gICAgICAgIC8vICAgICAgXCJCcm93c2VyXCI6IFwiQ2hyb21lLzU1LjAuMjg4My45MVwiLFxuICAgICAgICAvLyAgICAgIFwiUHJvdG9jb2wtVmVyc2lvblwiOiBcIjEuMlwiLFxuICAgICAgICAvLyAgICAgIFwiVXNlci1BZ2VudFwiOiBcIi4uLlwiLFxuICAgICAgICAvLyAgICAgIFwiV2ViS2l0LVZlcnNpb25cIjogXCI1MzcuMzZcIlxuICAgICAgICAvLyAgIH1cbiAgICAgICAgY29uc3Qgb3V0ID0gc3Rkb3V0ICsgc3RkZXJyO1xuICAgICAgICBsZXQgbWF0Y2ggPSAvXCJCcm93c2VyXCI6IFwiKC4qKVwiLy5leGVjKG91dCk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIHdlYnZpZXdWZXJzaW9uID0gbWF0Y2hbMV07XG4gICAgICAgICAgbG9nLmRlYnVnKGBXZWJ2aWV3IHZlcnNpb246ICcke3dlYnZpZXdWZXJzaW9ufSdgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGFsc28gcHJpbnQgY2hyb21lZHJpdmVyIHZlcnNpb24gdG8gbG9nc1xuICAgICAgICAvLyB3aWxsIG91dHB1dCBzb21ldGhpbmcgbGlrZVxuICAgICAgICAvLyAgU3RhcnRpbmcgQ2hyb21lRHJpdmVyIDIuMzMuNTA2MTA2ICg4YTA2YzM5YzQ1ODJmYmZiYWI2OTY2ZGJiMWMzOGE5MTczYmZiMWEyKSBvbiBwb3J0IDk1MTVcbiAgICAgICAgbWF0Y2ggPSAvU3RhcnRpbmcgQ2hyb21lRHJpdmVyIChbLlxcZF0rKS8uZXhlYyhvdXQpO1xuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICBsb2cuZGVidWcoYENocm9tZWRyaXZlciB2ZXJzaW9uOiAnJHttYXRjaFsxXX0nYCk7XG4gICAgICAgICAgdGhpcy5zeW5jUHJvdG9jb2wobWF0Y2hbMV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZ2l2ZSB0aGUgb3V0cHV0IGlmIGl0IGlzIHJlcXVlc3RlZFxuICAgICAgICBpZiAodGhpcy52ZXJib3NlKSB7XG4gICAgICAgICAgZm9yIChsZXQgbGluZSBvZiAoc3Rkb3V0IHx8ICcnKS50cmltKCkuc3BsaXQoJ1xcbicpKSB7XG4gICAgICAgICAgICBpZiAoIWxpbmUudHJpbSgpLmxlbmd0aCkgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY3VybHlcbiAgICAgICAgICAgIGxvZy5kZWJ1ZyhgW1NURE9VVF0gJHtsaW5lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IgKGxldCBsaW5lIG9mIChzdGRlcnIgfHwgJycpLnRyaW0oKS5zcGxpdCgnXFxuJykpIHtcbiAgICAgICAgICAgIGlmICghbGluZS50cmltKCkubGVuZ3RoKSBjb250aW51ZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjdXJseVxuICAgICAgICAgICAgbG9nLmVycm9yKGBbU1RERVJSXSAke2xpbmV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gaGFuZGxlIG91dC1vZi1ib3VuZCBleGl0IGJ5IHNpbXBseSBlbWl0dGluZyBhIHN0b3BwZWQgc3RhdGVcbiAgICAgIHRoaXMucHJvYy5vbignZXhpdCcsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICAgICAgcHJvY2Vzc0lzQWxpdmUgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IENocm9tZWRyaXZlci5TVEFURV9TVE9QUEVEICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlICE9PSBDaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBJTkcgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgIT09IENocm9tZWRyaXZlci5TVEFURV9SRVNUQVJUSU5HKSB7XG4gICAgICAgICAgbGV0IG1zZyA9IGBDaHJvbWVkcml2ZXIgZXhpdGVkIHVuZXhwZWN0ZWRseSB3aXRoIGNvZGUgJHtjb2RlfSwgYCArXG4gICAgICAgICAgICAgICAgICAgIGBzaWduYWwgJHtzaWduYWx9YDtcbiAgICAgICAgICBsb2cuZXJyb3IobXNnKTtcbiAgICAgICAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9TVE9QUEVEKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBsb2cuaW5mbyhgU3Bhd25pbmcgY2hyb21lZHJpdmVyIHdpdGg6ICR7dGhpcy5jaHJvbWVkcml2ZXJ9IGAgK1xuICAgICAgICAgICAgICAgYCR7YXJncy5qb2luKCcgJyl9YCk7XG4gICAgICAvLyBzdGFydCBzdWJwcm9jIGFuZCB3YWl0IGZvciBzdGFydERldGVjdG9yXG4gICAgICBhd2FpdCB0aGlzLnByb2Muc3RhcnQoc3RhcnREZXRlY3Rvcik7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JPbmxpbmUoKTtcbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRTZXNzaW9uKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nLmRlYnVnKGUpO1xuICAgICAgdGhpcy5lbWl0KENocm9tZWRyaXZlci5FVkVOVF9FUlJPUiwgZSk7XG4gICAgICAvLyBqdXN0IGJlY2F1c2Ugd2UgaGFkIGFuIGVycm9yIGRvZXNuJ3QgbWVhbiB0aGUgY2hyb21lZHJpdmVyIHByb2Nlc3NcbiAgICAgIC8vIGZpbmlzaGVkOyB3ZSBzaG91bGQgY2xlYW4gdXAgaWYgbmVjZXNzYXJ5XG4gICAgICBpZiAocHJvY2Vzc0lzQWxpdmUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcm9jLnN0b3AoKTtcbiAgICAgIH1cblxuICAgICAgbGV0IG1lc3NhZ2UgPSAnJztcbiAgICAgIC8vIG9mdGVuIHRoZSB1c2VyJ3MgQ2hyb21lIHZlcnNpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgdmVyc2lvbiBvZiBDaHJvbWVkcml2ZXJcbiAgICAgIGlmIChlLm1lc3NhZ2UuaW5jbHVkZXMoJ0Nocm9tZSB2ZXJzaW9uIG11c3QgYmUnKSkge1xuICAgICAgICBtZXNzYWdlICs9ICdVbmFibGUgdG8gYXV0b21hdGUgQ2hyb21lIHZlcnNpb24gYmVjYXVzZSBpdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgdmVyc2lvbiBvZiBDaHJvbWVkcml2ZXIuXFxuJztcbiAgICAgICAgaWYgKHdlYnZpZXdWZXJzaW9uKSB7XG4gICAgICAgICAgbWVzc2FnZSArPSBgQ2hyb21lIHZlcnNpb24gb24gdGhlIGRldmljZTogJHt3ZWJ2aWV3VmVyc2lvbn1cXG5gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZlcnNpb25zU3VwcG9ydGVkQnlEcml2ZXIgPSAvQ2hyb21lIHZlcnNpb24gbXVzdCBiZSAoLispLy5leGVjKGUubWVzc2FnZSk/LlsxXSB8fCAnJztcbiAgICAgICAgaWYgKHZlcnNpb25zU3VwcG9ydGVkQnlEcml2ZXIpIHtcbiAgICAgICAgICBtZXNzYWdlICs9IGBDaHJvbWVkcml2ZXIgc3VwcG9ydHMgQ2hyb21lIHZlcnNpb24ocyk6ICR7dmVyc2lvbnNTdXBwb3J0ZWRCeURyaXZlcn1cXG5gO1xuICAgICAgICB9XG4gICAgICAgIG1lc3NhZ2UgKz0gYFZpc2l0ICcke0NIUk9NRURSSVZFUl9UVVRPUklBTH0nIHRvIHRyb3VibGVzaG9vdCB0aGUgcHJvYmxlbS5cXG5gO1xuICAgICAgfVxuXG4gICAgICBtZXNzYWdlICs9IGUubWVzc2FnZTtcbiAgICAgIGxvZy5lcnJvckFuZFRocm93KG1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIHNlc3Npb25JZCAoKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUgIT09IENocm9tZWRyaXZlci5TVEFURV9PTkxJTkUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmp3cHJveHkuc2Vzc2lvbklkO1xuICB9XG5cbiAgYXN5bmMgcmVzdGFydCAoKSB7XG4gICAgbG9nLmluZm8oJ1Jlc3RhcnRpbmcgY2hyb21lZHJpdmVyJyk7XG4gICAgaWYgKHRoaXMuc3RhdGUgIT09IENocm9tZWRyaXZlci5TVEFURV9PTkxJTkUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHJlc3RhcnQgd2hlbiB3ZSdyZSBub3Qgb25saW5lXCIpO1xuICAgIH1cbiAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9SRVNUQVJUSU5HKTtcbiAgICBhd2FpdCB0aGlzLnN0b3AoZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc3RhcnQodGhpcy5jYXBhYmlsaXRpZXMsIGZhbHNlKTtcbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JPbmxpbmUgKCkge1xuICAgIC8vIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgQ0QgaGFzbid0IGNyYXNoZWRcbiAgICBsZXQgY2hyb21lZHJpdmVyU3RvcHBlZCA9IGZhbHNlO1xuICAgIGF3YWl0IHJldHJ5SW50ZXJ2YWwoMjAsIDIwMCwgYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IENocm9tZWRyaXZlci5TVEFURV9TVE9QUEVEKSB7XG4gICAgICAgIC8vIHdlIGFyZSBlaXRoZXIgc3RvcHBlZCBvciBzdG9wcGluZywgc28gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICAgICAgY2hyb21lZHJpdmVyU3RvcHBlZCA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgfSk7XG4gICAgaWYgKGNocm9tZWRyaXZlclN0b3BwZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hyb21lRHJpdmVyIGNyYXNoZWQgZHVyaW5nIHN0YXJ0dXAuJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0U3RhdHVzICgpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKCkge1xuICAgIGNvbnN0IHNlc3Npb25DYXBzID0gdGhpcy5kZXNpcmVkUHJvdG9jb2wgPT09IFBST1RPQ09MUy5XM0NcbiAgICAgID8ge2NhcGFiaWxpdGllczoge2Fsd2F5c01hdGNoOiB0aGlzLmNhcGFiaWxpdGllc319XG4gICAgICA6IHtkZXNpcmVkQ2FwYWJpbGl0aWVzOiB0aGlzLmNhcGFiaWxpdGllc307XG4gICAgbG9nLmluZm8oYFN0YXJ0aW5nICR7dGhpcy5kZXNpcmVkUHJvdG9jb2x9IENocm9tZWRyaXZlciBzZXNzaW9uIHdpdGggY2FwYWJpbGl0aWVzOiBgICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KHNlc3Npb25DYXBzLCBudWxsLCAyKSk7XG4gICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zZXNzaW9uJywgJ1BPU1QnLCBzZXNzaW9uQ2Fwcyk7XG4gICAgdGhpcy5jaGFuZ2VTdGF0ZShDaHJvbWVkcml2ZXIuU1RBVEVfT05MSU5FKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AgKGVtaXRTdGF0ZXMgPSB0cnVlKSB7XG4gICAgaWYgKGVtaXRTdGF0ZXMpIHtcbiAgICAgIHRoaXMuY2hhbmdlU3RhdGUoQ2hyb21lZHJpdmVyLlNUQVRFX1NUT1BQSU5HKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuandwcm94eS5jb21tYW5kKCcnLCAnREVMRVRFJyk7XG4gICAgICBhd2FpdCB0aGlzLnByb2Muc3RvcCgnU0lHVEVSTScsIDIwMDAwKTtcbiAgICAgIGlmIChlbWl0U3RhdGVzKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlU3RhdGUoQ2hyb21lZHJpdmVyLlNUQVRFX1NUT1BQRUQpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZy5lcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICBjaGFuZ2VTdGF0ZSAoc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgbG9nLmRlYnVnKGBDaGFuZ2VkIHN0YXRlIHRvICcke3N0YXRlfSdgKTtcbiAgICB0aGlzLmVtaXQoQ2hyb21lZHJpdmVyLkVWRU5UX0NIQU5HRUQsIHtzdGF0ZX0pO1xuICB9XG5cbiAgYXN5bmMgc2VuZENvbW1hbmQgKHVybCwgbWV0aG9kLCBib2R5KSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuandwcm94eS5jb21tYW5kKHVybCwgbWV0aG9kLCBib2R5KTtcbiAgfVxuXG4gIGFzeW5jIHByb3h5UmVxIChyZXEsIHJlcykge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmp3cHJveHkucHJveHlSZXFSZXMocmVxLCByZXMpO1xuICB9XG5cbiAgYXN5bmMga2lsbEFsbCAoKSB7XG4gICAgbGV0IGNtZCA9IHN5c3RlbS5pc1dpbmRvd3MoKVxuICAgICAgPyBgd21pYyBwcm9jZXNzIHdoZXJlIFwiY29tbWFuZGxpbmUgbGlrZSAnJWNocm9tZWRyaXZlci5leGUlLS1wb3J0PSR7dGhpcy5wcm94eVBvcnR9JSdcIiBkZWxldGVgXG4gICAgICA6IGBwa2lsbCAtMTUgLWYgXCIke3RoaXMuY2hyb21lZHJpdmVyfS4qLS1wb3J0PSR7dGhpcy5wcm94eVBvcnR9XCJgO1xuICAgIGxvZy5kZWJ1ZyhgS2lsbGluZyBhbnkgb2xkIGNocm9tZWRyaXZlcnMsIHJ1bm5pbmc6ICR7Y21kfWApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCAoQi5wcm9taXNpZnkoY3AuZXhlYykpKGNtZCk7XG4gICAgICBsb2cuZGVidWcoJ1N1Y2Nlc3NmdWxseSBjbGVhbmVkIHVwIG9sZCBjaHJvbWVkcml2ZXJzJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2cud2FybignTm8gb2xkIGNocm9tZWRyaXZlcnMgc2VlbSB0byBleGlzdCcpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmFkYikge1xuICAgICAgY29uc3QgdWRpZEluZGV4ID0gdGhpcy5hZGIuZXhlY3V0YWJsZS5kZWZhdWx0QXJncy5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0gPT09ICctcycpO1xuICAgICAgY29uc3QgdWRpZCA9IHVkaWRJbmRleCA+IC0xID8gdGhpcy5hZGIuZXhlY3V0YWJsZS5kZWZhdWx0QXJnc1t1ZGlkSW5kZXggKyAxXSA6IG51bGw7XG5cbiAgICAgIGlmICh1ZGlkKSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhgQ2xlYW5pbmcgdGhpcyBkZXZpY2UncyBhZGIgZm9yd2FyZGVkIHBvcnQgc29ja2V0IGNvbm5lY3Rpb25zOiAke3VkaWR9YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2cuZGVidWcoYENsZWFuaW5nIGFueSBvbGQgYWRiIGZvcndhcmRlZCBwb3J0IHNvY2tldCBjb25uZWN0aW9uc2ApO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKGxldCBjb25uIG9mIGF3YWl0IHRoaXMuYWRiLmdldEZvcndhcmRMaXN0KCkpIHtcbiAgICAgICAgICAvLyBjaHJvbWVkcml2ZXIgd2lsbCBhc2sgQURCIHRvIGZvcndhcmQgYSBwb3J0IGxpa2UgXCJkZXZpY2VJZCB0Y3A6cG9ydCBsb2NhbGFic3RyYWN0OndlYnZpZXdfZGV2dG9vbHNfcmVtb3RlX3BvcnRcIlxuICAgICAgICAgIGlmICghKGNvbm4uaW5jbHVkZXMoJ3dlYnZpZXdfZGV2dG9vbHMnKSAmJiAoIXVkaWQgfHwgY29ubi5pbmNsdWRlcyh1ZGlkKSkpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgcGFyYW1zID0gY29ubi5zcGxpdCgvXFxzKy8pO1xuICAgICAgICAgIGlmIChwYXJhbXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIucmVtb3ZlUG9ydEZvcndhcmQocGFyYW1zWzFdLnJlcGxhY2UoL1tcXERdKi8sICcnKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nLndhcm4oYFVuYWJsZSB0byBjbGVhbiBmb3J3YXJkZWQgcG9ydHMuIEVycm9yOiAnJHtlcnIubWVzc2FnZX0nLiBDb250aW51aW5nLmApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGhhc1dvcmtpbmdXZWJ2aWV3ICgpIHtcbiAgICAvLyBzb21ldGltZXMgY2hyb21lZHJpdmVyIHN0b3BzIGF1dG9tYXRpbmcgd2Vidmlld3MuIHRoaXMgbWV0aG9kIHJ1bnMgYVxuICAgIC8vIHNpbXBsZSBjb21tYW5kIHRvIGRldGVybWluZSBvdXIgc3RhdGUsIGFuZCByZXNwb25kcyBhY2NvcmRpbmdseVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3VybCcsICdHRVQnKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cblxuQ2hyb21lZHJpdmVyLkVWRU5UX0VSUk9SID0gJ2Nocm9tZWRyaXZlcl9lcnJvcic7XG5DaHJvbWVkcml2ZXIuRVZFTlRfQ0hBTkdFRCA9ICdzdGF0ZUNoYW5nZWQnO1xuQ2hyb21lZHJpdmVyLlNUQVRFX1NUT1BQRUQgPSAnc3RvcHBlZCc7XG5DaHJvbWVkcml2ZXIuU1RBVEVfU1RBUlRJTkcgPSAnc3RhcnRpbmcnO1xuQ2hyb21lZHJpdmVyLlNUQVRFX09OTElORSA9ICdvbmxpbmUnO1xuQ2hyb21lZHJpdmVyLlNUQVRFX1NUT1BQSU5HID0gJ3N0b3BwaW5nJztcbkNocm9tZWRyaXZlci5TVEFURV9SRVNUQVJUSU5HID0gJ3Jlc3RhcnRpbmcnO1xuXG5leHBvcnQgeyBDaHJvbWVkcml2ZXIgfTtcbmV4cG9ydCBkZWZhdWx0IENocm9tZWRyaXZlcjtcbiJdLCJmaWxlIjoibGliL2Nocm9tZWRyaXZlci5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
|
|
739
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9jaHJvbWVkcml2ZXIuanMiXSwibmFtZXMiOlsiTkVXX0NEX1ZFUlNJT05fRk9STUFUX01BSk9SX1ZFUlNJT04iLCJERUZBVUxUX0hPU1QiLCJNSU5fQ0RfVkVSU0lPTl9XSVRIX1czQ19TVVBQT1JUIiwiREVGQVVMVF9QT1JUIiwiQ0hST01FX0JVTkRMRV9JRCIsIldFQlZJRVdfU0hFTExfQlVORExFX0lEIiwiV0VCVklFV19CVU5ETEVfSURTIiwiQ0hST01FRFJJVkVSX1RVVE9SSUFMIiwiVkVSU0lPTl9QQVRURVJOIiwiQ0RfVkVSU0lPTl9USU1FT1VUIiwiQ2hyb21lZHJpdmVyIiwiZXZlbnRzIiwiRXZlbnRFbWl0dGVyIiwiY29uc3RydWN0b3IiLCJhcmdzIiwiaG9zdCIsInBvcnQiLCJ1c2VTeXN0ZW1FeGVjdXRhYmxlIiwiZXhlY3V0YWJsZSIsImV4ZWN1dGFibGVEaXIiLCJidW5kbGVJZCIsIm1hcHBpbmdQYXRoIiwiY21kQXJncyIsImFkYiIsInZlcmJvc2UiLCJsb2dQYXRoIiwiZGlzYWJsZUJ1aWxkQ2hlY2siLCJkZXRhaWxzIiwiaXNBdXRvZG93bmxvYWRFbmFibGVkIiwiX2xvZyIsImxvZ2dlciIsImdldExvZ2dlciIsInByb3h5SG9zdCIsInByb3h5UG9ydCIsInByb2MiLCJjaHJvbWVkcml2ZXIiLCJleGVjdXRhYmxlVmVyaWZpZWQiLCJzdGF0ZSIsIlNUQVRFX1NUT1BQRUQiLCJqd3Byb3h5IiwiSldQcm94eSIsInNlcnZlciIsImxvZyIsInN0b3JhZ2VDbGllbnQiLCJDaHJvbWVkcml2ZXJTdG9yYWdlQ2xpZW50IiwiY2hyb21lZHJpdmVyRGlyIiwiY2FwYWJpbGl0aWVzIiwiZGVzaXJlZFByb3RvY29sIiwiUFJPVE9DT0xTIiwiTUpTT05XUCIsImdldERyaXZlcnNNYXBwaW5nIiwibWFwcGluZyIsIl8iLCJjbG9uZURlZXAiLCJDSFJPTUVEUklWRVJfQ0hST01FX01BUFBJTkciLCJkZWJ1ZyIsImZzIiwiZXhpc3RzIiwid2FybiIsImluZm8iLCJKU09OIiwicGFyc2UiLCJyZWFkRmlsZSIsImVyciIsIm1lc3NhZ2UiLCJjZFZlcnNpb24iLCJjaHJvbWVWZXJzaW9uIiwidG9QYWlycyIsImNvZXJjZWRWZXJzaW9uIiwic2VtdmVyIiwiY29lcmNlIiwidmVyc2lvbiIsImdldENocm9tZWRyaXZlcnMiLCJleGVjdXRhYmxlcyIsImdsb2IiLCJjd2QiLCJzdHJpY3QiLCJub2RpciIsImFic29sdXRlIiwidXRpbCIsInBsdXJhbGl6ZSIsImxlbmd0aCIsImNkcyIsImxvZ0Vycm9yIiwic3Rkb3V0Iiwic3RkZXJyIiwiZXJyTXNnIiwicGF0aCIsImJhc2VuYW1lIiwidGltZW91dCIsImluY2x1ZGVzIiwibWF0Y2giLCJleGVjIiwibWluQ2hyb21lVmVyc2lvbiIsIm1ham9yIiwibWlub3IiLCJmaWx0ZXIiLCJjZCIsInNvcnQiLCJhIiwiYiIsImlzRW1wdHkiLCJnZXRDaHJvbWVWZXJzaW9uIiwiQnJvd3NlciIsInZlcnNpb25NYXRjaCIsImFwaUxldmVsIiwiZ2V0QXBpTGV2ZWwiLCJ1cGRhdGVEcml2ZXJzTWFwcGluZyIsIm5ld01hcHBpbmciLCJzaG91bGRVcGRhdGVTdGF0aWNNYXBwaW5nIiwid3JpdGVGaWxlIiwic3RyaW5naWZ5IiwiZSIsIk9iamVjdCIsImFzc2lnbiIsImdldENvbXBhdGlibGVDaHJvbWVkcml2ZXIiLCJ2YWx1ZXMiLCJkaWRTdG9yYWdlU3luYyIsInN5bmNDaHJvbWVkcml2ZXJzIiwicmV0cmlldmVkTWFwcGluZyIsInJldHJpZXZlTWFwcGluZyIsImRyaXZlcktleXMiLCJzeW5jRHJpdmVycyIsIm1pbkJyb3dzZXJWZXJzaW9uIiwic3luY2hyb25pemVkRHJpdmVyc01hcHBpbmciLCJyZWR1Y2UiLCJhY2MiLCJ4IiwibWlzc2luZ1ZlcnNpb25zIiwiY29lcmNlZFZlciIsInNpemUiLCJlcnJvckFuZFRocm93IiwibWF0Y2hpbmdEcml2ZXJzIiwibWluQ2hyb21lVmVyc2lvblMiLCJndGUiLCJDRF9DRE4iLCJzdGFjayIsImF1dG9kb3dubG9hZFN1Z2dlc3Rpb24iLCJFcnJvciIsImJpblBhdGgiLCJpbml0Q2hyb21lZHJpdmVyUGF0aCIsInN5bmNQcm90b2NvbCIsIlczQyIsImNocm9tZU9wdGlvbnMiLCJ3M2MiLCJzdGFydCIsImNhcHMiLCJlbWl0U3RhcnRpbmdTdGF0ZSIsImxvZ2dpbmdQcmVmcyIsImJyb3dzZXIiLCJjaGFuZ2VTdGF0ZSIsIlNUQVRFX1NUQVJUSU5HIiwiYWRiUG9ydCIsInB1c2giLCJpc0FycmF5Iiwic3RhcnREZXRlY3RvciIsInN0YXJ0c1dpdGgiLCJwcm9jZXNzSXNBbGl2ZSIsIndlYnZpZXdWZXJzaW9uIiwia2lsbEFsbCIsIlN1YlByb2Nlc3MiLCJvbiIsIm91dCIsImxpbmUiLCJ0cmltIiwic3BsaXQiLCJlcnJvciIsImNvZGUiLCJzaWduYWwiLCJTVEFURV9TVE9QUElORyIsIlNUQVRFX1JFU1RBUlRJTkciLCJtc2ciLCJqb2luIiwid2FpdEZvck9ubGluZSIsInN0YXJ0U2Vzc2lvbiIsImVtaXQiLCJFVkVOVF9FUlJPUiIsInN0b3AiLCJ2ZXJzaW9uc1N1cHBvcnRlZEJ5RHJpdmVyIiwic2Vzc2lvbklkIiwiU1RBVEVfT05MSU5FIiwicmVzdGFydCIsImNocm9tZWRyaXZlclN0b3BwZWQiLCJnZXRTdGF0dXMiLCJjb21tYW5kIiwic2Vzc2lvbkNhcHMiLCJhbHdheXNNYXRjaCIsImRlc2lyZWRDYXBhYmlsaXRpZXMiLCJwcmVmaXgiLCJlbWl0U3RhdGVzIiwicnVuU2FmZVN0ZXAiLCJmIiwiRVZFTlRfQ0hBTkdFRCIsInNlbmRDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsInByb3h5UmVxIiwicmVxIiwicmVzIiwicHJveHlSZXFSZXMiLCJjbWQiLCJzeXN0ZW0iLCJpc1dpbmRvd3MiLCJCIiwicHJvbWlzaWZ5IiwiY3AiLCJ1ZGlkSW5kZXgiLCJkZWZhdWx0QXJncyIsImZpbmRJbmRleCIsIml0ZW0iLCJ1ZGlkIiwiY29ubiIsImdldEZvcndhcmRMaXN0Iiwi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Q3NMLGFBQWIsR0FBNkIsY0FBN0I7QUFDQXRMLFlBQVksQ0FBQzRCLGFBQWIsR0FBNkIsU0FBN0I7QUFDQTVCLFlBQVksQ0FBQzZJLGNBQWIsR0FBOEIsVUFBOUI7QUFDQTdJLFlBQVksQ0FBQzBLLFlBQWIsR0FBNEIsUUFBNUI7QUFDQTFLLFlBQVksQ0FBQytKLGNBQWIsR0FBOEIsVUFBOUI7QUFDQS9KLFlBQVksQ0FBQ2dLLGdCQUFiLEdBQWdDLFlBQWhDO2VBR2VoSyxZIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJhbnNwaWxlOm1haW5cblxuaW1wb3J0IGV2ZW50cyBmcm9tICdldmVudHMnO1xuaW1wb3J0IHsgSldQcm94eSwgUFJPVE9DT0xTIH0gZnJvbSAnQGFwcGl1bS9iYXNlLWRyaXZlcic7XG5pbXBvcnQgY3AgZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgeyBzeXN0ZW0sIGZzLCBsb2dnZXIsIHV0aWwgfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IHsgcmV0cnlJbnRlcnZhbCwgYXN5bmNtYXAgfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyBTdWJQcm9jZXNzLCBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCB7XG4gIGdldENocm9tZVZlcnNpb24sIGdldENocm9tZWRyaXZlckRpciwgQ0hST01FRFJJVkVSX0NIUk9NRV9NQVBQSU5HLFxuICBnZXRDaHJvbWVkcml2ZXJCaW5hcnlQYXRoLCBDRF9DRE4sIGdlbmVyYXRlTG9nUHJlZml4XG59IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGNvbXBhcmVWZXJzaW9ucyBmcm9tICdjb21wYXJlLXZlcnNpb25zJztcbmltcG9ydCBDaHJvbWVkcml2ZXJTdG9yYWdlQ2xpZW50IGZyb20gJy4vc3RvcmFnZS1jbGllbnQnO1xuaW1wb3J0IHsgdG9XM2NDYXBOYW1lcywgZ2V0Q2FwVmFsdWUgfSBmcm9tICcuL3Byb3RvY29sLWhlbHBlcnMnO1xuXG5jb25zdCBORVdfQ0RfVkVSU0lPTl9GT1JNQVRfTUFKT1JfVkVSU0lPTiA9IDczO1xuY29uc3QgREVGQVVMVF9IT1NUID0gJzEyNy4wLjAuMSc7XG5jb25zdCBNSU5fQ0RfVkVSU0lPTl9XSVRIX1czQ19TVVBQT1JUID0gNzU7XG5jb25zdCBERUZBVUxUX1BPUlQgPSA5NTE1O1xuY29uc3QgQ0hST01FX0JVTkRMRV9JRCA9ICdjb20uYW5kcm9pZC5jaHJvbWUnO1xuY29uc3QgV0VCVklFV19TSEVMTF9CVU5ETEVfSUQgPSAnb3JnLmNocm9taXVtLndlYnZpZXdfc2hlbGwnO1xuY29uc3QgV0VCVklFV19CVU5ETEVfSURTID0gW1xuICAnY29tLmdvb2dsZS5hbmRyb2lkLndlYnZpZXcnLFxuICAnY29tLmFuZHJvaWQud2VidmlldycsXG5dO1xuY29uc3QgQ0hST01FRFJJVkVSX1RVVE9SSUFMID0gJ2h0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2Jsb2IvbWFzdGVyL2RvY3MvZW4vd3JpdGluZy1ydW5uaW5nLWFwcGl1bS93ZWIvY2hyb21lZHJpdmVyLm1kJztcbmNvbnN0IFZFUlNJT05fUEFUVEVSTiA9IC8oW1xcZC5dKykvO1xuXG5jb25zdCBDRF9WRVJTSU9OX1RJTUVPVVQgPSA1MDAwO1xuXG5jbGFzcyBDaHJvbWVkcml2ZXIgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgY29uc3RydWN0b3IgKGFyZ3MgPSB7fSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBob3N0ID0gREVGQVVMVF9IT1NULFxuICAgICAgcG9ydCA9IERFRkFVTFRfUE9SVCxcbiAgICAgIHVzZVN5c3RlbUV4ZWN1dGFibGUgPSBmYWxzZSxcbiAgICAgIGV4ZWN1dGFibGUsXG4gICAgICBleGVjdXRhYmxlRGlyID0gZ2V0Q2hyb21lZHJpdmVyRGlyKCksXG4gICAgICBidW5kbGVJZCxcbiAgICAgIG1hcHBpbmdQYXRoLFxuICAgICAgY21kQXJncyxcbiAgICAgIGFkYixcbiAgICAgIHZlcmJvc2UsXG4gICAgICBsb2dQYXRoLFxuICAgICAgZGlzYWJsZUJ1aWxkQ2hlY2ssXG4gICAgICBkZXRhaWxzLFxuICAgICAgaXNBdXRvZG93bmxvYWRFbmFibGVkID0gZmFsc2UsXG4gICAgfSA9IGFyZ3M7XG4gICAgdGhpcy5fbG9nID0gbG9nZ2VyLmdldExvZ2dlcihnZW5lcmF0ZUxvZ1ByZWZpeCh0aGlzKSk7XG5cbiAgICB0aGlzLnByb3h5SG9zdCA9IGhvc3Q7XG4gICAgdGhpcy5wcm94eVBvcnQgPSBwb3J0O1xuICAgIHRoaXMuYWRiID0gYWRiO1xuICAgIHRoaXMuY21kQXJncyA9IGNtZEFyZ3M7XG4gICAgdGhpcy5wcm9jID0gbnVsbDtcbiAgICB0aGlzLnVzZVN5c3RlbUV4ZWN1dGFibGUgPSB1c2VTeXN0ZW1FeGVjdXRhYmxlO1xuICAgIHRoaXMuY2hyb21lZHJpdmVyID0gZXhlY3V0YWJsZTtcbiAgICB0aGlzLmV4ZWN1dGFibGVEaXIgPSBleGVjdXRhYmxlRGlyO1xuICAgIHRoaXMubWFwcGluZ1BhdGggPSBtYXBwaW5nUGF0aDtcbiAgICB0aGlzLmJ1bmRsZUlkID0gYnVuZGxlSWQ7XG4gICAgdGhpcy5leGVjdXRhYmxlVmVyaWZpZWQgPSBmYWxzZTtcbiAgICB0aGlzLnN0YXRlID0gQ2hyb21lZHJpdmVyLlNUQVRFX1NUT1BQRUQ7XG4gICAgdGhpcy5qd3Byb3h5ID0gbmV3IEpXUHJveHkoe1xuICAgICAgc2VydmVyOiB0aGlzLnByb3h5SG9zdCxcbiAgICAgIHBvcnQ6IHRoaXMucHJveHlQb3J0LFxuICAgICAgbG9nOiB0aGlzLl9sb2csXG4gICAgfSk7XG4gICAgdGhpcy52ZXJib3NlID0gdmVyYm9zZTtcbiAgICB0aGlzLmxvZ1BhdGggPSBsb2dQYXRoO1xuICAgIHRoaXMuZGlzYWJsZUJ1aWxkQ2hlY2sgPSAhIWRpc2FibGVCdWlsZENoZWNrO1xuICAgIHRoaXMuc3RvcmFnZUNsaWVudCA9IGlzQXV0b2Rvd25sb2FkRW5hYmxlZFxuICAgICAgPyBuZXcgQ2hyb21lZHJpdmVyU3RvcmFnZUNsaWVudCh7IGNocm9tZWRyaXZlckRpcjogdGhpcy5leGVjdXRhYmxlRGlyIH0pXG4gICAgICA6IG51bGw7XG4gICAgdGhpcy5kZXRhaWxzID0gZGV0YWlscztcbiAgICB0aGlzLmNhcGFiaWxpdGllcyA9IHt9O1xuICAgIHRoaXMuZGVzaXJlZFByb3RvY29sID0gUFJPVE9DT0xTLk1KU09OV1A7XG4gIH1cblxuICBnZXQgbG9nICgpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9nO1xuICB9XG5cbiAgYXN5bmMgZ2V0RHJpdmVyc01hcHBpbmcgKCkge1xuICAgIGxldCBtYXBwaW5nID0gXy5jbG9uZURlZXAoQ0hST01FRFJJVkVSX0NIUk9NRV9NQVBQSU5HKTtcbiAgICBpZiAodGhpcy5tYXBwaW5nUGF0aCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYEF0dGVtcHRpbmcgdG8gdXNlIENocm9tZWRyaXZlci0+Q2hyb21lIG1hcHBpbmcgZnJvbSAnJHt0aGlzLm1hcHBpbmdQYXRofSdgKTtcbiAgICAgIGlmICghYXdhaXQgZnMuZXhpc3RzKHRoaXMubWFwcGluZ1BhdGgpKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oYE5vIGZpbGUgZm91bmQgYXQgJyR7dGhpcy5tYXBwaW5nUGF0aH0nYCk7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0RlZmF1bHRpbmcgdG8gdGhlIHN0YXRpYyBDaHJvbWVkcml2ZXItPkNocm9tZSBtYXBwaW5nJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG1hcHBpbmcgPSBKU09OLnBhcnNlKGF3YWl0IGZzLnJlYWRGaWxlKHRoaXMubWFwcGluZ1BhdGgsICd1dGY4JykpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLmxvZy53YXJuKGBFcnJvciBwYXJzaW5nIG1hcHBpbmcgZnJvbSAnJHt0aGlzLm1hcHBpbmdQYXRofSc6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgdGhpcy5sb2cuaW5mbygnRGVmYXVsdGluZyB0byB0aGUgc3RhdGljIENocm9tZWRyaXZlci0+Q2hyb21lIG1hcHBpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZygnVXNpbmcgdGhlIHN0YXRpYyBDaHJvbWVkcml2ZXItPkNocm9tZSBtYXBwaW5nJyk7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIHZhbHVlcyBmb3IgbWluaW11bSBjaHJvbWUgdmVyc2lvbiBhcmUgc2VtdmVyIGNvbXBsaWFudFxuICAgIGZvciAoY29uc3QgW2NkVmVyc2lvbiwgY2hyb21lVmVyc2lvbl0gb2YgXy50b1BhaXJzKG1hcHBpbmcpKSB7XG4gICAgICBjb25zdCBjb2VyY2VkVmVyc2lvbiA9IHNlbXZlci5jb2VyY2UoY2hyb21lVmVyc2lvbik7XG4gICAgICBpZiAoY29lcmNlZFZlcnNpb24pIHtcbiAgICAgICAgbWFwcGluZ1tjZFZlcnNpb25dID0gY29lcmNlZFZlcnNpb24udmVyc2lvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oYCcke2Nocm9tZVZlcnNpb259JyBpcyBub3QgYSB2YWxpZCB2ZXJzaW9uIG51bWJlci4gU2tpcHBpbmcgaXRgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcHBpbmc7XG4gIH1cblxuICBhc3luYyBnZXRDaHJvbWVkcml2ZXJzIChtYXBwaW5nKSB7XG4gICAgLy8gZ28gdGhyb3VnaCB0aGUgdmVyc2lvbnMgYXZhaWxhYmxlXG4gICAgY29uc3QgZXhlY3V0YWJsZXMgPSBhd2FpdCBmcy5nbG9iKCcqJywge1xuICAgICAgY3dkOiB0aGlzLmV4ZWN1dGFibGVEaXIsXG4gICAgICBzdHJpY3Q6IGZhbHNlLFxuICAgICAgbm9kaXI6IHRydWUsXG4gICAgICBhYnNvbHV0ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgRm91bmQgJHt1dGlsLnBsdXJhbGl6ZSgnZXhlY3V0YWJsZScsIGV4ZWN1dGFibGVzLmxlbmd0aCwgdHJ1ZSl9IGAgK1xuICAgICAgYGluICcke3RoaXMuZXhlY3V0YWJsZURpcn0nYCk7XG4gICAgY29uc3QgY2RzID0gKGF3YWl0IGFzeW5jbWFwKGV4ZWN1dGFibGVzLCBhc3luYyAoZXhlY3V0YWJsZSkgPT4ge1xuICAgICAgY29uc3QgbG9nRXJyb3IgPSAoe21lc3NhZ2UsIHN0ZG91dCA9IG51bGwsIHN0ZGVyciA9IG51bGx9KSA9PiB7XG4gICAgICAgIGxldCBlcnJNc2cgPSBgQ2Fubm90IHJldHJpZXZlIHZlcnNpb24gbnVtYmVyIGZyb20gJyR7cGF0aC5iYXNlbmFtZShleGVjdXRhYmxlKX0nIENocm9tZWRyaXZlciBiaW5hcnkuIGAgK1xuICAgICAgICAgIGBNYWtlIHN1cmUgaXQgcmV0dXJucyBhIHZhbGlkIHZlcnNpb24gc3RyaW5nIGluIHJlc3BvbnNlIHRvICctLXZlcnNpb24nIGNvbW1hbmQgbGluZSBhcmd1bWVudC4gJHttZXNzYWdlfWA7XG4gICAgICAgIGlmIChzdGRvdXQpIHtcbiAgICAgICAgICBlcnJNc2cgKz0gYFxcblN0ZG91dDogJHtzdGRvdXR9YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgZXJyTXNnICs9IGBcXG5TdGRlcnI6ICR7c3RkZXJyfWA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2cud2FybihlcnJNc2cpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIGxldCBzdGRvdXQ7XG4gICAgICBsZXQgc3RkZXJyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgKHtzdGRvdXQsIHN0ZGVycn0gPSBhd2FpdCBleGVjKGV4ZWN1dGFibGUsIFsnLS12ZXJzaW9uJ10sIHtcbiAgICAgICAgICB0aW1lb3V0OiBDRF9WRVJTSU9OX1RJTUVPVVQsXG4gICAgICAgIH0pKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoIShlcnIubWVzc2FnZSB8fCAnJykuaW5jbHVkZXMoJ3RpbWVkIG91dCcpICYmICEoZXJyLnN0ZG91dCB8fCAnJykuaW5jbHVkZXMoJ1N0YXJ0aW5nIENocm9tZURyaXZlcicpKSB7XG4gICAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGlzIGhhcyB0aW1lZCBvdXQsIGl0IGhhcyBhY3R1YWxseSBzdGFydGVkIENocm9tZWRyaXZlcixcbiAgICAgICAgLy8gaW4gd2hpY2ggY2FzZSB0aGVyZSB3aWxsIGFsc28gYmUgdGhlIHZlcnNpb24gc3RyaW5nIGluIHRoZSBvdXRwdXRcbiAgICAgICAgc3Rkb3V0ID0gZXJyLnN0ZG91dDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWF0Y2ggPSAvQ2hyb21lRHJpdmVyXFxzK1xcKD92PyhbXFxkLl0rKVxcKT8vaS5leGVjKHN0ZG91dCk7IC8vIGh0dHBzOi8vcmVnZXgxMDEuY29tL3IvenBqNXdBLzFcbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKHttZXNzYWdlOiAnQ2Fubm90IHBhcnNlIHRoZSB2ZXJzaW9uIHN0cmluZycsIHN0ZG91dCwgc3RkZXJyfSk7XG4gICAgICB9XG4gICAgICBsZXQgdmVyc2lvbiA9IG1hdGNoWzFdO1xuICAgICAgbGV0IG1pbkNocm9tZVZlcnNpb24gPSBtYXBwaW5nW3ZlcnNpb25dO1xuICAgICAgY29uc3QgY29lcmNlZFZlcnNpb24gPSBzZW12ZXIuY29lcmNlKHZlcnNpb24pO1xuICAgICAgaWYgKGNvZXJjZWRWZXJzaW9uKSB7XG4gICAgICAgIC8vIGJlZm9yZSAyMDE5LTAzLTA2IHZlcnNpb25zIHdlcmUgb2YgdGhlIGZvcm0gbWFqb3IubWlub3JcbiAgICAgICAgaWYgKGNvZXJjZWRWZXJzaW9uLm1ham9yIDwgTkVXX0NEX1ZFUlNJT05fRk9STUFUX01BSk9SX1ZFUlNJT04pIHtcbiAgICAgICAgICB2ZXJzaW9uID0gYCR7Y29lcmNlZFZlcnNpb24ubWFqb3J9LiR7Y29lcmNlZFZlcnNpb24ubWlub3J9YDtcbiAgICAgICAgICBtaW5DaHJvbWVWZXJzaW9uID0gbWFwcGluZ1t2ZXJzaW9uXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW1pbkNocm9tZVZlcnNpb24gJiYgY29lcmNlZFZlcnNpb24ubWFqb3IgPj0gTkVXX0NEX1ZFUlNJT05fRk9STUFUX01BSk9SX1ZFUlNJT04pIHtcbiAgICAgICAgICAvLyBBc3N1bWUgdGhlIG1ham9yIENocm9tZSB2ZXJzaW9uIGlzIHRoZSBzYW1lIGFzIHRoZSBjb3JyZXNwb25kaW5nIGRyaXZlciBtYWpvciB2ZXJzaW9uXG4gICAgICAgICAgbWluQ2hyb21lVmVyc2lvbiA9IGAke2NvZXJjZWRWZXJzaW9uLm1ham9yfWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGV4ZWN1dGFibGUsXG4gICAgICAgIHZlcnNpb24sXG4gICAgICAgIG1pbkNocm9tZVZlcnNpb24sXG4gICAgICB9O1xuICAgIH0pKVxuICAgICAgLmZpbHRlcigoY2QpID0+ICEhY2QpXG4gICAgICAuc29ydCgoYSwgYikgPT4gY29tcGFyZVZlcnNpb25zKGIudmVyc2lvbiwgYS52ZXJzaW9uKSk7XG4gICAgaWYgKF8uaXNFbXB0eShjZHMpKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBObyBDaHJvbWVkcml2ZXJzIHdlcmUgZm91bmQgaW4gJyR7dGhpcy5leGVjdXRhYmxlRGlyfSdgKTtcbiAgICAgIHJldHVybiBjZHM7XG4gICAgfVxuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgZm9sbG93aW5nIENocm9tZWRyaXZlciBleGVjdXRhYmxlcyB3ZXJlIGZvdW5kOmApO1xuICAgIGZvciAoY29uc3QgY2Qgb2YgY2RzKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgICAgICcke2NkLmV4ZWN1dGFibGV9JyAodmVyc2lvbiAnJHtjZC52ZXJzaW9ufScsIG1pbmltdW0gQ2hyb21lIHZlcnNpb24gJyR7Y2QubWluQ2hyb21lVmVyc2lvbiA/IGNkLm1pbkNocm9tZVZlcnNpb24gOiAnVW5rbm93bid9JylgKTtcbiAgICB9XG4gICAgcmV0dXJuIGNkcztcbiAgfVxuXG4gIGFzeW5jIGdldENocm9tZVZlcnNpb24gKCkge1xuICAgIC8vIFRyeSB0byByZXRyaWV2ZSB0aGUgdmVyc2lvbiBmcm9tIGBkZXRhaWxzYCBwcm9wZXJ0eSBpZiBpdCBpcyBzZXRcbiAgICAvLyBUaGUgYGluZm9gIGl0ZW0gbXVzdCBjb250YWluIHRoZSBvdXRwdXQgb2YgL2pzb24vdmVyc2lvbiBDRFAgY29tbWFuZFxuICAgIC8vIHdoZXJlIGBCcm93c2VyYCBmaWVsZCBsb29rcyBsaWtlIGBDaHJvbWUvNzIuMC4zNjAxLjBgYFxuICAgIGlmICh0aGlzLmRldGFpbHM/LmluZm8pIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBCcm93c2VyIHZlcnNpb24gaW4gdGhlIHN1cHBsaWVkIGRldGFpbHM6ICR7dGhpcy5kZXRhaWxzPy5pbmZvPy5Ccm93c2VyfWApO1xuICAgIH1cbiAgICBjb25zdCB2ZXJzaW9uTWF0Y2ggPSBWRVJTSU9OX1BBVFRFUk4uZXhlYyh0aGlzLmRldGFpbHM/LmluZm8/LkJyb3dzZXIpO1xuICAgIGlmICh2ZXJzaW9uTWF0Y2gpIHtcbiAgICAgIGNvbnN0IGNvZXJjZWRWZXJzaW9uID0gc2VtdmVyLmNvZXJjZSh2ZXJzaW9uTWF0Y2hbMV0pO1xuICAgICAgaWYgKGNvZXJjZWRWZXJzaW9uKSB7XG4gICAgICAgIHJldHVybiBjb2VyY2VkVmVyc2lvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgY2hyb21lVmVyc2lvbjtcblxuICAgIC8vIGluIGNhc2Ugb2YgV2ViVmlldyBCcm93c2VyIFRlc3Rlciwgc2ltcGx5IHRyeSB0byBmaW5kIHRoZSB1bmRlcmx5aW5nIHdlYnZpZXdcbiAgICBpZiAodGhpcy5idW5kbGVJZCA9PT0gV0VCVklFV19TSEVMTF9CVU5ETEVfSUQpIHtcbiAgICAgIGZvciAoY29uc3QgYnVuZGxlSWQgb2YgV0VCVklFV19CVU5ETEVfSURTKSB7XG4gICAgICAgIGNocm9tZVZlcnNpb24gPSBhd2FpdCBnZXRDaHJvbWVWZXJzaW9uKHRoaXMuYWRiLCBidW5kbGVJZCk7XG4gICAgICAgIGlmIChjaHJvbWVWZXJzaW9uKSB7XG4gICAgICAgICAgdGhpcy5idW5kbGVJZCA9IGJ1bmRsZUlkO1xuICAgICAgICAgIHJldHVybiBzZW12ZXIuY29lcmNlKGNocm9tZVZlcnNpb24pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBvbiBBbmRyb2lkIDctOSB3ZWJ2aWV3cyBhcmUgYmFja2VkIGJ5IHRoZSBtYWluIENocm9tZSwgbm90IHRoZSBzeXN0ZW0gd2Vidmlld1xuICAgIGlmICh0aGlzLmFkYikge1xuICAgICAgY29uc3QgYXBpTGV2ZWwgPSBhd2FpdCB0aGlzLmFkYi5nZXRBcGlMZXZlbCgpO1xuICAgICAgaWYgKGFwaUxldmVsID49IDI0ICYmIGFwaUxldmVsIDw9IDI4ICYmXG4gICAgICAgICAgW1dFQlZJRVdfU0hFTExfQlVORExFX0lELCAuLi5XRUJWSUVXX0JVTkRMRV9JRFNdLmluY2x1ZGVzKHRoaXMuYnVuZGxlSWQpKSB7XG4gICAgICAgIHRoaXMuYnVuZGxlSWQgPSBDSFJPTUVfQlVORExFX0lEO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRyeSBvdXQgd2Vidmlld3Mgd2hlbiBubyBidW5kbGUgaWQgaXMgc2VudCBpblxuICAgIGlmICghdGhpcy5idW5kbGVJZCkge1xuICAgICAgLy8gZGVmYXVsdCB0byB0aGUgZ2VuZXJpYyBDaHJvbWUgYnVuZGxlXG4gICAgICB0aGlzLmJ1bmRsZUlkID0gQ0hST01FX0JVTkRMRV9JRDtcblxuICAgICAgLy8gd2UgaGF2ZSBhIHdlYnZpZXcgb2Ygc29tZSBzb3J0LCBzbyB0cnkgdG8gZmluZCB0aGUgYnVuZGxlIHZlcnNpb25cbiAgICAgIGZvciAoY29uc3QgYnVuZGxlSWQgb2YgV0VCVklFV19CVU5ETEVfSURTKSB7XG4gICAgICAgIGNocm9tZVZlcnNpb24gPSBhd2FpdCBnZXRDaHJvbWVWZXJzaW9uKHRoaXMuYWRiLCBidW5kbGVJZCk7XG4gICAgICAgIGlmIChjaHJvbWVWZXJzaW9uKSB7XG4gICAgICAgICAgdGhpcy5idW5kbGVJZCA9IGJ1bmRsZUlkO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgd2UgZG8gbm90IGhhdmUgYSBjaHJvbWUgdmVyc2lvbiwgaXQgbXVzdCBub3QgYmUgYSB3ZWJ2aWV3XG4gICAgaWYgKCFjaHJvbWVWZXJzaW9uKSB7XG4gICAgICBjaHJvbWVWZXJzaW9uID0gYXdhaXQgZ2V0Q2hyb21lVmVyc2lvbih0aGlzLmFkYiwgdGhpcy5idW5kbGVJZCk7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIGl0IGlzIHNlbXZlciwgc28gbGF0ZXIgY2hlY2tzIHdvbid0IGZhaWxcbiAgICByZXR1cm4gY2hyb21lVmVyc2lvbiA/IHNlbXZlci5jb2VyY2UoY2hyb21lVmVyc2lvbikgOiBudWxsO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlRHJpdmVyc01hcHBpbmcgKG5ld01hcHBpbmcpIHtcbiAgICBsZXQgc2hvdWxkVXBkYXRlU3RhdGljTWFwcGluZyA9IHRydWU7XG4gICAgaWYgKGF3YWl0IGZzLmV4aXN0cyh0aGlzLm1hcHBpbmdQYXRoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHRoaXMubWFwcGluZ1BhdGgsIEpTT04uc3RyaW5naWZ5KG5ld01hcHBpbmcsIG51bGwsIDIpLCAndXRmOCcpO1xuICAgICAgICBzaG91bGRVcGRhdGVTdGF0aWNNYXBwaW5nID0gZmFsc2U7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oYENhbm5vdCBzdG9yZSB0aGUgdXBkYXRlZCBjaHJvbWVkcml2ZXJzIG1hcHBpbmcgaW50byAnJHt0aGlzLm1hcHBpbmdQYXRofScuIGAgK1xuICAgICAgICAgIGBUaGlzIG1heSByZWR1Y2UgdGhlIHBlcmZvcm1hbmNlIG9mIGZ1cnRoZXIgZXhlY3V0aW9ucy4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hvdWxkVXBkYXRlU3RhdGljTWFwcGluZykge1xuICAgICAgT2JqZWN0LmFzc2lnbihDSFJPTUVEUklWRVJfQ0hST01FX01BUFBJTkcsIG5ld01hcHBpbmcpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENvbXBhdGlibGVDaHJvbWVkcml2ZXIgKCkge1xuICAgIGlmICghdGhpcy5hZGIpIHtcbiAgICAgIHJldHVybiBhd2FpdCBnZXRDaHJvbWVkcml2ZXJCaW5hcnlQYXRoKCk7XG4gICAgfVxuXG4gICAgY29uc3QgbWFwcGluZyA9IGF3YWl0IHRoaXMuZ2V0RHJpdmVyc01hcHBpbmcoKTtcbiAgICBpZiAoIV8uaXNFbXB0eShtYXBwaW5nKSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBtb3N0IHJlY2VudCBrbm93biBDaHJvbWUgdmVyc2lvbjogJHtfLnZhbHVlcyhtYXBwaW5nKVswXX1gKTtcbiAgICB9XG5cbiAgICBsZXQgZGlkU3RvcmFnZVN5bmMgPSBmYWxzZTtcbiAgICBjb25zdCBzeW5jQ2hyb21lZHJpdmVycyA9IGFzeW5jIChjaHJvbWVWZXJzaW9uKSA9PiB7XG4gICAgICBkaWRTdG9yYWdlU3luYyA9IHRydWU7XG4gICAgICBjb25zdCByZXRyaWV2ZWRNYXBwaW5nID0gYXdhaXQgdGhpcy5zdG9yYWdlQ2xpZW50LnJldHJpZXZlTWFwcGluZygpO1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ0dvdCBjaHJvbWVkcml2ZXJzIG1hcHBpbmcgZnJvbSB0aGUgc3RvcmFnZTogJyArXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHJldHJpZXZlZE1hcHBpbmcsIG51bGwsIDIpKTtcbiAgICAgIGNvbnN0IGRyaXZlcktleXMgPSBhd2FpdCB0aGlzLnN0b3JhZ2VDbGllbnQuc3luY0RyaXZlcnMoe1xuICAgICAgICBtaW5Ccm93c2VyVmVyc2lvbjogY2hyb21lVmVyc2lvbi5tYWpvcixcbiAgICAgIH0pO1xuICAgICAgaWYgKF8uaXNFbXB0eShkcml2ZXJLZXlzKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBzeW5jaHJvbml6ZWREcml2ZXJzTWFwcGluZyA9IGRyaXZlcktleXMucmVkdWNlKChhY2MsIHgpID0+IHtcbiAgICAgICAgY29uc3Qge3ZlcnNpb24sIG1pbkJyb3dzZXJWZXJzaW9ufSA9IHJldHJpZXZlZE1hcHBpbmdbeF07XG4gICAgICAgIGFjY1t2ZXJzaW9uXSA9IG1pbkJyb3dzZXJWZXJzaW9uO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwge30pO1xuICAgICAgT2JqZWN0LmFzc2lnbihtYXBwaW5nLCBzeW5jaHJvbml6ZWREcml2ZXJzTWFwcGluZyk7XG4gICAgICBhd2FpdCB0aGlzLnVwZGF0ZURyaXZlcnNNYXBwaW5nKG1hcHBpbmcpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGRvIHtcbiAgICAgIGNvbnN0IGNkcyA9IGF3YWl0IHRoaXMuZ2V0Q2hyb21lZHJpdmVycyhtYXBwaW5nKTtcblxuICAgICAgY29uc3QgbWlzc2luZ1ZlcnNpb25zID0ge307XG4gICAgICBmb3IgKGNvbnN0IHt2ZXJzaW9uLCBtaW5DaHJvbWVWZXJzaW9ufSBvZiBjZHMpIHtcbiAgICAgICAgaWYgKCFtaW5DaHJvbWVWZXJzaW9uIHx8IG1hcHBpbmdbdmVyc2lvbl0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb2VyY2VkVmVyID0gc2VtdmVyLmNvZXJjZSh2ZXJzaW9uKTtcbiAgICAgICAgaWYgKCFjb2VyY2VkVmVyIHx8IGNvZXJjZWRWZXIubWFqb3IgPCBORVdfQ0RfVkVSU0lPTl9GT1JNQVRfTUFKT1JfVkVSU0lPTikge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbWlzc2luZ1ZlcnNpb25zW3ZlcnNpb25dID0gbWluQ2hyb21lVmVyc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmICghXy5pc0VtcHR5KG1pc3NpbmdWZXJzaW9ucykpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbyhgRm91bmQgJHt1dGlsLnBsdXJhbGl6ZSgnQ2hyb21lZHJpdmVyJywgXy5zaXplKG1pc3NpbmdWZXJzaW9ucyksIHRydWUpfSwgYCArXG4gICAgICAgICAgYHdoaWNoICR7Xy5zaXplKG1pc3NpbmdWZXJzaW9ucykgPT09IDEgPyAnaXMnIDogJ2FyZSd9IG1pc3NpbmcgaW4gdGhlIGxpc3Qgb2Yga25vd24gdmVyc2lvbnM6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG1pc3NpbmdWZXJzaW9ucykpO1xuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZURyaXZlcnNNYXBwaW5nKE9iamVjdC5hc3NpZ24obWFwcGluZywgbWlzc2luZ1ZlcnNpb25zKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmRpc2FibGVCdWlsZENoZWNrKSB7XG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2RzKSkge1xuICAgICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coYFRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIENocm9tZWRyaXZlciBleGVjdXRhYmxlIGF2YWlsYWJsZSBmb3IgdXNlIGlmIGAgK1xuICAgICAgICAgICAgYCdjaHJvbWVkcml2ZXJEaXNhYmxlQnVpbGRDaGVjaycgY2FwYWJpbGl0eSBpcyBzZXQgdG8gJ3RydWUnYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qge3ZlcnNpb24sIGV4ZWN1dGFibGV9ID0gY2RzWzBdO1xuICAgICAgICB0aGlzLmxvZy53YXJuKGBDaHJvbWUgYnVpbGQgY2hlY2sgZGlzYWJsZWQuIFVzaW5nIG1vc3QgcmVjZW50IENocm9tZWRyaXZlciB2ZXJzaW9uICgke3ZlcnNpb259LCBhdCAnJHtleGVjdXRhYmxlfScpYCk7XG4gICAgICAgIHRoaXMubG9nLndhcm4oYElmIHRoaXMgaXMgd3JvbmcsIHNldCAnY2hyb21lZHJpdmVyRGlzYWJsZUJ1aWxkQ2hlY2snIGNhcGFiaWxpdHkgdG8gJ2ZhbHNlJ2ApO1xuICAgICAgICByZXR1cm4gZXhlY3V0YWJsZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hyb21lVmVyc2lvbiA9IGF3YWl0IHRoaXMuZ2V0Q2hyb21lVmVyc2lvbigpO1xuICAgICAgaWYgKCFjaHJvbWVWZXJzaW9uKSB7XG4gICAgICAgIC8vIHVuYWJsZSB0byBnZXQgdGhlIGNocm9tZSB2ZXJzaW9uXG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2RzKSkge1xuICAgICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coYFRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIENocm9tZWRyaXZlciBleGVjdXRhYmxlIGF2YWlsYWJsZSBmb3IgdXNlIGlmIGAgK1xuICAgICAgICAgICAgYHRoZSBjdXJyZW50IENocm9tZSB2ZXJzaW9uIGNhbm5vdCBiZSBkZXRlcm1pbmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qge3ZlcnNpb24sIGV4ZWN1dGFibGV9ID0gY2RzWzBdO1xuICAgICAgICB0aGlzLmxvZy53YXJuKGBVbmFibGUgdG8gZGlzY292ZXIgQ2hyb21lIHZlcnNpb24uIFVzaW5nIENocm9tZWRyaXZlciAke3ZlcnNpb259IGF0ICcke2V4ZWN1dGFibGV9J2ApO1xuICAgICAgICByZXR1cm4gZXhlY3V0YWJsZTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLmRlYnVnKGBGb3VuZCBDaHJvbWUgYnVuZGxlICcke3RoaXMuYnVuZGxlSWR9JyB2ZXJzaW9uICcke2Nocm9tZVZlcnNpb259J2ApO1xuXG4gICAgICBjb25zdCBtYXRjaGluZ0RyaXZlcnMgPSBjZHMuZmlsdGVyKCh7bWluQ2hyb21lVmVyc2lvbn0pID0+IHtcbiAgICAgICAgY29uc3QgbWluQ2hyb21lVmVyc2lvblMgPSBtaW5DaHJvbWVWZXJzaW9uICYmIHNlbXZlci5jb2VyY2UobWluQ2hyb21lVmVyc2lvbik7XG4gICAgICAgIGlmICghbWluQ2hyb21lVmVyc2lvblMpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hyb21lVmVyc2lvbi5tYWpvciA+IE5FV19DRF9WRVJTSU9OX0ZPUk1BVF9NQUpPUl9WRVJTSU9OXG4gICAgICAgICAgPyBtaW5DaHJvbWVWZXJzaW9uUy5tYWpvciA9PT0gY2hyb21lVmVyc2lvbi5tYWpvclxuICAgICAgICAgIDogc2VtdmVyLmd0ZShjaHJvbWVWZXJzaW9uLCBtaW5DaHJvbWVWZXJzaW9uUyk7XG4gICAgICB9KTtcbiAgICAgIGlmIChfLmlzRW1wdHkobWF0Y2hpbmdEcml2ZXJzKSkge1xuICAgICAgICBpZiAodGhpcy5zdG9yYWdlQ2xpZW50ICYmICFkaWRTdG9yYWdlU3luYykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoYXdhaXQgc3luY0Nocm9tZWRyaXZlcnMoY2hyb21lVmVyc2lvbikpIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5sb2cud2FybihgQ2Fubm90IHN5bmNocm9uaXplIGxvY2FsIGNocm9tZWRyaXZlcnMgd2l0aCB0aGUgcmVtb3RlIHN0b3JhZ2UgYXQgJHtDRF9DRE59OiBgICtcbiAgICAgICAgICAgICAgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGUuc3RhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdXRvZG93bmxvYWRTdWdnZXN0aW9uID1cbiAgICAgICAgICAnWW91IGNvdWxkIGFsc28gdHJ5IHRvIGVuYWJsZSBhdXRvbWF0ZWQgY2hyb21lZHJpdmVycyBkb3dubG9hZCBzZXJ2ZXIgZmVhdHVyZSc7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gQ2hyb21lZHJpdmVyIGZvdW5kIHRoYXQgY2FuIGF1dG9tYXRlIENocm9tZSAnJHtjaHJvbWVWZXJzaW9ufScuIGAgK1xuICAgICAgICAgICghdGhpcy5zdG9yYWdlQ2xpZW50ID8gYCR7YXV0b2Rvd25sb2FkU3VnZ2VzdGlvbn0uIGAgOiAnJykgK1xuICAgICAgICAgIGBTZWUgJHtDSFJPTUVEUklWRVJfVFVUT1JJQUx9IGZvciBtb3JlIGRldGFpbHNgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmluUGF0aCA9IG1hdGNoaW5nRHJpdmVyc1swXS5leGVjdXRhYmxlO1xuICAgICAgdGhpcy5sb2cuZGVidWcoYEZvdW5kICR7dXRpbC5wbHVyYWxpemUoJ2V4ZWN1dGFibGUnLCBtYXRjaGluZ0RyaXZlcnMubGVuZ3RoLCB0cnVlKX0gYCArXG4gICAgICAgIGBjYXBhYmxlIG9mIGF1dG9tYXRpbmcgQ2hyb21lICcke2Nocm9tZVZlcnNpb259Jy5cXG5DaG9vc2luZyB0aGUgbW9zdCByZWNlbnQsICcke2JpblBhdGh9Jy5gKTtcbiAgICAgIHRoaXMubG9nLmRlYnVnKCdJZiBhIHNwZWNpZmljIHZlcnNpb24gaXMgcmVxdWlyZWQsIHNwZWNpZnkgaXQgd2l0aCB0aGUgYGNocm9tZWRyaXZlckV4ZWN1dGFibGVgJyArXG4gICAgICAgICdkZXNpcmVkIGNhcGFiaWxpdHkuJyk7XG4gICAgICByZXR1cm4gYmluUGF0aDtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc3RhbnQtY29uZGl0aW9uXG4gICAgfSB3aGlsZSAodHJ1ZSk7XG4gIH1cblxuICBhc3luYyBpbml0Q2hyb21lZHJpdmVyUGF0aCAoKSB7XG4gICAgaWYgKHRoaXMuZXhlY3V0YWJsZVZlcmlmaWVkKSByZXR1cm47IC8vZXNsaW50LWRpc2FibGUtbGluZSBjdXJseVxuXG4gICAgLy8gdGhlIGV4ZWN1dGFibGUgbWlnaHQgYmUgc2V0IChpZiBwYXNzZWQgaW4pXG4gICAgLy8gb3Igd2UgbWlnaHQgd2FudCB0byB1c2UgdGhlIGJhc2ljIG9uZSBpbnN0YWxsZWQgd2l0aCB0aGlzIGRyaXZlclxuICAgIC8vIG9yIHdlIHdhbnQgdG8gZmlndXJlIG91dCB0aGUgYmVzdCBvbmVcbiAgICBpZiAoIXRoaXMuY2hyb21lZHJpdmVyKSB7XG4gICAgICB0aGlzLmNocm9tZWRyaXZlciA9IHRoaXMudXNlU3lzdGVtRXhlY3V0YWJsZVxuICAgICAgICA/IGF3YWl0IGdldENocm9tZWRyaXZlckJpbmFyeVBhdGgoKVxuICAgICAgICA6IGF3YWl0IHRoaXMuZ2V0Q29tcGF0aWJsZUNocm9tZWRyaXZlcigpO1xuICAgIH1cblxuICAgIGlmICghYXdhaXQgZnMuZXhpc3RzKHRoaXMuY2hyb21lZHJpdmVyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUcnlpbmcgdG8gdXNlIGEgY2hyb21lZHJpdmVyIGJpbmFyeSBhdCB0aGUgcGF0aCBgICtcbiAgICAgICAgICAgICAgICAgICAgICBgJHt0aGlzLmNocm9tZWRyaXZlcn0sIGJ1dCBpdCBkb2Vzbid0IGV4aXN0IWApO1xuICAgIH1cbiAgICB0aGlzLmV4ZWN1dGFibGVWZXJpZmllZCA9IHRydWU7XG4gICAgdGhpcy5sb2cuaW5mbyhgU2V0IGNocm9tZWRyaXZlciBiaW5hcnkgYXM6ICR7dGhpcy5jaHJvbWVkcml2ZXJ9YCk7XG4gIH1cblxuICBzeW5jUHJvdG9jb2wgKGNkVmVyc2lvbiA9IG51bGwpIHtcbiAgICBjb25zdCBjb2VyY2VkVmVyc2lvbiA9IHNlbXZlci5jb2VyY2UoY2RWZXJzaW9uKTtcbiAgICBpZiAoIWNvZXJjZWRWZXJzaW9uIHx8IGNvZXJjZWRWZXJzaW9uLm1ham9yIDwgTUlOX0NEX1ZFUlNJT05fV0lUSF9XM0NfU1VQUE9SVCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYENocm9tZWRyaXZlciB2LiAke2NkVmVyc2lvbn0gZG9lcyBub3QgZnVsbHkgc3VwcG9ydCAke1BST1RPQ09MUy5XM0N9IHByb3RvY29sLiBgICtcbiAgICAgICAgYERlZmF1bHRpbmcgdG8gJHtQUk9UT0NPTFMuTUpTT05XUH1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2hyb21lT3B0aW9ucyA9IGdldENhcFZhbHVlKHRoaXMuY2FwYWJpbGl0aWVzLCAnY2hyb21lT3B0aW9ucycsIHt9KTtcbiAgICBpZiAoY2hyb21lT3B0aW9ucy53M2MgPT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBDaHJvbWVkcml2ZXIgdi4gJHtjZFZlcnNpb259IHN1cHBvcnRzICR7UFJPVE9DT0xTLlczQ30gcHJvdG9jb2wsIGAgK1xuICAgICAgICBgYnV0ICR7UFJPVE9DT0xTLk1KU09OV1B9IG9uZSBoYXMgYmVlbiBleHBsaWNpdGx5IHJlcXVlc3RlZGApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRlc2lyZWRQcm90b2NvbCA9IFBST1RPQ09MUy5XM0M7XG4gICAgLy8gZ2l2ZW4gY2FwcyBtaWdodCBub3QgYmUgcHJvcGVybHkgcHJlZml4ZWRcbiAgICAvLyBzbyB3ZSB0cnkgdG8gZml4IHRoZW0gaW4gb3JkZXIgdG8gcHJvcGVybHkgaW5pdFxuICAgIC8vIHRoZSBuZXcgVzNDIHNlc3Npb25cbiAgICB0aGlzLmNhcGFiaWxpdGllcyA9IHRvVzNjQ2FwTmFtZXModGhpcy5jYXBhYmlsaXRpZXMpO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQgKGNhcHMsIGVtaXRTdGFydGluZ1N0YXRlID0gdHJ1ZSkge1xuICAgIHRoaXMuY2FwYWJpbGl0aWVzID0gXy5jbG9uZURlZXAoY2Fwcyk7XG5cbiAgICAvLyBzZXQgdGhlIGxvZ2dpbmcgcHJlZmVyZW5jZXMgdG8gQUxMIHRoZSBjb25zb2xlIGxvZ3NcbiAgICB0aGlzLmNhcGFiaWxpdGllcy5sb2dnaW5nUHJlZnMgPSBfLmNsb25lRGVlcChnZXRDYXBWYWx1ZShjYXBzLCAnbG9nZ2luZ1ByZWZzJywge30pKTtcbiAgICBpZiAoXy5pc0VtcHR5KHRoaXMuY2FwYWJpbGl0aWVzLmxvZ2dpbmdQcmVmcy5icm93c2VyKSkge1xuICAgICAgdGhpcy5jYXBhYmlsaXRpZXMubG9nZ2luZ1ByZWZzLmJyb3dzZXIgPSAnQUxMJztcbiAgICB9XG5cbiAgICBpZiAoZW1pdFN0YXJ0aW5nU3RhdGUpIHtcbiAgICAgIHRoaXMuY2hhbmdlU3RhdGUoQ2hyb21lZHJpdmVyLlNUQVRFX1NUQVJUSU5HKTtcbiAgICB9XG5cbiAgICBjb25zdCBhcmdzID0gW2AtLXBvcnQ9JHt0aGlzLnByb3h5UG9ydH1gXTtcbiAgICBpZiAodGhpcy5hZGIgJiYgdGhpcy5hZGIuYWRiUG9ydCkge1xuICAgICAgYXJncy5wdXNoKGAtLWFkYi1wb3J0PSR7dGhpcy5hZGIuYWRiUG9ydH1gKTtcbiAgICB9XG4gICAgaWYgKF8uaXNBcnJheSh0aGlzLmNtZEFyZ3MpKSB7XG4gICAgICBhcmdzLnB1c2goLi4udGhpcy5jbWRBcmdzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMubG9nUGF0aCkge1xuICAgICAgYXJncy5wdXNoKGAtLWxvZy1wYXRoPSR7dGhpcy5sb2dQYXRofWApO1xuICAgIH1cbiAgICBpZiAodGhpcy5kaXNhYmxlQnVpbGRDaGVjaykge1xuICAgICAgYXJncy5wdXNoKCctLWRpc2FibGUtYnVpbGQtY2hlY2snKTtcbiAgICB9XG4gICAgYXJncy5wdXNoKCctLXZlcmJvc2UnKTtcbiAgICAvLyB3aGF0IGFyZSB0aGUgcHJvY2VzcyBzdGRvdXQvc3RkZXJyIGNvbmRpdGlvbnMgd2hlcmVpbiB3ZSBrbm93IHRoYXRcbiAgICAvLyB0aGUgcHJvY2VzcyBoYXMgc3RhcnRlZCB0byBvdXIgc2F0aXNmYWN0aW9uP1xuICAgIGNvbnN0IHN0YXJ0RGV0ZWN0b3IgPSAoc3Rkb3V0KSA9PiBzdGRvdXQuc3RhcnRzV2l0aCgnU3RhcnRpbmcgJyk7XG5cbiAgICBsZXQgcHJvY2Vzc0lzQWxpdmUgPSBmYWxzZTtcbiAgICBsZXQgd2Vidmlld1ZlcnNpb247XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdENocm9tZWRyaXZlclBhdGgoKTtcbiAgICAgIGF3YWl0IHRoaXMua2lsbEFsbCgpO1xuXG4gICAgICAvLyBzZXQgdXAgb3VyIHN1YnByb2Nlc3Mgb2JqZWN0XG4gICAgICB0aGlzLnByb2MgPSBuZXcgU3ViUHJvY2Vzcyh0aGlzLmNocm9tZWRyaXZlciwgYXJncyk7XG4gICAgICBwcm9jZXNzSXNBbGl2ZSA9IHRydWU7XG5cbiAgICAgIC8vIGhhbmRsZSBsb2cgb3V0cHV0XG4gICAgICB0aGlzLnByb2Mub24oJ291dHB1dCcsIChzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICAvLyBpZiB0aGUgY2Qgb3V0cHV0IGlzIG5vdCBwcmludGVkLCBmaW5kIHRoZSBjaHJvbWUgdmVyc2lvbiBhbmQgcHJpbnRcbiAgICAgICAgLy8gd2lsbCBnZXQgYSByZXNwb25zZSBsaWtlXG4gICAgICAgIC8vICAgRGV2VG9vbHMgcmVzcG9uc2U6IHtcbiAgICAgICAgLy8gICAgICBcIkFuZHJvaWQtUGFja2FnZVwiOiBcImlvLmFwcGl1bS5zYW1wbGVhcHBcIixcbiAgICAgICAgLy8gICAgICBcIkJyb3dzZXJcIjogXCJDaHJvbWUvNTUuMC4yODgzLjkxXCIsXG4gICAgICAgIC8vICAgICAgXCJQcm90b2NvbC1WZXJzaW9uXCI6IFwiMS4yXCIsXG4gICAgICAgIC8vICAgICAgXCJVc2VyLUFnZW50XCI6IFwiLi4uXCIsXG4gICAgICAgIC8vICAgICAgXCJXZWJLaXQtVmVyc2lvblwiOiBcIjUzNy4zNlwiXG4gICAgICAgIC8vICAgfVxuICAgICAgICBjb25zdCBvdXQgPSBzdGRvdXQgKyBzdGRlcnI7XG4gICAgICAgIGxldCBtYXRjaCA9IC9cIkJyb3dzZXJcIjogXCIoLiopXCIvLmV4ZWMob3V0KTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgd2Vidmlld1ZlcnNpb24gPSBtYXRjaFsxXTtcbiAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgV2VidmlldyB2ZXJzaW9uOiAnJHt3ZWJ2aWV3VmVyc2lvbn0nYCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhbHNvIHByaW50IGNocm9tZWRyaXZlciB2ZXJzaW9uIHRvIGxvZ3NcbiAgICAgICAgLy8gd2lsbCBvdXRwdXQgc29tZXRoaW5nIGxpa2VcbiAgICAgICAgLy8gIFN0YXJ0aW5nIENocm9tZURyaXZlciAyLjMzLjUwNjEwNiAoOGEwNmMzOWM0NTgyZmJmYmFiNjk2NmRiYjFjMzhhOTE3M2JmYjFhMikgb24gcG9ydCA5NTE1XG4gICAgICAgIG1hdGNoID0gL1N0YXJ0aW5nIENocm9tZURyaXZlciAoWy5cXGRdKykvLmV4ZWMob3V0KTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgdGhpcy5sb2cuZGVidWcoYENocm9tZWRyaXZlciB2ZXJzaW9uOiAnJHttYXRjaFsxXX0nYCk7XG4gICAgICAgICAgdGhpcy5zeW5jUHJvdG9jb2wobWF0Y2hbMV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZ2l2ZSB0aGUgb3V0cHV0IGlmIGl0IGlzIHJlcXVlc3RlZFxuICAgICAgICBpZiAodGhpcy52ZXJib3NlKSB7XG4gICAgICAgICAgZm9yIChsZXQgbGluZSBvZiAoc3Rkb3V0IHx8ICcnKS50cmltKCkuc3BsaXQoJ1xcbicpKSB7XG4gICAgICAgICAgICBpZiAoIWxpbmUudHJpbSgpLmxlbmd0aCkgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY3VybHlcbiAgICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGBbU1RET1VUXSAke2xpbmV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvciAobGV0IGxpbmUgb2YgKHN0ZGVyciB8fCAnJykudHJpbSgpLnNwbGl0KCdcXG4nKSkge1xuICAgICAgICAgICAgaWYgKCFsaW5lLnRyaW0oKS5sZW5ndGgpIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGN1cmx5XG4gICAgICAgICAgICB0aGlzLmxvZy5lcnJvcihgW1NUREVSUl0gJHtsaW5lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIGhhbmRsZSBvdXQtb2YtYm91bmQgZXhpdCBieSBzaW1wbHkgZW1pdHRpbmcgYSBzdG9wcGVkIHN0YXRlXG4gICAgICB0aGlzLnByb2Mub24oJ2V4aXQnLCAoY29kZSwgc2lnbmFsKSA9PiB7XG4gICAgICAgIHByb2Nlc3NJc0FsaXZlID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBDaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBFRCAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZSAhPT0gQ2hyb21lZHJpdmVyLlNUQVRFX1NUT1BQSU5HICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlICE9PSBDaHJvbWVkcml2ZXIuU1RBVEVfUkVTVEFSVElORykge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGBDaHJvbWVkcml2ZXIgZXhpdGVkIHVuZXhwZWN0ZWRseSB3aXRoIGNvZGUgJHtjb2RlfSwgc2lnbmFsICR7c2lnbmFsfWA7XG4gICAgICAgICAgdGhpcy5sb2cuZXJyb3IobXNnKTtcbiAgICAgICAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9TVE9QUEVEKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBTcGF3bmluZyBjaHJvbWVkcml2ZXIgd2l0aDogJHt0aGlzLmNocm9tZWRyaXZlcn0gJHthcmdzLmpvaW4oJyAnKX1gKTtcbiAgICAgIC8vIHN0YXJ0IHN1YnByb2MgYW5kIHdhaXQgZm9yIHN0YXJ0RGV0ZWN0b3JcbiAgICAgIGF3YWl0IHRoaXMucHJvYy5zdGFydChzdGFydERldGVjdG9yKTtcbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvck9ubGluZSgpO1xuICAgICAgYXdhaXQgdGhpcy5zdGFydFNlc3Npb24oKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhlKTtcbiAgICAgIHRoaXMuZW1pdChDaHJvbWVkcml2ZXIuRVZFTlRfRVJST1IsIGUpO1xuICAgICAgLy8ganVzdCBiZWNhdXNlIHdlIGhhZCBhbiBlcnJvciBkb2Vzbid0IG1lYW4gdGhlIGNocm9tZWRyaXZlciBwcm9jZXNzXG4gICAgICAvLyBmaW5pc2hlZDsgd2Ugc2hvdWxkIGNsZWFuIHVwIGlmIG5lY2Vzc2FyeVxuICAgICAgaWYgKHByb2Nlc3NJc0FsaXZlKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJvYy5zdG9wKCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBtZXNzYWdlID0gJyc7XG4gICAgICAvLyBvZnRlbiB0aGUgdXNlcidzIENocm9tZSB2ZXJzaW9uIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHZlcnNpb24gb2YgQ2hyb21lZHJpdmVyXG4gICAgICBpZiAoZS5tZXNzYWdlLmluY2x1ZGVzKCdDaHJvbWUgdmVyc2lvbiBtdXN0IGJlJykpIHtcbiAgICAgICAgbWVzc2FnZSArPSAnVW5hYmxlIHRvIGF1dG9tYXRlIENocm9tZSB2ZXJzaW9uIGJlY2F1c2UgaXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIHZlcnNpb24gb2YgQ2hyb21lZHJpdmVyLlxcbic7XG4gICAgICAgIGlmICh3ZWJ2aWV3VmVyc2lvbikge1xuICAgICAgICAgIG1lc3NhZ2UgKz0gYENocm9tZSB2ZXJzaW9uIG9uIHRoZSBkZXZpY2U6ICR7d2Vidmlld1ZlcnNpb259XFxuYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2ZXJzaW9uc1N1cHBvcnRlZEJ5RHJpdmVyID0gL0Nocm9tZSB2ZXJzaW9uIG11c3QgYmUgKC4rKS8uZXhlYyhlLm1lc3NhZ2UpPy5bMV0gfHwgJyc7XG4gICAgICAgIGlmICh2ZXJzaW9uc1N1cHBvcnRlZEJ5RHJpdmVyKSB7XG4gICAgICAgICAgbWVzc2FnZSArPSBgQ2hyb21lZHJpdmVyIHN1cHBvcnRzIENocm9tZSB2ZXJzaW9uKHMpOiAke3ZlcnNpb25zU3VwcG9ydGVkQnlEcml2ZXJ9XFxuYDtcbiAgICAgICAgfVxuICAgICAgICBtZXNzYWdlICs9IGBWaXNpdCAnJHtDSFJPTUVEUklWRVJfVFVUT1JJQUx9JyB0byB0cm91Ymxlc2hvb3QgdGhlIHByb2JsZW0uXFxuYDtcbiAgICAgIH1cblxuICAgICAgbWVzc2FnZSArPSBlLm1lc3NhZ2U7XG4gICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KG1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIHNlc3Npb25JZCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENocm9tZWRyaXZlci5TVEFURV9PTkxJTkUgPyB0aGlzLmp3cHJveHkuc2Vzc2lvbklkIDogbnVsbDtcbiAgfVxuXG4gIGFzeW5jIHJlc3RhcnQgKCkge1xuICAgIHRoaXMubG9nLmluZm8oJ1Jlc3RhcnRpbmcgY2hyb21lZHJpdmVyJyk7XG4gICAgaWYgKHRoaXMuc3RhdGUgIT09IENocm9tZWRyaXZlci5TVEFURV9PTkxJTkUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHJlc3RhcnQgd2hlbiB3ZSdyZSBub3Qgb25saW5lXCIpO1xuICAgIH1cbiAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9SRVNUQVJUSU5HKTtcbiAgICBhd2FpdCB0aGlzLnN0b3AoZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc3RhcnQodGhpcy5jYXBhYmlsaXRpZXMsIGZhbHNlKTtcbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JPbmxpbmUgKCkge1xuICAgIC8vIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgQ0QgaGFzbid0IGNyYXNoZWRcbiAgICBsZXQgY2hyb21lZHJpdmVyU3RvcHBlZCA9IGZhbHNlO1xuICAgIGF3YWl0IHJldHJ5SW50ZXJ2YWwoMjAsIDIwMCwgYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IENocm9tZWRyaXZlci5TVEFURV9TVE9QUEVEKSB7XG4gICAgICAgIC8vIHdlIGFyZSBlaXRoZXIgc3RvcHBlZCBvciBzdG9wcGluZywgc28gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICAgICAgY2hyb21lZHJpdmVyU3RvcHBlZCA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgfSk7XG4gICAgaWYgKGNocm9tZWRyaXZlclN0b3BwZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hyb21lRHJpdmVyIGNyYXNoZWQgZHVyaW5nIHN0YXJ0dXAuJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0U3RhdHVzICgpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKCkge1xuICAgIGNvbnN0IHNlc3Npb25DYXBzID0gdGhpcy5kZXNpcmVkUHJvdG9jb2wgPT09IFBST1RPQ09MUy5XM0NcbiAgICAgID8ge2NhcGFiaWxpdGllczoge2Fsd2F5c01hdGNoOiB0aGlzLmNhcGFiaWxpdGllc319XG4gICAgICA6IHtkZXNpcmVkQ2FwYWJpbGl0aWVzOiB0aGlzLmNhcGFiaWxpdGllc307XG4gICAgdGhpcy5sb2cuaW5mbyhgU3RhcnRpbmcgJHt0aGlzLmRlc2lyZWRQcm90b2NvbH0gQ2hyb21lZHJpdmVyIHNlc3Npb24gd2l0aCBjYXBhYmlsaXRpZXM6IGAgK1xuICAgICAgSlNPTi5zdHJpbmdpZnkoc2Vzc2lvbkNhcHMsIG51bGwsIDIpKTtcbiAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHNlc3Npb25DYXBzKTtcbiAgICB0aGlzLmxvZy5wcmVmaXggPSBnZW5lcmF0ZUxvZ1ByZWZpeCh0aGlzLCB0aGlzLmp3cHJveHkuc2Vzc2lvbklkKTtcbiAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9PTkxJTkUpO1xuICB9XG5cbiAgYXN5bmMgc3RvcCAoZW1pdFN0YXRlcyA9IHRydWUpIHtcbiAgICBpZiAoZW1pdFN0YXRlcykge1xuICAgICAgdGhpcy5jaGFuZ2VTdGF0ZShDaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBJTkcpO1xuICAgIH1cbiAgICBjb25zdCBydW5TYWZlU3RlcCA9IGFzeW5jIChmKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgZigpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZy53YXJuKGUubWVzc2FnZSk7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGUuc3RhY2spO1xuICAgICAgfVxuICAgIH07XG4gICAgYXdhaXQgcnVuU2FmZVN0ZXAoKCkgPT4gdGhpcy5qd3Byb3h5LmNvbW1hbmQoJycsICdERUxFVEUnKSk7XG4gICAgYXdhaXQgcnVuU2FmZVN0ZXAoKCkgPT4gdGhpcy5wcm9jLnN0b3AoJ1NJR1RFUk0nLCAyMDAwMCkpO1xuICAgIHRoaXMubG9nLnByZWZpeCA9IGdlbmVyYXRlTG9nUHJlZml4KHRoaXMpO1xuICAgIGlmIChlbWl0U3RhdGVzKSB7XG4gICAgICB0aGlzLmNoYW5nZVN0YXRlKENocm9tZWRyaXZlci5TVEFURV9TVE9QUEVEKTtcbiAgICB9XG4gIH1cblxuICBjaGFuZ2VTdGF0ZSAoc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgdGhpcy5sb2cuZGVidWcoYENoYW5nZWQgc3RhdGUgdG8gJyR7c3RhdGV9J2ApO1xuICAgIHRoaXMuZW1pdChDaHJvbWVkcml2ZXIuRVZFTlRfQ0hBTkdFRCwge3N0YXRlfSk7XG4gIH1cblxuICBhc3luYyBzZW5kQ29tbWFuZCAodXJsLCBtZXRob2QsIGJvZHkpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQodXJsLCBtZXRob2QsIGJvZHkpO1xuICB9XG5cbiAgYXN5bmMgcHJveHlSZXEgKHJlcSwgcmVzKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuandwcm94eS5wcm94eVJlcVJlcyhyZXEsIHJlcyk7XG4gIH1cblxuICBhc3luYyBraWxsQWxsICgpIHtcbiAgICBsZXQgY21kID0gc3lzdGVtLmlzV2luZG93cygpXG4gICAgICA/IGB3bWljIHByb2Nlc3Mgd2hlcmUgXCJjb21tYW5kbGluZSBsaWtlICclY2hyb21lZHJpdmVyLmV4ZSUtLXBvcnQ9JHt0aGlzLnByb3h5UG9ydH0lJ1wiIGRlbGV0ZWBcbiAgICAgIDogYHBraWxsIC0xNSAtZiBcIiR7dGhpcy5jaHJvbWVkcml2ZXJ9LiotLXBvcnQ9JHt0aGlzLnByb3h5UG9ydH1cImA7XG4gICAgdGhpcy5sb2cuZGVidWcoYEtpbGxpbmcgYW55IG9sZCBjaHJvbWVkcml2ZXJzLCBydW5uaW5nOiAke2NtZH1gKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgKEIucHJvbWlzaWZ5KGNwLmV4ZWMpKShjbWQpO1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ1N1Y2Nlc3NmdWxseSBjbGVhbmVkIHVwIG9sZCBjaHJvbWVkcml2ZXJzJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKCdObyBvbGQgY2hyb21lZHJpdmVycyBzZWVtIHRvIGV4aXN0Jyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWRiKSB7XG4gICAgICBjb25zdCB1ZGlkSW5kZXggPSB0aGlzLmFkYi5leGVjdXRhYmxlLmRlZmF1bHRBcmdzLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbSA9PT0gJy1zJyk7XG4gICAgICBjb25zdCB1ZGlkID0gdWRpZEluZGV4ID4gLTEgPyB0aGlzLmFkYi5leGVjdXRhYmxlLmRlZmF1bHRBcmdzW3VkaWRJbmRleCArIDFdIDogbnVsbDtcblxuICAgICAgaWYgKHVkaWQpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYENsZWFuaW5nIHRoaXMgZGV2aWNlJ3MgYWRiIGZvcndhcmRlZCBwb3J0IHNvY2tldCBjb25uZWN0aW9uczogJHt1ZGlkfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYENsZWFuaW5nIGFueSBvbGQgYWRiIGZvcndhcmRlZCBwb3J0IHNvY2tldCBjb25uZWN0aW9uc2ApO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKGxldCBjb25uIG9mIGF3YWl0IHRoaXMuYWRiLmdldEZvcndhcmRMaXN0KCkpIHtcbiAgICAgICAgICAvLyBjaHJvbWVkcml2ZXIgd2lsbCBhc2sgQURCIHRvIGZvcndhcmQgYSBwb3J0IGxpa2UgXCJkZXZpY2VJZCB0Y3A6cG9ydCBsb2NhbGFic3RyYWN0OndlYnZpZXdfZGV2dG9vbHNfcmVtb3RlX3BvcnRcIlxuICAgICAgICAgIGlmICghKGNvbm4uaW5jbHVkZXMoJ3dlYnZpZXdfZGV2dG9vbHMnKSAmJiAoIXVkaWQgfHwgY29ubi5pbmNsdWRlcyh1ZGlkKSkpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgcGFyYW1zID0gY29ubi5zcGxpdCgvXFxzKy8pO1xuICAgICAgICAgIGlmIChwYXJhbXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIucmVtb3ZlUG9ydEZvcndhcmQocGFyYW1zWzFdLnJlcGxhY2UoL1tcXERdKi8sICcnKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5sb2cud2FybihgVW5hYmxlIHRvIGNsZWFuIGZvcndhcmRlZCBwb3J0cy4gRXJyb3I6ICcke2Vyci5tZXNzYWdlfScuIENvbnRpbnVpbmcuYCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFzV29ya2luZ1dlYnZpZXcgKCkge1xuICAgIC8vIHNvbWV0aW1lcyBjaHJvbWVkcml2ZXIgc3RvcHMgYXV0b21hdGluZyB3ZWJ2aWV3cy4gdGhpcyBtZXRob2QgcnVucyBhXG4gICAgLy8gc2ltcGxlIGNvbW1hbmQgdG8gZGV0ZXJtaW5lIG91ciBzdGF0ZSwgYW5kIHJlc3BvbmRzIGFjY29yZGluZ2x5XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuandwcm94eS5jb21tYW5kKCcvdXJsJywgJ0dFVCcpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufVxuXG5DaHJvbWVkcml2ZXIuRVZFTlRfRVJST1IgPSAnY2hyb21lZHJpdmVyX2Vycm9yJztcbkNocm9tZWRyaXZlci5FVkVOVF9DSEFOR0VEID0gJ3N0YXRlQ2hhbmdlZCc7XG5DaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBFRCA9ICdzdG9wcGVkJztcbkNocm9tZWRyaXZlci5TVEFURV9TVEFSVElORyA9ICdzdGFydGluZyc7XG5DaHJvbWVkcml2ZXIuU1RBVEVfT05MSU5FID0gJ29ubGluZSc7XG5DaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBJTkcgPSAnc3RvcHBpbmcnO1xuQ2hyb21lZHJpdmVyLlNUQVRFX1JFU1RBUlRJTkcgPSAncmVzdGFydGluZyc7XG5cbmV4cG9ydCB7IENocm9tZWRyaXZlciB9O1xuZXhwb3J0IGRlZmF1bHQgQ2hyb21lZHJpdmVyO1xuIl0sImZpbGUiOiJsaWIvY2hyb21lZHJpdmVyLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uIn0=
|
package/build/lib/utils.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports.X86 = exports.X64 = exports.OS = exports.M1_ARCH_SUFFIX = exports.CHROMEDRIVER_CHROME_MAPPING = exports.CD_VER = exports.CD_CDN = exports.CD_BASE_DIR = void 0;
|
|
9
|
+
exports.generateLogPrefix = generateLogPrefix;
|
|
9
10
|
exports.getChromeVersion = getChromeVersion;
|
|
10
11
|
exports.getChromedriverBinaryPath = getChromedriverBinaryPath;
|
|
11
12
|
exports.getChromedriverDir = getChromedriverDir;
|
|
@@ -19,6 +20,8 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
19
20
|
|
|
20
21
|
var _support = require("@appium/support");
|
|
21
22
|
|
|
23
|
+
var _baseDriver = require("@appium/base-driver");
|
|
24
|
+
|
|
22
25
|
var _path = _interopRequireDefault(require("path"));
|
|
23
26
|
|
|
24
27
|
var _compareVersions = _interopRequireDefault(require("compare-versions"));
|
|
@@ -121,7 +124,13 @@ const getOsInfo = _lodash.default.memoize(async function getOsInfo() {
|
|
|
121
124
|
};
|
|
122
125
|
});
|
|
123
126
|
|
|
124
|
-
exports.getOsInfo = getOsInfo;
|
|
127
|
+
exports.getOsInfo = getOsInfo;
|
|
128
|
+
|
|
129
|
+
const getBaseDriverInstance = _lodash.default.memoize(() => new _baseDriver.BaseDriver({}, false));
|
|
130
|
+
|
|
131
|
+
function generateLogPrefix(obj, sessionId = null) {
|
|
132
|
+
return getBaseDriverInstance().helpers.generateDriverLogPrefix(obj, sessionId);
|
|
133
|
+
}require('source-map-support').install();
|
|
125
134
|
|
|
126
135
|
|
|
127
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,
|
|
136
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi91dGlscy5qcyJdLCJuYW1lcyI6WyJyb290RGlyIiwicGF0aCIsImJhc2VuYW1lIiwiX19kaXJuYW1lIiwicmVzb2x2ZSIsInByb2Nlc3MiLCJlbnYiLCJOT19QUkVDT01QSUxFIiwiQ0hST01FRFJJVkVSX0NIUk9NRV9NQVBQSU5HIiwicmVxdWlyZSIsIkNEX1ZFUiIsIm5wbV9jb25maWdfY2hyb21lZHJpdmVyX3ZlcnNpb24iLCJDSFJPTUVEUklWRVJfVkVSU0lPTiIsImdldE1vc3RSZWNlbnRDaHJvbWVkcml2ZXIiLCJDRF9CQVNFX0RJUiIsIkNEX0NETiIsIm5wbV9jb25maWdfY2hyb21lZHJpdmVyX2NkbnVybCIsIkNIUk9NRURSSVZFUl9DRE5VUkwiLCJPUyIsImxpbnV4Iiwid2luZG93cyIsIm1hYyIsIlg2NCIsIlg4NiIsIk0xX0FSQ0hfU1VGRklYIiwiQ0RfRVhFQ1VUQUJMRV9QUkVGSVgiLCJtYXBwaW5nIiwiXyIsImlzRW1wdHkiLCJFcnJvciIsImxhc3QiLCJrZXlzIiwic29ydCIsImNvbXBhcmVWZXJzaW9ucyIsImdldENocm9tZVZlcnNpb24iLCJhZGIiLCJidW5kbGVJZCIsInZlcnNpb25OYW1lIiwiZ2V0UGFja2FnZUluZm8iLCJnZXRDaHJvbWVkcml2ZXJEaXIiLCJvc05hbWUiLCJnZXRPc05hbWUiLCJnZXRDaHJvbWVkcml2ZXJCaW5hcnlQYXRoIiwicGF0aFN1ZmZpeCIsInBhdGhzIiwiZnMiLCJnbG9iIiwiY3dkIiwiYWJzb2x1dGUiLCJub2Nhc2UiLCJub2RpciIsInN0cmljdCIsImZpcnN0IiwicmV0cmlldmVEYXRhIiwidXJsIiwiaGVhZGVycyIsIm9wdHMiLCJ0aW1lb3V0IiwicmVzcG9uc2VUeXBlIiwiZGF0YSIsIm1lbW9pemUiLCJzeXN0ZW0iLCJpc1dpbmRvd3MiLCJpc01hYyIsImdldE9zSW5mbyIsIm5hbWUiLCJhcmNoIiwiaGFyZHdhcmVOYW1lIiwidHJpbSIsImdldEJhc2VEcml2ZXJJbnN0YW5jZSIsIkJhc2VEcml2ZXIiLCJnZW5lcmF0ZUxvZ1ByZWZpeCIsIm9iaiIsInNlc3Npb25JZCIsImhlbHBlcnMiLCJnZW5lcmF0ZURyaXZlckxvZ1ByZWZpeCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsTUFBTUEsT0FBTyxHQUFHQyxjQUFLQyxRQUFMLENBQWNDLFNBQWQsTUFBNkIsS0FBN0IsR0FDWkYsY0FBS0csT0FBTCxDQUFhRCxTQUFiLEVBQXdCRSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsYUFBWixHQUE0QixJQUE1QixHQUFtQyxPQUEzRCxDQURZLEdBRVpKLFNBRko7O0FBSUEsTUFBTUssMkJBQTJCLEdBQUdDLE9BQU8sQ0FBQ1IsY0FBS0csT0FBTCxDQUFhSixPQUFiLEVBQXNCLFFBQXRCLEVBQWdDLGNBQWhDLENBQUQsQ0FBM0M7OztBQUVBLE1BQU1VLE1BQU0sR0FBR0wsT0FBTyxDQUFDQyxHQUFSLENBQVlLLCtCQUFaLElBQ1ZOLE9BQU8sQ0FBQ0MsR0FBUixDQUFZTSxvQkFERixJQUVWQyx5QkFBeUIsRUFGOUI7OztBQUdBLE1BQU1DLFdBQVcsR0FBR2IsY0FBS0csT0FBTCxDQUFhRCxTQUFiLEVBQXdCLElBQXhCLEVBQThCLElBQTlCLEVBQW9DLGNBQXBDLENBQXBCOzs7QUFDQSxNQUFNWSxNQUFNLEdBQUdWLE9BQU8sQ0FBQ0MsR0FBUixDQUFZVSw4QkFBWixJQUNWWCxPQUFPLENBQUNDLEdBQVIsQ0FBWVcsbUJBREYsSUFFViw2Q0FGTDs7QUFHQSxNQUFNQyxFQUFFLEdBQUc7QUFDVEMsRUFBQUEsS0FBSyxFQUFFLE9BREU7QUFFVEMsRUFBQUEsT0FBTyxFQUFFLEtBRkE7QUFHVEMsRUFBQUEsR0FBRyxFQUFFO0FBSEksQ0FBWDs7QUFLQSxNQUFNQyxHQUFHLEdBQUcsSUFBWjs7QUFDQSxNQUFNQyxHQUFHLEdBQUcsSUFBWjs7QUFDQSxNQUFNQyxjQUFjLEdBQUcsS0FBdkI7O0FBQ0EsTUFBTUMs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QUE0Qm5DLGdCQUFFeUMsSUFBRixDQUFPLE1BQU0sd0JBQUssT0FBTCxFQUFjLENBQUMsSUFBRCxDQUFkLENBQWI7QUFIckMsR0FBUDtBQUtELENBTmlCLENBQWxCOzs7O0FBUUEsTUFBTUMscUJBQXFCLEdBQUcxQyxnQkFBRWlDLE9BQUYsQ0FBVSxNQUFNLElBQUlVLHNCQUFKLENBQWUsRUFBZixFQUFtQixLQUFuQixDQUFoQixDQUE5Qjs7QUFTQSxTQUFTQyxpQkFBVCxDQUE0QkMsR0FBNUIsRUFBaUNDLFNBQVMsR0FBRyxJQUE3QyxFQUFtRDtBQUNqRCxTQUFPSixxQkFBcUIsR0FBR0ssT0FBeEIsQ0FBZ0NDLHVCQUFoQyxDQUF3REgsR0FBeEQsRUFBNkRDLFNBQTdELENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBzeXN0ZW0sIGZzIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7IEJhc2VEcml2ZXIgfSBmcm9tICdAYXBwaXVtL2Jhc2UtZHJpdmVyJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGNvbXBhcmVWZXJzaW9ucyBmcm9tICdjb21wYXJlLXZlcnNpb25zJztcbmltcG9ydCBheGlvcyBmcm9tICdheGlvcyc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcblxuXG5jb25zdCByb290RGlyID0gcGF0aC5iYXNlbmFtZShfX2Rpcm5hbWUpID09PSAnbGliJ1xuICA/IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIHByb2Nlc3MuZW52Lk5PX1BSRUNPTVBJTEUgPyAnLi4nIDogJy4uLy4uJylcbiAgOiBfX2Rpcm5hbWU7XG4vLyBDaHJvbWVkcml2ZXIgdmVyc2lvbjogbWluaW11bSBDaHJvbWUgdmVyc2lvblxuY29uc3QgQ0hST01FRFJJVkVSX0NIUk9NRV9NQVBQSU5HID0gcmVxdWlyZShwYXRoLnJlc29sdmUocm9vdERpciwgJ2NvbmZpZycsICdtYXBwaW5nLmpzb24nKSk7XG5cbmNvbnN0IENEX1ZFUiA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfY2hyb21lZHJpdmVyX3ZlcnNpb25cbiAgfHwgcHJvY2Vzcy5lbnYuQ0hST01FRFJJVkVSX1ZFUlNJT05cbiAgfHwgZ2V0TW9zdFJlY2VudENocm9tZWRyaXZlcigpO1xuY29uc3QgQ0RfQkFTRV9ESVIgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAnY2hyb21lZHJpdmVyJyk7XG5jb25zdCBDRF9DRE4gPSBwcm9jZXNzLmVudi5ucG1fY29uZmlnX2Nocm9tZWRyaXZlcl9jZG51cmxcbiAgfHwgcHJvY2Vzcy5lbnYuQ0hST01FRFJJVkVSX0NETlVSTFxuICB8fCAnaHR0cHM6Ly9jaHJvbWVkcml2ZXIuc3RvcmFnZS5nb29nbGVhcGlzLmNvbSc7XG5jb25zdCBPUyA9IHtcbiAgbGludXg6ICdsaW51eCcsXG4gIHdpbmRvd3M6ICd3aW4nLFxuICBtYWM6ICdtYWMnXG59O1xuY29uc3QgWDY0ID0gJzY0JztcbmNvbnN0IFg4NiA9ICczMic7XG5jb25zdCBNMV9BUkNIX1NVRkZJWCA9ICdfbTEnO1xuY29uc3QgQ0RfRVhFQ1VUQUJMRV9QUkVGSVggPSAnY2hyb21lZHJpdmVyJztcblxuXG5mdW5jdGlvbiBnZXRNb3N0UmVjZW50Q2hyb21lZHJpdmVyIChtYXBwaW5nID0gQ0hST01FRFJJVkVSX0NIUk9NRV9NQVBQSU5HKSB7XG4gIGlmIChfLmlzRW1wdHkobWFwcGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBnZXQgbW9zdCByZWNlbnQgQ2hyb21lZHJpdmVyIHZlcnNpb24gZnJvbSBlbXB0eSBtYXBwaW5nJyk7XG4gIH1cbiAgcmV0dXJuIF8ubGFzdChfLmtleXMobWFwcGluZykuc29ydChjb21wYXJlVmVyc2lvbnMpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0Q2hyb21lVmVyc2lvbiAoYWRiLCBidW5kbGVJZCkge1xuICBjb25zdCB7dmVyc2lvbk5hbWV9ID0gYXdhaXQgYWRiLmdldFBhY2thZ2VJbmZvKGJ1bmRsZUlkKTtcbiAgcmV0dXJuIHZlcnNpb25OYW1lO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVkcml2ZXJEaXIgKG9zTmFtZSA9IGdldE9zTmFtZSgpKSB7XG4gIHJldHVybiBwYXRoLnJlc29sdmUoQ0RfQkFTRV9ESVIsIG9zTmFtZSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldENocm9tZWRyaXZlckJpbmFyeVBhdGggKG9zTmFtZSA9IGdldE9zTmFtZSgpKSB7XG4gIGNvbnN0IHJvb3REaXIgPSBnZXRDaHJvbWVkcml2ZXJEaXIob3NOYW1lKTtcbiAgY29uc3QgcGF0aFN1ZmZpeCA9IG9zTmFtZSA9PT0gT1Mud2luZG93cyA/ICcuZXhlJyA6ICcnO1xuICBjb25zdCBwYXRocyA9IGF3YWl0IGZzLmdsb2IoYCR7Q0RfRVhFQ1VUQUJMRV9QUkVGSVh9KiR7cGF0aFN1ZmZpeH1gLCB7XG4gICAgY3dkOiByb290RGlyLFxuICAgIGFic29sdXRlOiB0cnVlLFxuICAgIG5vY2FzZTogdHJ1ZSxcbiAgICBub2RpcjogdHJ1ZSxcbiAgICBzdHJpY3Q6IGZhbHNlLFxuICB9KTtcbiAgcmV0dXJuIF8uaXNFbXB0eShwYXRocylcbiAgICA/IHBhdGgucmVzb2x2ZShyb290RGlyLCBgJHtDRF9FWEVDVVRBQkxFX1BSRUZJWH0ke3BhdGhTdWZmaXh9YClcbiAgICA6IF8uZmlyc3QocGF0aHMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXRyaWV2ZURhdGEgKHVybCwgaGVhZGVycywgb3B0cyA9IHt9KSB7XG4gIGNvbnN0IHtcbiAgICB0aW1lb3V0ID0gNTAwMCxcbiAgICByZXNwb25zZVR5cGUgPSAndGV4dCcsXG4gIH0gPSBvcHRzO1xuICByZXR1cm4gKGF3YWl0IGF4aW9zKHtcbiAgICB1cmwsXG4gICAgaGVhZGVycyxcbiAgICB0aW1lb3V0LFxuICAgIHJlc3BvbnNlVHlwZSxcbiAgfSkpLmRhdGE7XG59XG5cbmNvbnN0IGdldE9zTmFtZSA9IF8ubWVtb2l6ZShmdW5jdGlvbiBnZXRPc05hbWUgKCkge1xuICBpZiAoc3lzdGVtLmlzV2luZG93cygpKSB7XG4gICAgcmV0dXJuIE9TLndpbmRvd3M7XG4gIH1cbiAgaWYgKHN5c3RlbS5pc01hYygpKSB7XG4gICAgcmV0dXJuIE9TLm1hYztcbiAgfVxuICByZXR1cm4gT1MubGludXg7XG59KTtcblxuY29uc3QgZ2V0T3NJbmZvID0gXy5tZW1vaXplKGFzeW5jIGZ1bmN0aW9uIGdldE9zSW5mbyAoKSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogZ2V0T3NOYW1lKCksXG4gICAgYXJjaDogYXdhaXQgc3lzdGVtLmFyY2goKSxcbiAgICBoYXJkd2FyZU5hbWU6IHN5c3RlbS5pc1dpbmRvd3MoKSA/IG51bGwgOiBfLnRyaW0oYXdhaXQgZXhlYygndW5hbWUnLCBbJy1tJ10pKSxcbiAgfTtcbn0pO1xuXG5jb25zdCBnZXRCYXNlRHJpdmVySW5zdGFuY2UgPSBfLm1lbW9pemUoKCkgPT4gbmV3IEJhc2VEcml2ZXIoe30sIGZhbHNlKSk7XG5cbi8qKlxuICogR2VuZXJhdGVzIGxvZyBwcmVmaXggc3RyaW5nXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG9iaiBsb2cgb3duZXIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7c3RyaW5nP30gc2Vzc2lvbklkIE9wdGlvbmFsIHNlc3Npb24gaWRlbnRpZmllclxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVMb2dQcmVmaXggKG9iaiwgc2Vzc2lvbklkID0gbnVsbCkge1xuICByZXR1cm4gZ2V0QmFzZURyaXZlckluc3RhbmNlKCkuaGVscGVycy5nZW5lcmF0ZURyaXZlckxvZ1ByZWZpeChvYmosIHNlc3Npb25JZCk7XG59XG5cblxuZXhwb3J0IHtcbiAgZ2V0Q2hyb21lVmVyc2lvbiwgZ2V0Q2hyb21lZHJpdmVyRGlyLCBnZXRDaHJvbWVkcml2ZXJCaW5hcnlQYXRoLCBnZXRPc05hbWUsXG4gIENEX0JBU0VfRElSLCBDRF9DRE4sIENEX1ZFUiwgQ0hST01FRFJJVkVSX0NIUk9NRV9NQVBQSU5HLCBnZXRNb3N0UmVjZW50Q2hyb21lZHJpdmVyLFxuICByZXRyaWV2ZURhdGEsIGdldE9zSW5mbywgT1MsIFg2NCwgWDg2LCBNMV9BUkNIX1NVRkZJWCwgZ2VuZXJhdGVMb2dQcmVmaXgsXG59O1xuIl0sImZpbGUiOiJsaWIvdXRpbHMuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==
|
package/config/mapping.json
CHANGED
package/lib/chromedriver.js
CHANGED
|
@@ -9,7 +9,7 @@ import { SubProcess, exec } from 'teen_process';
|
|
|
9
9
|
import B from 'bluebird';
|
|
10
10
|
import {
|
|
11
11
|
getChromeVersion, getChromedriverDir, CHROMEDRIVER_CHROME_MAPPING,
|
|
12
|
-
getChromedriverBinaryPath, CD_CDN,
|
|
12
|
+
getChromedriverBinaryPath, CD_CDN, generateLogPrefix
|
|
13
13
|
} from './utils';
|
|
14
14
|
import semver from 'semver';
|
|
15
15
|
import _ from 'lodash';
|
|
@@ -18,9 +18,6 @@ import compareVersions from 'compare-versions';
|
|
|
18
18
|
import ChromedriverStorageClient from './storage-client';
|
|
19
19
|
import { toW3cCapNames, getCapValue } from './protocol-helpers';
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
const log = logger.getLogger('Chromedriver');
|
|
23
|
-
|
|
24
21
|
const NEW_CD_VERSION_FORMAT_MAJOR_VERSION = 73;
|
|
25
22
|
const DEFAULT_HOST = '127.0.0.1';
|
|
26
23
|
const MIN_CD_VERSION_WITH_W3C_SUPPORT = 75;
|
|
@@ -56,6 +53,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
56
53
|
details,
|
|
57
54
|
isAutodownloadEnabled = false,
|
|
58
55
|
} = args;
|
|
56
|
+
this._log = logger.getLogger(generateLogPrefix(this));
|
|
59
57
|
|
|
60
58
|
this.proxyHost = host;
|
|
61
59
|
this.proxyPort = port;
|
|
@@ -71,7 +69,8 @@ class Chromedriver extends events.EventEmitter {
|
|
|
71
69
|
this.state = Chromedriver.STATE_STOPPED;
|
|
72
70
|
this.jwproxy = new JWProxy({
|
|
73
71
|
server: this.proxyHost,
|
|
74
|
-
port: this.proxyPort
|
|
72
|
+
port: this.proxyPort,
|
|
73
|
+
log: this._log,
|
|
75
74
|
});
|
|
76
75
|
this.verbose = verbose;
|
|
77
76
|
this.logPath = logPath;
|
|
@@ -84,23 +83,27 @@ class Chromedriver extends events.EventEmitter {
|
|
|
84
83
|
this.desiredProtocol = PROTOCOLS.MJSONWP;
|
|
85
84
|
}
|
|
86
85
|
|
|
86
|
+
get log () {
|
|
87
|
+
return this._log;
|
|
88
|
+
}
|
|
89
|
+
|
|
87
90
|
async getDriversMapping () {
|
|
88
91
|
let mapping = _.cloneDeep(CHROMEDRIVER_CHROME_MAPPING);
|
|
89
92
|
if (this.mappingPath) {
|
|
90
|
-
log.debug(`Attempting to use Chromedriver->Chrome mapping from '${this.mappingPath}'`);
|
|
93
|
+
this.log.debug(`Attempting to use Chromedriver->Chrome mapping from '${this.mappingPath}'`);
|
|
91
94
|
if (!await fs.exists(this.mappingPath)) {
|
|
92
|
-
log.warn(`No file found at '${this.mappingPath}'`);
|
|
93
|
-
log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
95
|
+
this.log.warn(`No file found at '${this.mappingPath}'`);
|
|
96
|
+
this.log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
94
97
|
} else {
|
|
95
98
|
try {
|
|
96
99
|
mapping = JSON.parse(await fs.readFile(this.mappingPath, 'utf8'));
|
|
97
100
|
} catch (err) {
|
|
98
|
-
log.warn(`Error parsing mapping from '${this.mappingPath}': ${err.message}`);
|
|
99
|
-
log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
101
|
+
this.log.warn(`Error parsing mapping from '${this.mappingPath}': ${err.message}`);
|
|
102
|
+
this.log.info('Defaulting to the static Chromedriver->Chrome mapping');
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
105
|
} else {
|
|
103
|
-
log.debug('Using the static Chromedriver->Chrome mapping');
|
|
106
|
+
this.log.debug('Using the static Chromedriver->Chrome mapping');
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
// make sure that the values for minimum chrome version are semver compliant
|
|
@@ -109,7 +112,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
109
112
|
if (coercedVersion) {
|
|
110
113
|
mapping[cdVersion] = coercedVersion.version;
|
|
111
114
|
} else {
|
|
112
|
-
log.info(`'${chromeVersion}' is not a valid version number. Skipping it`);
|
|
115
|
+
this.log.info(`'${chromeVersion}' is not a valid version number. Skipping it`);
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
118
|
return mapping;
|
|
@@ -117,10 +120,15 @@ class Chromedriver extends events.EventEmitter {
|
|
|
117
120
|
|
|
118
121
|
async getChromedrivers (mapping) {
|
|
119
122
|
// go through the versions available
|
|
120
|
-
const executables = await fs.glob(
|
|
121
|
-
|
|
123
|
+
const executables = await fs.glob('*', {
|
|
124
|
+
cwd: this.executableDir,
|
|
125
|
+
strict: false,
|
|
126
|
+
nodir: true,
|
|
127
|
+
absolute: true,
|
|
128
|
+
});
|
|
129
|
+
this.log.debug(`Found ${util.pluralize('executable', executables.length, true)} ` +
|
|
122
130
|
`in '${this.executableDir}'`);
|
|
123
|
-
const cds = (await asyncmap(executables, async
|
|
131
|
+
const cds = (await asyncmap(executables, async (executable) => {
|
|
124
132
|
const logError = ({message, stdout = null, stderr = null}) => {
|
|
125
133
|
let errMsg = `Cannot retrieve version number from '${path.basename(executable)}' Chromedriver binary. ` +
|
|
126
134
|
`Make sure it returns a valid version string in response to '--version' command line argument. ${message}`;
|
|
@@ -130,7 +138,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
130
138
|
if (stderr) {
|
|
131
139
|
errMsg += `\nStderr: ${stderr}`;
|
|
132
140
|
}
|
|
133
|
-
log.warn(errMsg);
|
|
141
|
+
this.log.warn(errMsg);
|
|
134
142
|
return null;
|
|
135
143
|
};
|
|
136
144
|
|
|
@@ -177,12 +185,12 @@ class Chromedriver extends events.EventEmitter {
|
|
|
177
185
|
.filter((cd) => !!cd)
|
|
178
186
|
.sort((a, b) => compareVersions(b.version, a.version));
|
|
179
187
|
if (_.isEmpty(cds)) {
|
|
180
|
-
log.info(`No Chromedrivers were found in '${this.executableDir}'`);
|
|
188
|
+
this.log.info(`No Chromedrivers were found in '${this.executableDir}'`);
|
|
181
189
|
return cds;
|
|
182
190
|
}
|
|
183
|
-
log.debug(`The following Chromedriver executables were found:`);
|
|
191
|
+
this.log.debug(`The following Chromedriver executables were found:`);
|
|
184
192
|
for (const cd of cds) {
|
|
185
|
-
log.debug(` '${cd.executable}' (version '${cd.version}', minimum Chrome version '${cd.minChromeVersion ? cd.minChromeVersion : 'Unknown'}')`);
|
|
193
|
+
this.log.debug(` '${cd.executable}' (version '${cd.version}', minimum Chrome version '${cd.minChromeVersion ? cd.minChromeVersion : 'Unknown'}')`);
|
|
186
194
|
}
|
|
187
195
|
return cds;
|
|
188
196
|
}
|
|
@@ -192,7 +200,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
192
200
|
// The `info` item must contain the output of /json/version CDP command
|
|
193
201
|
// where `Browser` field looks like `Chrome/72.0.3601.0``
|
|
194
202
|
if (this.details?.info) {
|
|
195
|
-
log.debug(`Browser version in the supplied details: ${this.details?.info?.Browser}`);
|
|
203
|
+
this.log.debug(`Browser version in the supplied details: ${this.details?.info?.Browser}`);
|
|
196
204
|
}
|
|
197
205
|
const versionMatch = VERSION_PATTERN.exec(this.details?.info?.Browser);
|
|
198
206
|
if (versionMatch) {
|
|
@@ -256,7 +264,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
256
264
|
await fs.writeFile(this.mappingPath, JSON.stringify(newMapping, null, 2), 'utf8');
|
|
257
265
|
shouldUpdateStaticMapping = false;
|
|
258
266
|
} catch (e) {
|
|
259
|
-
log.warn(`Cannot store the updated chromedrivers mapping into '${this.mappingPath}'. ` +
|
|
267
|
+
this.log.warn(`Cannot store the updated chromedrivers mapping into '${this.mappingPath}'. ` +
|
|
260
268
|
`This may reduce the performance of further executions. Original error: ${e.message}`);
|
|
261
269
|
}
|
|
262
270
|
}
|
|
@@ -272,14 +280,14 @@ class Chromedriver extends events.EventEmitter {
|
|
|
272
280
|
|
|
273
281
|
const mapping = await this.getDriversMapping();
|
|
274
282
|
if (!_.isEmpty(mapping)) {
|
|
275
|
-
log.debug(`The most recent known Chrome version: ${_.values(mapping)[0]}`);
|
|
283
|
+
this.log.debug(`The most recent known Chrome version: ${_.values(mapping)[0]}`);
|
|
276
284
|
}
|
|
277
285
|
|
|
278
286
|
let didStorageSync = false;
|
|
279
287
|
const syncChromedrivers = async (chromeVersion) => {
|
|
280
288
|
didStorageSync = true;
|
|
281
289
|
const retrievedMapping = await this.storageClient.retrieveMapping();
|
|
282
|
-
log.debug('Got chromedrivers mapping from the storage: ' +
|
|
290
|
+
this.log.debug('Got chromedrivers mapping from the storage: ' +
|
|
283
291
|
JSON.stringify(retrievedMapping, null, 2));
|
|
284
292
|
const driverKeys = await this.storageClient.syncDrivers({
|
|
285
293
|
minBrowserVersion: chromeVersion.major,
|
|
@@ -313,7 +321,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
313
321
|
missingVersions[version] = minChromeVersion;
|
|
314
322
|
}
|
|
315
323
|
if (!_.isEmpty(missingVersions)) {
|
|
316
|
-
log.info(`Found ${util.pluralize('Chromedriver', _.size(missingVersions), true)}, ` +
|
|
324
|
+
this.log.info(`Found ${util.pluralize('Chromedriver', _.size(missingVersions), true)}, ` +
|
|
317
325
|
`which ${_.size(missingVersions) === 1 ? 'is' : 'are'} missing in the list of known versions: ` +
|
|
318
326
|
JSON.stringify(missingVersions));
|
|
319
327
|
await this.updateDriversMapping(Object.assign(mapping, missingVersions));
|
|
@@ -321,12 +329,12 @@ class Chromedriver extends events.EventEmitter {
|
|
|
321
329
|
|
|
322
330
|
if (this.disableBuildCheck) {
|
|
323
331
|
if (_.isEmpty(cds)) {
|
|
324
|
-
log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` +
|
|
332
|
+
this.log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` +
|
|
325
333
|
`'chromedriverDisableBuildCheck' capability is set to 'true'`);
|
|
326
334
|
}
|
|
327
335
|
const {version, executable} = cds[0];
|
|
328
|
-
log.warn(`Chrome build check disabled. Using most recent Chromedriver version (${version}, at '${executable}')`);
|
|
329
|
-
log.warn(`If this is wrong, set 'chromedriverDisableBuildCheck' capability to 'false'`);
|
|
336
|
+
this.log.warn(`Chrome build check disabled. Using most recent Chromedriver version (${version}, at '${executable}')`);
|
|
337
|
+
this.log.warn(`If this is wrong, set 'chromedriverDisableBuildCheck' capability to 'false'`);
|
|
330
338
|
return executable;
|
|
331
339
|
}
|
|
332
340
|
|
|
@@ -334,14 +342,14 @@ class Chromedriver extends events.EventEmitter {
|
|
|
334
342
|
if (!chromeVersion) {
|
|
335
343
|
// unable to get the chrome version
|
|
336
344
|
if (_.isEmpty(cds)) {
|
|
337
|
-
log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` +
|
|
345
|
+
this.log.errorAndThrow(`There must be at least one Chromedriver executable available for use if ` +
|
|
338
346
|
`the current Chrome version cannot be determined`);
|
|
339
347
|
}
|
|
340
348
|
const {version, executable} = cds[0];
|
|
341
|
-
log.warn(`Unable to discover Chrome version. Using Chromedriver ${version} at '${executable}'`);
|
|
349
|
+
this.log.warn(`Unable to discover Chrome version. Using Chromedriver ${version} at '${executable}'`);
|
|
342
350
|
return executable;
|
|
343
351
|
}
|
|
344
|
-
log.debug(`Found Chrome bundle '${this.bundleId}' version '${chromeVersion}'`);
|
|
352
|
+
this.log.debug(`Found Chrome bundle '${this.bundleId}' version '${chromeVersion}'`);
|
|
345
353
|
|
|
346
354
|
const matchingDrivers = cds.filter(({minChromeVersion}) => {
|
|
347
355
|
const minChromeVersionS = minChromeVersion && semver.coerce(minChromeVersion);
|
|
@@ -360,9 +368,9 @@ class Chromedriver extends events.EventEmitter {
|
|
|
360
368
|
continue;
|
|
361
369
|
}
|
|
362
370
|
} catch (e) {
|
|
363
|
-
log.warn(`Cannot synchronize local chromedrivers with the remote storage at ${CD_CDN}: ` +
|
|
371
|
+
this.log.warn(`Cannot synchronize local chromedrivers with the remote storage at ${CD_CDN}: ` +
|
|
364
372
|
e.message);
|
|
365
|
-
log.debug(e.stack);
|
|
373
|
+
this.log.debug(e.stack);
|
|
366
374
|
}
|
|
367
375
|
}
|
|
368
376
|
const autodownloadSuggestion =
|
|
@@ -373,9 +381,9 @@ class Chromedriver extends events.EventEmitter {
|
|
|
373
381
|
}
|
|
374
382
|
|
|
375
383
|
const binPath = matchingDrivers[0].executable;
|
|
376
|
-
log.debug(`Found ${util.pluralize('executable', matchingDrivers.length, true)} ` +
|
|
384
|
+
this.log.debug(`Found ${util.pluralize('executable', matchingDrivers.length, true)} ` +
|
|
377
385
|
`capable of automating Chrome '${chromeVersion}'.\nChoosing the most recent, '${binPath}'.`);
|
|
378
|
-
log.debug('If a specific version is required, specify it with the `chromedriverExecutable`' +
|
|
386
|
+
this.log.debug('If a specific version is required, specify it with the `chromedriverExecutable`' +
|
|
379
387
|
'desired capability.');
|
|
380
388
|
return binPath;
|
|
381
389
|
// eslint-disable-next-line no-constant-condition
|
|
@@ -399,19 +407,19 @@ class Chromedriver extends events.EventEmitter {
|
|
|
399
407
|
`${this.chromedriver}, but it doesn't exist!`);
|
|
400
408
|
}
|
|
401
409
|
this.executableVerified = true;
|
|
402
|
-
log.info(`Set chromedriver binary as: ${this.chromedriver}`);
|
|
410
|
+
this.log.info(`Set chromedriver binary as: ${this.chromedriver}`);
|
|
403
411
|
}
|
|
404
412
|
|
|
405
413
|
syncProtocol (cdVersion = null) {
|
|
406
414
|
const coercedVersion = semver.coerce(cdVersion);
|
|
407
415
|
if (!coercedVersion || coercedVersion.major < MIN_CD_VERSION_WITH_W3C_SUPPORT) {
|
|
408
|
-
log.debug(`Chromedriver v. ${cdVersion} does not fully support ${PROTOCOLS.W3C} protocol. ` +
|
|
416
|
+
this.log.debug(`Chromedriver v. ${cdVersion} does not fully support ${PROTOCOLS.W3C} protocol. ` +
|
|
409
417
|
`Defaulting to ${PROTOCOLS.MJSONWP}`);
|
|
410
418
|
return;
|
|
411
419
|
}
|
|
412
420
|
const chromeOptions = getCapValue(this.capabilities, 'chromeOptions', {});
|
|
413
421
|
if (chromeOptions.w3c === false) {
|
|
414
|
-
log.info(`Chromedriver v. ${cdVersion} supports ${PROTOCOLS.W3C} protocol, ` +
|
|
422
|
+
this.log.info(`Chromedriver v. ${cdVersion} supports ${PROTOCOLS.W3C} protocol, ` +
|
|
415
423
|
`but ${PROTOCOLS.MJSONWP} one has been explicitly requested`);
|
|
416
424
|
return;
|
|
417
425
|
}
|
|
@@ -478,7 +486,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
478
486
|
let match = /"Browser": "(.*)"/.exec(out);
|
|
479
487
|
if (match) {
|
|
480
488
|
webviewVersion = match[1];
|
|
481
|
-
log.debug(`Webview version: '${webviewVersion}'`);
|
|
489
|
+
this.log.debug(`Webview version: '${webviewVersion}'`);
|
|
482
490
|
}
|
|
483
491
|
|
|
484
492
|
// also print chromedriver version to logs
|
|
@@ -486,7 +494,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
486
494
|
// Starting ChromeDriver 2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2) on port 9515
|
|
487
495
|
match = /Starting ChromeDriver ([.\d]+)/.exec(out);
|
|
488
496
|
if (match) {
|
|
489
|
-
log.debug(`Chromedriver version: '${match[1]}'`);
|
|
497
|
+
this.log.debug(`Chromedriver version: '${match[1]}'`);
|
|
490
498
|
this.syncProtocol(match[1]);
|
|
491
499
|
}
|
|
492
500
|
|
|
@@ -494,11 +502,11 @@ class Chromedriver extends events.EventEmitter {
|
|
|
494
502
|
if (this.verbose) {
|
|
495
503
|
for (let line of (stdout || '').trim().split('\n')) {
|
|
496
504
|
if (!line.trim().length) continue; // eslint-disable-line curly
|
|
497
|
-
log.debug(`[STDOUT] ${line}`);
|
|
505
|
+
this.log.debug(`[STDOUT] ${line}`);
|
|
498
506
|
}
|
|
499
507
|
for (let line of (stderr || '').trim().split('\n')) {
|
|
500
508
|
if (!line.trim().length) continue; // eslint-disable-line curly
|
|
501
|
-
log.error(`[STDERR] ${line}`);
|
|
509
|
+
this.log.error(`[STDERR] ${line}`);
|
|
502
510
|
}
|
|
503
511
|
}
|
|
504
512
|
});
|
|
@@ -509,20 +517,18 @@ class Chromedriver extends events.EventEmitter {
|
|
|
509
517
|
if (this.state !== Chromedriver.STATE_STOPPED &&
|
|
510
518
|
this.state !== Chromedriver.STATE_STOPPING &&
|
|
511
519
|
this.state !== Chromedriver.STATE_RESTARTING) {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
log.error(msg);
|
|
520
|
+
const msg = `Chromedriver exited unexpectedly with code ${code}, signal ${signal}`;
|
|
521
|
+
this.log.error(msg);
|
|
515
522
|
this.changeState(Chromedriver.STATE_STOPPED);
|
|
516
523
|
}
|
|
517
524
|
});
|
|
518
|
-
log.info(`Spawning chromedriver with: ${this.chromedriver} `
|
|
519
|
-
`${args.join(' ')}`);
|
|
525
|
+
this.log.info(`Spawning chromedriver with: ${this.chromedriver} ${args.join(' ')}`);
|
|
520
526
|
// start subproc and wait for startDetector
|
|
521
527
|
await this.proc.start(startDetector);
|
|
522
528
|
await this.waitForOnline();
|
|
523
529
|
await this.startSession();
|
|
524
530
|
} catch (e) {
|
|
525
|
-
log.debug(e);
|
|
531
|
+
this.log.debug(e);
|
|
526
532
|
this.emit(Chromedriver.EVENT_ERROR, e);
|
|
527
533
|
// just because we had an error doesn't mean the chromedriver process
|
|
528
534
|
// finished; we should clean up if necessary
|
|
@@ -545,20 +551,16 @@ class Chromedriver extends events.EventEmitter {
|
|
|
545
551
|
}
|
|
546
552
|
|
|
547
553
|
message += e.message;
|
|
548
|
-
log.errorAndThrow(message);
|
|
554
|
+
this.log.errorAndThrow(message);
|
|
549
555
|
}
|
|
550
556
|
}
|
|
551
557
|
|
|
552
558
|
sessionId () {
|
|
553
|
-
|
|
554
|
-
return null;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return this.jwproxy.sessionId;
|
|
559
|
+
return this.state === Chromedriver.STATE_ONLINE ? this.jwproxy.sessionId : null;
|
|
558
560
|
}
|
|
559
561
|
|
|
560
562
|
async restart () {
|
|
561
|
-
log.info('Restarting chromedriver');
|
|
563
|
+
this.log.info('Restarting chromedriver');
|
|
562
564
|
if (this.state !== Chromedriver.STATE_ONLINE) {
|
|
563
565
|
throw new Error("Can't restart when we're not online");
|
|
564
566
|
}
|
|
@@ -591,9 +593,10 @@ class Chromedriver extends events.EventEmitter {
|
|
|
591
593
|
const sessionCaps = this.desiredProtocol === PROTOCOLS.W3C
|
|
592
594
|
? {capabilities: {alwaysMatch: this.capabilities}}
|
|
593
595
|
: {desiredCapabilities: this.capabilities};
|
|
594
|
-
log.info(`Starting ${this.desiredProtocol} Chromedriver session with capabilities: ` +
|
|
596
|
+
this.log.info(`Starting ${this.desiredProtocol} Chromedriver session with capabilities: ` +
|
|
595
597
|
JSON.stringify(sessionCaps, null, 2));
|
|
596
598
|
await this.jwproxy.command('/session', 'POST', sessionCaps);
|
|
599
|
+
this.log.prefix = generateLogPrefix(this, this.jwproxy.sessionId);
|
|
597
600
|
this.changeState(Chromedriver.STATE_ONLINE);
|
|
598
601
|
}
|
|
599
602
|
|
|
@@ -601,20 +604,25 @@ class Chromedriver extends events.EventEmitter {
|
|
|
601
604
|
if (emitStates) {
|
|
602
605
|
this.changeState(Chromedriver.STATE_STOPPING);
|
|
603
606
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
this.
|
|
607
|
+
const runSafeStep = async (f) => {
|
|
608
|
+
try {
|
|
609
|
+
return await f();
|
|
610
|
+
} catch (e) {
|
|
611
|
+
this.log.warn(e.message);
|
|
612
|
+
this.log.debug(e.stack);
|
|
609
613
|
}
|
|
610
|
-
}
|
|
611
|
-
|
|
614
|
+
};
|
|
615
|
+
await runSafeStep(() => this.jwproxy.command('', 'DELETE'));
|
|
616
|
+
await runSafeStep(() => this.proc.stop('SIGTERM', 20000));
|
|
617
|
+
this.log.prefix = generateLogPrefix(this);
|
|
618
|
+
if (emitStates) {
|
|
619
|
+
this.changeState(Chromedriver.STATE_STOPPED);
|
|
612
620
|
}
|
|
613
621
|
}
|
|
614
622
|
|
|
615
623
|
changeState (state) {
|
|
616
624
|
this.state = state;
|
|
617
|
-
log.debug(`Changed state to '${state}'`);
|
|
625
|
+
this.log.debug(`Changed state to '${state}'`);
|
|
618
626
|
this.emit(Chromedriver.EVENT_CHANGED, {state});
|
|
619
627
|
}
|
|
620
628
|
|
|
@@ -630,12 +638,12 @@ class Chromedriver extends events.EventEmitter {
|
|
|
630
638
|
let cmd = system.isWindows()
|
|
631
639
|
? `wmic process where "commandline like '%chromedriver.exe%--port=${this.proxyPort}%'" delete`
|
|
632
640
|
: `pkill -15 -f "${this.chromedriver}.*--port=${this.proxyPort}"`;
|
|
633
|
-
log.debug(`Killing any old chromedrivers, running: ${cmd}`);
|
|
641
|
+
this.log.debug(`Killing any old chromedrivers, running: ${cmd}`);
|
|
634
642
|
try {
|
|
635
643
|
await (B.promisify(cp.exec))(cmd);
|
|
636
|
-
log.debug('Successfully cleaned up old chromedrivers');
|
|
644
|
+
this.log.debug('Successfully cleaned up old chromedrivers');
|
|
637
645
|
} catch (err) {
|
|
638
|
-
log.warn('No old chromedrivers seem to exist');
|
|
646
|
+
this.log.warn('No old chromedrivers seem to exist');
|
|
639
647
|
}
|
|
640
648
|
|
|
641
649
|
if (this.adb) {
|
|
@@ -643,9 +651,9 @@ class Chromedriver extends events.EventEmitter {
|
|
|
643
651
|
const udid = udidIndex > -1 ? this.adb.executable.defaultArgs[udidIndex + 1] : null;
|
|
644
652
|
|
|
645
653
|
if (udid) {
|
|
646
|
-
log.debug(`Cleaning this device's adb forwarded port socket connections: ${udid}`);
|
|
654
|
+
this.log.debug(`Cleaning this device's adb forwarded port socket connections: ${udid}`);
|
|
647
655
|
} else {
|
|
648
|
-
log.debug(`Cleaning any old adb forwarded port socket connections`);
|
|
656
|
+
this.log.debug(`Cleaning any old adb forwarded port socket connections`);
|
|
649
657
|
}
|
|
650
658
|
|
|
651
659
|
try {
|
|
@@ -661,7 +669,7 @@ class Chromedriver extends events.EventEmitter {
|
|
|
661
669
|
}
|
|
662
670
|
}
|
|
663
671
|
} catch (err) {
|
|
664
|
-
log.warn(`Unable to clean forwarded ports. Error: '${err.message}'. Continuing.`);
|
|
672
|
+
this.log.warn(`Unable to clean forwarded ports. Error: '${err.message}'. Continuing.`);
|
|
665
673
|
}
|
|
666
674
|
}
|
|
667
675
|
}
|
package/lib/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import { system, fs } from '@appium/support';
|
|
3
|
+
import { BaseDriver } from '@appium/base-driver';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import compareVersions from 'compare-versions';
|
|
5
6
|
import axios from 'axios';
|
|
@@ -92,9 +93,22 @@ const getOsInfo = _.memoize(async function getOsInfo () {
|
|
|
92
93
|
};
|
|
93
94
|
});
|
|
94
95
|
|
|
96
|
+
const getBaseDriverInstance = _.memoize(() => new BaseDriver({}, false));
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Generates log prefix string
|
|
100
|
+
*
|
|
101
|
+
* @param {object} obj log owner instance
|
|
102
|
+
* @param {string?} sessionId Optional session identifier
|
|
103
|
+
* @returns {string}
|
|
104
|
+
*/
|
|
105
|
+
function generateLogPrefix (obj, sessionId = null) {
|
|
106
|
+
return getBaseDriverInstance().helpers.generateDriverLogPrefix(obj, sessionId);
|
|
107
|
+
}
|
|
108
|
+
|
|
95
109
|
|
|
96
110
|
export {
|
|
97
111
|
getChromeVersion, getChromedriverDir, getChromedriverBinaryPath, getOsName,
|
|
98
112
|
CD_BASE_DIR, CD_CDN, CD_VER, CHROMEDRIVER_CHROME_MAPPING, getMostRecentChromedriver,
|
|
99
|
-
retrieveData, getOsInfo, OS, X64, X86, M1_ARCH_SUFFIX,
|
|
113
|
+
retrieveData, getOsInfo, OS, X64, X86, M1_ARCH_SUFFIX, generateLogPrefix,
|
|
100
114
|
};
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"chrome",
|
|
7
7
|
"android"
|
|
8
8
|
],
|
|
9
|
-
"version": "5.0.
|
|
9
|
+
"version": "5.0.4",
|
|
10
10
|
"author": "appium",
|
|
11
11
|
"license": "Apache-2.0",
|
|
12
12
|
"repository": {
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"config/mapping.json"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@appium/base-driver": "^8.
|
|
38
|
+
"@appium/base-driver": "^8.4.0",
|
|
39
39
|
"@appium/support": "^2.55.3",
|
|
40
40
|
"@babel/runtime": "^7.0.0",
|
|
41
41
|
"@xmldom/xmldom": "^0.x",
|
|
42
42
|
"asyncbox": "^2.0.2",
|
|
43
43
|
"axios": "^0.x",
|
|
44
44
|
"bluebird": "^3.5.1",
|
|
45
|
-
"compare-versions": "^
|
|
45
|
+
"compare-versions": "^4.1.3",
|
|
46
46
|
"fancy-log": "^2.0.0",
|
|
47
47
|
"lodash": "^4.17.4",
|
|
48
48
|
"semver": "^7.0.0",
|
|
@@ -76,15 +76,13 @@
|
|
|
76
76
|
"@appium/test-support": "^1.0.0",
|
|
77
77
|
"@babel/core": "^7.16.0",
|
|
78
78
|
"@babel/eslint-parser": "^7.16.3",
|
|
79
|
+
"@semantic-release/git": "^10.0.1",
|
|
79
80
|
"chai": "^4.1.2",
|
|
80
81
|
"chai-as-promised": "^7.1.1",
|
|
81
|
-
"eslint": "^7.32.0",
|
|
82
|
-
"eslint-plugin-import": "^2.25.3",
|
|
83
|
-
"eslint-plugin-mocha": "^9.0.0",
|
|
84
|
-
"eslint-plugin-promise": "^6.0.0",
|
|
85
82
|
"gulp": "^4.0.0",
|
|
86
83
|
"mocha": "^9.0.0",
|
|
87
84
|
"pre-commit": "^1.1.3",
|
|
88
|
-
"
|
|
85
|
+
"semantic-release": "^19.0.2",
|
|
86
|
+
"sinon": "^13.0.0"
|
|
89
87
|
}
|
|
90
88
|
}
|