appium-ios-simulator
Version:
iOS Simulator interface for Appium.
815 lines (641 loc) • 52.9 kB
JavaScript
require('source-map-support').install();
'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'];
var _this = this;
var _chai = require('chai');
var _chai2 = _interopRequireDefault(_chai);
var _chaiAsPromised = require('chai-as-promised');
var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised);
var _libSettings = require('../../lib/settings');
var _libSimulatorXcode6 = require('../../lib/simulator-xcode-6');
var _libSimulatorXcode62 = _interopRequireDefault(_libSimulatorXcode6);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _appiumSupport = require('appium-support');
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
var _asyncbox = require('asyncbox');
var SIM_DIRECTORY = _path2['default'].resolve('test/assets/');
_chai2['default'].should();
var expect = _chai2['default'].expect;
_chai2['default'].use(_chaiAsPromised2['default']);
describe('settings', function () {
var sim = undefined;
before(function () {
// create a simulator object that returns our fixture directory
sim = new _libSimulatorXcode62['default']();
_sinon2['default'].stub(sim, 'getDir').returns(SIM_DIRECTORY);
});
describe('general plist handling', function () {
var plist = _path2['default'].resolve('test/assets/sample.plist');
var expectedField = 'com.apple.locationd.bundle-/System/Library/PrivateFrameworks/Parsec.framework';
var tmpPlist = undefined;
beforeEach(function callee$2$0() {
var temp;
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(_appiumSupport.tempDir.path());
case 2:
temp = context$3$0.sent;
tmpPlist = _path2['default'].resolve(temp, 'sample.plist');
context$3$0.next = 6;
return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(plist, tmpPlist));
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
afterEach(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(_appiumSupport.fs.unlink(tmpPlist));
case 2:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should update a plist', function callee$2$0() {
var originalData, updatedData;
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((0, _libSettings.read)(tmpPlist));
case 2:
originalData = context$3$0.sent;
originalData[expectedField].Whitelisted = true;
context$3$0.next = 6;
return _regeneratorRuntime.awrap((0, _libSettings.update)(tmpPlist, originalData));
case 6:
context$3$0.next = 8;
return _regeneratorRuntime.awrap((0, _libSettings.read)(tmpPlist));
case 8:
updatedData = context$3$0.sent;
updatedData[expectedField].Whitelisted.should.be['true'];
originalData.should.eql(updatedData);
case 11:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should read a plist', function callee$2$0() {
var data;
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((0, _libSettings.read)(tmpPlist));
case 2:
data = context$3$0.sent;
data[expectedField].should.be.an['instanceof'](Object);
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
});
describe('location services', function () {
var clientFixtureFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'clients-fixture.plist');
var clientFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'clients.plist');
var cacheFixtureFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'cache-fixture.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', 'com.apple.locationd-fixture.plist')];
var cacheFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'cache.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', 'com.apple.locationd.plist')];
beforeEach(function callee$2$0() {
var i;
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(_appiumSupport.fs.copyFile(clientFixtureFile, clientFile));
case 2:
i = 0;
case 3:
if (!(i < cacheFiles.length)) {
context$3$0.next = 9;
break;
}
context$3$0.next = 6;
return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(cacheFixtureFiles[i], cacheFiles[i]));
case 6:
i++;
context$3$0.next = 3;
break;
case 9:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
afterEach(function callee$2$0() {
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file;
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(_appiumSupport.fs.unlink(clientFile));
case 2:
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
context$3$0.prev = 5;
_iterator = _getIterator(cacheFiles);
case 7:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
context$3$0.next = 14;
break;
}
file = _step.value;
context$3$0.next = 11;
return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(file));
case 11:
_iteratorNormalCompletion = true;
context$3$0.next = 7;
break;
case 14:
context$3$0.next = 20;
break;
case 16:
context$3$0.prev = 16;
context$3$0.t0 = context$3$0['catch'](5);
_didIteratorError = true;
_iteratorError = context$3$0.t0;
case 20:
context$3$0.prev = 20;
context$3$0.prev = 21;
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
case 23:
context$3$0.prev = 23;
if (!_didIteratorError) {
context$3$0.next = 26;
break;
}
throw _iteratorError;
case 26:
return context$3$0.finish(23);
case 27:
return context$3$0.finish(20);
case 28:
case 'end':
return context$3$0.stop();
}
}, null, _this, [[5, 16, 20, 28], [21,, 23, 27]]);
});
describe('client plist', function () {
var data = undefined;
var weirdLocKey = 'com.apple.locationd.bundle-/System/Library/' + 'PrivateFrameworks/AOSNotification.framework';
beforeEach(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:
context$4$0.next = 2;
return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile));
case 2:
data = context$4$0.sent;
expect(data['com.apple.mobilesafari']).to.not.exist;
expect(data[weirdLocKey]).to.not.exist;
case 5:
case 'end':
return context$4$0.stop();
}
}, null, _this);
});
it('should update', function callee$3$0() {
var finalData;
return _regeneratorRuntime.async(function callee$3$0$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
context$4$0.next = 2;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'com.apple.mobilesafari', true));
case 2:
context$4$0.next = 4;
return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile));
case 4:
finalData = context$4$0.sent;
finalData.should.not.eql(data);
finalData['com.apple.mobilesafari'].should.exist;
finalData['com.apple.mobilesafari'].Authorized.should.be['true'];
case 8:
case 'end':
return context$4$0.stop();
}
}, null, _this);
});
it('should update an already existing bundle without changing anything but Authorized', function callee$3$0() {
var finalData, originalRecord, updatedRecord;
return _regeneratorRuntime.async(function callee$3$0$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
context$4$0.next = 2;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'io.appium.test', true));
case 2:
context$4$0.next = 4;
return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile));
case 4:
finalData = context$4$0.sent;
finalData.should.not.eql(data);
originalRecord = data['io.appium.test'];
updatedRecord = finalData['io.appium.test'];
updatedRecord.Whitelisted.should.equal(originalRecord.Whitelisted);
updatedRecord.Executable.should.equal(originalRecord.Executable);
updatedRecord.Registered.should.equal(originalRecord.Registered);
updatedRecord.Authorized.should.not.equal(originalRecord.Authorized);
case 12:
case 'end':
return context$4$0.stop();
}
}, null, _this);
});
it('should update with weird location key', function callee$3$0() {
var finalData;
return _regeneratorRuntime.async(function callee$3$0$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
context$4$0.next = 2;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'com.apple.mobilesafari', true));
case 2:
context$4$0.next = 4;
return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile));
case 4:
finalData = context$4$0.sent;
finalData.should.not.eql(data);
finalData[weirdLocKey].should.exist;
case 7:
case 'end':
return context$4$0.stop();
}
}, null, _this);
});
});
describe('cache plists', function () {
it('should update both files', function callee$3$0() {
var _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, file, finalData;
return _regeneratorRuntime.async(function callee$3$0$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
context$4$0.next = 2;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'com.apple.mobilesafari', true));
case 2:
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
context$4$0.prev = 5;
_iterator2 = _getIterator(cacheFiles);
case 7:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
context$4$0.next = 18;
break;
}
file = _step2.value;
context$4$0.next = 11;
return _regeneratorRuntime.awrap((0, _libSettings.read)(file));
case 11:
finalData = context$4$0.sent;
finalData['com.apple.mobilesafari'].should.exist;
finalData['com.apple.mobilesafari'].LastFenceActivityTimestamp.should.equal(412122103.232983);
finalData['com.apple.mobilesafari'].CleanShutdown.should.be['true'];
case 15:
_iteratorNormalCompletion2 = true;
context$4$0.next = 7;
break;
case 18:
context$4$0.next = 24;
break;
case 20:
context$4$0.prev = 20;
context$4$0.t0 = context$4$0['catch'](5);
_didIteratorError2 = true;
_iteratorError2 = context$4$0.t0;
case 24:
context$4$0.prev = 24;
context$4$0.prev = 25;
if (!_iteratorNormalCompletion2 && _iterator2['return']) {
_iterator2['return']();
}
case 27:
context$4$0.prev = 27;
if (!_didIteratorError2) {
context$4$0.next = 30;
break;
}
throw _iteratorError2;
case 30:
return context$4$0.finish(27);
case 31:
return context$4$0.finish(24);
case 32:
case 'end':
return context$4$0.stop();
}
}, null, _this, [[5, 20, 24, 32], [25,, 27, 31]]);
});
});
});
describe('updateLocale', function () {
var globalPlistFixtureFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', '.GlobalPreferences-fixture.plist');
var globalPlistFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', '.GlobalPreferences.plist');
beforeEach(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(_appiumSupport.fs.copyFile(globalPlistFixtureFile, globalPlistFile));
case 2:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
afterEach(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(_appiumSupport.fs.unlink(globalPlistFile));
case 2:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should update language', function callee$2$0() {
var originalData, finalData;
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((0, _libSettings.read)(globalPlistFile));
case 2:
originalData = context$3$0.sent;
context$3$0.next = 5;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, 'rr'));
case 5:
context$3$0.next = 7;
return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile));
case 7:
finalData = context$3$0.sent;
finalData.should.not.eql(originalData);
finalData.AppleLanguages.should.include('rr');
case 10:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should not do anything when language is already present', function callee$2$0() {
var originalData;
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((0, _libSettings.read)(globalPlistFile));
case 2:
originalData = context$3$0.sent;
context$3$0.next = 5;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, 'en'));
case 5:
context$3$0.next = 7;
return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile));
case 7:
context$3$0.t0 = originalData;
context$3$0.sent.should.eql(context$3$0.t0);
case 9:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should update locale', function callee$2$0() {
var originalData, finalData;
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((0, _libSettings.read)(globalPlistFile));
case 2:
originalData = context$3$0.sent;
context$3$0.next = 5;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, 'fr_US'));
case 5:
context$3$0.next = 7;
return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile));
case 7:
finalData = context$3$0.sent;
finalData.should.not.eql(originalData);
finalData.AppleLanguages.should.eql(originalData.AppleLanguages);
finalData.AppleLocale.should.include('fr_US');
case 11:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should update calendarFormat', function callee$2$0() {
var originalData, finalData;
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((0, _libSettings.read)(globalPlistFile));
case 2:
originalData = context$3$0.sent;
context$3$0.next = 5;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, undefined, 'something'));
case 5:
context$3$0.next = 7;
return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile));
case 7:
finalData = context$3$0.sent;
finalData.should.not.eql(originalData);
finalData.AppleLanguages.should.eql(originalData.AppleLanguages);
finalData.AppleLocale.should.include('@calendar=something');
case 11:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should preserve the calendarFormat when updating locale alone', function callee$2$0() {
var originalData, intermediateData, finalData;
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((0, _libSettings.read)(globalPlistFile));
case 2:
originalData = context$3$0.sent;
context$3$0.next = 5;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, undefined, 'something'));
case 5:
context$3$0.next = 7;
return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile));
case 7:
intermediateData = context$3$0.sent;
intermediateData.should.not.eql(originalData);
intermediateData.AppleLanguages.should.eql(originalData.AppleLanguages);
intermediateData.AppleLocale.should.include('@calendar=something');
// udpate with a new locale
context$3$0.next = 13;
return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, 'fr_US'));
case 13:
context$3$0.next = 15;
return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile));
case 15:
finalData = context$3$0.sent;
finalData.should.not.eql(intermediateData);
finalData.AppleLanguages.should.eql(originalData.AppleLanguages);
finalData.AppleLocale.should.eql('fr_US@calendar=something');
case 19:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
});
describe('updateSafariUserSettings', function () {
var fixtureFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'EffectiveUserSettings-fixture.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'UserSettings-fixture.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'PublicInfo', 'PublicEffectiveUserSettings-fixture.plist')];
var realFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'EffectiveUserSettings.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'UserSettings.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'PublicInfo', 'PublicEffectiveUserSettings.plist')];
beforeEach(function callee$2$0() {
var i;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
i = 0;
case 1:
if (!(i < fixtureFiles.length)) {
context$3$0.next = 7;
break;
}
context$3$0.next = 4;
return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(fixtureFiles[i], realFiles[i]));
case 4:
i++;
context$3$0.next = 1;
break;
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
afterEach(function callee$2$0() {
var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, file;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
_iteratorNormalCompletion3 = true;
_didIteratorError3 = false;
_iteratorError3 = undefined;
context$3$0.prev = 3;
_iterator3 = _getIterator(realFiles);
case 5:
if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
context$3$0.next = 12;
break;
}
file = _step3.value;
context$3$0.next = 9;
return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(file));
case 9:
_iteratorNormalCompletion3 = true;
context$3$0.next = 5;
break;
case 12:
context$3$0.next = 18;
break;
case 14:
context$3$0.prev = 14;
context$3$0.t0 = context$3$0['catch'](3);
_didIteratorError3 = true;
_iteratorError3 = context$3$0.t0;
case 18:
context$3$0.prev = 18;
context$3$0.prev = 19;
if (!_iteratorNormalCompletion3 && _iterator3['return']) {
_iterator3['return']();
}
case 21:
context$3$0.prev = 21;
if (!_didIteratorError3) {
context$3$0.next = 24;
break;
}
throw _iteratorError3;
case 24:
return context$3$0.finish(21);
case 25:
return context$3$0.finish(18);
case 26:
case 'end':
return context$3$0.stop();
}
}, null, _this, [[3, 14, 18, 26], [19,, 21, 25]]);
});
function getData() {
return _regeneratorRuntime.async(function getData$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
return context$3$0.abrupt('return', (0, _asyncbox.asyncmap)(realFiles, function (file) {
return (0, _libSettings.read)(file);
}, true));
case 1:
case 'end':
return context$3$0.stop();
}
}, null, this);
}
it('should update all the files', function callee$2$0() {
var originalData, settingSet, finalData, i;
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(getData());
case 2:
originalData = context$3$0.sent;
settingSet = {
WebKitJavaScriptEnabled: false,
WebKitJavaScriptCanOpenWindowsAutomatically: false,
WarnAboutFraudulentWebsites: false
};
context$3$0.next = 6;
return _regeneratorRuntime.awrap((0, _libSettings.updateSafariUserSettings)(sim, settingSet));
case 6:
context$3$0.next = 8;
return _regeneratorRuntime.awrap(getData());
case 8:
finalData = context$3$0.sent;
for (i = 0; i < realFiles.length; i++) {
finalData[i].should.not.eql(originalData[i]);
finalData[i].restrictedBool.safariAllowJavaScript.value.should.be['false'];
finalData[i].restrictedBool.safariAllowPopups.value.should.be['false'];
finalData[i].restrictedBool.safariForceFraudWarning.value.should.be['true'];
}
case 10:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
});
});
// get rid of the temporary plist we made
// make a copy of the clients plist
// and the cache plists
// get rid of the temporary plist we made
// get rid of the temporary plist we made
// get a calendar format into the plist
// make a copy of the fixture
// get rid of the temporary plists we made
// check the update
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvdW5pdC9zZXR0aW5ncy1zcGVjcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7b0JBRWlCLE1BQU07Ozs7OEJBQ0ksa0JBQWtCOzs7OzJCQUVKLG9CQUFvQjs7a0NBQ2pDLDZCQUE2Qjs7OztvQkFDeEMsTUFBTTs7Ozs2QkFDSyxnQkFBZ0I7O3FCQUMxQixPQUFPOzs7O3dCQUNBLFVBQVU7O0FBR25DLElBQU0sYUFBYSxHQUFHLGtCQUFLLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQzs7QUFFbkQsa0JBQUssTUFBTSxFQUFFLENBQUM7QUFDZCxJQUFJLE1BQU0sR0FBRyxrQkFBSyxNQUFNLENBQUM7QUFDekIsa0JBQUssR0FBRyw2QkFBZ0IsQ0FBQzs7QUFFekIsUUFBUSxDQUFDLFVBQVUsRUFBRSxZQUFNO0FBQ3pCLE1BQUksR0FBRyxZQUFBLENBQUM7QUFDUixRQUFNLENBQUMsWUFBTTs7QUFFWCxPQUFHLEdBQUcscUNBQXFCLENBQUM7QUFDNUIsdUJBQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7R0FDbEQsQ0FBQyxDQUFDOztBQUVILFVBQVEsQ0FBQyx3QkFBd0IsRUFBRSxZQUFNO0FBQ3ZDLFFBQU0sS0FBSyxHQUFHLGtCQUFLLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBQ3ZELFFBQU0sYUFBYSxHQUFHLCtFQUErRSxDQUFDO0FBQ3RHLFFBQUksUUFBUSxZQUFBLENBQUM7O0FBRWIsY0FBVSxDQUFDO1VBQ0wsSUFBSTs7Ozs7NkNBQVMsdUJBQVEsSUFBSSxFQUFFOzs7QUFBM0IsZ0JBQUk7O0FBQ1Isb0JBQVEsR0FBRyxrQkFBSyxPQUFPLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDOzs2Q0FDeEMsa0JBQUcsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7Ozs7Ozs7S0FDbkMsQ0FBQyxDQUFDOztBQUVILGFBQVMsQ0FBQzs7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QzlCLHlEQUEyQyxFQUFFLEtBQUs7QUFDbEQseUNBQTJCLEVBQUUsS0FBSzthQUNuQzs7NkNBQ0ssMkNBQXlCLEdBQUcsRUFBRSxVQUFVLENBQUM7Ozs7NkNBR3pCLE9BQU8sRUFBRTs7O0FBQTNCLHFCQUFTOztBQUNiLGlCQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDekMsdUJBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3Qyx1QkFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBTSxDQUFDO0FBQ3hFLHVCQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFNLENBQUM7QUFDcEUsdUJBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFFBQUssQ0FBQzthQUMxRTs7Ozs7OztLQUNGLENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQztDQUNKLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0L3VuaXQvc2V0dGluZ3Mtc3BlY3MuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgeyB1cGRhdGUsIHJlYWQsIHVwZGF0ZUxvY2F0aW9uU2V0dGluZ3MsIHVwZGF0ZUxvY2FsZSxcbiAgICAgICAgIHVwZGF0ZVNhZmFyaVVzZXJTZXR0aW5ncyB9IGZyb20gJy4uLy4uL2xpYi9zZXR0aW5ncyc7XG5pbXBvcnQgU2ltdWxhdG9yWGNvZGU2IGZyb20gJy4uLy4uL2xpYi9zaW11bGF0b3IteGNvZGUtNic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHRlbXBEaXIsIGZzIH0gZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IGFzeW5jbWFwIH0gZnJvbSAnYXN5bmNib3gnO1xuXG5cbmNvbnN0IFNJTV9ESVJFQ1RPUlkgPSBwYXRoLnJlc29sdmUoJ3Rlc3QvYXNzZXRzLycpO1xuXG5jaGFpLnNob3VsZCgpO1xubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuY2hhaS51c2UoY2hhaUFzUHJvbWlzZWQpO1xuXG5kZXNjcmliZSgnc2V0dGluZ3MnLCAoKSA9PiB7XG4gIGxldCBzaW07XG4gIGJlZm9yZSgoKSA9PiB7XG4gICAgLy8gY3JlYXRlIGEgc2ltdWxhdG9yIG9iamVjdCB0aGF0IHJldHVybnMgb3VyIGZpeHR1cmUgZGlyZWN0b3J5XG4gICAgc2ltID0gbmV3IFNpbXVsYXRvclhjb2RlNigpO1xuICAgIHNpbm9uLnN0dWIoc2ltLCAnZ2V0RGlyJykucmV0dXJucyhTSU1fRElSRUNUT1JZKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dlbmVyYWwgcGxpc3QgaGFuZGxpbmcnLCAoKSA9PiB7XG4gICAgY29uc3QgcGxpc3QgPSBwYXRoLnJlc29sdmUoJ3Rlc3QvYXNzZXRzL3NhbXBsZS5wbGlzdCcpO1xuICAgIGNvbnN0IGV4cGVjdGVkRmllbGQgPSAnY29tLmFwcGxlLmxvY2F0aW9uZC5idW5kbGUtL1N5c3RlbS9MaWJyYXJ5L1ByaXZhdGVGcmFtZXdvcmtzL1BhcnNlYy5mcmFtZXdvcmsnO1xuICAgIGxldCB0bXBQbGlzdDtcblxuICAgIGJlZm9yZUVhY2goYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IHRlbXAgPSBhd2FpdCB0ZW1wRGlyLnBhdGgoKTtcbiAgICAgIHRtcFBsaXN0ID0gcGF0aC5yZXNvbHZlKHRlbXAsICdzYW1wbGUucGxpc3QnKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKHBsaXN0LCB0bXBQbGlzdCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gZ2V0IHJpZCBvZiB0aGUgdGVtcG9yYXJ5IHBsaXN0IHdlIG1hZGVcbiAgICAgIGF3YWl0IGZzLnVubGluayh0bXBQbGlzdCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVwZGF0ZSBhIHBsaXN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IG9yaWdpbmFsRGF0YSA9IGF3YWl0IHJlYWQodG1wUGxpc3QpO1xuICAgICAgb3JpZ2luYWxEYXRhW2V4cGVjdGVkRmllbGRdXG4gICAgICAgIC5XaGl0ZWxpc3RlZCA9IHRydWU7XG4gICAgICBhd2FpdCB1cGRhdGUodG1wUGxpc3QsIG9yaWdpbmFsRGF0YSk7XG4gICAgICBsZXQgdXBkYXRlZERhdGEgPSBhd2FpdCByZWFkKHRtcFBsaXN0KTtcblxuICAgICAgdXBkYXRlZERhdGFbZXhwZWN0ZWRGaWVsZF1cbiAgICAgICAgLldoaXRlbGlzdGVkLnNob3VsZC5iZS50cnVlO1xuXG4gICAgICBvcmlnaW5hbERhdGEuc2hvdWxkLmVxbCh1cGRhdGVkRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlYWQgYSBwbGlzdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBkYXRhID0gYXdhaXQgcmVhZCh0bXBQbGlzdCk7XG4gICAgICBkYXRhW2V4cGVjdGVkRmllbGRdXG4gICAgICAgIC5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihPYmplY3QpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbG9jYXRpb24gc2VydmljZXMnLCAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50Rml4dHVyZUZpbGUgPSBwYXRoLnJlc29sdmUoU0lNX0RJUkVDVE9SWSwgJ0xpYnJhcnknLCAnQ2FjaGVzJywgJ2xvY2F0aW9uZCcsICdjbGllbnRzLWZpeHR1cmUucGxpc3QnKTtcbiAgICBjb25zdCBjbGllbnRGaWxlID0gcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ0NhY2hlcycsICdsb2NhdGlvbmQnLCAnY2xpZW50cy5wbGlzdCcpO1xuICAgIGNvbnN0IGNhY2hlRml4dHVyZUZpbGVzID0gW1xuICAgICAgcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ0NhY2hlcycsICdsb2NhdGlvbmQnLCAnY2FjaGUtZml4dHVyZS5wbGlzdCcpLFxuICAgICAgcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ1ByZWZlcmVuY2VzJywgJ2NvbS5hcHBsZS5sb2NhdGlvbmQtZml4dHVyZS5wbGlzdCcpXG4gICAgXTtcbiAgICBjb25zdCBjYWNoZUZpbGVzID0gW1xuICAgICAgcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ0NhY2hlcycsICdsb2NhdGlvbmQnLCAnY2FjaGUucGxpc3QnKSxcbiAgICAgIHBhdGgucmVzb2x2ZShTSU1fRElSRUNUT1JZLCAnTGlicmFyeScsICdQcmVmZXJlbmNlcycsICdjb20uYXBwbGUubG9jYXRpb25kLnBsaXN0JylcbiAgICBdO1xuICAgIGJlZm9yZUVhY2goYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gbWFrZSBhIGNvcHkgb2YgdGhlIGNsaWVudHMgcGxpc3RcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGNsaWVudEZpeHR1cmVGaWxlLCBjbGllbnRGaWxlKTtcblxuICAgICAgLy8gYW5kIHRoZSBjYWNoZSBwbGlzdHNcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2FjaGVGaWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBhd2FpdCBmcy5jb3B5RmlsZShjYWNoZUZpeHR1cmVGaWxlc1tpXSwgY2FjaGVGaWxlc1tpXSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGdldCByaWQgb2YgdGhlIHRlbXBvcmFyeSBwbGlzdCB3ZSBtYWRlXG4gICAgICBhd2FpdCBmcy51bmxpbmsoY2xpZW50RmlsZSk7XG4gICAgICBmb3IgKGxldCBmaWxlIG9mIGNhY2hlRmlsZXMpIHtcbiAgICAgICAgYXdhaXQgZnMudW5saW5rKGZpbGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NsaWVudCBwbGlzdCcsICgpID0+IHtcbiAgICAgIGxldCBkYXRhO1xuICAgICAgY29uc3Qgd2VpcmRMb2NLZXkgPSAnY29tLmFwcGxlLmxvY2F0aW9uZC5idW5kbGUtL1N5c3RlbS9MaWJyYXJ5LycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnUHJpdmF0ZUZyYW1ld29ya3MvQU9TTm90aWZpY2F0aW9uLmZyYW1ld29yayc7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgICAgZGF0YSA9IGF3YWl0IHJlYWQoY2xpZW50RmlsZSk7XG4gICAgICAgIGV4cGVjdChkYXRhWydjb20uYXBwbGUubW9iaWxlc2FmYXJpJ10pLnRvLm5vdC5leGlzdDtcbiAgICAgICAgZXhwZWN0KGRhdGFbd2VpcmRMb2NLZXldKS50by5ub3QuZXhpc3Q7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB1cGRhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHVwZGF0ZUxvY2F0aW9uU2V0dGluZ3Moc2ltLCAnY29tLmFwcGxlLm1vYmlsZXNhZmFyaScsIHRydWUpO1xuXG4gICAgICAgIGxldCBmaW5hbERhdGEgPSBhd2FpdCByZWFkKGNsaWVudEZpbGUpO1xuICAgICAgICBmaW5hbERhdGEuc2hvdWxkLm5vdC5lcWwoZGF0YSk7XG4gICAgICAgIGZpbmFsRGF0YVsnY29tLmFwcGxlLm1vYmlsZXNhZmFyaSddLnNob3VsZC5leGlzdDtcbiAgICAgICAgZmluYWxEYXRhWydjb20uYXBwbGUubW9iaWxlc2FmYXJpJ10uQXV0aG9yaXplZC5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVwZGF0ZSBhbiBhbHJlYWR5IGV4aXN0aW5nIGJ1bmRsZSB3aXRob3V0IGNoYW5naW5nIGFueXRoaW5nIGJ1dCBBdXRob3JpemVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB1cGRhdGVMb2NhdGlvblNldHRpbmdzKHNpbSwgJ2lvLmFwcGl1bS50ZXN0JywgdHJ1ZSk7XG5cbiAgICAgICAgbGV0IGZpbmFsRGF0YSA9IGF3YWl0IHJlYWQoY2xpZW50RmlsZSk7XG4gICAgICAgIGZpbmFsRGF0YS5zaG91bGQubm90LmVxbChkYXRhKTtcblxuICAgICAgICBsZXQgb3JpZ2luYWxSZWNvcmQgPSBkYXRhWydpby5hcHBpdW0udGVzdCddO1xuICAgICAgICBsZXQgdXBkYXRlZFJlY29yZCA9IGZpbmFsRGF0YVsnaW8uYXBwaXVtLnRlc3QnXTtcbiAgICAgICAgdXBkYXRlZFJlY29yZC5XaGl0ZWxpc3RlZC5zaG91bGQuZXF1YWwob3JpZ2luYWxSZWNvcmQuV2hpdGVsaXN0ZWQpO1xuICAgICAgICB1cGRhdGVkUmVjb3JkLkV4ZWN1dGFibGUuc2hvdWxkLmVxdWFsKG9yaWdpbmFsUmVjb3JkLkV4ZWN1dGFibGUpO1xuICAgICAgICB1cGRhdGVkUmVjb3JkLlJlZ2lzdGVyZWQuc2hvdWxkLmVxdWFsKG9yaWdpbmFsUmVjb3JkLlJlZ2lzdGVyZWQpO1xuICAgICAgICB1cGRhdGVkUmVjb3JkLkF1dGhvcml6ZWQuc2hvdWxkLm5vdC5lcXVhbChvcmlnaW5hbFJlY29yZC5BdXRob3JpemVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVwZGF0ZSB3aXRoIHdlaXJkIGxvY2F0aW9uIGtleScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdXBkYXRlTG9jYXRpb25TZXR0aW5ncyhzaW0sICdjb20uYXBwbGUubW9iaWxlc2FmYXJpJywgdHJ1ZSk7XG5cbiAgICAgICAgbGV0IGZpbmFsRGF0YSA9IGF3YWl0IHJlYWQoY2xpZW50RmlsZSk7XG4gICAgICAgIGZpbmFsRGF0YS5zaG91bGQubm90LmVxbChkYXRhKTtcbiAgICAgICAgZmluYWxEYXRhW3dlaXJkTG9jS2V5XS5zaG91bGQuZXhpc3Q7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjYWNoZSBwbGlzdHMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHVwZGF0ZSBib3RoIGZpbGVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB1cGRhdGVMb2NhdGlvblNldHRpbmdzKHNpbSwgJ2NvbS5hcHBsZS5tb2JpbGVzYWZhcmknLCB0cnVlKTtcblxuICAgICAgICBmb3IgKGxldCBmaWxlIG9mIGNhY2hlRmlsZXMpIHtcbiAgICAgICAgICBsZXQgZmluYWxEYXRhID0gYXdhaXQgcmVhZChmaWxlKTtcbiAgICAgICAgICBmaW5hbERhdGFbJ2NvbS5hcHBsZS5tb2JpbGVzYWZhcmknXS5zaG91bGQuZXhpc3Q7XG4gICAgICAgICAgZmluYWxEYXRhWydjb20uYXBwbGUubW9iaWxlc2FmYXJpJ10uTGFzdEZlbmNlQWN0aXZpdHlUaW1lc3RhbXAuc2hvdWxkLmVxdWFsKDQxMjEyMjEwMy4yMzI5ODMpO1xuICAgICAgICAgIGZpbmFsRGF0YVsnY29tLmFwcGxlLm1vYmlsZXNhZmFyaSddLkNsZWFuU2h1dGRvd24uc2hvdWxkLmJlLnRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndXBkYXRlTG9jYWxlJywgKCkgPT4ge1xuICAgIGNvbnN0IGdsb2JhbFBsaXN0Rml4dHVyZUZpbGUgPSBwYXRoLnJlc29sdmUoU0lNX0RJUkVDVE9SWSwgJ0xpYnJhcnknLCAnUHJlZmVyZW5jZXMnLCAnLkdsb2JhbFByZWZlcmVuY2VzLWZpeHR1cmUucGxpc3QnKTtcbiAgICBjb25zdCBnbG9iYWxQbGlzdEZpbGUgPSBwYXRoLnJlc29sdmUoU0lNX0RJUkVDVE9SWSwgJ0xpYnJhcnknLCAnUHJlZmVyZW5jZXMnLCAnLkdsb2JhbFByZWZlcmVuY2VzLnBsaXN0Jyk7XG5cbiAgICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGdsb2JhbFBsaXN0Rml4dHVyZUZpbGUsIGdsb2JhbFBsaXN0RmlsZSk7XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGdldCByaWQgb2YgdGhlIHRlbXBvcmFyeSBwbGlzdCB3ZSBtYWRlXG4gICAgICBhd2FpdCBmcy51bmxpbmsoZ2xvYmFsUGxpc3RGaWxlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXBkYXRlIGxhbmd1YWdlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IG9yaWdpbmFsRGF0YSA9IGF3YWl0IHJlYWQoZ2xvYmFsUGxpc3RGaWxlKTtcblxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgJ3JyJyk7XG4gICAgICBsZXQgZmluYWxEYXRhID0gYXdhaXQgcmVhZChnbG9iYWxQbGlzdEZpbGUpO1xuICAgICAgZmluYWxEYXRhLnNob3VsZC5ub3QuZXFsKG9yaWdpbmFsRGF0YSk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMuc2hvdWxkLmluY2x1ZGUoJ3JyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBkbyBhbnl0aGluZyB3aGVuIGxhbmd1YWdlIGlzIGFscmVhZHkgcHJlc2VudCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBvcmlnaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG5cbiAgICAgIGF3YWl0IHVwZGF0ZUxvY2FsZShzaW0sICdlbicpO1xuICAgICAgKGF3YWl0IHJlYWQoZ2xvYmFsUGxpc3RGaWxlKSkuc2hvdWxkLmVxbChvcmlnaW5hbERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1cGRhdGUgbG9jYWxlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IG9yaWdpbmFsRGF0YSA9IGF3YWl0IHJlYWQoZ2xvYmFsUGxpc3RGaWxlKTtcblxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgdW5kZWZpbmVkLCAnZnJfVVMnKTtcbiAgICAgIGxldCBmaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG4gICAgICBmaW5hbERhdGEuc2hvdWxkLm5vdC5lcWwob3JpZ2luYWxEYXRhKTtcbiAgICAgIGZpbmFsRGF0YS5BcHBsZUxhbmd1YWdlcy5zaG91bGQuZXFsKG9yaWdpbmFsRGF0YS5BcHBsZUxhbmd1YWdlcyk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMb2NhbGUuc2hvdWxkLmluY2x1ZGUoJ2ZyX1VTJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVwZGF0ZSBjYWxlbmRhckZvcm1hdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBvcmlnaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG5cbiAgICAgIGF3YWl0IHVwZGF0ZUxvY2FsZShzaW0sIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnc29tZXRoaW5nJyk7XG4gICAgICBsZXQgZmluYWxEYXRhID0gYXdhaXQgcmVhZChnbG9iYWxQbGlzdEZpbGUpO1xuICAgICAgZmluYWxEYXRhLnNob3VsZC5ub3QuZXFsKG9yaWdpbmFsRGF0YSk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMuc2hvdWxkLmVxbChvcmlnaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMpO1xuICAgICAgZmluYWxEYXRhLkFwcGxlTG9jYWxlLnNob3VsZC5pbmNsdWRlKCdAY2FsZW5kYXI9c29tZXRoaW5nJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByZXNlcnZlIHRoZSBjYWxlbmRhckZvcm1hdCB3aGVuIHVwZGF0aW5nIGxvY2FsZSBhbG9uZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBvcmlnaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG5cbiAgICAgIC8vIGdldCBhIGNhbGVuZGFyIGZvcm1hdCBpbnRvIHRoZSBwbGlzdFxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsICdzb21ldGhpbmcnKTtcbiAgICAgIGxldCBpbnRlcm1lZGlhdGVEYXRhID0gYXdhaXQgcmVhZChnbG9iYWxQbGlzdEZpbGUpO1xuICAgICAgaW50ZXJtZWRpYXRlRGF0YS5zaG91bGQubm90LmVxbChvcmlnaW5hbERhdGEpO1xuICAgICAgaW50ZXJtZWRpYXRlRGF0YS5BcHBsZUxhbmd1YWdlcy5zaG91bGQuZXFsKG9yaWdpbmFsRGF0YS5BcHBsZUxhbmd1YWdlcyk7XG4gICAgICBpbnRlcm1lZGlhdGVEYXRhLkFwcGxlTG9jYWxlLnNob3VsZC5pbmNsdWRlKCdAY2FsZW5kYXI9c29tZXRoaW5nJyk7XG5cbiAgICAgIC8vIHVkcGF0ZSB3aXRoIGEgbmV3IGxvY2FsZVxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgdW5kZWZpbmVkLCAnZnJfVVMnKTtcbiAgICAgIGxldCBmaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG4gICAgICBmaW5hbERhdGEuc2hvdWxkLm5vdC5lcWwoaW50ZXJtZWRpYXRlRGF0YSk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMuc2hvdWxkLmVxbChvcmlnaW5hbERhdGE