UNPKG

appium-xcuitest-driver-conan

Version:

Appium driver for iOS using XCUITest for backend

448 lines (349 loc) 25.9 kB
'use strict'; var _regeneratorRuntime = require('babel-runtime/regenerator')['default']; var _getIterator = require('babel-runtime/core-js/get-iterator')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _appiumSupport = require('appium-support'); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _appiumIosDriver = require('appium-ios-driver'); var _teen_process = require('teen_process'); var _appiumXcode = require('appium-xcode'); var _appiumXcode2 = _interopRequireDefault(_appiumXcode); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); var _packageJson = require('../../package.json'); var _packageJson2 = _interopRequireDefault(_packageJson); // eslint-disable-line import/no-unresolved var WDA_DERIVED_DATA_SEARCH_SUFFIX = 'Library/Developer/Xcode/DerivedData/WebDriverAgent-*'; var WDA_ATTACHMENTS_FOLDER_RELATIVE_PATH = 'Logs/Test/Attachments'; var DRIVER_VER = _packageJson2['default'].version; function detectUdid() { var cmd, args, udid, _ref, stdout, udids; return _regeneratorRuntime.async(function detectUdid$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _logger2['default'].debug('Auto-detecting real device udid...'); cmd = undefined, args = []; context$1$0.prev = 2; context$1$0.next = 5; return _regeneratorRuntime.awrap(_appiumSupport.fs.which('idevice_id')); case 5: cmd = context$1$0.sent; args.push('-l'); _logger2['default'].debug('Using idevice_id'); context$1$0.next = 14; break; case 10: context$1$0.prev = 10; context$1$0.t0 = context$1$0['catch'](2); _logger2['default'].debug('Using udidetect'); cmd = require.resolve('udidetect'); case 14: udid = undefined; context$1$0.prev = 15; context$1$0.next = 18; return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, args, { timeout: 3000 })); case 18: _ref = context$1$0.sent; stdout = _ref.stdout; udids = _lodash2['default'].filter(stdout.split('\n'), Boolean); udid = _lodash2['default'].last(udids); if (udids.length > 1) { _logger2['default'].warn('Multiple devices found: ' + udids.join(', ')); _logger2['default'].warn('Choosing \'' + udid + '\'. If this is wrong, manually set with \'udid\' desired capability'); } context$1$0.next = 28; break; case 25: context$1$0.prev = 25; context$1$0.t1 = context$1$0['catch'](15); _logger2['default'].errorAndThrow('Error detecting udid: ' + context$1$0.t1.message); case 28: if (!(!udid || udid.length <= 2)) { context$1$0.next = 30; break; } throw new Error('Could not detect udid.'); case 30: _logger2['default'].debug('Detected real device udid: \'' + udid + '\''); return context$1$0.abrupt('return', udid); case 32: case 'end': return context$1$0.stop(); } }, null, this, [[2, 10], [15, 25]]); } function getAndCheckXcodeVersion() { var version; return _regeneratorRuntime.async(function getAndCheckXcodeVersion$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: version = undefined; context$1$0.prev = 1; context$1$0.next = 4; return _regeneratorRuntime.awrap(_appiumXcode2['default'].getVersion(true)); case 4: version = context$1$0.sent; context$1$0.next = 11; break; case 7: context$1$0.prev = 7; context$1$0.t0 = context$1$0['catch'](1); _logger2['default'].debug(context$1$0.t0); _logger2['default'].errorAndThrow('Could not determine Xcode version: ' + context$1$0.t0.message); case 11: if (version.toolsVersion) { context$1$0.next = 20; break; } context$1$0.prev = 12; context$1$0.next = 15; return _regeneratorRuntime.awrap(_appiumXcode2['default'].getCommandLineToolsVersion()); case 15: version.toolsVersion = context$1$0.sent; context$1$0.next = 20; break; case 18: context$1$0.prev = 18; context$1$0.t1 = context$1$0['catch'](12); case 20: // we do not support Xcodes < 7.3, if (version.versionFloat < 7.3) { _logger2['default'].errorAndThrow('Xcode version \'' + version.versionString + '\'. Support for ' + ('Xcode ' + version.versionString + ' is not supported. ') + 'Please upgrade to version 7.3 or higher'); } return context$1$0.abrupt('return', version); case 22: case 'end': return context$1$0.stop(); } }, null, this, [[1, 7], [12, 18]]); } function getAndCheckIosSdkVersion() { var versionNumber; return _regeneratorRuntime.async(function getAndCheckIosSdkVersion$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: versionNumber = undefined; context$1$0.prev = 1; context$1$0.next = 4; return _regeneratorRuntime.awrap(_appiumXcode2['default'].getMaxIOSSDK()); case 4: versionNumber = context$1$0.sent; context$1$0.next = 10; break; case 7: context$1$0.prev = 7; context$1$0.t0 = context$1$0['catch'](1); _logger2['default'].errorAndThrow('Could not determine iOS SDK version: ' + context$1$0.t0.message); case 10: return context$1$0.abrupt('return', versionNumber); case 11: case 'end': return context$1$0.stop(); } }, null, this, [[1, 7]]); } function killAppUsingAppName(udid, appName) { var psArgs; return _regeneratorRuntime.async(function killAppUsingAppName$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: psArgs = ['-c', 'ps -ax|grep -i "' + appName + '"|grep -i "' + udid + '"|grep -v grep|awk \'{print "kill -9 " $1}\'|sh']; context$1$0.prev = 1; context$1$0.next = 4; return _regeneratorRuntime.awrap((0, _teen_process.exec)('bash', psArgs)); case 4: context$1$0.next = 9; break; case 6: context$1$0.prev = 6; context$1$0.t0 = context$1$0['catch'](1); _logger2['default'].debug('Error : ' + context$1$0.t0.message); case 9: case 'end': return context$1$0.stop(); } }, null, this, [[1, 6]]); } function adjustWDAAttachmentsPermissions(perms) { var derivedDataSearchMask, folders, changesMade, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, folder, attachmentsFolder; return _regeneratorRuntime.async(function adjustWDAAttachmentsPermissions$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (process.env.HOME) { context$1$0.next = 2; break; } throw new Error('Need HOME env var to be set in order to adjust WDA attachments permission'); case 2: derivedDataSearchMask = _path2['default'].join(process.env.HOME, WDA_DERIVED_DATA_SEARCH_SUFFIX); context$1$0.next = 5; return _regeneratorRuntime.awrap(_appiumSupport.fs.glob(derivedDataSearchMask)); case 5: folders = context$1$0.sent; changesMade = false; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; context$1$0.prev = 10; _iterator = _getIterator(folders); case 12: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { context$1$0.next = 26; break; } folder = _step.value; _logger2['default'].debug('Found WDA derived data folder: \'' + folder + '\''); attachmentsFolder = _path2['default'].join(folder, WDA_ATTACHMENTS_FOLDER_RELATIVE_PATH); context$1$0.next = 18; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(attachmentsFolder)); case 18: if (!context$1$0.sent) { context$1$0.next = 23; break; } _logger2['default'].info('Setting \'' + perms + '\' permissions to \'' + attachmentsFolder + '\' folder'); context$1$0.next = 22; return _regeneratorRuntime.awrap(_appiumSupport.fs.chmod(attachmentsFolder, perms)); case 22: changesMade = true; case 23: _iteratorNormalCompletion = true; context$1$0.next = 12; break; case 26: context$1$0.next = 32; break; case 28: context$1$0.prev = 28; context$1$0.t0 = context$1$0['catch'](10); _didIteratorError = true; _iteratorError = context$1$0.t0; case 32: context$1$0.prev = 32; context$1$0.prev = 33; if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } case 35: context$1$0.prev = 35; if (!_didIteratorError) { context$1$0.next = 38; break; } throw _iteratorError; case 38: return context$1$0.finish(35); case 39: return context$1$0.finish(32); case 40: if (!changesMade) { _logger2['default'].info('No WDA derived data folders have been found.'); } case 41: case 'end': return context$1$0.stop(); } }, null, this, [[10, 28, 32, 40], [33,, 35, 39]]); } function clearSystemFiles(wda) { var toDelete; return _regeneratorRuntime.async(function clearSystemFiles$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (!(!wda || !wda.derivedDataPath)) { context$1$0.next = 3; break; } _logger2['default'].debug('No WebDriverAgent derived data available, so unable to clear system files'); return context$1$0.abrupt('return'); case 3: toDelete = [_path2['default'].resolve(wda.derivedDataPath, 'Logs')]; context$1$0.next = 6; return _regeneratorRuntime.awrap(_appiumIosDriver.utils.clearLogs(toDelete)); case 6: case 'end': return context$1$0.stop(); } }, null, this); } function generateXcodeConfigFile(orgId, signingId) { var contents, xcconfigPath; return _regeneratorRuntime.async(function generateXcodeConfigFile$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _logger2['default'].debug('Generating xcode config file for orgId \'' + orgId + '\' and signingId ' + ('\'' + signingId + '\'')); contents = 'DEVELOPMENT_TEAM = ' + orgId + '\nCODE_SIGN_IDENTITY = ' + signingId + '\n'; context$1$0.next = 4; return _regeneratorRuntime.awrap(_appiumSupport.tempDir.path('appium-temp.xcconfig')); case 4: xcconfigPath = context$1$0.sent; _logger2['default'].debug('Writing xcode config file to ' + xcconfigPath); context$1$0.next = 8; return _regeneratorRuntime.awrap(_appiumSupport.fs.writeFile(xcconfigPath, contents, "utf8")); case 8: return context$1$0.abrupt('return', xcconfigPath); case 9: case 'end': return context$1$0.stop(); } }, null, this); } function checkAppPresent(app) { return _regeneratorRuntime.async(function checkAppPresent$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _logger2['default'].debug('Checking whether app \'' + app + '\' is actually present on file system'); context$1$0.next = 3; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(app)); case 3: if (context$1$0.sent) { context$1$0.next = 5; break; } _logger2['default'].errorAndThrow('Could not find app at \'' + app + '\''); case 5: _logger2['default'].debug('App is present'); case 6: case 'end': return context$1$0.stop(); } }, null, this); } function getDriverInfo() { var stat, built, info; return _regeneratorRuntime.async(function getDriverInfo$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.stat(_path2['default'].resolve(__dirname, '..'))); case 2: stat = context$1$0.sent; built = stat.mtime.getTime(); info = { built: built, version: DRIVER_VER }; return context$1$0.abrupt('return', info); case 6: case 'end': return context$1$0.stop(); } }, null, this); } exports.detectUdid = detectUdid; exports.getAndCheckXcodeVersion = getAndCheckXcodeVersion; exports.getAndCheckIosSdkVersion = getAndCheckIosSdkVersion; exports.killAppUsingAppName = killAppUsingAppName; exports.adjustWDAAttachmentsPermissions = adjustWDAAttachmentsPermissions; exports.generateXcodeConfigFile = generateXcodeConfigFile; exports.checkAppPresent = checkAppPresent; exports.getDriverInfo = getDriverInfo; exports.clearSystemFiles = clearSystemFiles; // only want to clear the system files for the particular WDA xcode run //# sourceMappingURL=data:application/json;charset=utf8;base64,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RUFBRSxJQUFJLENBQUMsQ0FBQzs7O0FBQW5ELFlBQUk7QUFDSixhQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUU7QUFDNUIsWUFBSSxHQUFHO0FBQ1QsZUFBSyxFQUFMLEtBQUs7QUFDTCxpQkFBTyxFQUFFLFVBQVU7U0FDcEI7NENBQ00sSUFBSTs7Ozs7OztDQUNaOztRQUVRLFVBQVUsR0FBVixVQUFVO1FBQUUsdUJBQXVCLEdBQXZCLHVCQUF1QjtRQUFFLHdCQUF3QixHQUF4Qix3QkFBd0I7UUFDN0QsbUJBQW1CLEdBQW5CLG1CQUFtQjtRQUFFLCtCQUErQixHQUEvQiwrQkFBK0I7UUFDcEQsdUJBQXVCLEdBQXZCLHVCQUF1QjtRQUFFLGVBQWUsR0FBZixlQUFlO1FBQUUsYUFBYSxHQUFiLGFBQWE7UUFDdkQsZ0JBQWdCLEdBQWhCLGdCQUFnQiIsImZpbGUiOiJsaWIvdXRpbHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmcywgdGVtcERpciB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgdXRpbHMgYXMgaW9zVXRpbHMgfSBmcm9tICdhcHBpdW0taW9zLWRyaXZlcic7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCB4Y29kZSBmcm9tICdhcHBpdW0teGNvZGUnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHBrZ09iaiBmcm9tICcuLi8uLi9wYWNrYWdlLmpzb24nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGltcG9ydC9uby11bnJlc29sdmVkXG5cblxuY29uc3QgV0RBX0RFUklWRURfREFUQV9TRUFSQ0hfU1VGRklYID0gJ0xpYnJhcnkvRGV2ZWxvcGVyL1hjb2RlL0Rlcml2ZWREYXRhL1dlYkRyaXZlckFnZW50LSonO1xuY29uc3QgV0RBX0FUVEFDSE1FTlRTX0ZPTERFUl9SRUxBVElWRV9QQVRIID0gJ0xvZ3MvVGVzdC9BdHRhY2htZW50cyc7XG5jb25zdCBEUklWRVJfVkVSID0gcGtnT2JqLnZlcnNpb247XG5cblxuYXN5bmMgZnVuY3Rpb24gZGV0ZWN0VWRpZCAoKSB7XG4gIGxvZy5kZWJ1ZygnQXV0by1kZXRlY3RpbmcgcmVhbCBkZXZpY2UgdWRpZC4uLicpO1xuICBsZXQgIGNtZCwgYXJncyA9IFtdO1xuICB0cnkge1xuICAgIGNtZCA9IGF3YWl0IGZzLndoaWNoKCdpZGV2aWNlX2lkJyk7XG4gICAgYXJncy5wdXNoKCctbCcpO1xuICAgIGxvZy5kZWJ1ZygnVXNpbmcgaWRldmljZV9pZCcpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZGVidWcoJ1VzaW5nIHVkaWRldGVjdCcpO1xuICAgIGNtZCA9IHJlcXVpcmUucmVzb2x2ZSgndWRpZGV0ZWN0Jyk7XG4gIH1cbiAgbGV0IHVkaWQ7XG4gIHRyeSB7XG4gICAgbGV0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYyhjbWQsIGFyZ3MsIHt0aW1lb3V0OiAzMDAwfSk7XG4gICAgbGV0IHVkaWRzID0gXy5maWx0ZXIoc3Rkb3V0LnNwbGl0KCdcXG4nKSwgQm9vbGVhbik7XG4gICAgdWRpZCA9IF8ubGFzdCh1ZGlkcyk7XG4gICAgaWYgKHVkaWRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGxvZy53YXJuKGBNdWx0aXBsZSBkZXZpY2VzIGZvdW5kOiAke3VkaWRzLmpvaW4oJywgJyl9YCk7XG4gICAgICBsb2cud2FybihgQ2hvb3NpbmcgJyR7dWRpZH0nLiBJZiB0aGlzIGlzIHdyb25nLCBtYW51YWxseSBzZXQgd2l0aCAndWRpZCcgZGVzaXJlZCBjYXBhYmlsaXR5YCk7XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZXJyb3JBbmRUaHJvdyhgRXJyb3IgZGV0ZWN0aW5nIHVkaWQ6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gIH1cbiAgaWYgKCF1ZGlkIHx8IHVkaWQubGVuZ3RoIDw9IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBkZXRlY3QgdWRpZC4nKTtcbiAgfVxuICBsb2cuZGVidWcoYERldGVjdGVkIHJlYWwgZGV2aWNlIHVkaWQ6ICcke3VkaWR9J2ApO1xuICByZXR1cm4gdWRpZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QW5kQ2hlY2tYY29kZVZlcnNpb24gKCkge1xuICBsZXQgdmVyc2lvbjtcbiAgdHJ5IHtcbiAgICB2ZXJzaW9uID0gYXdhaXQgeGNvZGUuZ2V0VmVyc2lvbih0cnVlKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nLmRlYnVnKGVycik7XG4gICAgbG9nLmVycm9yQW5kVGhyb3coYENvdWxkIG5vdCBkZXRlcm1pbmUgWGNvZGUgdmVyc2lvbjogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmICghdmVyc2lvbi50b29sc1ZlcnNpb24pIHtcbiAgICB0cnkge1xuICAgICAgdmVyc2lvbi50b29sc1ZlcnNpb24gPSBhd2FpdCB4Y29kZS5nZXRDb21tYW5kTGluZVRvb2xzVmVyc2lvbigpO1xuICAgIH0gY2F0Y2ggKGlnbikge31cbiAgfVxuXG4gIC8vIHdlIGRvIG5vdCBzdXBwb3J0IFhjb2RlcyA8IDcuMyxcbiAgaWYgKHZlcnNpb24udmVyc2lvbkZsb2F0IDwgNy4zKSB7XG4gICAgbG9nLmVycm9yQW5kVGhyb3coYFhjb2RlIHZlcnNpb24gJyR7dmVyc2lvbi52ZXJzaW9uU3RyaW5nfScuIFN1cHBvcnQgZm9yIGAgK1xuICAgICAgICAgICAgICAgICAgICAgIGBYY29kZSAke3ZlcnNpb24udmVyc2lvblN0cmluZ30gaXMgbm90IHN1cHBvcnRlZC4gYCArXG4gICAgICAgICAgICAgICAgICAgICAgYFBsZWFzZSB1cGdyYWRlIHRvIHZlcnNpb24gNy4zIG9yIGhpZ2hlcmApO1xuICB9XG4gIHJldHVybiB2ZXJzaW9uO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBbmRDaGVja0lvc1Nka1ZlcnNpb24gKCkge1xuICBsZXQgdmVyc2lvbk51bWJlcjtcbiAgdHJ5IHtcbiAgICB2ZXJzaW9uTnVtYmVyID0gYXdhaXQgeGNvZGUuZ2V0TWF4SU9TU0RLKCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5lcnJvckFuZFRocm93KGBDb3VsZCBub3QgZGV0ZXJtaW5lIGlPUyBTREsgdmVyc2lvbjogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxuICByZXR1cm4gdmVyc2lvbk51bWJlcjtcbn1cblxuYXN5bmMgZnVuY3Rpb24ga2lsbEFwcFVzaW5nQXBwTmFtZSAodWRpZCwgYXBwTmFtZSkge1xuICBsZXQgcHNBcmdzID0gW2AtY2AsIGBwcyAtYXh8Z3JlcCAtaSBcIiR7YXBwTmFtZX1cInxncmVwIC1pIFwiJHt1ZGlkfVwifGdyZXAgLXYgZ3JlcHxhd2sgJ3twcmludCBcImtpbGwgLTkgXCIgJDF9J3xzaGBdO1xuICB0cnkge1xuICAgIGF3YWl0IGV4ZWMoYGJhc2hgLCBwc0FyZ3MpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZGVidWcoYEVycm9yIDogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBhZGp1c3RXREFBdHRhY2htZW50c1Blcm1pc3Npb25zIChwZXJtcykge1xuICBpZiAoIXByb2Nlc3MuZW52LkhPTUUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05lZWQgSE9NRSBlbnYgdmFyIHRvIGJlIHNldCBpbiBvcmRlciB0byBhZGp1c3QgV0RBIGF0dGFjaG1lbnRzIHBlcm1pc3Npb24nKTtcbiAgfVxuICBsZXQgZGVyaXZlZERhdGFTZWFyY2hNYXNrID0gcGF0aC5qb2luKHByb2Nlc3MuZW52LkhPTUUsIFdEQV9ERVJJVkVEX0RBVEFfU0VBUkNIX1NVRkZJWCk7XG4gIGxldCBmb2xkZXJzID0gYXdhaXQgZnMuZ2xvYihkZXJpdmVkRGF0YVNlYXJjaE1hc2spO1xuICBsZXQgY2hhbmdlc01hZGUgPSBmYWxzZTtcbiAgZm9yIChsZXQgZm9sZGVyIG9mIGZvbGRlcnMpIHtcbiAgICBsb2cuZGVidWcoYEZvdW5kIFdEQSBkZXJpdmVkIGRhdGEgZm9sZGVyOiAnJHtmb2xkZXJ9J2ApO1xuICAgIGxldCBhdHRhY2htZW50c0ZvbGRlciA9IHBhdGguam9pbihmb2xkZXIsIFdEQV9BVFRBQ0hNRU5UU19GT0xERVJfUkVMQVRJVkVfUEFUSCk7XG4gICAgaWYgKGF3YWl0IGZzLmV4aXN0cyhhdHRhY2htZW50c0ZvbGRlcikpIHtcbiAgICAgIGxvZy5pbmZvKGBTZXR0aW5nICcke3Blcm1zfScgcGVybWlzc2lvbnMgdG8gJyR7YXR0YWNobWVudHNGb2xkZXJ9JyBmb2xkZXJgKTtcbiAgICAgIGF3YWl0IGZzLmNobW9kKGF0dGFjaG1lbnRzRm9sZGVyLCBwZXJtcyk7XG4gICAgICBjaGFuZ2VzTWFkZSA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmICghY2hhbmdlc01hZGUpIHtcbiAgICBsb2cuaW5mbygnTm8gV0RBIGRlcml2ZWQgZGF0YSBmb2xkZXJzIGhhdmUgYmVlbiBmb3VuZC4nKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjbGVhclN5c3RlbUZpbGVzICh3ZGEpIHtcbiAgLy8gb25seSB3YW50IHRvIGNsZWFyIHRoZSBzeXN0ZW0gZmlsZXMgZm9yIHRoZSBwYXJ0aWN1bGFyIFdEQSB4Y29kZSBydW5cbiAgaWYgKCF3ZGEgfHwgIXdkYS5kZXJpdmVkRGF0YVBhdGgpIHtcbiAgICBsb2cuZGVidWcoJ05vIFdlYkRyaXZlckFnZW50IGRlcml2ZWQgZGF0YSBhdmFpbGFibGUsIHNvIHVuYWJsZSB0byBjbGVhciBzeXN0ZW0gZmlsZXMnKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgdG9EZWxldGUgPSBbcGF0aC5yZXNvbHZlKHdkYS5kZXJpdmVkRGF0YVBhdGgsICdMb2dzJyldO1xuICBhd2FpdCBpb3NVdGlscy5jbGVhckxvZ3ModG9EZWxldGUpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVhjb2RlQ29uZmlnRmlsZSAob3JnSWQsIHNpZ25pbmdJZCkge1xuICBsb2cuZGVidWcoYEdlbmVyYXRpbmcgeGNvZGUgY29uZmlnIGZpbGUgZm9yIG9yZ0lkICcke29yZ0lkfScgYW5kIHNpZ25pbmdJZCBgICtcbiAgICAgICAgICAgIGAnJHtzaWduaW5nSWR9J2ApO1xuICBsZXQgY29udGVudHMgPSBgREVWRUxPUE1FTlRfVEVBTSA9ICR7b3JnSWR9XG5DT0RFX1NJR05fSURFTlRJVFkgPSAke3NpZ25pbmdJZH1cbmA7XG4gIGxldCB4Y2NvbmZpZ1BhdGggPSBhd2FpdCB0ZW1wRGlyLnBhdGgoJ2FwcGl1bS10ZW1wLnhjY29uZmlnJyk7XG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyB4Y29kZSBjb25maWcgZmlsZSB0byAke3hjY29uZmlnUGF0aH1gKTtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKHhjY29uZmlnUGF0aCwgY29udGVudHMsIFwidXRmOFwiKTtcbiAgcmV0dXJuIHhjY29uZmlnUGF0aDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY2hlY2tBcHBQcmVzZW50IChhcHApIHtcbiAgbG9nLmRlYnVnKGBDaGVja2luZyB3aGV0aGVyIGFwcCAnJHthcHB9JyBpcyBhY3R1YWxseSBwcmVzZW50IG9uIGZpbGUgc3lzdGVtYCk7XG4gIGlmICghKGF3YWl0IGZzLmV4aXN0cyhhcHApKSkge1xuICAgIGxvZy5lcnJvckFuZFRocm93KGBDb3VsZCBub3QgZmluZCBhcHAgYXQgJyR7YXBwfSdgKTtcbiAgfVxuICBsb2cuZGVidWcoJ0FwcCBpcyBwcmVzZW50Jyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERyaXZlckluZm8gKCkge1xuICBsZXQgc3RhdCA9IGF3YWl0IGZzLnN0YXQocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJykpO1xuICBsZXQgYnVpbHQgPSBzdGF0Lm10aW1lLmdldFRpbWUoKTtcbiAgbGV0IGluZm8gPSB7XG4gICAgYnVpbHQsXG4gICAgdmVyc2lvbjogRFJJVkVSX1ZFUixcbiAgfTtcbiAgcmV0dXJuIGluZm87XG59XG5cbmV4cG9ydCB7IGRldGVjdFVkaWQsIGdldEFuZENoZWNrWGNvZGVWZXJzaW9uLCBnZXRBbmRDaGVja0lvc1Nka1ZlcnNpb24sXG4gICAgICAgICBraWxsQXBwVXNpbmdBcHBOYW1lLCBhZGp1c3RXREFBdHRhY2htZW50c1Blcm1pc3Npb25zLFxuICAgICAgICAgZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUsIGNoZWNrQXBwUHJlc2VudCwgZ2V0RHJpdmVySW5mbyxcbiAgICAgICAgIGNsZWFyU3lzdGVtRmlsZXMgfTtcbiJdLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==