appium-doctor
Version:
Test environment for fitness to run Appium
605 lines (510 loc) • 49.8 kB
JavaScript
require('source-map-support').install();
;
var _Promise = require('babel-runtime/core-js/promise')['default'];
var _regeneratorRuntime = require('babel-runtime/regenerator')['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 _libIos = require('../lib/ios');
var _appiumSupport = require('appium-support');
var _libUtils = require('../lib/utils');
var utils = _interopRequireWildcard(_libUtils);
var _teen_process = require('teen_process');
var tp = _interopRequireWildcard(_teen_process);
var _libPrompt = require('../lib/prompt');
var prompter = _interopRequireWildcard(_libPrompt);
var _libNodeDetector = require('../lib/node-detector');
var _libNodeDetector2 = _interopRequireDefault(_libNodeDetector);
var _libDoctor = require('../lib/doctor');
var _libDoctor2 = _interopRequireDefault(_libDoctor);
var _libLogger = require('../lib/logger');
var _libLogger2 = _interopRequireDefault(_libLogger);
var _chai = require('chai');
var _chai2 = _interopRequireDefault(_chai);
var _chaiAsPromised = require('chai-as-promised');
var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised);
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _appiumTestSupport = require('appium-test-support');
_chai2['default'].should();
_chai2['default'].use(_chaiAsPromised2['default']);
var P = _Promise;
describe('ios', function () {
describe('XcodeCheck', (0, _appiumTestSupport.withMocks)({ tp: tp, fs: _appiumSupport.fs }, function (mocks) {
var check = new _libIos.XcodeCheck();
it('autofix', function () {
check.autofix.should.not.be.ok;
});
it('diagnose - success', 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(P.resolve({ stdout: '/a/b/c/d\n', stderr: '' }));
mocks.fs.expects('exists').once().returns(P.resolve(true));
context$3$0.next = 4;
return _regeneratorRuntime.awrap(check.diagnose());
case 4:
context$3$0.t0 = {
ok: true,
message: 'Xcode is installed at: /a/b/c/d'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - xcode-select', 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(P.reject(new Error('Something wrong!')));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: false,
message: 'Xcode is NOT installed!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - path not exists', 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(P.resolve({ stdout: '/a/b/c/d\n', stderr: '' }));
mocks.fs.expects('exists').once().returns(P.resolve(false));
context$3$0.next = 4;
return _regeneratorRuntime.awrap(check.diagnose());
case 4:
context$3$0.t0 = {
ok: false,
message: 'Xcode cannot be found at \'/a/b/c/d\'!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix', 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:
context$3$0.next = 2;
return _regeneratorRuntime.awrap(check.fix());
case 2:
context$3$0.sent.should.equal('Manually install Xcode.');
case 3:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('XcodeCmdLineToolsCheck', (0, _appiumTestSupport.withMocks)({ tp: tp, utils: utils, prompter: prompter, system: _appiumSupport.system }, function (mocks, S) {
var check = new _libIos.XcodeCmdLineToolsCheck();
it('autofix', function () {
check.autofix.should.be.ok;
});
it('diagnose - success', 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.system.expects('macOsxVersion').once().returns(P.resolve('10.10'));
mocks.tp.expects('exec').once().returns(P.resolve({ stdout: '1234 install-time\n', stderr: '' }));
context$3$0.next = 4;
return _regeneratorRuntime.awrap(check.diagnose());
case 4:
context$3$0.t0 = {
ok: true,
message: 'Xcode Command Line Tools are installed.'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - pkgutil crash', 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.system.expects('macOsxVersion').once().returns(_bluebird2['default'].resolve('10.10'));
mocks.tp.expects('exec').once().returns(_Promise.reject(new Error('Something wrong!')));
context$3$0.next = 4;
return _regeneratorRuntime.awrap(check.diagnose());
case 4:
context$3$0.t0 = {
ok: false,
message: 'Xcode Command Line Tools are NOT installed!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - no install time', 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.system.expects('macOsxVersion').once().returns(_bluebird2['default'].resolve('10.10'));
mocks.tp.expects('exec').once().returns(P.resolve({ stdout: '1234 abcd\n', stderr: '' }));
context$3$0.next = 4;
return _regeneratorRuntime.awrap(check.diagnose());
case 4:
context$3$0.t0 = {
ok: false,
message: 'Xcode Command Line Tools are NOT installed!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix - yes', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.tp.expects('exec').once().returns(P.resolve({ stdout: '', stderr: '' }));
mocks.prompter.expects('fixIt').once().returns(P.resolve('yes'));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(check.fix());
case 5:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: The following command need be executed: xcode-select --install'].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix - no', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.tp.expects('exec').never();
mocks.prompter.expects('fixIt').once().returns(P.resolve('no'));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(check.fix().should.be.rejectedWith(_libDoctor2['default']));
case 5:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: The following command need be executed: xcode-select --install', 'info: Skipping you will need to install Xcode manually.'].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('authorizeIosFix', (0, _appiumTestSupport.withMocks)({ utils: utils, prompter: prompter }, function (mocks, S) {
it('fix - yes', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.utils.expects('authorize').once();
mocks.prompter.expects('fixIt').once().returns(P.resolve('yes'));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(_libIos.fixes.authorizeIosFix());
case 5:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: The authorize iOS script need to be run.'].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix - no', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.utils.expects('authorize').never();
mocks.prompter.expects('fixIt').once().returns(P.resolve('no'));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(_libIos.fixes.authorizeIosFix().should.be.rejectedWith(_libDoctor2['default']));
case 5:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: The authorize iOS script need to be run.', 'info: Skipping you will need to run the authorize iOS manually.'].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('DevToolsSecurityCheck', (0, _appiumTestSupport.withMocks)({ fixes: _libIos.fixes, tp: tp }, function (mocks) {
var check = new _libIos.DevToolsSecurityCheck();
it('autofix', function () {
check.autofix.should.be.ok;
});
it('diagnose - success', 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(P.resolve({ stdout: '1234 enabled\n', stderr: '' }));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: true,
message: 'DevToolsSecurity is enabled.'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - DevToolsSecurity crash', 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.reject(new Error('Something wrong!')));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: false,
message: 'DevToolsSecurity is NOT enabled!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - not enabled', 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(P.resolve({ stdout: '1234 abcd\n', stderr: '' }));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: false,
message: 'DevToolsSecurity is NOT enabled!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix', 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.fixes.expects('authorizeIosFix').once();
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.fix());
case 3:
(0, _appiumTestSupport.verify)(mocks);
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('AuthorizationDbCheck', (0, _appiumTestSupport.withMocks)({ fixes: _libIos.fixes, tp: tp, fs: _appiumSupport.fs, utils: utils, system: _appiumSupport.system }, function (mocks) {
var check = new _libIos.AuthorizationDbCheck();
it('autofix', function () {
check.autofix.should.be.ok;
});
it('diagnose - success - 10.10', 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(P.resolve({ stdout: '1234 is-developer\n', stderr: '' }));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: true,
message: 'The Authorization DB is set up properly.'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - success - 10.8', 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(P.reject(new Error('Oh No!')));
mocks.system.expects('macOsxVersion').once().returns(P.resolve('10.8'));
mocks.fs.expects('readFile').once().returns(P.resolve('<key>system.privilege.taskport</key> \n <dict>\n <key>allow-root</key>\n <true/>'));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(check.diagnose());
case 5:
context$3$0.t0 = {
ok: true,
message: 'The Authorization DB is set up properly.'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - 10.10 - security', 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(P.reject(new Error('Oh No!')));
mocks.system.expects('macOsxVersion').once().returns(P.resolve('10.10'));
context$3$0.next = 4;
return _regeneratorRuntime.awrap(check.diagnose());
case 4:
context$3$0.t0 = {
ok: false,
message: 'The Authorization DB is NOT set up properly.'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure - /etc/authorization', 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(P.reject(new Error('Oh No!')));
mocks.system.expects('macOsxVersion').once().returns(P.resolve('10.8'));
mocks.fs.expects('readFile').once().returns(P.resolve(''));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(check.diagnose());
case 5:
context$3$0.t0 = {
ok: false,
message: 'The Authorization DB is NOT set up properly.'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix', 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.fixes.expects('authorizeIosFix').once();
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.fix());
case 3:
(0, _appiumTestSupport.verify)(mocks);
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('NodeBinaryCheck', (0, _appiumTestSupport.withMocks)({ NodeDetector: _libNodeDetector2['default'] }, function (mocks) {
var check = new _libIos.NodeBinaryCheck();
it('autofix', function () {
check.autofix.should.not.be.ok;
});
it('diagnose - success', 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.NodeDetector.expects('detect').once().returns(P.resolve('/a/b/c/d'));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: true,
message: 'The Node.js binary was found at: /a/b/c/d'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('diagnose - failure', 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.NodeDetector.expects('detect').once().returns(P.resolve(null));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(check.diagnose());
case 3:
context$3$0.t0 = {
ok: false,
message: 'The Node.js binary was NOT found!'
};
context$3$0.sent.should.deep.equal(context$3$0.t0);
(0, _appiumTestSupport.verify)(mocks);
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix', 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:
context$3$0.next = 2;
return _regeneratorRuntime.awrap(check.fix());
case 2:
context$3$0.sent.should.equal('Manually setup Node.js.');
case 3:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
});
//# sourceMappingURL=data:application/json;base64,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Ozs7Ozs7O0tBQzNELENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQyxDQUFDO0NBQ0wsQ0FBQyxDQUFDIiwiZmlsZSI6InRlc3QvaW9zLXNwZWNzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJhbnNwaWxlOm1vY2hhXG5cbmltcG9ydCB7IGZpeGVzLCBYY29kZUNoZWNrLCBYY29kZUNtZExpbmVUb29sc0NoZWNrLCBEZXZUb29sc1NlY3VyaXR5Q2hlY2ssXG4gIEF1dGhvcml6YXRpb25EYkNoZWNrLCBOb2RlQmluYXJ5Q2hlY2t9IGZyb20gJy4uL2xpYi9pb3MnO1xuaW1wb3J0IHsgZnMgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuLi9saWIvdXRpbHMnO1xuaW1wb3J0ICogYXMgdHAgZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCAqIGFzIHByb21wdGVyIGZyb20gJy4uL2xpYi9wcm9tcHQnO1xuaW1wb3J0IE5vZGVEZXRlY3RvciBmcm9tICcuLi9saWIvbm9kZS1kZXRlY3Rvcic7XG5pbXBvcnQgRml4U2tpcHBlZEVycm9yIGZyb20gJy4uL2xpYi9kb2N0b3InO1xuaW1wb3J0IGxvZyBmcm9tICcuLi9saWIvbG9nZ2VyJztcbmltcG9ydCBjaGFpIGZyb20gJ2NoYWknO1xuaW1wb3J0IGNoYWlBc1Byb21pc2VkIGZyb20gJ2NoYWktYXMtcHJvbWlzZWQnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgd2l0aE1vY2tzLCB2ZXJpZnksIHN0dWJMb2cgfSBmcm9tICdhcHBpdW0tdGVzdC1zdXBwb3J0JztcbmltcG9ydCB7IHN5c3RlbSB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcblxuY2hhaS5zaG91bGQoKTtcbmNoYWkudXNlKGNoYWlBc1Byb21pc2VkKTtcbmxldCBQID0gUHJvbWlzZTtcblxuZGVzY3JpYmUoJ2lvcycsICgpID0+IHtcbiAgZGVzY3JpYmUoJ1hjb2RlQ2hlY2snLCB3aXRoTW9ja3Moe3RwLCBmc30gLChtb2NrcykgPT4ge1xuICAgIGxldCBjaGVjayA9IG5ldyBYY29kZUNoZWNrKCk7XG4gICAgaXQoJ2F1dG9maXgnLCAoKSA9PiB7XG4gICAgICBjaGVjay5hdXRvZml4LnNob3VsZC5ub3QuYmUub2s7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gc3VjY2VzcycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwLmV4cGVjdHMoJ2V4ZWMnKS5vbmNlKCkucmV0dXJucyhcbiAgICAgICAgUC5yZXNvbHZlKHtzdGRvdXQ6ICcvYS9iL2MvZFxcbicsIHN0ZGVycjogJyd9KSk7XG4gICAgICBtb2Nrcy5mcy5leHBlY3RzKCdleGlzdHMnKS5vbmNlKCkucmV0dXJucyhQLnJlc29sdmUodHJ1ZSkpO1xuICAgICAgKGF3YWl0IGNoZWNrLmRpYWdub3NlKCkpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgb2s6IHRydWUsXG4gICAgICAgIG1lc3NhZ2U6ICdYY29kZSBpcyBpbnN0YWxsZWQgYXQ6IC9hL2IvYy9kJ1xuICAgICAgfSk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICAgIGl0KCdkaWFnbm9zZSAtIGZhaWx1cmUgLSB4Y29kZS1zZWxlY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy50cC5leHBlY3RzKCdleGVjJykub25jZSgpLnJldHVybnMoUC5yZWplY3QobmV3IEVycm9yKCdTb21ldGhpbmcgd3JvbmchJykpKTtcbiAgICAgIChhd2FpdCBjaGVjay5kaWFnbm9zZSgpKS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgbWVzc2FnZTogJ1hjb2RlIGlzIE5PVCBpbnN0YWxsZWQhJ1xuICAgICAgfSk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICAgIGl0KCdkaWFnbm9zZSAtIGZhaWx1cmUgLSBwYXRoIG5vdCBleGlzdHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy50cC5leHBlY3RzKCdleGVjJykub25jZSgpLnJldHVybnMoXG4gICAgICAgIFAucmVzb2x2ZSh7c3Rkb3V0OiAnL2EvYi9jL2RcXG4nLCBzdGRlcnI6ICcnfSkpO1xuICAgICAgbW9ja3MuZnMuZXhwZWN0cygnZXhpc3RzJykub25jZSgpLnJldHVybnMoUC5yZXNvbHZlKGZhbHNlKSk7XG4gICAgICAoYXdhaXQgY2hlY2suZGlhZ25vc2UoKSkuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICBvazogZmFsc2UsXG4gICAgICAgIG1lc3NhZ2U6ICdYY29kZSBjYW5ub3QgYmUgZm91bmQgYXQgXFwnL2EvYi9jL2RcXCchJ1xuICAgICAgfSk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICAgIGl0KCdmaXgnLCBhc3luYyAoKSA9PiB7XG4gICAgICAoYXdhaXQgY2hlY2suZml4KCkpLnNob3VsZC5lcXVhbCgnTWFudWFsbHkgaW5zdGFsbCBYY29kZS4nKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnWGNvZGVDbWRMaW5lVG9vbHNDaGVjaycsIHdpdGhNb2Nrcyh7dHAsIHV0aWxzLCBwcm9tcHRlciwgc3lzdGVtfSAsKG1vY2tzLCBTKSA9PiB7XG4gICAgbGV0IGNoZWNrID0gbmV3IFhjb2RlQ21kTGluZVRvb2xzQ2hlY2soKTtcbiAgICBpdCgnYXV0b2ZpeCcsICgpID0+IHtcbiAgICAgIGNoZWNrLmF1dG9maXguc2hvdWxkLmJlLm9rO1xuICAgIH0pO1xuICAgIGl0KCdkaWFnbm9zZSAtIHN1Y2Nlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5zeXN0ZW0uZXhwZWN0cygnbWFjT3N4VmVyc2lvbicpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSgnMTAuMTAnKSk7XG4gICAgICBtb2Nrcy50cC5leHBlY3RzKCdleGVjJykub25jZSgpLnJldHVybnMoXG4gICAgICAgIFAucmVzb2x2ZSh7c3Rkb3V0OiAnMTIzNCBpbnN0YWxsLXRpbWVcXG4nLCBzdGRlcnI6ICcnfSkpO1xuICAgICAgKGF3YWl0IGNoZWNrLmRpYWdub3NlKCkpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgb2s6IHRydWUsXG4gICAgICAgIG1lc3NhZ2U6ICdYY29kZSBDb21tYW5kIExpbmUgVG9vbHMgYXJlIGluc3RhbGxlZC4nXG4gICAgICB9KTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gZmFpbHVyZSAtIHBrZ3V0aWwgY3Jhc2gnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5zeXN0ZW0uZXhwZWN0cygnbWFjT3N4VmVyc2lvbicpLm9uY2UoKS5yZXR1cm5zKEIucmVzb2x2ZSgnMTAuMTAnKSk7XG4gICAgICBtb2Nrcy50cC5leHBlY3RzKCdleGVjJykub25jZSgpLnJldHVybnMoUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdTb21ldGhpbmcgd3JvbmchJykpKTtcbiAgICAgIChhd2FpdCBjaGVjay5kaWFnbm9zZSgpKS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgbWVzc2FnZTogJ1hjb2RlIENvbW1hbmQgTGluZSBUb29scyBhcmUgTk9UIGluc3RhbGxlZCEnXG4gICAgICB9KTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gZmFpbHVyZSAtIG5vIGluc3RhbGwgdGltZScsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnN5c3RlbS5leHBlY3RzKCdtYWNPc3hWZXJzaW9uJykub25jZSgpLnJldHVybnMoQi5yZXNvbHZlKCcxMC4xMCcpKTtcbiAgICAgIG1vY2tzLnRwLmV4cGVjdHMoJ2V4ZWMnKS5vbmNlKCkucmV0dXJucyhcbiAgICAgICAgUC5yZXNvbHZlKHtzdGRvdXQ6ICcxMjM0IGFiY2RcXG4nLCBzdGRlcnI6ICcnfSkpO1xuICAgICAgKGF3YWl0IGNoZWNrLmRpYWdub3NlKCkpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgb2s6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiAnWGNvZGUgQ29tbWFuZCBMaW5lIFRvb2xzIGFyZSBOT1QgaW5zdGFsbGVkISdcbiAgICAgIH0pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnZml4IC0geWVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IGxvZ1N0dWIgPSBzdHViTG9nKFMuc2FuZGJveCwgbG9nLCB7c3RyaXBDb2xvcnM6IHRydWV9KTtcbiAgICAgIG1vY2tzLnRwLmV4cGVjdHMoJ2V4ZWMnKS5vbmNlKCkucmV0dXJucyhcbiAgICAgICAgUC5yZXNvbHZlKHtzdGRvdXQ6ICcnLCBzdGRlcnI6ICcnfSkpO1xuICAgICAgbW9ja3MucHJvbXB0ZXIuZXhwZWN0cygnZml4SXQnKS5vbmNlKCkucmV0dXJucyhQLnJlc29sdmUoJ3llcycpKTtcbiAgICAgIGF3YWl0IGNoZWNrLmZpeCgpO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICAgIGxvZ1N0dWIub3V0cHV0LnNob3VsZC5lcXVhbChbXG4gICAgICAgICdpbmZvOiBUaGUgZm9sbG93aW5nIGNvbW1hbmQgbmVlZCBiZSBleGVjdXRlZDogeGNvZGUtc2VsZWN0IC0taW5zdGFsbCcsXG4gICAgICBdLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbiAgICBpdCgnZml4IC0gbm8nLCBhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgbG9nU3R1YiA9IHN0dWJMb2coUy5zYW5kYm94LCBsb2csIHtzdHJpcENvbG9yczogdHJ1ZX0pO1xuICAgICAgbW9ja3MudHAuZXhwZWN0cygnZXhlYycpLm5ldmVyKCk7XG4gICAgICBtb2Nrcy5wcm9tcHRlci5leHBlY3RzKCdmaXhJdCcpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSgnbm8nKSk7XG4gICAgICBhd2FpdCBjaGVjay5maXgoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKEZpeFNraXBwZWRFcnJvcik7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgbG9nU3R1Yi5vdXRwdXQuc2hvdWxkLmVxdWFsKFtcbiAgICAgICAgJ2luZm86IFRoZSBmb2xsb3dpbmcgY29tbWFuZCBuZWVkIGJlIGV4ZWN1dGVkOiB4Y29kZS1zZWxlY3QgLS1pbnN0YWxsJyxcbiAgICAgICAgJ2luZm86IFNraXBwaW5nIHlvdSB3aWxsIG5lZWQgdG8gaW5zdGFsbCBYY29kZSBtYW51YWxseS4nXG4gICAgICBdLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbiAgfSkpO1xuXG4gIGRlc2NyaWJlKCdhdXRob3JpemVJb3NGaXgnLCB3aXRoTW9ja3Moe3V0aWxzLCBwcm9tcHRlcn0gLChtb2NrcywgUykgPT4ge1xuICAgIGl0KCdmaXggLSB5ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgbG9nU3R1YiA9IHN0dWJMb2coUy5zYW5kYm94LCBsb2csIHtzdHJpcENvbG9yczogdHJ1ZX0pO1xuICAgICAgbW9ja3MudXRpbHMuZXhwZWN0cygnYXV0aG9yaXplJykub25jZSgpO1xuICAgICAgbW9ja3MucHJvbXB0ZXIuZXhwZWN0cygnZml4SXQnKS5vbmNlKCkucmV0dXJucyhQLnJlc29sdmUoJ3llcycpKTtcbiAgICAgIGF3YWl0IGZpeGVzLmF1dGhvcml6ZUlvc0ZpeCgpO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICAgIGxvZ1N0dWIub3V0cHV0LnNob3VsZC5lcXVhbChbXG4gICAgICAgICdpbmZvOiBUaGUgYXV0aG9yaXplIGlPUyBzY3JpcHQgbmVlZCB0byBiZSBydW4uJyxcbiAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuICAgIGl0KCdmaXggLSBubycsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2dTdHViID0gc3R1YkxvZyhTLnNhbmRib3gsIGxvZywge3N0cmlwQ29sb3JzOiB0cnVlfSk7XG4gICAgICBtb2Nrcy51dGlscy5leHBlY3RzKCdhdXRob3JpemUnKS5uZXZlcigpO1xuICAgICAgbW9ja3MucHJvbXB0ZXIuZXhwZWN0cygnZml4SXQnKS5vbmNlKCkucmV0dXJucyhQLnJlc29sdmUoJ25vJykpO1xuICAgICAgYXdhaXQgZml4ZXMuYXV0aG9yaXplSW9zRml4KCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChGaXhTa2lwcGVkRXJyb3IpO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICAgIGxvZ1N0dWIub3V0cHV0LnNob3VsZC5lcXVhbChbXG4gICAgICAgICdpbmZvOiBUaGUgYXV0aG9yaXplIGlPUyBzY3JpcHQgbmVlZCB0byBiZSBydW4uJyxcbiAgICAgICAgJ2luZm86IFNraXBwaW5nIHlvdSB3aWxsIG5lZWQgdG8gcnVuIHRoZSBhdXRob3JpemUgaU9TIG1hbnVhbGx5LidcbiAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuICB9KSk7XG4gIGRlc2NyaWJlKCdEZXZUb29sc1NlY3VyaXR5Q2hlY2snLCB3aXRoTW9ja3Moe2ZpeGVzLCB0cH0gLChtb2NrcykgPT4ge1xuICAgIGxldCBjaGVjayA9IG5ldyBEZXZUb29sc1NlY3VyaXR5Q2hlY2soKTtcbiAgICBpdCgnYXV0b2ZpeCcsICgpID0+IHtcbiAgICAgIGNoZWNrLmF1dG9maXguc2hvdWxkLmJlLm9rO1xuICAgIH0pO1xuICAgIGl0KCdkaWFnbm9zZSAtIHN1Y2Nlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy50cC5leHBlY3RzKCdleGVjJykub25jZSgpLnJldHVybnMoXG4gICAgICAgIFAucmVzb2x2ZSh7c3Rkb3V0OiAnMTIzNCBlbmFibGVkXFxuJywgc3RkZXJyOiAnJ30pKTtcbiAgICAgIChhd2FpdCBjaGVjay5kaWFnbm9zZSgpKS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIG9rOiB0cnVlLFxuICAgICAgICBtZXNzYWdlOiAnRGV2VG9vbHNTZWN1cml0eSBpcyBlbmFibGVkLidcbiAgICAgIH0pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnZGlhZ25vc2UgLSBmYWlsdXJlIC0gRGV2VG9vbHNTZWN1cml0eSBjcmFzaCcsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwLmV4cGVjdHMoJ2V4ZWMnKS5vbmNlKCkucmV0dXJucyhQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ1NvbWV0aGluZyB3cm9uZyEnKSkpO1xuICAgICAgKGF3YWl0IGNoZWNrLmRpYWdub3NlKCkpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgb2s6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiAnRGV2VG9vbHNTZWN1cml0eSBpcyBOT1QgZW5hYmxlZCEnXG4gICAgICB9KTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gZmFpbHVyZSAtIG5vdCBlbmFibGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MudHAuZXhwZWN0cygnZXhlYycpLm9uY2UoKS5yZXR1cm5zKFxuICAgICAgICBQLnJlc29sdmUoe3N0ZG91dDogJzEyMzQgYWJjZFxcbicsIHN0ZGVycjogJyd9KSk7XG4gICAgICAoYXdhaXQgY2hlY2suZGlhZ25vc2UoKSkuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICBvazogZmFsc2UsXG4gICAgICAgIG1lc3NhZ2U6ICdEZXZUb29sc1NlY3VyaXR5IGlzIE5PVCBlbmFibGVkISdcbiAgICAgIH0pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnZml4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuZml4ZXMuZXhwZWN0cygnYXV0aG9yaXplSW9zRml4Jykub25jZSgpO1xuICAgICAgYXdhaXQgY2hlY2suZml4KCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICB9KSk7XG4gIGRlc2NyaWJlKCdBdXRob3JpemF0aW9uRGJDaGVjaycsIHdpdGhNb2Nrcyh7Zml4ZXMsIHRwLCBmcywgdXRpbHMsIHN5c3RlbX0gLChtb2NrcykgPT4ge1xuICAgIGxldCBjaGVjayA9IG5ldyBBdXRob3JpemF0aW9uRGJDaGVjaygpO1xuICAgIGl0KCdhdXRvZml4JywgKCkgPT4ge1xuICAgICAgY2hlY2suYXV0b2ZpeC5zaG91bGQuYmUub2s7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gc3VjY2VzcyAtIDEwLjEwJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MudHAuZXhwZWN0cygnZXhlYycpLm9uY2UoKS5yZXR1cm5zKFxuICAgICAgICBQLnJlc29sdmUoe3N0ZG91dDogJzEyMzQgaXMtZGV2ZWxvcGVyXFxuJywgc3RkZXJyOiAnJ30pKTtcbiAgICAgIChhd2FpdCBjaGVjay5kaWFnbm9zZSgpKS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIG9rOiB0cnVlLFxuICAgICAgICBtZXNzYWdlOiAnVGhlIEF1dGhvcml6YXRpb24gREIgaXMgc2V0IHVwIHByb3Blcmx5LidcbiAgICAgIH0pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnZGlhZ25vc2UgLSBzdWNjZXNzIC0gMTAuOCcsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwLmV4cGVjdHMoJ2V4ZWMnKS5vbmNlKCkucmV0dXJucyhQLnJlamVjdChuZXcgRXJyb3IoJ09oIE5vIScpKSk7XG4gICAgICBtb2Nrcy5zeXN0ZW0uZXhwZWN0cygnbWFjT3N4VmVyc2lvbicpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSgnMTAuOCcpKTtcbiAgICAgIG1vY2tzLmZzLmV4cGVjdHMoJ3JlYWRGaWxlJykub25jZSgpLnJldHVybnMoUC5yZXNvbHZlKFxuICAgICAgICAnPGtleT5zeXN0ZW0ucHJpdmlsZWdlLnRhc2twb3J0PC9rZXk+IFxcbiA8ZGljdD5cXG4gPGtleT5hbGxvdy1yb290PC9rZXk+XFxuIDx0cnVlLz4nKSk7XG4gICAgICAoYXdhaXQgY2hlY2suZGlhZ25vc2UoKSkuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgbWVzc2FnZTogJ1RoZSBBdXRob3JpemF0aW9uIERCIGlzIHNldCB1cCBwcm9wZXJseS4nXG4gICAgICB9KTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gZmFpbHVyZSAtIDEwLjEwIC0gc2VjdXJpdHknLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy50cC5leHBlY3RzKCdleGVjJykub25jZSgpLnJldHVybnMoUC5yZWplY3QobmV3IEVycm9yKCdPaCBObyEnKSkpO1xuICAgICAgbW9ja3Muc3lzdGVtLmV4cGVjdHMoJ21hY09zeFZlcnNpb24nKS5vbmNlKCkucmV0dXJucyhQLnJlc29sdmUoJzEwLjEwJykpO1xuICAgICAgKGF3YWl0IGNoZWNrLmRpYWdub3NlKCkpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgb2s6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiAnVGhlIEF1dGhvcml6YXRpb24gREIgaXMgTk9UIHNldCB1cCBwcm9wZXJseS4nXG4gICAgICB9KTtcbiAgICAgIHZlcmlmeShtb2Nrcyk7XG4gICAgfSk7XG4gICAgaXQoJ2RpYWdub3NlIC0gZmFpbHVyZSAtIC9ldGMvYXV0aG9yaXphdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLnRwLmV4cGVjdHMoJ2V4ZWMnKS5vbmNlKCkucmV0dXJucyhQLnJlamVjdChuZXcgRXJyb3IoJ09oIE5vIScpKSk7XG4gICAgICBtb2Nrcy5zeXN0ZW0uZXhwZWN0cygnbWFjT3N4VmVyc2lvbicpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSgnMTAuOCcpKTtcbiAgICAgIG1vY2tzLmZzLmV4cGVjdHMoJ3JlYWRGaWxlJykub25jZSgpLnJldHVybnMoUC5yZXNvbHZlKCcnKSk7XG4gICAgICAoYXdhaXQgY2hlY2suZGlhZ25vc2UoKSkuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICBvazogZmFsc2UsXG4gICAgICAgIG1lc3NhZ2U6ICdUaGUgQXV0aG9yaXphdGlvbiBEQiBpcyBOT1Qgc2V0IHVwIHByb3Blcmx5LidcbiAgICAgIH0pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnZml4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuZml4ZXMuZXhwZWN0cygnYXV0aG9yaXplSW9zRml4Jykub25jZSgpO1xuICAgICAgYXdhaXQgY2hlY2suZml4KCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICB9KSk7XG4gIGRlc2NyaWJlKCdOb2RlQmluYXJ5Q2hlY2snLCB3aXRoTW9ja3Moe05vZGVEZXRlY3Rvcn0gLChtb2NrcykgPT4ge1xuICAgIGxldCBjaGVjayA9IG5ldyBOb2RlQmluYXJ5Q2hlY2soKTtcbiAgICBpdCgnYXV0b2ZpeCcsICgpID0+IHtcbiAgICAgIGNoZWNrLmF1dG9maXguc2hvdWxkLm5vdC5iZS5vaztcbiAgICB9KTtcbiAgICBpdCgnZGlhZ25vc2UgLSBzdWNjZXNzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuTm9kZURldGVjdG9yLmV4cGVjdHMoJ2RldGVjdCcpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSgnL2EvYi9jL2QnKSk7XG4gICAgICAoYXdhaXQgY2hlY2suZGlhZ25vc2UoKSkuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgbWVzc2FnZTogJ1RoZSBOb2RlLmpzIGJpbmFyeSB3YXMgZm91bmQgYXQ6IC9hL2IvYy9kJ1xuICAgICAgfSk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICAgIGl0KCdkaWFnbm9zZSAtIGZhaWx1cmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5Ob2RlRGV0ZWN0b3IuZXhwZWN0cygnZGV0ZWN0Jykub25jZSgpLnJldHVybnMoUC5yZXNvbHZlKG51bGwpKTtcbiAgICAgIChhd2FpdCBjaGVjay5kaWFnbm9zZSgpKS5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgbWVzc2FnZTogJ1RoZSBOb2RlLmpzIGJpbmFyeSB3YXMgTk9UIGZvdW5kISdcbiAgICAgIH0pO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICB9KTtcbiAgICBpdCgnZml4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgKGF3YWl0IGNoZWNrLmZpeCgpKS5zaG91bGQuZXF1YWwoJ01hbnVhbGx5IHNldHVwIE5vZGUuanMuJyk7XG4gICAgfSk7XG4gIH0pKTtcbn0pO1xuIl19