appium-xcuitest-driver-conan
Version:
Appium driver for iOS using XCUITest for backend
374 lines (290 loc) • 22.9 kB
JavaScript
;
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 _teen_process = require('teen_process');
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _logger = require('./logger');
var _logger2 = _interopRequireDefault(_logger);
var WDA_RUNNER_BUNDLE_ID = 'com.facebook.WebDriverAgentRunner';
var PROJECT_FILE = 'project.pbxproj';
var XCUICOORDINATE_FILE = 'PrivateHeaders/XCTest/XCUICoordinate.h';
function replaceInFile(file, find, replace) {
var contents, newContents;
return _regeneratorRuntime.async(function replaceInFile$(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.readFile(file, 'utf-8'));
case 2:
contents = context$1$0.sent;
newContents = contents.replace(find, replace);
if (!(newContents !== contents)) {
context$1$0.next = 7;
break;
}
context$1$0.next = 7;
return _regeneratorRuntime.awrap(_appiumSupport.fs.writeFile(file, newContents, 'utf-8'));
case 7:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
function updateProjectFile(agentPath, newBundleId) {
var projectFilePath;
return _regeneratorRuntime.async(function updateProjectFile$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
projectFilePath = agentPath + '/' + PROJECT_FILE;
context$1$0.prev = 1;
context$1$0.next = 4;
return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(projectFilePath, projectFilePath + '.old'));
case 4:
context$1$0.next = 6;
return _regeneratorRuntime.awrap(replaceInFile(projectFilePath, new RegExp(WDA_RUNNER_BUNDLE_ID.replace('.', '\.'), 'g'), newBundleId));
case 6:
// jshint ignore:line
_logger2['default'].debug('Successfully updated \'' + projectFilePath + '\' with bundle id \'' + newBundleId + '\'');
context$1$0.next = 13;
break;
case 9:
context$1$0.prev = 9;
context$1$0.t0 = context$1$0['catch'](1);
_logger2['default'].debug('Error updating project file: ' + context$1$0.t0.message);
_logger2['default'].warn('Unable to update project file \'' + projectFilePath + '\' with ' + ('bundle id \'' + newBundleId + '\'. WebDriverAgent may not start'));
case 13:
case 'end':
return context$1$0.stop();
}
}, null, this, [[1, 9]]);
}
function resetProjectFile(agentPath, newBundleId) {
var projectFilePath;
return _regeneratorRuntime.async(function resetProjectFile$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
projectFilePath = agentPath + '/' + PROJECT_FILE;
context$1$0.prev = 1;
context$1$0.next = 4;
return _regeneratorRuntime.awrap(replaceInFile(projectFilePath, new RegExp(newBundleId.replace('.', '\.'), 'g'), WDA_RUNNER_BUNDLE_ID));
case 4:
context$1$0.next = 6;
return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(projectFilePath + '.old'));
case 6:
_logger2['default'].debug('Successfully reset \'' + projectFilePath + '\' with bundle id \'' + WDA_RUNNER_BUNDLE_ID + '\'');
context$1$0.next = 13;
break;
case 9:
context$1$0.prev = 9;
context$1$0.t0 = context$1$0['catch'](1);
_logger2['default'].debug('Error resetting project file: ' + context$1$0.t0.message);
_logger2['default'].warn('Unable to reset project file \'' + projectFilePath + '\' with ' + ('bundle id \'' + WDA_RUNNER_BUNDLE_ID + '\'. WebDriverAgent has been ') + 'modified and not returned to the original state.');
case 13:
case 'end':
return context$1$0.stop();
}
}, null, this, [[1, 9]]);
}
function checkForDependencies(bootstrapPath) {
var useSsl = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
var carthagePath, args, _arr, _i, std, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line;
return _regeneratorRuntime.async(function checkForDependencies$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.prev = 0;
context$1$0.next = 3;
return _regeneratorRuntime.awrap(_appiumSupport.fs.which('carthage'));
case 3:
carthagePath = context$1$0.sent;
_logger2['default'].debug('Carthage found: \'' + carthagePath + '\'');
context$1$0.next = 10;
break;
case 7:
context$1$0.prev = 7;
context$1$0.t0 = context$1$0['catch'](0);
_logger2['default'].warn('Carthage not found. Install using `brew install carthage`');
case 10:
context$1$0.next = 12;
return _regeneratorRuntime.awrap(_appiumSupport.fs.hasAccess(bootstrapPath + '/Carthage'));
case 12:
if (context$1$0.sent) {
context$1$0.next = 59;
break;
}
_logger2['default'].debug('Running WebDriverAgent bootstrap script to install dependencies');
context$1$0.prev = 14;
args = useSsl ? ['-d', '-D'] : ['-d'];
context$1$0.next = 18;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('Scripts/bootstrap.sh', args, { cwd: bootstrapPath }));
case 18:
context$1$0.next = 59;
break;
case 20:
context$1$0.prev = 20;
context$1$0.t1 = context$1$0['catch'](14);
_arr = ['stdout', 'stderr'];
_i = 0;
case 24:
if (!(_i < _arr.length)) {
context$1$0.next = 56;
break;
}
std = _arr[_i];
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
context$1$0.prev = 29;
_iterator = _getIterator((context$1$0.t1[std] || '').split('\n'));
case 31:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
context$1$0.next = 39;
break;
}
line = _step.value;
if (line.length) {
context$1$0.next = 35;
break;
}
return context$1$0.abrupt('continue', 36);
case 35:
_logger2['default'].error(line);
case 36:
_iteratorNormalCompletion = true;
context$1$0.next = 31;
break;
case 39:
context$1$0.next = 45;
break;
case 41:
context$1$0.prev = 41;
context$1$0.t2 = context$1$0['catch'](29);
_didIteratorError = true;
_iteratorError = context$1$0.t2;
case 45:
context$1$0.prev = 45;
context$1$0.prev = 46;
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
case 48:
context$1$0.prev = 48;
if (!_didIteratorError) {
context$1$0.next = 51;
break;
}
throw _iteratorError;
case 51:
return context$1$0.finish(48);
case 52:
return context$1$0.finish(45);
case 53:
_i++;
context$1$0.next = 24;
break;
case 56:
context$1$0.next = 58;
return _regeneratorRuntime.awrap(_appiumSupport.fs.rimraf(bootstrapPath + '/Carthage'));
case 58:
throw context$1$0.t1;
case 59:
context$1$0.next = 61;
return _regeneratorRuntime.awrap(_appiumSupport.fs.hasAccess(bootstrapPath + '/Resources'));
case 61:
if (context$1$0.sent) {
context$1$0.next = 65;
break;
}
_logger2['default'].debug('Creating WebDriverAgent resources directory');
context$1$0.next = 65;
return _regeneratorRuntime.awrap(_appiumSupport.fs.mkdir(bootstrapPath + '/Resources'));
case 65:
context$1$0.next = 67;
return _regeneratorRuntime.awrap(_appiumSupport.fs.hasAccess(bootstrapPath + '/Resources/WebDriverAgent.bundle'));
case 67:
if (context$1$0.sent) {
context$1$0.next = 71;
break;
}
_logger2['default'].debug('Creating WebDriverAgent resource bundle directory');
context$1$0.next = 71;
return _regeneratorRuntime.awrap(_appiumSupport.fs.mkdir(bootstrapPath + '/Resources/WebDriverAgent.bundle'));
case 71:
case 'end':
return context$1$0.stop();
}
}, null, this, [[0, 7], [14, 20], [29, 41, 45, 53], [46,, 48, 52]]);
}
function setRealDeviceSecurity(keychainPath, keychainPassword) {
return _regeneratorRuntime.async(function setRealDeviceSecurity$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_logger2['default'].debug('Setting security for iOS device');
context$1$0.next = 3;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['-v', 'list-keychains', '-s', keychainPath]));
case 3:
context$1$0.next = 5;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['-v', 'unlock-keychain', '-p', keychainPassword, keychainPath]));
case 5:
context$1$0.next = 7;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['set-keychain-settings', '-t', '3600', '-l', keychainPath]));
case 7:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
function fixXCUICoordinateFile(bootstrapPath) {
var initial = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
var file, oldDef, newDef, _ref;
return _regeneratorRuntime.async(function fixXCUICoordinateFile$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
file = _path2['default'].resolve(bootstrapPath, XCUICOORDINATE_FILE);
oldDef = '- (void)pressForDuration:(double)arg1 thenDragToCoordinate:(id)arg2;';
newDef = '- (void)pressForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate;';
if (!initial) {
_ref = [newDef, oldDef];
oldDef = _ref[0];
newDef = _ref[1];
}
context$1$0.next = 6;
return _regeneratorRuntime.awrap(replaceInFile(file, oldDef, newDef));
case 6:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
function fixForXcode7(bootstrapPath) {
var initial = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
return _regeneratorRuntime.async(function fixForXcode7$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.next = 2;
return _regeneratorRuntime.awrap(fixXCUICoordinateFile(bootstrapPath, initial));
case 2:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
exports.updateProjectFile = updateProjectFile;
exports.resetProjectFile = resetProjectFile;
exports.checkForDependencies = checkForDependencies;
exports.setRealDeviceSecurity = setRealDeviceSecurity;
exports.fixForXcode7 = fixForXcode7;
// backup the file, and then update the bundle id for the runner
// jshint ignore:line
// print out the stdout and stderr reports
// remove the carthage directory, or else subsequent runs will see it and
// assume the dependencies are already downloaded
// the way the updated XCTest headers are in the WDA project, building in
// Xcode 8.0 causes a duplicate declaration of method
// so fix the offending line in the local headers
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi93ZWJkcml2ZXJhZ2VudC11dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7NkJBQW1CLGdCQUFnQjs7NEJBQ2QsY0FBYzs7b0JBQ2xCLE1BQU07Ozs7c0JBQ1AsVUFBVTs7OztBQUcxQixJQUFNLG9CQUFvQixHQUFHLG1DQUFtQyxDQUFDO0FBQ2pFLElBQU0sWUFBWSxHQUFHLGlCQUFpQixDQUFDO0FBQ3ZDLElBQU0sbUJBQW1CLEdBQUcsd0NBQXdDLENBQUM7O0FBRXJFLFNBQWUsYUFBYSxDQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTztNQUMzQyxRQUFRLEVBRVIsV0FBVzs7Ozs7eUNBRk0sa0JBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7OztBQUEzQyxnQkFBUTtBQUVSLG1CQUFXLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDOztjQUM3QyxXQUFXLEtBQUssUUFBUSxDQUFBOzs7Ozs7eUNBQ3BCLGtCQUFHLFNBQVMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQzs7Ozs7OztDQUVqRDs7QUFFRCxTQUFlLGlCQUFpQixDQUFFLFNBQVMsRUFBRSxXQUFXO01BQ2xELGVBQWU7Ozs7QUFBZix1QkFBZSxHQUFNLFNBQVMsU0FBSSxZQUFZOzs7eUNBRzFDLGtCQUFHLFFBQVEsQ0FBQyxlQUFlLEVBQUssZUFBZSxVQUFPOzs7O3lDQUN0RCxhQUFhLENBQUMsZUFBZSxFQUFFLElBQUksTUFBTSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsV0FBVyxDQUFDOzs7O0FBQzNHLDRCQUFJLEtBQUssNkJBQTBCLGVBQWUsNEJBQXFCLFdBQVcsUUFBSSxDQUFDOzs7Ozs7OztBQUV2Riw0QkFBSSxLQUFLLG1DQUFpQyxlQUFJLE9BQU8sQ0FBRyxDQUFDO0FBQ3pELDRCQUFJLElBQUksQ0FB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QUMsQ0FBQzs7Ozs7OztDQUNwRjs7QUFFRCxTQUFlLHFCQUFxQixDQUFFLGFBQWE7TUFBRSxPQUFPLHlEQUFHLElBQUk7O01BSTNELElBQUksRUFFTixNQUFNLEVBQ04sTUFBTTs7Ozs7QUFISixZQUFJLEdBQUcsa0JBQUssT0FBTyxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQztBQUV6RCxjQUFNLEdBQUcsc0VBQXNFO0FBQy9FLGNBQU0sR0FBRywyR0FBMkc7O0FBQ3hILFlBQUksQ0FBQyxPQUFPLEVBQUU7aUJBQ08sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDO0FBQWxDLGdCQUFNO0FBQUUsZ0JBQU07U0FDaEI7O3lDQUNLLGFBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQzs7Ozs7OztDQUMxQzs7QUFFRCxTQUFlLFlBQVksQ0FBRSxhQUFhO01BQUUsT0FBTyx5REFBRyxJQUFJOzs7Ozt5Q0FDbEQscUJBQXFCLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQzs7Ozs7OztDQUNwRDs7UUFFUSxpQkFBaUIsR0FBakIsaUJBQWlCO1FBQUUsZ0JBQWdCLEdBQWhCLGdCQUFnQjtRQUFFLG9CQUFvQixHQUFwQixvQkFBb0I7UUFDekQscUJBQXFCLEdBQXJCLHFCQUFxQjtRQUFFLFlBQVksR0FBWixZQUFZIiwiZmlsZSI6ImxpYi93ZWJkcml2ZXJhZ2VudC11dGlscy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZzIH0gZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJ3RlZW5fcHJvY2Vzcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuXG5cbmNvbnN0IFdEQV9SVU5ORVJfQlVORExFX0lEID0gJ2NvbS5mYWNlYm9vay5XZWJEcml2ZXJBZ2VudFJ1bm5lcic7XG5jb25zdCBQUk9KRUNUX0ZJTEUgPSAncHJvamVjdC5wYnhwcm9qJztcbmNvbnN0IFhDVUlDT09SRElOQVRFX0ZJTEUgPSAnUHJpdmF0ZUhlYWRlcnMvWENUZXN0L1hDVUlDb29yZGluYXRlLmgnO1xuXG5hc3luYyBmdW5jdGlvbiByZXBsYWNlSW5GaWxlIChmaWxlLCBmaW5kLCByZXBsYWNlKSB7XG4gIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGUsICd1dGYtOCcpO1xuXG4gIGxldCBuZXdDb250ZW50cyA9IGNvbnRlbnRzLnJlcGxhY2UoZmluZCwgcmVwbGFjZSk7XG4gIGlmIChuZXdDb250ZW50cyAhPT0gY29udGVudHMpIHtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUoZmlsZSwgbmV3Q29udGVudHMsICd1dGYtOCcpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVByb2plY3RGaWxlIChhZ2VudFBhdGgsIG5ld0J1bmRsZUlkKSB7XG4gIGxldCBwcm9qZWN0RmlsZVBhdGggPSBgJHthZ2VudFBhdGh9LyR7UFJPSkVDVF9GSUxFfWA7XG4gIHRyeSB7XG4gICAgLy8gYmFja3VwIHRoZSBmaWxlLCBhbmQgdGhlbiB1cGRhdGUgdGhlIGJ1bmRsZSBpZCBmb3IgdGhlIHJ1bm5lclxuICAgIGF3YWl0IGZzLmNvcHlGaWxlKHByb2plY3RGaWxlUGF0aCwgYCR7cHJvamVjdEZpbGVQYXRofS5vbGRgKTtcbiAgICBhd2FpdCByZXBsYWNlSW5GaWxlKHByb2plY3RGaWxlUGF0aCwgbmV3IFJlZ0V4cChXREFfUlVOTkVSX0JVTkRMRV9JRC5yZXBsYWNlKCcuJywgJ1xcLicpLCAnZycpLCBuZXdCdW5kbGVJZCk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgIGxvZy5kZWJ1ZyhgU3VjY2Vzc2Z1bGx5IHVwZGF0ZWQgJyR7cHJvamVjdEZpbGVQYXRofScgd2l0aCBidW5kbGUgaWQgJyR7bmV3QnVuZGxlSWR9J2ApO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZGVidWcoYEVycm9yIHVwZGF0aW5nIHByb2plY3QgZmlsZTogJHtlcnIubWVzc2FnZX1gKTtcbiAgICBsb2cud2FybihgVW5hYmxlIHRvIHVwZGF0ZSBwcm9qZWN0IGZpbGUgJyR7cHJvamVjdEZpbGVQYXRofScgd2l0aCBgICtcbiAgICAgICAgICAgICBgYnVuZGxlIGlkICcke25ld0J1bmRsZUlkfScuIFdlYkRyaXZlckFnZW50IG1heSBub3Qgc3RhcnRgKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiByZXNldFByb2plY3RGaWxlIChhZ2VudFBhdGgsIG5ld0J1bmRsZUlkKSB7XG4gIGxldCBwcm9qZWN0RmlsZVBhdGggPSBgJHthZ2VudFBhdGh9LyR7UFJPSkVDVF9GSUxFfWA7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVwbGFjZUluRmlsZShwcm9qZWN0RmlsZVBhdGgsIG5ldyBSZWdFeHAobmV3QnVuZGxlSWQucmVwbGFjZSgnLicsICdcXC4nKSwgJ2cnKSwgV0RBX1JVTk5FUl9CVU5ETEVfSUQpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICBhd2FpdCBmcy51bmxpbmsoYCR7cHJvamVjdEZpbGVQYXRofS5vbGRgKTtcbiAgICBsb2cuZGVidWcoYFN1Y2Nlc3NmdWxseSByZXNldCAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGJ1bmRsZSBpZCAnJHtXREFfUlVOTkVSX0JVTkRMRV9JRH0nYCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5kZWJ1ZyhgRXJyb3IgcmVzZXR0aW5nIHByb2plY3QgZmlsZTogJHtlcnIubWVzc2FnZX1gKTtcbiAgICBsb2cud2FybihgVW5hYmxlIHRvIHJlc2V0IHByb2plY3QgZmlsZSAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGAgK1xuICAgICAgICAgICAgIGBidW5kbGUgaWQgJyR7V0RBX1JVTk5FUl9CVU5ETEVfSUR9Jy4gV2ViRHJpdmVyQWdlbnQgaGFzIGJlZW4gYCArXG4gICAgICAgICAgICAgYG1vZGlmaWVkIGFuZCBub3QgcmV0dXJuZWQgdG8gdGhlIG9yaWdpbmFsIHN0YXRlLmApO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNoZWNrRm9yRGVwZW5kZW5jaWVzIChib290c3RyYXBQYXRoLCB1c2VTc2wgPSBmYWxzZSkge1xuICB0cnkge1xuICAgIGxldCBjYXJ0aGFnZVBhdGggPSBhd2FpdCBmcy53aGljaCgnY2FydGhhZ2UnKTtcbiAgICBsb2cuZGVidWcoYENhcnRoYWdlIGZvdW5kOiAnJHtjYXJ0aGFnZVBhdGh9J2ApO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cud2FybignQ2FydGhhZ2Ugbm90IGZvdW5kLiBJbnN0YWxsIHVzaW5nIGBicmV3IGluc3RhbGwgY2FydGhhZ2VgJyk7XG4gIH1cbiAgaWYgKCFhd2FpdCBmcy5oYXNBY2Nlc3MoYCR7Ym9vdHN0cmFwUGF0aH0vQ2FydGhhZ2VgKSkge1xuICAgIGxvZy5kZWJ1ZygnUnVubmluZyBXZWJEcml2ZXJBZ2VudCBib290c3RyYXAgc2NyaXB0IHRvIGluc3RhbGwgZGVwZW5kZW5jaWVzJyk7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBhcmdzID0gdXNlU3NsID8gWyctZCcsICctRCddIDogWyctZCddO1xuICAgICAgYXdhaXQgZXhlYygnU2NyaXB0cy9ib290c3RyYXAuc2gnLCBhcmdzLCB7Y3dkOiBib290c3RyYXBQYXRofSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBwcmludCBvdXQgdGhlIHN0ZG91dCBhbmQgc3RkZXJyIHJlcG9ydHNcbiAgICAgIGZvciAobGV0IHN0ZCBvZiBbJ3N0ZG91dCcsICdzdGRlcnInXSkge1xuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIChlcnJbc3RkXSB8fCAnJykuc3BsaXQoJ1xcbicpKSB7XG4gICAgICAgICAgaWYgKCFsaW5lLmxlbmd0aCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZy5lcnJvcihsaW5lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIHRoZSBjYXJ0aGFnZSBkaXJlY3RvcnksIG9yIGVsc2Ugc3Vic2VxdWVudCBydW5zIHdpbGwgc2VlIGl0IGFuZFxuICAgICAgLy8gYXNzdW1lIHRoZSBkZXBlbmRlbmNpZXMgYXJlIGFscmVhZHkgZG93bmxvYWRlZFxuICAgICAgYXdhaXQgZnMucmltcmFmKGAke2Jvb3RzdHJhcFBhdGh9L0NhcnRoYWdlYCk7XG5cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cbiAgaWYgKCFhd2FpdCBmcy5oYXNBY2Nlc3MoYCR7Ym9vdHN0cmFwUGF0aH0vUmVzb3VyY2VzYCkpIHtcbiAgICBsb2cuZGVidWcoJ0NyZWF0aW5nIFdlYkRyaXZlckFnZW50IHJlc291cmNlcyBkaXJlY3RvcnknKTtcbiAgICBhd2FpdCBmcy5ta2RpcihgJHtib290c3RyYXBQYXRofS9SZXNvdXJjZXNgKTtcbiAgfVxuICBpZiAoIWF3YWl0IGZzLmhhc0FjY2VzcyhgJHtib290c3RyYXBQYXRofS9SZXNvdXJjZXMvV2ViRHJpdmVyQWdlbnQuYnVuZGxlYCkpIHtcbiAgICBsb2cuZGVidWcoJ0NyZWF0aW5nIFdlYkRyaXZlckFnZW50IHJlc291cmNlIGJ1bmRsZSBkaXJlY3RvcnknKTtcbiAgICBhd2FpdCBmcy5ta2RpcihgJHtib290c3RyYXBQYXRofS9SZXNvdXJjZXMvV2ViRHJpdmVyQWdlbnQuYnVuZGxlYCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0UmVhbERldmljZVNlY3VyaXR5IChrZXljaGFpblBhdGgsIGtleWNoYWluUGFzc3dvcmQpIHtcbiAgbG9nLmRlYnVnKCdTZXR0aW5nIHNlY3VyaXR5IGZvciBpT1MgZGV2aWNlJyk7XG4gIGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWyctdicsICdsaXN0LWtleWNoYWlucycsICctcycsIGtleWNoYWluUGF0aF0pO1xuICBhd2FpdCBleGVjKCdzZWN1cml0eScsIFsnLXYnLCAndW5sb2NrLWtleWNoYWluJywgJy1wJywga2V5Y2hhaW5QYXNzd29yZCwga2V5Y2hhaW5QYXRoXSk7XG4gIGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWydzZXQta2V5Y2hhaW4tc2V0dGluZ3MnLCAnLXQnLCAnMzYwMCcsICctbCcsIGtleWNoYWluUGF0aF0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaXhYQ1VJQ29vcmRpbmF0ZUZpbGUgKGJvb3RzdHJhcFBhdGgsIGluaXRpYWwgPSB0cnVlKSB7XG4gIC8vIHRoZSB3YXkgdGhlIHVwZGF0ZWQgWENUZXN0IGhlYWRlcnMgYXJlIGluIHRoZSBXREEgcHJvamVjdCwgYnVpbGRpbmcgaW5cbiAgLy8gWGNvZGUgOC4wIGNhdXNlcyBhIGR1cGxpY2F0ZSBkZWNsYXJhdGlvbiBvZiBtZXRob2RcbiAgLy8gc28gZml4IHRoZSBvZmZlbmRpbmcgbGluZSBpbiB0aGUgbG9jYWwgaGVhZGVyc1xuICBjb25zdCBmaWxlID0gcGF0aC5yZXNvbHZlKGJvb3RzdHJhcFBhdGgsIFhDVUlDT09SRElOQVRFX0ZJTEUpO1xuXG4gIGxldCBvbGREZWYgPSAnLSAodm9pZClwcmVzc0ZvckR1cmF0aW9uOihkb3VibGUpYXJnMSB0aGVuRHJhZ1RvQ29vcmRpbmF0ZTooaWQpYXJnMjsnO1xuICBsZXQgbmV3RGVmID0gJy0gKHZvaWQpcHJlc3NGb3JEdXJhdGlvbjooTlNUaW1lSW50ZXJ2YWwpZHVyYXRpb24gdGhlbkRyYWdUb0Nvb3JkaW5hdGU6KFhDVUlDb29yZGluYXRlICopb3RoZXJDb29yZGluYXRlOyc7XG4gIGlmICghaW5pdGlhbCkge1xuICAgIFtvbGREZWYsIG5ld0RlZl0gPSBbbmV3RGVmLCBvbGREZWZdO1xuICB9XG4gIGF3YWl0IHJlcGxhY2VJbkZpbGUoZmlsZSwgb2xkRGVmLCBuZXdEZWYpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaXhGb3JYY29kZTcgKGJvb3RzdHJhcFBhdGgsIGluaXRpYWwgPSB0cnVlKSB7XG4gIGF3YWl0IGZpeFhDVUlDb29yZGluYXRlRmlsZShib290c3RyYXBQYXRoLCBpbml0aWFsKTtcbn1cblxuZXhwb3J0IHsgdXBkYXRlUHJvamVjdEZpbGUsIHJlc2V0UHJvamVjdEZpbGUsIGNoZWNrRm9yRGVwZW5kZW5jaWVzLFxuICAgICAgICAgc2V0UmVhbERldmljZVNlY3VyaXR5LCBmaXhGb3JYY29kZTcgfTtcbiJdLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==