appium-webdriveragent 4.9.1 → 4.9.2

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.
@@ -1,7 +1,6 @@
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
  });
@@ -21,56 +20,38 @@ exports.resetTestProcesses = resetTestProcesses;
21
20
  exports.setRealDeviceSecurity = setRealDeviceSecurity;
22
21
  exports.setXctestrunFile = setXctestrunFile;
23
22
  exports.updateProjectFile = updateProjectFile;
24
-
25
23
  require("source-map-support/register");
26
-
27
24
  var _support = require("appium/support");
28
-
29
25
  var _teen_process = require("teen_process");
30
-
31
26
  var _path = _interopRequireDefault(require("path"));
32
-
33
27
  var _logger = _interopRequireDefault(require("./logger"));
34
-
35
28
  var _lodash = _interopRequireDefault(require("lodash"));
36
-
37
29
  var _constants = require("./constants");
38
-
39
30
  var _bluebird = _interopRequireDefault(require("bluebird"));
40
-
41
31
  var _fs2 = _interopRequireDefault(require("fs"));
42
-
43
32
  var _asyncbox = require("asyncbox");
44
-
45
33
  const PROJECT_FILE = 'project.pbxproj';
46
34
 
47
35
  const getModuleRoot = _lodash.default.memoize(function getModuleRoot() {
48
36
  let currentDir = _path.default.dirname(_path.default.resolve(__filename));
49
-
50
37
  let isAtFsRoot = false;
51
-
52
38
  while (!isAtFsRoot) {
53
39
  const manifestPath = _path.default.join(currentDir, 'package.json');
54
-
55
40
  try {
56
41
  if (_fs2.default.existsSync(manifestPath) && JSON.parse(_fs2.default.readFileSync(manifestPath, 'utf8')).name === 'appium-webdriveragent') {
57
42
  return currentDir;
58
43
  }
59
44
  } catch (ign) {}
60
-
61
45
  currentDir = _path.default.dirname(currentDir);
62
46
  isAtFsRoot = currentDir.length <= _path.default.dirname(currentDir).length;
63
47
  }
64
-
65
48
  throw new Error('Cannot find the root folder of the appium-webdriveragent Node.js module');
66
49
  });
67
-
68
50
  const BOOTSTRAP_PATH = getModuleRoot();
69
51
  exports.BOOTSTRAP_PATH = BOOTSTRAP_PATH;
70
-
71
52
  async function getPIDsUsingPattern(pattern) {
72
- const args = ['-if', pattern];
73
-
53
+ const args = ['-if',
54
+ pattern];
74
55
  try {
75
56
  const {
76
57
  stdout
@@ -78,54 +59,47 @@ async function getPIDsUsingPattern(pattern) {
78
59
  return stdout.split(/\s+/).map(x => parseInt(x, 10)).filter(_lodash.default.isInteger).map(x => `${x}`);
79
60
  } catch (err) {
80
61
  _logger.default.debug(`'pgrep ${args.join(' ')}' didn't detect any matching processes. Return code: ${err.code}`);
81
-
82
62
  return [];
83
63
  }
84
64
  }
85
-
86
65
  async function killAppUsingPattern(pgrepPattern) {
87
66
  const signals = [2, 15, 9];
88
-
89
67
  for (const signal of signals) {
90
68
  const matchedPids = await getPIDsUsingPattern(pgrepPattern);
91
-
92
69
  if (_lodash.default.isEmpty(matchedPids)) {
93
70
  return;
94
71
  }
95
-
96
72
  const args = [`-${signal}`, ...matchedPids];
97
-
98
73
  try {
99
74
  await (0, _teen_process.exec)('kill', args);
100
75
  } catch (err) {
101
76
  _logger.default.debug(`kill ${args.join(' ')} -> ${err.message}`);
102
77
  }
103
-
104
78
  if (signal === _lodash.default.last(signals)) {
105
79
  return;
106
80
  }
107
-
108
81
  try {
109
82
  await (0, _asyncbox.waitForCondition)(async () => {
110
- const pidCheckPromises = matchedPids.map(pid => (0, _teen_process.exec)('kill', ['-0', pid]).then(() => false).catch(() => true));
83
+ const pidCheckPromises = matchedPids.map(pid => (0, _teen_process.exec)('kill', ['-0', pid])
84
+ .then(() => false)
85
+ .catch(() => true));
111
86
  return (await _bluebird.default.all(pidCheckPromises)).every(x => x === true);
112
87
  }, {
113
88
  waitMs: 1000,
114
89
  intervalMs: 100
115
90
  });
116
91
  return;
117
- } catch (ign) {}
92
+ } catch (ign) {
93
+ }
118
94
  }
119
95
  }
120
96
 
121
97
  function isTvOS(platformName) {
122
98
  return _lodash.default.toLower(platformName) === _lodash.default.toLower(_constants.PLATFORM_NAME_TVOS);
123
99
  }
124
-
125
100
  async function replaceInFile(file, find, replace) {
126
101
  let contents = await _support.fs.readFile(file, 'utf8');
127
102
  let newContents = contents.replace(find, replace);
128
-
129
103
  if (newContents !== contents) {
130
104
  await _support.fs.writeFile(file, newContents, 'utf8');
131
105
  }
@@ -133,55 +107,43 @@ async function replaceInFile(file, find, replace) {
133
107
 
134
108
  async function updateProjectFile(agentPath, newBundleId) {
135
109
  let projectFilePath = _path.default.resolve(agentPath, PROJECT_FILE);
136
-
137
110
  try {
138
111
  await _support.fs.copyFile(projectFilePath, `${projectFilePath}.old`);
139
112
  await replaceInFile(projectFilePath, new RegExp(_lodash.default.escapeRegExp(_constants.WDA_RUNNER_BUNDLE_ID), 'g'), newBundleId);
140
-
141
113
  _logger.default.debug(`Successfully updated '${projectFilePath}' with bundle id '${newBundleId}'`);
142
114
  } catch (err) {
143
115
  _logger.default.debug(`Error updating project file: ${err.message}`);
144
-
145
116
  _logger.default.warn(`Unable to update project file '${projectFilePath}' with ` + `bundle id '${newBundleId}'. WebDriverAgent may not start`);
146
117
  }
147
118
  }
148
119
 
149
120
  async function resetProjectFile(agentPath) {
150
121
  const projectFilePath = _path.default.join(agentPath, PROJECT_FILE);
151
-
152
122
  try {
153
123
  if (!(await _support.fs.exists(`${projectFilePath}.old`))) {
154
124
  return;
155
125
  }
156
126
 
157
127
  await _support.fs.mv(`${projectFilePath}.old`, projectFilePath);
158
-
159
128
  _logger.default.debug(`Successfully reset '${projectFilePath}' with bundle id '${_constants.WDA_RUNNER_BUNDLE_ID}'`);
160
129
  } catch (err) {
161
130
  _logger.default.debug(`Error resetting project file: ${err.message}`);
162
-
163
131
  _logger.default.warn(`Unable to reset project file '${projectFilePath}' with ` + `bundle id '${_constants.WDA_RUNNER_BUNDLE_ID}'. WebDriverAgent has been ` + `modified and not returned to the original state.`);
164
132
  }
165
133
  }
166
-
167
134
  async function setRealDeviceSecurity(keychainPath, keychainPassword) {
168
135
  _logger.default.debug('Setting security for iOS device');
169
-
170
136
  await (0, _teen_process.exec)('security', ['-v', 'list-keychains', '-s', keychainPath]);
171
137
  await (0, _teen_process.exec)('security', ['-v', 'unlock-keychain', '-p', keychainPassword, keychainPath]);
172
138
  await (0, _teen_process.exec)('security', ['set-keychain-settings', '-t', '3600', '-l', keychainPath]);
173
139
  }
174
-
175
140
  async function generateXcodeConfigFile(orgId, signingId) {
176
141
  _logger.default.debug(`Generating xcode config file for orgId '${orgId}' and signingId ` + `'${signingId}'`);
177
-
178
142
  const contents = `DEVELOPMENT_TEAM = ${orgId}
179
143
  CODE_SIGN_IDENTITY = ${signingId}
180
144
  `;
181
145
  const xcconfigPath = await _support.tempDir.path('appium-temp.xcconfig');
182
-
183
146
  _logger.default.debug(`Writing xcode config file to ${xcconfigPath}`);
184
-
185
147
  await _support.fs.writeFile(xcconfigPath, contents, 'utf8');
186
148
  return xcconfigPath;
187
149
  }
@@ -190,9 +152,7 @@ async function setXctestrunFile(deviceInfo, sdkVersion, bootstrapPath, wdaRemote
190
152
  const xctestrunFilePath = await getXctestrunFilePath(deviceInfo, sdkVersion, bootstrapPath);
191
153
  const xctestRunContent = await _support.plist.parsePlistFile(xctestrunFilePath);
192
154
  const updateWDAPort = getAdditionalRunContent(deviceInfo.platformName, wdaRemotePort);
193
-
194
155
  const newXctestRunContent = _lodash.default.merge(xctestRunContent, updateWDAPort);
195
-
196
156
  await _support.plist.updatePlistFile(xctestrunFilePath, newXctestRunContent, true);
197
157
  return xctestrunFilePath;
198
158
  }
@@ -211,41 +171,30 @@ function getAdditionalRunContent(platformName, wdaRemotePort) {
211
171
  async function getXctestrunFilePath(deviceInfo, sdkVersion, bootstrapPath) {
212
172
  const sdkBased = [_path.default.resolve(bootstrapPath, `${deviceInfo.udid}_${sdkVersion}.xctestrun`), sdkVersion];
213
173
  const platformBased = [_path.default.resolve(bootstrapPath, `${deviceInfo.udid}_${deviceInfo.platformVersion}.xctestrun`), deviceInfo.platformVersion];
214
-
215
174
  for (const [filePath, version] of [sdkBased, platformBased]) {
216
175
  if (await _support.fs.exists(filePath)) {
217
176
  _logger.default.info(`Using '${filePath}' as xctestrun file`);
218
-
219
177
  return filePath;
220
178
  }
221
-
222
179
  const originalXctestrunFile = _path.default.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, version));
223
-
224
180
  if (await _support.fs.exists(originalXctestrunFile)) {
225
181
  await _support.fs.copyFile(originalXctestrunFile, filePath);
226
-
227
182
  _logger.default.info(`Using '${filePath}' as xctestrun file copied by '${originalXctestrunFile}'`);
228
-
229
183
  return filePath;
230
184
  }
231
185
  }
232
-
233
186
  _logger.default.errorAndThrow(`If you are using 'useXctestrunFile' capability then you ` + `need to have a xctestrun file (expected: ` + `'${_path.default.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')`);
234
187
  }
235
188
 
236
189
  function getXctestrunFileName(deviceInfo, version) {
237
190
  return isTvOS(deviceInfo.platformName) ? `WebDriverAgentRunner_tvOS_appletv${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun` : `WebDriverAgentRunner_iphone${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun`;
238
191
  }
239
-
240
192
  async function killProcess(name, proc) {
241
193
  if (!proc || !proc.isRunning) {
242
194
  return;
243
195
  }
244
-
245
196
  _logger.default.info(`Shutting down '${name}' process (pid '${proc.proc.pid}')`);
246
-
247
197
  _logger.default.info(`Sending 'SIGTERM'...`);
248
-
249
198
  try {
250
199
  await proc.stop('SIGTERM', 1000);
251
200
  return;
@@ -253,19 +202,15 @@ async function killProcess(name, proc) {
253
202
  if (!err.message.includes(`Process didn't end after`)) {
254
203
  throw err;
255
204
  }
256
-
257
205
  _logger.default.debug(`${name} process did not end in a timely fashion: '${err.message}'.`);
258
206
  }
259
-
260
207
  _logger.default.info(`Sending 'SIGKILL'...`);
261
-
262
208
  try {
263
209
  await proc.stop('SIGKILL');
264
210
  } catch (err) {
265
211
  if (err.message.includes('not currently running')) {
266
212
  return;
267
213
  }
268
-
269
214
  throw err;
270
215
  }
271
216
  }
@@ -276,11 +221,9 @@ function randomInt(low, high) {
276
221
 
277
222
  async function getWDAUpgradeTimestamp() {
278
223
  const packageManifest = _path.default.resolve(getModuleRoot(), 'package.json');
279
-
280
224
  if (!(await _support.fs.exists(packageManifest))) {
281
225
  return null;
282
226
  }
283
-
284
227
  const {
285
228
  mtime
286
229
  } = await _support.fs.stat(packageManifest);
@@ -289,20 +232,16 @@ async function getWDAUpgradeTimestamp() {
289
232
 
290
233
  async function resetTestProcesses(udid, isSimulator) {
291
234
  const processPatterns = [`xcodebuild.*${udid}`];
292
-
293
235
  if (isSimulator) {
294
236
  processPatterns.push(`${udid}.*XCTRunner`);
295
237
  processPatterns.push(`xctest.*${udid}`);
296
238
  }
297
-
298
239
  _logger.default.debug(`Killing running processes '${processPatterns.join(', ')}' for the device ${udid}...`);
299
-
300
240
  await _bluebird.default.all(processPatterns.map(killAppUsingPattern));
301
241
  }
302
242
 
303
243
  async function getPIDsListeningOnPort(port, filteringFunc = null) {
304
244
  const result = [];
305
-
306
245
  try {
307
246
  const {
308
247
  stdout
@@ -312,17 +251,13 @@ async function getPIDsListeningOnPort(port, filteringFunc = null) {
312
251
  if (e.code !== 1) {
313
252
  _logger.default.debug(`Error getting processes listening on port '${port}': ${e.stderr || e.message}`);
314
253
  }
315
-
316
254
  return result;
317
255
  }
318
-
319
256
  if (!_lodash.default.isFunction(filteringFunc)) {
320
257
  return result;
321
258
  }
322
-
323
259
  return await _bluebird.default.filter(result, async pid => {
324
260
  let stdout;
325
-
326
261
  try {
327
262
  ({
328
263
  stdout
@@ -331,11 +266,9 @@ async function getPIDsListeningOnPort(port, filteringFunc = null) {
331
266
  if (e.code === 1) {
332
267
  return false;
333
268
  }
334
-
335
269
  throw e;
336
270
  }
337
-
338
271
  return await filteringFunc(stdout);
339
272
  });
340
273
  }
341
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQUk9KRUNUX0ZJTEUiLCJnZXRNb2R1bGVSb290IiwiXyIsIm1lbW9pemUiLCJjdXJyZW50RGlyIiwicGF0aCIsImRpcm5hbWUiLCJyZXNvbHZlIiwiX19maWxlbmFtZSIsImlzQXRGc1Jvb3QiLCJtYW5pZmVzdFBhdGgiLCJqb2luIiwiX2ZzIiwiZXhpc3RzU3luYyIsIkpTT04iLCJwYXJzZSIsInJlYWRGaWxlU3luYyIsIm5hbWUiLCJpZ24iLCJsZW5ndGgiLCJFcnJvciIsIkJPT1RTVFJBUF9QQVRIIiwiZ2V0UElEc1VzaW5nUGF0dGVybiIsInBhdHRlcm4iLCJhcmdzIiwic3Rkb3V0IiwiZXhlYyIsInNwbGl0IiwibWFwIiwieCIsInBhcnNlSW50IiwiZmlsdGVyIiwiaXNJbnRlZ2VyIiwiZXJyIiwibG9nIiwiZGVidWciLCJjb2RlIiwia2lsbEFwcFVzaW5nUGF0dGVybiIsInBncmVwUGF0dGVybiIsInNpZ25hbHMiLCJzaWduYWwiLCJtYXRjaGVkUGlkcyIsImlzRW1wdHkiLCJtZXNzYWdlIiwibGFzdCIsIndhaXRGb3JDb25kaXRpb24iLCJwaWRDaGVja1Byb21pc2VzIiwicGlkIiwidGhlbiIsImNhdGNoIiwiQiIsImFsbCIsImV2ZXJ5Iiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImlzVHZPUyIsInBsYXRmb3JtTmFtZSIsInRvTG93ZXIiLCJQTEFURk9STV9OQU1FX1RWT1MiLCJyZXBsYWNlSW5GaWxlIiwiZmlsZSIsImZpbmQiLCJyZXBsYWNlIiwiY29udGVudHMiLCJmcyIsInJlYWRGaWxlIiwibmV3Q29udGVudHMiLCJ3cml0ZUZpbGUiLCJ1cGRhdGVQcm9qZWN0RmlsZSIsImFnZW50UGF0aCIsIm5ld0J1bmRsZUlkIiwicHJvamVjdEZpbGVQYXRoIiwiY29weUZpbGUiLCJSZWdFeHAiLCJlc2NhcGVSZWdFeHAiLCJXREFfUlVOTkVSX0JVTkRMRV9JRCIsIndhcm4iLCJyZXNldFByb2plY3RGaWxlIiwiZXhpc3RzIiwibXYiLCJzZXRSZWFsRGV2aWNlU2VjdXJpdHkiLCJrZXljaGFpblBhdGgiLCJrZXljaGFpblBhc3N3b3JkIiwiZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUiLCJvcmdJZCIsInNpZ25pbmdJZCIsInhjY29uZmlnUGF0aCIsInRlbXBEaXIiLCJzZXRYY3Rlc3RydW5GaWxlIiwiZGV2aWNlSW5mbyIsInNka1ZlcnNpb24iLCJib290c3RyYXBQYXRoIiwid2RhUmVtb3RlUG9ydCIsInhjdGVzdHJ1bkZpbGVQYXRoIiwiZ2V0WGN0ZXN0cnVuRmlsZVBhdGgiLCJ4Y3Rlc3RSdW5Db250ZW50IiwicGxpc3QiLCJwYXJzZVBsaXN0RmlsZSIsInVwZGF0ZVdEQVBvcnQiLCJnZXRBZGRpdGlvbmFsUnVuQ29udGVudCIsIm5ld1hjdGVzdFJ1bkNvbnRlbnQiLCJtZXJnZSIsInVwZGF0ZVBsaXN0RmlsZSIsInJ1bm5lciIsIkVudmlyb25tZW50VmFyaWFibGVzIiwiVVNFX1BPUlQiLCJzZGtCYXNlZCIsInVkaWQiLCJwbGF0Zm9ybUJhc2VkIiwicGxhdGZvcm1WZXJzaW9uIiwiZmlsZVBhdGgiLCJ2ZXJzaW9uIiwiaW5mbyIsIm9yaWdpbmFsWGN0ZXN0cnVuRmlsZSIsImdldFhjdGVzdHJ1bkZpbGVOYW1lIiwiZXJyb3JBbmRUaHJvdyIsImlzUmVhbERldmljZSIsImtpbGxQcm9jZXNzIiwicHJvYyIsImlzUnVubmluZyIsInN0b3AiLCJpbmNsdWRlcyIsInJhbmRvbUludCIsImxvdyIsImhpZ2giLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJnZXRXREFVcGdyYWRlVGltZXN0YW1wIiwicGFja2FnZU1hbmlmZXN0IiwibXRpbWUiLCJzdGF0IiwiZ2V0VGltZSIsInJlc2V0VGVzdFByb2Nlc3NlcyIsImlzU2ltdWxhdG9yIiwicHJvY2Vzc1BhdHRlcm5zIiwicHVzaCIsImdldFBJRHNMaXN0ZW5pbmdPblBvcnQiLCJwb3J0IiwiZmlsdGVyaW5nRnVuYyIsInJlc3VsdCIsInRyaW0iLCJlIiwic3RkZXJyIiwiaXNGdW5jdGlvbiJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91dGlscy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmcywgdGVtcERpciwgcGxpc3QgfSBmcm9tICdhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgV0RBX1JVTk5FUl9CVU5ETEVfSUQsIFBMQVRGT1JNX05BTUVfVFZPUyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBfZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcblxuY29uc3QgUFJPSkVDVF9GSUxFID0gJ3Byb2plY3QucGJ4cHJvaic7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcGF0aCB0byB0aGUgY3VycmVudCBtb2R1bGUncyByb290IGZvbGRlclxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmdWxsIHBhdGggdG8gbW9kdWxlIHJvb3RcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgY3VycmVudCBtb2R1bGUgcm9vdCBmb2xkZXIgY2Fubm90IGJlIGRldGVybWluZWRcbiAqL1xuY29uc3QgZ2V0TW9kdWxlUm9vdCA9IF8ubWVtb2l6ZShmdW5jdGlvbiBnZXRNb2R1bGVSb290ICgpIHtcbiAgbGV0IGN1cnJlbnREaXIgPSBwYXRoLmRpcm5hbWUocGF0aC5yZXNvbHZlKF9fZmlsZW5hbWUpKTtcbiAgbGV0IGlzQXRGc1Jvb3QgPSBmYWxzZTtcbiAgd2hpbGUgKCFpc0F0RnNSb290KSB7XG4gICAgY29uc3QgbWFuaWZlc3RQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgICB0cnkge1xuICAgICAgaWYgKF9mcy5leGlzdHNTeW5jKG1hbmlmZXN0UGF0aCkgJiZcbiAgICAgICAgICBKU09OLnBhcnNlKF9mcy5yZWFkRmlsZVN5bmMobWFuaWZlc3RQYXRoLCAndXRmOCcpKS5uYW1lID09PSAnYXBwaXVtLXdlYmRyaXZlcmFnZW50Jykge1xuICAgICAgICByZXR1cm4gY3VycmVudERpcjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChpZ24pIHt9XG4gICAgY3VycmVudERpciA9IHBhdGguZGlybmFtZShjdXJyZW50RGlyKTtcbiAgICBpc0F0RnNSb290ID0gY3VycmVudERpci5sZW5ndGggPD0gcGF0aC5kaXJuYW1lKGN1cnJlbnREaXIpLmxlbmd0aDtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIHRoZSByb290IGZvbGRlciBvZiB0aGUgYXBwaXVtLXdlYmRyaXZlcmFnZW50IE5vZGUuanMgbW9kdWxlJyk7XG59KTtcblxuZXhwb3J0IGNvbnN0IEJPT1RTVFJBUF9QQVRIID0gZ2V0TW9kdWxlUm9vdCgpO1xuXG5hc3luYyBmdW5jdGlvbiBnZXRQSURzVXNpbmdQYXR0ZXJuIChwYXR0ZXJuKSB7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgJy1pZicsIC8vIGNhc2UgaW5zZW5zaXRpdmUsIGZ1bGwgY21kbGluZSBtYXRjaFxuICAgIHBhdHRlcm4sXG4gIF07XG4gIHRyeSB7XG4gICAgY29uc3Qge3N0ZG91dH0gPSBhd2FpdCBleGVjKCdwZ3JlcCcsIGFyZ3MpO1xuICAgIHJldHVybiBzdGRvdXQuc3BsaXQoL1xccysvKVxuICAgICAgLm1hcCgoeCkgPT4gcGFyc2VJbnQoeCwgMTApKVxuICAgICAgLmZpbHRlcihfLmlzSW50ZWdlcilcbiAgICAgIC5tYXAoKHgpID0+IGAke3h9YCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5kZWJ1ZyhgJ3BncmVwICR7YXJncy5qb2luKCcgJyl9JyBkaWRuJ3QgZGV0ZWN0IGFueSBtYXRjaGluZyBwcm9jZXNzZXMuIFJldHVybiBjb2RlOiAke2Vyci5jb2RlfWApO1xuICAgIHJldHVybiBbXTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBraWxsQXBwVXNpbmdQYXR0ZXJuIChwZ3JlcFBhdHRlcm4pIHtcbiAgY29uc3Qgc2lnbmFscyA9IFsyLCAxNSwgOV07XG4gIGZvciAoY29uc3Qgc2lnbmFsIG9mIHNpZ25hbHMpIHtcbiAgICBjb25zdCBtYXRjaGVkUGlkcyA9IGF3YWl0IGdldFBJRHNVc2luZ1BhdHRlcm4ocGdyZXBQYXR0ZXJuKTtcbiAgICBpZiAoXy5pc0VtcHR5KG1hdGNoZWRQaWRzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhcmdzID0gW2AtJHtzaWduYWx9YCwgLi4ubWF0Y2hlZFBpZHNdO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjKCdraWxsJywgYXJncyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2cuZGVidWcoYGtpbGwgJHthcmdzLmpvaW4oJyAnKX0gLT4gJHtlcnIubWVzc2FnZX1gKTtcbiAgICB9XG4gICAgaWYgKHNpZ25hbCA9PT0gXy5sYXN0KHNpZ25hbHMpKSB7XG4gICAgICAvLyB0aGVyZSBpcyBubyBuZWVkIHRvIHdhaXQgYWZ0ZXIgU0lHS0lMTFxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBpZENoZWNrUHJvbWlzZXMgPSBtYXRjaGVkUGlkc1xuICAgICAgICAgIC5tYXAoKHBpZCkgPT4gZXhlYygna2lsbCcsIFsnLTAnLCBwaWRdKVxuICAgICAgICAgICAgLy8gdGhlIHByb2Nlc3MgaXMgc3RpbGwgYWxpdmVcbiAgICAgICAgICAgIC50aGVuKCgpID0+IGZhbHNlKVxuICAgICAgICAgICAgLy8gdGhlIHByb2Nlc3MgaXMgZGVhZFxuICAgICAgICAgICAgLmNhdGNoKCgpID0+IHRydWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIChhd2FpdCBCLmFsbChwaWRDaGVja1Byb21pc2VzKSlcbiAgICAgICAgICAuZXZlcnkoKHgpID0+IHggPT09IHRydWUpO1xuICAgICAgfSwge1xuICAgICAgICB3YWl0TXM6IDEwMDAsXG4gICAgICAgIGludGVydmFsTXM6IDEwMCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGlnbikge1xuICAgICAgLy8gdHJ5IHRoZSBuZXh0IHNpZ25hbFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIHRoZSBwbGF0Zm9ybU5hbWUgaXMgdHZPU1xuICogQHBhcmFtIHtzdHJpbmd9IHBsYXRmb3JtTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGxhdG9ybVxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybiB0cnVlIGlmIHRoZSBwbGF0Zm9ybU5hbWUgaXMgdHZPU1xuICovXG5mdW5jdGlvbiBpc1R2T1MgKHBsYXRmb3JtTmFtZSkge1xuICByZXR1cm4gXy50b0xvd2VyKHBsYXRmb3JtTmFtZSkgPT09IF8udG9Mb3dlcihQTEFURk9STV9OQU1FX1RWT1MpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXBsYWNlSW5GaWxlIChmaWxlLCBmaW5kLCByZXBsYWNlKSB7XG4gIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGUsICd1dGY4Jyk7XG5cbiAgbGV0IG5ld0NvbnRlbnRzID0gY29udGVudHMucmVwbGFjZShmaW5kLCByZXBsYWNlKTtcbiAgaWYgKG5ld0NvbnRlbnRzICE9PSBjb250ZW50cykge1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShmaWxlLCBuZXdDb250ZW50cywgJ3V0ZjgnKTtcbiAgfVxufVxuXG4vKipcbiAqIFVwZGF0ZSBXZWJEcml2ZXJBZ2VudFJ1bm5lciBwcm9qZWN0IGJ1bmRsZSBJRCB3aXRoIG5ld0J1bmRsZUlkLlxuICogVGhpcyBtZXRob2QgYXNzdW1lcyBwcm9qZWN0IGZpbGUgaXMgaW4gdGhlIGNvcnJlY3Qgc3RhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gYWdlbnRQYXRoIC0gUGF0aCB0byB0aGUgLnhjb2RlcHJvaiBkaXJlY3RvcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmV3QnVuZGxlSWQgdGhlIG5ldyBidW5kbGUgSUQgdXNlZCB0byB1cGRhdGUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVByb2plY3RGaWxlIChhZ2VudFBhdGgsIG5ld0J1bmRsZUlkKSB7XG4gIGxldCBwcm9qZWN0RmlsZVBhdGggPSBwYXRoLnJlc29sdmUoYWdlbnRQYXRoLCBQUk9KRUNUX0ZJTEUpO1xuICB0cnkge1xuICAgIC8vIEFzc3VtaW5nIHByb2plY3RGaWxlUGF0aCBpcyBpbiB0aGUgY29ycmVjdCBzdGF0ZSwgY3JlYXRlIC5vbGQgZnJvbSBwcm9qZWN0RmlsZVBhdGhcbiAgICBhd2FpdCBmcy5jb3B5RmlsZShwcm9qZWN0RmlsZVBhdGgsIGAke3Byb2plY3RGaWxlUGF0aH0ub2xkYCk7XG4gICAgYXdhaXQgcmVwbGFjZUluRmlsZShwcm9qZWN0RmlsZVBhdGgsIG5ldyBSZWdFeHAoXy5lc2NhcGVSZWdFeHAoV0RBX1JVTk5FUl9CVU5ETEVfSUQpLCAnZycpLCBuZXdCdW5kbGVJZCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdXNlbGVzcy1lc2NhcGVcbiAgICBsb2cuZGVidWcoYFN1Y2Nlc3NmdWxseSB1cGRhdGVkICcke3Byb2plY3RGaWxlUGF0aH0nIHdpdGggYnVuZGxlIGlkICcke25ld0J1bmRsZUlkfSdgKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nLmRlYnVnKGBFcnJvciB1cGRhdGluZyBwcm9qZWN0IGZpbGU6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgbG9nLndhcm4oYFVuYWJsZSB0byB1cGRhdGUgcHJvamVjdCBmaWxlICcke3Byb2plY3RGaWxlUGF0aH0nIHdpdGggYCArXG4gICAgICBgYnVuZGxlIGlkICcke25ld0J1bmRsZUlkfScuIFdlYkRyaXZlckFnZW50IG1heSBub3Qgc3RhcnRgKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc2V0IFdlYkRyaXZlckFnZW50UnVubmVyIHByb2plY3QgYnVuZGxlIElEIHRvIGNvcnJlY3Qgc3RhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gYWdlbnRQYXRoIC0gUGF0aCB0byB0aGUgLnhjb2RlcHJvaiBkaXJlY3RvcnkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc2V0UHJvamVjdEZpbGUgKGFnZW50UGF0aCkge1xuICBjb25zdCBwcm9qZWN0RmlsZVBhdGggPSBwYXRoLmpvaW4oYWdlbnRQYXRoLCBQUk9KRUNUX0ZJTEUpO1xuICB0cnkge1xuICAgIC8vIHJlc3RvcmUgcHJvamVjdEZpbGVQYXRoIGZyb20gLm9sZCBmaWxlXG4gICAgaWYgKCFhd2FpdCBmcy5leGlzdHMoYCR7cHJvamVjdEZpbGVQYXRofS5vbGRgKSkge1xuICAgICAgcmV0dXJuOyAvLyBubyBuZWVkIHRvIHJlc2V0XG4gICAgfVxuICAgIGF3YWl0IGZzLm12KGAke3Byb2plY3RGaWxlUGF0aH0ub2xkYCwgcHJvamVjdEZpbGVQYXRoKTtcbiAgICBsb2cuZGVidWcoYFN1Y2Nlc3NmdWxseSByZXNldCAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGJ1bmRsZSBpZCAnJHtXREFfUlVOTkVSX0JVTkRMRV9JRH0nYCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5kZWJ1ZyhgRXJyb3IgcmVzZXR0aW5nIHByb2plY3QgZmlsZTogJHtlcnIubWVzc2FnZX1gKTtcbiAgICBsb2cud2FybihgVW5hYmxlIHRvIHJlc2V0IHByb2plY3QgZmlsZSAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGAgK1xuICAgICAgYGJ1bmRsZSBpZCAnJHtXREFfUlVOTkVSX0JVTkRMRV9JRH0nLiBXZWJEcml2ZXJBZ2VudCBoYXMgYmVlbiBgICtcbiAgICAgIGBtb2RpZmllZCBhbmQgbm90IHJldHVybmVkIHRvIHRoZSBvcmlnaW5hbCBzdGF0ZS5gKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRSZWFsRGV2aWNlU2VjdXJpdHkgKGtleWNoYWluUGF0aCwga2V5Y2hhaW5QYXNzd29yZCkge1xuICBsb2cuZGVidWcoJ1NldHRpbmcgc2VjdXJpdHkgZm9yIGlPUyBkZXZpY2UnKTtcbiAgYXdhaXQgZXhlYygnc2VjdXJpdHknLCBbJy12JywgJ2xpc3Qta2V5Y2hhaW5zJywgJy1zJywga2V5Y2hhaW5QYXRoXSk7XG4gIGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWyctdicsICd1bmxvY2sta2V5Y2hhaW4nLCAnLXAnLCBrZXljaGFpblBhc3N3b3JkLCBrZXljaGFpblBhdGhdKTtcbiAgYXdhaXQgZXhlYygnc2VjdXJpdHknLCBbJ3NldC1rZXljaGFpbi1zZXR0aW5ncycsICctdCcsICczNjAwJywgJy1sJywga2V5Y2hhaW5QYXRoXSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlWGNvZGVDb25maWdGaWxlIChvcmdJZCwgc2lnbmluZ0lkKSB7XG4gIGxvZy5kZWJ1ZyhgR2VuZXJhdGluZyB4Y29kZSBjb25maWcgZmlsZSBmb3Igb3JnSWQgJyR7b3JnSWR9JyBhbmQgc2lnbmluZ0lkIGAgK1xuICAgICAgICAgICAgYCcke3NpZ25pbmdJZH0nYCk7XG4gIGNvbnN0IGNvbnRlbnRzID0gYERFVkVMT1BNRU5UX1RFQU0gPSAke29yZ0lkfVxuQ09ERV9TSUdOX0lERU5USVRZID0gJHtzaWduaW5nSWR9XG5gO1xuICBjb25zdCB4Y2NvbmZpZ1BhdGggPSBhd2FpdCB0ZW1wRGlyLnBhdGgoJ2FwcGl1bS10ZW1wLnhjY29uZmlnJyk7XG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyB4Y29kZSBjb25maWcgZmlsZSB0byAke3hjY29uZmlnUGF0aH1gKTtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKHhjY29uZmlnUGF0aCwgY29udGVudHMsICd1dGY4Jyk7XG4gIHJldHVybiB4Y2NvbmZpZ1BhdGg7XG59XG5cbi8qKlxuICogSW5mb3JtYXRpb24gb2YgdGhlIGRldmljZSB1bmRlciB0ZXN0XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEZXZpY2VJbmZvXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaXNSZWFsRGV2aWNlIC0gRXF1YWxzIHRvIHRydWUgaWYgdGhlIGN1cnJlbnQgZGV2aWNlIGlzIGEgcmVhbCBkZXZpY2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1ZGlkIC0gVGhlIGRldmljZSBVRElELlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHBsYXRmb3JtVmVyc2lvbiAtIFRoZSBwbGF0Zm9ybSB2ZXJzaW9uIG9mIE9TLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHBsYXRmb3JtTmFtZSAtIFRoZSBwbGF0Zm9ybSBuYW1lIG9mIGlPUywgdHZPU1xuKi9cbi8qKlxuICogQ3JlYXRlcyB4Y3Rlc3RydW4gZmlsZSBwZXIgZGV2aWNlICYgcGxhdGZvcm0gdmVyc2lvbi5cbiAqIFdlIGV4cGVjdHMgdG8gaGF2ZSBXZWJEcml2ZXJBZ2VudFJ1bm5lcl9pcGhvbmVvcyR7c2RrVmVyc2lvbnxwbGF0Zm9ybVZlcnNpb259LWFybTY0LnhjdGVzdHJ1biBmb3IgcmVhbCBkZXZpY2VcbiAqIGFuZCBXZWJEcml2ZXJBZ2VudFJ1bm5lcl9pcGhvbmVzaW11bGF0b3Ike3Nka1ZlcnNpb258cGxhdGZvcm1WZXJzaW9ufS14ODZfNjQueGN0ZXN0cnVuIGZvciBzaW11bGF0b3IgbG9jYXRlZCBAYm9vdHN0cmFwUGF0aFxuICogTmV3ZXIgWGNvZGUgKFhjb2RlIDEwLjAgYXQgbGVhc3QpIGdlbmVyYXRlIHhjdGVzdHJ1biBmaWxlIGZvbGxvd2luZyBzZGtWZXJzaW9uLlxuICogZS5nLiBYY29kZSB3aGljaCBoYXMgaU9TIFNESyBWZXJzaW9uIDEyLjIgZ2VuZXJhdGUgV2ViRHJpdmVyQWdlbnRSdW5uZXJfaXBob25lc2ltdWxhdG9yLjIteDg2XzY0LnhjdGVzdHJ1blxuICogICAgICBldmVuIGlmIHRoZSBjYXAgaGFzIHBsYXRmb3JtIHZlcnNpb24gMTEuNFxuICpcbiAqIEBwYXJhbSB7RGV2aWNlSW5mb30gZGV2aWNlSW5mb1xuICogQHBhcmFtIHtzdHJpbmd9IHNka1ZlcnNpb24gLSBUaGUgWGNvZGUgU0RLIHZlcnNpb24gb2YgT1MuXG4gKiBAcGFyYW0ge3N0cmluZ30gYm9vdHN0cmFwUGF0aCAtIFRoZSBmb2xkZXIgcGF0aCBjb250YWluaW5nIHhjdGVzdHJ1biBmaWxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHdkYVJlbW90ZVBvcnQgLSBUaGUgcmVtb3RlIHBvcnQgV0RBIGlzIGxpc3RlbmluZyBvbi5cbiAqIEByZXR1cm4ge3N0cmluZ30gcmV0dXJucyB4Y3Rlc3RydW5GaWxlUGF0aCBmb3IgZ2l2ZW4gZGV2aWNlXG4gKiBAdGhyb3dzIGlmIFdlYkRyaXZlckFnZW50UnVubmVyX2lwaG9uZW9zJHtzZGtWZXJzaW9ufHBsYXRmb3JtVmVyc2lvbn0tYXJtNjQueGN0ZXN0cnVuIGZvciByZWFsIGRldmljZVxuICogb3IgV2ViRHJpdmVyQWdlbnRSdW5uZXJfaXBob25lc2ltdWxhdG9yJHtzZGtWZXJzaW9ufHBsYXRmb3JtVmVyc2lvbn0teDg2XzY0LnhjdGVzdHJ1biBmb3Igc2ltdWxhdG9yIGlzIG5vdCBmb3VuZCBAYm9vdHN0cmFwUGF0aCxcbiAqIHRoZW4gaXQgd2lsbCB0aHJvdyBmaWxlIG5vdCBmb3VuZCBleGNlcHRpb25cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2V0WGN0ZXN0cnVuRmlsZSAoZGV2aWNlSW5mbywgc2RrVmVyc2lvbiwgYm9vdHN0cmFwUGF0aCwgd2RhUmVtb3RlUG9ydCkge1xuICBjb25zdCB4Y3Rlc3RydW5GaWxlUGF0aCA9IGF3YWl0IGdldFhjdGVzdHJ1bkZpbGVQYXRoKGRldmljZUluZm8sIHNka1ZlcnNpb24sIGJvb3RzdHJhcFBhdGgpO1xuICBjb25zdCB4Y3Rlc3RSdW5Db250ZW50ID0gYXdhaXQgcGxpc3QucGFyc2VQbGlzdEZpbGUoeGN0ZXN0cnVuRmlsZVBhdGgpO1xuICBjb25zdCB1cGRhdGVXREFQb3J0ID0gZ2V0QWRkaXRpb25hbFJ1bkNvbnRlbnQoZGV2aWNlSW5mby5wbGF0Zm9ybU5hbWUsIHdkYVJlbW90ZVBvcnQpO1xuICBjb25zdCBuZXdYY3Rlc3RSdW5Db250ZW50ID0gXy5tZXJnZSh4Y3Rlc3RSdW5Db250ZW50LCB1cGRhdGVXREFQb3J0KTtcbiAgYXdhaXQgcGxpc3QudXBkYXRlUGxpc3RGaWxlKHhjdGVzdHJ1bkZpbGVQYXRoLCBuZXdYY3Rlc3RSdW5Db250ZW50LCB0cnVlKTtcblxuICByZXR1cm4geGN0ZXN0cnVuRmlsZVBhdGg7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBXREEgb2JqZWN0IHdoaWNoIGFwcGVuZHMgZXhpc3RpbmcgeGN0ZXN0IHJ1bm5lciBjb250ZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gcGxhdGZvcm1OYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHBsYXRmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvbiAtIFRoZSBYY29kZSBTREsgdmVyc2lvbiBvZiBPUy5cbiAqIEByZXR1cm4ge29iamVjdH0gcmV0dXJucyBhIHJ1bm5lciBvYmplY3Qgd2hpY2ggaGFzIFVTRV9QT1JUXG4gKi9cbmZ1bmN0aW9uIGdldEFkZGl0aW9uYWxSdW5Db250ZW50IChwbGF0Zm9ybU5hbWUsIHdkYVJlbW90ZVBvcnQpIHtcbiAgY29uc3QgcnVubmVyID0gYFdlYkRyaXZlckFnZW50UnVubmVyJHtpc1R2T1MocGxhdGZvcm1OYW1lKSA/ICdfdHZPUycgOiAnJ31gO1xuXG4gIHJldHVybiB7XG4gICAgW3J1bm5lcl06IHtcbiAgICAgIEVudmlyb25tZW50VmFyaWFibGVzOiB7XG4gICAgICAgIC8vIFVTRV9QT1JUIG11c3QgYmUgJ3N0cmluZydcbiAgICAgICAgVVNFX1BPUlQ6IGAke3dkYVJlbW90ZVBvcnR9YFxuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHBhdGggb2YgeGN0ZXN0cnVuIGlmIGl0IGV4aXN0c1xuICogQHBhcmFtIHtEZXZpY2VJbmZvfSBkZXZpY2VJbmZvXG4gKiBAcGFyYW0ge3N0cmluZ30gc2RrVmVyc2lvbiAtIFRoZSBYY29kZSBTREsgdmVyc2lvbiBvZiBPUy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBib290c3RyYXBQYXRoIC0gVGhlIGZvbGRlciBwYXRoIGNvbnRhaW5pbmcgeGN0ZXN0cnVuIGZpbGUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFhjdGVzdHJ1bkZpbGVQYXRoIChkZXZpY2VJbmZvLCBzZGtWZXJzaW9uLCBib290c3RyYXBQYXRoKSB7XG4gIC8vIEZpcnN0IHRyeSB0aGUgU0RLIHBhdGgsIGZvciBYY29kZSAxMCAoYXQgbGVhc3QpXG4gIGNvbnN0IHNka0Jhc2VkID0gW1xuICAgIHBhdGgucmVzb2x2ZShib290c3RyYXBQYXRoLCBgJHtkZXZpY2VJbmZvLnVkaWR9XyR7c2RrVmVyc2lvbn0ueGN0ZXN0cnVuYCksXG4gICAgc2RrVmVyc2lvbixcbiAgXTtcbiAgLy8gTmV4dCB0cnkgUGxhdGZvcm0gcGF0aCwgZm9yIGVhcmxpZXIgWGNvZGUgdmVyc2lvbnNcbiAgY29uc3QgcGxhdGZvcm1CYXNlZCA9IFtcbiAgICBwYXRoLnJlc29sdmUoYm9vdHN0cmFwUGF0aCwgYCR7ZGV2aWNlSW5mby51ZGlkfV8ke2RldmljZUluZm8ucGxhdGZvcm1WZXJzaW9ufS54Y3Rlc3RydW5gKSxcbiAgICBkZXZpY2VJbmZvLnBsYXRmb3JtVmVyc2lvbixcbiAgXTtcblxuICBmb3IgKGNvbnN0IFtmaWxlUGF0aCwgdmVyc2lvbl0gb2YgW3Nka0Jhc2VkLCBwbGF0Zm9ybUJhc2VkXSkge1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMoZmlsZVBhdGgpKSB7XG4gICAgICBsb2cuaW5mbyhgVXNpbmcgJyR7ZmlsZVBhdGh9JyBhcyB4Y3Rlc3RydW4gZmlsZWApO1xuICAgICAgcmV0dXJuIGZpbGVQYXRoO1xuICAgIH1cbiAgICBjb25zdCBvcmlnaW5hbFhjdGVzdHJ1bkZpbGUgPSBwYXRoLnJlc29sdmUoYm9vdHN0cmFwUGF0aCwgZ2V0WGN0ZXN0cnVuRmlsZU5hbWUoZGV2aWNlSW5mbywgdmVyc2lvbikpO1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMob3JpZ2luYWxYY3Rlc3RydW5GaWxlKSkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBmaXJzdCB0aW1lIHJ1biBmb3IgZ2l2ZW4gZGV2aWNlLCB0aGVuIGZpcnN0IGdlbmVyYXRlIHhjdGVzdHJ1biBmaWxlIGZvciBkZXZpY2UuXG4gICAgICAvLyBXZSBuZWVkIHRvIGhhdmUgYSB4Y3Rlc3RydW4gZmlsZSAqKnBlciBkZXZpY2UqKiBiZWNhdXNlIHdlIGNhbnQgbm90IGhhdmUgc2FtZSB3ZGEgcG9ydCBmb3IgYWxsIGRldmljZXMuXG4gICAgICBhd2FpdCBmcy5jb3B5RmlsZShvcmlnaW5hbFhjdGVzdHJ1bkZpbGUsIGZpbGVQYXRoKTtcbiAgICAgIGxvZy5pbmZvKGBVc2luZyAnJHtmaWxlUGF0aH0nIGFzIHhjdGVzdHJ1biBmaWxlIGNvcGllZCBieSAnJHtvcmlnaW5hbFhjdGVzdHJ1bkZpbGV9J2ApO1xuICAgICAgcmV0dXJuIGZpbGVQYXRoO1xuICAgIH1cbiAgfVxuXG4gIGxvZy5lcnJvckFuZFRocm93KGBJZiB5b3UgYXJlIHVzaW5nICd1c2VYY3Rlc3RydW5GaWxlJyBjYXBhYmlsaXR5IHRoZW4geW91IGAgK1xuICAgIGBuZWVkIHRvIGhhdmUgYSB4Y3Rlc3RydW4gZmlsZSAoZXhwZWN0ZWQ6IGAgK1xuICAgIGAnJHtwYXRoLnJlc29sdmUoYm9vdHN0cmFwUGF0aCwgZ2V0WGN0ZXN0cnVuRmlsZU5hbWUoZGV2aWNlSW5mbywgc2RrVmVyc2lvbikpfScpYCk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIG5hbWUgb2YgeGN0ZXN0cnVuIGZpbGVcbiAqIEBwYXJhbSB7RGV2aWNlSW5mb30gZGV2aWNlSW5mb1xuICogQHBhcmFtIHtzdHJpbmd9IHZlcnNpb24gLSBUaGUgWGNvZGUgU0RLIHZlcnNpb24gb2YgT1MuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHJldHVybnMgeGN0ZXN0cnVuRmlsZVBhdGggZm9yIGdpdmVuIGRldmljZVxuICovXG5mdW5jdGlvbiBnZXRYY3Rlc3RydW5GaWxlTmFtZSAoZGV2aWNlSW5mbywgdmVyc2lvbikge1xuICByZXR1cm4gaXNUdk9TKGRldmljZUluZm8ucGxhdGZvcm1OYW1lKVxuICAgID8gYFdlYkRyaXZlckFnZW50UnVubmVyX3R2T1NfYXBwbGV0diR7ZGV2aWNlSW5mby5pc1JlYWxEZXZpY2UgPyBgb3Mke3ZlcnNpb259LWFybTY0YCA6IGBzaW11bGF0b3Ike3ZlcnNpb259LXg4Nl82NGB9LnhjdGVzdHJ1bmBcbiAgICA6IGBXZWJEcml2ZXJBZ2VudFJ1bm5lcl9pcGhvbmUke2RldmljZUluZm8uaXNSZWFsRGV2aWNlID8gYG9zJHt2ZXJzaW9ufS1hcm02NGAgOiBgc2ltdWxhdG9yJHt2ZXJzaW9ufS14ODZfNjRgfS54Y3Rlc3RydW5gO1xufVxuXG5hc3luYyBmdW5jdGlvbiBraWxsUHJvY2VzcyAobmFtZSwgcHJvYykge1xuICBpZiAoIXByb2MgfHwgIXByb2MuaXNSdW5uaW5nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbG9nLmluZm8oYFNodXR0aW5nIGRvd24gJyR7bmFtZX0nIHByb2Nlc3MgKHBpZCAnJHtwcm9jLnByb2MucGlkfScpYCk7XG5cbiAgbG9nLmluZm8oYFNlbmRpbmcgJ1NJR1RFUk0nLi4uYCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgcHJvYy5zdG9wKCdTSUdURVJNJywgMTAwMCk7XG4gICAgcmV0dXJuO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBpZiAoIWVyci5tZXNzYWdlLmluY2x1ZGVzKGBQcm9jZXNzIGRpZG4ndCBlbmQgYWZ0ZXJgKSkge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICBsb2cuZGVidWcoYCR7bmFtZX0gcHJvY2VzcyBkaWQgbm90IGVuZCBpbiBhIHRpbWVseSBmYXNoaW9uOiAnJHtlcnIubWVzc2FnZX0nLmApO1xuICB9XG5cbiAgbG9nLmluZm8oYFNlbmRpbmcgJ1NJR0tJTEwnLi4uYCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgcHJvYy5zdG9wKCdTSUdLSUxMJyk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChlcnIubWVzc2FnZS5pbmNsdWRlcygnbm90IGN1cnJlbnRseSBydW5uaW5nJykpIHtcbiAgICAgIC8vIHRoZSBwcm9jZXNzIGVuZGVkIGJ1dCBmb3Igc29tZSByZWFzb24gd2Ugd2VyZSBub3QgaW5mb3JtZWRcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSByYW5kb20gaW50ZWdlci5cbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEEgcmFuZG9tIGludGVnZXIgbnVtYmVyIGluIHJhbmdlIFtsb3csIGhpZ2h0KS4gYGxvd2BgIGlzIGluY2x1c2l2ZSBhbmQgYGhpZ2hgIGlzIGV4Y2x1c2l2ZS5cbiAqL1xuZnVuY3Rpb24gcmFuZG9tSW50IChsb3csIGhpZ2gpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChoaWdoIC0gbG93KSArIGxvdyk7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIFdEQSB1cGdyYWRlIHRpbWVzdGFtcFxuICpcbiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSBVTklYIHRpbWVzdGFtcCBvZiB0aGUgcGFja2FnZSBtYW5pZmVzdC4gVGhlIG1hbmlmZXN0IG9ubHkgZ2V0cyBtb2RpZmllZCBvblxuICogcGFja2FnZSB1cGdyYWRlLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRXREFVcGdyYWRlVGltZXN0YW1wICgpIHtcbiAgY29uc3QgcGFja2FnZU1hbmlmZXN0ID0gcGF0aC5yZXNvbHZlKGdldE1vZHVsZVJvb3QoKSwgJ3BhY2thZ2UuanNvbicpO1xuICBpZiAoIWF3YWl0IGZzLmV4aXN0cyhwYWNrYWdlTWFuaWZlc3QpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qge210aW1lfSA9IGF3YWl0IGZzLnN0YXQocGFja2FnZU1hbmlmZXN0KTtcbiAgcmV0dXJuIG10aW1lLmdldFRpbWUoKTtcbn1cblxuLyoqXG4gKiBLaWxscyBydW5uaW5nIFhDVGVzdCBwcm9jZXNzZXMgZm9yIHRoZSBwYXJ0aWN1bGFyIGRldmljZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdWRpZCAtIFRoZSBkZXZpY2UgVURJRC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNTaW11bGF0b3IgLSBFcXVhbHMgdG8gdHJ1ZSBpZiB0aGUgY3VycmVudCBkZXZpY2UgaXMgYSBTaW11bGF0b3JcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzZXRUZXN0UHJvY2Vzc2VzICh1ZGlkLCBpc1NpbXVsYXRvcikge1xuICBjb25zdCBwcm9jZXNzUGF0dGVybnMgPSBbYHhjb2RlYnVpbGQuKiR7dWRpZH1gXTtcbiAgaWYgKGlzU2ltdWxhdG9yKSB7XG4gICAgcHJvY2Vzc1BhdHRlcm5zLnB1c2goYCR7dWRpZH0uKlhDVFJ1bm5lcmApO1xuICAgIC8vIFRoZSBwYXR0ZXJuIHRvIGZpbmQgaW4gY2FzZSBpZGIgd2FzIHVzZWRcbiAgICBwcm9jZXNzUGF0dGVybnMucHVzaChgeGN0ZXN0Lioke3VkaWR9YCk7XG4gIH1cbiAgbG9nLmRlYnVnKGBLaWxsaW5nIHJ1bm5pbmcgcHJvY2Vzc2VzICcke3Byb2Nlc3NQYXR0ZXJucy5qb2luKCcsICcpfScgZm9yIHRoZSBkZXZpY2UgJHt1ZGlkfS4uLmApO1xuICBhd2FpdCBCLmFsbChwcm9jZXNzUGF0dGVybnMubWFwKGtpbGxBcHBVc2luZ1BhdHRlcm4pKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIElEcyBvZiBwcm9jZXNzZXMgbGlzdGVuaW5nIG9uIHRoZSBwYXJ0aWN1bGFyIHN5c3RlbSBwb3J0LlxuICogSXQgaXMgYWxzbyBwb3NzaWJsZSB0byBhcHBseSBhZGRpdGlvbmFsIGZpbHRlcmluZyBiYXNlZCBvbiB0aGVcbiAqIHByb2Nlc3MgY29tbWFuZCBsaW5lLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gcG9ydCAtIFRoZSBwb3J0IG51bWJlci5cbiAqIEBwYXJhbSB7P0Z1bmN0aW9ufSBmaWx0ZXJpbmdGdW5jIC0gT3B0aW9uYWwgbGFtYmRhIGZ1bmN0aW9uLCB3aGljaFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlcyBjb21tYW5kIGxpbmUgc3RyaW5nIG9mIHRoZSBwYXJ0aWN1bGFyIHByb2Nlc3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuaW5nIG9uIGdpdmVuIHBvcnQsIGFuZCBpcyBleHBlY3RlZCB0byByZXR1cm5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWl0aGVyIHRydWUgb3IgZmFsc2UgdG8gaW5jbHVkZS9leGNsdWRlIHRoZSBjb3JyZXNwb25kaW5nIFBJRFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tIHRoZSByZXN1bHRpbmcgYXJyYXkuXG4gKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gLSB0aGUgbGlzdCBvZiBtYXRjaGVkIHByb2Nlc3MgaWRzLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRQSURzTGlzdGVuaW5nT25Qb3J0IChwb3J0LCBmaWx0ZXJpbmdGdW5jID0gbnVsbCkge1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgdHJ5IHtcbiAgICAvLyBUaGlzIG9ubHkgd29ya3Mgc2luY2UgTWFjIE9TIFggRWwgQ2FwaXRhblxuICAgIGNvbnN0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYygnbHNvZicsIFsnLXRpJywgYHRjcDoke3BvcnR9YF0pO1xuICAgIHJlc3VsdC5wdXNoKC4uLihzdGRvdXQudHJpbSgpLnNwbGl0KC9cXG4rLykpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlLmNvZGUgIT09IDEpIHtcbiAgICAgIC8vIGNvZGUgMSBtZWFucyBubyBwcm9jZXNzZXMuIE90aGVyIGVycm9ycyBuZWVkIHJlcG9ydGluZ1xuICAgICAgbG9nLmRlYnVnKGBFcnJvciBnZXR0aW5nIHByb2Nlc3NlcyBsaXN0ZW5pbmcgb24gcG9ydCAnJHtwb3J0fSc6ICR7ZS5zdGRlcnIgfHwgZS5tZXNzYWdlfWApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKCFfLmlzRnVuY3Rpb24oZmlsdGVyaW5nRnVuYykpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHJldHVybiBhd2FpdCBCLmZpbHRlcihyZXN1bHQsIGFzeW5jIChwaWQpID0+IHtcbiAgICBsZXQgc3Rkb3V0O1xuICAgIHRyeSB7XG4gICAgICAoe3N0ZG91dH0gPSBhd2FpdCBleGVjKCdwcycsIFsnLXAnLCBwaWQsICctbycsICdjb21tYW5kJ10pKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZS5jb2RlID09PSAxKSB7XG4gICAgICAgIC8vIFRoZSBwcm9jZXNzIGRvZXMgbm90IGV4aXN0IGFueW1vcmUsIHRoZXJlJ3Mgbm90aGluZyB0byBmaWx0ZXJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgcmV0dXJuIGF3YWl0IGZpbHRlcmluZ0Z1bmMoc3Rkb3V0KTtcbiAgfSk7XG59XG5cbmV4cG9ydCB7IHVwZGF0ZVByb2plY3RGaWxlLCByZXNldFByb2plY3RGaWxlLCBzZXRSZWFsRGV2aWNlU2VjdXJpdHksXG4gIGdldEFkZGl0aW9uYWxSdW5Db250ZW50LCBnZXRYY3Rlc3RydW5GaWxlTmFtZSwgZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUsXG4gIHNldFhjdGVzdHJ1bkZpbGUsIGdldFhjdGVzdHJ1bkZpbGVQYXRoLCBraWxsUHJvY2VzcywgcmFuZG9tSW50LFxuICBnZXRXREFVcGdyYWRlVGltZXN0YW1wLCByZXNldFRlc3RQcm9jZXNzZXMsXG4gIGdldFBJRHNMaXN0ZW5pbmdPblBvcnQsIGtpbGxBcHBVc2luZ1BhdHRlcm4sIGlzVHZPU1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxNQUFNQSxZQUFZLEdB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
274
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQUk9KRUNUX0ZJTEUiLCJnZXRNb2R1bGVSb290IiwiXyIsIm1lbW9pemUiLCJjdXJyZW50RGlyIiwicGF0aCIsImRpcm5hbWUiLCJyZXNvbHZlIiwiX19maWxlbmFtZSIsImlzQXRGc1Jvb3QiLCJtYW5pZmVzdFBhdGgiLCJqb2luIiwiX2ZzIiwiZXhpc3RzU3luYyIsIkpTT04iLCJwYXJzZSIsInJlYWRGaWxlU3luYyIsIm5hbWUiLCJpZ24iLCJsZW5ndGgiLCJFcnJvciIsIkJPT1RTVFJBUF9QQVRIIiwiZ2V0UElEc1VzaW5nUGF0dGVybiIsInBhdHRlcm4iLCJhcmdzIiwic3Rkb3V0IiwiZXhlYyIsInNwbGl0IiwibWFwIiwieCIsInBhcnNlSW50IiwiZmlsdGVyIiwiaXNJbnRlZ2VyIiwiZXJyIiwibG9nIiwiZGVidWciLCJjb2RlIiwia2lsbEFwcFVzaW5nUGF0dGVybiIsInBncmVwUGF0dGVybiIsInNpZ25hbHMiLCJzaWduYWwiLCJtYXRjaGVkUGlkcyIsImlzRW1wdHkiLCJtZXNzYWdlIiwibGFzdCIsIndhaXRGb3JDb25kaXRpb24iLCJwaWRDaGVja1Byb21pc2VzIiwicGlkIiwidGhlbiIsImNhdGNoIiwiQiIsImFsbCIsImV2ZXJ5Iiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImlzVHZPUyIsInBsYXRmb3JtTmFtZSIsInRvTG93ZXIiLCJQTEFURk9STV9OQU1FX1RWT1MiLCJyZXBsYWNlSW5GaWxlIiwiZmlsZSIsImZpbmQiLCJyZXBsYWNlIiwiY29udGVudHMiLCJmcyIsInJlYWRGaWxlIiwibmV3Q29udGVudHMiLCJ3cml0ZUZpbGUiLCJ1cGRhdGVQcm9qZWN0RmlsZSIsImFnZW50UGF0aCIsIm5ld0J1bmRsZUlkIiwicHJvamVjdEZpbGVQYXRoIiwiY29weUZpbGUiLCJSZWdFeHAiLCJlc2NhcGVSZWdFeHAiLCJXREFfUlVOTkVSX0JVTkRMRV9JRCIsIndhcm4iLCJyZXNldFByb2plY3RGaWxlIiwiZXhpc3RzIiwibXYiLCJzZXRSZWFsRGV2aWNlU2VjdXJpdHkiLCJrZXljaGFpblBhdGgiLCJrZXljaGFpblBhc3N3b3JkIiwiZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUiLCJvcmdJZCIsInNpZ25pbmdJZCIsInhjY29uZmlnUGF0aCIsInRlbXBEaXIiLCJzZXRYY3Rlc3RydW5GaWxlIiwiZGV2aWNlSW5mbyIsInNka1ZlcnNpb24iLCJib290c3RyYXBQYXRoIiwid2RhUmVtb3RlUG9ydCIsInhjdGVzdHJ1bkZpbGVQYXRoIiwiZ2V0WGN0ZXN0cnVuRmlsZVBhdGgiLCJ4Y3Rlc3RSdW5Db250ZW50IiwicGxpc3QiLCJwYXJzZVBsaXN0RmlsZSIsInVwZGF0ZVdEQVBvcnQiLCJnZXRBZGRpdGlvbmFsUnVuQ29udGVudCIsIm5ld1hjdGVzdFJ1bkNvbnRlbnQiLCJtZXJnZSIsInVwZGF0ZVBsaXN0RmlsZSIsInJ1bm5lciIsIkVudmlyb25tZW50VmFyaWFibGVzIiwiVVNFX1BPUlQiLCJzZGtCYXNlZCIsInVkaWQiLCJwbGF0Zm9ybUJhc2VkIiwicGxhdGZvcm1WZXJzaW9uIiwiZmlsZVBhdGgiLCJ2ZXJzaW9uIiwiaW5mbyIsIm9yaWdpbmFsWGN0ZXN0cnVuRmlsZSIsImdldFhjdGVzdHJ1bkZpbGVOYW1lIiwiZXJyb3JBbmRUaHJvdyIsImlzUmVhbERldmljZSIsImtpbGxQcm9jZXNzIiwicHJvYyIsImlzUnVubmluZyIsInN0b3AiLCJpbmNsdWRlcyIsInJhbmRvbUludCIsImxvdyIsImhpZ2giLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJnZXRXREFVcGdyYWRlVGltZXN0YW1wIiwicGFja2FnZU1hbmlmZXN0IiwibXRpbWUiLCJzdGF0IiwiZ2V0VGltZSIsInJlc2V0VGVzdFByb2Nlc3NlcyIsImlzU2ltdWxhdG9yIiwicHJvY2Vzc1BhdHRlcm5zIiwicHVzaCIsImdldFBJRHNMaXN0ZW5pbmdPblBvcnQiLCJwb3J0IiwiZmlsdGVyaW5nRnVuYyIsInJlc3VsdCIsInRyaW0iLCJlIiwic3RkZXJyIiwiaXNGdW5jdGlvbiJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91dGlscy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmcywgdGVtcERpciwgcGxpc3QgfSBmcm9tICdhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgV0RBX1JVTk5FUl9CVU5ETEVfSUQsIFBMQVRGT1JNX05BTUVfVFZPUyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBfZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcblxuY29uc3QgUFJPSkVDVF9GSUxFID0gJ3Byb2plY3QucGJ4cHJvaic7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcGF0aCB0byB0aGUgY3VycmVudCBtb2R1bGUncyByb290IGZvbGRlclxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmdWxsIHBhdGggdG8gbW9kdWxlIHJvb3RcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgY3VycmVudCBtb2R1bGUgcm9vdCBmb2xkZXIgY2Fubm90IGJlIGRldGVybWluZWRcbiAqL1xuY29uc3QgZ2V0TW9kdWxlUm9vdCA9IF8ubWVtb2l6ZShmdW5jdGlvbiBnZXRNb2R1bGVSb290ICgpIHtcbiAgbGV0IGN1cnJlbnREaXIgPSBwYXRoLmRpcm5hbWUocGF0aC5yZXNvbHZlKF9fZmlsZW5hbWUpKTtcbiAgbGV0IGlzQXRGc1Jvb3QgPSBmYWxzZTtcbiAgd2hpbGUgKCFpc0F0RnNSb290KSB7XG4gICAgY29uc3QgbWFuaWZlc3RQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgICB0cnkge1xuICAgICAgaWYgKF9mcy5leGlzdHNTeW5jKG1hbmlmZXN0UGF0aCkgJiZcbiAgICAgICAgICBKU09OLnBhcnNlKF9mcy5yZWFkRmlsZVN5bmMobWFuaWZlc3RQYXRoLCAndXRmOCcpKS5uYW1lID09PSAnYXBwaXVtLXdlYmRyaXZlcmFnZW50Jykge1xuICAgICAgICByZXR1cm4gY3VycmVudERpcjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChpZ24pIHt9XG4gICAgY3VycmVudERpciA9IHBhdGguZGlybmFtZShjdXJyZW50RGlyKTtcbiAgICBpc0F0RnNSb290ID0gY3VycmVudERpci5sZW5ndGggPD0gcGF0aC5kaXJuYW1lKGN1cnJlbnREaXIpLmxlbmd0aDtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIHRoZSByb290IGZvbGRlciBvZiB0aGUgYXBwaXVtLXdlYmRyaXZlcmFnZW50IE5vZGUuanMgbW9kdWxlJyk7XG59KTtcblxuZXhwb3J0IGNvbnN0IEJPT1RTVFJBUF9QQVRIID0gZ2V0TW9kdWxlUm9vdCgpO1xuXG5hc3luYyBmdW5jdGlvbiBnZXRQSURzVXNpbmdQYXR0ZXJuIChwYXR0ZXJuKSB7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgJy1pZicsIC8vIGNhc2UgaW5zZW5zaXRpdmUsIGZ1bGwgY21kbGluZSBtYXRjaFxuICAgIHBhdHRlcm4sXG4gIF07XG4gIHRyeSB7XG4gICAgY29uc3Qge3N0ZG91dH0gPSBhd2FpdCBleGVjKCdwZ3JlcCcsIGFyZ3MpO1xuICAgIHJldHVybiBzdGRvdXQuc3BsaXQoL1xccysvKVxuICAgICAgLm1hcCgoeCkgPT4gcGFyc2VJbnQoeCwgMTApKVxuICAgICAgLmZpbHRlcihfLmlzSW50ZWdlcilcbiAgICAgIC5tYXAoKHgpID0+IGAke3h9YCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5kZWJ1ZyhgJ3BncmVwICR7YXJncy5qb2luKCcgJyl9JyBkaWRuJ3QgZGV0ZWN0IGFueSBtYXRjaGluZyBwcm9jZXNzZXMuIFJldHVybiBjb2RlOiAke2Vyci5jb2RlfWApO1xuICAgIHJldHVybiBbXTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBraWxsQXBwVXNpbmdQYXR0ZXJuIChwZ3JlcFBhdHRlcm4pIHtcbiAgY29uc3Qgc2lnbmFscyA9IFsyLCAxNSwgOV07XG4gIGZvciAoY29uc3Qgc2lnbmFsIG9mIHNpZ25hbHMpIHtcbiAgICBjb25zdCBtYXRjaGVkUGlkcyA9IGF3YWl0IGdldFBJRHNVc2luZ1BhdHRlcm4ocGdyZXBQYXR0ZXJuKTtcbiAgICBpZiAoXy5pc0VtcHR5KG1hdGNoZWRQaWRzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhcmdzID0gW2AtJHtzaWduYWx9YCwgLi4ubWF0Y2hlZFBpZHNdO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjKCdraWxsJywgYXJncyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2cuZGVidWcoYGtpbGwgJHthcmdzLmpvaW4oJyAnKX0gLT4gJHtlcnIubWVzc2FnZX1gKTtcbiAgICB9XG4gICAgaWYgKHNpZ25hbCA9PT0gXy5sYXN0KHNpZ25hbHMpKSB7XG4gICAgICAvLyB0aGVyZSBpcyBubyBuZWVkIHRvIHdhaXQgYWZ0ZXIgU0lHS0lMTFxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBpZENoZWNrUHJvbWlzZXMgPSBtYXRjaGVkUGlkc1xuICAgICAgICAgIC5tYXAoKHBpZCkgPT4gZXhlYygna2lsbCcsIFsnLTAnLCBwaWRdKVxuICAgICAgICAgICAgLy8gdGhlIHByb2Nlc3MgaXMgc3RpbGwgYWxpdmVcbiAgICAgICAgICAgIC50aGVuKCgpID0+IGZhbHNlKVxuICAgICAgICAgICAgLy8gdGhlIHByb2Nlc3MgaXMgZGVhZFxuICAgICAgICAgICAgLmNhdGNoKCgpID0+IHRydWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIChhd2FpdCBCLmFsbChwaWRDaGVja1Byb21pc2VzKSlcbiAgICAgICAgICAuZXZlcnkoKHgpID0+IHggPT09IHRydWUpO1xuICAgICAgfSwge1xuICAgICAgICB3YWl0TXM6IDEwMDAsXG4gICAgICAgIGludGVydmFsTXM6IDEwMCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGlnbikge1xuICAgICAgLy8gdHJ5IHRoZSBuZXh0IHNpZ25hbFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIHRoZSBwbGF0Zm9ybU5hbWUgaXMgdHZPU1xuICogQHBhcmFtIHtzdHJpbmd9IHBsYXRmb3JtTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGxhdG9ybVxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybiB0cnVlIGlmIHRoZSBwbGF0Zm9ybU5hbWUgaXMgdHZPU1xuICovXG5mdW5jdGlvbiBpc1R2T1MgKHBsYXRmb3JtTmFtZSkge1xuICByZXR1cm4gXy50b0xvd2VyKHBsYXRmb3JtTmFtZSkgPT09IF8udG9Mb3dlcihQTEFURk9STV9OQU1FX1RWT1MpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXBsYWNlSW5GaWxlIChmaWxlLCBmaW5kLCByZXBsYWNlKSB7XG4gIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGUsICd1dGY4Jyk7XG5cbiAgbGV0IG5ld0NvbnRlbnRzID0gY29udGVudHMucmVwbGFjZShmaW5kLCByZXBsYWNlKTtcbiAgaWYgKG5ld0NvbnRlbnRzICE9PSBjb250ZW50cykge1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShmaWxlLCBuZXdDb250ZW50cywgJ3V0ZjgnKTtcbiAgfVxufVxuXG4vKipcbiAqIFVwZGF0ZSBXZWJEcml2ZXJBZ2VudFJ1bm5lciBwcm9qZWN0IGJ1bmRsZSBJRCB3aXRoIG5ld0J1bmRsZUlkLlxuICogVGhpcyBtZXRob2QgYXNzdW1lcyBwcm9qZWN0IGZpbGUgaXMgaW4gdGhlIGNvcnJlY3Qgc3RhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gYWdlbnRQYXRoIC0gUGF0aCB0byB0aGUgLnhjb2RlcHJvaiBkaXJlY3RvcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmV3QnVuZGxlSWQgdGhlIG5ldyBidW5kbGUgSUQgdXNlZCB0byB1cGRhdGUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVByb2plY3RGaWxlIChhZ2VudFBhdGgsIG5ld0J1bmRsZUlkKSB7XG4gIGxldCBwcm9qZWN0RmlsZVBhdGggPSBwYXRoLnJlc29sdmUoYWdlbnRQYXRoLCBQUk9KRUNUX0ZJTEUpO1xuICB0cnkge1xuICAgIC8vIEFzc3VtaW5nIHByb2plY3RGaWxlUGF0aCBpcyBpbiB0aGUgY29ycmVjdCBzdGF0ZSwgY3JlYXRlIC5vbGQgZnJvbSBwcm9qZWN0RmlsZVBhdGhcbiAgICBhd2FpdCBmcy5jb3B5RmlsZShwcm9qZWN0RmlsZVBhdGgsIGAke3Byb2plY3RGaWxlUGF0aH0ub2xkYCk7XG4gICAgYXdhaXQgcmVwbGFjZUluRmlsZShwcm9qZWN0RmlsZVBhdGgsIG5ldyBSZWdFeHAoXy5lc2NhcGVSZWdFeHAoV0RBX1JVTk5FUl9CVU5ETEVfSUQpLCAnZycpLCBuZXdCdW5kbGVJZCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdXNlbGVzcy1lc2NhcGVcbiAgICBsb2cuZGVidWcoYFN1Y2Nlc3NmdWxseSB1cGRhdGVkICcke3Byb2plY3RGaWxlUGF0aH0nIHdpdGggYnVuZGxlIGlkICcke25ld0J1bmRsZUlkfSdgKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nLmRlYnVnKGBFcnJvciB1cGRhdGluZyBwcm9qZWN0IGZpbGU6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgbG9nLndhcm4oYFVuYWJsZSB0byB1cGRhdGUgcHJvamVjdCBmaWxlICcke3Byb2plY3RGaWxlUGF0aH0nIHdpdGggYCArXG4gICAgICBgYnVuZGxlIGlkICcke25ld0J1bmRsZUlkfScuIFdlYkRyaXZlckFnZW50IG1heSBub3Qgc3RhcnRgKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc2V0IFdlYkRyaXZlckFnZW50UnVubmVyIHByb2plY3QgYnVuZGxlIElEIHRvIGNvcnJlY3Qgc3RhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gYWdlbnRQYXRoIC0gUGF0aCB0byB0aGUgLnhjb2RlcHJvaiBkaXJlY3RvcnkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc2V0UHJvamVjdEZpbGUgKGFnZW50UGF0aCkge1xuICBjb25zdCBwcm9qZWN0RmlsZVBhdGggPSBwYXRoLmpvaW4oYWdlbnRQYXRoLCBQUk9KRUNUX0ZJTEUpO1xuICB0cnkge1xuICAgIC8vIHJlc3RvcmUgcHJvamVjdEZpbGVQYXRoIGZyb20gLm9sZCBmaWxlXG4gICAgaWYgKCFhd2FpdCBmcy5leGlzdHMoYCR7cHJvamVjdEZpbGVQYXRofS5vbGRgKSkge1xuICAgICAgcmV0dXJuOyAvLyBubyBuZWVkIHRvIHJlc2V0XG4gICAgfVxuICAgIGF3YWl0IGZzLm12KGAke3Byb2plY3RGaWxlUGF0aH0ub2xkYCwgcHJvamVjdEZpbGVQYXRoKTtcbiAgICBsb2cuZGVidWcoYFN1Y2Nlc3NmdWxseSByZXNldCAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGJ1bmRsZSBpZCAnJHtXREFfUlVOTkVSX0JVTkRMRV9JRH0nYCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5kZWJ1ZyhgRXJyb3IgcmVzZXR0aW5nIHByb2plY3QgZmlsZTogJHtlcnIubWVzc2FnZX1gKTtcbiAgICBsb2cud2FybihgVW5hYmxlIHRvIHJlc2V0IHByb2plY3QgZmlsZSAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGAgK1xuICAgICAgYGJ1bmRsZSBpZCAnJHtXREFfUlVOTkVSX0JVTkRMRV9JRH0nLiBXZWJEcml2ZXJBZ2VudCBoYXMgYmVlbiBgICtcbiAgICAgIGBtb2RpZmllZCBhbmQgbm90IHJldHVybmVkIHRvIHRoZSBvcmlnaW5hbCBzdGF0ZS5gKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRSZWFsRGV2aWNlU2VjdXJpdHkgKGtleWNoYWluUGF0aCwga2V5Y2hhaW5QYXNzd29yZCkge1xuICBsb2cuZGVidWcoJ1NldHRpbmcgc2VjdXJpdHkgZm9yIGlPUyBkZXZpY2UnKTtcbiAgYXdhaXQgZXhlYygnc2VjdXJpdHknLCBbJy12JywgJ2xpc3Qta2V5Y2hhaW5zJywgJy1zJywga2V5Y2hhaW5QYXRoXSk7XG4gIGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWyctdicsICd1bmxvY2sta2V5Y2hhaW4nLCAnLXAnLCBrZXljaGFpblBhc3N3b3JkLCBrZXljaGFpblBhdGhdKTtcbiAgYXdhaXQgZXhlYygnc2VjdXJpdHknLCBbJ3NldC1rZXljaGFpbi1zZXR0aW5ncycsICctdCcsICczNjAwJywgJy1sJywga2V5Y2hhaW5QYXRoXSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlWGNvZGVDb25maWdGaWxlIChvcmdJZCwgc2lnbmluZ0lkKSB7XG4gIGxvZy5kZWJ1ZyhgR2VuZXJhdGluZyB4Y29kZSBjb25maWcgZmlsZSBmb3Igb3JnSWQgJyR7b3JnSWR9JyBhbmQgc2lnbmluZ0lkIGAgK1xuICAgICAgICAgICAgYCcke3NpZ25pbmdJZH0nYCk7XG4gIGNvbnN0IGNvbnRlbnRzID0gYERFVkVMT1BNRU5UX1RFQU0gPSAke29yZ0lkfVxuQ09ERV9TSUdOX0lERU5USVRZID0gJHtzaWduaW5nSWR9XG5gO1xuICBjb25zdCB4Y2NvbmZpZ1BhdGggPSBhd2FpdCB0ZW1wRGlyLnBhdGgoJ2FwcGl1bS10ZW1wLnhjY29uZmlnJyk7XG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyB4Y29kZSBjb25maWcgZmlsZSB0byAke3hjY29uZmlnUGF0aH1gKTtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKHhjY29uZmlnUGF0aCwgY29udGVudHMsICd1dGY4Jyk7XG4gIHJldHVybiB4Y2NvbmZpZ1BhdGg7XG59XG5cbi8qKlxuICogSW5mb3JtYXRpb24gb2YgdGhlIGRldmljZSB1bmRlciB0ZXN0XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEZXZpY2VJbmZvXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaXNSZWFsRGV2aWNlIC0gRXF1YWxzIHRvIHRydWUgaWYgdGhlIGN1cnJlbnQgZGV2aWNlIGlzIGEgcmVhbCBkZXZpY2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1ZGlkIC0gVGhlIGRldmljZSBVRElELlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHBsYXRmb3JtVmVyc2lvbiAtIFRoZSBwbGF0Zm9ybSB2ZXJzaW9uIG9mIE9TLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHBsYXRmb3JtTmFtZSAtIFRoZSBwbGF0Zm9ybSBuYW1lIG9mIGlPUywgdHZPU1xuKi9cbi8qKlxuICogQ3JlYXRlcyB4Y3Rlc3RydW4gZmlsZSBwZXIgZGV2aWNlICYgcGxhdGZvcm0gdmVyc2lvbi5cbiAqIFdlIGV4cGVjdHMgdG8gaGF2ZSBXZWJEcml2ZXJBZ2VudFJ1bm5lcl9pcGhvbmVvcyR7c2RrVmVyc2lvbnxwbGF0Zm9ybVZlcnNpb259LWFybTY0LnhjdGVzdHJ1biBmb3IgcmVhbCBkZXZpY2VcbiAqIGFuZCBXZWJEcml2ZXJBZ2VudFJ1bm5lcl9pcGhvbmVzaW11bGF0b3Ike3Nka1ZlcnNpb258cGxhdGZvcm1WZXJzaW9ufS14ODZfNjQueGN0ZXN0cnVuIGZvciBzaW11bGF0b3IgbG9jYXRlZCBAYm9vdHN0cmFwUGF0aFxuICogTmV3ZXIgWGNvZGUgKFhjb2RlIDEwLjAgYXQgbGVhc3QpIGdlbmVyYXRlIHhjdGVzdHJ1biBmaWxlIGZvbGxvd2luZyBzZGtWZXJzaW9uLlxuICogZS5nLiBYY29kZSB3aGljaCBoYXMgaU9TIFNESyBWZXJzaW9uIDEyLjIgZ2VuZXJhdGUgV2ViRHJpdmVyQWdlbnRSdW5uZXJfaXBob25lc2ltdWxhdG9yLjIteDg2XzY0LnhjdGVzdHJ1blxuICogICAgICBldmVuIGlmIHRoZSBjYXAgaGFzIHBsYXRmb3JtIHZlcnNpb24gMTEuNFxuICpcbiAqIEBwYXJhbSB7RGV2aWNlSW5mb30gZGV2aWNlSW5mb1xuICogQHBhcmFtIHtzdHJpbmd9IHNka1ZlcnNpb24gLSBUaGUgWGNvZGUgU0RLIHZlcnNpb24gb2YgT1MuXG4gKiBAcGFyYW0ge3N0cmluZ30gYm9vdHN0cmFwUGF0aCAtIFRoZSBmb2xkZXIgcGF0aCBjb250YWluaW5nIHhjdGVzdHJ1biBmaWxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHdkYVJlbW90ZVBvcnQgLSBUaGUgcmVtb3RlIHBvcnQgV0RBIGlzIGxpc3RlbmluZyBvbi5cbiAqIEByZXR1cm4ge3N0cmluZ30gcmV0dXJucyB4Y3Rlc3RydW5GaWxlUGF0aCBmb3IgZ2l2ZW4gZGV2aWNlXG4gKiBAdGhyb3dzIGlmIFdlYkRyaXZlckFnZW50UnVubmVyX2lwaG9uZW9zJHtzZGtWZXJzaW9ufHBsYXRmb3JtVmVyc2lvbn0tYXJtNjQueGN0ZXN0cnVuIGZvciByZWFsIGRldmljZVxuICogb3IgV2ViRHJpdmVyQWdlbnRSdW5uZXJfaXBob25lc2ltdWxhdG9yJHtzZGtWZXJzaW9ufHBsYXRmb3JtVmVyc2lvbn0teDg2XzY0LnhjdGVzdHJ1biBmb3Igc2ltdWxhdG9yIGlzIG5vdCBmb3VuZCBAYm9vdHN0cmFwUGF0aCxcbiAqIHRoZW4gaXQgd2lsbCB0aHJvdyBmaWxlIG5vdCBmb3VuZCBleGNlcHRpb25cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2V0WGN0ZXN0cnVuRmlsZSAoZGV2aWNlSW5mbywgc2RrVmVyc2lvbiwgYm9vdHN0cmFwUGF0aCwgd2RhUmVtb3RlUG9ydCkge1xuICBjb25zdCB4Y3Rlc3RydW5GaWxlUGF0aCA9IGF3YWl0IGdldFhjdGVzdHJ1bkZpbGVQYXRoKGRldmljZUluZm8sIHNka1ZlcnNpb24sIGJvb3RzdHJhcFBhdGgpO1xuICBjb25zdCB4Y3Rlc3RSdW5Db250ZW50ID0gYXdhaXQgcGxpc3QucGFyc2VQbGlzdEZpbGUoeGN0ZXN0cnVuRmlsZVBhdGgpO1xuICBjb25zdCB1cGRhdGVXREFQb3J0ID0gZ2V0QWRkaXRpb25hbFJ1bkNvbnRlbnQoZGV2aWNlSW5mby5wbGF0Zm9ybU5hbWUsIHdkYVJlbW90ZVBvcnQpO1xuICBjb25zdCBuZXdYY3Rlc3RSdW5Db250ZW50ID0gXy5tZXJnZSh4Y3Rlc3RSdW5Db250ZW50LCB1cGRhdGVXREFQb3J0KTtcbiAgYXdhaXQgcGxpc3QudXBkYXRlUGxpc3RGaWxlKHhjdGVzdHJ1bkZpbGVQYXRoLCBuZXdYY3Rlc3RSdW5Db250ZW50LCB0cnVlKTtcblxuICByZXR1cm4geGN0ZXN0cnVuRmlsZVBhdGg7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBXREEgb2JqZWN0IHdoaWNoIGFwcGVuZHMgZXhpc3RpbmcgeGN0ZXN0IHJ1bm5lciBjb250ZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gcGxhdGZvcm1OYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHBsYXRmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvbiAtIFRoZSBYY29kZSBTREsgdmVyc2lvbiBvZiBPUy5cbiAqIEByZXR1cm4ge29iamVjdH0gcmV0dXJucyBhIHJ1bm5lciBvYmplY3Qgd2hpY2ggaGFzIFVTRV9QT1JUXG4gKi9cbmZ1bmN0aW9uIGdldEFkZGl0aW9uYWxSdW5Db250ZW50IChwbGF0Zm9ybU5hbWUsIHdkYVJlbW90ZVBvcnQpIHtcbiAgY29uc3QgcnVubmVyID0gYFdlYkRyaXZlckFnZW50UnVubmVyJHtpc1R2T1MocGxhdGZvcm1OYW1lKSA/ICdfdHZPUycgOiAnJ31gO1xuXG4gIHJldHVybiB7XG4gICAgW3J1bm5lcl06IHtcbiAgICAgIEVudmlyb25tZW50VmFyaWFibGVzOiB7XG4gICAgICAgIC8vIFVTRV9QT1JUIG11c3QgYmUgJ3N0cmluZydcbiAgICAgICAgVVNFX1BPUlQ6IGAke3dkYVJlbW90ZVBvcnR9YFxuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHBhdGggb2YgeGN0ZXN0cnVuIGlmIGl0IGV4aXN0c1xuICogQHBhcmFtIHtEZXZpY2VJbmZvfSBkZXZpY2VJbmZvXG4gKiBAcGFyYW0ge3N0cmluZ30gc2RrVmVyc2lvbiAtIFRoZSBYY29kZSBTREsgdmVyc2lvbiBvZiBPUy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBib290c3RyYXBQYXRoIC0gVGhlIGZvbGRlciBwYXRoIGNvbnRhaW5pbmcgeGN0ZXN0cnVuIGZpbGUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFhjdGVzdHJ1bkZpbGVQYXRoIChkZXZpY2VJbmZvLCBzZGtWZXJzaW9uLCBib290c3RyYXBQYXRoKSB7XG4gIC8vIEZpcnN0IHRyeSB0aGUgU0RLIHBhdGgsIGZvciBYY29kZSAxMCAoYXQgbGVhc3QpXG4gIGNvbnN0IHNka0Jhc2VkID0gW1xuICAgIHBhdGgucmVzb2x2ZShib290c3RyYXBQYXRoLCBgJHtkZXZpY2VJbmZvLnVkaWR9XyR7c2RrVmVyc2lvbn0ueGN0ZXN0cnVuYCksXG4gICAgc2RrVmVyc2lvbixcbiAgXTtcbiAgLy8gTmV4dCB0cnkgUGxhdGZvcm0gcGF0aCwgZm9yIGVhcmxpZXIgWGNvZGUgdmVyc2lvbnNcbiAgY29uc3QgcGxhdGZvcm1CYXNlZCA9IFtcbiAgICBwYXRoLnJlc29sdmUoYm9vdHN0cmFwUGF0aCwgYCR7ZGV2aWNlSW5mby51ZGlkfV8ke2RldmljZUluZm8ucGxhdGZvcm1WZXJzaW9ufS54Y3Rlc3RydW5gKSxcbiAgICBkZXZpY2VJbmZvLnBsYXRmb3JtVmVyc2lvbixcbiAgXTtcblxuICBmb3IgKGNvbnN0IFtmaWxlUGF0aCwgdmVyc2lvbl0gb2YgW3Nka0Jhc2VkLCBwbGF0Zm9ybUJhc2VkXSkge1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMoZmlsZVBhdGgpKSB7XG4gICAgICBsb2cuaW5mbyhgVXNpbmcgJyR7ZmlsZVBhdGh9JyBhcyB4Y3Rlc3RydW4gZmlsZWApO1xuICAgICAgcmV0dXJuIGZpbGVQYXRoO1xuICAgIH1cbiAgICBjb25zdCBvcmlnaW5hbFhjdGVzdHJ1bkZpbGUgPSBwYXRoLnJlc29sdmUoYm9vdHN0cmFwUGF0aCwgZ2V0WGN0ZXN0cnVuRmlsZU5hbWUoZGV2aWNlSW5mbywgdmVyc2lvbikpO1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMob3JpZ2luYWxYY3Rlc3RydW5GaWxlKSkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBmaXJzdCB0aW1lIHJ1biBmb3IgZ2l2ZW4gZGV2aWNlLCB0aGVuIGZpcnN0IGdlbmVyYXRlIHhjdGVzdHJ1biBmaWxlIGZvciBkZXZpY2UuXG4gICAgICAvLyBXZSBuZWVkIHRvIGhhdmUgYSB4Y3Rlc3RydW4gZmlsZSAqKnBlciBkZXZpY2UqKiBiZWNhdXNlIHdlIGNhbnQgbm90IGhhdmUgc2FtZSB3ZGEgcG9ydCBmb3IgYWxsIGRldmljZXMuXG4gICAgICBhd2FpdCBmcy5jb3B5RmlsZShvcmlnaW5hbFhjdGVzdHJ1bkZpbGUsIGZpbGVQYXRoKTtcbiAgICAgIGxvZy5pbmZvKGBVc2luZyAnJHtmaWxlUGF0aH0nIGFzIHhjdGVzdHJ1biBmaWxlIGNvcGllZCBieSAnJHtvcmlnaW5hbFhjdGVzdHJ1bkZpbGV9J2ApO1xuICAgICAgcmV0dXJuIGZpbGVQYXRoO1xuICAgIH1cbiAgfVxuXG4gIGxvZy5lcnJvckFuZFRocm93KGBJZiB5b3UgYXJlIHVzaW5nICd1c2VYY3Rlc3RydW5GaWxlJyBjYXBhYmlsaXR5IHRoZW4geW91IGAgK1xuICAgIGBuZWVkIHRvIGhhdmUgYSB4Y3Rlc3RydW4gZmlsZSAoZXhwZWN0ZWQ6IGAgK1xuICAgIGAnJHtwYXRoLnJlc29sdmUoYm9vdHN0cmFwUGF0aCwgZ2V0WGN0ZXN0cnVuRmlsZU5hbWUoZGV2aWNlSW5mbywgc2RrVmVyc2lvbikpfScpYCk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIG5hbWUgb2YgeGN0ZXN0cnVuIGZpbGVcbiAqIEBwYXJhbSB7RGV2aWNlSW5mb30gZGV2aWNlSW5mb1xuICogQHBhcmFtIHtzdHJpbmd9IHZlcnNpb24gLSBUaGUgWGNvZGUgU0RLIHZlcnNpb24gb2YgT1MuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHJldHVybnMgeGN0ZXN0cnVuRmlsZVBhdGggZm9yIGdpdmVuIGRldmljZVxuICovXG5mdW5jdGlvbiBnZXRYY3Rlc3RydW5GaWxlTmFtZSAoZGV2aWNlSW5mbywgdmVyc2lvbikge1xuICByZXR1cm4gaXNUdk9TKGRldmljZUluZm8ucGxhdGZvcm1OYW1lKVxuICAgID8gYFdlYkRyaXZlckFnZW50UnVubmVyX3R2T1NfYXBwbGV0diR7ZGV2aWNlSW5mby5pc1JlYWxEZXZpY2UgPyBgb3Mke3ZlcnNpb259LWFybTY0YCA6IGBzaW11bGF0b3Ike3ZlcnNpb259LXg4Nl82NGB9LnhjdGVzdHJ1bmBcbiAgICA6IGBXZWJEcml2ZXJBZ2VudFJ1bm5lcl9pcGhvbmUke2RldmljZUluZm8uaXNSZWFsRGV2aWNlID8gYG9zJHt2ZXJzaW9ufS1hcm02NGAgOiBgc2ltdWxhdG9yJHt2ZXJzaW9ufS14ODZfNjRgfS54Y3Rlc3RydW5gO1xufVxuXG5hc3luYyBmdW5jdGlvbiBraWxsUHJvY2VzcyAobmFtZSwgcHJvYykge1xuICBpZiAoIXByb2MgfHwgIXByb2MuaXNSdW5uaW5nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbG9nLmluZm8oYFNodXR0aW5nIGRvd24gJyR7bmFtZX0nIHByb2Nlc3MgKHBpZCAnJHtwcm9jLnByb2MucGlkfScpYCk7XG5cbiAgbG9nLmluZm8oYFNlbmRpbmcgJ1NJR1RFUk0nLi4uYCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgcHJvYy5zdG9wKCdTSUdURVJNJywgMTAwMCk7XG4gICAgcmV0dXJuO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBpZiAoIWVyci5tZXNzYWdlLmluY2x1ZGVzKGBQcm9jZXNzIGRpZG4ndCBlbmQgYWZ0ZXJgKSkge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICBsb2cuZGVidWcoYCR7bmFtZX0gcHJvY2VzcyBkaWQgbm90IGVuZCBpbiBhIHRpbWVseSBmYXNoaW9uOiAnJHtlcnIubWVzc2FnZX0nLmApO1xuICB9XG5cbiAgbG9nLmluZm8oYFNlbmRpbmcgJ1NJR0tJTEwnLi4uYCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgcHJvYy5zdG9wKCdTSUdLSUxMJyk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChlcnIubWVzc2FnZS5pbmNsdWRlcygnbm90IGN1cnJlbnRseSBydW5uaW5nJykpIHtcbiAgICAgIC8vIHRoZSBwcm9jZXNzIGVuZGVkIGJ1dCBmb3Igc29tZSByZWFzb24gd2Ugd2VyZSBub3QgaW5mb3JtZWRcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSByYW5kb20gaW50ZWdlci5cbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEEgcmFuZG9tIGludGVnZXIgbnVtYmVyIGluIHJhbmdlIFtsb3csIGhpZ2h0KS4gYGxvd2BgIGlzIGluY2x1c2l2ZSBhbmQgYGhpZ2hgIGlzIGV4Y2x1c2l2ZS5cbiAqL1xuZnVuY3Rpb24gcmFuZG9tSW50IChsb3csIGhpZ2gpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChoaWdoIC0gbG93KSArIGxvdyk7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIFdEQSB1cGdyYWRlIHRpbWVzdGFtcFxuICpcbiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSBVTklYIHRpbWVzdGFtcCBvZiB0aGUgcGFja2FnZSBtYW5pZmVzdC4gVGhlIG1hbmlmZXN0IG9ubHkgZ2V0cyBtb2RpZmllZCBvblxuICogcGFja2FnZSB1cGdyYWRlLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRXREFVcGdyYWRlVGltZXN0YW1wICgpIHtcbiAgY29uc3QgcGFja2FnZU1hbmlmZXN0ID0gcGF0aC5yZXNvbHZlKGdldE1vZHVsZVJvb3QoKSwgJ3BhY2thZ2UuanNvbicpO1xuICBpZiAoIWF3YWl0IGZzLmV4aXN0cyhwYWNrYWdlTWFuaWZlc3QpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qge210aW1lfSA9IGF3YWl0IGZzLnN0YXQocGFja2FnZU1hbmlmZXN0KTtcbiAgcmV0dXJuIG10aW1lLmdldFRpbWUoKTtcbn1cblxuLyoqXG4gKiBLaWxscyBydW5uaW5nIFhDVGVzdCBwcm9jZXNzZXMgZm9yIHRoZSBwYXJ0aWN1bGFyIGRldmljZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdWRpZCAtIFRoZSBkZXZpY2UgVURJRC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNTaW11bGF0b3IgLSBFcXVhbHMgdG8gdHJ1ZSBpZiB0aGUgY3VycmVudCBkZXZpY2UgaXMgYSBTaW11bGF0b3JcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzZXRUZXN0UHJvY2Vzc2VzICh1ZGlkLCBpc1NpbXVsYXRvcikge1xuICBjb25zdCBwcm9jZXNzUGF0dGVybnMgPSBbYHhjb2RlYnVpbGQuKiR7dWRpZH1gXTtcbiAgaWYgKGlzU2ltdWxhdG9yKSB7XG4gICAgcHJvY2Vzc1BhdHRlcm5zLnB1c2goYCR7dWRpZH0uKlhDVFJ1bm5lcmApO1xuICAgIC8vIFRoZSBwYXR0ZXJuIHRvIGZpbmQgaW4gY2FzZSBpZGIgd2FzIHVzZWRcbiAgICBwcm9jZXNzUGF0dGVybnMucHVzaChgeGN0ZXN0Lioke3VkaWR9YCk7XG4gIH1cbiAgbG9nLmRlYnVnKGBLaWxsaW5nIHJ1bm5pbmcgcHJvY2Vzc2VzICcke3Byb2Nlc3NQYXR0ZXJucy5qb2luKCcsICcpfScgZm9yIHRoZSBkZXZpY2UgJHt1ZGlkfS4uLmApO1xuICBhd2FpdCBCLmFsbChwcm9jZXNzUGF0dGVybnMubWFwKGtpbGxBcHBVc2luZ1BhdHRlcm4pKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIElEcyBvZiBwcm9jZXNzZXMgbGlzdGVuaW5nIG9uIHRoZSBwYXJ0aWN1bGFyIHN5c3RlbSBwb3J0LlxuICogSXQgaXMgYWxzbyBwb3NzaWJsZSB0byBhcHBseSBhZGRpdGlvbmFsIGZpbHRlcmluZyBiYXNlZCBvbiB0aGVcbiAqIHByb2Nlc3MgY29tbWFuZCBsaW5lLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gcG9ydCAtIFRoZSBwb3J0IG51bWJlci5cbiAqIEBwYXJhbSB7P0Z1bmN0aW9ufSBmaWx0ZXJpbmdGdW5jIC0gT3B0aW9uYWwgbGFtYmRhIGZ1bmN0aW9uLCB3aGljaFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlcyBjb21tYW5kIGxpbmUgc3RyaW5nIG9mIHRoZSBwYXJ0aWN1bGFyIHByb2Nlc3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuaW5nIG9uIGdpdmVuIHBvcnQsIGFuZCBpcyBleHBlY3RlZCB0byByZXR1cm5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWl0aGVyIHRydWUgb3IgZmFsc2UgdG8gaW5jbHVkZS9leGNsdWRlIHRoZSBjb3JyZXNwb25kaW5nIFBJRFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tIHRoZSByZXN1bHRpbmcgYXJyYXkuXG4gKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gLSB0aGUgbGlzdCBvZiBtYXRjaGVkIHByb2Nlc3MgaWRzLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRQSURzTGlzdGVuaW5nT25Qb3J0IChwb3J0LCBmaWx0ZXJpbmdGdW5jID0gbnVsbCkge1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgdHJ5IHtcbiAgICAvLyBUaGlzIG9ubHkgd29ya3Mgc2luY2UgTWFjIE9TIFggRWwgQ2FwaXRhblxuICAgIGNvbnN0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYygnbHNvZicsIFsnLXRpJywgYHRjcDoke3BvcnR9YF0pO1xuICAgIHJlc3VsdC5wdXNoKC4uLihzdGRvdXQudHJpbSgpLnNwbGl0KC9cXG4rLykpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlLmNvZGUgIT09IDEpIHtcbiAgICAgIC8vIGNvZGUgMSBtZWFucyBubyBwcm9jZXNzZXMuIE90aGVyIGVycm9ycyBuZWVkIHJlcG9ydGluZ1xuICAgICAgbG9nLmRlYnVnKGBFcnJvciBnZXR0aW5nIHByb2Nlc3NlcyBsaXN0ZW5pbmcgb24gcG9ydCAnJHtwb3J0fSc6ICR7ZS5zdGRlcnIgfHwgZS5tZXNzYWdlfWApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKCFfLmlzRnVuY3Rpb24oZmlsdGVyaW5nRnVuYykpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHJldHVybiBhd2FpdCBCLmZpbHRlcihyZXN1bHQsIGFzeW5jIChwaWQpID0+IHtcbiAgICBsZXQgc3Rkb3V0O1xuICAgIHRyeSB7XG4gICAgICAoe3N0ZG91dH0gPSBhd2FpdCBleGVjKCdwcycsIFsnLXAnLCBwaWQsICctbycsICdjb21tYW5kJ10pKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZS5jb2RlID09PSAxKSB7XG4gICAgICAgIC8vIFRoZSBwcm9jZXNzIGRvZXMgbm90IGV4aXN0IGFueW1vcmUsIHRoZXJlJ3Mgbm90aGluZyB0byBmaWx0ZXJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgcmV0dXJuIGF3YWl0IGZpbHRlcmluZ0Z1bmMoc3Rkb3V0KTtcbiAgfSk7XG59XG5cbmV4cG9ydCB7IHVwZGF0ZVByb2plY3RGaWxlLCByZXNldFByb2plY3RGaWxlLCBzZXRSZWFsRGV2aWNlU2VjdXJpdHksXG4gIGdldEFkZGl0aW9uYWxSdW5Db250ZW50LCBnZXRYY3Rlc3RydW5GaWxlTmFtZSwgZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUsXG4gIHNldFhjdGVzdHJ1bkZpbGUsIGdldFhjdGVzdHJ1bkZpbGVQYXRoLCBraWxsUHJvY2VzcywgcmFuZG9tSW50LFxuICBnZXRXREFVcGdyYWRlVGltZXN0YW1wLCByZXNldFRlc3RQcm9jZXNzZXMsXG4gIGdldFBJRHNMaXN0ZW5pbmdPblBvcnQsIGtpbGxBcHBVc2luZ1BhdHRlcm4sIGlzVHZPU1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSxNQUFNQSxZQUFZLEdBQUcsaUJBQWlCOztB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
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["PROJECT_FILE","getModuleRoot","_","memoize","currentDir","path","dirname","resolve","__filename","isAtFsRoot","manifestPath","join","_fs","existsSync","JSON","parse","readFileSync","name","ign","length","Error","BOOTSTRAP_PATH","getPIDsUsingPattern","pattern","args","stdout","exec","split","map","x","parseInt","filter","isInteger","err","log","debug","code","killAppUsingPattern","pgrepPattern","signals","signal","matchedPids","isEmpty","message","last","waitForCondition","pidCheckPromises","pid","then","catch","B","all","every","waitMs","intervalMs","isTvOS","platformName","toLower","PLATFORM_NAME_TVOS","replaceInFile","file","find","replace","contents","fs","readFile","newContents","writeFile","updateProjectFile","agentPath","newBundleId","projectFilePath","copyFile","RegExp","escapeRegExp","WDA_RUNNER_BUNDLE_ID","warn","resetProjectFile","exists","mv","setRealDeviceSecurity","keychainPath","keychainPassword","generateXcodeConfigFile","orgId","signingId","xcconfigPath","tempDir","setXctestrunFile","deviceInfo","sdkVersion","bootstrapPath","wdaRemotePort","xctestrunFilePath","getXctestrunFilePath","xctestRunContent","plist","parsePlistFile","updateWDAPort","getAdditionalRunContent","newXctestRunContent","merge","updatePlistFile","runner","EnvironmentVariables","USE_PORT","sdkBased","udid","platformBased","platformVersion","filePath","version","info","originalXctestrunFile","getXctestrunFileName","errorAndThrow","isRealDevice","killProcess","proc","isRunning","stop","includes","randomInt","low","high","Math","floor","random","getWDAUpgradeTimestamp","packageManifest","mtime","stat","getTime","resetTestProcesses","isSimulator","processPatterns","push","getPIDsListeningOnPort","port","filteringFunc","result","trim","e","stderr","isFunction"],"sources":["../../lib/utils.js"],"sourcesContent":["import { fs, tempDir, plist } from 'appium/support';\nimport { exec } from 'teen_process';\nimport path from 'path';\nimport log from './logger';\nimport _ from 'lodash';\nimport { WDA_RUNNER_BUNDLE_ID, PLATFORM_NAME_TVOS } from './constants';\nimport B from 'bluebird';\nimport _fs from 'fs';\nimport { waitForCondition } from 'asyncbox';\n\nconst PROJECT_FILE = 'project.pbxproj';\n\n/**\n * Calculates the path to the current module's root folder\n *\n * @returns {string} The full path to module root\n * @throws {Error} If the current module root folder cannot be determined\n */\nconst getModuleRoot = _.memoize(function getModuleRoot () {\n let currentDir = path.dirname(path.resolve(__filename));\n let isAtFsRoot = false;\n while (!isAtFsRoot) {\n const manifestPath = path.join(currentDir, 'package.json');\n try {\n if (_fs.existsSync(manifestPath) &&\n JSON.parse(_fs.readFileSync(manifestPath, 'utf8')).name === 'appium-webdriveragent') {\n return currentDir;\n }\n } catch (ign) {}\n currentDir = path.dirname(currentDir);\n isAtFsRoot = currentDir.length <= path.dirname(currentDir).length;\n }\n throw new Error('Cannot find the root folder of the appium-webdriveragent Node.js module');\n});\n\nexport const BOOTSTRAP_PATH = getModuleRoot();\n\nasync function getPIDsUsingPattern (pattern) {\n const args = [\n '-if', // case insensitive, full cmdline match\n pattern,\n ];\n try {\n const {stdout} = await exec('pgrep', args);\n return stdout.split(/\\s+/)\n .map((x) => parseInt(x, 10))\n .filter(_.isInteger)\n .map((x) => `${x}`);\n } catch (err) {\n log.debug(`'pgrep ${args.join(' ')}' didn't detect any matching processes. Return code: ${err.code}`);\n return [];\n }\n}\n\nasync function killAppUsingPattern (pgrepPattern) {\n const signals = [2, 15, 9];\n for (const signal of signals) {\n const matchedPids = await getPIDsUsingPattern(pgrepPattern);\n if (_.isEmpty(matchedPids)) {\n return;\n }\n const args = [`-${signal}`, ...matchedPids];\n try {\n await exec('kill', args);\n } catch (err) {\n log.debug(`kill ${args.join(' ')} -> ${err.message}`);\n }\n if (signal === _.last(signals)) {\n // there is no need to wait after SIGKILL\n return;\n }\n try {\n await waitForCondition(async () => {\n const pidCheckPromises = matchedPids\n .map((pid) => exec('kill', ['-0', pid])\n // the process is still alive\n .then(() => false)\n // the process is dead\n .catch(() => true)\n );\n return (await B.all(pidCheckPromises))\n .every((x) => x === true);\n }, {\n waitMs: 1000,\n intervalMs: 100,\n });\n return;\n } catch (ign) {\n // try the next signal\n }\n }\n}\n\n/**\n * Return true if the platformName is tvOS\n * @param {string} platformName The name of the platorm\n * @returns {boolean} Return true if the platformName is tvOS\n */\nfunction isTvOS (platformName) {\n return _.toLower(platformName) === _.toLower(PLATFORM_NAME_TVOS);\n}\n\nasync function replaceInFile (file, find, replace) {\n let contents = await fs.readFile(file, 'utf8');\n\n let newContents = contents.replace(find, replace);\n if (newContents !== contents) {\n await fs.writeFile(file, newContents, 'utf8');\n }\n}\n\n/**\n * Update WebDriverAgentRunner project bundle ID with newBundleId.\n * This method assumes project file is in the correct state.\n * @param {string} agentPath - Path to the .xcodeproj directory.\n * @param {string} newBundleId the new bundle ID used to update.\n */\nasync function updateProjectFile (agentPath, newBundleId) {\n let projectFilePath = path.resolve(agentPath, PROJECT_FILE);\n try {\n // Assuming projectFilePath is in the correct state, create .old from projectFilePath\n await fs.copyFile(projectFilePath, `${projectFilePath}.old`);\n await replaceInFile(projectFilePath, new RegExp(_.escapeRegExp(WDA_RUNNER_BUNDLE_ID), 'g'), newBundleId); // eslint-disable-line no-useless-escape\n log.debug(`Successfully updated '${projectFilePath}' with bundle id '${newBundleId}'`);\n } catch (err) {\n log.debug(`Error updating project file: ${err.message}`);\n log.warn(`Unable to update project file '${projectFilePath}' with ` +\n `bundle id '${newBundleId}'. WebDriverAgent may not start`);\n }\n}\n\n/**\n * Reset WebDriverAgentRunner project bundle ID to correct state.\n * @param {string} agentPath - Path to the .xcodeproj directory.\n */\nasync function resetProjectFile (agentPath) {\n const projectFilePath = path.join(agentPath, PROJECT_FILE);\n try {\n // restore projectFilePath from .old file\n if (!await fs.exists(`${projectFilePath}.old`)) {\n return; // no need to reset\n }\n await fs.mv(`${projectFilePath}.old`, projectFilePath);\n log.debug(`Successfully reset '${projectFilePath}' with bundle id '${WDA_RUNNER_BUNDLE_ID}'`);\n } catch (err) {\n log.debug(`Error resetting project file: ${err.message}`);\n log.warn(`Unable to reset project file '${projectFilePath}' with ` +\n `bundle id '${WDA_RUNNER_BUNDLE_ID}'. WebDriverAgent has been ` +\n `modified and not returned to the original state.`);\n }\n}\n\nasync function setRealDeviceSecurity (keychainPath, keychainPassword) {\n log.debug('Setting security for iOS device');\n await exec('security', ['-v', 'list-keychains', '-s', keychainPath]);\n await exec('security', ['-v', 'unlock-keychain', '-p', keychainPassword, keychainPath]);\n await exec('security', ['set-keychain-settings', '-t', '3600', '-l', keychainPath]);\n}\n\nasync function generateXcodeConfigFile (orgId, signingId) {\n log.debug(`Generating xcode config file for orgId '${orgId}' and signingId ` +\n `'${signingId}'`);\n const contents = `DEVELOPMENT_TEAM = ${orgId}\nCODE_SIGN_IDENTITY = ${signingId}\n`;\n const xcconfigPath = await tempDir.path('appium-temp.xcconfig');\n log.debug(`Writing xcode config file to ${xcconfigPath}`);\n await fs.writeFile(xcconfigPath, contents, 'utf8');\n return xcconfigPath;\n}\n\n/**\n * Information of the device under test\n * @typedef {Object} DeviceInfo\n * @property {string} isRealDevice - Equals to true if the current device is a real device\n * @property {string} udid - The device UDID.\n * @property {string} platformVersion - The platform version of OS.\n * @property {string} platformName - The platform name of iOS, tvOS\n*/\n/**\n * Creates xctestrun file per device & platform version.\n * We expects to have WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device\n * and WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator located @bootstrapPath\n * Newer Xcode (Xcode 10.0 at least) generate xctestrun file following sdkVersion.\n * e.g. Xcode which has iOS SDK Version 12.2 generate WebDriverAgentRunner_iphonesimulator.2-x86_64.xctestrun\n * even if the cap has platform version 11.4\n *\n * @param {DeviceInfo} deviceInfo\n * @param {string} sdkVersion - The Xcode SDK version of OS.\n * @param {string} bootstrapPath - The folder path containing xctestrun file.\n * @param {string} wdaRemotePort - The remote port WDA is listening on.\n * @return {string} returns xctestrunFilePath for given device\n * @throws if WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device\n * or WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator is not found @bootstrapPath,\n * then it will throw file not found exception\n */\nasync function setXctestrunFile (deviceInfo, sdkVersion, bootstrapPath, wdaRemotePort) {\n const xctestrunFilePath = await getXctestrunFilePath(deviceInfo, sdkVersion, bootstrapPath);\n const xctestRunContent = await plist.parsePlistFile(xctestrunFilePath);\n const updateWDAPort = getAdditionalRunContent(deviceInfo.platformName, wdaRemotePort);\n const newXctestRunContent = _.merge(xctestRunContent, updateWDAPort);\n await plist.updatePlistFile(xctestrunFilePath, newXctestRunContent, true);\n\n return xctestrunFilePath;\n}\n\n/**\n * Return the WDA object which appends existing xctest runner content\n * @param {string} platformName - The name of the platform\n * @param {string} version - The Xcode SDK version of OS.\n * @return {object} returns a runner object which has USE_PORT\n */\nfunction getAdditionalRunContent (platformName, wdaRemotePort) {\n const runner = `WebDriverAgentRunner${isTvOS(platformName) ? '_tvOS' : ''}`;\n\n return {\n [runner]: {\n EnvironmentVariables: {\n // USE_PORT must be 'string'\n USE_PORT: `${wdaRemotePort}`\n }\n }\n };\n}\n\n/**\n * Return the path of xctestrun if it exists\n * @param {DeviceInfo} deviceInfo\n * @param {string} sdkVersion - The Xcode SDK version of OS.\n * @param {string} bootstrapPath - The folder path containing xctestrun file.\n */\nasync function getXctestrunFilePath (deviceInfo, sdkVersion, bootstrapPath) {\n // First try the SDK path, for Xcode 10 (at least)\n const sdkBased = [\n path.resolve(bootstrapPath, `${deviceInfo.udid}_${sdkVersion}.xctestrun`),\n sdkVersion,\n ];\n // Next try Platform path, for earlier Xcode versions\n const platformBased = [\n path.resolve(bootstrapPath, `${deviceInfo.udid}_${deviceInfo.platformVersion}.xctestrun`),\n deviceInfo.platformVersion,\n ];\n\n for (const [filePath, version] of [sdkBased, platformBased]) {\n if (await fs.exists(filePath)) {\n log.info(`Using '${filePath}' as xctestrun file`);\n return filePath;\n }\n const originalXctestrunFile = path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, version));\n if (await fs.exists(originalXctestrunFile)) {\n // If this is first time run for given device, then first generate xctestrun file for device.\n // We need to have a xctestrun file **per device** because we cant not have same wda port for all devices.\n await fs.copyFile(originalXctestrunFile, filePath);\n log.info(`Using '${filePath}' as xctestrun file copied by '${originalXctestrunFile}'`);\n return filePath;\n }\n }\n\n log.errorAndThrow(`If you are using 'useXctestrunFile' capability then you ` +\n `need to have a xctestrun file (expected: ` +\n `'${path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')`);\n}\n\n\n/**\n * Return the name of xctestrun file\n * @param {DeviceInfo} deviceInfo\n * @param {string} version - The Xcode SDK version of OS.\n * @return {string} returns xctestrunFilePath for given device\n */\nfunction getXctestrunFileName (deviceInfo, version) {\n return isTvOS(deviceInfo.platformName)\n ? `WebDriverAgentRunner_tvOS_appletv${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun`\n : `WebDriverAgentRunner_iphone${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun`;\n}\n\nasync function killProcess (name, proc) {\n if (!proc || !proc.isRunning) {\n return;\n }\n\n log.info(`Shutting down '${name}' process (pid '${proc.proc.pid}')`);\n\n log.info(`Sending 'SIGTERM'...`);\n try {\n await proc.stop('SIGTERM', 1000);\n return;\n } catch (err) {\n if (!err.message.includes(`Process didn't end after`)) {\n throw err;\n }\n log.debug(`${name} process did not end in a timely fashion: '${err.message}'.`);\n }\n\n log.info(`Sending 'SIGKILL'...`);\n try {\n await proc.stop('SIGKILL');\n } catch (err) {\n if (err.message.includes('not currently running')) {\n // the process ended but for some reason we were not informed\n return;\n }\n throw err;\n }\n}\n\n/**\n * Generate a random integer.\n *\n * @return {number} A random integer number in range [low, hight). `low`` is inclusive and `high` is exclusive.\n */\nfunction randomInt (low, high) {\n return Math.floor(Math.random() * (high - low) + low);\n}\n\n/**\n * Retrieves WDA upgrade timestamp\n *\n * @return {?number} The UNIX timestamp of the package manifest. The manifest only gets modified on\n * package upgrade.\n */\nasync function getWDAUpgradeTimestamp () {\n const packageManifest = path.resolve(getModuleRoot(), 'package.json');\n if (!await fs.exists(packageManifest)) {\n return null;\n }\n const {mtime} = await fs.stat(packageManifest);\n return mtime.getTime();\n}\n\n/**\n * Kills running XCTest processes for the particular device.\n *\n * @param {string} udid - The device UDID.\n * @param {boolean} isSimulator - Equals to true if the current device is a Simulator\n */\nasync function resetTestProcesses (udid, isSimulator) {\n const processPatterns = [`xcodebuild.*${udid}`];\n if (isSimulator) {\n processPatterns.push(`${udid}.*XCTRunner`);\n // The pattern to find in case idb was used\n processPatterns.push(`xctest.*${udid}`);\n }\n log.debug(`Killing running processes '${processPatterns.join(', ')}' for the device ${udid}...`);\n await B.all(processPatterns.map(killAppUsingPattern));\n}\n\n/**\n * Get the IDs of processes listening on the particular system port.\n * It is also possible to apply additional filtering based on the\n * process command line.\n *\n * @param {string|number} port - The port number.\n * @param {?Function} filteringFunc - Optional lambda function, which\n * receives command line string of the particular process\n * listening on given port, and is expected to return\n * either true or false to include/exclude the corresponding PID\n * from the resulting array.\n * @returns {Array<string>} - the list of matched process ids.\n */\nasync function getPIDsListeningOnPort (port, filteringFunc = null) {\n const result = [];\n try {\n // This only works since Mac OS X El Capitan\n const {stdout} = await exec('lsof', ['-ti', `tcp:${port}`]);\n result.push(...(stdout.trim().split(/\\n+/)));\n } catch (e) {\n if (e.code !== 1) {\n // code 1 means no processes. Other errors need reporting\n log.debug(`Error getting processes listening on port '${port}': ${e.stderr || e.message}`);\n }\n return result;\n }\n\n if (!_.isFunction(filteringFunc)) {\n return result;\n }\n return await B.filter(result, async (pid) => {\n let stdout;\n try {\n ({stdout} = await exec('ps', ['-p', pid, '-o', 'command']));\n } catch (e) {\n if (e.code === 1) {\n // The process does not exist anymore, there's nothing to filter\n return false;\n }\n throw e;\n }\n return await filteringFunc(stdout);\n });\n}\n\nexport { updateProjectFile, resetProjectFile, setRealDeviceSecurity,\n getAdditionalRunContent, getXctestrunFileName, generateXcodeConfigFile,\n setXctestrunFile, getXctestrunFilePath, killProcess, randomInt,\n getWDAUpgradeTimestamp, resetTestProcesses,\n getPIDsListeningOnPort, killAppUsingPattern, isTvOS\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","names":["PROJECT_FILE","getModuleRoot","_","memoize","currentDir","path","dirname","resolve","__filename","isAtFsRoot","manifestPath","join","_fs","existsSync","JSON","parse","readFileSync","name","ign","length","Error","BOOTSTRAP_PATH","getPIDsUsingPattern","pattern","args","stdout","exec","split","map","x","parseInt","filter","isInteger","err","log","debug","code","killAppUsingPattern","pgrepPattern","signals","signal","matchedPids","isEmpty","message","last","waitForCondition","pidCheckPromises","pid","then","catch","B","all","every","waitMs","intervalMs","isTvOS","platformName","toLower","PLATFORM_NAME_TVOS","replaceInFile","file","find","replace","contents","fs","readFile","newContents","writeFile","updateProjectFile","agentPath","newBundleId","projectFilePath","copyFile","RegExp","escapeRegExp","WDA_RUNNER_BUNDLE_ID","warn","resetProjectFile","exists","mv","setRealDeviceSecurity","keychainPath","keychainPassword","generateXcodeConfigFile","orgId","signingId","xcconfigPath","tempDir","setXctestrunFile","deviceInfo","sdkVersion","bootstrapPath","wdaRemotePort","xctestrunFilePath","getXctestrunFilePath","xctestRunContent","plist","parsePlistFile","updateWDAPort","getAdditionalRunContent","newXctestRunContent","merge","updatePlistFile","runner","EnvironmentVariables","USE_PORT","sdkBased","udid","platformBased","platformVersion","filePath","version","info","originalXctestrunFile","getXctestrunFileName","errorAndThrow","isRealDevice","killProcess","proc","isRunning","stop","includes","randomInt","low","high","Math","floor","random","getWDAUpgradeTimestamp","packageManifest","mtime","stat","getTime","resetTestProcesses","isSimulator","processPatterns","push","getPIDsListeningOnPort","port","filteringFunc","result","trim","e","stderr","isFunction"],"sources":["../../lib/utils.js"],"sourcesContent":["import { fs, tempDir, plist } from 'appium/support';\nimport { exec } from 'teen_process';\nimport path from 'path';\nimport log from './logger';\nimport _ from 'lodash';\nimport { WDA_RUNNER_BUNDLE_ID, PLATFORM_NAME_TVOS } from './constants';\nimport B from 'bluebird';\nimport _fs from 'fs';\nimport { waitForCondition } from 'asyncbox';\n\nconst PROJECT_FILE = 'project.pbxproj';\n\n/**\n * Calculates the path to the current module's root folder\n *\n * @returns {string} The full path to module root\n * @throws {Error} If the current module root folder cannot be determined\n */\nconst getModuleRoot = _.memoize(function getModuleRoot () {\n let currentDir = path.dirname(path.resolve(__filename));\n let isAtFsRoot = false;\n while (!isAtFsRoot) {\n const manifestPath = path.join(currentDir, 'package.json');\n try {\n if (_fs.existsSync(manifestPath) &&\n JSON.parse(_fs.readFileSync(manifestPath, 'utf8')).name === 'appium-webdriveragent') {\n return currentDir;\n }\n } catch (ign) {}\n currentDir = path.dirname(currentDir);\n isAtFsRoot = currentDir.length <= path.dirname(currentDir).length;\n }\n throw new Error('Cannot find the root folder of the appium-webdriveragent Node.js module');\n});\n\nexport const BOOTSTRAP_PATH = getModuleRoot();\n\nasync function getPIDsUsingPattern (pattern) {\n const args = [\n '-if', // case insensitive, full cmdline match\n pattern,\n ];\n try {\n const {stdout} = await exec('pgrep', args);\n return stdout.split(/\\s+/)\n .map((x) => parseInt(x, 10))\n .filter(_.isInteger)\n .map((x) => `${x}`);\n } catch (err) {\n log.debug(`'pgrep ${args.join(' ')}' didn't detect any matching processes. Return code: ${err.code}`);\n return [];\n }\n}\n\nasync function killAppUsingPattern (pgrepPattern) {\n const signals = [2, 15, 9];\n for (const signal of signals) {\n const matchedPids = await getPIDsUsingPattern(pgrepPattern);\n if (_.isEmpty(matchedPids)) {\n return;\n }\n const args = [`-${signal}`, ...matchedPids];\n try {\n await exec('kill', args);\n } catch (err) {\n log.debug(`kill ${args.join(' ')} -> ${err.message}`);\n }\n if (signal === _.last(signals)) {\n // there is no need to wait after SIGKILL\n return;\n }\n try {\n await waitForCondition(async () => {\n const pidCheckPromises = matchedPids\n .map((pid) => exec('kill', ['-0', pid])\n // the process is still alive\n .then(() => false)\n // the process is dead\n .catch(() => true)\n );\n return (await B.all(pidCheckPromises))\n .every((x) => x === true);\n }, {\n waitMs: 1000,\n intervalMs: 100,\n });\n return;\n } catch (ign) {\n // try the next signal\n }\n }\n}\n\n/**\n * Return true if the platformName is tvOS\n * @param {string} platformName The name of the platorm\n * @returns {boolean} Return true if the platformName is tvOS\n */\nfunction isTvOS (platformName) {\n return _.toLower(platformName) === _.toLower(PLATFORM_NAME_TVOS);\n}\n\nasync function replaceInFile (file, find, replace) {\n let contents = await fs.readFile(file, 'utf8');\n\n let newContents = contents.replace(find, replace);\n if (newContents !== contents) {\n await fs.writeFile(file, newContents, 'utf8');\n }\n}\n\n/**\n * Update WebDriverAgentRunner project bundle ID with newBundleId.\n * This method assumes project file is in the correct state.\n * @param {string} agentPath - Path to the .xcodeproj directory.\n * @param {string} newBundleId the new bundle ID used to update.\n */\nasync function updateProjectFile (agentPath, newBundleId) {\n let projectFilePath = path.resolve(agentPath, PROJECT_FILE);\n try {\n // Assuming projectFilePath is in the correct state, create .old from projectFilePath\n await fs.copyFile(projectFilePath, `${projectFilePath}.old`);\n await replaceInFile(projectFilePath, new RegExp(_.escapeRegExp(WDA_RUNNER_BUNDLE_ID), 'g'), newBundleId); // eslint-disable-line no-useless-escape\n log.debug(`Successfully updated '${projectFilePath}' with bundle id '${newBundleId}'`);\n } catch (err) {\n log.debug(`Error updating project file: ${err.message}`);\n log.warn(`Unable to update project file '${projectFilePath}' with ` +\n `bundle id '${newBundleId}'. WebDriverAgent may not start`);\n }\n}\n\n/**\n * Reset WebDriverAgentRunner project bundle ID to correct state.\n * @param {string} agentPath - Path to the .xcodeproj directory.\n */\nasync function resetProjectFile (agentPath) {\n const projectFilePath = path.join(agentPath, PROJECT_FILE);\n try {\n // restore projectFilePath from .old file\n if (!await fs.exists(`${projectFilePath}.old`)) {\n return; // no need to reset\n }\n await fs.mv(`${projectFilePath}.old`, projectFilePath);\n log.debug(`Successfully reset '${projectFilePath}' with bundle id '${WDA_RUNNER_BUNDLE_ID}'`);\n } catch (err) {\n log.debug(`Error resetting project file: ${err.message}`);\n log.warn(`Unable to reset project file '${projectFilePath}' with ` +\n `bundle id '${WDA_RUNNER_BUNDLE_ID}'. WebDriverAgent has been ` +\n `modified and not returned to the original state.`);\n }\n}\n\nasync function setRealDeviceSecurity (keychainPath, keychainPassword) {\n log.debug('Setting security for iOS device');\n await exec('security', ['-v', 'list-keychains', '-s', keychainPath]);\n await exec('security', ['-v', 'unlock-keychain', '-p', keychainPassword, keychainPath]);\n await exec('security', ['set-keychain-settings', '-t', '3600', '-l', keychainPath]);\n}\n\nasync function generateXcodeConfigFile (orgId, signingId) {\n log.debug(`Generating xcode config file for orgId '${orgId}' and signingId ` +\n `'${signingId}'`);\n const contents = `DEVELOPMENT_TEAM = ${orgId}\nCODE_SIGN_IDENTITY = ${signingId}\n`;\n const xcconfigPath = await tempDir.path('appium-temp.xcconfig');\n log.debug(`Writing xcode config file to ${xcconfigPath}`);\n await fs.writeFile(xcconfigPath, contents, 'utf8');\n return xcconfigPath;\n}\n\n/**\n * Information of the device under test\n * @typedef {Object} DeviceInfo\n * @property {string} isRealDevice - Equals to true if the current device is a real device\n * @property {string} udid - The device UDID.\n * @property {string} platformVersion - The platform version of OS.\n * @property {string} platformName - The platform name of iOS, tvOS\n*/\n/**\n * Creates xctestrun file per device & platform version.\n * We expects to have WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device\n * and WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator located @bootstrapPath\n * Newer Xcode (Xcode 10.0 at least) generate xctestrun file following sdkVersion.\n * e.g. Xcode which has iOS SDK Version 12.2 generate WebDriverAgentRunner_iphonesimulator.2-x86_64.xctestrun\n * even if the cap has platform version 11.4\n *\n * @param {DeviceInfo} deviceInfo\n * @param {string} sdkVersion - The Xcode SDK version of OS.\n * @param {string} bootstrapPath - The folder path containing xctestrun file.\n * @param {string} wdaRemotePort - The remote port WDA is listening on.\n * @return {string} returns xctestrunFilePath for given device\n * @throws if WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device\n * or WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator is not found @bootstrapPath,\n * then it will throw file not found exception\n */\nasync function setXctestrunFile (deviceInfo, sdkVersion, bootstrapPath, wdaRemotePort) {\n const xctestrunFilePath = await getXctestrunFilePath(deviceInfo, sdkVersion, bootstrapPath);\n const xctestRunContent = await plist.parsePlistFile(xctestrunFilePath);\n const updateWDAPort = getAdditionalRunContent(deviceInfo.platformName, wdaRemotePort);\n const newXctestRunContent = _.merge(xctestRunContent, updateWDAPort);\n await plist.updatePlistFile(xctestrunFilePath, newXctestRunContent, true);\n\n return xctestrunFilePath;\n}\n\n/**\n * Return the WDA object which appends existing xctest runner content\n * @param {string} platformName - The name of the platform\n * @param {string} version - The Xcode SDK version of OS.\n * @return {object} returns a runner object which has USE_PORT\n */\nfunction getAdditionalRunContent (platformName, wdaRemotePort) {\n const runner = `WebDriverAgentRunner${isTvOS(platformName) ? '_tvOS' : ''}`;\n\n return {\n [runner]: {\n EnvironmentVariables: {\n // USE_PORT must be 'string'\n USE_PORT: `${wdaRemotePort}`\n }\n }\n };\n}\n\n/**\n * Return the path of xctestrun if it exists\n * @param {DeviceInfo} deviceInfo\n * @param {string} sdkVersion - The Xcode SDK version of OS.\n * @param {string} bootstrapPath - The folder path containing xctestrun file.\n */\nasync function getXctestrunFilePath (deviceInfo, sdkVersion, bootstrapPath) {\n // First try the SDK path, for Xcode 10 (at least)\n const sdkBased = [\n path.resolve(bootstrapPath, `${deviceInfo.udid}_${sdkVersion}.xctestrun`),\n sdkVersion,\n ];\n // Next try Platform path, for earlier Xcode versions\n const platformBased = [\n path.resolve(bootstrapPath, `${deviceInfo.udid}_${deviceInfo.platformVersion}.xctestrun`),\n deviceInfo.platformVersion,\n ];\n\n for (const [filePath, version] of [sdkBased, platformBased]) {\n if (await fs.exists(filePath)) {\n log.info(`Using '${filePath}' as xctestrun file`);\n return filePath;\n }\n const originalXctestrunFile = path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, version));\n if (await fs.exists(originalXctestrunFile)) {\n // If this is first time run for given device, then first generate xctestrun file for device.\n // We need to have a xctestrun file **per device** because we cant not have same wda port for all devices.\n await fs.copyFile(originalXctestrunFile, filePath);\n log.info(`Using '${filePath}' as xctestrun file copied by '${originalXctestrunFile}'`);\n return filePath;\n }\n }\n\n log.errorAndThrow(`If you are using 'useXctestrunFile' capability then you ` +\n `need to have a xctestrun file (expected: ` +\n `'${path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')`);\n}\n\n\n/**\n * Return the name of xctestrun file\n * @param {DeviceInfo} deviceInfo\n * @param {string} version - The Xcode SDK version of OS.\n * @return {string} returns xctestrunFilePath for given device\n */\nfunction getXctestrunFileName (deviceInfo, version) {\n return isTvOS(deviceInfo.platformName)\n ? `WebDriverAgentRunner_tvOS_appletv${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun`\n : `WebDriverAgentRunner_iphone${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun`;\n}\n\nasync function killProcess (name, proc) {\n if (!proc || !proc.isRunning) {\n return;\n }\n\n log.info(`Shutting down '${name}' process (pid '${proc.proc.pid}')`);\n\n log.info(`Sending 'SIGTERM'...`);\n try {\n await proc.stop('SIGTERM', 1000);\n return;\n } catch (err) {\n if (!err.message.includes(`Process didn't end after`)) {\n throw err;\n }\n log.debug(`${name} process did not end in a timely fashion: '${err.message}'.`);\n }\n\n log.info(`Sending 'SIGKILL'...`);\n try {\n await proc.stop('SIGKILL');\n } catch (err) {\n if (err.message.includes('not currently running')) {\n // the process ended but for some reason we were not informed\n return;\n }\n throw err;\n }\n}\n\n/**\n * Generate a random integer.\n *\n * @return {number} A random integer number in range [low, hight). `low`` is inclusive and `high` is exclusive.\n */\nfunction randomInt (low, high) {\n return Math.floor(Math.random() * (high - low) + low);\n}\n\n/**\n * Retrieves WDA upgrade timestamp\n *\n * @return {?number} The UNIX timestamp of the package manifest. The manifest only gets modified on\n * package upgrade.\n */\nasync function getWDAUpgradeTimestamp () {\n const packageManifest = path.resolve(getModuleRoot(), 'package.json');\n if (!await fs.exists(packageManifest)) {\n return null;\n }\n const {mtime} = await fs.stat(packageManifest);\n return mtime.getTime();\n}\n\n/**\n * Kills running XCTest processes for the particular device.\n *\n * @param {string} udid - The device UDID.\n * @param {boolean} isSimulator - Equals to true if the current device is a Simulator\n */\nasync function resetTestProcesses (udid, isSimulator) {\n const processPatterns = [`xcodebuild.*${udid}`];\n if (isSimulator) {\n processPatterns.push(`${udid}.*XCTRunner`);\n // The pattern to find in case idb was used\n processPatterns.push(`xctest.*${udid}`);\n }\n log.debug(`Killing running processes '${processPatterns.join(', ')}' for the device ${udid}...`);\n await B.all(processPatterns.map(killAppUsingPattern));\n}\n\n/**\n * Get the IDs of processes listening on the particular system port.\n * It is also possible to apply additional filtering based on the\n * process command line.\n *\n * @param {string|number} port - The port number.\n * @param {?Function} filteringFunc - Optional lambda function, which\n * receives command line string of the particular process\n * listening on given port, and is expected to return\n * either true or false to include/exclude the corresponding PID\n * from the resulting array.\n * @returns {Array<string>} - the list of matched process ids.\n */\nasync function getPIDsListeningOnPort (port, filteringFunc = null) {\n const result = [];\n try {\n // This only works since Mac OS X El Capitan\n const {stdout} = await exec('lsof', ['-ti', `tcp:${port}`]);\n result.push(...(stdout.trim().split(/\\n+/)));\n } catch (e) {\n if (e.code !== 1) {\n // code 1 means no processes. Other errors need reporting\n log.debug(`Error getting processes listening on port '${port}': ${e.stderr || e.message}`);\n }\n return result;\n }\n\n if (!_.isFunction(filteringFunc)) {\n return result;\n }\n return await B.filter(result, async (pid) => {\n let stdout;\n try {\n ({stdout} = await exec('ps', ['-p', pid, '-o', 'command']));\n } catch (e) {\n if (e.code === 1) {\n // The process does not exist anymore, there's nothing to filter\n return false;\n }\n throw e;\n }\n return await filteringFunc(stdout);\n });\n}\n\nexport { updateProjectFile, resetProjectFile, setRealDeviceSecurity,\n getAdditionalRunContent, getXctestrunFileName, generateXcodeConfigFile,\n setXctestrunFile, getXctestrunFilePath, killProcess, randomInt,\n getWDAUpgradeTimestamp, resetTestProcesses,\n getPIDsListeningOnPort, killAppUsingPattern, isTvOS\n};\n"],"mappings":"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"}