appium-xcode 4.0.4 → 5.0.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.
@@ -1,152 +1,135 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
- exports.clearInternalCache = clearInternalCache;
8
- exports.getAutomationTraceTemplatePath = void 0;
9
- exports.getAutomationTraceTemplatePathWithoutRetry = getAutomationTraceTemplatePathWithoutRetry;
10
8
  exports.getClangVersion = getClangVersion;
11
- exports.getCommandLineToolsVersion = getCommandLineToolsVersion;
12
- exports.getConnectedDevices = getConnectedDevices;
13
- exports.getMaxIOSSDK = exports.getInstrumentsPath = void 0;
9
+ exports.getMaxIOSSDK = void 0;
14
10
  exports.getMaxIOSSDKWithoutRetry = getMaxIOSSDKWithoutRetry;
15
11
  exports.getMaxTVOSSDK = void 0;
16
12
  exports.getMaxTVOSSDKWithoutRetry = getMaxTVOSSDKWithoutRetry;
17
13
  exports.getPath = void 0;
14
+ exports.getPathFromDeveloperDir = getPathFromDeveloperDir;
15
+ exports.getPathFromXcodeSelect = getPathFromXcodeSelect;
18
16
  exports.getVersion = getVersion;
17
+
19
18
  require("source-map-support/register");
19
+
20
20
  var _support = require("@appium/support");
21
+
21
22
  var _path = _interopRequireDefault(require("path"));
23
+
22
24
  var _asyncbox = require("asyncbox");
25
+
23
26
  var _lodash = _interopRequireDefault(require("lodash"));
24
- var _plist = require("plist");
27
+
25
28
  var _teen_process = require("teen_process");
29
+
26
30
  var _semver = _interopRequireDefault(require("semver"));
27
- const env = process.env;
28
- const XCRUN_TIMEOUT = 15000;
29
- const XCODE_SUBDIR = '/Contents/Developer';
30
- const DEFAULT_NUMBER_OF_RETRIES = 3;
31
+
32
+ var _helpers = require("./helpers");
33
+
34
+ const DEFAULT_NUMBER_OF_RETRIES = 2;
35
+ const XCODE_BUNDLE_ID = 'com.apple.dt.Xcode';
36
+
31
37
  const log = _support.logger.getLogger('Xcode');
32
- function hasExpectedSubDir(path) {
33
- return path.substring(path.length - XCODE_SUBDIR.length) === XCODE_SUBDIR;
34
- }
35
- async function runXcrunCommand(args, timeout = XCRUN_TIMEOUT) {
38
+
39
+ async function getPathFromXcodeSelect(timeout = _helpers.XCRUN_TIMEOUT) {
40
+ const generateErrorMessage = async prefix => {
41
+ const xcodePaths = await (0, _helpers.findAppPaths)(XCODE_BUNDLE_ID);
42
+
43
+ if (_lodash.default.isEmpty(xcodePaths)) {
44
+ return `${prefix}. Consider installing Xcode to address this issue.`;
45
+ }
46
+
47
+ const proposals = xcodePaths.map(p => ` sudo xcode-select -s "${_path.default.join(p, 'Contents', 'Developer')}"`);
48
+ return `${prefix}. ` + `Consider running${proposals.length > 1 ? ' any of' : ''}:\n${'\n'.join(proposals)}\nto address this issue.`;
49
+ };
50
+
51
+ let stdout;
52
+
36
53
  try {
37
- const res = await (0, _teen_process.exec)('xcrun', args, {
54
+ ({
55
+ stdout
56
+ } = await (0, _teen_process.exec)('xcode-select', ['--print-path'], {
38
57
  timeout
39
- });
40
- if (_lodash.default.isUndefined(res)) {
41
- throw new Error(`Nothing returned from trying to run 'xcrun ${args.join(' ')}'`);
42
- }
43
- return res;
44
- } catch (err) {
45
- if (err.stderr) {
46
- err.message = `${err.message}: ${err.stderr}`;
47
- }
48
- throw err;
58
+ }));
59
+ } catch (e) {
60
+ log.errorAndThrow(`Cannot determine the path to Xcode by running 'xcode-select -p' command. ` + `Original error: ${e.stderr || e.message}`);
49
61
  }
50
- }
51
- async function getPathFromSymlink(failMessage) {
52
- log.warn(`Finding XcodePath by symlink because ${failMessage}`);
53
- const symlinkPath = '/var/db/xcode_select_link';
54
- const legacySymlinkPath = '/usr/share/xcode-select/xcode_dir_link';
55
- let xcodePath = null;
56
- if (_support.util.hasContent(env.DEVELOPER_DIR)) {
57
- const customPath = hasExpectedSubDir(env.DEVELOPER_DIR) ? env.DEVELOPER_DIR : env.DEVELOPER_DIR + XCODE_SUBDIR;
58
- if (await _support.fs.exists(customPath)) {
59
- xcodePath = customPath;
60
- } else {
61
- let mesg = `Could not find path to Xcode, environment variable ` + `DEVELOPER_DIR set to: ${env.DEVELOPER_DIR} ` + `but no Xcode found`;
62
- log.warn(mesg);
63
- throw new Error(mesg);
64
- }
65
- } else if (await _support.fs.exists(symlinkPath)) {
66
- xcodePath = await _support.fs.readlink(symlinkPath);
67
- } else if (await _support.fs.exists(legacySymlinkPath)) {
68
- xcodePath = await _support.fs.readlink(legacySymlinkPath);
62
+
63
+ const developerRoot = stdout.replace(/\/$/, '').trim();
64
+
65
+ if (!developerRoot) {
66
+ log.errorAndThrow(await generateErrorMessage(`'xcode-select -p' returned an empty string`));
69
67
  }
70
- if (xcodePath) {
71
- return xcodePath.replace(new RegExp('/$'), '').trim();
68
+
69
+ const {
70
+ CFBundleIdentifier
71
+ } = await (0, _helpers.readXcodePlist)(developerRoot);
72
+
73
+ if (CFBundleIdentifier === XCODE_BUNDLE_ID) {
74
+ return developerRoot;
72
75
  }
73
- let msg = `Could not find path to Xcode by symlinks located in ${symlinkPath}, or ${legacySymlinkPath}`;
74
- log.warn(msg);
75
- throw new Error(msg);
76
+
77
+ log.errorAndThrow(await generateErrorMessage(`'${developerRoot}' is not a valid Xcode path`));
76
78
  }
77
- async function getPathFromXcodeSelect(timeout = XCRUN_TIMEOUT) {
78
- let {
79
- stdout
80
- } = await (0, _teen_process.exec)('xcode-select', ['--print-path'], {
81
- timeout
82
- });
83
- const xcodeFolderPath = stdout.replace(/\/$/, '').trim();
84
- if (!_support.util.hasContent(xcodeFolderPath)) {
85
- log.errorAndThrow('xcode-select returned an empty string');
86
- }
87
- if (await _support.fs.exists(xcodeFolderPath)) {
88
- return xcodeFolderPath;
89
- } else {
90
- const msg = `xcode-select could not find xcode. Path '${xcodeFolderPath}' does not exist.`;
91
- log.errorAndThrow(msg);
79
+
80
+ async function getPathFromDeveloperDir() {
81
+ const developerRoot = process.env.DEVELOPER_DIR;
82
+ const {
83
+ CFBundleIdentifier
84
+ } = await (0, _helpers.readXcodePlist)(developerRoot);
85
+
86
+ if (CFBundleIdentifier === XCODE_BUNDLE_ID) {
87
+ return developerRoot;
92
88
  }
89
+
90
+ log.errorAndThrow(`The path to Xcode Developer dir '${developerRoot}' provided in DEVELOPER_DIR ` + `environment variable is not a valid path`);
93
91
  }
94
- const getPath = _lodash.default.memoize(function getPath(timeout = XCRUN_TIMEOUT) {
95
- return (async () => {
96
- try {
97
- return await getPathFromXcodeSelect(timeout);
98
- } catch (e) {
99
- return await getPathFromSymlink(e.message);
100
- }
101
- })();
92
+
93
+ const getPath = _lodash.default.memoize(function getPath(timeout = _helpers.XCRUN_TIMEOUT) {
94
+ return process.env.DEVELOPER_DIR ? getPathFromDeveloperDir() : getPathFromXcodeSelect(timeout);
102
95
  });
96
+
103
97
  exports.getPath = getPath;
104
- async function getVersionWithoutRetry(timeout = XCRUN_TIMEOUT) {
105
- const xcodePath = await getPath(timeout);
106
- const plistPath = _path.default.resolve(xcodePath, '..', 'Info.plist');
107
- if (!(await _support.fs.exists(plistPath))) {
108
- throw new Error(`Could not get Xcode version. ${plistPath} does not exist on disk.`);
109
- }
110
- const version = await _support.plist.parsePlistFile(plistPath);
111
- return _semver.default.coerce(version.CFBundleShortVersionString);
98
+
99
+ async function getVersionWithoutRetry(timeout = _helpers.XCRUN_TIMEOUT) {
100
+ const developerPath = await getPath(timeout);
101
+ const {
102
+ CFBundleShortVersionString
103
+ } = await (0, _helpers.readXcodePlist)(developerPath);
104
+ return _semver.default.coerce(CFBundleShortVersionString);
112
105
  }
113
- const getVersionMemoized = _lodash.default.memoize(function getVersionMemoized(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = XCRUN_TIMEOUT) {
106
+
107
+ const getVersionMemoized = _lodash.default.memoize(function getVersionMemoized(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = _helpers.XCRUN_TIMEOUT) {
114
108
  return (0, _asyncbox.retry)(retries, getVersionWithoutRetry, timeout);
115
109
  });
116
- async function getVersion(parse = false, retries = DEFAULT_NUMBER_OF_RETRIES, timeout = XCRUN_TIMEOUT) {
110
+
111
+ async function getVersion(parse = false, retries = DEFAULT_NUMBER_OF_RETRIES, timeout = _helpers.XCRUN_TIMEOUT) {
117
112
  const version = await getVersionMemoized(retries, timeout);
118
113
  const versionString = version.patch > 0 ? version.version : `${version.major}.${version.minor}`;
114
+
119
115
  if (!parse) {
120
116
  return versionString;
121
117
  }
118
+
122
119
  return {
123
120
  versionString,
124
121
  versionFloat: parseFloat(versionString),
125
122
  major: version.major,
126
123
  minor: version.minor,
127
124
  patch: version.patch > 0 ? version.patch : undefined,
125
+
128
126
  toString() {
129
127
  return versionString;
130
128
  }
129
+
131
130
  };
132
131
  }
133
- async function getCommandLineToolsVersion() {
134
- const getVersionFunctions = [async () => {
135
- let pkg = (await (0, _teen_process.exec)('pkgutil', ['--pkgs=com.apple.pkg.DevSDK_.*'])).stdout;
136
- return (await (0, _teen_process.exec)('pkgutil', [`--pkg-info=${pkg.trim()}`])).stdout;
137
- }, async () => (await (0, _teen_process.exec)('pkgutil', [`--pkg-info=com.apple.pkg.CLTools_Executables`])).stdout, async () => (await (0, _teen_process.exec)('pkgutil', [`--pkg-info=com.apple.pkg.DeveloperToolsCLI`])).stdout];
138
- let stdout;
139
- for (let getVersion of getVersionFunctions) {
140
- try {
141
- stdout = await getVersion();
142
- break;
143
- } catch (ign) {
144
- stdout = '';
145
- }
146
- }
147
- let match = /^version: (.+)$/m.exec(stdout);
148
- return match ? match[1] : undefined;
149
- }
132
+
150
133
  async function getClangVersion() {
151
134
  try {
152
135
  await _support.fs.which('clang');
@@ -154,134 +137,58 @@ async function getClangVersion() {
154
137
  log.info('Cannot find clang executable on the local system. ' + 'Are Xcode Command Line Tools installed?');
155
138
  return null;
156
139
  }
140
+
157
141
  const {
158
142
  stdout
159
143
  } = await (0, _teen_process.exec)('clang', ['--version']);
160
144
  const match = /clang-([0-9.]+)/.exec(stdout);
145
+
161
146
  if (!match) {
162
147
  log.info(`Cannot parse clang version from ${stdout}`);
163
148
  return null;
164
149
  }
150
+
165
151
  return match[1];
166
152
  }
167
- async function getAutomationTraceTemplatePathWithoutRetry(timeout = XCRUN_TIMEOUT) {
168
- const xcodePath = await getPath(timeout);
169
- const extensions = ['xrplugin', 'bundle'];
170
- const pathPrefix = _path.default.resolve(xcodePath, '../Applications/Instruments.app/Contents/PlugIns');
171
- const pathSuffix = 'Contents/Resources/Automation.tracetemplate';
172
- let automationTraceTemplatePaths = [_path.default.resolve(pathPrefix, `AutomationInstrument.${extensions[0]}`, pathSuffix), _path.default.resolve(pathPrefix, `AutomationInstrument.${extensions[1]}`, pathSuffix)];
173
- if (await _support.fs.exists(automationTraceTemplatePaths[0])) {
174
- return automationTraceTemplatePaths[0];
175
- }
176
- if (await _support.fs.exists(automationTraceTemplatePaths[1])) {
177
- return automationTraceTemplatePaths[1];
178
- }
179
- const msg = 'Could not find Automation.tracetemplate in any of the following' + `locations ${automationTraceTemplatePaths.toString()}`;
180
- log.error(msg);
181
- throw new Error(msg);
182
- }
183
- const getAutomationTraceTemplatePath = _lodash.default.memoize(function getAutomationTraceTemplatePath(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = XCRUN_TIMEOUT) {
184
- return (0, _asyncbox.retry)(retries, getAutomationTraceTemplatePathWithoutRetry, timeout);
185
- });
186
- exports.getAutomationTraceTemplatePath = getAutomationTraceTemplatePath;
187
- async function getMaxIOSSDKWithoutRetry(timeout = XCRUN_TIMEOUT) {
188
- const version = await getVersion(false, DEFAULT_NUMBER_OF_RETRIES, timeout);
189
- if (version[0] === '4') {
190
- return '6.1';
191
- }
153
+
154
+ async function getMaxIOSSDKWithoutRetry(timeout = _helpers.XCRUN_TIMEOUT) {
192
155
  const args = ['--sdk', 'iphonesimulator', '--show-sdk-version'];
193
156
  const {
194
157
  stdout
195
- } = await runXcrunCommand(args, timeout);
158
+ } = await (0, _helpers.runXcrunCommand)(args, timeout);
196
159
  const sdkVersion = stdout.trim();
197
160
  const match = /\d.\d/.exec(stdout);
161
+
198
162
  if (!match) {
199
163
  throw new Error(`xcrun returned a non-numeric iOS SDK version: '${sdkVersion}'`);
200
164
  }
165
+
201
166
  return sdkVersion;
202
167
  }
203
- async function getMaxIOSSDKFromXcodeVersion(timeout = XCRUN_TIMEOUT) {
204
- const version = await getVersion(true, DEFAULT_NUMBER_OF_RETRIES, timeout);
205
- return `${version.major + 2}.${version.minor}`;
206
- }
207
- const getMaxIOSSDK = _lodash.default.memoize(function getMaxIOSSDK(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = XCRUN_TIMEOUT) {
208
- try {
209
- return (0, _asyncbox.retry)(retries, getMaxIOSSDKWithoutRetry, timeout);
210
- } catch (err) {
211
- log.warn(`Unable to retrieve maximum iOS version: ${err.message}`);
212
- log.warn('Guessing from Xcode version');
213
- return getMaxIOSSDKFromXcodeVersion(timeout);
214
- }
168
+
169
+ const getMaxIOSSDK = _lodash.default.memoize(function getMaxIOSSDK(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = _helpers.XCRUN_TIMEOUT) {
170
+ return (0, _asyncbox.retry)(retries, getMaxIOSSDKWithoutRetry, timeout);
215
171
  });
172
+
216
173
  exports.getMaxIOSSDK = getMaxIOSSDK;
217
- async function getMaxTVOSSDKWithoutRetry(timeout = XCRUN_TIMEOUT) {
174
+
175
+ async function getMaxTVOSSDKWithoutRetry(timeout = _helpers.XCRUN_TIMEOUT) {
218
176
  const args = ['--sdk', 'appletvsimulator', '--show-sdk-version'];
219
177
  const {
220
178
  stdout
221
- } = await runXcrunCommand(args, timeout);
179
+ } = await (0, _helpers.runXcrunCommand)(args, timeout);
222
180
  const sdkVersion = stdout.trim();
181
+
223
182
  if (isNaN(parseFloat(sdkVersion))) {
224
183
  throw new Error(`xcrun returned a non-numeric tvOS SDK version: '${sdkVersion}'`);
225
184
  }
185
+
226
186
  return sdkVersion;
227
187
  }
228
- const getMaxTVOSSDK = _lodash.default.memoize(function getMaxTVOSSDK(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = XCRUN_TIMEOUT) {
188
+
189
+ const getMaxTVOSSDK = _lodash.default.memoize(function getMaxTVOSSDK(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = _helpers.XCRUN_TIMEOUT) {
229
190
  return (0, _asyncbox.retry)(retries, getMaxTVOSSDKWithoutRetry, timeout);
230
191
  });
192
+
231
193
  exports.getMaxTVOSSDK = getMaxTVOSSDK;
232
- async function getConnectedDevices(timeout = XCRUN_TIMEOUT) {
233
- const cmd = '/usr/sbin/system_profiler';
234
- const args = ['-xml', 'SPUSBDataType'];
235
- let {
236
- stdout
237
- } = await (0, _teen_process.exec)(cmd, args, {
238
- timeout
239
- });
240
- let plistContent = (0, _plist.parse)(stdout);
241
- let devicesFound = [];
242
- let entriesToSearch = [plistContent[0]];
243
- while (entriesToSearch.length > 0) {
244
- let currentEntry = entriesToSearch.pop();
245
- if (currentEntry instanceof Array) {
246
- entriesToSearch = entriesToSearch.concat(currentEntry);
247
- } else if (currentEntry._name && currentEntry._name.substring(0, 4) === 'iPad' || currentEntry._name && currentEntry._name.substring(0, 6) === 'iPhone' || currentEntry._name && _lodash.default.includes(currentEntry._name, 'Apple TV')) {
248
- let deviceInfo = {
249
- name: currentEntry._name,
250
- udid: currentEntry.serial_num,
251
- productId: currentEntry.product_id,
252
- deviceVersion: currentEntry.bcd_device
253
- };
254
- devicesFound.push(deviceInfo);
255
- } else if (currentEntry._items) {
256
- entriesToSearch = entriesToSearch.concat(currentEntry._items);
257
- }
258
- }
259
- return devicesFound;
260
- }
261
- async function getInstrumentsPathWithoutRetry(timeout = XCRUN_TIMEOUT) {
262
- const args = ['-find', 'instruments'];
263
- let {
264
- stdout
265
- } = await runXcrunCommand(args, timeout);
266
- if (!stdout) {
267
- stdout = '';
268
- }
269
- let instrumentsPath = stdout.trim();
270
- if (!instrumentsPath) {
271
- throw new Error(`Could not find path to instruments binary using 'xcrun ${args.join(' ')}'`);
272
- }
273
- return instrumentsPath;
274
- }
275
- const getInstrumentsPath = _lodash.default.memoize(function getInstrumentsPath(retries = DEFAULT_NUMBER_OF_RETRIES, timeout = XCRUN_TIMEOUT) {
276
- return (0, _asyncbox.retry)(retries, getInstrumentsPathWithoutRetry, timeout);
277
- });
278
- exports.getInstrumentsPath = getInstrumentsPath;
279
- function clearInternalCache() {
280
- const memoized = [getPath, getVersionMemoized, getAutomationTraceTemplatePath, getMaxIOSSDK, getMaxTVOSSDK, getInstrumentsPath];
281
- memoized.forEach(f => {
282
- if (f.cache) {
283
- f.cache = new _lodash.default.memoize.Cache();
284
- }
285
- });
286
- }
287
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJlbnYiLCJwcm9jZXNzIiwiWENSVU5fVElNRU9VVCIsIlhDT0RFX1NVQkRJUiIsIkRFRkFVTFRfTlVNQkVSX09GX1JFVFJJRVMiLCJsb2ciLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJoYXNFeHBlY3RlZFN1YkRpciIsInBhdGgiLCJzdWJzdHJpbmciLCJsZW5ndGgiLCJydW5YY3J1bkNvbW1hbmQiLCJhcmdzIiwidGltZW91dCIsInJlcyIsImV4ZWMiLCJfIiwiaXNVbmRlZmluZWQiLCJFcnJvciIsImpvaW4iLCJlcnIiLCJzdGRlcnIiLCJtZXNzYWdlIiwiZ2V0UGF0aEZyb21TeW1saW5rIiwiZmFpbE1lc3NhZ2UiLCJ3YXJuIiwic3ltbGlua1BhdGgiLCJsZWdhY3lTeW1saW5rUGF0aCIsInhjb2RlUGF0aCIsInV0aWwiLCJoYXNDb250ZW50IiwiREVWRUxPUEVSX0RJUiIsImN1c3RvbVBhdGgiLCJmcyIsImV4aXN0cyIsIm1lc2ciLCJyZWFkbGluayIsInJlcGxhY2UiLCJSZWdFeHAiLCJ0cmltIiwibXNnIiwiZ2V0UGF0aEZyb21YY29kZVNlbGVjdCIsInN0ZG91dCIsInhjb2RlRm9sZGVyUGF0aCIsImVycm9yQW5kVGhyb3ciLCJnZXRQYXRoIiwibWVtb2l6ZSIsImUiLCJnZXRWZXJzaW9uV2l0aG91dFJldHJ5IiwicGxpc3RQYXRoIiwicmVzb2x2ZSIsInZlcnNpb24iLCJwbGlzdCIsInBhcnNlUGxpc3RGaWxlIiwic2VtdmVyIiwiY29lcmNlIiwiQ0ZCdW5kbGVTaG9ydFZlcnNpb25TdHJpbmciLCJnZXRWZXJzaW9uTWVtb2l6ZWQiLCJyZXRyaWVzIiwicmV0cnkiLCJnZXRWZXJzaW9uIiwicGFyc2UiLCJ2ZXJzaW9uU3RyaW5nIiwicGF0Y2giLCJtYWpvciIsIm1pbm9yIiwidmVyc2lvbkZsb2F0IiwicGFyc2VGbG9hdCIsInVuZGVmaW5lZCIsInRvU3RyaW5nIiwiZ2V0Q29tbWFuZExpbmVUb29sc1ZlcnNpb24iLCJnZXRWZXJzaW9uRnVuY3Rpb25zIiwicGtnIiwiaWduIiwibWF0Y2giLCJnZXRDbGFuZ1ZlcnNpb24iLCJ3aGljaCIsImluZm8iLCJnZXRBdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhXaXRob3V0UmV0cnkiLCJleHRlbnNpb25zIiwicGF0aFByZWZpeCIsInBhdGhTdWZmaXgiLCJhdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhzIiwiZXJyb3IiLCJnZXRBdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGgiLCJnZXRNYXhJT1NTREtXaXRob3V0UmV0cnkiLCJzZGtWZXJzaW9uIiwiZ2V0TWF4SU9TU0RLRnJvbVhjb2RlVmVyc2lvbiIsImdldE1heElPU1NESyIsImdldE1heFRWT1NTREtXaXRob3V0UmV0cnkiLCJpc05hTiIsImdldE1heFRWT1NTREsiLCJnZXRDb25uZWN0ZWREZXZpY2VzIiwiY21kIiwicGxpc3RDb250ZW50IiwicGFyc2VQbGlzdERhdGEiLCJkZXZpY2VzRm91bmQiLCJlbnRyaWVzVG9TZWFyY2giLCJjdXJyZW50RW50cnkiLCJwb3AiLCJBcnJheSIsImNvbmNhdCIsIl9uYW1lIiwiaW5jbHVkZXMiLCJkZXZpY2VJbmZvIiwibmFtZSIsInVkaWQiLCJzZXJpYWxfbnVtIiwicHJvZHVjdElkIiwicHJvZHVjdF9pZCIsImRldmljZVZlcnNpb24iLCJiY2RfZGV2aWNlIiwicHVzaCIsIl9pdGVtcyIsImdldEluc3RydW1lbnRzUGF0aFdpdGhvdXRSZXRyeSIsImluc3RydW1lbnRzUGF0aCIsImdldEluc3RydW1lbnRzUGF0aCIsImNsZWFySW50ZXJuYWxDYWNoZSIsIm1lbW9pemVkIiwiZm9yRWFjaCIsImYiLCJjYWNoZSIsIkNhY2hlIl0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3hjb2RlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHV0aWwsIGZzLCBwbGlzdCwgbG9nZ2VyIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgcmV0cnkgfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgcGFyc2UgYXMgcGFyc2VQbGlzdERhdGEgfSBmcm9tICdwbGlzdCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBzZW12ZXIgZnJvbSAnc2VtdmVyJztcblxuXG5jb25zdCBlbnYgPSBwcm9jZXNzLmVudjtcblxuY29uc3QgWENSVU5fVElNRU9VVCA9IDE1MDAwO1xuY29uc3QgWENPREVfU1VCRElSID0gJy9Db250ZW50cy9EZXZlbG9wZXInO1xuY29uc3QgREVGQVVMVF9OVU1CRVJfT0ZfUkVUUklFUyA9IDM7XG5cbmNvbnN0IGxvZyA9IGxvZ2dlci5nZXRMb2dnZXIoJ1hjb2RlJyk7XG5cblxuZnVuY3Rpb24gaGFzRXhwZWN0ZWRTdWJEaXIgKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGguc3Vic3RyaW5nKHBhdGgubGVuZ3RoIC0gWENPREVfU1VCRElSLmxlbmd0aCkgPT09IFhDT0RFX1NVQkRJUjtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuWGNydW5Db21tYW5kIChhcmdzLCB0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICB0cnkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGV4ZWMoJ3hjcnVuJywgYXJncywge3RpbWVvdXR9KTtcbiAgICBpZiAoXy5pc1VuZGVmaW5lZChyZXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdGhpbmcgcmV0dXJuZWQgZnJvbSB0cnlpbmcgdG8gcnVuICd4Y3J1biAke2FyZ3Muam9pbignICcpfSdgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gdGhlIHRydWUgZXJyb3IgY2FuIGJlIGhpZGRlbiB3aXRoaW4gdGhlIHN0ZGVyclxuICAgIGlmIChlcnIuc3RkZXJyKSB7XG4gICAgICBlcnIubWVzc2FnZSA9IGAke2Vyci5tZXNzYWdlfTogJHtlcnIuc3RkZXJyfWA7XG4gICAgfVxuXG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFBhdGhGcm9tU3ltbGluayAoZmFpbE1lc3NhZ2UpIHtcbiAgLy8gTm9kZSdzIGludm9jYXRpb24gb2YgeGNvZGUtc2VsZWN0IHNvbWV0aW1lcyBmbGFrZXMgYW5kIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLlxuICAvLyBOb3QgY2xlYXIgd2h5LiBBcyBhIHdvcmthcm91bmQsIEFwcGl1bSBjYW4gcmVsaWFibHkgZGVkdWNlIHRoZSB2ZXJzaW9uIGluIHVzZSBieSBjaGVja2luZ1xuICAvLyB0aGUgbG9jYXRpb25zIHhjb2RlLXNlbGVjdCB1c2VzIHRvIHN0b3JlIHRoZSBzZWxlY3RlZCB2ZXJzaW9uJ3MgcGF0aC4gVGhpcyBzaG91bGQgYmUgMTAwJVxuICAvLyByZWxpYWJsZSBzbyBsb25nIGFzIHRoZSBsaW5rIGxvY2F0aW9ucyByZW1haW4gdGhlIHNhbWUuIEhvd2V2ZXIsIHNpbmNlIHdlJ3JlIHJlbHlpbmcgb25cbiAgLy8gaGFyZGNvZGVkIHBhdGhzLCB0aGlzIGFwcHJvYWNoIHdpbGwgYnJlYWsgdGhlIG5leHQgdGltZSBBcHBsZSBjaGFuZ2VzIHRoZSBzeW1saW5rIGxvY2F0aW9uLlxuICBsb2cud2FybihgRmluZGluZyBYY29kZVBhdGggYnkgc3ltbGluayBiZWNhdXNlICR7ZmFpbE1lc3NhZ2V9YCk7XG5cbiAgY29uc3Qgc3ltbGlua1BhdGggPSAnL3Zhci9kYi94Y29kZV9zZWxlY3RfbGluayc7XG4gIGNvbnN0IGxlZ2FjeVN5bWxpbmtQYXRoID0gJy91c3Ivc2hhcmUveGNvZGUtc2VsZWN0L3hjb2RlX2Rpcl9saW5rJzsgLy8gIFhjb2RlIDwgNS54XG4gIGxldCB4Y29kZVBhdGggPSBudWxsO1xuXG4gIC8vIHhjb2RlLXNlbGVjdCBhbGxvd3MgdXNlcnMgdG8gb3ZlcnJpZGUgaXRzIHNldHRpbmdzIHdpdGggdGhlIERFVkVMT1BFUl9ESVIgZW52IHZhcixcbiAgLy8gc28gY2hlY2sgdGhhdCBmaXJzdFxuICBpZiAodXRpbC5oYXNDb250ZW50KGVudi5ERVZFTE9QRVJfRElSKSkge1xuICAgIGNvbnN0IGN1c3RvbVBhdGggPSBoYXNFeHBlY3RlZFN1YkRpcihlbnYuREVWRUxPUEVSX0RJUilcbiAgICAgID8gZW52LkRFVkVMT1BFUl9ESVJcbiAgICAgIDogZW52LkRFVkVMT1BFUl9ESVIgKyBYQ09ERV9TVUJESVI7XG5cbiAgICBpZiAoYXdhaXQgZnMuZXhpc3RzKGN1c3RvbVBhdGgpKSB7XG4gICAgICB4Y29kZVBhdGggPSBjdXN0b21QYXRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbWVzZyA9IGBDb3VsZCBub3QgZmluZCBwYXRoIHRvIFhjb2RlLCBlbnZpcm9ubWVudCB2YXJpYWJsZSBgICtcbiAgICAgICAgICAgICAgICAgYERFVkVMT1BFUl9ESVIgc2V0IHRvOiAke2Vudi5ERVZFTE9QRVJfRElSfSBgICtcbiAgICAgICAgICAgICAgICAgYGJ1dCBubyBYY29kZSBmb3VuZGA7XG4gICAgICBsb2cud2FybihtZXNnKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihtZXNnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoYXdhaXQgZnMuZXhpc3RzKHN5bWxpbmtQYXRoKSkge1xuICAgIHhjb2RlUGF0aCA9IGF3YWl0IGZzLnJlYWRsaW5rKHN5bWxpbmtQYXRoKTtcbiAgfSBlbHNlIGlmIChhd2FpdCBmcy5leGlzdHMobGVnYWN5U3ltbGlua1BhdGgpKSB7XG4gICAgeGNvZGVQYXRoID0gYXdhaXQgZnMucmVhZGxpbmsobGVnYWN5U3ltbGlua1BhdGgpO1xuICB9XG5cbiAgaWYgKHhjb2RlUGF0aCkge1xuICAgIHJldHVybiB4Y29kZVBhdGgucmVwbGFjZShuZXcgUmVnRXhwKCcvJCcpLCAnJykudHJpbSgpO1xuICB9XG5cbiAgLy8gV2Ugc2hvdWxkIG9ubHkgZ2V0IGhlcmUgaXMgd2UgZmFpbGVkIHRvIGNhcHR1cmUgeGNvZGUtc2VsZWN0J3Mgc3Rkb3V0IGFuZCBvdXJcbiAgLy8gb3RoZXIgY2hlY2tzIGZhaWxlZC4gRWl0aGVyIEFwcGxlIGhhcyBtb3ZlZCB0aGUgc3ltbGluayB0byBhIG5ldyBsb2NhdGlvbiBvciB0aGUgdXNlclxuICAvLyBpcyBub3QgdXNpbmcgdGhlIGRlZmF1bHQgaW5zdGFsbC4gOTkuOTk5JSBjaGFuY2UgaXQncyB0aGUgbGF0dGVyLCBzbyBpc3N1ZSBhIHdhcm5pbmdcbiAgLy8gc2hvdWxkIHdlIGV2ZXIgaGl0IHRoZSBlZGdlIGNhc2UuXG4gIGxldCBtc2cgPSBgQ291bGQgbm90IGZpbmQgcGF0aCB0byBYY29kZSBieSBzeW1saW5rcyBsb2NhdGVkIGluICR7c3ltbGlua1BhdGh9LCBvciAke2xlZ2FjeVN5bWxpbmtQYXRofWA7XG4gIGxvZy53YXJuKG1zZyk7XG4gIHRocm93IG5ldyBFcnJvcihtc2cpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRQYXRoRnJvbVhjb2RlU2VsZWN0ICh0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBsZXQge3N0ZG91dH0gPSBhd2FpdCBleGVjKCd4Y29kZS1zZWxlY3QnLCBbJy0tcHJpbnQtcGF0aCddLCB7dGltZW91dH0pO1xuXG4gIC8vIHRyaW0gYW5kIHJlbW92ZSB0cmFpbGluZyBzbGFzaFxuICBjb25zdCB4Y29kZUZvbGRlclBhdGggPSBzdGRvdXQucmVwbGFjZSgvXFwvJC8sICcnKS50cmltKCk7XG5cbiAgaWYgKCF1dGlsLmhhc0NvbnRlbnQoeGNvZGVGb2xkZXJQYXRoKSkge1xuICAgIGxvZy5lcnJvckFuZFRocm93KCd4Y29kZS1zZWxlY3QgcmV0dXJuZWQgYW4gZW1wdHkgc3RyaW5nJyk7XG4gIH1cblxuICBpZiAoYXdhaXQgZnMuZXhpc3RzKHhjb2RlRm9sZGVyUGF0aCkpIHtcbiAgICByZXR1cm4geGNvZGVGb2xkZXJQYXRoO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG1zZyA9IGB4Y29kZS1zZWxlY3QgY291bGQgbm90IGZpbmQgeGNvZGUuIFBhdGggJyR7eGNvZGVGb2xkZXJQYXRofScgZG9lcyBub3QgZXhpc3QuYDtcbiAgICBsb2cuZXJyb3JBbmRUaHJvdyhtc2cpO1xuICB9XG59XG5cbmNvbnN0IGdldFBhdGggPSBfLm1lbW9pemUoZnVuY3Rpb24gZ2V0UGF0aCAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgLy8gZmlyc3Qgd2UgdHJ5IHVzaW5nIHhjb2RlLXNlbGVjdCB0byBmaW5kIHRoZSBwYXRoXG4gIC8vIHRoZW4gd2UgdHJ5IHVzaW5nIHRoZSBzeW1saW5rcyB0aGF0IEFwcGxlIGhhcyBieSBkZWZhdWx0XG4gIHJldHVybiAoYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgZ2V0UGF0aEZyb21YY29kZVNlbGVjdCh0aW1lb3V0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgZ2V0UGF0aEZyb21TeW1saW5rKGUubWVzc2FnZSk7XG4gICAgfVxuICB9KSgpO1xufSk7XG5cblxuYXN5bmMgZnVuY3Rpb24gZ2V0VmVyc2lvbldpdGhvdXRSZXRyeSAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgY29uc3QgeGNvZGVQYXRoID0gYXdhaXQgZ2V0UGF0aCh0aW1lb3V0KTtcblxuICAvLyB3ZSB3YW50IHRvIHJlYWQgdGhlIENGQnVuZGxlU2hvcnRWZXJzaW9uU3RyaW5nIGZyb20gWGNvZGUncyBwbGlzdC5cbiAgLy8gSXQgc2hvdWxkIGJlIGluIC9bcm9vdF0vWENvZGUuYXBwL0NvbnRlbnRzL1xuICBjb25zdCBwbGlzdFBhdGggPSBwYXRoLnJlc29sdmUoeGNvZGVQYXRoLCAnLi4nLCAnSW5mby5wbGlzdCcpO1xuXG4gIGlmICghYXdhaXQgZnMuZXhpc3RzKHBsaXN0UGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBnZXQgWGNvZGUgdmVyc2lvbi4gJHtwbGlzdFBhdGh9IGRvZXMgbm90IGV4aXN0IG9uIGRpc2suYCk7XG4gIH1cblxuICBjb25zdCB2ZXJzaW9uID0gYXdhaXQgcGxpc3QucGFyc2VQbGlzdEZpbGUocGxpc3RQYXRoKTtcbiAgcmV0dXJuIHNlbXZlci5jb2VyY2UodmVyc2lvbi5DRkJ1bmRsZVNob3J0VmVyc2lvblN0cmluZyk7XG59XG5cbmNvbnN0IGdldFZlcnNpb25NZW1vaXplZCA9IF8ubWVtb2l6ZShcbiAgZnVuY3Rpb24gZ2V0VmVyc2lvbk1lbW9pemVkIChyZXRyaWVzID0gREVGQVVMVF9OVU1CRVJfT0ZfUkVUUklFUywgdGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgICByZXR1cm4gcmV0cnkocmV0cmllcywgZ2V0VmVyc2lvbldpdGhvdXRSZXRyeSwgdGltZW91dCk7XG4gIH1cbik7XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFZlcnNpb24gKHBhcnNlID0gZmFsc2UsIHJldHJpZXMgPSBERUZBVUxUX05VTUJFUl9PRl9SRVRSSUVTLCB0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBjb25zdCB2ZXJzaW9uID0gYXdhaXQgZ2V0VmVyc2lvbk1lbW9pemVkKHJldHJpZXMsIHRpbWVvdXQpO1xuICAvLyB4Y29kZSB2ZXJzaW9uIHN0cmluZ3MgYXJlIG5vdCBleGFjdGx5IHNlbXZlciBzdHJpbmc6IHBhdGNoIHZlcnNpb25zIG9mIDBcbiAgLy8gYXJlIHJlbW92ZWQgKGUuZy4sICcxMC4wLjAnID0+ICcxMC4wJylcbiAgY29uc3QgdmVyc2lvblN0cmluZyA9IHZlcnNpb24ucGF0Y2ggPiAwID8gdmVyc2lvbi52ZXJzaW9uIDogYCR7dmVyc2lvbi5tYWpvcn0uJHt2ZXJzaW9uLm1pbm9yfWA7XG4gIGlmICghcGFyc2UpIHtcbiAgICByZXR1cm4gdmVyc2lvblN0cmluZztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmVyc2lvblN0cmluZyxcbiAgICB2ZXJzaW9uRmxvYXQ6IHBhcnNlRmxvYXQodmVyc2lvblN0cmluZyksXG4gICAgbWFqb3I6IHZlcnNpb24ubWFqb3IsXG4gICAgbWlub3I6IHZlcnNpb24ubWlub3IsXG4gICAgcGF0Y2g6IHZlcnNpb24ucGF0Y2ggPiAwID8gdmVyc2lvbi5wYXRjaCA6IHVuZGVmaW5lZCxcbiAgICB0b1N0cmluZyAoKSB7XG4gICAgICByZXR1cm4gdmVyc2lvblN0cmluZztcbiAgICB9LFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRDb21tYW5kTGluZVRvb2xzVmVyc2lvbiAoKSB7XG4gIC8vIHRoZXJlIGFyZSBhIG51bWJlciBvZiBkaWZmZXJlbnQgd2F5cyB0aGF0IHRoZSBDTEkgdG9vbHMgdmVyc2lvbiBoYXMgYmVlblxuICAvLyByZXByZXNlbnRlZC4gVHJ5IHRoZW0gZnJvbSBtb3N0IHJlbGlhYmxlIHRvIGxlYXN0LCBmYWxsaW5nIGRvd24gdGhlIGNoYWluXG4gIGNvbnN0IGdldFZlcnNpb25GdW5jdGlvbnMgPSBbXG4gICAgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IHBrZyA9IChhd2FpdCBleGVjKCdwa2d1dGlsJywgWyctLXBrZ3M9Y29tLmFwcGxlLnBrZy5EZXZTREtfLionXSkpLnN0ZG91dDtcbiAgICAgIHJldHVybiAoYXdhaXQgZXhlYygncGtndXRpbCcsIFtgLS1wa2ctaW5mbz0ke3BrZy50cmltKCl9YF0pKS5zdGRvdXQ7XG4gICAgfSxcbiAgICBhc3luYyAoKSA9PiAoYXdhaXQgZXhlYygncGtndXRpbCcsIFtgLS1wa2ctaW5mbz1jb20uYXBwbGUucGtnLkNMVG9vbHNfRXhlY3V0YWJsZXNgXSkpLnN0ZG91dCxcbiAgICBhc3luYyAoKSA9PiAoYXdhaXQgZXhlYygncGtndXRpbCcsIFtgLS1wa2ctaW5mbz1jb20uYXBwbGUucGtnLkRldmVsb3BlclRvb2xzQ0xJYF0pKS5zdGRvdXQsXG4gIF07XG4gIGxldCBzdGRvdXQ7XG4gIGZvciAobGV0IGdldFZlcnNpb24gb2YgZ2V0VmVyc2lvbkZ1bmN0aW9ucykge1xuICAgIHRyeSB7XG4gICAgICBzdGRvdXQgPSBhd2FpdCBnZXRWZXJzaW9uKCk7XG4gICAgICBicmVhaztcbiAgICB9IGNhdGNoIChpZ24pIHtcbiAgICAgIHN0ZG91dCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIC8vIHN0ZG91dCBzaG91bGQgaGF2ZSBhIGxpbmUgbGlrZSBgdmVyc2lvbjogOC4wLjAuMC4xLjE0NzI0MzU4ODFgXG4gIGxldCBtYXRjaCA9IC9edmVyc2lvbjogKC4rKSQvbS5leGVjKHN0ZG91dCk7IC8vIGh0dHBzOi8vcmVnZXgxMDEuY29tL3IvSFYzeDRkLzFcbiAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQ2hlY2sgaHR0cHM6Ly90cmFjLm1hY3BvcnRzLm9yZy93aWtpL1hjb2RlVmVyc2lvbkluZm9cbiAqIHRvIHNlZSB0aGUgYWN0dWFsIG1hcHBpbmcgYmV0d2VlbiBjbGFuZyBhbmQgb3RoZXIgY29tcG9uZW50cy5cbiAqXG4gKiBAcmV0dXJucyB7P3N0cmluZ30gVGhlIGFjdHVhbCBDbGFuZyB2ZXJzaW9uIGluIHgueC54Lnggb3IgeC54LnggZm9ybWF0LFxuICogd2hpY2ggaXMgc3VwcGxpZWQgd2l0aCBDb21tYW5kIExpbmUgVG9vbHMuIGBudWxsYCBpcyByZXR1cm5lZFxuICogaWYgQ0xUIGFyZSBub3QgaW5zdGFsbGVkLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRDbGFuZ1ZlcnNpb24gKCkge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLndoaWNoKCdjbGFuZycpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nLmluZm8oJ0Nhbm5vdCBmaW5kIGNsYW5nIGV4ZWN1dGFibGUgb24gdGhlIGxvY2FsIHN5c3RlbS4gJyArXG4gICAgICAnQXJlIFhjb2RlIENvbW1hbmQgTGluZSBUb29scyBpbnN0YWxsZWQ/Jyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qge3N0ZG91dH0gPSBhd2FpdCBleGVjKCdjbGFuZycsIFsnLS12ZXJzaW9uJ10pO1xuICBjb25zdCBtYXRjaCA9IC9jbGFuZy0oWzAtOS5dKykvLmV4ZWMoc3Rkb3V0KTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIGxvZy5pbmZvKGBDYW5ub3QgcGFyc2UgY2xhbmcgdmVyc2lvbiBmcm9tICR7c3Rkb3V0fWApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBtYXRjaFsxXTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QXV0b21hdGlvblRyYWNlVGVtcGxhdGVQYXRoV2l0aG91dFJldHJ5ICh0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBjb25zdCB4Y29kZVBhdGggPSBhd2FpdCBnZXRQYXRoKHRpbWVvdXQpO1xuXG4gIC8vIGZvciBpb3MgOCBhbmQgdXAsIHRoZSBmaWxlIGV4dGVuc2lvbiBmb3IgQXV0aW9tYXRpb25JbnN0cnVtZW50IGNoYW5nZWQuXG4gIC8vIHJhdGhlciB0aGFuIHdhc3RlIHRpbWUgZ2V0dGluZyB0aGUgaU9TU0RLVmVyc2lvbiwganVzdCBnZXQgYm90aCBwYXRocyBhbmQgc2VlIHdoaWNoIG9uZSBleGlzdHNcbiAgY29uc3QgZXh0ZW5zaW9ucyA9IFsneHJwbHVnaW4nLCAnYnVuZGxlJ107XG4gIGNvbnN0IHBhdGhQcmVmaXggPSBwYXRoLnJlc29sdmUoeGNvZGVQYXRoLCAnLi4vQXBwbGljYXRpb25zL0luc3RydW1lbnRzLmFwcC9Db250ZW50cy9QbHVnSW5zJyk7XG4gIGNvbnN0IHBhdGhTdWZmaXggPSAnQ29udGVudHMvUmVzb3VyY2VzL0F1dG9tYXRpb24udHJhY2V0ZW1wbGF0ZSc7XG4gIGxldCBhdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhzID0gW1xuICAgIHBhdGgucmVzb2x2ZShwYXRoUHJlZml4LCBgQXV0b21hdGlvbkluc3RydW1lbnQuJHtleHRlbnNpb25zWzBdfWAsIHBhdGhTdWZmaXgpLFxuICAgIHBhdGgucmVzb2x2ZShwYXRoUHJlZml4LCBgQXV0b21hdGlvbkluc3RydW1lbnQuJHtleHRlbnNpb25zWzFdfWAsIHBhdGhTdWZmaXgpXG4gIF07XG5cbiAgaWYgKGF3YWl0IGZzLmV4aXN0cyhhdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhzWzBdKSkge1xuICAgIHJldHVybiBhdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhzWzBdO1xuICB9XG5cbiAgaWYgKGF3YWl0IGZzLmV4aXN0cyhhdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhzWzFdKSkge1xuICAgIHJldHVybiBhdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhzWzFdO1xuICB9XG5cbiAgY29uc3QgbXNnID0gJ0NvdWxkIG5vdCBmaW5kIEF1dG9tYXRpb24udHJhY2V0ZW1wbGF0ZSBpbiBhbnkgb2YgdGhlIGZvbGxvd2luZycgK1xuICAgICAgICAgICAgICBgbG9jYXRpb25zICR7YXV0b21hdGlvblRyYWNlVGVtcGxhdGVQYXRocy50b1N0cmluZygpfWA7XG4gIGxvZy5lcnJvcihtc2cpO1xuICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcblxufVxuXG5jb25zdCBnZXRBdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGggPSBfLm1lbW9pemUoXG4gIGZ1bmN0aW9uIGdldEF1dG9tYXRpb25UcmFjZVRlbXBsYXRlUGF0aCAocmV0cmllcyA9IERFRkFVTFRfTlVNQkVSX09GX1JFVFJJRVMsIHRpbWVvdXQgPSBYQ1JVTl9USU1FT1VUKSB7XG4gICAgcmV0dXJuIHJldHJ5KHJldHJpZXMsIGdldEF1dG9tYXRpb25UcmFjZVRlbXBsYXRlUGF0aFdpdGhvdXRSZXRyeSwgdGltZW91dCk7XG4gIH1cbik7XG5cbmFzeW5jIGZ1bmN0aW9uIGdldE1heElPU1NES1dpdGhvdXRSZXRyeSAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgY29uc3QgdmVyc2lvbiA9IGF3YWl0IGdldFZlcnNpb24oZmFsc2UsIERFRkFVTFRfTlVNQkVSX09GX1JFVFJJRVMsIHRpbWVvdXQpO1xuICBpZiAodmVyc2lvblswXSA9PT0gJzQnKSB7XG4gICAgcmV0dXJuICc2LjEnO1xuICB9XG5cbiAgY29uc3QgYXJncyA9IFsnLS1zZGsnLCAnaXBob25lc2ltdWxhdG9yJywgJy0tc2hvdy1zZGstdmVyc2lvbiddO1xuICBjb25zdCB7c3Rkb3V0fSA9IGF3YWl0IHJ1blhjcnVuQ29tbWFuZChhcmdzLCB0aW1lb3V0KTtcblxuICBjb25zdCBzZGtWZXJzaW9uID0gc3Rkb3V0LnRyaW0oKTtcbiAgY29uc3QgbWF0Y2ggPSAvXFxkLlxcZC8uZXhlYyhzdGRvdXQpO1xuXG4gIGlmICghbWF0Y2gpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHhjcnVuIHJldHVybmVkIGEgbm9uLW51bWVyaWMgaU9TIFNESyB2ZXJzaW9uOiAnJHtzZGtWZXJzaW9ufSdgKTtcbiAgfVxuXG4gIHJldHVybiBzZGtWZXJzaW9uO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRNYXhJT1NTREtGcm9tWGNvZGVWZXJzaW9uICh0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBjb25zdCB2ZXJzaW9uID0gYXdhaXQgZ2V0VmVyc2lvbih0cnVlLCBERUZBVUxUX05VTUJFUl9PRl9SRVRSSUVTLCB0aW1lb3V0KTtcbiAgLy8gYXMgb2Ygbm93LCB0aGUgaU9TIHZlcnNpb24gYXNzb2NpYXRlZCB3aXRoIGFuIFhjb2RlIHZlcnNpb24gaXNcbiAgLy8ganVzdCB0aGUgWGNvZGUgdmVyc2lvbiArIDJcbiAgcmV0dXJuIGAke3ZlcnNpb24ubWFqb3IgKyAyfS4ke3ZlcnNpb24ubWlub3J9YDtcbn1cblxuY29uc3QgZ2V0TWF4SU9TU0RLID0gXy5tZW1vaXplKFxuICBmdW5jdGlvbiBnZXRNYXhJT1NTREsgKHJldHJpZXMgPSBERUZBVUxUX05VTUJFUl9PRl9SRVRSSUVTLCB0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmV0cnkocmV0cmllcywgZ2V0TWF4SU9TU0RLV2l0aG91dFJldHJ5LCB0aW1lb3V0KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZy53YXJuKGBVbmFibGUgdG8gcmV0cmlldmUgbWF4aW11bSBpT1MgdmVyc2lvbjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIGxvZy53YXJuKCdHdWVzc2luZyBmcm9tIFhjb2RlIHZlcnNpb24nKTtcbiAgICAgIHJldHVybiBnZXRNYXhJT1NTREtGcm9tWGNvZGVWZXJzaW9uKHRpbWVvdXQpO1xuICAgIH1cbiAgfVxuKTtcblxuYXN5bmMgZnVuY3Rpb24gZ2V0TWF4VFZPU1NES1dpdGhvdXRSZXRyeSAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgY29uc3QgYXJncyA9IFsnLS1zZGsnLCAnYXBwbGV0dnNpbXVsYXRvcicsICctLXNob3ctc2RrLXZlcnNpb24nXTtcbiAgY29uc3Qge3N0ZG91dH0gPSBhd2FpdCBydW5YY3J1bkNvbW1hbmQoYXJncywgdGltZW91dCk7XG5cbiAgY29uc3Qgc2RrVmVyc2lvbiA9IHN0ZG91dC50cmltKCk7XG5cbiAgaWYgKGlzTmFOKHBhcnNlRmxvYXQoc2RrVmVyc2lvbikpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGB4Y3J1biByZXR1cm5lZCBhIG5vbi1udW1lcmljIHR2T1MgU0RLIHZlcnNpb246ICcke3Nka1ZlcnNpb259J2ApO1xuICB9XG5cbiAgcmV0dXJuIHNka1ZlcnNpb247XG59XG5cbmNvbnN0IGdldE1heFRWT1NTREsgPSBfLm1lbW9pemUoXG4gIGZ1bmN0aW9uIGdldE1heFRWT1NTREsgKHJldHJpZXMgPSBERUZBVUxUX05VTUJFUl9PRl9SRVRSSUVTLCB0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICAgIHJldHVybiByZXRyeShyZXRyaWVzLCBnZXRNYXhUVk9TU0RLV2l0aG91dFJldHJ5LCB0aW1lb3V0KTtcbiAgfVxuKTtcblxuYXN5bmMgZnVuY3Rpb24gZ2V0Q29ubmVjdGVkRGV2aWNlcyAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgY29uc3QgY21kID0gJy91c3Ivc2Jpbi9zeXN0ZW1fcHJvZmlsZXInO1xuICBjb25zdCBhcmdzID0gWycteG1sJywgJ1NQVVNCRGF0YVR5cGUnXTtcbiAgbGV0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYyhjbWQsIGFyZ3MsIHt0aW1lb3V0fSk7XG4gIGxldCBwbGlzdENvbnRlbnQgPSBwYXJzZVBsaXN0RGF0YShzdGRvdXQpO1xuXG4gIGxldCBkZXZpY2VzRm91bmQgPSBbXTtcbiAgbGV0IGVudHJpZXNUb1NlYXJjaCA9IFtwbGlzdENvbnRlbnRbMF1dO1xuICB3aGlsZSAoZW50cmllc1RvU2VhcmNoLmxlbmd0aCA+IDApIHtcbiAgICBsZXQgY3VycmVudEVudHJ5ID0gZW50cmllc1RvU2VhcmNoLnBvcCgpO1xuICAgIGlmIChjdXJyZW50RW50cnkgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgZW50cmllc1RvU2VhcmNoID0gZW50cmllc1RvU2VhcmNoLmNvbmNhdChjdXJyZW50RW50cnkpO1xuICAgIH0gZWxzZSBpZiAoKGN1cnJlbnRFbnRyeS5fbmFtZSAmJlxuICAgICAgICAgICAgICAgIGN1cnJlbnRFbnRyeS5fbmFtZS5zdWJzdHJpbmcoMCwgNCkgPT09ICdpUGFkJykgfHxcbiAgICAgICAgICAgICAgIChjdXJyZW50RW50cnkuX25hbWUgJiZcbiAgICAgICAgICAgICAgICBjdXJyZW50RW50cnkuX25hbWUuc3Vic3RyaW5nKDAsIDYpID09PSAnaVBob25lJykgfHxcbiAgICAgICAgICAgICAgIChjdXJyZW50RW50cnkuX25hbWUgJiYgXy5pbmNsdWRlcyhjdXJyZW50RW50cnkuX25hbWUsICdBcHBsZSBUVicpKSkge1xuICAgICAgbGV0IGRldmljZUluZm8gPSB7XG4gICAgICAgIG5hbWU6IGN1cnJlbnRFbnRyeS5fbmFtZSxcbiAgICAgICAgdWRpZDogY3VycmVudEVudHJ5LnNlcmlhbF9udW0sXG4gICAgICAgIHByb2R1Y3RJZDogY3VycmVudEVudHJ5LnByb2R1Y3RfaWQsXG4gICAgICAgIGRldmljZVZlcnNpb246IGN1cnJlbnRFbnRyeS5iY2RfZGV2aWNlXG4gICAgICB9O1xuICAgICAgZGV2aWNlc0ZvdW5kLnB1c2goZGV2aWNlSW5mbyk7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50RW50cnkuX2l0ZW1zKSB7XG4gICAgICBlbnRyaWVzVG9TZWFyY2ggPSBlbnRyaWVzVG9TZWFyY2guY29uY2F0KGN1cnJlbnRFbnRyeS5faXRlbXMpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGV2aWNlc0ZvdW5kO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRJbnN0cnVtZW50c1BhdGhXaXRob3V0UmV0cnkgKHRpbWVvdXQgPSBYQ1JVTl9USU1FT1VUKSB7XG4gIGNvbnN0IGFyZ3MgPSBbJy1maW5kJywgJ2luc3RydW1lbnRzJ107XG4gIGxldCB7c3Rkb3V0fSA9IGF3YWl0IHJ1blhjcnVuQ29tbWFuZChhcmdzLCB0aW1lb3V0KTtcblxuICBpZiAoIXN0ZG91dCkge1xuICAgIHN0ZG91dCA9ICcnO1xuICB9XG5cbiAgbGV0IGluc3RydW1lbnRzUGF0aCA9IHN0ZG91dC50cmltKCk7XG5cbiAgaWYgKCFpbnN0cnVtZW50c1BhdGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBmaW5kIHBhdGggdG8gaW5zdHJ1bWVudHMgYmluYXJ5IHVzaW5nICd4Y3J1biAke2FyZ3Muam9pbignICcpfSdgKTtcbiAgfVxuXG4gIHJldHVybiBpbnN0cnVtZW50c1BhdGg7XG59XG5cbmNvbnN0IGdldEluc3RydW1lbnRzUGF0aCA9IF8ubWVtb2l6ZShcbiAgZnVuY3Rpb24gZ2V0SW5zdHJ1bWVudHNQYXRoIChyZXRyaWVzID0gREVGQVVMVF9OVU1CRVJfT0ZfUkVUUklFUywgdGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgICByZXR1cm4gcmV0cnkocmV0cmllcywgZ2V0SW5zdHJ1bWVudHNQYXRoV2l0aG91dFJldHJ5LCB0aW1lb3V0KTtcbiAgfVxuKTtcblxuZnVuY3Rpb24gY2xlYXJJbnRlcm5hbENhY2hlICgpIHtcblxuICAvLyBtZW1vaXplZCBmdW5jdGlvbnNcbiAgY29uc3QgbWVtb2l6ZWQgPSBbXG4gICAgZ2V0UGF0aCwgZ2V0VmVyc2lvbk1lbW9pemVkLCBnZXRBdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGgsIGdldE1heElPU1NESyxcbiAgICBnZXRNYXhUVk9TU0RLLCBnZXRJbnN0cnVtZW50c1BhdGgsXG4gIF07XG5cbiAgbWVtb2l6ZWQuZm9yRWFjaCgoZikgPT4ge1xuICAgIGlmIChmLmNhY2hlKSB7XG4gICAgICBmLmNhY2hlID0gbmV3IF8ubWVtb2l6ZS5DYWNoZSgpO1xuICAgIH1cbiAgfSk7XG59XG5cbmV4cG9ydCB7XG4gIGdldFBhdGgsIGdldFZlcnNpb24sIGdldEF1dG9tYXRpb25UcmFjZVRlbXBsYXRlUGF0aCwgZ2V0TWF4SU9TU0RLLFxuICBnZXRBdXRvbWF0aW9uVHJhY2VUZW1wbGF0ZVBhdGhXaXRob3V0UmV0cnksIGdldE1heElPU1NES1dpdGhvdXRSZXRyeSxcbiAgZ2V0Q29ubmVjdGVkRGV2aWNlcywgY2xlYXJJbnRlcm5hbENhY2hlLCBnZXRJbnN0cnVtZW50c1BhdGgsXG4gIGdldENvbW1hbmRMaW5lVG9vbHNWZXJzaW9uLCBnZXRNYXhUVk9TU0RLLCBnZXRNYXhUVk9TU0RLV2l0aG91dFJldHJ5LFxuICBnZXRDbGFuZ1ZlcnNpb24sXG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQSxNQUFNQSxHQUFHLEdBQUdDLE9BQU8sQ0FBQ0QsR0FBRztBQUV2QixNQUFNRSxhQUFhLEdBQUcsS0FBSztBQUMzQixNQUFNQyxZQUFZLEdBQUcscUJBQXFCO0FBQzFDLE1BQU1DLHlCQUF5QixHQUFHLENBQUM7QUFFbkMsTUFBTUMsR0FBRyxHQUFHQyxlQUFNLENBQUNDLFNBQVMsQ0FBQyxPQUFPLENBQUM7QUFHckMsU0FBU0MsaUJBQWlCLENBQUVDLElBQUksRUFBRTtFQUNoQyxPQUFPQSxJQUFJLENBQUNDLFNBQVMsQ0FBQ0QsSUFBSSxDQUFDRSxNQUFNLEdBQUdSLFlBQVksQ0FBQ1EsTUFBTSxDQUFDLEtBQUtSLFlBQVk7QUFDM0U7QUFFQSxlQUFlUyxlQUFlLENBQUVDLElBQUksRUFBRUMsT0FBTyxHQUFHWixhQUFhLEVBQUU7RUFDN0QsSUFBSTtJQUNGLE1BQU1h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
194
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJERUZBVUxUX05VTUJFUl9PRl9SRVRSSUVTIiwiWENPREVfQlVORExFX0lEIiwibG9nIiwibG9nZ2VyIiwiZ2V0TG9nZ2VyIiwiZ2V0UGF0aEZyb21YY29kZVNlbGVjdCIsInRpbWVvdXQiLCJYQ1JVTl9USU1FT1VUIiwiZ2VuZXJhdGVFcnJvck1lc3NhZ2UiLCJwcmVmaXgiLCJ4Y29kZVBhdGhzIiwiZmluZEFwcFBhdGhzIiwiXyIsImlzRW1wdHkiLCJwcm9wb3NhbHMiLCJtYXAiLCJwIiwicGF0aCIsImpvaW4iLCJsZW5ndGgiLCJzdGRvdXQiLCJleGVjIiwiZSIsImVycm9yQW5kVGhyb3ciLCJzdGRlcnIiLCJtZXNzYWdlIiwiZGV2ZWxvcGVyUm9vdCIsInJlcGxhY2UiLCJ0cmltIiwiQ0ZCdW5kbGVJZGVudGlmaWVyIiwicmVhZFhjb2RlUGxpc3QiLCJnZXRQYXRoRnJvbURldmVsb3BlckRpciIsInByb2Nlc3MiLCJlbnYiLCJERVZFTE9QRVJfRElSIiwiZ2V0UGF0aCIsIm1lbW9pemUiLCJnZXRWZXJzaW9uV2l0aG91dFJldHJ5IiwiZGV2ZWxvcGVyUGF0aCIsIkNGQnVuZGxlU2hvcnRWZXJzaW9uU3RyaW5nIiwic2VtdmVyIiwiY29lcmNlIiwiZ2V0VmVyc2lvbk1lbW9pemVkIiwicmV0cmllcyIsInJldHJ5IiwiZ2V0VmVyc2lvbiIsInBhcnNlIiwidmVyc2lvbiIsInZlcnNpb25TdHJpbmciLCJwYXRjaCIsIm1ham9yIiwibWlub3IiLCJ2ZXJzaW9uRmxvYXQiLCJwYXJzZUZsb2F0IiwidW5kZWZpbmVkIiwidG9TdHJpbmciLCJnZXRDbGFuZ1ZlcnNpb24iLCJmcyIsIndoaWNoIiwiaW5mbyIsIm1hdGNoIiwiZ2V0TWF4SU9TU0RLV2l0aG91dFJldHJ5IiwiYXJncyIsInJ1blhjcnVuQ29tbWFuZCIsInNka1ZlcnNpb24iLCJFcnJvciIsImdldE1heElPU1NESyIsImdldE1heFRWT1NTREtXaXRob3V0UmV0cnkiLCJpc05hTiIsImdldE1heFRWT1NTREsiXSwic291cmNlcyI6WyIuLi8uLi9saWIveGNvZGUuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnMsIGxvZ2dlciB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHJldHJ5IH0gZnJvbSAnYXN5bmNib3gnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGV4ZWMgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IHtcbiAgcnVuWGNydW5Db21tYW5kLCBmaW5kQXBwUGF0aHMsIFhDUlVOX1RJTUVPVVQsIHJlYWRYY29kZVBsaXN0XG59IGZyb20gJy4vaGVscGVycyc7XG5cbmNvbnN0IERFRkFVTFRfTlVNQkVSX09GX1JFVFJJRVMgPSAyO1xuY29uc3QgWENPREVfQlVORExFX0lEID0gJ2NvbS5hcHBsZS5kdC5YY29kZSc7XG5cbmNvbnN0IGxvZyA9IGxvZ2dlci5nZXRMb2dnZXIoJ1hjb2RlJyk7XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBmdWxsIHBhdGggdG8gWGNvZGUgRGV2ZWxvcGVyIHN1YmZvbGRlciB2aWEgeGNvZGUtc2VsZWN0XG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgVGhlIG1heGltdW0gdGltZW91dCBmb3IgeGNvZGUtc2VsZWN0IGV4ZWN1dGlvblxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gRnVsbCBwYXRoIHRvIFhjb2RlIERldmVsb3BlciBzdWJmb2xkZXJcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCBpcyBub3QgcG9zc2libGUgdG8gcmV0cmlldmUgYSBwcm9wZXIgcGF0aFxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRQYXRoRnJvbVhjb2RlU2VsZWN0ICh0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBjb25zdCBnZW5lcmF0ZUVycm9yTWVzc2FnZSA9IGFzeW5jIChwcmVmaXgpID0+IHtcbiAgICBjb25zdCB4Y29kZVBhdGhzID0gYXdhaXQgZmluZEFwcFBhdGhzKFhDT0RFX0JVTkRMRV9JRCk7XG4gICAgaWYgKF8uaXNFbXB0eSh4Y29kZVBhdGhzKSkge1xuICAgICAgcmV0dXJuIGAke3ByZWZpeH0uIENvbnNpZGVyIGluc3RhbGxpbmcgWGNvZGUgdG8gYWRkcmVzcyB0aGlzIGlzc3VlLmA7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvcG9zYWxzID0geGNvZGVQYXRocy5tYXAoKHApID0+IGAgICAgc3VkbyB4Y29kZS1zZWxlY3QgLXMgXCIke3BhdGguam9pbihwLCAnQ29udGVudHMnLCAnRGV2ZWxvcGVyJyl9XCJgKTtcbiAgICByZXR1cm4gYCR7cHJlZml4fS4gYCArXG4gICAgICBgQ29uc2lkZXIgcnVubmluZyR7cHJvcG9zYWxzLmxlbmd0aCA+IDEgPyAnIGFueSBvZicgOiAnJ306XFxuJHsnXFxuJy5qb2luKHByb3Bvc2Fscyl9XFxudG8gYWRkcmVzcyB0aGlzIGlzc3VlLmA7XG4gIH07XG5cbiAgbGV0IHN0ZG91dDtcbiAgdHJ5IHtcbiAgICAoe3N0ZG91dH0gPSBhd2FpdCBleGVjKCd4Y29kZS1zZWxlY3QnLCBbJy0tcHJpbnQtcGF0aCddLCB7dGltZW91dH0pKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZy5lcnJvckFuZFRocm93KGBDYW5ub3QgZGV0ZXJtaW5lIHRoZSBwYXRoIHRvIFhjb2RlIGJ5IHJ1bm5pbmcgJ3hjb2RlLXNlbGVjdCAtcCcgY29tbWFuZC4gYCArXG4gICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZS5zdGRlcnIgfHwgZS5tZXNzYWdlfWApO1xuICB9XG4gIC8vIHRyaW0gYW5kIHJlbW92ZSB0cmFpbGluZyBzbGFzaFxuICBjb25zdCBkZXZlbG9wZXJSb290ID0gc3Rkb3V0LnJlcGxhY2UoL1xcLyQvLCAnJykudHJpbSgpO1xuICBpZiAoIWRldmVsb3BlclJvb3QpIHtcbiAgICBsb2cuZXJyb3JBbmRUaHJvdyhhd2FpdCBnZW5lcmF0ZUVycm9yTWVzc2FnZShgJ3hjb2RlLXNlbGVjdCAtcCcgcmV0dXJuZWQgYW4gZW1wdHkgc3RyaW5nYCkpO1xuICB9XG4gIC8vIHhjb2RlLXNlbGVjdCBtaWdodCBhbHNvIHJldHVybiBhIHBhdGggdG8gY29tbWFuZCBsaW5lIHRvb2xzXG4gIGNvbnN0IHtDRkJ1bmRsZUlkZW50aWZpZXJ9ID0gYXdhaXQgcmVhZFhjb2RlUGxpc3QoZGV2ZWxvcGVyUm9vdCk7XG4gIGlmIChDRkJ1bmRsZUlkZW50aWZpZXIgPT09IFhDT0RFX0JVTkRMRV9JRCkge1xuICAgIHJldHVybiBkZXZlbG9wZXJSb290O1xuICB9XG5cbiAgbG9nLmVycm9yQW5kVGhyb3coYXdhaXQgZ2VuZXJhdGVFcnJvck1lc3NhZ2UoYCcke2RldmVsb3BlclJvb3R9JyBpcyBub3QgYSB2YWxpZCBYY29kZSBwYXRoYCkpO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgZnVsbCBwYXRoIHRvIFhjb2RlIERldmVsb3BlciBzdWJmb2xkZXIgdmlhIERFVkVMT1BFUl9ESVIgZW52aXJvbm1lbnQgdmFyaWFibGVcbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBGdWxsIHBhdGggdG8gWGNvZGUgRGV2ZWxvcGVyIHN1YmZvbGRlclxuICogQHRocm93cyB7RXJyb3J9IElmIGl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXRyaWV2ZSBhIHByb3BlciBwYXRoXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFBhdGhGcm9tRGV2ZWxvcGVyRGlyICgpIHtcbiAgY29uc3QgZGV2ZWxvcGVyUm9vdCA9IHByb2Nlc3MuZW52LkRFVkVMT1BFUl9ESVI7XG4gIGNvbnN0IHtDRkJ1bmRsZUlkZW50aWZpZXJ9ID0gYXdhaXQgcmVhZFhjb2RlUGxpc3QoZGV2ZWxvcGVyUm9vdCk7XG4gIGlmIChDRkJ1bmRsZUlkZW50aWZpZXIgPT09IFhDT0RFX0JVTkRMRV9JRCkge1xuICAgIHJldHVybiBkZXZlbG9wZXJSb290O1xuICB9XG5cbiAgbG9nLmVycm9yQW5kVGhyb3coYFRoZSBwYXRoIHRvIFhjb2RlIERldmVsb3BlciBkaXIgJyR7ZGV2ZWxvcGVyUm9vdH0nIHByb3ZpZGVkIGluIERFVkVMT1BFUl9ESVIgYCArXG4gICAgYGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBhIHZhbGlkIHBhdGhgKTtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGZ1bGwgcGF0aCB0byBYY29kZSBEZXZlbG9wZXIgc3ViZm9sZGVyLlxuICogSWYgREVWRUxPUEVSX0RJUiBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyBwcm92aWRlZCB0aGVuIGl0cyB2YWx1ZSBoYXMgYSBwcmlvcml0eS5cbiAqXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZW91dCBbMTUwMDBdIFRoZSBtYXhpbXVtIHRpbWVvdXQgZm9yIHhjb2RlLXNlbGVjdCBleGVjdXRpb25cbiAqIEByZXR1cm5zIHtzdHJpbmd9IEZ1bGwgcGF0aCB0byBYY29kZSBEZXZlbG9wZXIgc3ViZm9sZGVyXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGFuIGVycm9yIHdoaWxlIHJldHJpZXZpbmcgdGhlIHBhdGguXG4gKi9cbmNvbnN0IGdldFBhdGggPSBfLm1lbW9pemUoZnVuY3Rpb24gZ2V0UGF0aCAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgcmV0dXJuIHByb2Nlc3MuZW52LkRFVkVMT1BFUl9ESVIgPyBnZXRQYXRoRnJvbURldmVsb3BlckRpcigpIDogZ2V0UGF0aEZyb21YY29kZVNlbGVjdCh0aW1lb3V0KTtcbn0pO1xuXG4vKipcbiAqIFJldHJpZXZlcyBYY29kZSB2ZXJzaW9uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgWzE1MDAwXSBUaW1lb3V0IG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IGZvciB0ZXJtaW5hbCBjb21tYW5kcy5cbiAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcInNlbXZlclwiKS5TZW1WZXIgfCBudWxsPn0gWGNvZGUgdmVyc2lvblxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhIGZhaWx1cmUgd2hpbGUgcmV0cmlldmluZyB0aGUgdmVyc2lvblxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRWZXJzaW9uV2l0aG91dFJldHJ5ICh0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBjb25zdCBkZXZlbG9wZXJQYXRoID0gYXdhaXQgZ2V0UGF0aCh0aW1lb3V0KTtcbiAgLy8gd2Ugd2FudCB0byByZWFkIHRoZSBDRkJ1bmRsZVNob3J0VmVyc2lvblN0cmluZyBmcm9tIFhjb2RlJ3MgcGxpc3QuXG4gIGNvbnN0IHtDRkJ1bmRsZVNob3J0VmVyc2lvblN0cmluZ30gPSBhd2FpdCByZWFkWGNvZGVQbGlzdChkZXZlbG9wZXJQYXRoKTtcbiAgcmV0dXJuIHNlbXZlci5jb2VyY2UoQ0ZCdW5kbGVTaG9ydFZlcnNpb25TdHJpbmcpO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyBYY29kZSB2ZXJzaW9uIG9yIHRoZSBjYWNoZWQgb25lIGlmIGNhbGxlZCBtb3JlIHRoYW4gb25jZVxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSByZXRyaWVzIFsyXSBIb3cgbWFueSByZXRyaWVzIHRvIGFwcGx5IGZvciB2ZXJzaW9uIHJldHJpZXZhbFxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgWzE1MDAwXSBUaW1lb3V0IG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IGZvciB0ZXJtaW5hbCBjb21tYW5kc1xuICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwic2VtdmVyXCIpLlNlbVZlciB8IG51bGw+fSBYY29kZSB2ZXJzaW9uXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGEgZmFpbHVyZSB3aGlsZSByZXRyaWV2aW5nIHRoZSB2ZXJzaW9uXG4gKi9cbmNvbnN0IGdldFZlcnNpb25NZW1vaXplZCA9IF8ubWVtb2l6ZShcbiAgZnVuY3Rpb24gZ2V0VmVyc2lvbk1lbW9pemVkIChyZXRyaWVzID0gREVGQVVMVF9OVU1CRVJfT0ZfUkVUUklFUywgdGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgICByZXR1cm4gcmV0cnkocmV0cmllcywgZ2V0VmVyc2lvbldpdGhvdXRSZXRyeSwgdGltZW91dCk7XG4gIH1cbik7XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gWGNvZGVWZXJzaW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdmVyc2lvblN0cmluZyBYY29kZSB2ZXJzaW9uIGFzIGEgc3RyaW5nXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyc2lvbkZsb2F0IFhjb2RlIHZlcnNpb24gYXMgYSBmbG9hdCBudW1iZXJcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtYWpvciBNYWpvciBudW1iZXIgb2YgWGNvZGUgdmVyc2lvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pbm9yIE1pbm9yIG51bWJlciBvZiBYY29kZSB2ZXJzaW9uXG4gKiBAcHJvcGVydHkge251bWJlcj99IHBhdGNoIFBhdGNoIG51bWJlciBvZiBYY29kZSB2ZXJzaW9uIChpZiBleGlzdHMpXG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZXMgWGNvZGUgdmVyc2lvblxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gcGFyc2UgW2ZhbHNlXSBXaGV0aGVyIHRvIHBhcnNlIHRoZSB2ZXJzaW9uIHRvIGEgWGNvZGVWZXJzaW9uIHZlcnNpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXRyaWVzIFsyXSBIb3cgbWFueSByZXRyaWVzIHRvIGFwcGx5IGZvciBnZXR0aW5nIHRoZSB2ZXJzaW9uIG51bWJlclxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgWzE1MDAwXSBUaW1lb3V0IG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IGZvciB0ZXJtaW5hbCBjb21tYW5kc1xuICogQHJldHVybnMge1Byb21pc2U8WGNvZGVWZXJzaW9uIHwgc3RyaW5nPn0gWGNvZGUgdmVyc2lvbiBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIGBwYXJzZWAgZmxhZ1xuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhIGZhaWx1cmUgd2hpbGUgcmV0cmlldmluZyB0aGUgdmVyc2lvblxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRWZXJzaW9uIChwYXJzZSA9IGZhbHNlLCByZXRyaWVzID0gREVGQVVMVF9OVU1CRVJfT0ZfUkVUUklFUywgdGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgY29uc3QgdmVyc2lvbiA9IGF3YWl0IGdldFZlcnNpb25NZW1vaXplZChyZXRyaWVzLCB0aW1lb3V0KTtcbiAgLy8geGNvZGUgdmVyc2lvbiBzdHJpbmdzIGFyZSBub3QgZXhhY3RseSBzZW12ZXIgc3RyaW5nOiBwYXRjaCB2ZXJzaW9ucyBvZiAwXG4gIC8vIGFyZSByZW1vdmVkIChlLmcuLCAnMTAuMC4wJyA9PiAnMTAuMCcpXG4gIGNvbnN0IHZlcnNpb25TdHJpbmcgPSB2ZXJzaW9uLnBhdGNoID4gMCA/IHZlcnNpb24udmVyc2lvbiA6IGAke3ZlcnNpb24ubWFqb3J9LiR7dmVyc2lvbi5taW5vcn1gO1xuICBpZiAoIXBhcnNlKSB7XG4gICAgcmV0dXJuIHZlcnNpb25TdHJpbmc7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHZlcnNpb25TdHJpbmcsXG4gICAgdmVyc2lvbkZsb2F0OiBwYXJzZUZsb2F0KHZlcnNpb25TdHJpbmcpLFxuICAgIG1ham9yOiB2ZXJzaW9uLm1ham9yLFxuICAgIG1pbm9yOiB2ZXJzaW9uLm1pbm9yLFxuICAgIHBhdGNoOiB2ZXJzaW9uLnBhdGNoID4gMCA/IHZlcnNpb24ucGF0Y2ggOiB1bmRlZmluZWQsXG4gICAgdG9TdHJpbmcgKCkge1xuICAgICAgcmV0dXJuIHZlcnNpb25TdHJpbmc7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBDaGVjayBodHRwczovL3RyYWMubWFjcG9ydHMub3JnL3dpa2kvWGNvZGVWZXJzaW9uSW5mb1xuICogdG8gc2VlIHRoZSBhY3R1YWwgbWFwcGluZyBiZXR3ZWVuIGNsYW5nIGFuZCBvdGhlciBjb21wb25lbnRzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz8+fSBUaGUgYWN0dWFsIENsYW5nIHZlcnNpb24gaW4geC54LngueCBvciB4LngueCBmb3JtYXQsXG4gKiB3aGljaCBpcyBzdXBwbGllZCB3aXRoIENvbW1hbmQgTGluZSBUb29scy4gYG51bGxgIGlzIHJldHVybmVkXG4gKiBpZiBDTFQgYXJlIG5vdCBpbnN0YWxsZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldENsYW5nVmVyc2lvbiAoKSB7XG4gIHRyeSB7XG4gICAgYXdhaXQgZnMud2hpY2goJ2NsYW5nJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2cuaW5mbygnQ2Fubm90IGZpbmQgY2xhbmcgZXhlY3V0YWJsZSBvbiB0aGUgbG9jYWwgc3lzdGVtLiAnICtcbiAgICAgICdBcmUgWGNvZGUgQ29tbWFuZCBMaW5lIFRvb2xzIGluc3RhbGxlZD8nKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCB7c3Rkb3V0fSA9IGF3YWl0IGV4ZWMoJ2NsYW5nJywgWyctLXZlcnNpb24nXSk7XG4gIGNvbnN0IG1hdGNoID0gL2NsYW5nLShbMC05Ll0rKS8uZXhlYyhzdGRvdXQpO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgbG9nLmluZm8oYENhbm5vdCBwYXJzZSBjbGFuZyB2ZXJzaW9uIGZyb20gJHtzdGRvdXR9YCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIG1hdGNoWzFdO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbWF4aW11bSB2ZXJzaW9uIG9mIGlPUyBTREsgc3VwcG9ydGVkIGJ5IHRoZSBpbnN0YWxsZWQgWGNvZGVcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZW91dCBbMTUwMDBdIFRpbWVvdXQgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIHRlcm1pbmFsIGNvbW1hbmRzXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgU0RLIHZlcnNpb25cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgU0RLIHZlcnNpb24gbnVtYmVyIGNhbm5vdCBiZSBkZXRlcm1pbmVkXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldE1heElPU1NES1dpdGhvdXRSZXRyeSAodGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgY29uc3QgYXJncyA9IFsnLS1zZGsnLCAnaXBob25lc2ltdWxhdG9yJywgJy0tc2hvdy1zZGstdmVyc2lvbiddO1xuICBjb25zdCB7c3Rkb3V0fSA9IGF3YWl0IHJ1blhjcnVuQ29tbWFuZChhcmdzLCB0aW1lb3V0KTtcbiAgY29uc3Qgc2RrVmVyc2lvbiA9IHN0ZG91dC50cmltKCk7XG4gIGNvbnN0IG1hdGNoID0gL1xcZC5cXGQvLmV4ZWMoc3Rkb3V0KTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgeGNydW4gcmV0dXJuZWQgYSBub24tbnVtZXJpYyBpT1MgU0RLIHZlcnNpb246ICcke3Nka1ZlcnNpb259J2ApO1xuICB9XG4gIHJldHVybiBzZGtWZXJzaW9uO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbWF4aW11bSB2ZXJzaW9uIG9mIGlPUyBTREsgc3VwcG9ydGVkIGJ5IHRoZSBpbnN0YWxsZWQgWGNvZGVcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZW91dCBbMTUwMDBdIFRpbWVvdXQgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIHRlcm1pbmFsIGNvbW1hbmRzXG4gKiBAcGFyYW0ge251bWJlcn0gcmV0cmllcyBbMl0gVGhlIG1heGltdW0gbnVtYmVyIG9mIHJldHJpZXNcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBTREsgdmVyc2lvblxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBTREsgdmVyc2lvbiBudW1iZXIgY2Fubm90IGJlIGRldGVybWluZWRcbiAqL1xuY29uc3QgZ2V0TWF4SU9TU0RLID0gXy5tZW1vaXplKFxuICBmdW5jdGlvbiBnZXRNYXhJT1NTREsgKHJldHJpZXMgPSBERUZBVUxUX05VTUJFUl9PRl9SRVRSSUVTLCB0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICAgIHJldHVybiByZXRyeShyZXRyaWVzLCBnZXRNYXhJT1NTREtXaXRob3V0UmV0cnksIHRpbWVvdXQpO1xuICB9XG4pO1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbWF4aW11bSB2ZXJzaW9uIG9mIHR2T1MgU0RLIHN1cHBvcnRlZCBieSB0aGUgaW5zdGFsbGVkIFhjb2RlXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgWzE1MDAwXSBUaW1lb3V0IG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IGZvciB0ZXJtaW5hbCBjb21tYW5kc1xuICogQHJldHVybnMge3N0cmluZ30gVGhlIFNESyB2ZXJzaW9uXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIFNESyB2ZXJzaW9uIG51bWJlciBjYW5ub3QgYmUgZGV0ZXJtaW5lZFxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRNYXhUVk9TU0RLV2l0aG91dFJldHJ5ICh0aW1lb3V0ID0gWENSVU5fVElNRU9VVCkge1xuICBjb25zdCBhcmdzID0gWyctLXNkaycsICdhcHBsZXR2c2ltdWxhdG9yJywgJy0tc2hvdy1zZGstdmVyc2lvbiddO1xuICBjb25zdCB7c3Rkb3V0fSA9IGF3YWl0IHJ1blhjcnVuQ29tbWFuZChhcmdzLCB0aW1lb3V0KTtcbiAgY29uc3Qgc2RrVmVyc2lvbiA9IHN0ZG91dC50cmltKCk7XG4gIGlmIChpc05hTihwYXJzZUZsb2F0KHNka1ZlcnNpb24pKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgeGNydW4gcmV0dXJuZWQgYSBub24tbnVtZXJpYyB0dk9TIFNESyB2ZXJzaW9uOiAnJHtzZGtWZXJzaW9ufSdgKTtcbiAgfVxuICByZXR1cm4gc2RrVmVyc2lvbjtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIG1heGltdW0gdmVyc2lvbiBvZiB0dk9TIFNESyBzdXBwb3J0ZWQgYnkgdGhlIGluc3RhbGxlZCBYY29kZVxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IFsxNTAwMF0gVGltZW91dCBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgdGVybWluYWwgY29tbWFuZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSByZXRyaWVzIFsyXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgcmV0cmllc1xuICogQHJldHVybnMge3N0cmluZ30gVGhlIFNESyB2ZXJzaW9uXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIFNESyB2ZXJzaW9uIG51bWJlciBjYW5ub3QgYmUgZGV0ZXJtaW5lZFxuICovXG5jb25zdCBnZXRNYXhUVk9TU0RLID0gXy5tZW1vaXplKFxuICBmdW5jdGlvbiBnZXRNYXhUVk9TU0RLIChyZXRyaWVzID0gREVGQVVMVF9OVU1CRVJfT0ZfUkVUUklFUywgdGltZW91dCA9IFhDUlVOX1RJTUVPVVQpIHtcbiAgICByZXR1cm4gcmV0cnkocmV0cmllcywgZ2V0TWF4VFZPU1NES1dpdGhvdXRSZXRyeSwgdGltZW91dCk7XG4gIH1cbik7XG5cbmV4cG9ydCB7XG4gIGdldFBhdGgsIGdldFZlcnNpb24sIGdldE1heElPU1NESywgZ2V0TWF4SU9TU0RLV2l0aG91dFJldHJ5LFxuICBnZXRNYXhUVk9TU0RLLCBnZXRNYXhUVk9TU0RLV2l0aG91dFJldHJ5LCBnZXRDbGFuZ1ZlcnNpb24sXG4gIGdldFBhdGhGcm9tRGV2ZWxvcGVyRGlyLCBnZXRQYXRoRnJvbVhjb2RlU2VsZWN0LFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUlBLE1BQU1BLHlCQUF5QixHQUFHLENBQWxDO0FBQ0EsTUFBTUMsZUFBZSxHQUFHLG9CQUF4Qjs7QUFFQSxNQUFNQyxHQUFHLEdBQUdDLGVBQUEsQ0FBT0MsU0FBUCxDQUFpQixPQUFqQixDQUFaOztBQVNBLGVBQWVDLHNCQUFmLENBQXVDQyxPQUFPLEdBQUdDLHNCQUFqRCxFQUFnRTtFQUM5RCxNQUFNQyxvQkFBb0IsR0FBRyxNQUFPQyxNQUFQLElBQWtCO0lBQzdDLE1BQU1DLFVBQVUsR0FBRyxNQUFN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
package/index.js CHANGED
@@ -1,21 +1,25 @@
1
1
  // transpile:main
2
-
3
- import * as xcode from './lib/xcode';
4
-
5
-
6
- const {
7
- getPath, getVersion, getAutomationTraceTemplatePath, getMaxIOSSDK,
8
- getAutomationTraceTemplatePathWithoutRetry, getMaxIOSSDKWithoutRetry,
9
- getConnectedDevices, clearInternalCache, getInstrumentsPath,
10
- getCommandLineToolsVersion, getMaxTVOSSDK, getMaxTVOSSDKWithoutRetry,
2
+ import {
3
+ getPath,
4
+ getVersion,
5
+ getMaxIOSSDK,
6
+ getMaxTVOSSDK,
11
7
  getClangVersion,
12
- } = xcode;
8
+ } from './lib/xcode';
9
+
10
+ const xcode = {
11
+ getPath,
12
+ getVersion,
13
+ getMaxIOSSDK,
14
+ getMaxTVOSSDK,
15
+ getClangVersion
16
+ };
13
17
 
14
18
  export {
15
- getPath, getVersion, getAutomationTraceTemplatePath, getMaxIOSSDK,
16
- getAutomationTraceTemplatePathWithoutRetry, getMaxIOSSDKWithoutRetry,
17
- getConnectedDevices, clearInternalCache, getInstrumentsPath,
18
- getCommandLineToolsVersion, getMaxTVOSSDK, getMaxTVOSSDKWithoutRetry,
19
- getClangVersion,
19
+ getPath,
20
+ getVersion,
21
+ getMaxIOSSDK,
22
+ getMaxTVOSSDK,
23
+ getClangVersion
20
24
  };
21
25
  export default xcode;
package/lib/helpers.js ADDED
@@ -0,0 +1,72 @@
1
+ import _ from 'lodash';
2
+ import B from 'bluebird';
3
+ import { exec } from 'teen_process';
4
+ import { fs, plist } from '@appium/support';
5
+ import path from 'path';
6
+
7
+ export const XCRUN_TIMEOUT = 15000;
8
+
9
+ /**
10
+ * Executes 'xcrun' command line utility
11
+ *
12
+ * @param {string[]} args xcrun arguments
13
+ * @param {number} timeout [15000] The maximum number of milliseconds to wait until xcrun exists
14
+ * @returns {Promise<import("teen_process").ExecResult>} The result of xcrun execution
15
+ * @throws {Error} If xcrun returned non-zero exit code or timed out
16
+ */
17
+ export async function runXcrunCommand (args, timeout = XCRUN_TIMEOUT) {
18
+ try {
19
+ return await exec('xcrun', args, {timeout});
20
+ } catch (err) {
21
+ // the true error can be hidden within the stderr
22
+ if (err.stderr) {
23
+ err.message = `${err.message}: ${err.stderr}`;
24
+ }
25
+
26
+ throw err;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Uses macOS Spotlight service to detect where the given app is installed
32
+ *
33
+ * @param {string} bundleId Bundle identifier of the target app
34
+ * @returns {Promise<string[]>} Full paths to where the app with the given bundle id is present.
35
+ */
36
+ export async function findAppPaths (bundleId) {
37
+ let stdout;
38
+ try {
39
+ ({stdout} = await exec('/usr/bin/mdfind', [
40
+ `kMDItemCFBundleIdentifier=${bundleId}`
41
+ ]));
42
+ } catch (e) {
43
+ return [];
44
+ }
45
+
46
+ const matchedPaths = _.trim(stdout)
47
+ .split('\n')
48
+ .map(_.trim)
49
+ .filter(Boolean);
50
+ if (_.isEmpty(matchedPaths)) {
51
+ return [];
52
+ }
53
+ const results = matchedPaths.map((p) => (async () => {
54
+ if (await fs.exists(p)) {
55
+ return p;
56
+ }
57
+ })());
58
+ return (await B.all(results)).filter(Boolean);
59
+ }
60
+
61
+ /**
62
+ * Finds and retrieves the content of the Xcode's Info.plist file
63
+ *
64
+ * @param {string} developerRoot Full path to the Contents/Developer folder under Xcode.app root
65
+ * @returns {Promise<object>} All plist entries as an object or an empty object if no plist was found
66
+ */
67
+ export async function readXcodePlist (developerRoot) {
68
+ const plistPath = path.resolve(developerRoot, '..', 'Info.plist');
69
+ return await fs.exists(plistPath)
70
+ ? await plist.parsePlistFile(plistPath)
71
+ : {};
72
+ }