UNPKG

appium-xcuitest-driver-conan

Version:

Appium driver for iOS using XCUITest for backend

516 lines (401 loc) 25.2 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 _path = require('path'); var _path2 = _interopRequireDefault(_path); var _appiumIosSimulator = require('appium-ios-simulator'); var _nodeSimctl = require('node-simctl'); var _asyncbox = require('asyncbox'); var _teen_process = require('teen_process'); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); // returns true if sim is booted. false if not booted or doesnt exist function simBooted(sim) { var stat; return _regeneratorRuntime.async(function simBooted$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(sim.stat()); case 2: stat = context$1$0.sent; return context$1$0.abrupt('return', stat.state === 'Booted'); case 4: case 'end': return context$1$0.stop(); } }, null, this); } // returns sim for desired caps function createSim(caps, sessionId) { var name, udid; return _regeneratorRuntime.async(function createSim$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: name = 'appiumTest-' + sessionId; context$1$0.next = 3; return _regeneratorRuntime.awrap((0, _nodeSimctl.createDevice)(name, caps.deviceName, caps.platformVersion)); case 3: udid = context$1$0.sent; context$1$0.next = 6; return _regeneratorRuntime.awrap((0, _appiumIosSimulator.getSimulator)(udid)); case 6: return context$1$0.abrupt('return', context$1$0.sent); case 7: case 'end': return context$1$0.stop(); } }, null, this); } function getExistingSim(deviceName, platformVersion) { var devices, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, device; return _regeneratorRuntime.async(function getExistingSim$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap((0, _nodeSimctl.getDevices)(platformVersion)); case 2: devices = context$1$0.sent; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; context$1$0.prev = 6; _iterator = _getIterator(_lodash2['default'].values(devices)); case 8: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { context$1$0.next = 17; break; } device = _step.value; if (!(device.name === deviceName)) { context$1$0.next = 14; break; } context$1$0.next = 13; return _regeneratorRuntime.awrap((0, _appiumIosSimulator.getSimulator)(device.udid)); case 13: return context$1$0.abrupt('return', context$1$0.sent); case 14: _iteratorNormalCompletion = true; context$1$0.next = 8; break; case 17: context$1$0.next = 23; break; case 19: context$1$0.prev = 19; context$1$0.t0 = context$1$0['catch'](6); _didIteratorError = true; _iteratorError = context$1$0.t0; case 23: context$1$0.prev = 23; context$1$0.prev = 24; if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } case 26: context$1$0.prev = 26; if (!_didIteratorError) { context$1$0.next = 29; break; } throw _iteratorError; case 29: return context$1$0.finish(26); case 30: return context$1$0.finish(23); case 31: return context$1$0.abrupt('return', null); case 32: case 'end': return context$1$0.stop(); } }, null, this, [[6, 19, 23, 31], [24,, 26, 30]]); } function prepareSafariForCleanup() { var timeout = arguments.length <= 0 || arguments[0] === undefined ? 5000 : arguments[0]; return _regeneratorRuntime.async(function prepareSafariForCleanup$(context$1$0) { var _this = this; 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((0, _asyncbox.waitForCondition)(function callee$1$0() { return _regeneratorRuntime.async(function callee$1$0$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: context$2$0.prev = 0; context$2$0.next = 3; return _regeneratorRuntime.awrap((0, _teen_process.exec)('pgrep', ['-x', 'MobileSafari'])); case 3: context$2$0.next = 19; break; case 5: context$2$0.prev = 5; context$2$0.t0 = context$2$0['catch'](0); if (!(context$2$0.t0.code === 1)) { context$2$0.next = 9; break; } return context$2$0.abrupt('return', true); case 9: context$2$0.prev = 9; context$2$0.next = 12; return _regeneratorRuntime.awrap((0, _teen_process.exec)('pkill', ['-9', '-x', 'MobileSafari'])); case 12: context$2$0.next = 19; break; case 14: context$2$0.prev = 14; context$2$0.t1 = context$2$0['catch'](9); if (!(context$2$0.t1.code === 1)) { context$2$0.next = 18; break; } return context$2$0.abrupt('return', true); case 18: _logger2['default'].warn(context$2$0.t1.message); case 19: return context$2$0.abrupt('return', false); case 20: case 'end': return context$2$0.stop(); } }, null, _this, [[0, 5], [9, 14]]); }, { waitMs: timeout, intervalMs: 200 })); case 3: _logger2['default'].debug('Mobile Safari process is not running. Continuing with cleanup'); context$1$0.next = 9; break; case 6: context$1$0.prev = 6; context$1$0.t0 = context$1$0['catch'](0); _logger2['default'].warn('Mobile Safari is still running after ' + timeout + ' ms'); case 9: case 'end': return context$1$0.stop(); } }, null, this, [[0, 6]]); } function runSimulatorReset(device, opts) { var isSafari; return _regeneratorRuntime.async(function runSimulatorReset$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (!(opts.noReset && !opts.fullReset)) { context$1$0.next = 3; break; } // noReset === true && fullReset === false _logger2['default'].debug('Reset: noReset is on. Leaving simulator as is'); return context$1$0.abrupt('return'); case 3: if (device) { context$1$0.next = 6; break; } _logger2['default'].debug('Reset: no device available. Skipping'); return context$1$0.abrupt('return'); case 6: if (!opts.fullReset) { context$1$0.next = 14; break; } _logger2['default'].debug('Reset: fullReset is on. Cleaning simulator'); // The simulator process must be ended before we delete applications. context$1$0.next = 10; return _regeneratorRuntime.awrap(endSimulator(device)); case 10: context$1$0.next = 12; return _regeneratorRuntime.awrap(fullResetSimulator(device)); case 12: context$1$0.next = 51; break; case 14: if (!opts.bundleId) { context$1$0.next = 51; break; } context$1$0.next = 17; return _regeneratorRuntime.awrap(simBooted(device)); case 17: if (!context$1$0.sent) { context$1$0.next = 31; break; } if (!(device.xcodeVersion.major >= 8)) { context$1$0.next = 29; break; } context$1$0.prev = 19; context$1$0.next = 22; return _regeneratorRuntime.awrap((0, _nodeSimctl.terminate)(device.udid, opts.bundleId)); case 22: context$1$0.next = 27; break; case 24: context$1$0.prev = 24; context$1$0.t0 = context$1$0['catch'](19); _logger2['default'].warn('Reset: failed to terminate Simulator application with id "' + opts.bundleId + '"'); case 27: context$1$0.next = 31; break; case 29: context$1$0.next = 31; return _regeneratorRuntime.awrap(endSimulator(device)); case 31: if (!opts.app) { context$1$0.next = 34; break; } _logger2['default'].info('Not scrubbing third party app in anticipation of uninstall'); return context$1$0.abrupt('return'); case 34: isSafari = (opts.browserName || '').toLowerCase() === 'safari'; context$1$0.prev = 35; if (!isSafari) { context$1$0.next = 43; break; } context$1$0.next = 39; return _regeneratorRuntime.awrap(prepareSafariForCleanup()); case 39: context$1$0.next = 41; return _regeneratorRuntime.awrap(device.cleanSafari()); case 41: context$1$0.next = 45; break; case 43: context$1$0.next = 45; return _regeneratorRuntime.awrap(device.scrubCustomApp(_path2['default'].basename(opts.app), opts.bundleId)); case 45: context$1$0.next = 51; break; case 47: context$1$0.prev = 47; context$1$0.t1 = context$1$0['catch'](35); _logger2['default'].warn(context$1$0.t1.message); _logger2['default'].warn('Reset: could not scrub ' + (isSafari ? 'Safari browser' : 'application with id "' + opts.bundleId + '"') + '. Leaving as is.'); case 51: case 'end': return context$1$0.stop(); } }, null, this, [[19, 24], [35, 47]]); } function fullResetSimulator(device) { return _regeneratorRuntime.async(function fullResetSimulator$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (device) { context$1$0.next = 2; break; } return context$1$0.abrupt('return'); case 2: context$1$0.next = 4; return _regeneratorRuntime.awrap(device.clean()); case 4: case 'end': return context$1$0.stop(); } }, null, this); } function endSimulator(device) { return _regeneratorRuntime.async(function endSimulator$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (device) { context$1$0.next = 2; break; } return context$1$0.abrupt('return'); case 2: _logger2['default'].debug('Reset: shutting down simulator'); context$1$0.next = 5; return _regeneratorRuntime.awrap(device.shutdown()); case 5: case 'end': return context$1$0.stop(); } }, null, this); } function isolateSimulatorDevice(device) { var isolateSimDevice = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; return _regeneratorRuntime.async(function isolateSimulatorDevice$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (!isolateSimDevice) { context$1$0.next = 3; break; } context$1$0.next = 3; return _regeneratorRuntime.awrap(device.isolateSim()); case 3: case 'end': return context$1$0.stop(); } }, null, this); } function installToSimulator(device, app, bundleId) { var noReset = arguments.length <= 3 || arguments[3] === undefined ? true : arguments[3]; return _regeneratorRuntime.async(function installToSimulator$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (app) { context$1$0.next = 3; break; } _logger2['default'].debug('No app path is given. Nothing to install.'); return context$1$0.abrupt('return'); case 3: if (!bundleId) { context$1$0.next = 13; break; } context$1$0.next = 6; return _regeneratorRuntime.awrap(device.isAppInstalled(bundleId)); case 6: if (!context$1$0.sent) { context$1$0.next = 13; break; } if (!noReset) { context$1$0.next = 10; break; } _logger2['default'].debug('App \'' + bundleId + '\' is already installed. No need to reinstall.'); return context$1$0.abrupt('return'); case 10: _logger2['default'].debug('Reset requested. Removing app with id \'' + bundleId + '\' from the device'); context$1$0.next = 13; return _regeneratorRuntime.awrap(device.removeApp(bundleId)); case 13: _logger2['default'].debug('Installing ' + app + ' on Simulator with UUID \'' + device.udid + '\'...'); context$1$0.next = 16; return _regeneratorRuntime.awrap(device.installApp(app)); case 16: _logger2['default'].debug('The app has been installed successfully.'); case 17: case 'end': return context$1$0.stop(); } }, null, this); } exports.simBooted = simBooted; exports.createSim = createSim; exports.getExistingSim = getExistingSim; exports.runSimulatorReset = runSimulatorReset; exports.isolateSimulatorDevice = isolateSimulatorDevice; exports.installToSimulator = installToSimulator; // Terminate the app under test if it is still running on Simulator // Termination is not needed if Simulator is not running //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9zaW11bGF0b3ItbWFuYWdlbWVudC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7b0JBQWlCLE1BQU07Ozs7a0NBQ00sc0JBQXNCOzswQkFDQyxhQUFhOzt3QkFDaEMsVUFBVTs7NEJBQ3RCLGNBQWM7O3NCQUNyQixRQUFROzs7O3NCQUNOLFVBQVU7Ozs7O0FBSTFCLFNBQWUsU0FBUyxDQUFFLEdBQUc7TUFDdkIsSUFBSTs7Ozs7eUNBQVMsR0FBRyxDQUFDLElBQUksRUFBRTs7O0FBQXZCLFlBQUk7NENBQ0QsSUFBSSxDQUFDLEtBQUssS0FBSyxRQUFROzs7Ozs7O0NBQy9COzs7QUFHRCxTQUFlLFNBQVMsQ0FBRSxJQUFJLEVBQUUsU0FBUztNQUNuQyxJQUFJLEVBQ0osSUFBSTs7OztBQURKLFlBQUksbUJBQWlCLFNBQVM7O3lDQUNqQiw4QkFBYSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDOzs7QUFBdEUsWUFBSTs7eUNBQ0ssc0NBQWEsSUFBSSxDQUFDOzs7Ozs7Ozs7O0NBQ2hDOztBQUVELFNBQWUsY0FBYyxDQUFFLFVBQVUsRUFBRSxlQUFlO01BQ3BELE9BQU8sa0ZBQ0YsTUFBTTs7Ozs7O3lDQURLLDRCQUFXLGVBQWUsQ0FBQzs7O0FBQTNDLGVBQU87Ozs7O2lDQUNRLG9CQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUM7Ozs7Ozs7O0FBQTNCLGNBQU07O2NBQ1QsTUFBTSxDQUFDLElBQUksS0FBSyxVQUFVLENBQUE7Ozs7Ozt5Q0FDZixzQ0FBYSxNQUFNLENBQUMsSUFBSSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7NENBR25DLElBQUk7Ozs7Ozs7Q0FDWjs7QUFFRCxTQUFlLHVCQUF1QjtNQUFFLE9BQU8seURBQUcsSUFBSTs7Ozs7Ozs7eUNBRTVDLGdDQUFpQjs7Ozs7O2lEQUViLHdCQUFLLE9BQU8sRUFBRSxDQUFDLElBQUksRUFB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Q0FFNUI7O0FBRUQsU0FBZSxrQkFBa0IsQ0FBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVE7TUFBRSxPQUFPLHlEQUFHLElBQUk7Ozs7WUFDakUsR0FBRzs7Ozs7QUFDTiw0QkFBSSxLQUFLLENBQUMsMkNBQTJDLENBQUMsQ0FBQzs7OzthQUlyRCxRQUFROzs7Ozs7eUNBQ0EsTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUM7Ozs7Ozs7O2FBQ25DLE9BQU87Ozs7O0FBQ1QsNEJBQUksS0FBSyxZQUFTLFFBQVEsb0RBQWdELENBQUM7Ozs7QUFHN0UsNEJBQUksS0FBSyw4Q0FBMkMsUUFBUSx3QkFBb0IsQ0FBQzs7eUNBQzNFLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDOzs7QUFHcEMsNEJBQUksS0FBSyxpQkFBZSxHQUFHLGtDQUE0QixNQUFNLENBQUMsSUFBSSxXQUFPLENBQUM7O3lDQUNwRSxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQzs7O0FBQzVCLDRCQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDOzs7Ozs7O0NBQ3ZEOztRQUdRLFNBQVMsR0FBVCxTQUFTO1FBQUUsU0FBUyxHQUFULFNBQVM7UUFBRSxjQUFjLEdBQWQsY0FBYztRQUFFLGlCQUFpQixHQUFqQixpQkFBaUI7UUFDdkQsc0JBQXNCLEdBQXRCLHNCQUFzQjtRQUFFLGtCQUFrQixHQUFsQixrQkFBa0IiLCJmaWxlIjoibGliL3NpbXVsYXRvci1tYW5hZ2VtZW50LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBnZXRTaW11bGF0b3IgfSBmcm9tICdhcHBpdW0taW9zLXNpbXVsYXRvcic7XG5pbXBvcnQgeyBjcmVhdGVEZXZpY2UsIGdldERldmljZXMsIHRlcm1pbmF0ZSB9IGZyb20gJ25vZGUtc2ltY3RsJztcbmltcG9ydCB7IHdhaXRGb3JDb25kaXRpb24gfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9nIGZyb20gJy4vbG9nZ2VyJztcblxuXG4vLyByZXR1cm5zIHRydWUgaWYgc2ltIGlzIGJvb3RlZC4gZmFsc2UgaWYgbm90IGJvb3RlZCBvciBkb2VzbnQgZXhpc3RcbmFzeW5jIGZ1bmN0aW9uIHNpbUJvb3RlZCAoc2ltKSB7XG4gIGxldCBzdGF0ID0gYXdhaXQgc2ltLnN0YXQoKTtcbiAgcmV0dXJuIHN0YXQuc3RhdGUgPT09ICdCb290ZWQnO1xufVxuXG4vLyByZXR1cm5zIHNpbSBmb3IgZGVzaXJlZCBjYXBzXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVTaW0gKGNhcHMsIHNlc3Npb25JZCkge1xuICBsZXQgbmFtZSA9IGBhcHBpdW1UZXN0LSR7c2Vzc2lvbklkfWA7XG4gIGxldCB1ZGlkID0gYXdhaXQgY3JlYXRlRGV2aWNlKG5hbWUsIGNhcHMuZGV2aWNlTmFtZSwgY2Fwcy5wbGF0Zm9ybVZlcnNpb24pO1xuICByZXR1cm4gYXdhaXQgZ2V0U2ltdWxhdG9yKHVkaWQpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRFeGlzdGluZ1NpbSAoZGV2aWNlTmFtZSwgcGxhdGZvcm1WZXJzaW9uKSB7XG4gIGxldCBkZXZpY2VzID0gYXdhaXQgZ2V0RGV2aWNlcyhwbGF0Zm9ybVZlcnNpb24pO1xuICBmb3IgKGxldCBkZXZpY2Ugb2YgXy52YWx1ZXMoZGV2aWNlcykpIHtcbiAgICBpZiAoZGV2aWNlLm5hbWUgPT09IGRldmljZU5hbWUpIHtcbiAgICAgIHJldHVybiBhd2FpdCBnZXRTaW11bGF0b3IoZGV2aWNlLnVkaWQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJlcGFyZVNhZmFyaUZvckNsZWFudXAgKHRpbWVvdXQgPSA1MDAwKSB7XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBleGVjKCdwZ3JlcCcsIFsnLXgnLCAnTW9iaWxlU2FmYXJpJ10pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoZS5jb2RlID09PSAxKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBleGVjKCdwa2lsbCcsIFsnLTknLCAnLXgnLCAnTW9iaWxlU2FmYXJpJ10pO1xuICAgICAgICB9IGNhdGNoIChlMSkge1xuICAgICAgICAgIGlmIChlMS5jb2RlID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbG9nLndhcm4oZTEubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LCB7XG4gICAgICB3YWl0TXM6IHRpbWVvdXQsXG4gICAgICBpbnRlcnZhbE1zOiAyMDBcbiAgICB9KTtcbiAgICBsb2cuZGVidWcoJ01vYmlsZSBTYWZhcmkgcHJvY2VzcyBpcyBub3QgcnVubmluZy4gQ29udGludWluZyB3aXRoIGNsZWFudXAnKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nLndhcm4oYE1vYmlsZSBTYWZhcmkgaXMgc3RpbGwgcnVubmluZyBhZnRlciAke3RpbWVvdXR9IG1zYCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuU2ltdWxhdG9yUmVzZXQgKGRldmljZSwgb3B0cykge1xuICBpZiAob3B0cy5ub1Jlc2V0ICYmICFvcHRzLmZ1bGxSZXNldCkge1xuICAgIC8vIG5vUmVzZXQgPT09IHRydWUgJiYgZnVsbFJlc2V0ID09PSBmYWxzZVxuICAgIGxvZy5kZWJ1ZygnUmVzZXQ6IG5vUmVzZXQgaXMgb24uIExlYXZpbmcgc2ltdWxhdG9yIGFzIGlzJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFkZXZpY2UpIHtcbiAgICBsb2cuZGVidWcoJ1Jlc2V0OiBubyBkZXZpY2UgYXZhaWxhYmxlLiBTa2lwcGluZycpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChvcHRzLmZ1bGxSZXNldCkge1xuICAgIGxvZy5kZWJ1ZygnUmVzZXQ6IGZ1bGxSZXNldCBpcyBvbi4gQ2xlYW5pbmcgc2ltdWxhdG9yJyk7XG4gICAgLy8gVGhlIHNpbXVsYXRvciBwcm9jZXNzIG11c3QgYmUgZW5kZWQgYmVmb3JlIHdlIGRlbGV0ZSBhcHBsaWNhdGlvbnMuXG4gICAgYXdhaXQgZW5kU2ltdWxhdG9yKGRldmljZSk7XG4gICAgYXdhaXQgZnVsbFJlc2V0U2ltdWxhdG9yKGRldmljZSk7XG4gIH0gZWxzZSBpZiAob3B0cy5idW5kbGVJZCkge1xuICAgIC8vIFRlcm1pbmF0ZSB0aGUgYXBwIHVuZGVyIHRlc3QgaWYgaXQgaXMgc3RpbGwgcnVubmluZyBvbiBTaW11bGF0b3JcbiAgICAvLyBUZXJtaW5hdGlvbiBpcyBub3QgbmVlZGVkIGlmIFNpbXVsYXRvciBpcyBub3QgcnVubmluZ1xuICAgIGlmIChhd2FpdCBzaW1Cb290ZWQoZGV2aWNlKSkge1xuICAgICAgaWYgKGRldmljZS54Y29kZVZlcnNpb24ubWFqb3IgPj0gOCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRlcm1pbmF0ZShkZXZpY2UudWRpZCwgb3B0cy5idW5kbGVJZCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGxvZy53YXJuKGBSZXNldDogZmFpbGVkIHRvIHRlcm1pbmF0ZSBTaW11bGF0b3IgYXBwbGljYXRpb24gd2l0aCBpZCBcIiR7b3B0cy5idW5kbGVJZH1cImApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBlbmRTaW11bGF0b3IoZGV2aWNlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG9wdHMuYXBwKSB7XG4gICAgICBsb2cuaW5mbygnTm90IHNjcnViYmluZyB0aGlyZCBwYXJ0eSBhcHAgaW4gYW50aWNpcGF0aW9uIG9mIHVuaW5zdGFsbCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpc1NhZmFyaSA9IChvcHRzLmJyb3dzZXJOYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpID09PSAnc2FmYXJpJztcbiAgICB0cnkge1xuICAgICAgaWYgKGlzU2FmYXJpKSB7XG4gICAgICAgIGF3YWl0IHByZXBhcmVTYWZhcmlGb3JDbGVhbnVwKCk7XG4gICAgICAgIGF3YWl0IGRldmljZS5jbGVhblNhZmFyaSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgZGV2aWNlLnNjcnViQ3VzdG9tQXBwKHBhdGguYmFzZW5hbWUob3B0cy5hcHApLCBvcHRzLmJ1bmRsZUlkKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZy53YXJuKGVyci5tZXNzYWdlKTtcbiAgICAgIGxvZy53YXJuKGBSZXNldDogY291bGQgbm90IHNjcnViICR7aXNTYWZhcmkgPyAnU2FmYXJpIGJyb3dzZXInIDogJ2FwcGxpY2F0aW9uIHdpdGggaWQgXCInICsgb3B0cy5idW5kbGVJZCArICdcIid9LiBMZWF2aW5nIGFzIGlzLmApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBmdWxsUmVzZXRTaW11bGF0b3IgKGRldmljZSkge1xuICBpZiAoIWRldmljZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IGRldmljZS5jbGVhbigpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBlbmRTaW11bGF0b3IgKGRldmljZSkge1xuICBpZiAoIWRldmljZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxvZy5kZWJ1ZygnUmVzZXQ6IHNodXR0aW5nIGRvd24gc2ltdWxhdG9yJyk7XG4gIGF3YWl0IGRldmljZS5zaHV0ZG93bigpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBpc29sYXRlU2ltdWxhdG9yRGV2aWNlIChkZXZpY2UsIGlzb2xhdGVTaW1EZXZpY2UgPSB0cnVlKSB7XG4gIGlmIChpc29sYXRlU2ltRGV2aWNlKSB7XG4gICAgYXdhaXQgZGV2aWNlLmlzb2xhdGVTaW0oKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBpbnN0YWxsVG9TaW11bGF0b3IgKGRldmljZSwgYXBwLCBidW5kbGVJZCwgbm9SZXNldCA9IHRydWUpIHtcbiAgaWYgKCFhcHApIHtcbiAgICBsb2cuZGVidWcoJ05vIGFwcCBwYXRoIGlzIGdpdmVuLiBOb3RoaW5nIHRvIGluc3RhbGwuJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGJ1bmRsZUlkKSB7XG4gICAgaWYgKGF3YWl0IGRldmljZS5pc0FwcEluc3RhbGxlZChidW5kbGVJZCkpIHtcbiAgICAgIGlmIChub1Jlc2V0KSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhgQXBwICcke2J1bmRsZUlkfScgaXMgYWxyZWFkeSBpbnN0YWxsZWQuIE5vIG5lZWQgdG8gcmVpbnN0YWxsLmApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2cuZGVidWcoYFJlc2V0IHJlcXVlc3RlZC4gUmVtb3ZpbmcgYXBwIHdpdGggaWQgJyR7YnVuZGxlSWR9JyBmcm9tIHRoZSBkZXZpY2VgKTtcbiAgICAgIGF3YWl0IGRldmljZS5yZW1vdmVBcHAoYnVuZGxlSWQpO1xuICAgIH1cbiAgfVxuICBsb2cuZGVidWcoYEluc3RhbGxpbmcgJHthcHB9IG9uIFNpbXVsYXRvciB3aXRoIFVVSUQgJyR7ZGV2aWNlLnVkaWR9Jy4uLmApO1xuICBhd2FpdCBkZXZpY2UuaW5zdGFsbEFwcChhcHApO1xuICBsb2cuZGVidWcoJ1RoZSBhcHAgaGFzIGJlZW4gaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4nKTtcbn1cblxuXG5leHBvcnQgeyBzaW1Cb290ZWQsIGNyZWF0ZVNpbSwgZ2V0RXhpc3RpbmdTaW0sIHJ1blNpbXVsYXRvclJlc2V0LFxuICAgICAgICAgaXNvbGF0ZVNpbXVsYXRvckRldmljZSwgaW5zdGFsbFRvU2ltdWxhdG9yIH07XG4iXSwic291cmNlUm9vdCI6Ii4uLy4uIn0=