appium-uiautomator2-driver 2.7.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +3 -3
  2. package/build/index.js +1 -4
  3. package/build/lib/commands/actions.js +3 -12
  4. package/build/lib/commands/actions.js.map +1 -1
  5. package/build/lib/commands/alert.js +3 -9
  6. package/build/lib/commands/alert.js.map +1 -1
  7. package/build/lib/commands/battery.js +3 -5
  8. package/build/lib/commands/battery.js.map +1 -1
  9. package/build/lib/commands/element.js +3 -36
  10. package/build/lib/commands/element.js.map +1 -1
  11. package/build/lib/commands/find.js +2 -9
  12. package/build/lib/commands/find.js.map +1 -1
  13. package/build/lib/commands/general.js +5 -36
  14. package/build/lib/commands/general.js.map +1 -1
  15. package/build/lib/commands/gestures.js +1 -15
  16. package/build/lib/commands/gestures.js.map +1 -1
  17. package/build/lib/commands/index.js +3 -15
  18. package/build/lib/commands/index.js.map +1 -1
  19. package/build/lib/commands/screenshot.js +1 -8
  20. package/build/lib/commands/screenshot.js.map +1 -1
  21. package/build/lib/commands/touch.js +2 -8
  22. package/build/lib/commands/touch.js.map +1 -1
  23. package/build/lib/commands/viewport.js +3 -9
  24. package/build/lib/commands/viewport.js.map +1 -1
  25. package/build/lib/css-converter.js +1 -42
  26. package/build/lib/css-converter.js.map +1 -1
  27. package/build/lib/desired-caps.js +1 -4
  28. package/build/lib/desired-caps.js.map +1 -1
  29. package/build/lib/driver.js +24 -102
  30. package/build/lib/driver.js.map +1 -1
  31. package/build/lib/extensions.js +1 -3
  32. package/build/lib/extensions.js.map +1 -1
  33. package/build/lib/helpers.js +1 -15
  34. package/build/lib/helpers.js.map +1 -1
  35. package/build/lib/logger.js +1 -5
  36. package/build/lib/logger.js.map +1 -1
  37. package/build/lib/uiautomator2.js +1 -70
  38. package/build/lib/uiautomator2.js.map +1 -1
  39. package/npm-shrinkwrap.json +195 -108
  40. package/package.json +3 -3
@@ -1,32 +1,20 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.default = exports.UiAutomator2Server = exports.SERVER_TEST_PACKAGE_ID = exports.SERVER_PACKAGE_ID = exports.INSTRUMENTATION_TARGET = void 0;
9
-
10
8
  require("source-map-support/register");
11
-
12
9
  var _lodash = _interopRequireDefault(require("lodash"));
13
-
14
10
  var _driver = require("appium/driver");
15
-
16
11
  var _asyncbox = require("asyncbox");
17
-
18
12
  var _appiumUiautomator2Server = require("appium-uiautomator2-server");
19
-
20
13
  var _support = require("appium/support");
21
-
22
14
  var _bluebird = _interopRequireDefault(require("bluebird"));
23
-
24
15
  var _helpers = _interopRequireDefault(require("./helpers"));
25
-
26
16
  var _axios = _interopRequireDefault(require("axios"));
27
-
28
17
  var _path = _interopRequireDefault(require("path"));
29
-
30
18
  const REQD_PARAMS = ['adb', 'tmpDir', 'host', 'systemPort', 'devicePort', 'disableWindowAnimation'];
31
19
  const SERVER_LAUNCH_TIMEOUT = 30000;
32
20
  const SERVER_INSTALL_RETRIES = 20;
@@ -37,30 +25,23 @@ const SERVER_TEST_PACKAGE_ID = `${SERVER_PACKAGE_ID}.test`;
37
25
  exports.SERVER_TEST_PACKAGE_ID = SERVER_TEST_PACKAGE_ID;
38
26
  const INSTRUMENTATION_TARGET = `${SERVER_TEST_PACKAGE_ID}/androidx.test.runner.AndroidJUnitRunner`;
39
27
  exports.INSTRUMENTATION_TARGET = INSTRUMENTATION_TARGET;
40
-
41
28
  const instrumentationLogger = _support.logger.getLogger('Instrumentation');
42
-
43
29
  class UIA2Proxy extends _driver.JWProxy {
44
30
  async proxyCommand(url, method, body = null) {
45
31
  if (this.didInstrumentationExit) {
46
32
  throw new _driver.errors.InvalidContextError(`'${method} ${url}' cannot be proxied to UiAutomator2 server because ` + 'the instrumentation process is not running (probably crashed). ' + 'Check the server log and/or the logcat output for more details');
47
33
  }
48
-
49
34
  return await super.proxyCommand(url, method, body);
50
35
  }
51
-
52
36
  }
53
-
54
37
  class UiAutomator2Server {
55
38
  constructor(log, opts = {}) {
56
39
  for (let req of REQD_PARAMS) {
57
40
  if (!opts || !_support.util.hasValue(opts[req])) {
58
41
  throw new Error(`Option '${req}' is required!`);
59
42
  }
60
-
61
43
  this[req] = opts[req];
62
44
  }
63
-
64
45
  this.log = log;
65
46
  this.disableSuppressAccessibilityService = opts.disableSuppressAccessibilityService;
66
47
  const proxyOpts = {
@@ -69,11 +50,9 @@ class UiAutomator2Server {
69
50
  port: this.systemPort,
70
51
  keepAlive: true
71
52
  };
72
-
73
53
  if (opts.readTimeout && opts.readTimeout > 0) {
74
54
  proxyOpts.timeout = opts.readTimeout;
75
55
  }
76
-
77
56
  this.jwproxy = new UIA2Proxy(proxyOpts);
78
57
  this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);
79
58
  this.proxyCommand = this.jwproxy.command.bind(this.jwproxy);
@@ -82,7 +61,6 @@ class UiAutomator2Server {
82
61
 
83
62
  async installServerApk(installTimeout = SERVER_INSTALL_RETRIES * 1000) {
84
63
  const tmpRoot = await _support.tempDir.openDir();
85
-
86
64
  const packageInfosMapper = async ({
87
65
  appPath,
88
66
  appId
@@ -93,18 +71,14 @@ class UiAutomator2Server {
93
71
  appId
94
72
  };
95
73
  }
96
-
97
74
  this.log.info(`Server package at '${appPath}' is not writeable. ` + `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` + `Consider making this file writeable manually in order to improve the performance of session startup.`);
98
-
99
75
  const dstPath = _path.default.resolve(tmpRoot, _path.default.basename(appPath));
100
-
101
76
  await _support.fs.copyFile(appPath, dstPath);
102
77
  return {
103
78
  appPath: dstPath,
104
79
  appId
105
80
  };
106
81
  };
107
-
108
82
  try {
109
83
  const packagesInfo = await _bluebird.default.all(_bluebird.default.map([{
110
84
  appPath: _appiumUiautomator2Server.SERVER_APK_PATH,
@@ -115,7 +89,6 @@ class UiAutomator2Server {
115
89
  }], packageInfosMapper));
116
90
  let shouldUninstallServerPackages = false;
117
91
  let shouldInstallServerPackages = false;
118
-
119
92
  for (const {
120
93
  appId,
121
94
  appPath
@@ -128,33 +101,25 @@ class UiAutomator2Server {
128
101
  shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;
129
102
  shouldInstallServerPackages = true;
130
103
  }
131
-
132
104
  if (!isAppInstalled) {
133
105
  shouldInstallServerPackages = true;
134
106
  }
135
-
136
107
  continue;
137
108
  }
138
-
139
109
  const appState = await this.adb.getApplicationInstallState(appPath, appId);
140
110
  this.log.debug(`${appId} installation state: ${appState}`);
141
-
142
111
  if (await this.adb.checkApkCert(appPath, appId)) {
143
112
  shouldUninstallServerPackages = shouldUninstallServerPackages || [this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED, this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED].includes(appState);
144
113
  } else {
145
114
  await _helpers.default.signApp(this.adb, appPath);
146
115
  shouldUninstallServerPackages = shouldUninstallServerPackages || ![this.adb.APP_INSTALL_STATE.NOT_INSTALLED].includes(appState);
147
116
  }
148
-
149
117
  shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [this.adb.APP_INSTALL_STATE.NOT_INSTALLED].includes(appState);
150
118
  }
151
-
152
119
  this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);
153
-
154
120
  if (shouldInstallServerPackages && shouldUninstallServerPackages) {
155
121
  this.log.info('Full packages reinstall is going to be performed');
156
122
  }
157
-
158
123
  for (const {
159
124
  appId,
160
125
  appPath
@@ -166,7 +131,6 @@ class UiAutomator2Server {
166
131
  this.log.warn(`Error uninstalling '${appId}': ${err.message}`);
167
132
  }
168
133
  }
169
-
170
134
  if (shouldInstallServerPackages) {
171
135
  await this.adb.install(appPath, {
172
136
  noIncremental: true,
@@ -179,28 +143,23 @@ class UiAutomator2Server {
179
143
  } finally {
180
144
  await _support.fs.rimraf(tmpRoot);
181
145
  }
182
-
183
146
  await this.verifyServicesAvailability();
184
147
  }
185
-
186
148
  async verifyServicesAvailability() {
187
149
  this.log.debug(`Waiting up to ${SERVICES_LAUNCH_TIMEOUT}ms for services to be available`);
188
150
  let isPmServiceAvailable = false;
189
151
  let pmOutput = '';
190
152
  let pmError = null;
191
-
192
153
  try {
193
154
  await (0, _asyncbox.waitForCondition)(async () => {
194
155
  if (!isPmServiceAvailable) {
195
156
  pmError = null;
196
157
  pmOutput = '';
197
-
198
158
  try {
199
159
  pmOutput = await this.adb.shell(['pm', 'list', 'instrumentation']);
200
160
  } catch (e) {
201
161
  pmError = e;
202
162
  }
203
-
204
163
  if (pmOutput.includes('Could not access the Package Manager')) {
205
164
  pmError = new Error(`Problem running Package Manager: ${pmOutput}`);
206
165
  pmOutput = '';
@@ -212,7 +171,6 @@ class UiAutomator2Server {
212
171
  pmError = new Error('The instrumentation target is not listed by Package Manager');
213
172
  }
214
173
  }
215
-
216
174
  return isPmServiceAvailable;
217
175
  }, {
218
176
  waitMs: SERVICES_LAUNCH_TIMEOUT,
@@ -220,38 +178,31 @@ class UiAutomator2Server {
220
178
  });
221
179
  } catch (err) {
222
180
  this.log.error(`Unable to find instrumentation target '${INSTRUMENTATION_TARGET}': ${(pmError || {}).message}`);
223
-
224
181
  if (pmOutput) {
225
182
  this.log.debug('Available targets:');
226
-
227
183
  for (const line of pmOutput.split('\n')) {
228
184
  this.log.debug(` ${line.replace('instrumentation:', '')}`);
229
185
  }
230
186
  }
231
187
  }
232
188
  }
233
-
234
189
  async startSession(caps) {
235
190
  await this.cleanupAutomationLeftovers();
236
-
237
191
  if (caps.skipServerInstallation) {
238
192
  this.log.info(`'skipServerInstallation' is set. Attempting to use UIAutomator2 server from the device`);
239
193
  } else {
240
194
  this.log.info(`Starting UIAutomator2 server ${_appiumUiautomator2Server.version}`);
241
195
  this.log.info(`Using UIAutomator2 server from '${_appiumUiautomator2Server.SERVER_APK_PATH}' and test from '${_appiumUiautomator2Server.TEST_APK_PATH}'`);
242
196
  }
243
-
244
197
  const timeout = caps.uiautomator2ServerLaunchTimeout || SERVER_LAUNCH_TIMEOUT;
245
198
  const timer = new _support.timing.Timer().start();
246
199
  let retries = 0;
247
200
  const maxRetries = 2;
248
201
  const delayBetweenRetries = 3000;
249
-
250
202
  while (retries < maxRetries) {
251
203
  this.log.info(`Waiting up to ${timeout}ms for UiAutomator2 to be online...`);
252
204
  this.jwproxy.didInstrumentationExit = false;
253
205
  await this.startInstrumentationProcess();
254
-
255
206
  if (!this.jwproxy.didInstrumentationExit) {
256
207
  try {
257
208
  await (0, _asyncbox.waitForCondition)(async () => {
@@ -269,22 +220,17 @@ class UiAutomator2Server {
269
220
  this.log.errorAndThrow(`The instrumentation process cannot be initialized within ${timeout}ms timeout. ` + 'Make sure the application under test does not crash and investigate the logcat output. ' + `You could also try to increase the value of 'uiautomator2ServerLaunchTimeout' capability`);
270
221
  }
271
222
  }
272
-
273
223
  if (!this.jwproxy.didInstrumentationExit) {
274
224
  break;
275
225
  }
276
-
277
226
  retries++;
278
-
279
227
  if (retries >= maxRetries) {
280
228
  this.log.errorAndThrow('The instrumentation process cannot be initialized. ' + 'Make sure the application under test does not crash and investigate the logcat output.');
281
229
  }
282
-
283
230
  this.log.warn(`The instrumentation process has been unexpectedly terminated. ` + `Retrying UiAutomator2 startup (#${retries} of ${maxRetries - 1})`);
284
231
  await this.cleanupAutomationLeftovers(true);
285
232
  await _bluebird.default.delay(delayBetweenRetries);
286
233
  }
287
-
288
234
  this.log.debug(`The initialization of the instrumentation process took ` + `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
289
235
  await this.jwproxy.command('/session', 'POST', {
290
236
  capabilities: {
@@ -293,24 +239,19 @@ class UiAutomator2Server {
293
239
  }
294
240
  });
295
241
  }
296
-
297
242
  async startInstrumentationProcess() {
298
243
  const cmd = ['am', 'instrument', '-w'];
299
-
300
244
  if (this.disableWindowAnimation) {
301
245
  cmd.push('--no-window-animation');
302
246
  }
303
-
304
247
  if (_lodash.default.isBoolean(this.disableSuppressAccessibilityService)) {
305
248
  cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);
306
249
  }
307
-
308
250
  cmd.push('-e', 'disableAnalytics', true);
309
251
  cmd.push(INSTRUMENTATION_TARGET);
310
252
  const instrumentationProcess = this.adb.createSubProcess(['shell', ...cmd]);
311
253
  instrumentationProcess.on('output', (stdout, stderr) => {
312
254
  const output = _lodash.default.trim(stdout || stderr);
313
-
314
255
  if (output) {
315
256
  instrumentationLogger.debug(output);
316
257
  }
@@ -321,20 +262,16 @@ class UiAutomator2Server {
321
262
  });
322
263
  await instrumentationProcess.start(0);
323
264
  }
324
-
325
265
  async deleteSession() {
326
266
  this.log.debug('Deleting UiAutomator2 server session');
327
-
328
267
  try {
329
268
  await this.jwproxy.command('/', 'DELETE');
330
269
  } catch (err) {
331
270
  this.log.warn(`Did not get confirmation UiAutomator2 deleteSession worked; ` + `Error was: ${err}`);
332
271
  }
333
272
  }
334
-
335
273
  async cleanupAutomationLeftovers(strictCleanup = false) {
336
274
  this.log.debug(`Performing ${strictCleanup ? 'strict' : 'shallow'} cleanup of automation leftovers`);
337
-
338
275
  try {
339
276
  const {
340
277
  value
@@ -345,7 +282,6 @@ class UiAutomator2Server {
345
282
  const activeSessionIds = value.map(({
346
283
  id
347
284
  }) => id).filter(Boolean);
348
-
349
285
  if (activeSessionIds.length) {
350
286
  this.log.debug(`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`);
351
287
  this.log.debug(`Cleaning up ${_support.util.pluralize('obsolete session', activeSessionIds.length, true)}`);
@@ -357,23 +293,18 @@ class UiAutomator2Server {
357
293
  } catch (e) {
358
294
  this.log.debug(`No obsolete sessions have been detected (${e.message})`);
359
295
  }
360
-
361
296
  try {
362
297
  await this.adb.forceStop(SERVER_TEST_PACKAGE_ID);
363
298
  } catch (ignore) {}
364
-
365
299
  if (!strictCleanup) {
366
300
  return;
367
301
  }
368
-
369
302
  try {
370
303
  await this.adb.killProcessesByName('uiautomator');
371
304
  } catch (ignore) {}
372
305
  }
373
-
374
306
  }
375
-
376
307
  exports.UiAutomator2Server = UiAutomator2Server;
377
308
  var _default = UiAutomator2Server;
378
309
  exports.default = _default;
379
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSRVFEX1BBUkFNUyIsIlNFUlZFUl9MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9JTlNUQUxMX1JFVFJJRVMiLCJTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9QQUNLQUdFX0lEIiwiU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCIsIklOU1RSVU1FTlRBVElPTl9UQVJHRVQiLCJpbnN0cnVtZW50YXRpb25Mb2dnZXIiLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJVSUEyUHJveHkiLCJKV1Byb3h5IiwicHJveHlDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImRpZEluc3RydW1lbnRhdGlvbkV4aXQiLCJlcnJvcnMiLCJJbnZhbGlkQ29udGV4dEVycm9yIiwiVWlBdXRvbWF0b3IyU2VydmVyIiwiY29uc3RydWN0b3IiLCJsb2ciLCJvcHRzIiwicmVxIiwidXRpbCIsImhhc1ZhbHVlIiwiRXJyb3IiLCJkaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSIsInByb3h5T3B0cyIsInNlcnZlciIsImhvc3QiLCJwb3J0Iiwic3lzdGVtUG9ydCIsImtlZXBBbGl2ZSIsInJlYWRUaW1lb3V0IiwidGltZW91dCIsImp3cHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJjb21tYW5kIiwiaW5zdGFsbFNlcnZlckFwayIsImluc3RhbGxUaW1lb3V0IiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwicGFja2FnZUluZm9zTWFwcGVyIiwiYXBwUGF0aCIsImFwcElkIiwiaGVscGVycyIsImlzV3JpdGVhYmxlIiwiaW5mbyIsImRzdFBhdGgiLCJwYXRoIiwicmVzb2x2ZSIsImJhc2VuYW1lIiwiZnMiLCJjb3B5RmlsZSIsInBhY2thZ2VzSW5mbyIsIkIiLCJhbGwiLCJtYXAiLCJhcGtQYXRoIiwidGVzdEFwa1BhdGgiLCJzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsInNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsImlzQXBwSW5zdGFsbGVkIiwiYWRiIiwiY2hlY2tBcGtDZXJ0Iiwic2lnbkFwcCIsImFwcFN0YXRlIiwiZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUiLCJkZWJ1ZyIsIkFQUF9JTlNUQUxMX1NUQVRFIiwiT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQiLCJORVdFUl9WRVJTSU9OX0lOU1RBTExFRCIsImluY2x1ZGVzIiwiTk9UX0lOU1RBTExFRCIsInVuaW5zdGFsbEFwayIsImVyciIsIndhcm4iLCJtZXNzYWdlIiwiaW5zdGFsbCIsIm5vSW5jcmVtZW50YWwiLCJyZXBsYWNlIiwidGltZW91dENhcE5hbWUiLCJyaW1yYWYiLCJ2ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSIsImlzUG1TZXJ2aWNlQXZhaWxhYmxlIiwicG1PdXRwdXQiLCJwbUVycm9yIiwid2FpdEZvckNvbmRpdGlvbiIsInNoZWxsIiwiZSIsIndhaXRNcyIsImludGVydmFsTXMiLCJlcnJvciIsImxpbmUiLCJzcGxpdCIsInN0YXJ0U2Vzc2lvbiIsImNhcHMiLCJjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyIsInNraXBTZXJ2ZXJJbnN0YWxsYXRpb24iLCJzZXJ2ZXJWZXJzaW9uIiwidWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJzdGFydCIsInJldHJpZXMiLCJtYXhSZXRyaWVzIiwiZGVsYXlCZXR3ZWVuUmV0cmllcyIsInN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImVycm9yQW5kVGhyb3ciLCJkZWxheSIsImdldER1cmF0aW9uIiwiYXNNaWxsaVNlY29uZHMiLCJ0b0ZpeGVkIiwiY2FwYWJpbGl0aWVzIiwiZmlyc3RNYXRjaCIsImFsd2F5c01hdGNoIiwiY21kIiwiZGlzYWJsZVdpbmRvd0FuaW1hdGlvbiIsInB1c2giLCJfIiwiaXNCb29sZWFuIiwiaW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImNyZWF0ZVN1YlByb2Nlc3MiLCJvbiIsInN0ZG91dCIsInN0ZGVyciIsIm91dHB1dCIsInRyaW0iLCJjb2RlIiwiZGVsZXRlU2Vzc2lvbiIsInN0cmljdENsZWFudXAiLCJ2YWx1ZSIsImF4aW9zIiwiZGF0YSIsImFjdGl2ZVNlc3Npb25JZHMiLCJpZCIsImZpbHRlciIsIkJvb2xlYW4iLCJsZW5ndGgiLCJKU09OIiwic3RyaW5naWZ5IiwicGx1cmFsaXplIiwiZGVsZXRlIiwiZm9yY2VTdG9wIiwiaWdub3JlIiwia2lsbFByb2Nlc3Nlc0J5TmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91aWF1dG9tYXRvcjIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEpXUHJveHksIGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7XG4gIFNFUlZFUl9BUEtfUEFUSCBhcyBhcGtQYXRoLFxuICBURVNUX0FQS19QQVRIIGFzIHRlc3RBcGtQYXRoLFxuICB2ZXJzaW9uIGFzIHNlcnZlclZlcnNpb25cbn0gZnJvbSAnYXBwaXVtLXVpYXV0b21hdG9yMi1zZXJ2ZXInO1xuaW1wb3J0IHtcbiAgdXRpbCwgbG9nZ2VyLCB0ZW1wRGlyLCBmcywgdGltaW5nXG59IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IFJFUURfUEFSQU1TID0gWydhZGInLCAndG1wRGlyJywgJ2hvc3QnLCAnc3lzdGVtUG9ydCcsICdkZXZpY2VQb3J0JywgJ2Rpc2FibGVXaW5kb3dBbmltYXRpb24nXTtcbmNvbnN0IFNFUlZFUl9MQVVOQ0hfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgU0VSVkVSX0lOU1RBTExfUkVUUklFUyA9IDIwO1xuY29uc3QgU0VSVklDRVNfTEFVTkNIX1RJTUVPVVQgPSAzMDAwMDtcbmNvbnN0IFNFUlZFUl9QQUNLQUdFX0lEID0gJ2lvLmFwcGl1bS51aWF1dG9tYXRvcjIuc2VydmVyJztcbmNvbnN0IFNFUlZFUl9URVNUX1BBQ0tBR0VfSUQgPSBgJHtTRVJWRVJfUEFDS0FHRV9JRH0udGVzdGA7XG5jb25zdCBJTlNUUlVNRU5UQVRJT05fVEFSR0VUID0gYCR7U0VSVkVSX1RFU1RfUEFDS0FHRV9JRH0vYW5kcm9pZHgudGVzdC5ydW5uZXIuQW5kcm9pZEpVbml0UnVubmVyYDtcbmNvbnN0IGluc3RydW1lbnRhdGlvbkxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIoJ0luc3RydW1lbnRhdGlvbicpO1xuXG5jbGFzcyBVSUEyUHJveHkgZXh0ZW5kcyBKV1Byb3h5IHtcbiAgYXN5bmMgcHJveHlDb21tYW5kICh1cmwsIG1ldGhvZCwgYm9keSA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRDb250ZXh0RXJyb3IoXG4gICAgICAgIGAnJHttZXRob2R9ICR7dXJsfScgY2Fubm90IGJlIHByb3hpZWQgdG8gVWlBdXRvbWF0b3IyIHNlcnZlciBiZWNhdXNlIGAgK1xuICAgICAgICAndGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGlzIG5vdCBydW5uaW5nIChwcm9iYWJseSBjcmFzaGVkKS4gJyArXG4gICAgICAgICdDaGVjayB0aGUgc2VydmVyIGxvZyBhbmQvb3IgdGhlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscycpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgc3VwZXIucHJveHlDb21tYW5kKHVybCwgbWV0aG9kLCBib2R5KTtcbiAgfVxufVxuXG5jbGFzcyBVaUF1dG9tYXRvcjJTZXJ2ZXIge1xuICBjb25zdHJ1Y3RvciAobG9nLCBvcHRzID0ge30pIHtcbiAgICBmb3IgKGxldCByZXEgb2YgUkVRRF9QQVJBTVMpIHtcbiAgICAgIGlmICghb3B0cyB8fCAhdXRpbC5oYXNWYWx1ZShvcHRzW3JlcV0pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgT3B0aW9uICcke3JlcX0nIGlzIHJlcXVpcmVkIWApO1xuICAgICAgfVxuICAgICAgdGhpc1tyZXFdID0gb3B0c1tyZXFdO1xuICAgIH1cbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlID0gb3B0cy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZTtcbiAgICBjb25zdCBwcm94eU9wdHMgPSB7XG4gICAgICBsb2csXG4gICAgICBzZXJ2ZXI6IHRoaXMuaG9zdCxcbiAgICAgIHBvcnQ6IHRoaXMuc3lzdGVtUG9ydCxcbiAgICAgIGtlZXBBbGl2ZTogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChvcHRzLnJlYWRUaW1lb3V0ICYmIG9wdHMucmVhZFRpbWVvdXQgPiAwKSB7XG4gICAgICBwcm94eU9wdHMudGltZW91dCA9IG9wdHMucmVhZFRpbWVvdXQ7XG4gICAgfVxuICAgIHRoaXMuandwcm94eSA9IG5ldyBVSUEyUHJveHkocHJveHlPcHRzKTtcbiAgICB0aGlzLnByb3h5UmVxUmVzID0gdGhpcy5qd3Byb3h5LnByb3h5UmVxUmVzLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuandwcm94eS5jb21tYW5kLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHRoZSBhcGtzIG9uIHRvIHRoZSBkZXZpY2Ugb3IgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbnN0YWxsVGltZW91dCAtIEluc3RhbGxhdGlvbiB0aW1lb3V0XG4gICAqL1xuICBhc3luYyBpbnN0YWxsU2VydmVyQXBrIChpbnN0YWxsVGltZW91dCA9IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgKiAxMDAwKSB7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIGNvbnN0IHBhY2thZ2VJbmZvc01hcHBlciA9IGFzeW5jICh7YXBwUGF0aCwgYXBwSWR9KSA9PiB7XG4gICAgICBpZiAoYXdhaXQgaGVscGVycy5pc1dyaXRlYWJsZShhcHBQYXRoKSkge1xuICAgICAgICByZXR1cm4geyBhcHBQYXRoLCBhcHBJZCB9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZy5pbmZvKGBTZXJ2ZXIgcGFja2FnZSBhdCAnJHthcHBQYXRofScgaXMgbm90IHdyaXRlYWJsZS4gYCArXG4gICAgICAgIGBXaWxsIGNvcHkgaXQgaW50byB0aGUgdGVtcG9yYXJ5IGxvY2F0aW9uIGF0ICcke3RtcFJvb3R9JyBhcyBhIHdvcmthcm91bmQuIGAgK1xuICAgICAgICBgQ29uc2lkZXIgbWFraW5nIHRoaXMgZmlsZSB3cml0ZWFibGUgbWFudWFsbHkgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygc2Vzc2lvbiBzdGFydHVwLmApO1xuICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLmJhc2VuYW1lKGFwcFBhdGgpKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGFwcFBhdGgsIGRzdFBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwUGF0aDogZHN0UGF0aCxcbiAgICAgICAgYXBwSWQsXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFja2FnZXNJbmZvID0gYXdhaXQgQi5hbGwoQi5tYXAoW1xuICAgICAgICB7XG4gICAgICAgICAgYXBwUGF0aDogYXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1BBQ0tBR0VfSUQsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBhcHBQYXRoOiB0ZXN0QXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCxcbiAgICAgICAgfSxcbiAgICAgIF0sIHBhY2thZ2VJbmZvc01hcHBlcikpO1xuXG4gICAgICBsZXQgc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGxldCBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3Qge2FwcElkLCBhcHBQYXRofSBvZiBwYWNrYWdlc0luZm8pIHtcbiAgICAgICAgaWYgKGFwcElkID09PSBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKSB7XG4gICAgICAgICAgY29uc3QgaXNBcHBJbnN0YWxsZWQgPSBhd2FpdCB0aGlzLmFkYi5pc0FwcEluc3RhbGxlZChhcHBJZCk7XG5cbiAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwb2ludCBpbiBnZXR0aW5nIHRoZSBzdGF0ZSBmb3IgdGVzdCBzZXJ2ZXIsXG4gICAgICAgICAgLy8gc2luY2UgaXQgZG9lcyBub3QgY29udGFpbiB2ZXJzaW9uIGluZm9cbiAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMuYWRiLmNoZWNrQXBrQ2VydChhcHBQYXRoLCBhcHBJZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGhlbHBlcnMuc2lnbkFwcCh0aGlzLmFkYiwgYXBwUGF0aCk7XG4gICAgICAgICAgICBzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyA9IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IGlzQXBwSW5zdGFsbGVkO1xuICAgICAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWlzQXBwSW5zdGFsbGVkKSB7XG4gICAgICAgICAgICBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcFN0YXRlID0gYXdhaXQgdGhpcy5hZGIuZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUoYXBwUGF0aCwgYXBwSWQpO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgJHthcHBJZH0gaW5zdGFsbGF0aW9uIHN0YXRlOiAke2FwcFN0YXRlfWApO1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5hZGIuY2hlY2tBcGtDZXJ0KGFwcFBhdGgsIGFwcElkKSkge1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgW1xuICAgICAgICAgICAgdGhpcy5hZGIuQVBQX0lOU1RBTExfU1RBVEUuT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQsXG4gICAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5ORVdFUl9WRVJTSU9OX0lOU1RBTExFRCxcbiAgICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCBoZWxwZXJzLnNpZ25BcHAodGhpcy5hZGIsIGFwcFBhdGgpO1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgIVtcbiAgICAgICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICAgICAgXS5pbmNsdWRlcyhhcHBTdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IFtcbiAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5OT1RfSU5TVEFMTEVELFxuICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLmluZm8oYFNlcnZlciBwYWNrYWdlcyBhcmUgJHtzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPyAnJyA6ICdub3QgJ31nb2luZyB0byBiZSAocmUpaW5zdGFsbGVkYCk7XG4gICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzICYmIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0Z1bGwgcGFja2FnZXMgcmVpbnN0YWxsIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm1lZCcpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB7YXBwSWQsIGFwcFBhdGh9IG9mIHBhY2thZ2VzSW5mbykge1xuICAgICAgICBpZiAoc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIudW5pbnN0YWxsQXBrKGFwcElkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9nLndhcm4oYEVycm9yIHVuaW5zdGFsbGluZyAnJHthcHBJZH0nOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIuaW5zdGFsbChhcHBQYXRoLCB7XG4gICAgICAgICAgICBub0luY3JlbWVudGFsOiB0cnVlLFxuICAgICAgICAgICAgcmVwbGFjZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpbWVvdXQ6IGluc3RhbGxUaW1lb3V0LFxuICAgICAgICAgICAgdGltZW91dENhcE5hbWU6ICd1aWF1dG9tYXRvcjJTZXJ2ZXJJbnN0YWxsVGltZW91dCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy52ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSgpO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5U2VydmljZXNBdmFpbGFiaWxpdHkgKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKGBXYWl0aW5nIHVwIHRvICR7U0VSVklDRVNfTEFVTkNIX1RJTUVPVVR9bXMgZm9yIHNlcnZpY2VzIHRvIGJlIGF2YWlsYWJsZWApO1xuICAgIGxldCBpc1BtU2VydmljZUF2YWlsYWJsZSA9IGZhbHNlO1xuICAgIGxldCBwbU91dHB1dCA9ICcnO1xuICAgIGxldCBwbUVycm9yID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghaXNQbVNlcnZpY2VBdmFpbGFibGUpIHtcbiAgICAgICAgICBwbUVycm9yID0gbnVsbDtcbiAgICAgICAgICBwbU91dHB1dCA9ICcnO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwbU91dHB1dCA9IGF3YWl0IHRoaXMuYWRiLnNoZWxsKFsncG0nLCAnbGlzdCcsICdpbnN0cnVtZW50YXRpb24nXSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcG1FcnJvciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwbU91dHB1dC5pbmNsdWRlcygnQ291bGQgbm90IGFjY2VzcyB0aGUgUGFja2FnZSBNYW5hZ2VyJykpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoYFByb2JsZW0gcnVubmluZyBQYWNrYWdlIE1hbmFnZXI6ICR7cG1PdXRwdXR9YCk7XG4gICAgICAgICAgICBwbU91dHB1dCA9ICcnOyAvLyByZW1vdmUgb3V0cHV0LCBzbyBpdCBpcyBub3QgcHJpbnRlZCBiZWxvd1xuICAgICAgICAgIH0gZWxzZSBpZiAocG1PdXRwdXQuaW5jbHVkZXMoSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCkpIHtcbiAgICAgICAgICAgIHBtT3V0cHV0ID0gJyc7IC8vIHJlbW92ZSBvdXRwdXQsIHNvIGl0IGlzIG5vdCBwcmludGVkIGJlbG93XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgSW5zdHJ1bWVudGF0aW9uIHRhcmdldCAnJHtJTlNUUlVNRU5UQVRJT05fVEFSR0VUfScgaXMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlc1xuICAgICAgICAgICAgaXNQbVNlcnZpY2VBdmFpbGFibGUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXBtRXJyb3IpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBpbnN0cnVtZW50YXRpb24gdGFyZ2V0IGlzIG5vdCBsaXN0ZWQgYnkgUGFja2FnZSBNYW5hZ2VyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc1BtU2VydmljZUF2YWlsYWJsZTtcbiAgICAgIH0sIHtcbiAgICAgICAgd2FpdE1zOiBTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCxcbiAgICAgICAgaW50ZXJ2YWxNczogMTAwMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYFVuYWJsZSB0byBmaW5kIGluc3RydW1lbnRhdGlvbiB0YXJnZXQgJyR7SU5TVFJVTUVOVEFUSU9OX1RBUkdFVH0nOiAkeyhwbUVycm9yIHx8IHt9KS5tZXNzYWdlfWApO1xuICAgICAgaWYgKHBtT3V0cHV0KSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdBdmFpbGFibGUgdGFyZ2V0czonKTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHBtT3V0cHV0LnNwbGl0KCdcXG4nKSkge1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGAgICAgJHtsaW5lLnJlcGxhY2UoJ2luc3RydW1lbnRhdGlvbjonLCAnJyl9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKGNhcHMpIHtcbiAgICBhd2FpdCB0aGlzLmNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzKCk7XG4gICAgaWYgKGNhcHMuc2tpcFNlcnZlckluc3RhbGxhdGlvbikge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgJ3NraXBTZXJ2ZXJJbnN0YWxsYXRpb24nIGlzIHNldC4gQXR0ZW1wdGluZyB0byB1c2UgVUlBdXRvbWF0b3IyIHNlcnZlciBmcm9tIHRoZSBkZXZpY2VgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgU3RhcnRpbmcgVUlBdXRvbWF0b3IyIHNlcnZlciAke3NlcnZlclZlcnNpb259YCk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBVc2luZyBVSUF1dG9tYXRvcjIgc2VydmVyIGZyb20gJyR7YXBrUGF0aH0nIGFuZCB0ZXN0IGZyb20gJyR7dGVzdEFwa1BhdGh9J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXQgPSBjYXBzLnVpYXV0b21hdG9yMlNlcnZlckxhdW5jaFRpbWVvdXQgfHwgU0VSVkVSX0xBVU5DSF9USU1FT1VUO1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgbGV0IHJldHJpZXMgPSAwO1xuICAgIGNvbnN0IG1heFJldHJpZXMgPSAyO1xuICAgIGNvbnN0IGRlbGF5QmV0d2VlblJldHJpZXMgPSAzMDAwO1xuICAgIHdoaWxlIChyZXRyaWVzIDwgbWF4UmV0cmllcykge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgV2FpdGluZyB1cCB0byAke3RpbWVvdXR9bXMgZm9yIFVpQXV0b21hdG9yMiB0byBiZSBvbmxpbmUuLi5gKTtcbiAgICAgIHRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcygpO1xuICAgICAgaWYgKCF0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIC8vIHNob3J0IGNpcmN1aXQgdG8gcmV0cnkgb3IgZmFpbCBmYXN0XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICB3YWl0TXM6IHRpbWVvdXQsXG4gICAgICAgICAgICBpbnRlcnZhbE1zOiAxMDAwLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBUaGUgaW5zdHJ1bWVudGF0aW9uIHByb2Nlc3MgY2Fubm90IGJlIGluaXRpYWxpemVkIHdpdGhpbiAke3RpbWVvdXR9bXMgdGltZW91dC4gYFxuICAgICAgICAgICAgKyAnTWFrZSBzdXJlIHRoZSBhcHBsaWNhdGlvbiB1bmRlciB0ZXN0IGRvZXMgbm90IGNyYXNoIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgbG9nY2F0IG91dHB1dC4gJ1xuICAgICAgICAgICAgKyBgWW91IGNvdWxkIGFsc28gdHJ5IHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiAndWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCcgY2FwYWJpbGl0eWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXRyaWVzKys7XG4gICAgICBpZiAocmV0cmllcyA+PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coJ1RoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBjYW5ub3QgYmUgaW5pdGlhbGl6ZWQuICdcbiAgICAgICAgICArICdNYWtlIHN1cmUgdGhlIGFwcGxpY2F0aW9uIHVuZGVyIHRlc3QgZG9lcyBub3QgY3Jhc2ggYW5kIGludmVzdGlnYXRlIHRoZSBsb2djYXQgb3V0cHV0LicpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihgVGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGhhcyBiZWVuIHVuZXhwZWN0ZWRseSB0ZXJtaW5hdGVkLiBgXG4gICAgICAgICsgYFJldHJ5aW5nIFVpQXV0b21hdG9yMiBzdGFydHVwICgjJHtyZXRyaWVzfSBvZiAke21heFJldHJpZXMgLSAxfSlgKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xlYW51cEF1dG9tYXRpb25MZWZ0b3ZlcnModHJ1ZSk7XG4gICAgICBhd2FpdCBCLmRlbGF5KGRlbGF5QmV0d2VlblJldHJpZXMpO1xuICAgIH1cblxuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIHRvb2sgYFxuICAgICAgKyBgJHt0aW1lci5nZXREdXJhdGlvbigpLmFzTWlsbGlTZWNvbmRzLnRvRml4ZWQoMCl9bXNgKTtcbiAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHtcbiAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICBmaXJzdE1hdGNoOiBbY2Fwc10sXG4gICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyAoKSB7XG4gICAgY29uc3QgY21kID0gWydhbScsICdpbnN0cnVtZW50JywgJy13J107XG4gICAgaWYgKHRoaXMuZGlzYWJsZVdpbmRvd0FuaW1hdGlvbikge1xuICAgICAgY21kLnB1c2goJy0tbm8td2luZG93LWFuaW1hdGlvbicpO1xuICAgIH1cbiAgICBpZiAoXy5pc0Jvb2xlYW4odGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSkpIHtcbiAgICAgIGNtZC5wdXNoKCctZScsICdESVNBQkxFX1NVUFBSRVNTX0FDQ0VTU0lCSUxJVFlfU0VSVklDRVMnLCB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlKTtcbiAgICB9XG4gICAgLy8gRGlzYWJsZSBHb29nbGUgYW5hbHl0aWNzIHRvIHByZXZlbnQgcG9zc2libGUgZmF0YWwgZXhjZXB0aW9uXG4gICAgY21kLnB1c2goJy1lJywgJ2Rpc2FibGVBbmFseXRpY3MnLCB0cnVlKTtcbiAgICBjbWQucHVzaChJTlNUUlVNRU5UQVRJT05fVEFSR0VUKTtcbiAgICBjb25zdCBpbnN0cnVtZW50YXRpb25Qcm9jZXNzID0gdGhpcy5hZGIuY3JlYXRlU3ViUHJvY2VzcyhbJ3NoZWxsJywgLi4uY21kXSk7XG4gICAgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5vbignb3V0cHV0JywgKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBfLnRyaW0oc3Rkb3V0IHx8IHN0ZGVycik7XG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGluc3RydW1lbnRhdGlvbkxvZ2dlci5kZWJ1ZyhvdXRwdXQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGluc3RydW1lbnRhdGlvblByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgICAgaW5zdHJ1bWVudGF0aW9uTG9nZ2VyLmRlYnVnKGBUaGUgcHJvY2VzcyBoYXMgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IHRydWU7XG4gICAgfSk7XG4gICAgYXdhaXQgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5zdGFydCgwKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZVNlc3Npb24gKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKCdEZWxldGluZyBVaUF1dG9tYXRvcjIgc2VydmVyIHNlc3Npb24nKTtcbiAgICAvLyByZWx5IG9uIGp3cHJveHkncyBpbnRlbGxpZ2VuY2UgdG8ga25vdyB3aGF0IHdlJ3JlIHRhbGtpbmcgYWJvdXQgYW5kXG4gICAgLy8gZGVsZXRlIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy8nLCAnREVMRVRFJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKGBEaWQgbm90IGdldCBjb25maXJtYXRpb24gVWlBdXRvbWF0b3IyIGRlbGV0ZVNlc3Npb24gd29ya2VkOyBgICtcbiAgICAgICAgICBgRXJyb3Igd2FzOiAke2Vycn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyAoc3RyaWN0Q2xlYW51cCA9IGZhbHNlKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoYFBlcmZvcm1pbmcgJHtzdHJpY3RDbGVhbnVwID8gJ3N0cmljdCcgOiAnc2hhbGxvdyd9IGNsZWFudXAgb2YgYXV0b21hdGlvbiBsZWZ0b3ZlcnNgKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7dmFsdWV9ID0gKGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbnNgLFxuICAgICAgICB0aW1lb3V0OiA1MDAsXG4gICAgICB9KSkuZGF0YTtcbiAgICAgIGNvbnN0IGFjdGl2ZVNlc3Npb25JZHMgPSB2YWx1ZS5tYXAoKHtpZH0pID0+IGlkKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgICBpZiAoYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBmb2xsb3dpbmcgb2Jzb2xldGUgc2Vzc2lvbnMgYXJlIHN0aWxsIHJ1bm5pbmc6ICR7SlNPTi5zdHJpbmdpZnkoYWN0aXZlU2Vzc2lvbklkcyl9YCk7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBDbGVhbmluZyB1cCAke3V0aWwucGx1cmFsaXplKCdvYnNvbGV0ZSBzZXNzaW9uJywgYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgsIHRydWUpfWApO1xuICAgICAgICBhd2FpdCBCLmFsbChhY3RpdmVTZXNzaW9uSWRzXG4gICAgICAgICAgLm1hcCgoaWQpID0+IGF4aW9zLmRlbGV0ZShgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbi8ke2lkfWApKVxuICAgICAgICApO1xuICAgICAgICAvLyBMZXQgYWxsIHNlc3Npb25zIHRvIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWQgYmVmb3JlIGNvbnRpbnVpbmdcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdObyBvYnNvbGV0ZSBzZXNzaW9ucyBoYXZlIGJlZW4gZGV0ZWN0ZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgTm8gb2Jzb2xldGUgc2Vzc2lvbnMgaGF2ZSBiZWVuIGRldGVjdGVkICgke2UubWVzc2FnZX0pYCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLmZvcmNlU3RvcChTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKTtcbiAgICB9IGNhdGNoIChpZ25vcmUpIHt9XG4gICAgaWYgKCFzdHJpY3RDbGVhbnVwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMDc0OVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5raWxsUHJvY2Vzc2VzQnlOYW1lKCd1aWF1dG9tYXRvcicpO1xuICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cbiAgfVxufVxuXG5leHBvcnQgeyBVaUF1dG9tYXRvcjJTZXJ2ZXIsIElOU1RSVU1FTlRBVElPTl9UQVJHRVQsIFNFUlZFUl9QQUNLQUdFX0lELCBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEIH07XG5leHBvcnQgZGVmYXVsdCBVaUF1dG9tYXRvcjJTZXJ2ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBS0E7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsTUFBTUEsV0FBVyxHQUFHLENBQUMsS0FBRCxFQUFRLFFBQVIsRUFBa0IsTUFBbEIsRUFBMEIsWUFBMUIsRUFBd0MsWUFBeEMsRUFBc0Qsd0JBQXRELENBQXBCO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsS0FBOUI7QUFDQSxNQUFNQyxzQkFBc0IsR0FBRyxFQUEvQjtBQUNBLE1BQU1DLHVCQUF1QixHQUFHLEtBQWhDO0FBQ0EsTUFBTUMsaUJBQWlCLEdBQUcsK0JBQTFCOztBQUNBLE1BQU1DLHNCQUFzQixHQUFJLEdBQUVELGlCQUFrQixPQUFwRDs7QUFDQSxNQUFNRSxzQkFBc0IsR0FBSSxHQUFFRCxzQkFBdUIsMENBQXpEOzs7QUFDQSxNQUFNRSxxQkFBcUIsR0FBR0MsZUFBQSxDQUFPQyxTQUFQLENBQWlCLGlCQUFqQixDQUE5Qjs7QUFFQSxNQUFNQyxTQUFOLFNBQXdCQyxlQUF4QixDQUFnQztFQUNaLE1BQVpDLFlBQVksQ0FBRUMsR0FBRixFQUFPQyxNQUFQLEVBQWVDLElBQUksR0FBRyxJQUF0QixFQUE0QjtJQUM1QyxJQUFJLEtBQUtDLHNCQUFULEVBQWlDO01BQy9CLE1BQU0sSUFBSUMsY0FBQSxDQUFPQyxtQkFBWCxDQUNILElBQUdKLE1BQU8sSUFBR0QsR0FBSSxxREFBbEIsR0FDQSxpRUFEQSxHQUVBLGdFQUhJLENBQU47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
310
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSRVFEX1BBUkFNUyIsIlNFUlZFUl9MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9JTlNUQUxMX1JFVFJJRVMiLCJTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9QQUNLQUdFX0lEIiwiU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCIsIklOU1RSVU1FTlRBVElPTl9UQVJHRVQiLCJpbnN0cnVtZW50YXRpb25Mb2dnZXIiLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJVSUEyUHJveHkiLCJKV1Byb3h5IiwicHJveHlDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImRpZEluc3RydW1lbnRhdGlvbkV4aXQiLCJlcnJvcnMiLCJJbnZhbGlkQ29udGV4dEVycm9yIiwiVWlBdXRvbWF0b3IyU2VydmVyIiwiY29uc3RydWN0b3IiLCJsb2ciLCJvcHRzIiwicmVxIiwidXRpbCIsImhhc1ZhbHVlIiwiRXJyb3IiLCJkaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSIsInByb3h5T3B0cyIsInNlcnZlciIsImhvc3QiLCJwb3J0Iiwic3lzdGVtUG9ydCIsImtlZXBBbGl2ZSIsInJlYWRUaW1lb3V0IiwidGltZW91dCIsImp3cHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJjb21tYW5kIiwiaW5zdGFsbFNlcnZlckFwayIsImluc3RhbGxUaW1lb3V0IiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwicGFja2FnZUluZm9zTWFwcGVyIiwiYXBwUGF0aCIsImFwcElkIiwiaGVscGVycyIsImlzV3JpdGVhYmxlIiwiaW5mbyIsImRzdFBhdGgiLCJwYXRoIiwicmVzb2x2ZSIsImJhc2VuYW1lIiwiZnMiLCJjb3B5RmlsZSIsInBhY2thZ2VzSW5mbyIsIkIiLCJhbGwiLCJtYXAiLCJhcGtQYXRoIiwidGVzdEFwa1BhdGgiLCJzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsInNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsImlzQXBwSW5zdGFsbGVkIiwiYWRiIiwiY2hlY2tBcGtDZXJ0Iiwic2lnbkFwcCIsImFwcFN0YXRlIiwiZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUiLCJkZWJ1ZyIsIkFQUF9JTlNUQUxMX1NUQVRFIiwiT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQiLCJORVdFUl9WRVJTSU9OX0lOU1RBTExFRCIsImluY2x1ZGVzIiwiTk9UX0lOU1RBTExFRCIsInVuaW5zdGFsbEFwayIsImVyciIsIndhcm4iLCJtZXNzYWdlIiwiaW5zdGFsbCIsIm5vSW5jcmVtZW50YWwiLCJyZXBsYWNlIiwidGltZW91dENhcE5hbWUiLCJyaW1yYWYiLCJ2ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSIsImlzUG1TZXJ2aWNlQXZhaWxhYmxlIiwicG1PdXRwdXQiLCJwbUVycm9yIiwid2FpdEZvckNvbmRpdGlvbiIsInNoZWxsIiwiZSIsIndhaXRNcyIsImludGVydmFsTXMiLCJlcnJvciIsImxpbmUiLCJzcGxpdCIsInN0YXJ0U2Vzc2lvbiIsImNhcHMiLCJjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyIsInNraXBTZXJ2ZXJJbnN0YWxsYXRpb24iLCJzZXJ2ZXJWZXJzaW9uIiwidWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJzdGFydCIsInJldHJpZXMiLCJtYXhSZXRyaWVzIiwiZGVsYXlCZXR3ZWVuUmV0cmllcyIsInN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImVycm9yQW5kVGhyb3ciLCJkZWxheSIsImdldER1cmF0aW9uIiwiYXNNaWxsaVNlY29uZHMiLCJ0b0ZpeGVkIiwiY2FwYWJpbGl0aWVzIiwiZmlyc3RNYXRjaCIsImFsd2F5c01hdGNoIiwiY21kIiwiZGlzYWJsZVdpbmRvd0FuaW1hdGlvbiIsInB1c2giLCJfIiwiaXNCb29sZWFuIiwiaW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImNyZWF0ZVN1YlByb2Nlc3MiLCJvbiIsInN0ZG91dCIsInN0ZGVyciIsIm91dHB1dCIsInRyaW0iLCJjb2RlIiwiZGVsZXRlU2Vzc2lvbiIsInN0cmljdENsZWFudXAiLCJ2YWx1ZSIsImF4aW9zIiwiZGF0YSIsImFjdGl2ZVNlc3Npb25JZHMiLCJpZCIsImZpbHRlciIsIkJvb2xlYW4iLCJsZW5ndGgiLCJKU09OIiwic3RyaW5naWZ5IiwicGx1cmFsaXplIiwiZGVsZXRlIiwiZm9yY2VTdG9wIiwiaWdub3JlIiwia2lsbFByb2Nlc3Nlc0J5TmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91aWF1dG9tYXRvcjIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEpXUHJveHksIGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7XG4gIFNFUlZFUl9BUEtfUEFUSCBhcyBhcGtQYXRoLFxuICBURVNUX0FQS19QQVRIIGFzIHRlc3RBcGtQYXRoLFxuICB2ZXJzaW9uIGFzIHNlcnZlclZlcnNpb25cbn0gZnJvbSAnYXBwaXVtLXVpYXV0b21hdG9yMi1zZXJ2ZXInO1xuaW1wb3J0IHtcbiAgdXRpbCwgbG9nZ2VyLCB0ZW1wRGlyLCBmcywgdGltaW5nXG59IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IFJFUURfUEFSQU1TID0gWydhZGInLCAndG1wRGlyJywgJ2hvc3QnLCAnc3lzdGVtUG9ydCcsICdkZXZpY2VQb3J0JywgJ2Rpc2FibGVXaW5kb3dBbmltYXRpb24nXTtcbmNvbnN0IFNFUlZFUl9MQVVOQ0hfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgU0VSVkVSX0lOU1RBTExfUkVUUklFUyA9IDIwO1xuY29uc3QgU0VSVklDRVNfTEFVTkNIX1RJTUVPVVQgPSAzMDAwMDtcbmNvbnN0IFNFUlZFUl9QQUNLQUdFX0lEID0gJ2lvLmFwcGl1bS51aWF1dG9tYXRvcjIuc2VydmVyJztcbmNvbnN0IFNFUlZFUl9URVNUX1BBQ0tBR0VfSUQgPSBgJHtTRVJWRVJfUEFDS0FHRV9JRH0udGVzdGA7XG5jb25zdCBJTlNUUlVNRU5UQVRJT05fVEFSR0VUID0gYCR7U0VSVkVSX1RFU1RfUEFDS0FHRV9JRH0vYW5kcm9pZHgudGVzdC5ydW5uZXIuQW5kcm9pZEpVbml0UnVubmVyYDtcbmNvbnN0IGluc3RydW1lbnRhdGlvbkxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIoJ0luc3RydW1lbnRhdGlvbicpO1xuXG5jbGFzcyBVSUEyUHJveHkgZXh0ZW5kcyBKV1Byb3h5IHtcbiAgYXN5bmMgcHJveHlDb21tYW5kICh1cmwsIG1ldGhvZCwgYm9keSA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRDb250ZXh0RXJyb3IoXG4gICAgICAgIGAnJHttZXRob2R9ICR7dXJsfScgY2Fubm90IGJlIHByb3hpZWQgdG8gVWlBdXRvbWF0b3IyIHNlcnZlciBiZWNhdXNlIGAgK1xuICAgICAgICAndGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGlzIG5vdCBydW5uaW5nIChwcm9iYWJseSBjcmFzaGVkKS4gJyArXG4gICAgICAgICdDaGVjayB0aGUgc2VydmVyIGxvZyBhbmQvb3IgdGhlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscycpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgc3VwZXIucHJveHlDb21tYW5kKHVybCwgbWV0aG9kLCBib2R5KTtcbiAgfVxufVxuXG5jbGFzcyBVaUF1dG9tYXRvcjJTZXJ2ZXIge1xuICBjb25zdHJ1Y3RvciAobG9nLCBvcHRzID0ge30pIHtcbiAgICBmb3IgKGxldCByZXEgb2YgUkVRRF9QQVJBTVMpIHtcbiAgICAgIGlmICghb3B0cyB8fCAhdXRpbC5oYXNWYWx1ZShvcHRzW3JlcV0pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgT3B0aW9uICcke3JlcX0nIGlzIHJlcXVpcmVkIWApO1xuICAgICAgfVxuICAgICAgdGhpc1tyZXFdID0gb3B0c1tyZXFdO1xuICAgIH1cbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlID0gb3B0cy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZTtcbiAgICBjb25zdCBwcm94eU9wdHMgPSB7XG4gICAgICBsb2csXG4gICAgICBzZXJ2ZXI6IHRoaXMuaG9zdCxcbiAgICAgIHBvcnQ6IHRoaXMuc3lzdGVtUG9ydCxcbiAgICAgIGtlZXBBbGl2ZTogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChvcHRzLnJlYWRUaW1lb3V0ICYmIG9wdHMucmVhZFRpbWVvdXQgPiAwKSB7XG4gICAgICBwcm94eU9wdHMudGltZW91dCA9IG9wdHMucmVhZFRpbWVvdXQ7XG4gICAgfVxuICAgIHRoaXMuandwcm94eSA9IG5ldyBVSUEyUHJveHkocHJveHlPcHRzKTtcbiAgICB0aGlzLnByb3h5UmVxUmVzID0gdGhpcy5qd3Byb3h5LnByb3h5UmVxUmVzLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuandwcm94eS5jb21tYW5kLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHRoZSBhcGtzIG9uIHRvIHRoZSBkZXZpY2Ugb3IgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbnN0YWxsVGltZW91dCAtIEluc3RhbGxhdGlvbiB0aW1lb3V0XG4gICAqL1xuICBhc3luYyBpbnN0YWxsU2VydmVyQXBrIChpbnN0YWxsVGltZW91dCA9IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgKiAxMDAwKSB7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIGNvbnN0IHBhY2thZ2VJbmZvc01hcHBlciA9IGFzeW5jICh7YXBwUGF0aCwgYXBwSWR9KSA9PiB7XG4gICAgICBpZiAoYXdhaXQgaGVscGVycy5pc1dyaXRlYWJsZShhcHBQYXRoKSkge1xuICAgICAgICByZXR1cm4geyBhcHBQYXRoLCBhcHBJZCB9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZy5pbmZvKGBTZXJ2ZXIgcGFja2FnZSBhdCAnJHthcHBQYXRofScgaXMgbm90IHdyaXRlYWJsZS4gYCArXG4gICAgICAgIGBXaWxsIGNvcHkgaXQgaW50byB0aGUgdGVtcG9yYXJ5IGxvY2F0aW9uIGF0ICcke3RtcFJvb3R9JyBhcyBhIHdvcmthcm91bmQuIGAgK1xuICAgICAgICBgQ29uc2lkZXIgbWFraW5nIHRoaXMgZmlsZSB3cml0ZWFibGUgbWFudWFsbHkgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygc2Vzc2lvbiBzdGFydHVwLmApO1xuICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLmJhc2VuYW1lKGFwcFBhdGgpKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGFwcFBhdGgsIGRzdFBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwUGF0aDogZHN0UGF0aCxcbiAgICAgICAgYXBwSWQsXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFja2FnZXNJbmZvID0gYXdhaXQgQi5hbGwoQi5tYXAoW1xuICAgICAgICB7XG4gICAgICAgICAgYXBwUGF0aDogYXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1BBQ0tBR0VfSUQsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBhcHBQYXRoOiB0ZXN0QXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCxcbiAgICAgICAgfSxcbiAgICAgIF0sIHBhY2thZ2VJbmZvc01hcHBlcikpO1xuXG4gICAgICBsZXQgc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGxldCBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3Qge2FwcElkLCBhcHBQYXRofSBvZiBwYWNrYWdlc0luZm8pIHtcbiAgICAgICAgaWYgKGFwcElkID09PSBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKSB7XG4gICAgICAgICAgY29uc3QgaXNBcHBJbnN0YWxsZWQgPSBhd2FpdCB0aGlzLmFkYi5pc0FwcEluc3RhbGxlZChhcHBJZCk7XG5cbiAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwb2ludCBpbiBnZXR0aW5nIHRoZSBzdGF0ZSBmb3IgdGVzdCBzZXJ2ZXIsXG4gICAgICAgICAgLy8gc2luY2UgaXQgZG9lcyBub3QgY29udGFpbiB2ZXJzaW9uIGluZm9cbiAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMuYWRiLmNoZWNrQXBrQ2VydChhcHBQYXRoLCBhcHBJZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGhlbHBlcnMuc2lnbkFwcCh0aGlzLmFkYiwgYXBwUGF0aCk7XG4gICAgICAgICAgICBzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyA9IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IGlzQXBwSW5zdGFsbGVkO1xuICAgICAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWlzQXBwSW5zdGFsbGVkKSB7XG4gICAgICAgICAgICBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcFN0YXRlID0gYXdhaXQgdGhpcy5hZGIuZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUoYXBwUGF0aCwgYXBwSWQpO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgJHthcHBJZH0gaW5zdGFsbGF0aW9uIHN0YXRlOiAke2FwcFN0YXRlfWApO1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5hZGIuY2hlY2tBcGtDZXJ0KGFwcFBhdGgsIGFwcElkKSkge1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgW1xuICAgICAgICAgICAgdGhpcy5hZGIuQVBQX0lOU1RBTExfU1RBVEUuT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQsXG4gICAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5ORVdFUl9WRVJTSU9OX0lOU1RBTExFRCxcbiAgICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCBoZWxwZXJzLnNpZ25BcHAodGhpcy5hZGIsIGFwcFBhdGgpO1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgIVtcbiAgICAgICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICAgICAgXS5pbmNsdWRlcyhhcHBTdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IFtcbiAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5OT1RfSU5TVEFMTEVELFxuICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLmluZm8oYFNlcnZlciBwYWNrYWdlcyBhcmUgJHtzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPyAnJyA6ICdub3QgJ31nb2luZyB0byBiZSAocmUpaW5zdGFsbGVkYCk7XG4gICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzICYmIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0Z1bGwgcGFja2FnZXMgcmVpbnN0YWxsIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm1lZCcpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB7YXBwSWQsIGFwcFBhdGh9IG9mIHBhY2thZ2VzSW5mbykge1xuICAgICAgICBpZiAoc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIudW5pbnN0YWxsQXBrKGFwcElkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9nLndhcm4oYEVycm9yIHVuaW5zdGFsbGluZyAnJHthcHBJZH0nOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIuaW5zdGFsbChhcHBQYXRoLCB7XG4gICAgICAgICAgICBub0luY3JlbWVudGFsOiB0cnVlLFxuICAgICAgICAgICAgcmVwbGFjZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpbWVvdXQ6IGluc3RhbGxUaW1lb3V0LFxuICAgICAgICAgICAgdGltZW91dENhcE5hbWU6ICd1aWF1dG9tYXRvcjJTZXJ2ZXJJbnN0YWxsVGltZW91dCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy52ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSgpO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5U2VydmljZXNBdmFpbGFiaWxpdHkgKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKGBXYWl0aW5nIHVwIHRvICR7U0VSVklDRVNfTEFVTkNIX1RJTUVPVVR9bXMgZm9yIHNlcnZpY2VzIHRvIGJlIGF2YWlsYWJsZWApO1xuICAgIGxldCBpc1BtU2VydmljZUF2YWlsYWJsZSA9IGZhbHNlO1xuICAgIGxldCBwbU91dHB1dCA9ICcnO1xuICAgIGxldCBwbUVycm9yID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghaXNQbVNlcnZpY2VBdmFpbGFibGUpIHtcbiAgICAgICAgICBwbUVycm9yID0gbnVsbDtcbiAgICAgICAgICBwbU91dHB1dCA9ICcnO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwbU91dHB1dCA9IGF3YWl0IHRoaXMuYWRiLnNoZWxsKFsncG0nLCAnbGlzdCcsICdpbnN0cnVtZW50YXRpb24nXSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcG1FcnJvciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwbU91dHB1dC5pbmNsdWRlcygnQ291bGQgbm90IGFjY2VzcyB0aGUgUGFja2FnZSBNYW5hZ2VyJykpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoYFByb2JsZW0gcnVubmluZyBQYWNrYWdlIE1hbmFnZXI6ICR7cG1PdXRwdXR9YCk7XG4gICAgICAgICAgICBwbU91dHB1dCA9ICcnOyAvLyByZW1vdmUgb3V0cHV0LCBzbyBpdCBpcyBub3QgcHJpbnRlZCBiZWxvd1xuICAgICAgICAgIH0gZWxzZSBpZiAocG1PdXRwdXQuaW5jbHVkZXMoSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCkpIHtcbiAgICAgICAgICAgIHBtT3V0cHV0ID0gJyc7IC8vIHJlbW92ZSBvdXRwdXQsIHNvIGl0IGlzIG5vdCBwcmludGVkIGJlbG93XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgSW5zdHJ1bWVudGF0aW9uIHRhcmdldCAnJHtJTlNUUlVNRU5UQVRJT05fVEFSR0VUfScgaXMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlc1xuICAgICAgICAgICAgaXNQbVNlcnZpY2VBdmFpbGFibGUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXBtRXJyb3IpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBpbnN0cnVtZW50YXRpb24gdGFyZ2V0IGlzIG5vdCBsaXN0ZWQgYnkgUGFja2FnZSBNYW5hZ2VyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc1BtU2VydmljZUF2YWlsYWJsZTtcbiAgICAgIH0sIHtcbiAgICAgICAgd2FpdE1zOiBTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCxcbiAgICAgICAgaW50ZXJ2YWxNczogMTAwMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYFVuYWJsZSB0byBmaW5kIGluc3RydW1lbnRhdGlvbiB0YXJnZXQgJyR7SU5TVFJVTUVOVEFUSU9OX1RBUkdFVH0nOiAkeyhwbUVycm9yIHx8IHt9KS5tZXNzYWdlfWApO1xuICAgICAgaWYgKHBtT3V0cHV0KSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdBdmFpbGFibGUgdGFyZ2V0czonKTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHBtT3V0cHV0LnNwbGl0KCdcXG4nKSkge1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGAgICAgJHtsaW5lLnJlcGxhY2UoJ2luc3RydW1lbnRhdGlvbjonLCAnJyl9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKGNhcHMpIHtcbiAgICBhd2FpdCB0aGlzLmNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzKCk7XG4gICAgaWYgKGNhcHMuc2tpcFNlcnZlckluc3RhbGxhdGlvbikge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgJ3NraXBTZXJ2ZXJJbnN0YWxsYXRpb24nIGlzIHNldC4gQXR0ZW1wdGluZyB0byB1c2UgVUlBdXRvbWF0b3IyIHNlcnZlciBmcm9tIHRoZSBkZXZpY2VgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgU3RhcnRpbmcgVUlBdXRvbWF0b3IyIHNlcnZlciAke3NlcnZlclZlcnNpb259YCk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBVc2luZyBVSUF1dG9tYXRvcjIgc2VydmVyIGZyb20gJyR7YXBrUGF0aH0nIGFuZCB0ZXN0IGZyb20gJyR7dGVzdEFwa1BhdGh9J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXQgPSBjYXBzLnVpYXV0b21hdG9yMlNlcnZlckxhdW5jaFRpbWVvdXQgfHwgU0VSVkVSX0xBVU5DSF9USU1FT1VUO1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgbGV0IHJldHJpZXMgPSAwO1xuICAgIGNvbnN0IG1heFJldHJpZXMgPSAyO1xuICAgIGNvbnN0IGRlbGF5QmV0d2VlblJldHJpZXMgPSAzMDAwO1xuICAgIHdoaWxlIChyZXRyaWVzIDwgbWF4UmV0cmllcykge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgV2FpdGluZyB1cCB0byAke3RpbWVvdXR9bXMgZm9yIFVpQXV0b21hdG9yMiB0byBiZSBvbmxpbmUuLi5gKTtcbiAgICAgIHRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcygpO1xuICAgICAgaWYgKCF0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIC8vIHNob3J0IGNpcmN1aXQgdG8gcmV0cnkgb3IgZmFpbCBmYXN0XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICB3YWl0TXM6IHRpbWVvdXQsXG4gICAgICAgICAgICBpbnRlcnZhbE1zOiAxMDAwLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBUaGUgaW5zdHJ1bWVudGF0aW9uIHByb2Nlc3MgY2Fubm90IGJlIGluaXRpYWxpemVkIHdpdGhpbiAke3RpbWVvdXR9bXMgdGltZW91dC4gYFxuICAgICAgICAgICAgKyAnTWFrZSBzdXJlIHRoZSBhcHBsaWNhdGlvbiB1bmRlciB0ZXN0IGRvZXMgbm90IGNyYXNoIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgbG9nY2F0IG91dHB1dC4gJ1xuICAgICAgICAgICAgKyBgWW91IGNvdWxkIGFsc28gdHJ5IHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiAndWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCcgY2FwYWJpbGl0eWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXRyaWVzKys7XG4gICAgICBpZiAocmV0cmllcyA+PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coJ1RoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBjYW5ub3QgYmUgaW5pdGlhbGl6ZWQuICdcbiAgICAgICAgICArICdNYWtlIHN1cmUgdGhlIGFwcGxpY2F0aW9uIHVuZGVyIHRlc3QgZG9lcyBub3QgY3Jhc2ggYW5kIGludmVzdGlnYXRlIHRoZSBsb2djYXQgb3V0cHV0LicpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihgVGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGhhcyBiZWVuIHVuZXhwZWN0ZWRseSB0ZXJtaW5hdGVkLiBgXG4gICAgICAgICsgYFJldHJ5aW5nIFVpQXV0b21hdG9yMiBzdGFydHVwICgjJHtyZXRyaWVzfSBvZiAke21heFJldHJpZXMgLSAxfSlgKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xlYW51cEF1dG9tYXRpb25MZWZ0b3ZlcnModHJ1ZSk7XG4gICAgICBhd2FpdCBCLmRlbGF5KGRlbGF5QmV0d2VlblJldHJpZXMpO1xuICAgIH1cblxuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIHRvb2sgYFxuICAgICAgKyBgJHt0aW1lci5nZXREdXJhdGlvbigpLmFzTWlsbGlTZWNvbmRzLnRvRml4ZWQoMCl9bXNgKTtcbiAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHtcbiAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICBmaXJzdE1hdGNoOiBbY2Fwc10sXG4gICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyAoKSB7XG4gICAgY29uc3QgY21kID0gWydhbScsICdpbnN0cnVtZW50JywgJy13J107XG4gICAgaWYgKHRoaXMuZGlzYWJsZVdpbmRvd0FuaW1hdGlvbikge1xuICAgICAgY21kLnB1c2goJy0tbm8td2luZG93LWFuaW1hdGlvbicpO1xuICAgIH1cbiAgICBpZiAoXy5pc0Jvb2xlYW4odGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSkpIHtcbiAgICAgIGNtZC5wdXNoKCctZScsICdESVNBQkxFX1NVUFBSRVNTX0FDQ0VTU0lCSUxJVFlfU0VSVklDRVMnLCB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlKTtcbiAgICB9XG4gICAgLy8gRGlzYWJsZSBHb29nbGUgYW5hbHl0aWNzIHRvIHByZXZlbnQgcG9zc2libGUgZmF0YWwgZXhjZXB0aW9uXG4gICAgY21kLnB1c2goJy1lJywgJ2Rpc2FibGVBbmFseXRpY3MnLCB0cnVlKTtcbiAgICBjbWQucHVzaChJTlNUUlVNRU5UQVRJT05fVEFSR0VUKTtcbiAgICBjb25zdCBpbnN0cnVtZW50YXRpb25Qcm9jZXNzID0gdGhpcy5hZGIuY3JlYXRlU3ViUHJvY2VzcyhbJ3NoZWxsJywgLi4uY21kXSk7XG4gICAgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5vbignb3V0cHV0JywgKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBfLnRyaW0oc3Rkb3V0IHx8IHN0ZGVycik7XG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGluc3RydW1lbnRhdGlvbkxvZ2dlci5kZWJ1ZyhvdXRwdXQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGluc3RydW1lbnRhdGlvblByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgICAgaW5zdHJ1bWVudGF0aW9uTG9nZ2VyLmRlYnVnKGBUaGUgcHJvY2VzcyBoYXMgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IHRydWU7XG4gICAgfSk7XG4gICAgYXdhaXQgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5zdGFydCgwKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZVNlc3Npb24gKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKCdEZWxldGluZyBVaUF1dG9tYXRvcjIgc2VydmVyIHNlc3Npb24nKTtcbiAgICAvLyByZWx5IG9uIGp3cHJveHkncyBpbnRlbGxpZ2VuY2UgdG8ga25vdyB3aGF0IHdlJ3JlIHRhbGtpbmcgYWJvdXQgYW5kXG4gICAgLy8gZGVsZXRlIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy8nLCAnREVMRVRFJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKGBEaWQgbm90IGdldCBjb25maXJtYXRpb24gVWlBdXRvbWF0b3IyIGRlbGV0ZVNlc3Npb24gd29ya2VkOyBgICtcbiAgICAgICAgICBgRXJyb3Igd2FzOiAke2Vycn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyAoc3RyaWN0Q2xlYW51cCA9IGZhbHNlKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoYFBlcmZvcm1pbmcgJHtzdHJpY3RDbGVhbnVwID8gJ3N0cmljdCcgOiAnc2hhbGxvdyd9IGNsZWFudXAgb2YgYXV0b21hdGlvbiBsZWZ0b3ZlcnNgKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7dmFsdWV9ID0gKGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbnNgLFxuICAgICAgICB0aW1lb3V0OiA1MDAsXG4gICAgICB9KSkuZGF0YTtcbiAgICAgIGNvbnN0IGFjdGl2ZVNlc3Npb25JZHMgPSB2YWx1ZS5tYXAoKHtpZH0pID0+IGlkKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgICBpZiAoYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBmb2xsb3dpbmcgb2Jzb2xldGUgc2Vzc2lvbnMgYXJlIHN0aWxsIHJ1bm5pbmc6ICR7SlNPTi5zdHJpbmdpZnkoYWN0aXZlU2Vzc2lvbklkcyl9YCk7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBDbGVhbmluZyB1cCAke3V0aWwucGx1cmFsaXplKCdvYnNvbGV0ZSBzZXNzaW9uJywgYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgsIHRydWUpfWApO1xuICAgICAgICBhd2FpdCBCLmFsbChhY3RpdmVTZXNzaW9uSWRzXG4gICAgICAgICAgLm1hcCgoaWQpID0+IGF4aW9zLmRlbGV0ZShgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbi8ke2lkfWApKVxuICAgICAgICApO1xuICAgICAgICAvLyBMZXQgYWxsIHNlc3Npb25zIHRvIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWQgYmVmb3JlIGNvbnRpbnVpbmdcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdObyBvYnNvbGV0ZSBzZXNzaW9ucyBoYXZlIGJlZW4gZGV0ZWN0ZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgTm8gb2Jzb2xldGUgc2Vzc2lvbnMgaGF2ZSBiZWVuIGRldGVjdGVkICgke2UubWVzc2FnZX0pYCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLmZvcmNlU3RvcChTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKTtcbiAgICB9IGNhdGNoIChpZ25vcmUpIHt9XG4gICAgaWYgKCFzdHJpY3RDbGVhbnVwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMDc0OVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5raWxsUHJvY2Vzc2VzQnlOYW1lKCd1aWF1dG9tYXRvcicpO1xuICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cbiAgfVxufVxuXG5leHBvcnQgeyBVaUF1dG9tYXRvcjJTZXJ2ZXIsIElOU1RSVU1FTlRBVElPTl9UQVJHRVQsIFNFUlZFUl9QQUNLQUdFX0lELCBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEIH07XG5leHBvcnQgZGVmYXVsdCBVaUF1dG9tYXRvcjJTZXJ2ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTUEsV0FBVyxHQUFHLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSx3QkFBd0IsQ0FBQztBQUNuRyxNQUFNQyxxQkFBcUIsR0FBRyxLQUFLO0FBQ25DLE1BQU1DLHNCQUFzQixHQUFHLEVBQUU7QUFDakMsTUFBTUMsdUJBQXVCLEdBQUcsS0FBSztBQUNyQyxNQUFNQyxpQkFBaUIsR0FBRywrQkFBK0I7QUFBQztBQUMxRCxNQUFNQyxzQkFBc0IsR0FBSSxHQUFFRCxpQkFBa0IsT0FBTTtBQUFDO0FBQzNELE1BQU1FLHNCQUFzQixHQUFJLEdBQUVELHNCQUF1QiwwQ0FBeUM7QUFBQztBQUNuRyxNQUFNRSxxQkFBcUIsR0FBR0MsZUFBTSxDQUFDQyxTQUFTLENBQUMsaUJBQWlCLENBQUM7QUFFakUsTUFBTUMsU0FBUyxTQUFTQyxlQUFPLENBQUM7RUFDOUIsTUFBTUMsWUFBWSxDQUFFQyxHQUFHLEVBQUVDLE1BQU0sRUFBRUMsSUFBSSxHQUFHLElBQUksRUFBRTtJQUM1QyxJQUFJLElBQUksQ0FBQ0Msc0JBQXNCLEVBQUU7TUFDL0IsTUFBTSxJQUFJQyxjQUFNLENBQUNDLG1CQUFtQixDQUNqQyxJQUFHSixNQUFPLElBQUdELEdBQUkscURBQW9ELEdBQ3RFLGlFQUFpRSxHQUNqRSxnRUFBZ0UsQ0FBQztJQUNyRTtJQUNBLE9BQU8sTUFBTSxLQUFLLENBQUNELFlBQVksQ0FBQ0MsR0FBRyxFQUFFQyxNQUFNLEVBQUVDLElBQUksQ0FBQztFQUNwRDtBQUNGO0FBRUEsTUFBTUksa0JBQWtCLENBQUM7RUFDdkJDLFdBQVcsQ0FBRUMsR0FBRyxFQUFFQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUU7SUFDM0IsS0FBSyxJQUFJQyxHQUFHLElBQUl2QixXQUFXLEVBQUU7TUFDM0IsSUFBSSxDQUFDc0IsSUFBSSxJQUFJLENBQUNFLGFBQUksQ0FBQ0MsUUFBUSxDQUFDSCxJQUFJLENBQUNDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7UUFDdEMsTUFBTSxJQUFJRyxLQUFLLENBQUUsV0FBVUgsR0FBSSxnQkFBZSxDQUFDO01BQ2pEO01BQ0EsSUFBSSxDQUFDQSxHQUFHLENBQUMsR0FBR0QsSUFBSSxDQUFDQyxHQUFHLENBQUM7SUFDdkI7SUFDQSxJQUFJLENBQUNGLEdBQUcsR0FBR0EsR0FBRztJQUNkLElBQUksQ0FBQ00sbUNBQW1DLEdBQUdMLElBQUksQ0FBQ0ssbUNBQW1DO0lBQ25GLE1BQU1DLFNBQVMsR0FBRztNQUNoQlAsR0FBRztNQUNIUSxNQUFNLEVBQUUsSUFBSSxDQUFDQyxJQUFJO01BQ2pCQyxJQUFJLEVBQUUsSUFBSSxDQUFDQyxVQUFVO01BQ3JCQyxTQUFTLEVBQUU7SUFDYixDQUFDO0lBQ0QsSUFBSVgsSUFBSSxDQUFDWSxXQUFXLElBQUlaLElBQUksQ0FBQ1ksV0FBVyxHQUFHLENBQUMsRUFBRTtNQUM1Q04sU0FBUyxDQUFDTyxPQUFPLEdBQUdiLElBQUksQ0FBQ1ksV0FBVztJQUN0QztJQUNBLElBQUksQ0FBQ0UsT0FBTyxHQUFHLElBQUkxQixTQUFTLENBQUNrQixTQUFTLENBQUM7SUFDdkMsSUFBSSxDQUFDUyxXQUFXLEdBQUcsSUFBSSxDQUFDRCxPQUFPLENBQUNDLFdBQVcsQ0FBQ0MsSUFBSSxDQUFDLElBQUksQ0FBQ0YsT0FBTyxDQUFDO0lBQzlELElBQUksQ0FBQ3hCLFlBQVksR0FBRyxJQUFJLENBQUN3QixPQUFPLENBQUNHLE9BQU8sQ0FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQ0YsT0FBTyxDQUFDO0lBQzNELElBQUksQ0FBQ0EsT0FBTyxDQUFDcEIsc0JBQXNCLEdBQUcsS0FBSztFQUM3Qzs7RUFPQSxNQUFNd0IsZ0JBQWdCLENBQUVDLGNBQWMsR0FBR3ZDLHNCQUFzQixHQUFHLElBQUksRUFBRTtJQUN0RSxNQUFNd0MsT0FBTyxHQUFHLE1BQU1DLGdCQUFPLENBQUNDLE9BQU8sRUFBRTtJQUN2QyxNQUFNQyxrQkFBa0IsR0FBRyxPQUFPO01BQUNDLE9BQU87TUFBRUM7SUFBSyxDQUFDLEtBQUs7TUFDckQsSUFBSSxNQUFNQyxnQkFBTyxDQUFDQyxXQUFXLENBQUNILE9BQU8sQ0FBQyxFQUFFO1FBQ3RDLE9BQU87VUFBRUEsT0FBTztVQUFFQztRQUFNLENBQUM7TUFDM0I7TUFFQSxJQUFJLENBQUMxQixHQUFHLENBQUM2QixJQUFJLENBQUUsc0JBQXFCSixPQUFRLHNCQUFxQixHQUM5RCxnREFBK0NKLE9BQVEscUJBQW9CLEdBQzNFLHNHQUFxRyxDQUFDO01BQ3pHLE1BQU1TLE9BQU8sR0FBR0MsYUFBSSxDQUFDQyxPQUFPLENBQUNYLE9BQU8sRUFBRVUsYUFBSSxDQUFDRSxRQUFRLENBQUNSLE9BQU8sQ0FBQyxDQUFDO01BQzdELE1BQU1TLFdBQUUsQ0FBQ0MsUUFBUSxDQUFDVixPQUFPLEVBQUVLLE9BQU8sQ0FBQztNQUNuQyxPQUFPO1FBQ0xMLE9BQU8sRUFBRUssT0FBTztRQUNoQko7TUFDRixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUk7TUFDRixNQUFNVSxZQUFZLEdBQUcsTUFBTUMsaUJBQUMsQ0FBQ0MsR0FBRyxDQUFDRCxpQkFBQyxDQUFDRSxHQUFHLENBQUMsQ0FDckM7UUFDRWQsT0FBTyxFQUFFZSx5Q0FBTztRQUNoQmQsS0FBSyxFQUFFM0M7TUFDVCxDQUFDLEVBQUU7UUFDRDBDLE9BQU8sRUFBRWdCLHVDQUFXO1FBQ3BCZixLQUFLLEVBQUUxQztNQUNULENBQUMsQ0FDRixFQUFFd0Msa0JBQWtCLENBQUMsQ0FBQztNQUV2QixJQUFJa0IsNkJBQTZCLEdBQUcsS0FBSztNQUN6QyxJQUFJQywyQkFBMkIsR0FBRyxLQUFLO01BQ3ZDLEtBQUssTUFBTTtRQUFDakIsS0FBSztRQUFFRDtNQUFPLENBQUMsSUFBSVcsWUFBWSxFQUFFO1FBQzNDLElBQUlWLEtBQUssS0FBSzFDLHNCQUFzQixFQUFFO1VBQ3BDLE1BQU00RCxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUNDLEdBQUcsQ0FBQ0QsY0FBYyxDQUFDbEIsS0FBSyxDQUFDOztVQUkzRCxJQUFJLEVBQUMsTUFBTSxJQUFJLENBQUNtQixHQUFHLENBQUNDLFlBQVksQ0FBQ3JCLE9BQU8sRUFBRUMsS0FBSyxDQUFDLEdBQUU7WUFDaEQsTUFBTUMsZ0JBQU8sQ0FBQ29CLE9BQU8sQ0FBQyxJQUFJLENBQUNGLEdBQUcsRUFBRXBCLE9BQU8sQ0FBQztZQUN4Q2lCLDZCQUE2QixHQUFHQSw2QkFBNkIsSUFBSUUsY0FBYztZQUMvRUQsMkJBQTJCLEdBQUcsSUFBSTtVQUNwQztVQUVBLElBQUksQ0FBQ0MsY0FBYyxFQUFFO1lBQ25CRCwyQkFBMkIsR0FBRyxJQUFJO1VBQ3BDO1VBQ0E7UUFDRjtRQUVBLE1BQU1LLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQ0gsR0FBRyxDQUFDSSwwQkFBMEIsQ0FBQ3hCLE9BQU8sRUFBRUMsS0FBSyxDQUFDO1FBQzFFLElBQUksQ0FBQzFCLEdBQUcsQ0FBQ2tELEtBQUssQ0FBRSxHQUFFeEIsS0FBTSx3QkFBdUJzQixRQUFTLEVBQUMsQ0FBQztRQUMxRCxJQUFJLE1BQU0sSUFBSSxDQUFDSCxHQUFHLENBQUNDLFlBQVksQ0FBQ3JCLE9BQU8sRUFBRUMsS0FBSyxDQUFDLEVBQUU7VUFDL0NnQiw2QkFBNkIsR0FBR0EsNkJBQTZCLElBQUksQ0FDL0QsSUFBSSxDQUFDRyxHQUFHLENBQUNNLGlCQUFpQixDQUFDQyx1QkFBdUIsRUFDbEQsSUFBSSxDQUFDUCxHQUFHLENBQUNNLGlCQUFpQixDQUFDRSx1QkFBdUIsQ0FDbkQsQ0FBQ0MsUUFBUSxDQUFDTixRQUFRLENBQUM7UUFDdEIsQ0FBQyxNQUFNO1VBQ0wsTUFBTXJCLGdCQUFPLENBQUNvQixPQUFPLENBQUMsSUFBSSxDQUFDRixHQUFHLEVBQUVwQixPQUFPLENBQUM7VUFDeENpQiw2QkFBNkIsR0FBR0EsNkJBQTZCLElBQUksQ0FBQyxDQUNoRSxJQUFJLENBQUNHLEdBQUcsQ0FBQ00saUJBQWlCLENBQUNJLGFBQWEsQ0FDekMsQ0FBQ0QsUUFBUSxDQUFDTixRQUFRLENBQUM7UUFDdEI7UUFDQUwsMkJBQTJCLEdBQUdBLDJCQUEyQixJQUFJRCw2QkFBNkIsSUFBSSxDQUM1RixJQUFJLENBQUNHLEdBQUcsQ0FBQ00saUJBQWlCLENBQUNJLGFBQWEsQ0FDekMsQ0FBQ0QsUUFBUSxDQUFDTixRQUFRLENBQUM7TUFDdEI7TUFDQSxJQUFJLENBQUNoRCxHQUFHLENBQUM2QixJQUFJLENBQUUsdUJBQXNCYywyQkFBMkIsR0FBRyxFQUFFLEdBQUcsTUFBTywyQkFBMEIsQ0FBQztNQUMxRyxJQUFJQSwyQkFBMkIsSUFBSUQsNkJBQTZCLEVBQUU7UUFDaEUsSUFBSSxDQUFDMUMsR0FBRyxDQUFDNkIsSUFBSSxDQUFDLGtEQUFrRCxDQUFDO01BQ25FO01BQ0EsS0FBSyxNQUFNO1FBQUNILEtBQUs7UUFBRUQ7TUFBTyxDQUFDLElBQUlXLFlBQVksRUFBRTtRQUMzQyxJQUFJTSw2QkFBNkIsRUFBRTtVQUNqQyxJQUFJO1lBQ0YsTUFBTSxJQUFJLENBQUNHLEdBQUcsQ0FBQ1csWUFBWSxDQUFDOUIsS0FBSyxDQUFDO1VBQ3BDLENBQUMsQ0FBQyxPQUFPK0IsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDekQsR0FBRyxDQUFDMEQsSUFBSSxDQUFFLHVCQUFzQmhDLEtBQU0sTUFBSytCLEdBQUcsQ0FBQ0UsT0FBUSxFQUFDLENBQUM7VUFDaEU7UUFDRjtRQUNBLElBQUloQiwyQkFBMkIsRUFBRTtVQUMvQixNQUFNLElBQUksQ0FBQ0UsR0FBRyxDQUFDZSxPQUFPLENBQUNuQyxPQUFPLEVBQUU7WUFDOUJvQyxhQUFhLEVBQUUsSUFBSTtZQUNuQkMsT0FBTyxFQUFFLElBQUk7WUFDYmhELE9BQU8sRUFBRU0sY0FBYztZQUN2QjJDLGNBQWMsRUFBRTtVQUNsQixDQUFDLENBQUM7UUFDSjtNQUNGO0lBQ0YsQ0FBQyxTQUFTO01BQ1IsTUFBTTdCLFdBQUUsQ0FBQzhCLE1BQU0sQ0FBQzNDLE9BQU8sQ0FBQztJQUMxQjtJQUVBLE1BQU0sSUFBSSxDQUFDNEMsMEJBQTBCLEVBQUU7RUFDekM7RUFFQSxNQUFNQSwwQkFBMEIsR0FBSTtJQUNsQyxJQUFJLENBQUNqRSxHQUFHLENBQUNrRCxLQUFLLENBQUUsaUJBQWdCcEUsdUJBQXdCLGlDQUFnQyxDQUFDO0lBQ3pGLElBQUlvRixvQkFBb0IsR0FBRyxLQUFLO0lBQ2hDLElBQUlDLFFBQVEsR0FBRyxFQUFFO0lBQ2pCLElBQUlDLE9BQU8sR0FBRyxJQUFJO0lBQ2xCLElBQUk7TUFDRixNQUFNLElBQUFDLDBCQUFnQixFQUFDLFlBQVk7UUFDakMsSUFBSSxDQUFDSCxvQkFBb0IsRUFBRTtVQUN6QkUsT0FBTyxHQUFHLElBQUk7VUFDZEQsUUFBUSxHQUFHLEVBQUU7VUFDYixJQUFJO1lBQ0ZBLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQ3RCLEdBQUcsQ0FBQ3lCLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztVQUNwRSxDQUFDLENBQUMsT0FBT0MsQ0FBQyxFQUFFO1lBQ1ZILE9BQU8sR0FBR0csQ0FBQztVQUNiO1VBQ0EsSUFBSUosUUFBUSxDQUFDYixRQUFRLENBQUMsc0NBQXNDLENBQUMsRUFBRTtZQUM3RGMsT0FBTyxHQUFHLElBQUkvRCxLQUFLLENBQUUsb0NBQW1DOEQsUUFBUyxFQUFDLENBQUM7WUFDbkVBLFFBQVEsR0FBRyxFQUFFO1VBQ2YsQ0FBQyxNQUFNLElBQUlBLFFBQVEsQ0FBQ2IsUUFBUSxDQUFDckUsc0JBQXNCLENBQUMsRUFBRTtZQUNwRGtGLFFBQVEsR0FBRyxFQUFFO1lBQ2IsSUFBSSxDQUFDbkUsR0FBRyxDQUFDa0QsS0FBSyxDQUFFLDJCQUEwQmpFLHNCQUF1QixnQkFBZSxDQUFDO1lBRWpGaUYsb0JBQW9CLEdBQUcsSUFBSTtVQUM3QixDQUFDLE1BQU0sSUFBSSxDQUFDRSxPQUFPLEVBQUU7WUFDbkJBLE9BQU8sR0FBRyxJQUFJL0QsS0FBSyxDQUFDLDZEQUE2RCxDQUFDO1VBQ3BGO1FBQ0Y7UUFDQSxPQUFPNkQsb0JBQW9CO01BQzdCLENBQUMsRUFBRTtRQUNETSxNQUFNLEVBQUUxRix1QkFBdUI7UUFDL0IyRixVQUFVLEVBQUU7TUFDZCxDQUFDLENBQUM7SUFDSixDQUFDLENBQUMsT0FBT2hCLEdBQUcsRUFBRTtNQUNaLElBQUksQ0FBQ3pELEdBQUcsQ0FBQzBFLEtBQUssQ0FBRSwwQ0FBeUN6RixzQkFBdUIsTUFBSyxDQUFDbUYsT0FBTyxJQUFJLENBQUMsQ0FBQyxFQUFFVCxPQUFRLEVBQUMsQ0FBQztNQUMvRyxJQUFJUSxRQUFRLEVBQUU7UUFDWixJQUFJLENBQUNuRSxHQUFHLENBQUNrRCxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDcEMsS0FBSyxNQUFNeUIsSUFBSSxJQUFJUixRQUFRLENBQUNTLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtVQUN2QyxJQUFJLENBQUM1RSxHQUFHLENBQUNrRCxLQUFLLENBQUUsT0FBTXlCLElBQUksQ0FBQ2IsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBRSxFQUFDLENBQUM7UUFDL0Q7TUFDRjtJQUNGO0VBQ0Y7RUFFQSxNQUFNZSxZQUFZLENBQUVDLElBQUksRUFBRTtJQUN4QixNQUFNLElBQUksQ0FBQ0MsMEJBQTBCLEVBQUU7SUFDdkMsSUFBSUQsSUFBSSxDQUFDRSxzQkFBc0IsRUFBRTtNQUMvQixJQUFJLENBQUNoRixHQUFHLENBQUM2QixJQUFJLENBQUUsd0ZBQXVGLENBQUM7SUFDekcsQ0FBQyxNQUFNO01BQ0wsSUFBSSxDQUFDN0IsR0FBRyxDQUFDNkIsSUFBSSxDQUFFLGdDQUErQm9ELGlDQUFjLEVBQUMsQ0FBQztNQUM5RCxJQUFJLENBQUNqRixHQUFHLENBQUM2QixJQUFJLENBQUUsbUNBQWtDVyx5Q0FBUSxvQkFBbUJDLHVDQUFZLEdBQUUsQ0FBQztJQUM3RjtJQUVBLE1BQU0zQixPQUFPLEdBQUdnRSxJQUFJLENBQUNJLCtCQUErQixJQUFJdEcscUJBQXFCO0lBQzdFLE1BQU11RyxLQUFLLEdBQUcsSUFBSUMsZUFBTSxDQUFDQyxLQUFLLEVBQUUsQ0FBQ0MsS0FBSyxFQUFFO0lBQ3hDLElBQUlDLE9BQU8sR0FBRyxDQUFDO0lBQ2YsTUFBTUMsVUFBVSxHQUFHLENBQUM7SUFDcEIsTUFBTUMsbUJBQW1CLEdBQUcsSUFBSTtJQUNoQyxPQUFPRixPQUFPLEdBQUdDLFVBQVUsRUFBRTtNQUMzQixJQUFJLENBQUN4RixHQUFHLENBQUM2QixJQUFJLENBQUUsaUJBQWdCZixPQUFRLHFDQUFvQyxDQUFDO01BQzVFLElBQUksQ0FBQ0MsT0FBTyxDQUFDcEIsc0JBQXNCLEdBQUcsS0FBSztNQUMzQyxNQUFNLElBQUksQ0FBQytGLDJCQUEyQixFQUFFO01BQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMzRSxPQUFPLENBQUNwQixzQkFBc0IsRUFBRTtRQUN4QyxJQUFJO1VBQ0YsTUFBTSxJQUFBMEUsMEJBQWdCLEVBQUMsWUFBWTtZQUNqQyxJQUFJO2NBQ0YsTUFBTSxJQUFJLENBQUN0RCxPQUFPLENBQUNHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDO2NBQzVDLE9BQU8sSUFBSTtZQUNiLENBQUMsQ0FBQyxPQUFPdUMsR0FBRyxFQUFFO2NBRVosT0FBTyxJQUFJLENBQUMxQyxPQUFPLENBQUNwQixzQkFBc0I7WUFDNUM7VUFDRixDQUFDLEVBQUU7WUFDRDZFLE1BQU0sRUFBRTFELE9BQU87WUFDZjJELFVBQVUsRUFBRTtVQUNkLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxPQUFPaEIsR0FBRyxFQUFFO1VBQ1osSUFBSSxDQUFDekQsR0FBRyxDQUFDMkYsYUFBYSxDQUFFLDREQUEyRDdFLE9BQVEsY0FBYSxHQUNwRyx5RkFBeUYsR0FDeEYsMEZBQXlGLENBQUM7UUFDakc7TUFDRjtNQUNBLElBQUksQ0FBQyxJQUFJLENBQUNDLE9BQU8sQ0FBQ3BCLHNCQUFzQixFQUFFO1FBQ3hDO01BQ0Y7TUFFQTRGLE9BQU8sRUFBRTtNQUNULElBQUlBLE9BQU8sSUFBSUMsVUFBVSxFQUFFO1FBQ3pCLElBQUksQ0FBQ3hGLEdBQUcsQ0FBQzJGLGFBQWEsQ0FBQyxxREFBcUQsR0FDeEUsd0ZBQXdGLENBQUM7TUFDL0Y7TUFDQSxJQUFJLENBQUMzRixHQUFHLENBQUMwRCxJQUFJLENBQUUsZ0VBQStELEdBQ3pFLG1DQUFrQzZCLE9BQVEsT0FBTUMsVUFBVSxHQUFHLENBQUUsR0FBRSxDQUFDO01BQ3ZFLE1BQU0sSUFBSSxDQUFDVCwwQkFBMEIsQ0FBQyxJQUFJLENBQUM7TUFDM0MsTUFBTTFDLGlCQUFDLENBQUN1RCxLQUFLLENBQUNILG1CQUFtQixDQUFDO0lBQ3BDO0lBRUEsSUFBSSxDQUFDekYsR0FBRyxDQUFDa0QsS0FBSyxDQUFFLHlEQUF3RCxHQUNuRSxHQUFFaUMsS0FBSyxDQUFDVSxXQUFXLEVBQUUsQ0FBQ0MsY0FBYyxDQUFDQyxPQUFPLENBQUMsQ0FBQyxDQUFFLElBQUcsQ0FBQztJQUN6RCxNQUFNLElBQUksQ0FBQ2hGLE9BQU8sQ0FBQ0csT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUU7TUFDN0M4RSxZQUFZLEVBQUU7UUFDWkMsVUFBVSxFQUFFLENBQUNuQixJQUFJLENBQUM7UUFDbEJvQixXQUFXLEVBQUUsQ0FBQztNQUNoQjtJQUNGLENBQUMsQ0FBQztFQUNKO0VBRUEsTUFBTVIsMkJBQTJCLEdBQUk7SUFDbkMsTUFBTVMsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUM7SUFDdEMsSUFBSSxJQUFJLENBQUNDLHNCQUFzQixFQUFFO01BQy9CRCxHQUFHLENBQUNFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztJQUNuQztJQUNBLElBQUlDLGVBQUMsQ0FBQ0MsU0FBUyxDQUFDLElBQUksQ0FBQ2pHLG1DQUFtQyxDQUFDLEVBQUU7TUFDekQ2RixHQUFHLENBQUNFLElBQUksQ0FBQyxJQUFJLEVBQUUseUNBQXlDLEVBQUUsSUFBSSxDQUFDL0YsbUNBQW1DLENBQUM7SUFDckc7SUFFQTZGLEdBQUcsQ0FBQ0UsSUFBSSxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLENBQUM7SUFDeENGLEdBQUcsQ0FBQ0UsSUFBSSxDQUFDcEgsc0JBQXNCLENBQUM7SUFDaEMsTUFBTXVILHNCQUFzQixHQUFHLElBQUksQ0FBQzNELEdBQUcsQ0FBQzRELGdCQUFnQixDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUdOLEdBQUcsQ0FBQyxDQUFDO0lBQzNFSyxzQkFBc0IsQ0FBQ0UsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDQyxNQUFNLEVBQUVDLE1BQU0sS0FBSztNQUN0RCxNQUFNQyxNQUFNLEdBQUdQLGVBQUMsQ0FBQ1EsSUFBSSxDQUFDSCxNQUFNLElBQUlDLE1BQU0sQ0FBQztNQUN2QyxJQUFJQyxNQUFNLEVBQUU7UUFDVjNILHFCQUFxQixDQUFDZ0UsS0FBSyxDQUFDMkQsTUFBTSxDQUFDO01BQ3JDO0lBQ0YsQ0FBQyxDQUFDO0lBQ0ZMLHNCQUFzQixDQUFDRSxFQUFFLENBQUMsTUFBTSxFQUFHSyxJQUFJLElBQUs7TUFDMUM3SCxxQkFBcUIsQ0FBQ2dFLEtBQUssQ0FBRSxvQ0FBbUM2RCxJQUFLLEVBQUMsQ0FBQztNQUN2RSxJQUFJLENBQUNoRyxPQUFPLENBQUNwQixzQkFBc0IsR0FBRyxJQUFJO0lBQzVDLENBQUMsQ0FBQztJQUNGLE1BQU02RyxzQkFBc0IsQ0FBQ2xCLEtBQUssQ0FBQyxDQUFDLENBQUM7RUFDdkM7RUFFQSxNQUFNMEIsYUFBYSxHQUFJO0lBQ3JCLElBQUksQ0FBQ2hILEdBQUcsQ0FBQ2tELEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQztJQUd0RCxJQUFJO01BQ0YsTUFBTSxJQUFJLENBQUNuQyxPQUFPLENBQUNHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDO0lBQzNDLENBQUMsQ0FBQyxPQUFPdUMsR0FBRyxFQUFFO01BQ1osSUFBSSxDQUFDekQsR0FBRyxDQUFDMEQsSUFBSSxDQUFFLDhEQUE2RCxHQUN2RSxjQUFhRCxHQUFJLEVBQUMsQ0FBQztJQUMxQjtFQUNGO0VBRUEsTUFBTXNCLDBCQUEwQixDQUFFa0MsYUFBYSxHQUFHLEtBQUssRUFBRTtJQUN2RCxJQUFJLENBQUNqSCxHQUFHLENBQUNrRCxLQUFLLENBQUUsY0FBYStELGFBQWEsR0FBRyxRQUFRLEdBQUcsU0FBVSxrQ0FBaUMsQ0FBQztJQUVwRyxJQUFJO01BQ0YsTUFBTTtRQUFDQztNQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBQUMsY0FBSyxFQUFDO1FBQzNCM0gsR0FBRyxFQUFHLFVBQVMsSUFBSSxDQUFDaUIsSUFBSyxJQUFHLElBQUksQ0FBQ0UsVUFBVyxXQUFVO1FBQ3RERyxPQUFPLEVBQUU7TUFDWCxDQUFDLENBQUMsRUFBRXNHLElBQUk7TUFDUixNQUFNQyxnQkFBZ0IsR0FBR0gsS0FBSyxDQUFDM0UsR0FBRyxDQUFDLENBQUM7UUFBQytFO01BQUUsQ0FBQyxLQUFLQSxFQUFFLENBQUMsQ0FBQ0MsTUFBTSxDQUFDQyxPQUFPLENBQUM7TUFDaEUsSUFBSUgsZ0JBQWdCLENBQUNJLE1BQU0sRUFBRTtRQUMzQixJQUFJLENBQUN6SCxHQUFHLENBQUNrRCxLQUFLLENBQUUsc0RBQXFEd0UsSUFBSSxDQUFDQyxTQUFTLENBQUNOLGdCQUFnQixDQUFFLEVBQUMsQ0FBQztRQUN4RyxJQUFJLENBQUNySCxHQUFHLENBQUNrRCxLQUFLLENBQUUsZUFBYy9DLGFBQUksQ0FBQ3lILFNBQVMsQ0FBQyxrQkFBa0IsRUFBRVAsZ0JBQWdCLENBQUNJLE1BQU0sRUFBRSxJQUFJLENBQUUsRUFBQyxDQUFDO1FBQ2xHLE1BQU1wRixpQkFBQyxDQUFDQyxHQUFHLENBQUMrRSxnQkFBZ0IsQ0FDekI5RSxHQUFHLENBQUUrRSxFQUFFLElBQUtILGNBQUssQ0FBQ1UsTUFBTSxDQUFFLFVBQVMsSUFBSSxDQUFDcEgsSUFBSyxJQUFHLElBQUksQ0FBQ0UsVUFBVyxZQUFXMkcsRUFBRyxFQUFDLENBQUMsQ0FBQyxDQUNuRjtRQUVELE1BQU1qRixpQkFBQyxDQUFDdUQsS0FBSyxDQUFDLElBQUksQ0FBQztNQUNyQixDQUFDLE1BQU07UUFDTCxJQUFJLENBQUM1RixHQUFHLENBQUNrRCxLQUFLLENBQUMseUNBQXlDLENBQUM7TUFDM0Q7SUFDRixDQUFDLENBQUMsT0FBT3FCLENBQUMsRUFBRTtNQUNWLElBQUksQ0FBQ3ZFLEdBQUcsQ0FBQ2tELEtBQUssQ0FBRSw0Q0FBMkNxQixDQUFDLENBQUNaLE9BQVEsR0FBRSxDQUFDO0lBQzFFO0lBRUEsSUFBSTtNQUNGLE1BQU0sSUFBSSxDQUFDZCxHQUFHLENBQUNpRixTQUFTLENBQUM5SSxzQkFBc0IsQ0FBQztJQUNsRCxDQUFDLENBQUMsT0FBTytJLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLElBQUksQ0FBQ2QsYUFBYSxFQUFFO01BQ2xCO0lBQ0Y7SUFFQSxJQUFJO01BQ0YsTUFBTSxJQUFJLENBQUNwRSxHQUFHLENBQUNtRixtQkFBbUIsQ0FBQyxhQUFhLENBQUM7SUFDbkQsQ0FBQyxDQUFDLE9BQU9ELE1BQU0sRUFBRSxDQUFDO0VBQ3BCO0FBQ0Y7QUFBQztBQUFBLGVBR2NqSSxrQkFBa0I7QUFBQSJ9
@@ -1 +1 @@
1
- {"version":3,"file":"uiautomator2.js","names":["REQD_PARAMS","SERVER_LAUNCH_TIMEOUT","SERVER_INSTALL_RETRIES","SERVICES_LAUNCH_TIMEOUT","SERVER_PACKAGE_ID","SERVER_TEST_PACKAGE_ID","INSTRUMENTATION_TARGET","instrumentationLogger","logger","getLogger","UIA2Proxy","JWProxy","proxyCommand","url","method","body","didInstrumentationExit","errors","InvalidContextError","UiAutomator2Server","constructor","log","opts","req","util","hasValue","Error","disableSuppressAccessibilityService","proxyOpts","server","host","port","systemPort","keepAlive","readTimeout","timeout","jwproxy","proxyReqRes","bind","command","installServerApk","installTimeout","tmpRoot","tempDir","openDir","packageInfosMapper","appPath","appId","helpers","isWriteable","info","dstPath","path","resolve","basename","fs","copyFile","packagesInfo","B","all","map","apkPath","testApkPath","shouldUninstallServerPackages","shouldInstallServerPackages","isAppInstalled","adb","checkApkCert","signApp","appState","getApplicationInstallState","debug","APP_INSTALL_STATE","OLDER_VERSION_INSTALLED","NEWER_VERSION_INSTALLED","includes","NOT_INSTALLED","uninstallApk","err","warn","message","install","noIncremental","replace","timeoutCapName","rimraf","verifyServicesAvailability","isPmServiceAvailable","pmOutput","pmError","waitForCondition","shell","e","waitMs","intervalMs","error","line","split","startSession","caps","cleanupAutomationLeftovers","skipServerInstallation","serverVersion","uiautomator2ServerLaunchTimeout","timer","timing","Timer","start","retries","maxRetries","delayBetweenRetries","startInstrumentationProcess","errorAndThrow","delay","getDuration","asMilliSeconds","toFixed","capabilities","firstMatch","alwaysMatch","cmd","disableWindowAnimation","push","_","isBoolean","instrumentationProcess","createSubProcess","on","stdout","stderr","output","trim","code","deleteSession","strictCleanup","value","axios","data","activeSessionIds","id","filter","Boolean","length","JSON","stringify","pluralize","delete","forceStop","ignore","killProcessesByName"],"sources":["../../lib/uiautomator2.js"],"sourcesContent":["import _ from 'lodash';\nimport { JWProxy, errors } from 'appium/driver';\nimport { waitForCondition } from 'asyncbox';\nimport {\n SERVER_APK_PATH as apkPath,\n TEST_APK_PATH as testApkPath,\n version as serverVersion\n} from 'appium-uiautomator2-server';\nimport {\n util, logger, tempDir, fs, timing\n} from 'appium/support';\nimport B from 'bluebird';\nimport helpers from './helpers';\nimport axios from 'axios';\nimport path from 'path';\n\nconst REQD_PARAMS = ['adb', 'tmpDir', 'host', 'systemPort', 'devicePort', 'disableWindowAnimation'];\nconst SERVER_LAUNCH_TIMEOUT = 30000;\nconst SERVER_INSTALL_RETRIES = 20;\nconst SERVICES_LAUNCH_TIMEOUT = 30000;\nconst SERVER_PACKAGE_ID = 'io.appium.uiautomator2.server';\nconst SERVER_TEST_PACKAGE_ID = `${SERVER_PACKAGE_ID}.test`;\nconst INSTRUMENTATION_TARGET = `${SERVER_TEST_PACKAGE_ID}/androidx.test.runner.AndroidJUnitRunner`;\nconst instrumentationLogger = logger.getLogger('Instrumentation');\n\nclass UIA2Proxy extends JWProxy {\n async proxyCommand (url, method, body = null) {\n if (this.didInstrumentationExit) {\n throw new errors.InvalidContextError(\n `'${method} ${url}' cannot be proxied to UiAutomator2 server because ` +\n 'the instrumentation process is not running (probably crashed). ' +\n 'Check the server log and/or the logcat output for more details');\n }\n return await super.proxyCommand(url, method, body);\n }\n}\n\nclass UiAutomator2Server {\n constructor (log, opts = {}) {\n for (let req of REQD_PARAMS) {\n if (!opts || !util.hasValue(opts[req])) {\n throw new Error(`Option '${req}' is required!`);\n }\n this[req] = opts[req];\n }\n this.log = log;\n this.disableSuppressAccessibilityService = opts.disableSuppressAccessibilityService;\n const proxyOpts = {\n log,\n server: this.host,\n port: this.systemPort,\n keepAlive: true,\n };\n if (opts.readTimeout && opts.readTimeout > 0) {\n proxyOpts.timeout = opts.readTimeout;\n }\n this.jwproxy = new UIA2Proxy(proxyOpts);\n this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);\n this.proxyCommand = this.jwproxy.command.bind(this.jwproxy);\n this.jwproxy.didInstrumentationExit = false;\n }\n\n /**\n * Installs the apks on to the device or emulator.\n *\n * @param {number} installTimeout - Installation timeout\n */\n async installServerApk (installTimeout = SERVER_INSTALL_RETRIES * 1000) {\n const tmpRoot = await tempDir.openDir();\n const packageInfosMapper = async ({appPath, appId}) => {\n if (await helpers.isWriteable(appPath)) {\n return { appPath, appId };\n }\n\n this.log.info(`Server package at '${appPath}' is not writeable. ` +\n `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` +\n `Consider making this file writeable manually in order to improve the performance of session startup.`);\n const dstPath = path.resolve(tmpRoot, path.basename(appPath));\n await fs.copyFile(appPath, dstPath);\n return {\n appPath: dstPath,\n appId,\n };\n };\n\n try {\n const packagesInfo = await B.all(B.map([\n {\n appPath: apkPath,\n appId: SERVER_PACKAGE_ID,\n }, {\n appPath: testApkPath,\n appId: SERVER_TEST_PACKAGE_ID,\n },\n ], packageInfosMapper));\n\n let shouldUninstallServerPackages = false;\n let shouldInstallServerPackages = false;\n for (const {appId, appPath} of packagesInfo) {\n if (appId === SERVER_TEST_PACKAGE_ID) {\n const isAppInstalled = await this.adb.isAppInstalled(appId);\n\n // There is no point in getting the state for test server,\n // since it does not contain version info\n if (!await this.adb.checkApkCert(appPath, appId)) {\n await helpers.signApp(this.adb, appPath);\n shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;\n shouldInstallServerPackages = true;\n }\n\n if (!isAppInstalled) {\n shouldInstallServerPackages = true;\n }\n continue;\n }\n\n const appState = await this.adb.getApplicationInstallState(appPath, appId);\n this.log.debug(`${appId} installation state: ${appState}`);\n if (await this.adb.checkApkCert(appPath, appId)) {\n shouldUninstallServerPackages = shouldUninstallServerPackages || [\n this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,\n this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED,\n ].includes(appState);\n } else {\n await helpers.signApp(this.adb, appPath);\n shouldUninstallServerPackages = shouldUninstallServerPackages || ![\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n ].includes(appState);\n }\n shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n ].includes(appState);\n }\n this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);\n if (shouldInstallServerPackages && shouldUninstallServerPackages) {\n this.log.info('Full packages reinstall is going to be performed');\n }\n for (const {appId, appPath} of packagesInfo) {\n if (shouldUninstallServerPackages) {\n try {\n await this.adb.uninstallApk(appId);\n } catch (err) {\n this.log.warn(`Error uninstalling '${appId}': ${err.message}`);\n }\n }\n if (shouldInstallServerPackages) {\n await this.adb.install(appPath, {\n noIncremental: true,\n replace: true,\n timeout: installTimeout,\n timeoutCapName: 'uiautomator2ServerInstallTimeout'\n });\n }\n }\n } finally {\n await fs.rimraf(tmpRoot);\n }\n\n await this.verifyServicesAvailability();\n }\n\n async verifyServicesAvailability () {\n this.log.debug(`Waiting up to ${SERVICES_LAUNCH_TIMEOUT}ms for services to be available`);\n let isPmServiceAvailable = false;\n let pmOutput = '';\n let pmError = null;\n try {\n await waitForCondition(async () => {\n if (!isPmServiceAvailable) {\n pmError = null;\n pmOutput = '';\n try {\n pmOutput = await this.adb.shell(['pm', 'list', 'instrumentation']);\n } catch (e) {\n pmError = e;\n }\n if (pmOutput.includes('Could not access the Package Manager')) {\n pmError = new Error(`Problem running Package Manager: ${pmOutput}`);\n pmOutput = ''; // remove output, so it is not printed below\n } else if (pmOutput.includes(INSTRUMENTATION_TARGET)) {\n pmOutput = ''; // remove output, so it is not printed below\n this.log.debug(`Instrumentation target '${INSTRUMENTATION_TARGET}' is available`);\n // eslint-disable-next-line require-atomic-updates\n isPmServiceAvailable = true;\n } else if (!pmError) {\n pmError = new Error('The instrumentation target is not listed by Package Manager');\n }\n }\n return isPmServiceAvailable;\n }, {\n waitMs: SERVICES_LAUNCH_TIMEOUT,\n intervalMs: 1000,\n });\n } catch (err) {\n this.log.error(`Unable to find instrumentation target '${INSTRUMENTATION_TARGET}': ${(pmError || {}).message}`);\n if (pmOutput) {\n this.log.debug('Available targets:');\n for (const line of pmOutput.split('\\n')) {\n this.log.debug(` ${line.replace('instrumentation:', '')}`);\n }\n }\n }\n }\n\n async startSession (caps) {\n await this.cleanupAutomationLeftovers();\n if (caps.skipServerInstallation) {\n this.log.info(`'skipServerInstallation' is set. Attempting to use UIAutomator2 server from the device`);\n } else {\n this.log.info(`Starting UIAutomator2 server ${serverVersion}`);\n this.log.info(`Using UIAutomator2 server from '${apkPath}' and test from '${testApkPath}'`);\n }\n\n const timeout = caps.uiautomator2ServerLaunchTimeout || SERVER_LAUNCH_TIMEOUT;\n const timer = new timing.Timer().start();\n let retries = 0;\n const maxRetries = 2;\n const delayBetweenRetries = 3000;\n while (retries < maxRetries) {\n this.log.info(`Waiting up to ${timeout}ms for UiAutomator2 to be online...`);\n this.jwproxy.didInstrumentationExit = false;\n await this.startInstrumentationProcess();\n if (!this.jwproxy.didInstrumentationExit) {\n try {\n await waitForCondition(async () => {\n try {\n await this.jwproxy.command('/status', 'GET');\n return true;\n } catch (err) {\n // short circuit to retry or fail fast\n return this.jwproxy.didInstrumentationExit;\n }\n }, {\n waitMs: timeout,\n intervalMs: 1000,\n });\n } catch (err) {\n this.log.errorAndThrow(`The instrumentation process cannot be initialized within ${timeout}ms timeout. `\n + 'Make sure the application under test does not crash and investigate the logcat output. '\n + `You could also try to increase the value of 'uiautomator2ServerLaunchTimeout' capability`);\n }\n }\n if (!this.jwproxy.didInstrumentationExit) {\n break;\n }\n\n retries++;\n if (retries >= maxRetries) {\n this.log.errorAndThrow('The instrumentation process cannot be initialized. '\n + 'Make sure the application under test does not crash and investigate the logcat output.');\n }\n this.log.warn(`The instrumentation process has been unexpectedly terminated. `\n + `Retrying UiAutomator2 startup (#${retries} of ${maxRetries - 1})`);\n await this.cleanupAutomationLeftovers(true);\n await B.delay(delayBetweenRetries);\n }\n\n this.log.debug(`The initialization of the instrumentation process took `\n + `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);\n await this.jwproxy.command('/session', 'POST', {\n capabilities: {\n firstMatch: [caps],\n alwaysMatch: {},\n }\n });\n }\n\n async startInstrumentationProcess () {\n const cmd = ['am', 'instrument', '-w'];\n if (this.disableWindowAnimation) {\n cmd.push('--no-window-animation');\n }\n if (_.isBoolean(this.disableSuppressAccessibilityService)) {\n cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);\n }\n // Disable Google analytics to prevent possible fatal exception\n cmd.push('-e', 'disableAnalytics', true);\n cmd.push(INSTRUMENTATION_TARGET);\n const instrumentationProcess = this.adb.createSubProcess(['shell', ...cmd]);\n instrumentationProcess.on('output', (stdout, stderr) => {\n const output = _.trim(stdout || stderr);\n if (output) {\n instrumentationLogger.debug(output);\n }\n });\n instrumentationProcess.on('exit', (code) => {\n instrumentationLogger.debug(`The process has exited with code ${code}`);\n this.jwproxy.didInstrumentationExit = true;\n });\n await instrumentationProcess.start(0);\n }\n\n async deleteSession () {\n this.log.debug('Deleting UiAutomator2 server session');\n // rely on jwproxy's intelligence to know what we're talking about and\n // delete the current session\n try {\n await this.jwproxy.command('/', 'DELETE');\n } catch (err) {\n this.log.warn(`Did not get confirmation UiAutomator2 deleteSession worked; ` +\n `Error was: ${err}`);\n }\n }\n\n async cleanupAutomationLeftovers (strictCleanup = false) {\n this.log.debug(`Performing ${strictCleanup ? 'strict' : 'shallow'} cleanup of automation leftovers`);\n\n try {\n const {value} = (await axios({\n url: `http://${this.host}:${this.systemPort}/sessions`,\n timeout: 500,\n })).data;\n const activeSessionIds = value.map(({id}) => id).filter(Boolean);\n if (activeSessionIds.length) {\n this.log.debug(`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`);\n this.log.debug(`Cleaning up ${util.pluralize('obsolete session', activeSessionIds.length, true)}`);\n await B.all(activeSessionIds\n .map((id) => axios.delete(`http://${this.host}:${this.systemPort}/session/${id}`))\n );\n // Let all sessions to be properly terminated before continuing\n await B.delay(1000);\n } else {\n this.log.debug('No obsolete sessions have been detected');\n }\n } catch (e) {\n this.log.debug(`No obsolete sessions have been detected (${e.message})`);\n }\n\n try {\n await this.adb.forceStop(SERVER_TEST_PACKAGE_ID);\n } catch (ignore) {}\n if (!strictCleanup) {\n return;\n }\n // https://github.com/appium/appium/issues/10749\n try {\n await this.adb.killProcessesByName('uiautomator');\n } catch (ignore) {}\n }\n}\n\nexport { UiAutomator2Server, INSTRUMENTATION_TARGET, SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID };\nexport default UiAutomator2Server;\n"],"mappings":"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"}
1
+ {"version":3,"file":"uiautomator2.js","names":["REQD_PARAMS","SERVER_LAUNCH_TIMEOUT","SERVER_INSTALL_RETRIES","SERVICES_LAUNCH_TIMEOUT","SERVER_PACKAGE_ID","SERVER_TEST_PACKAGE_ID","INSTRUMENTATION_TARGET","instrumentationLogger","logger","getLogger","UIA2Proxy","JWProxy","proxyCommand","url","method","body","didInstrumentationExit","errors","InvalidContextError","UiAutomator2Server","constructor","log","opts","req","util","hasValue","Error","disableSuppressAccessibilityService","proxyOpts","server","host","port","systemPort","keepAlive","readTimeout","timeout","jwproxy","proxyReqRes","bind","command","installServerApk","installTimeout","tmpRoot","tempDir","openDir","packageInfosMapper","appPath","appId","helpers","isWriteable","info","dstPath","path","resolve","basename","fs","copyFile","packagesInfo","B","all","map","apkPath","testApkPath","shouldUninstallServerPackages","shouldInstallServerPackages","isAppInstalled","adb","checkApkCert","signApp","appState","getApplicationInstallState","debug","APP_INSTALL_STATE","OLDER_VERSION_INSTALLED","NEWER_VERSION_INSTALLED","includes","NOT_INSTALLED","uninstallApk","err","warn","message","install","noIncremental","replace","timeoutCapName","rimraf","verifyServicesAvailability","isPmServiceAvailable","pmOutput","pmError","waitForCondition","shell","e","waitMs","intervalMs","error","line","split","startSession","caps","cleanupAutomationLeftovers","skipServerInstallation","serverVersion","uiautomator2ServerLaunchTimeout","timer","timing","Timer","start","retries","maxRetries","delayBetweenRetries","startInstrumentationProcess","errorAndThrow","delay","getDuration","asMilliSeconds","toFixed","capabilities","firstMatch","alwaysMatch","cmd","disableWindowAnimation","push","_","isBoolean","instrumentationProcess","createSubProcess","on","stdout","stderr","output","trim","code","deleteSession","strictCleanup","value","axios","data","activeSessionIds","id","filter","Boolean","length","JSON","stringify","pluralize","delete","forceStop","ignore","killProcessesByName"],"sources":["../../lib/uiautomator2.js"],"sourcesContent":["import _ from 'lodash';\nimport { JWProxy, errors } from 'appium/driver';\nimport { waitForCondition } from 'asyncbox';\nimport {\n SERVER_APK_PATH as apkPath,\n TEST_APK_PATH as testApkPath,\n version as serverVersion\n} from 'appium-uiautomator2-server';\nimport {\n util, logger, tempDir, fs, timing\n} from 'appium/support';\nimport B from 'bluebird';\nimport helpers from './helpers';\nimport axios from 'axios';\nimport path from 'path';\n\nconst REQD_PARAMS = ['adb', 'tmpDir', 'host', 'systemPort', 'devicePort', 'disableWindowAnimation'];\nconst SERVER_LAUNCH_TIMEOUT = 30000;\nconst SERVER_INSTALL_RETRIES = 20;\nconst SERVICES_LAUNCH_TIMEOUT = 30000;\nconst SERVER_PACKAGE_ID = 'io.appium.uiautomator2.server';\nconst SERVER_TEST_PACKAGE_ID = `${SERVER_PACKAGE_ID}.test`;\nconst INSTRUMENTATION_TARGET = `${SERVER_TEST_PACKAGE_ID}/androidx.test.runner.AndroidJUnitRunner`;\nconst instrumentationLogger = logger.getLogger('Instrumentation');\n\nclass UIA2Proxy extends JWProxy {\n async proxyCommand (url, method, body = null) {\n if (this.didInstrumentationExit) {\n throw new errors.InvalidContextError(\n `'${method} ${url}' cannot be proxied to UiAutomator2 server because ` +\n 'the instrumentation process is not running (probably crashed). ' +\n 'Check the server log and/or the logcat output for more details');\n }\n return await super.proxyCommand(url, method, body);\n }\n}\n\nclass UiAutomator2Server {\n constructor (log, opts = {}) {\n for (let req of REQD_PARAMS) {\n if (!opts || !util.hasValue(opts[req])) {\n throw new Error(`Option '${req}' is required!`);\n }\n this[req] = opts[req];\n }\n this.log = log;\n this.disableSuppressAccessibilityService = opts.disableSuppressAccessibilityService;\n const proxyOpts = {\n log,\n server: this.host,\n port: this.systemPort,\n keepAlive: true,\n };\n if (opts.readTimeout && opts.readTimeout > 0) {\n proxyOpts.timeout = opts.readTimeout;\n }\n this.jwproxy = new UIA2Proxy(proxyOpts);\n this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);\n this.proxyCommand = this.jwproxy.command.bind(this.jwproxy);\n this.jwproxy.didInstrumentationExit = false;\n }\n\n /**\n * Installs the apks on to the device or emulator.\n *\n * @param {number} installTimeout - Installation timeout\n */\n async installServerApk (installTimeout = SERVER_INSTALL_RETRIES * 1000) {\n const tmpRoot = await tempDir.openDir();\n const packageInfosMapper = async ({appPath, appId}) => {\n if (await helpers.isWriteable(appPath)) {\n return { appPath, appId };\n }\n\n this.log.info(`Server package at '${appPath}' is not writeable. ` +\n `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` +\n `Consider making this file writeable manually in order to improve the performance of session startup.`);\n const dstPath = path.resolve(tmpRoot, path.basename(appPath));\n await fs.copyFile(appPath, dstPath);\n return {\n appPath: dstPath,\n appId,\n };\n };\n\n try {\n const packagesInfo = await B.all(B.map([\n {\n appPath: apkPath,\n appId: SERVER_PACKAGE_ID,\n }, {\n appPath: testApkPath,\n appId: SERVER_TEST_PACKAGE_ID,\n },\n ], packageInfosMapper));\n\n let shouldUninstallServerPackages = false;\n let shouldInstallServerPackages = false;\n for (const {appId, appPath} of packagesInfo) {\n if (appId === SERVER_TEST_PACKAGE_ID) {\n const isAppInstalled = await this.adb.isAppInstalled(appId);\n\n // There is no point in getting the state for test server,\n // since it does not contain version info\n if (!await this.adb.checkApkCert(appPath, appId)) {\n await helpers.signApp(this.adb, appPath);\n shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;\n shouldInstallServerPackages = true;\n }\n\n if (!isAppInstalled) {\n shouldInstallServerPackages = true;\n }\n continue;\n }\n\n const appState = await this.adb.getApplicationInstallState(appPath, appId);\n this.log.debug(`${appId} installation state: ${appState}`);\n if (await this.adb.checkApkCert(appPath, appId)) {\n shouldUninstallServerPackages = shouldUninstallServerPackages || [\n this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,\n this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED,\n ].includes(appState);\n } else {\n await helpers.signApp(this.adb, appPath);\n shouldUninstallServerPackages = shouldUninstallServerPackages || ![\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n ].includes(appState);\n }\n shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n ].includes(appState);\n }\n this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);\n if (shouldInstallServerPackages && shouldUninstallServerPackages) {\n this.log.info('Full packages reinstall is going to be performed');\n }\n for (const {appId, appPath} of packagesInfo) {\n if (shouldUninstallServerPackages) {\n try {\n await this.adb.uninstallApk(appId);\n } catch (err) {\n this.log.warn(`Error uninstalling '${appId}': ${err.message}`);\n }\n }\n if (shouldInstallServerPackages) {\n await this.adb.install(appPath, {\n noIncremental: true,\n replace: true,\n timeout: installTimeout,\n timeoutCapName: 'uiautomator2ServerInstallTimeout'\n });\n }\n }\n } finally {\n await fs.rimraf(tmpRoot);\n }\n\n await this.verifyServicesAvailability();\n }\n\n async verifyServicesAvailability () {\n this.log.debug(`Waiting up to ${SERVICES_LAUNCH_TIMEOUT}ms for services to be available`);\n let isPmServiceAvailable = false;\n let pmOutput = '';\n let pmError = null;\n try {\n await waitForCondition(async () => {\n if (!isPmServiceAvailable) {\n pmError = null;\n pmOutput = '';\n try {\n pmOutput = await this.adb.shell(['pm', 'list', 'instrumentation']);\n } catch (e) {\n pmError = e;\n }\n if (pmOutput.includes('Could not access the Package Manager')) {\n pmError = new Error(`Problem running Package Manager: ${pmOutput}`);\n pmOutput = ''; // remove output, so it is not printed below\n } else if (pmOutput.includes(INSTRUMENTATION_TARGET)) {\n pmOutput = ''; // remove output, so it is not printed below\n this.log.debug(`Instrumentation target '${INSTRUMENTATION_TARGET}' is available`);\n // eslint-disable-next-line require-atomic-updates\n isPmServiceAvailable = true;\n } else if (!pmError) {\n pmError = new Error('The instrumentation target is not listed by Package Manager');\n }\n }\n return isPmServiceAvailable;\n }, {\n waitMs: SERVICES_LAUNCH_TIMEOUT,\n intervalMs: 1000,\n });\n } catch (err) {\n this.log.error(`Unable to find instrumentation target '${INSTRUMENTATION_TARGET}': ${(pmError || {}).message}`);\n if (pmOutput) {\n this.log.debug('Available targets:');\n for (const line of pmOutput.split('\\n')) {\n this.log.debug(` ${line.replace('instrumentation:', '')}`);\n }\n }\n }\n }\n\n async startSession (caps) {\n await this.cleanupAutomationLeftovers();\n if (caps.skipServerInstallation) {\n this.log.info(`'skipServerInstallation' is set. Attempting to use UIAutomator2 server from the device`);\n } else {\n this.log.info(`Starting UIAutomator2 server ${serverVersion}`);\n this.log.info(`Using UIAutomator2 server from '${apkPath}' and test from '${testApkPath}'`);\n }\n\n const timeout = caps.uiautomator2ServerLaunchTimeout || SERVER_LAUNCH_TIMEOUT;\n const timer = new timing.Timer().start();\n let retries = 0;\n const maxRetries = 2;\n const delayBetweenRetries = 3000;\n while (retries < maxRetries) {\n this.log.info(`Waiting up to ${timeout}ms for UiAutomator2 to be online...`);\n this.jwproxy.didInstrumentationExit = false;\n await this.startInstrumentationProcess();\n if (!this.jwproxy.didInstrumentationExit) {\n try {\n await waitForCondition(async () => {\n try {\n await this.jwproxy.command('/status', 'GET');\n return true;\n } catch (err) {\n // short circuit to retry or fail fast\n return this.jwproxy.didInstrumentationExit;\n }\n }, {\n waitMs: timeout,\n intervalMs: 1000,\n });\n } catch (err) {\n this.log.errorAndThrow(`The instrumentation process cannot be initialized within ${timeout}ms timeout. `\n + 'Make sure the application under test does not crash and investigate the logcat output. '\n + `You could also try to increase the value of 'uiautomator2ServerLaunchTimeout' capability`);\n }\n }\n if (!this.jwproxy.didInstrumentationExit) {\n break;\n }\n\n retries++;\n if (retries >= maxRetries) {\n this.log.errorAndThrow('The instrumentation process cannot be initialized. '\n + 'Make sure the application under test does not crash and investigate the logcat output.');\n }\n this.log.warn(`The instrumentation process has been unexpectedly terminated. `\n + `Retrying UiAutomator2 startup (#${retries} of ${maxRetries - 1})`);\n await this.cleanupAutomationLeftovers(true);\n await B.delay(delayBetweenRetries);\n }\n\n this.log.debug(`The initialization of the instrumentation process took `\n + `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);\n await this.jwproxy.command('/session', 'POST', {\n capabilities: {\n firstMatch: [caps],\n alwaysMatch: {},\n }\n });\n }\n\n async startInstrumentationProcess () {\n const cmd = ['am', 'instrument', '-w'];\n if (this.disableWindowAnimation) {\n cmd.push('--no-window-animation');\n }\n if (_.isBoolean(this.disableSuppressAccessibilityService)) {\n cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);\n }\n // Disable Google analytics to prevent possible fatal exception\n cmd.push('-e', 'disableAnalytics', true);\n cmd.push(INSTRUMENTATION_TARGET);\n const instrumentationProcess = this.adb.createSubProcess(['shell', ...cmd]);\n instrumentationProcess.on('output', (stdout, stderr) => {\n const output = _.trim(stdout || stderr);\n if (output) {\n instrumentationLogger.debug(output);\n }\n });\n instrumentationProcess.on('exit', (code) => {\n instrumentationLogger.debug(`The process has exited with code ${code}`);\n this.jwproxy.didInstrumentationExit = true;\n });\n await instrumentationProcess.start(0);\n }\n\n async deleteSession () {\n this.log.debug('Deleting UiAutomator2 server session');\n // rely on jwproxy's intelligence to know what we're talking about and\n // delete the current session\n try {\n await this.jwproxy.command('/', 'DELETE');\n } catch (err) {\n this.log.warn(`Did not get confirmation UiAutomator2 deleteSession worked; ` +\n `Error was: ${err}`);\n }\n }\n\n async cleanupAutomationLeftovers (strictCleanup = false) {\n this.log.debug(`Performing ${strictCleanup ? 'strict' : 'shallow'} cleanup of automation leftovers`);\n\n try {\n const {value} = (await axios({\n url: `http://${this.host}:${this.systemPort}/sessions`,\n timeout: 500,\n })).data;\n const activeSessionIds = value.map(({id}) => id).filter(Boolean);\n if (activeSessionIds.length) {\n this.log.debug(`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`);\n this.log.debug(`Cleaning up ${util.pluralize('obsolete session', activeSessionIds.length, true)}`);\n await B.all(activeSessionIds\n .map((id) => axios.delete(`http://${this.host}:${this.systemPort}/session/${id}`))\n );\n // Let all sessions to be properly terminated before continuing\n await B.delay(1000);\n } else {\n this.log.debug('No obsolete sessions have been detected');\n }\n } catch (e) {\n this.log.debug(`No obsolete sessions have been detected (${e.message})`);\n }\n\n try {\n await this.adb.forceStop(SERVER_TEST_PACKAGE_ID);\n } catch (ignore) {}\n if (!strictCleanup) {\n return;\n }\n // https://github.com/appium/appium/issues/10749\n try {\n await this.adb.killProcessesByName('uiautomator');\n } catch (ignore) {}\n }\n}\n\nexport { UiAutomator2Server, INSTRUMENTATION_TARGET, SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID };\nexport default UiAutomator2Server;\n"],"mappings":"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"}