appium-adb
Version:
385 lines (326 loc) • 36.3 kB
JavaScript
;
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
var _this = this;
var _chai = require('chai');
var _chai2 = _interopRequireDefault(_chai);
var _chaiAsPromised = require('chai-as-promised');
var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised);
var _ = require('../..');
var _2 = _interopRequireDefault(_);
var _appiumTestSupport = require('appium-test-support');
_chai2['default'].use(_chaiAsPromised2['default']);
var should = _chai2['default'].should(),
pkg = 'com.example.android.contactmanager',
uri = 'content://contacts/people/1',
act = '.ContactManager',
startAppOptions = { stopApp: true, action: 'action', category: 'cat',
flags: 'flags', pkg: 'pkg', activity: 'act',
optionalIntentArguments: '-x options' },
cmd = ['am', 'start', '-n', 'pkg/act', '-S', '-a', 'action', '-c', 'cat', '-f', 'flags', '-x options'];
describe('Apk-utils', function () {
var adb = new _2['default']();
describe('isAppInstalled', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should parse correctly and return true', function callee$2$0() {
var pkg;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
pkg = 'dummy.package';
mocks.adb.expects('getApiLevel').once().withExactArgs().returns("17");
mocks.adb.expects('shell').once().withExactArgs(['pm', 'list', 'packages', '-3', pkg]).returns('package:' + pkg);
context$3$0.next = 5;
return _regeneratorRuntime.awrap(adb.isAppInstalled(pkg));
case 5:
context$3$0.sent.should.be['true'];
mocks.adb.verify();
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should parse correctly and return false', function callee$2$0() {
var pkg;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
pkg = 'dummy.package';
mocks.adb.expects('getApiLevel').once().withExactArgs().returns("17");
mocks.adb.expects('shell').once().withExactArgs(['pm', 'list', 'packages', '-3', pkg]).returns("");
context$3$0.next = 5;
return _regeneratorRuntime.awrap(adb.isAppInstalled(pkg));
case 5:
context$3$0.sent.should.be['false'];
mocks.adb.verify();
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('getFocusedPackageAndActivity', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should parse correctly and return package and activity', function callee$2$0() {
var _ref, appPackage, appActivity;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.adb.expects('shell').once().withExactArgs(['dumpsys', 'window', 'windows']).returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + ('ActivityRecord{2 u ' + pkg + '/' + act + ' t181}}}'));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.getFocusedPackageAndActivity());
case 3:
_ref = context$3$0.sent;
appPackage = _ref.appPackage;
appActivity = _ref.appActivity;
appPackage.should.equal(pkg);
appActivity.should.equal(act);
mocks.adb.verify();
case 9:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should parse correctly and return null', function callee$2$0() {
var _ref2, appPackage, appActivity;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.adb.expects('shell').once().withExactArgs(['dumpsys', 'window', 'windows']).returns('mFocusedApp=null');
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.getFocusedPackageAndActivity());
case 3:
_ref2 = context$3$0.sent;
appPackage = _ref2.appPackage;
appActivity = _ref2.appActivity;
should.not.exist(appPackage);
should.not.exist(appActivity);
mocks.adb.verify();
case 9:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('waitForActivityOrNot', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call shell once and should return', 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.adb.expects('shell').once().withExactArgs(['dumpsys', 'window', 'windows']).returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + ('ActivityRecord{2 u ' + pkg + '/' + act + ' t181}}}'));
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.waitForActivityOrNot(pkg, act, false));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should call shell multiple times and return', 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.adb.expects('shell').onCall(0).returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + 'ActivityRecord{2c7c4318 u0 foo/bar t181}}}');
mocks.adb.expects('shell').returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + 'ActivityRecord{2c7c4318 u0 com.example.android.contactmanager/.ContactManager t181}}}');
context$3$0.next = 4;
return _regeneratorRuntime.awrap(adb.waitForActivityOrNot(pkg, act, false));
case 4:
mocks.adb.verify();
case 5:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should call shell once return for not', 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.adb.expects('shell').once().withExactArgs(['dumpsys', 'window', 'windows']).returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + 'ActivityRecord{c 0 foo/bar t181}}}');
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.waitForActivityOrNot(pkg, act, true));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should call shell multiple times and return for not', 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.adb.expects('shell').onCall(0).returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + ('ActivityRecord{2 u ' + pkg + '/' + act + ' t181}}}'));
mocks.adb.expects('shell').returns('mFocusedApp=AppWindowToken{38600b56 token=Token{9ea1171 ' + 'ActivityRecord{2c7c4318 u0 foo/bar t181}}}');
context$3$0.next = 4;
return _regeneratorRuntime.awrap(adb.waitForActivityOrNot(pkg, act, true));
case 4:
mocks.adb.verify();
case 5:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('waitForActivity', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call waitForActivityOrNot with correct arguments', 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.adb.expects('waitForActivityOrNot').once().withExactArgs(pkg, act, false, 20000).returns('');
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.waitForActivity(pkg, act));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('waitForNotActivity', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call waitForActivityOrNot with correct arguments', 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.adb.expects('waitForActivityOrNot').once().withExactArgs(pkg, act, true, 20000).returns('');
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.waitForNotActivity(pkg, act));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('uninstallApk', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call forceStop and adbExec with correct arguments', 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.adb.expects('forceStop').once().withExactArgs(pkg).returns('');
mocks.adb.expects('adbExec').once().withExactArgs(['uninstall', pkg], { timeout: 20000 }).returns('Success');
context$3$0.next = 4;
return _regeneratorRuntime.awrap(adb.uninstallApk(pkg));
case 4:
context$3$0.sent.should.be['true'];
mocks.adb.verify();
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('installFromDevicePath', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call forceStop and adbExec with correct arguments', 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.adb.expects('shell').once().withExactArgs(['pm', 'install', '-r', 'foo'], {}).returns('');
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.installFromDevicePath('foo'));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('install', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call forceStop and adbExec with correct arguments', 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.adb.expects('adbExec').once().withExactArgs(['install', '-r', 'foo'], { timeout: 60000 }).returns('');
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.install('foo'));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('startUri', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should fail if uri or pkg are not provided', 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(adb.startUri().should.eventually.be.rejectedWith(/arguments are required/));
case 2:
context$3$0.next = 4;
return _regeneratorRuntime.awrap(adb.startUri('foo').should.eventually.be.rejectedWith(/arguments are required/));
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should build a call to a VIEW intent with the uri', 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.adb.expects('shell').once().withExactArgs(['am', 'start', '-W', '-a', 'android.intent.action.VIEW', '-d', uri, pkg]);
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.startUri(uri, pkg));
case 3:
mocks.adb.verify();
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('startApp', (0, _appiumTestSupport.withMocks)({ adb: adb }, function (mocks) {
it('should call getApiLevel and shell with correct arguments', 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.adb.expects('getApiLevel').once().withExactArgs().returns('17');
mocks.adb.expects('shell').once().withExactArgs(cmd).returns('');
context$3$0.next = 4;
return _regeneratorRuntime.awrap(adb.startApp(startAppOptions));
case 4:
mocks.adb.verify();
case 5:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should call getApiLevel and shell with correct arguments', 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.adb.expects('getApiLevel').twice().returns('17');
mocks.adb.expects('shell').onCall(0).returns('Error: Activity class foo does not exist');
mocks.adb.expects('shell').returns('');
context$3$0.next = 5;
return _regeneratorRuntime.awrap(adb.startApp(startAppOptions));
case 5:
mocks.adb.verify();
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvdW5pdC9hcGstdXRpbHMtc3BlY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7b0JBQWlCLE1BQU07Ozs7OEJBQ0ksa0JBQWtCOzs7O2dCQUM3QixPQUFPOzs7O2lDQUNHLHFCQUFxQjs7QUFHL0Msa0JBQUssR0FBRyw2QkFBZ0IsQ0FBQztBQUN6QixJQUFNLE1BQU0sR0FBRyxrQkFBSyxNQUFNLEVBQUU7SUFDdEIsR0FBRyxHQUFHLG9DQUFvQztJQUMxQyxHQUFHLEdBQUcsNkJBQTZCO0lBQ25DLEdBQUcsR0FBRyxpQkFBaUI7SUFDdkIsZUFBZSxHQUFHLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLO0FBQ2hELE9BQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSztBQUMzQyx5QkFBdUIsRUFBRSxZQUFZLEVBQUM7SUFDekQsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQ2pFLElBQUksRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7O0FBRTFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsWUFBTTtBQUMxQixNQUFJLEdBQUcsR0FBRyxtQkFBUyxDQUFDO0FBQ3BCLFVBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxrQ0FBVSxFQUFDLEdBQUcsRUFBSCxHQUFHLEVBQUMsRUFBRSxVQUFDLEtBQUssRUFBSztBQUNyRCxNQUFFLENBQUMsd0NBQXdDLEVBQUU7VUFDckMsR0FBRzs7OztBQUFILGVBQUcsR0FBRyxlQUFlOztBQUMzQixpQkFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQzdCLElBQUksRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUN0QixPQUFPLENBQUMsSUFBSSxD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QztBQUNqQixpQkFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQ3ZCLElBQUksRUFBRSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FDekIsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDOzs2Q0FDUixHQUFHLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQzs7O0FBQ3BDLGlCQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDOzs7Ozs7O0tBQ3BCLENBQUMsQ0FBQztBQUNILE1BQUUsQ0FBQywwREFBMEQsRUFBRTs7OztBQUM3RCxpQkFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQzdCLEtBQUssRUFBRSxDQUNQLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNqQixpQkFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FDVCxPQUFPLENBQUMsMENBQTBDLENBQUMsQ0FBQztBQUN2RCxpQkFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQ3ZCLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQzs7NkNBQ1IsR0FBRyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7OztBQUNwQyxpQkFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQzs7Ozs7OztLQUNwQixDQUFDLENBQUM7R0FDSixDQUFDLENBQUMsQ0FBQztDQUNMLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0L3VuaXQvYXBrLXV0aWxzLXNwZWNzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgQURCIGZyb20gJy4uLy4uJztcbmltcG9ydCB7IHdpdGhNb2NrcyB9IGZyb20gJ2FwcGl1bS10ZXN0LXN1cHBvcnQnO1xuXG5cbmNoYWkudXNlKGNoYWlBc1Byb21pc2VkKTtcbmNvbnN0IHNob3VsZCA9IGNoYWkuc2hvdWxkKCksXG4gICAgICBwa2cgPSAnY29tLmV4YW1wbGUuYW5kcm9pZC5jb250YWN0bWFuYWdlcicsXG4gICAgICB1cmkgPSAnY29udGVudDovL2NvbnRhY3RzL3Blb3BsZS8xJyxcbiAgICAgIGFjdCA9ICcuQ29udGFjdE1hbmFnZXInLFxuICAgICAgc3RhcnRBcHBPcHRpb25zID0ge3N0b3BBcHA6IHRydWUsIGFjdGlvbjogJ2FjdGlvbicsIGNhdGVnb3J5OiAnY2F0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICBmbGFnczogJ2ZsYWdzJywgcGtnOiAncGtnJywgYWN0aXZpdHk6ICdhY3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50ZW50QXJndW1lbnRzOiAnLXggb3B0aW9ucyd9LFxuICAgICAgY21kID0gWydhbScsICdzdGFydCcsICctbicsICdwa2cvYWN0JywgJy1TJywgJy1hJywgJ2FjdGlvbicsICctYycsICdjYXQnLFxuICAgICAgICAgICAgICctZicsICdmbGFncycsICcteCBvcHRpb25zJ107XG5cbmRlc2NyaWJlKCdBcGstdXRpbHMnLCAoKSA9PiB7XG4gIGxldCBhZGIgPSBuZXcgQURCKCk7XG4gIGRlc2NyaWJlKCdpc0FwcEluc3RhbGxlZCcsIHdpdGhNb2Nrcyh7YWRifSwgKG1vY2tzKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBjb3JyZWN0bHkgYW5kIHJldHVybiB0cnVlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGtnID0gJ2R1bW15LnBhY2thZ2UnO1xuICAgICAgbW9ja3MuYWRiLmV4cGVjdHMoJ2dldEFwaUxldmVsJylcbiAgICAgICAgLm9uY2UoKS53aXRoRXhhY3RBcmdzKClcbiAgICAgICAgLnJldHVybnMoXCIxN1wiKTtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdzaGVsbCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhbJ3BtJywgJ2xpc3QnLCAncGFja2FnZXMnLCAnLTMnLCBwa2ddKVxuICAgICAgICAucmV0dXJucyhgcGFja2FnZToke3BrZ31gKTtcbiAgICAgIChhd2FpdCBhZGIuaXNBcHBJbnN0YWxsZWQocGtnKSkuc2hvdWxkLmJlLnRydWU7XG4gICAgICBtb2Nrcy5hZGIudmVyaWZ5KCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBjb3JyZWN0bHkgYW5kIHJldHVybiBmYWxzZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBrZyA9ICdkdW1teS5wYWNrYWdlJztcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdnZXRBcGlMZXZlbCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncygpXG4gICAgICAgIC5yZXR1cm5zKFwiMTdcIik7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoWydwbScsICdsaXN0JywgJ3BhY2thZ2VzJywgJy0zJywgcGtnXSlcbiAgICAgICAgLnJldHVybnMoXCJcIik7XG4gICAgICAoYXdhaXQgYWRiLmlzQXBwSW5zdGFsbGVkKHBrZykpLnNob3VsZC5iZS5mYWxzZTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnZ2V0Rm9jdXNlZFBhY2thZ2VBbmRBY3Rpdml0eScsIHdpdGhNb2Nrcyh7YWRifSwgKG1vY2tzKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBjb3JyZWN0bHkgYW5kIHJldHVybiBwYWNrYWdlIGFuZCBhY3Rpdml0eScsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdzaGVsbCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhbJ2R1bXBzeXMnLCAnd2luZG93JywgJ3dpbmRvd3MnXSlcbiAgICAgICAgLnJldHVybnMoYG1Gb2N1c2VkQXBwPUFwcFdpbmRvd1Rva2VuezM4NjAwYjU2IHRva2VuPVRva2VuezllYTExNzEgYCArXG4gICAgICAgICAgICAgICAgIGBBY3Rpdml0eVJlY29yZHsyIHUgJHtwa2d9LyR7YWN0fSB0MTgxfX19YCk7XG5cbiAgICAgIGxldCB7YXBwUGFja2FnZSwgYXBwQWN0aXZpdHl9ID0gYXdhaXQgYWRiLmdldEZvY3VzZWRQYWNrYWdlQW5kQWN0aXZpdHkoKTtcbiAgICAgIGFwcFBhY2thZ2Uuc2hvdWxkLmVxdWFsKHBrZyk7XG4gICAgICBhcHBBY3Rpdml0eS5zaG91bGQuZXF1YWwoYWN0KTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHBhcnNlIGNvcnJlY3RseSBhbmQgcmV0dXJuIG51bGwnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoWydkdW1wc3lzJywgJ3dpbmRvdycsICd3aW5kb3dzJ10pXG4gICAgICAgIC5yZXR1cm5zKCdtRm9jdXNlZEFwcD1udWxsJyk7XG4gICAgICBsZXQge2FwcFBhY2thZ2UsIGFwcEFjdGl2aXR5fSA9IGF3YWl0IGFkYi5nZXRGb2N1c2VkUGFja2FnZUFuZEFjdGl2aXR5KCk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KGFwcFBhY2thZ2UpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChhcHBBY3Rpdml0eSk7XG4gICAgICBtb2Nrcy5hZGIudmVyaWZ5KCk7XG4gICAgfSk7XG4gIH0pKTtcbiAgZGVzY3JpYmUoJ3dhaXRGb3JBY3Rpdml0eU9yTm90Jywgd2l0aE1vY2tzKHthZGJ9LCAobW9ja3MpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgc2hlbGwgb25jZSBhbmQgc2hvdWxkIHJldHVybicsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdzaGVsbCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhbJ2R1bXBzeXMnLCAnd2luZG93JywgJ3dpbmRvd3MnXSlcbiAgICAgICAgLnJldHVybnMoYG1Gb2N1c2VkQXBwPUFwcFdpbmRvd1Rva2VuezM4NjAwYjU2IHRva2VuPVRva2VuezllYTExNzEgYCArXG4gICAgICAgICAgICAgICAgIGBBY3Rpdml0eVJlY29yZHsyIHUgJHtwa2d9LyR7YWN0fSB0MTgxfX19YCk7XG5cbiAgICAgIGF3YWl0IGFkYi53YWl0Rm9yQWN0aXZpdHlPck5vdChwa2csIGFjdCwgZmFsc2UpO1xuICAgICAgbW9ja3MuYWRiLnZlcmlmeSgpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgY2FsbCBzaGVsbCBtdWx0aXBsZSB0aW1lcyBhbmQgcmV0dXJuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuYWRiLmV4cGVjdHMoJ3NoZWxsJykub25DYWxsKDApXG4gICAgICAgIC5yZXR1cm5zKCdtRm9jdXNlZEFwcD1BcHBXaW5kb3dUb2tlbnszODYwMGI1NiB0b2tlbj1Ub2tlbns5ZWExMTcxICcgK1xuICAgICAgICAgICAgICAgICAnQWN0aXZpdHlSZWNvcmR7MmM3YzQzMTggdTAgZm9vL2JhciB0MTgxfX19Jyk7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAucmV0dXJucygnbUZvY3VzZWRBcHA9QXBwV2luZG93VG9rZW57Mzg2MDBiNTYgdG9rZW49VG9rZW57OWVhMTE3MSAnICtcbiAgICAgICAgICAgICAgICAgJ0FjdGl2aXR5UmVjb3JkezJjN2M0MzE4IHUwIGNvbS5leGFtcGxlLmFuZHJvaWQuY29udGFjdG1hbmFnZXIvLkNvbnRhY3RNYW5hZ2VyIHQxODF9fX0nKTtcblxuICAgICAgYXdhaXQgYWRiLndhaXRGb3JBY3Rpdml0eU9yTm90KHBrZywgYWN0LCBmYWxzZSk7XG4gICAgICBtb2Nrcy5hZGIudmVyaWZ5KCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIHNoZWxsIG9uY2UgcmV0dXJuIGZvciBub3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoWydkdW1wc3lzJywgJ3dpbmRvdycsICd3aW5kb3dzJ10pXG4gICAgICAgIC5yZXR1cm5zKCdtRm9jdXNlZEFwcD1BcHBXaW5kb3dUb2tlbnszODYwMGI1NiB0b2tlbj1Ub2tlbns5ZWExMTcxICcgK1xuICAgICAgICAgICAgICAgICAnQWN0aXZpdHlSZWNvcmR7YyAwIGZvby9iYXIgdDE4MX19fScpO1xuXG4gICAgICBhd2FpdCBhZGIud2FpdEZvckFjdGl2aXR5T3JOb3QocGtnLCBhY3QsIHRydWUpO1xuICAgICAgbW9ja3MuYWRiLnZlcmlmeSgpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgY2FsbCBzaGVsbCBtdWx0aXBsZSB0aW1lcyBhbmQgcmV0dXJuIGZvciBub3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKS5vbkNhbGwoMClcbiAgICAgICAgLnJldHVybnMoYG1Gb2N1c2VkQXBwPUFwcFdpbmRvd1Rva2VuezM4NjAwYjU2IHRva2VuPVRva2VuezllYTExNzEgYCArXG4gICAgICAgICAgICAgICAgIGBBY3Rpdml0eVJlY29yZHsyIHUgJHtwa2d9LyR7YWN0fSB0MTgxfX19YCk7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAucmV0dXJucygnbUZvY3VzZWRBcHA9QXBwV2luZG93VG9rZW57Mzg2MDBiNTYgdG9rZW49VG9rZW57OWVhMTE3MSAnICtcbiAgICAgICAgICAgICAgICAgJ0FjdGl2aXR5UmVjb3JkezJjN2M0MzE4IHUwIGZvby9iYXIgdDE4MX19fScpO1xuICAgICAgYXdhaXQgYWRiLndhaXRGb3JBY3Rpdml0eU9yTm90KHBrZywgYWN0LCB0cnVlKTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnd2FpdEZvckFjdGl2aXR5Jywgd2l0aE1vY2tzKHthZGJ9LCAobW9ja3MpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgd2FpdEZvckFjdGl2aXR5T3JOb3Qgd2l0aCBjb3JyZWN0IGFyZ3VtZW50cycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCd3YWl0Rm9yQWN0aXZpdHlPck5vdCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhwa2csIGFjdCwgZmFsc2UsIDIwMDAwKVxuICAgICAgICAucmV0dXJucygnJyk7XG4gICAgICBhd2FpdCBhZGIud2FpdEZvckFjdGl2aXR5KHBrZywgYWN0KTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnd2FpdEZvck5vdEFjdGl2aXR5Jywgd2l0aE1vY2tzKHthZGJ9LCAobW9ja3MpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgd2FpdEZvckFjdGl2aXR5T3JOb3Qgd2l0aCBjb3JyZWN0IGFyZ3VtZW50cycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCd3YWl0Rm9yQWN0aXZpdHlPck5vdCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhwa2csIGFjdCwgdHJ1ZSwgMjAwMDApXG4gICAgICAgIC5yZXR1cm5zKCcnKTtcbiAgICAgIGF3YWl0IGFkYi53YWl0Rm9yTm90QWN0aXZpdHkocGtnLCBhY3QpO1xuICAgICAgbW9ja3MuYWRiLnZlcmlmeSgpO1xuICAgIH0pO1xuICB9KSk7XG4gIGRlc2NyaWJlKCd1bmluc3RhbGxBcGsnLCB3aXRoTW9ja3Moe2FkYn0sIChtb2NrcykgPT4ge1xuICAgIGl0KCdzaG91bGQgY2FsbCBmb3JjZVN0b3AgYW5kIGFkYkV4ZWMgd2l0aCBjb3JyZWN0IGFyZ3VtZW50cycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdmb3JjZVN0b3AnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MocGtnKVxuICAgICAgICAucmV0dXJucygnJyk7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnYWRiRXhlYycpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhbJ3VuaW5zdGFsbCcsIHBrZ10sIHt0aW1lb3V0OiAyMDAwMH0pXG4gICAgICAgIC5yZXR1cm5zKCdTdWNjZXNzJyk7XG4gICAgICAoYXdhaXQgYWRiLnVuaW5zdGFsbEFwayhwa2cpKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnaW5zdGFsbEZyb21EZXZpY2VQYXRoJywgd2l0aE1vY2tzKHthZGJ9LCAobW9ja3MpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZm9yY2VTdG9wIGFuZCBhZGJFeGVjIHdpdGggY29ycmVjdCBhcmd1bWVudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoWydwbScsICdpbnN0YWxsJywgJy1yJywgJ2ZvbyddLCB7fSlcbiAgICAgICAgLnJldHVybnMoJycpO1xuICAgICAgKGF3YWl0IGFkYi5pbnN0YWxsRnJvbURldmljZVBhdGgoJ2ZvbycpKTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnaW5zdGFsbCcsIHdpdGhNb2Nrcyh7YWRifSwgKG1vY2tzKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGZvcmNlU3RvcCBhbmQgYWRiRXhlYyB3aXRoIGNvcnJlY3QgYXJndW1lbnRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuYWRiLmV4cGVjdHMoJ2FkYkV4ZWMnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoWydpbnN0YWxsJywgJy1yJywgJ2ZvbyddLCB7dGltZW91dDogNjAwMDB9KVxuICAgICAgICAucmV0dXJucygnJyk7XG4gICAgICAoYXdhaXQgYWRiLmluc3RhbGwoJ2ZvbycpKTtcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZSgnc3RhcnRVcmknLCB3aXRoTW9ja3Moe2FkYn0sIChtb2NrcykgPT4ge1xuICAgIGl0KCdzaG91bGQgZmFpbCBpZiB1cmkgb3IgcGtnIGFyZSBub3QgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBhZGIuc3RhcnRVcmkoKS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoL2FyZ3VtZW50cyBhcmUgcmVxdWlyZWQvKTtcbiAgICAgIGF3YWl0IGFkYi5zdGFydFVyaSgnZm9vJykuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKC9hcmd1bWVudHMgYXJlIHJlcXVpcmVkLyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIGNhbGwgdG8gYSBWSUVXIGludGVudCB3aXRoIHRoZSB1cmknLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoWydhbScsICdzdGFydCcsICctVycsICctYScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FuZHJvaWQuaW50ZW50LmFjdGlvbi5WSUVXJywgJy1kJywgdXJpLCBwa2ddKTtcbiAgICAgIGF3YWl0IGFkYi5zdGFydFVyaSh1cmksIHBrZyk7XG4gICAgICBtb2Nrcy5hZGIudmVyaWZ5KCk7XG4gICAgfSk7XG4gIH0pKTtcbiAgZGVzY3JpYmUoJ3N0YXJ0QXBwJywgd2l0aE1vY2tzKHthZGJ9LCAobW9ja3MpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZ2V0QXBpTGV2ZWwgYW5kIHNoZWxsIHdpdGggY29ycmVjdCBhcmd1bWVudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnZ2V0QXBpTGV2ZWwnKVxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoKVxuICAgICAgICAucmV0dXJucygnMTcnKTtcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdzaGVsbCcpXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhjbWQpXG4gICAgICAgIC5yZXR1cm5zKCcnKTtcbiAgICAgIChhd2FpdCBhZGIuc3RhcnRBcHAoc3RhcnRBcHBPcHRpb25zKSk7XG4gICAgICBtb2Nrcy5hZGIudmVyaWZ5KCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdldEFwaUxldmVsIGFuZCBzaGVsbCB3aXRoIGNvcnJlY3QgYXJndW1lbnRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuYWRiLmV4cGVjdHMoJ2dldEFwaUxldmVsJylcbiAgICAgICAgLnR3aWNlKClcbiAgICAgICAgLnJldHVybnMoJzE3Jyk7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAub25DYWxsKDApXG4gICAgICAgIC5yZXR1cm5zKCdFcnJvcjogQWN0aXZpdHkgY2xhc3MgZm9vIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnc2hlbGwnKVxuICAgICAgICAucmV0dXJucygnJyk7XG4gICAgICAoYXdhaXQgYWRiLnN0YXJ0QXBwKHN0YXJ0QXBwT3B0aW9ucykpO1xuICAgICAgbW9ja3MuYWRiLnZlcmlmeSgpO1xuICAgIH0pO1xuICB9KSk7XG59KTtcbiJdfQ==