UNPKG

appium-instruments

Version:

IOS Instruments + instruments-without-delay launcher used by Appium

308 lines (254 loc) 41.7 kB
require('source-map-support').install(); 'use strict'; var _regeneratorRuntime = require('babel-runtime/regenerator')['default']; var _Promise = require('babel-runtime/core-js/promise')['default']; var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; var _interopRequireWildcard = require('babel-runtime/helpers/interop-require-wildcard')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; var _this = this; var _ = require('..'); var _teen_process = require('teen_process'); var tp = _interopRequireWildcard(_teen_process); var _appiumXcode = require('appium-xcode'); var _appiumXcode2 = _interopRequireDefault(_appiumXcode); var _chai = require('chai'); var _chai2 = _interopRequireDefault(_chai); var _chaiAsPromised = require('chai-as-promised'); var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised); var _appiumTestSupport = require('appium-test-support'); var _appiumSupport = require('appium-support'); _chai2['default'].should(); _chai2['default'].use(_chaiAsPromised2['default']); describe('utils', function () { describe('getInstrumentsPath', (0, _appiumTestSupport.withMocks)({ tp: tp }, function (mocks) { it('should retrieve path', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.tp.expects('exec').once().returns(_Promise.resolve({ stdout: '/a/b/c/d\n', stderr: '' })); context$3$0.next = 3; return _regeneratorRuntime.awrap(_.utils.getInstrumentsPath()); case 3: context$3$0.sent.should.equal('/a/b/c/d'); (0, _appiumTestSupport.verify)(mocks); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should throw an error if cannnot find Instruments', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.tp.expects('exec').once().throws(new Error('Instruments not found')); context$3$0.next = 3; return _regeneratorRuntime.awrap(_.utils.getInstrumentsPath().should.be.rejectedWith(/Could not find the instruments binary/)); case 3: (0, _appiumTestSupport.verify)(mocks); case 4: case 'end': return context$3$0.stop(); } }, null, _this); }); })); describe('getAvailableDevices', (0, _appiumTestSupport.withMocks)({ tp: tp }, function (mocks) { var xcodeVersions = { '8.1(8B62)': { instrumentsOutput: 'Known Devices:\ngalaxy [D633B2E7-6A48-5B2C-B9E4-A1525D3F1155]\nAngel (10.1.1) [xxxx]\nApple TV 1080p (10.0) [70D6BCBA-FCAD-4BBA-ADE9-B71757F4261F] (Simulator)\nApple Watch - 42mm (3.1) [C0E1D6CC-F1C8-4223-AC71-BB8A5182A1A8] (Simulator)\niPad 2 (9.3) [74266576-7E47-4BCB-B0D9-B11133B06A77] (Simulator)\niPad Air (10.1) [8B3934DB-350A-44A0-A8E2-1BC83E346309] (Simulator)\niPad Air 2 (10.1) [D9C1D938-D06D-4CDA-AB59-E16DC30ABD03] (Simulator)\niPad Pro (12.9 inch) (10.1) [9E0F7B13-1BCE-4E7C-9A89-8B19F9B99223] (Simulator)\niPad Pro (9.3) [B02F8899-AF72-40EA-B925-149B22BB72B2] (Simulator)\niPad Pro (9.7 inch) (10.1) [D4E6E5BC-F17F-4088-8FD4-58F07ECC6349] (Simulator)\niPad Retina (10.1) [2B6F522D-B7EA-4F74-811A-DB70B4E7CC7C] (Simulator)\niPad Retina (9.3) [EEAB60FD-3F39-43FE-B8DF-C1097CB22066] (Simulator)\niPhone 4s (9.3) [D61E60EE-25A8-49FA-ADEF-C05F7B737D1E] (Simulator)\niPhone 5 (10.1) [271D45F7-34F5-4F76-8E40-951842CF8F51] (Simulator)\niPhone 5 (9.3) [BF101A98-9FCF-4A4A-8484-F7FF1D575170] (Simulator)\niPhone 5s (10.1) [36F901CC-C539-442E-AEA6-CE87346CA8D7] (Simulator)\niPhone 5s (9.3) [D5C1064D-9543-4484-994E-4D1191587D3E] (Simulator)\niPhone 6 (10.1) [A9672FEC-2E64-4717-8DA1-3538751CCA8A] (Simulator)\niPhone 6 (9.3) [A65D1276-D09E-416A-9B55-C1FF91BE66B5] (Simulator)\niPhone 6 Plus (10.1) [58F617A9-C5F3-4AD0-A35C-F413F757645D] (Simulator)\niPhone 6 Plus (9.3) [805C5E84-CFF6-4E8B-A396-5A5EFBE93551] (Simulator)\niPhone 6s (10.1) [B760E290-B16D-44B9-ACBA-B3088E3FDE7A] (Simulator)\niPhone 6s (9.3) [FC002921-2164-4CEC-B131-CAC308EDD66A] (Simulator)\niPhone 6s Plus (10.1) [8D28052A-4694-4F3A-A988-37D2CC1EDBFC] (Simulator)\niPhone 6s Plus (9.3) [528BA7BD-887B-48EF-92AB-C1E1867C6970] (Simulator)\niPhone 7 (10.1) [F127C749-B3C8-467C-A6A2-1C556F66B1E9] (Simulator)\niPhone 7 (10.1) + Apple Watch Series 2 - 38mm (3.1) [FDBC436C-88D5-4B5D-ABD6-857D5B26C895] (Simulator)\niPhone 7 Plus (10.1) [70AE2D72-BF88-4033-B21E-838185E0EC3E] (Simulator)\niPhone 7 Plus (10.1) + Apple Watch Series 2 - 42mm (3.1) [368E0E6A-DBB0-4272-B242-B8031739E9A8] (Simulator)\niPhone SE (10.1) [1711A8A4-8733-4B37-BBCB-777F6A5B544B] (Simulator)', devices: ['Angel (10.1.1) [xxxx]', 'Apple TV 1080p (10.0) [70D6BCBA-FCAD-4BBA-ADE9-B71757F4261F] (Simulator)', 'Apple Watch - 42mm (3.1) [C0E1D6CC-F1C8-4223-AC71-BB8A5182A1A8] (Simulator)', 'iPad 2 (9.3) [74266576-7E47-4BCB-B0D9-B11133B06A77] (Simulator)', 'iPad Air (10.1) [8B3934DB-350A-44A0-A8E2-1BC83E346309] (Simulator)', 'iPad Air 2 (10.1) [D9C1D938-D06D-4CDA-AB59-E16DC30ABD03] (Simulator)', 'iPad Pro (12.9 inch) (10.1) [9E0F7B13-1BCE-4E7C-9A89-8B19F9B99223] (Simulator)', 'iPad Pro (9.3) [B02F8899-AF72-40EA-B925-149B22BB72B2] (Simulator)', 'iPad Pro (9.7 inch) (10.1) [D4E6E5BC-F17F-4088-8FD4-58F07ECC6349] (Simulator)', 'iPad Retina (10.1) [2B6F522D-B7EA-4F74-811A-DB70B4E7CC7C] (Simulator)', 'iPad Retina (9.3) [EEAB60FD-3F39-43FE-B8DF-C1097CB22066] (Simulator)', 'iPhone 4s (9.3) [D61E60EE-25A8-49FA-ADEF-C05F7B737D1E] (Simulator)', 'iPhone 5 (10.1) [271D45F7-34F5-4F76-8E40-951842CF8F51] (Simulator)', 'iPhone 5 (9.3) [BF101A98-9FCF-4A4A-8484-F7FF1D575170] (Simulator)', 'iPhone 5s (10.1) [36F901CC-C539-442E-AEA6-CE87346CA8D7] (Simulator)', 'iPhone 5s (9.3) [D5C1064D-9543-4484-994E-4D1191587D3E] (Simulator)', 'iPhone 6 (10.1) [A9672FEC-2E64-4717-8DA1-3538751CCA8A] (Simulator)', 'iPhone 6 (9.3) [A65D1276-D09E-416A-9B55-C1FF91BE66B5] (Simulator)', 'iPhone 6 Plus (10.1) [58F617A9-C5F3-4AD0-A35C-F413F757645D] (Simulator)', 'iPhone 6 Plus (9.3) [805C5E84-CFF6-4E8B-A396-5A5EFBE93551] (Simulator)', 'iPhone 6s (10.1) [B760E290-B16D-44B9-ACBA-B3088E3FDE7A] (Simulator)', 'iPhone 6s (9.3) [FC002921-2164-4CEC-B131-CAC308EDD66A] (Simulator)', 'iPhone 6s Plus (10.1) [8D28052A-4694-4F3A-A988-37D2CC1EDBFC] (Simulator)', 'iPhone 6s Plus (9.3) [528BA7BD-887B-48EF-92AB-C1E1867C6970] (Simulator)', 'iPhone 7 (10.1) [F127C749-B3C8-467C-A6A2-1C556F66B1E9] (Simulator)', 'iPhone 7 (10.1) + Apple Watch Series 2 - 38mm (3.1) [FDBC436C-88D5-4B5D-ABD6-857D5B26C895] (Simulator)', 'iPhone 7 Plus (10.1) [70AE2D72-BF88-4033-B21E-838185E0EC3E] (Simulator)', 'iPhone 7 Plus (10.1) + Apple Watch Series 2 - 42mm (3.1) [368E0E6A-DBB0-4272-B242-B8031739E9A8] (Simulator)', 'iPhone SE (10.1) [1711A8A4-8733-4B37-BBCB-777F6A5B544B] (Simulator)'] }, '7.3': { instrumentsOutput: 'Known Devices:\nINsaikrisv [C8476FF9-9BC4-5E52-AE3D-536A2E85D43B]\nAppiumParallel1 (9.2) [0120C306-95C1-4196-BC13-4196105EBEF9]\nApple TV 1080p (9.1) [C5957108-6BA4-4A98-9A83-4BED47EFF1BC]\niPad 2 (8.4) [B45264A0-551C-41A5-A636-8211C05D8003] (Simulator)\niPad 2 (9.2) [4444EB1E-BA48-4DFA-B16C-777171FCF3BC] (Simulator)\niPad Air (8.4) [F26279E7-8BAF-4D7B-ABFE-08D1AC364DCF] (Simulator)', devices: ['AppiumParallel1 (9.2) [0120C306-95C1-4196-BC13-4196105EBEF9]', 'Apple TV 1080p (9.1) [C5957108-6BA4-4A98-9A83-4BED47EFF1BC]', 'iPad 2 (8.4) [B45264A0-551C-41A5-A636-8211C05D8003] (Simulator)', 'iPad 2 (9.2) [4444EB1E-BA48-4DFA-B16C-777171FCF3BC] (Simulator)', 'iPad Air (8.4) [F26279E7-8BAF-4D7B-ABFE-08D1AC364DCF] (Simulator)'] }, '7.0-7.2': { instrumentsOutput: 'Known Devices:\nINsaikrisv [C8476FF9-9BC4-5E52-AE3D-536A2E85D43B]\nAppiumParallel1 (9.2) [0120C306-95C1-4196-BC13-4196105EBEF9]\nApple TV 1080p (9.1) [C5957108-6BA4-4A98-9A83-4BED47EFF1BC]\niPad 2 (8.4) [B45264A0-551C-41A5-A636-8211C05D8003]\niPad 2 (9.2) [4444EB1E-BA48-4DFA-B16C-777171FCF3BC]\niPad Air (8.4) [F26279E7-8BAF-4D7B-ABFE-08D1AC364DCF]', devices: ['AppiumParallel1 (9.2) [0120C306-95C1-4196-BC13-4196105EBEF9]', 'Apple TV 1080p (9.1) [C5957108-6BA4-4A98-9A83-4BED47EFF1BC]', 'iPad 2 (8.4) [B45264A0-551C-41A5-A636-8211C05D8003]', 'iPad 2 (9.2) [4444EB1E-BA48-4DFA-B16C-777171FCF3BC]', 'iPad Air (8.4) [F26279E7-8BAF-4D7B-ABFE-08D1AC364DCF]'] }, '6.0-6.4': { instrumentsOutput: 'Known Devices:\nINsaikrisv [C8476FF9-9BC4-5E52-AE3D-536A2E85D43B]\nAppiumParallel1 (8.4 Simulator) [0120C306-95C1-4196-BC13-4196105EBEF9]\nApple TV 1080p (8.4 Simulator) [C5957108-6BA4-4A98-9A83-4BED47EFF1BC]\niPad 2 (8.4 Simulator) [B45264A0-551C-41A5-A636-8211C05D8003]\niPad Air (8.2 Simulator) [F26279E7-8BAF-4D7B-ABFE-08D1AC364DCF]', devices: ['AppiumParallel1 (8.4 Simulator) [0120C306-95C1-4196-BC13-4196105EBEF9]', 'Apple TV 1080p (8.4 Simulator) [C5957108-6BA4-4A98-9A83-4BED47EFF1BC]', 'iPad 2 (8.4 Simulator) [B45264A0-551C-41A5-A636-8211C05D8003]', 'iPad Air (8.2 Simulator) [F26279E7-8BAF-4D7B-ABFE-08D1AC364DCF]'] } }; _Object$keys(xcodeVersions).forEach(function (version) { return it('should work for Xcode ' + version, function callee$3$0() { return _regeneratorRuntime.async(function callee$3$0$(context$4$0) { while (1) switch (context$4$0.prev = context$4$0.next) { case 0: mocks.tp.expects('exec').once().returns(_Promise.resolve({ stdout: '/a/b/c/d\n', stderr: '' })); mocks.tp.expects('exec').once().returns(_Promise.resolve({ stdout: xcodeVersions[version].instrumentsOutput, stderr: '' })); context$4$0.next = 4; return _regeneratorRuntime.awrap(_.utils.getAvailableDevices()); case 4: context$4$0.t0 = xcodeVersions[version].devices; context$4$0.sent.should.deep.equal(context$4$0.t0); (0, _appiumTestSupport.verify)(mocks); case 7: case 'end': return context$4$0.stop(); } }, null, _this); }); }); it('should throw an error when Instruments fails', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.tp.expects('exec').once().returns(_Promise.resolve({ stdout: '/a/b/c/d\n', stderr: '' })); mocks.tp.expects('exec').once().throws(new Error('Instruments failed')); context$3$0.next = 4; return _regeneratorRuntime.awrap(_.utils.getAvailableDevices().should.be.rejectedWith(/Failed getting devices, err: Error: Instruments failed./)); case 4: (0, _appiumTestSupport.verify)(mocks); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); })); describe('killAllInstruments', (0, _appiumTestSupport.withMocks)({ tp: tp }, function (mocks) { it('should work', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.tp.expects('exec').once().returns(_Promise.resolve({ stdout: '', stderr: '' })); context$3$0.next = 3; return _regeneratorRuntime.awrap(_.utils.killAllInstruments()); case 3: (0, _appiumTestSupport.verify)(mocks); case 4: case 'end': return context$3$0.stop(); } }, null, _this); }); })); describe('cleanAllTraces', (0, _appiumTestSupport.withMocks)({ fs: _appiumSupport.fs }, function (mocks) { (0, _appiumTestSupport.stubEnv)(); it('should work', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: process.env.CLEAN_TRACES = 1; mocks.fs.expects('rimraf').once().returns(_Promise.resolve({ stdout: '', stderr: '' })); context$3$0.next = 4; return _regeneratorRuntime.awrap(_.utils.cleanAllTraces()); case 4: (0, _appiumTestSupport.verify)(mocks); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); })); describe('parseLaunchTimeout', function () { (0, _appiumTestSupport.stubEnv)(); it('should work', function () { _.utils.parseLaunchTimeout(90000).should.deep.equal({ global: 90000 }); _.utils.parseLaunchTimeout('90000').should.deep.equal({ global: 90000 }); _.utils.parseLaunchTimeout({ global: 90000, afterLaunch: 30000 }).should.deep.equal({ global: 90000, afterLaunch: 30000 }); _.utils.parseLaunchTimeout('{"global": 90000, "afterLaunch": 30000}').should.deep.equal({ global: 90000, afterLaunch: 30000 }); }); it('should work with invalid JSON', function () { _.utils.parseLaunchTimeout('x').should.equal('x'); }); }); describe('getIwdPath', (0, _appiumTestSupport.withMocks)({ fs: _appiumSupport.fs }, function (mocks) { it('should work when path is found', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.fs.expects('exists').once().returns(_Promise.resolve(true)); context$3$0.next = 3; return _regeneratorRuntime.awrap(_.utils.getIwdPath('10')); case 3: context$3$0.sent.should.match(/.*thirdparty\/iwd10/); (0, _appiumTestSupport.verify)(mocks); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should work when path is not found', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.fs.expects('exists').once().returns(_Promise.resolve(false)); context$3$0.next = 3; return _regeneratorRuntime.awrap(_.utils.getIwdPath('10')); case 3: context$3$0.sent.should.match(/.*thirdparty\/iwd/); (0, _appiumTestSupport.verify)(mocks); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); })); describe('quickLaunch', (0, _appiumTestSupport.withMocks)({ fs: _appiumSupport.fs, tp: tp }, function (mocks) { it('should remove trace directory', function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.fs.expects('rimraf').once().returns(_Promise.resolve()); mocks.tp.expects('exec').once().withArgs('xcrun').returns(_Promise.resolve({ stdout: '', stderr: '' })); context$3$0.next = 4; return _regeneratorRuntime.awrap(_.utils.quickLaunch()); case 4: (0, _appiumTestSupport.verify)(mocks); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); })); describe('quickInstruments', (0, _appiumTestSupport.withMocks)({ xcode: _appiumXcode2['default'] }, function (mocks) { it('should create an Instruments object', function callee$2$0() { var inst; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_.utils.quickInstruments({ xcodeTraceTemplatePath: '/some/path' })); case 2: inst = context$3$0.sent; inst.should.be.an['instanceof'](_.Instruments); case 4: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should get xcode trace template if none supplied', function callee$2$0() { var inst; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: mocks.xcode.expects('getAutomationTraceTemplatePath').once().returns(_Promise.resolve('/some/path')); context$3$0.next = 3; return _regeneratorRuntime.awrap(_.utils.quickInstruments()); case 3: inst = context$3$0.sent; inst.template.should.equal('/some/path'); case 5: case 'end': return context$3$0.stop(); } }, null, _this); }); })); }); //# sourceMappingURL=data:application/json;charset=utf8;base64,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MkNBQU8sS0FBSyxDQUFDLENBQUM7Ozs7Ozs7S0FDZixDQUFDLENBQUM7R0FDSixDQUFDLENBQUMsQ0FBQzs7QUFFSixVQUFRLENBQUMsa0JBQWtCLEVBQUUsa0NBQVUsRUFBQyxLQUFLLDBCQUFBLEVBQUMsRUFBRSxVQUFDLEtBQUssRUFBSztBQUN6RCxNQUFFLENBQUMscUNBQXFDLEVBQUU7VUFDcEMsSUFBSTs7Ozs7NkNBQVMsUUFBTSxnQkFBZ0IsQ0FBQztBQUN0QyxvQ0FBc0IsRUFBRSxZQUFZO2FBQ3JDLENBQUM7OztBQUZFLGdCQUFJOztBQUdSLGdCQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLGNBQVcsZUFBYSxDQUFDOzs7Ozs7O0tBQzNDLENBQUMsQ0FBQzs7QUFFSCxNQUFFLENBQUMsa0RBQWtELEVBQUU7VUFLakQsSUFBSTs7OztBQUpSLGlCQUFLLENBQUMsS0FBSyxDQUNSLE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUN6QyxJQUFJLEVBQUUsQ0FDTixPQUFPLENBQUMsU0FBUSxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQzs7NkNBQ3pCLFFBQU0sZ0JBQWdCLEVBQUU7OztBQUFyQyxnQkFBSTs7QUFDUixnQkFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDOzs7Ozs7O0tBQzFDLENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQyxDQUFDO0NBQ0wsQ0FBQyxDQUFDIiwiZmlsZSI6InRlc3QvdXRpbHMtc3BlY3MuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IHsgdXRpbHMsIEluc3RydW1lbnRzIH0gZnJvbSAnLi4nO1xuaW1wb3J0ICogYXMgdHAgZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCB4Y29kZSBmcm9tICdhcHBpdW0teGNvZGUnO1xuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgeyB3aXRoTW9ja3MsIHZlcmlmeSwgc3R1YkVudiB9IGZyb20gJ2FwcGl1bS10ZXN0LXN1cHBvcnQnO1xuaW1wb3J0IHsgZnMgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5cblxuY2hhaS5zaG91bGQoKTtcbmNoYWkudXNlKGNoYWlBc1Byb21pc2VkKTtcblxuZGVzY3JpYmUoJ3V0aWxzJywgKCkgPT4ge1xuICBkZXNjcmliZSgnZ2V0SW5zdHJ1bWVudHNQYXRoJywgd2l0aE1vY2tzKHt0cH0sIChtb2NrcykgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0cmlldmUgcGF0aCcsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwXG4gICAgICAgIC5leHBlY3RzKCdleGVjJylcbiAgICAgICAgLm9uY2UoKVxuICAgICAgICAucmV0dXJucyhQcm9taXNlLnJlc29sdmUoe3N0ZG91dDogJy9hL2IvYy9kXFxuJywgc3RkZXJyOicnIH0pKTtcbiAgICAgIChhd2FpdCB1dGlscy5nZXRJbnN0cnVtZW50c1BhdGgoKSkuc2hvdWxkLmVxdWFsKCcvYS9iL2MvZCcpO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIGNhbm5ub3QgZmluZCBJbnN0cnVtZW50cycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwXG4gICAgICAgIC5leHBlY3RzKCdleGVjJylcbiAgICAgICAgLm9uY2UoKVxuICAgICAgICAudGhyb3dzKG5ldyBFcnJvcignSW5zdHJ1bWVudHMgbm90IGZvdW5kJykpO1xuICAgICAgYXdhaXQgdXRpbHMuZ2V0SW5zdHJ1bWVudHNQYXRoKCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvQ291bGQgbm90IGZpbmQgdGhlIGluc3RydW1lbnRzIGJpbmFyeS8pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnZ2V0QXZhaWxhYmxlRGV2aWNlcycsIHdpdGhNb2Nrcyh7dHB9LCAobW9ja3MpID0+IHtcbiAgICBjb25zdCB4Y29kZVZlcnNpb25zID0ge1xuICAgICAgJzguMSg4QjYyKSc6IHtcbiAgICAgICAgaW5zdHJ1bWVudHNPdXRwdXQ6XG5gS25vd24gRGV2aWNlczpcbmdhbGF4eSBbRDYzM0IyRTctNkE0OC01QjJDLUI5RTQtQTE1MjVEM0YxMTU1XVxuQW5nZWwgKDEwLjEuMSkgW3h4eHhdXG5BcHBsZSBUViAxMDgwcCAoMTAuMCkgWzcwRDZCQ0JBLUZDQUQtNEJCQS1BREU5LUI3MTc1N0Y0MjYxRl0gKFNpbXVsYXRvcilcbkFwcGxlIFdhdGNoIC0gNDJtbSAoMy4xKSBbQzBFMUQ2Q0MtRjFDOC00MjIzLUFDNzEtQkI4QTUxODJBMUE4XSAoU2ltdWxhdG9yKVxuaVBhZCAyICg5LjMpIFs3NDI2NjU3Ni03RTQ3LTRCQ0ItQjBEOS1CMTExMzNCMDZBNzddIChTaW11bGF0b3IpXG5pUGFkIEFpciAoMTAuMSkgWzhCMzkzNERCLTM1MEEtNDRBMC1BOEUyLTFCQzgzRTM0NjMwOV0gKFNpbXVsYXRvcilcbmlQYWQgQWlyIDIgKDEwLjEpIFtEOUMxRDkzOC1EMDZELTRDREEtQUI1OS1FMTZEQzMwQUJEMDNdIChTaW11bGF0b3IpXG5pUGFkIFBybyAoMTIuOSBpbmNoKSAoMTAuMSkgWzlFMEY3QjEzLTFCQ0UtNEU3Qy05QTg5LThCMTlGOUI5OTIyM10gKFNpbXVsYXRvcilcbmlQYWQgUHJvICg5LjMpIFtCMDJGODg5OS1BRjcyLTQwRUEtQjkyNS0xNDlCMjJCQjcyQjJdIChTaW11bGF0b3IpXG5pUGFkIFBybyAoOS43IGluY2gpICgxMC4xKSBbRDRFNkU1QkMtRjE3Ri00MDg4LThGRDQtNThGMDdFQ0M2MzQ5XSAoU2ltdWxhdG9yKVxuaVBhZCBSZXRpbmEgKDEwLjEpIFsyQjZGNTIyRC1CN0VBLTRGNzQtODExQS1EQjcwQjRFN0NDN0NdIChTaW11bGF0b3IpXG5pUGFkIFJldGluYSAoOS4zKSBbRUVBQjYwRkQtM0YzOS00M0ZFLUI4REYtQzEwOTdDQjIyMDY2XSAoU2ltdWxhdG9yKVxuaVBob25lIDRzICg5LjMpIFtENjFFNjBFRS0yNUE4LTQ5RkEtQURFRi1DMDVGN0I3MzdEMUVdIChTaW11bGF0b3IpXG5pUGhvbmUgNSAoMTAuMSkgWzI3MUQ0NUY3LTM0RjUtNEY3Ni04RTQwLTk1MTg0MkNGOEY1MV0gKFNpbXVsYXRvcilcbmlQaG9uZSA1ICg5LjMpIFtCRjEwMUE5OC05RkNGLTRBNEEtODQ4NC1GN0ZGMUQ1NzUxNzBdIChTaW11bGF0b3IpXG5pUGhvbmUgNXMgKDEwLjEpIFszNkY5MDFDQy1DNTM5LTQ0MkUtQUVBNi1DRTg3MzQ2Q0E4RDddIChTaW11bGF0b3IpXG5pUGhvbmUgNXMgKDkuMykgW0Q1QzEwNjRELTk1NDMtNDQ4NC05OTRFLTREMTE5MTU4N0QzRV0gKFNpbXVsYXRvcilcbmlQaG9uZSA2ICgxMC4xKSBbQTk2NzJGRUMtMkU2NC00NzE3LThEQTEtMzUzODc1MUNDQThBXSAoU2ltdWxhdG9yKVxuaVBob25lIDYgKDkuMykgW0E2NUQxMjc2LUQwOUUtNDE2QS05QjU1LUMxRkY5MUJFNjZCNV0gKFNpbXVsYXRvcilcbmlQaG9uZSA2IFBsdXMgKDEwLjEpIFs1OEY2MTdBOS1DNUYzLTRBRDAtQTM1Qy1GNDEzRjc1NzY0NURdIChTaW11bGF0b3IpXG5pUGhvbmUgNiBQbHVzICg5LjMpIFs4MDVDNUU4NC1DRkY2LTRFOEItQTM5Ni01QTVFRkJFOTM1NTFdIChTaW11bGF0b3IpXG5pUGhvbmUgNnMgKDEwLjEpIFtCNzYwRTI5MC1CMTZELTQ0QjktQUNCQS1CMzA4OEUzRkRFN0FdIChTaW11bGF0b3IpXG5pUGhvbmUgNnMgKDkuMykgW0ZDMDAyOTIxLTIxNjQtNENFQy1CMTMxLUNBQzMwOEVERDY2QV0gKFNpbXVsYXRvcilcbmlQaG9uZSA2cyBQbHVzICgxMC4xKSBbOEQyODA1MkEtNDY5NC00RjNBLUE5ODgtMzdEMkNDMUVEQkZDXSAoU2ltdWxhdG9yKVxuaVBob25lIDZzIFBsdXMgKDkuMykgWzUyOEJBN0JELTg4N0ItNDhFRi05MkFCLUMxRTE4NjdDNjk3MF0gKFNpbXVsYXRvcilcbmlQaG9uZSA3ICgxMC4xKSBbRjEyN0M3NDktQjNDOC00NjdDLUE2QTItMUM1NTZGNjZCMUU5XSAoU2ltdWxhdG9yKVxuaVBob25lIDcgKDEwLjEpICsgQXBwbGUgV2F0Y2ggU2VyaWVzIDIgLSAzOG1tICgzLjEpIFtGREJDNDM2Qy04OEQ1LTRCNUQtQUJENi04NTdENUIyNkM4OTVdIChTaW11bGF0b3IpXG5pUGhvbmUgNyBQbHVzICgxMC4xKSBbNzBBRTJENzItQkY4OC00MDMzLUIyMUUtODM4MTg1RTBFQzNFXSAoU2ltdWxhdG9yKVxuaVBob25lIDcgUGx1cyAoMTAuMSkgKyBBcHBsZSBXYXRjaCBTZXJpZXMgMiAtIDQybW0gKDMuMSkgWzM2OEUwRTZBLURCQjAtNDI3Mi1CMjQyLUI4MDMxNzM5RTlBOF0gKFNpbXVsYXRvcilcbmlQaG9uZSBTRSAoMTAuMSkgWzE3MTFBOEE0LTg3MzMtNEIzNy1CQkNCLTc3N0Y2QTVCNTQ0Ql0gKFNpbXVsYXRvcilgLFxuICAgICAgICBkZXZpY2VzOiBbXG4gICAgICAgICAgJ0FuZ2VsICgxMC4xLjEpIFt4eHh4XScsXG4gICAgICAgICAgJ0FwcGxlIFRWIDEwODBwICgxMC4wKSBbNzBENkJDQkEtRkNBRC00QkJBLUFERTktQjcxNzU3RjQyNjFGXSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ0FwcGxlIFdhdGNoIC0gNDJtbSAoMy4xKSBbQzBFMUQ2Q0MtRjFDOC00MjIzLUFDNzEtQkI4QTUxODJBMUE4XSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQYWQgMiAoOS4zKSBbNzQyNjY1NzYtN0U0Ny00QkNCLUIwRDktQjExMTMzQjA2QTc3XSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQYWQgQWlyICgxMC4xKSBbOEIzOTM0REItMzUwQS00NEEwLUE4RTItMUJDODNFMzQ2MzA5XSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQYWQgQWlyIDIgKDEwLjEpIFtEOUMxRDkzOC1EMDZELTRDREEtQUI1OS1FMTZEQzMwQUJEMDNdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBhZCBQcm8gKDEyLjkgaW5jaCkgKDEwLjEpIFs5RTBGN0IxMy0xQkNFLTRFN0MtOUE4OS04QjE5RjlCOTkyMjNdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBhZCBQcm8gKDkuMykgW0IwMkY4ODk5LUFGNzItNDBFQS1COTI1LTE0OUIyMkJCNzJCMl0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGFkIFBybyAoOS43IGluY2gpICgxMC4xKSBbRDRFNkU1QkMtRjE3Ri00MDg4LThGRDQtNThGMDdFQ0M2MzQ5XSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQYWQgUmV0aW5hICgxMC4xKSBbMkI2RjUyMkQtQjdFQS00Rjc0LTgxMUEtREI3MEI0RTdDQzdDXSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQYWQgUmV0aW5hICg5LjMpIFtFRUFCNjBGRC0zRjM5LTQzRkUtQjhERi1DMTA5N0NCMjIwNjZdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDRzICg5LjMpIFtENjFFNjBFRS0yNUE4LTQ5RkEtQURFRi1DMDVGN0I3MzdEMUVdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDUgKDEwLjEpIFsyNzFENDVGNy0zNEY1LTRGNzYtOEU0MC05NTE4NDJDRjhGNTFdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDUgKDkuMykgW0JGMTAxQTk4LTlGQ0YtNEE0QS04NDg0LUY3RkYxRDU3NTE3MF0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGhvbmUgNXMgKDEwLjEpIFszNkY5MDFDQy1DNTM5LTQ0MkUtQUVBNi1DRTg3MzQ2Q0E4RDddIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDVzICg5LjMpIFtENUMxMDY0RC05NTQzLTQ0ODQtOTk0RS00RDExOTE1ODdEM0VdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDYgKDEwLjEpIFtBOTY3MkZFQy0yRTY0LTQ3MTctOERBMS0zNTM4NzUxQ0NBOEFdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDYgKDkuMykgW0E2NUQxMjc2LUQwOUUtNDE2QS05QjU1LUMxRkY5MUJFNjZCNV0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGhvbmUgNiBQbHVzICgxMC4xKSBbNThGNjE3QTktQzVGMy00QUQwLUEzNUMtRjQxM0Y3NTc2NDVEXSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQaG9uZSA2IFBsdXMgKDkuMykgWzgwNUM1RTg0LUNGRjYtNEU4Qi1BMzk2LTVBNUVGQkU5MzU1MV0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGhvbmUgNnMgKDEwLjEpIFtCNzYwRTI5MC1CMTZELTQ0QjktQUNCQS1CMzA4OEUzRkRFN0FdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDZzICg5LjMpIFtGQzAwMjkyMS0yMTY0LTRDRUMtQjEzMS1DQUMzMDhFREQ2NkFdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDZzIFBsdXMgKDEwLjEpIFs4RDI4MDUyQS00Njk0LTRGM0EtQTk4OC0zN0QyQ0MxRURCRkNdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIDZzIFBsdXMgKDkuMykgWzUyOEJBN0JELTg4N0ItNDhFRi05MkFCLUMxRTE4NjdDNjk3MF0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGhvbmUgNyAoMTAuMSkgW0YxMjdDNzQ5LUIzQzgtNDY3Qy1BNkEyLTFDNTU2RjY2QjFFOV0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGhvbmUgNyAoMTAuMSkgKyBBcHBsZSBXYXRjaCBTZXJpZXMgMiAtIDM4bW0gKDMuMSkgW0ZEQkM0MzZDLTg4RDUtNEI1RC1BQkQ2LTg1N0Q1QjI2Qzg5NV0gKFNpbXVsYXRvciknLFxuICAgICAgICAgICdpUGhvbmUgNyBQbHVzICgxMC4xKSBbNzBBRTJENzItQkY4OC00MDMzLUIyMUUtODM4MTg1RTBFQzNFXSAoU2ltdWxhdG9yKScsXG4gICAgICAgICAgJ2lQaG9uZSA3IFBsdXMgKDEwLjEpICsgQXBwbGUgV2F0Y2ggU2VyaWVzIDIgLSA0Mm1tICgzLjEpIFszNjhFMEU2QS1EQkIwLTQyNzItQjI0Mi1CODAzMTczOUU5QThdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBob25lIFNFICgxMC4xKSBbMTcxMUE4QTQtODczMy00QjM3LUJCQ0ItNzc3RjZBNUI1NDRCXSAoU2ltdWxhdG9yKSdcbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgICc3LjMnOiB7XG4gICAgICAgIGluc3RydW1lbnRzT3V0cHV0OlxuYEtub3duIERldmljZXM6XG5JTnNhaWtyaXN2IFtDODQ3NkZGOS05QkM0LTVFNTItQUUzRC01MzZBMkU4NUQ0M0JdXG5BcHBpdW1QYXJhbGxlbDEgKDkuMikgWzAxMjBDMzA2LTk1QzEtNDE5Ni1CQzEzLTQxOTYxMDVFQkVGOV1cbkFwcGxlIFRWIDEwODBwICg5LjEpIFtDNTk1NzEwOC02QkE0LTRBOTgtOUE4My00QkVENDdFRkYxQkNdXG5pUGFkIDIgKDguNCkgW0I0NTI2NEEwLTU1MUMtNDFBNS1BNjM2LTgyMTFDMDVEODAwM10gKFNpbXVsYXRvcilcbmlQYWQgMiAoOS4yKSBbNDQ0NEVCMUUtQkE0OC00REZBLUIxNkMtNzc3MTcxRkNGM0JDXSAoU2ltdWxhdG9yKVxuaVBhZCBBaXIgKDguNCkgW0YyNjI3OUU3LThCQUYtNEQ3Qi1BQkZFLTA4RDFBQzM2NERDRl0gKFNpbXVsYXRvcilgLFxuICAgICAgICBkZXZpY2VzOiBbXG4gICAgICAgICAgJ0FwcGl1bVBhcmFsbGVsMSAoOS4yKSBbMDEyMEMzMDYtOTVDMS00MTk2LUJDMTMtNDE5NjEwNUVCRUY5XScsXG4gICAgICAgICAgJ0FwcGxlIFRWIDEwODBwICg5LjEpIFtDNTk1NzEwOC02QkE0LTRBOTgtOUE4My00QkVENDdFRkYxQkNdJyxcbiAgICAgICAgICAnaVBhZCAyICg4LjQpIFtCNDUyNjRBMC01NTFDLTQxQTUtQTYzNi04MjExQzA1RDgwMDNdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBhZCAyICg5LjIpIFs0NDQ0RUIxRS1CQTQ4LTRERkEtQjE2Qy03NzcxNzFGQ0YzQkNdIChTaW11bGF0b3IpJyxcbiAgICAgICAgICAnaVBhZCBBaXIgKDguNCkgW0YyNjI3OUU3LThCQUYtNEQ3Qi1BQkZFLTA4RDFBQzM2NERDRl0gKFNpbXVsYXRvciknXG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICAnNy4wLTcuMic6IHtcbiAgICAgICAgaW5zdHJ1bWVudHNPdXRwdXQ6XG5gS25vd24gRGV2aWNlczpcbklOc2Fpa3Jpc3YgW0M4NDc2RkY5LTlCQzQtNUU1Mi1BRTNELTUzNkEyRTg1RDQzQl1cbkFwcGl1bVBhcmFsbGVsMSAoOS4yKSBbMDEyMEMzMDYtOTVDMS00MTk2LUJDMTMtNDE5NjEwNUVCRUY5XVxuQXBwbGUgVFYgMTA4MHAgKDkuMSkgW0M1OTU3MTA4LTZCQTQtNEE5OC05QTgzLTRCRUQ0N0VGRjFCQ11cbmlQYWQgMiAoOC40KSBbQjQ1MjY0QTAtNTUxQy00MUE1LUE2MzYtODIxMUMwNUQ4MDAzXVxuaVBhZCAyICg5LjIpIFs0NDQ0RUIxRS1CQTQ4LTRERkEtQjE2Qy03NzcxNzFGQ0YzQkNdXG5pUGFkIEFpciAoOC40KSBbRjI2Mjc5RTctOEJBRi00RDdCLUFCRkUtMDhEMUFDMzY0RENGXWAsXG4gICAgICAgIGRldmljZXM6IFtcbiAgICAgICAgICAnQXBwaXVtUGFyYWxsZWwxICg5LjIpIFswMTIwQzMwNi05NUMxLTQxOTYtQkMxMy00MTk2MTA1RUJFRjldJyxcbiAgICAgICAgICAnQXBwbGUgVFYgMTA4MHAgKDkuMSkgW0M1OTU3MTA4LTZCQTQtNEE5OC05QTgzLTRCRUQ0N0VGRjFCQ10nLFxuICAgICAgICAgICdpUGFkIDIgKDguNCkgW0I0NTI2NEEwLTU1MUMtNDFBNS1BNjM2LTgyMTFDMDVEODAwM10nLFxuICAgICAgICAgICdpUGFkIDIgKDkuMikgWzQ0NDRFQjFFLUJBNDgtNERGQS1CMTZDLTc3NzE3MUZDRjNCQ10nLFxuICAgICAgICAgICdpUGFkIEFpciAoOC40KSBbRjI2Mjc5RTctOEJBRi00RDdCLUFCRkUtMDhEMUFDMzY0RENGXSdcbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgICc2LjAtNi40Jzoge1xuICAgICAgICBpbnN0cnVtZW50c091dHB1dDpcbmBLbm93biBEZXZpY2VzOlxuSU5zYWlrcmlzdiBbQzg0NzZGRjktOUJDNC01RTUyLUFFM0QtNTM2QTJFODVENDNCXVxuQXBwaXVtUGFyYWxsZWwxICg4LjQgU2ltdWxhdG9yKSBbMDEyMEMzMDYtOTVDMS00MTk2LUJDMTMtNDE5NjEwNUVCRUY5XVxuQXBwbGUgVFYgMTA4MHAgKDguNCBTaW11bGF0b3IpIFtDNTk1NzEwOC02QkE0LTRBOTgtOUE4My00QkVENDdFRkYxQkNdXG5pUGFkIDIgKDguNCBTaW11bGF0b3IpIFtCNDUyNjRBMC01NTFDLTQxQTUtQTYzNi04MjExQzA1RDgwMDNdXG5pUGFkIEFpciAoOC4yIFNpbXVsYXRvcikgW0YyNjI3OUU3LThCQUYtNEQ3Qi1BQkZFLTA4RDFBQzM2NERDRl1gLFxuICAgICAgICBkZXZpY2VzOiBbXG4gICAgICAgICAgJ0FwcGl1bVBhcmFsbGVsMSAoOC40IFNpbXVsYXRvcikgWzAxMjBDMzA2LTk1QzEtNDE5Ni1CQzEzLTQxOTYxMDVFQkVGOV0nLFxuICAgICAgICAgICdBcHBsZSBUViAxMDgwcCAoOC40IFNpbXVsYXRvcikgW0M1OTU3MTA4LTZCQTQtNEE5OC05QTgzLTRCRUQ0N0VGRjFCQ10nLFxuICAgICAgICAgICdpUGFkIDIgKDguNCBTaW11bGF0b3IpIFtCNDUyNjRBMC01NTFDLTQxQTUtQTYzNi04MjExQzA1RDgwMDNdJyxcbiAgICAgICAgICAnaVBhZCBBaXIgKDguMiBTaW11bGF0b3IpIFtGMjYyNzlFNy04QkFGLTREN0ItQUJGRS0wOEQxQUMzNjREQ0ZdJ1xuICAgICAgICBdXG4gICAgICB9XG4gICAgfTtcblxuICAgIE9iamVjdC5rZXlzKHhjb2RlVmVyc2lvbnMpLmZvckVhY2goKHZlcnNpb24pID0+XG4gICAgICBpdChgc2hvdWxkIHdvcmsgZm9yIFhjb2RlICR7dmVyc2lvbn1gLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG1vY2tzLnRwXG4gICAgICAgICAgLmV4cGVjdHMoJ2V4ZWMnKVxuICAgICAgICAgIC5vbmNlKClcbiAgICAgICAgICAucmV0dXJucyhQcm9taXNlLnJlc29sdmUoe3N0ZG91dDogJy9hL2IvYy9kXFxuJywgc3RkZXJyOicnIH0pKTtcbiAgICAgICAgbW9ja3MudHBcbiAgICAgICAgICAuZXhwZWN0cygnZXhlYycpXG4gICAgICAgICAgLm9uY2UoKVxuICAgICAgICAgIC5yZXR1cm5zKFByb21pc2UucmVzb2x2ZSh7c3Rkb3V0OiB4Y29kZVZlcnNpb25zW3ZlcnNpb25dLmluc3RydW1lbnRzT3V0cHV0LCBzdGRlcnI6JycgfSkpO1xuICAgICAgICAoYXdhaXQgdXRpbHMuZ2V0QXZhaWxhYmxlRGV2aWNlcygpKS5zaG91bGQuZGVlcC5lcXVhbCh4Y29kZVZlcnNpb25zW3ZlcnNpb25dLmRldmljZXMpO1xuICAgICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIEluc3RydW1lbnRzIGZhaWxzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MudHBcbiAgICAgICAgLmV4cGVjdHMoJ2V4ZWMnKVxuICAgICAgICAub25jZSgpXG4gICAgICAgIC5yZXR1cm5zKFByb21pc2UucmVzb2x2ZSh7c3Rkb3V0OiAnL2EvYi9jL2RcXG4nLCBzdGRlcnI6JycgfSkpO1xuICAgICAgbW9ja3MudHBcbiAgICAgICAgLmV4cGVjdHMoJ2V4ZWMnKVxuICAgICAgICAub25jZSgpXG4gICAgICAgIC50aHJvd3MobmV3IEVycm9yKCdJbnN0cnVtZW50cyBmYWlsZWQnKSk7XG4gICAgICBhd2FpdCB1dGlscy5nZXRBdmFpbGFibGVEZXZpY2VzKCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvRmFpbGVkIGdldHRpbmcgZGV2aWNlcywgZXJyOiBFcnJvcjogSW5zdHJ1bWVudHMgZmFpbGVkLi8pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgna2lsbEFsbEluc3RydW1lbnRzJywgd2l0aE1vY2tzKHt0cH0sIChtb2NrcykgPT4ge1xuICAgIGl0KCdzaG91bGQgd29yaycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwXG4gICAgICAgIC5leHBlY3RzKCdleGVjJylcbiAgICAgICAgLm9uY2UoKVxuICAgICAgICAucmV0dXJucyhQcm9taXNlLnJlc29sdmUoe3N0ZG91dDogJycsIHN0ZGVycjonJyB9KSk7XG4gICAgICBhd2FpdCB1dGlscy5raWxsQWxsSW5zdHJ1bWVudHMoKTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gIH0pKTtcbiAgZGVzY3JpYmUoJ2NsZWFuQWxsVHJhY2VzJywgd2l0aE1vY2tzKHtmc30sIChtb2NrcykgPT4ge1xuICAgIHN0dWJFbnYoKTtcbiAgICBpdCgnc2hvdWxkIHdvcmsnLCBhc3luYyAoKSA9PiB7XG4gICAgICBwcm9jZXNzLmVudi5DTEVBTl9UUkFDRVMgPSAxO1xuICAgICAgbW9ja3MuZnNcbiAgICAgICAgLmV4cGVjdHMoJ3JpbXJhZicpXG4gICAgICAgIC5vbmNlKClcbiAgICAgICAgLnJldHVybnMoUHJvbWlzZS5yZXNvbHZlKHtzdGRvdXQ6ICcnLCBzdGRlcnI6JycgfSkpO1xuICAgICAgYXdhaXQgdXRpbHMuY2xlYW5BbGxUcmFjZXMoKTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gIH0pKTtcbiAgZGVzY3JpYmUoJ3BhcnNlTGF1bmNoVGltZW91dCcsICgpID0+IHtcbiAgICBzdHViRW52KCk7XG4gICAgaXQoJ3Nob3VsZCB3b3JrJywgKCkgPT4ge1xuICAgICAgdXRpbHMucGFyc2VMYXVuY2hUaW1lb3V0KDkwMDAwKS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIGdsb2JhbDogOTAwMDAgfSk7XG4gICAgICB1dGlscy5wYXJzZUxhdW5jaFRpbWVvdXQoJzkwMDAwJykuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICBnbG9iYWw6IDkwMDAwIH0pO1xuICAgICAgdXRpbHMucGFyc2VMYXVuY2hUaW1lb3V0KHtnbG9iYWw6IDkwMDAwLCBhZnRlckxhdW5jaDogMzAwMDB9KS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIGdsb2JhbDogOTAwMDAsIGFmdGVyTGF1bmNoOiAzMDAwMCB9KTtcbiAgICAgIHV0aWxzLnBhcnNlTGF1bmNoVGltZW91dCgne1wiZ2xvYmFsXCI6IDkwMDAwLCBcImFmdGVyTGF1bmNoXCI6IDMwMDAwfScpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgZ2xvYmFsOiA5MDAwMCwgYWZ0ZXJMYXVuY2g6IDMwMDAwIH0pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgd29yayB3aXRoIGludmFsaWQgSlNPTicsICgpID0+IHtcbiAgICAgIHV0aWxzLnBhcnNlTGF1bmNoVGltZW91dCgneCcpLnNob3VsZC5lcXVhbCgneCcpO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJ2dldEl3ZFBhdGgnLCB3aXRoTW9ja3Moe2ZzfSwgKG1vY2tzKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB3b3JrIHdoZW4gcGF0aCBpcyBmb3VuZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmZzXG4gICAgICAgIC5leHBlY3RzKCdleGlzdHMnKVxuICAgICAgICAub25jZSgpXG4gICAgICAgIC5yZXR1cm5zKFByb21pc2UucmVzb2x2ZSh0cnVlKSk7XG4gICAgICAoYXdhaXQgdXRpbHMuZ2V0SXdkUGF0aCgnMTAnKSkuc2hvdWxkLm1hdGNoKFxuICAgICAgICAvLip0aGlyZHBhcnR5XFwvaXdkMTAvKTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCB3b3JrIHdoZW4gcGF0aCBpcyBub3QgZm91bmQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5mc1xuICAgICAgICAuZXhwZWN0cygnZXhpc3RzJylcbiAgICAgICAgLm9uY2UoKVxuICAgICAgICAucmV0dXJucyhQcm9taXNlLnJlc29sdmUoZmFsc2UpKTtcbiAgICAgIChhd2FpdCB1dGlscy5nZXRJd2RQYXRoKCcxMCcpKS5zaG91bGQubWF0Y2goXG4gICAgICAgIC8uKnRoaXJkcGFydHlcXC9pd2QvKTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gIH0pKTtcblxuICBkZXNjcmliZSgncXVpY2tMYXVuY2gnLCB3aXRoTW9ja3Moe2ZzLCB0cH0sIChtb2NrcykgPT4ge1xuICAgIGl0KCdzaG91bGQgcmVtb3ZlIHRyYWNlIGRpcmVjdG9yeScsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmZzXG4gICAgICAgIC5leHBlY3RzKCdyaW1yYWYnKVxuICAgICAgICAub25jZSgpXG4gICAgICAgIC5yZXR1cm5zKFByb21pc2UucmVzb2x2ZSgpKTtcbiAgICAgIG1vY2tzLnRwXG4gICAgICAgIC5leHBlY3RzKCdleGVjJylcbiAgICAgICAgLm9uY2UoKVxuICAgICAgICAud2l0aEFyZ3MoJ3hjcnVuJylcbiAgICAgICAgLnJldHVybnMoUHJvbWlzZS5yZXNvbHZlKHtzdGRvdXQ6ICcnLCBzdGRlcnI6JycgfSkpO1xuICAgICAgYXdhaXQgdXRpbHMucXVpY2tMYXVuY2goKTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gIH0pKTtcblxuICBkZXNjcmliZSgncXVpY2tJbnN0cnVtZW50cycsIHdpdGhNb2Nrcyh7eGNvZGV9LCAobW9ja3MpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhbiBJbnN0cnVtZW50cyBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgaW5zdCA9IGF3YWl0IHV0aWxzLnF1aWNrSW5zdHJ1bWVudHMoe1xuICAgICAgICB4Y29kZVRyYWNlVGVtcGxhdGVQYXRoOiAnL3NvbWUvcGF0aCdcbiAgICAgIH0pO1xuICAgICAgaW5zdC5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihJbnN0cnVtZW50cyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB4Y29kZSB0cmFjZSB0ZW1wbGF0ZSBpZiBub25lIHN1cHBsaWVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MueGNvZGVcbiAgICAgICAgLmV4cGVjdHMoJ2dldEF1dG9tYXRpb25UcmFjZVRlbXBsYXRlUGF0aCcpXG4gICAgICAgIC5vbmNlKClcbiAgICAgICAgLnJldHVybnMoUHJvbWlzZS5yZXNvbHZlKCcvc29tZS9wYXRoJykpO1xuICAgICAgbGV0IGluc3QgPSBhd2FpdCB1dGlscy5xdWlja0luc3RydW1lbnRzKCk7XG4gICAgICBpbnN0LnRlbXBsYXRlLnNob3VsZC5lcXVhbCgnL3NvbWUvcGF0aCcpO1xuICAgIH0pO1xuICB9KSk7XG59KTtcbiJdLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==