electron-forge
Version:
A complete tool for building modern Electron applications
656 lines (495 loc) • 47.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _bluebird = require('bluebird');
var _debug = require('debug');
var _debug2 = _interopRequireDefault(_debug);
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _inquirer = require('inquirer');
var _inquirer2 = _interopRequireDefault(_inquirer);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _initGit = require('../init/init-git');
var _initGit2 = _interopRequireDefault(_initGit);
var _initNpm = require('../init/init-npm');
var _oraHandler = require('../util/ora-handler');
var _oraHandler2 = _interopRequireDefault(_oraHandler);
var _messages = require('../util/messages');
var _installDependencies = require('../util/install-dependencies');
var _installDependencies2 = _interopRequireDefault(_installDependencies);
var _readPackageJson = require('../util/read-package-json');
var _readPackageJson2 = _interopRequireDefault(_readPackageJson);
var _confirmIfInteractive = require('../util/confirm-if-interactive');
var _confirmIfInteractive2 = _interopRequireDefault(_confirmIfInteractive);
var _yarnOrNpm = require('../util/yarn-or-npm');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var d = (0, _debug2.default)('electron-forge:import');
/**
* @typedef {Object} ImportOptions
* @property {string} [dir=process.cwd()] The path to the app to be imported
* @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually
* @property {boolean} [updateScripts=true] Whether to update the modules package.json scripts to be electron-forge commands
* @property {string} [outDir=`${dir}/out`] The path to the directory containing generated distributables
*/
/**
* Attempt to import a given module directory to the Electron Forge standard.
*
* - Replaces the prebuilt electron package with the one that integrates with `electron-compile`
* - Sets up `git` and the correct NPM dependencies
* - Adds a template forge config to `package.json`
*
* @param {ImportOptions} providedOptions - Options for the import method
* @return {Promise} Will resolve when the import process is complete
*/
exports.default = function () {
var _ref = (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee8() {
var providedOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _Object$assign, dir, interactive, updateScripts, outDir, confirm, packageJSON, shouldContinue, shouldChangeMain, _ref2, newMain, keys, buildToolPackages, electronName, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, key, explanation, shouldRemoveDependency, updatePackageScript, writeChanges, electronVersion, electronPackageJSON, templatePackageJSON, babelConfig, babelPath;
return _regenerator2.default.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
_Object$assign = (0, _assign2.default)({
dir: process.cwd(),
interactive: false,
updateScripts: true
}, providedOptions), dir = _Object$assign.dir, interactive = _Object$assign.interactive, updateScripts = _Object$assign.updateScripts;
outDir = providedOptions.outDir || 'out';
_oraHandler2.default.interactive = interactive;
d('Attempting to import project in: ' + dir);
_context8.next = 6;
return _fsExtra2.default.pathExists(dir);
case 6:
_context8.t0 = !_context8.sent;
if (_context8.t0) {
_context8.next = 11;
break;
}
_context8.next = 10;
return _fsExtra2.default.pathExists(_path2.default.resolve(dir, 'package.json'));
case 10:
_context8.t0 = !_context8.sent;
case 11:
if (!_context8.t0) {
_context8.next = 13;
break;
}
throw 'We couldn\'t find a project in: ' + dir;
case 13:
_context8.next = 15;
return (0, _confirmIfInteractive2.default)(interactive, 'WARNING: We will now attempt to import: "' + dir + '". This will involve modifying some files, are you sure you want to continue?');
case 15:
confirm = _context8.sent;
if (!confirm) {
process.exit(0);
}
_context8.next = 19;
return (0, _initGit2.default)(dir);
case 19:
_context8.next = 21;
return (0, _readPackageJson2.default)(dir);
case 21:
packageJSON = _context8.sent;
if (!(packageJSON.config && packageJSON.config.forge)) {
_context8.next = 28;
break;
}
(0, _messages.warn)(interactive, 'It looks like this project is already configured for "electron-forge"'.green);
_context8.next = 26;
return (0, _confirmIfInteractive2.default)(interactive, 'Are you sure you want to continue?');
case 26:
shouldContinue = _context8.sent;
if (!shouldContinue) {
process.exit(0);
}
case 28:
_context8.next = 30;
return (0, _confirmIfInteractive2.default)(interactive, 'Do you want us to change the "main" attribute of your package.json? If you are currently using babel and pointing to a "build" directory say yes.', false);
case 30:
shouldChangeMain = _context8.sent;
if (!shouldChangeMain) {
_context8.next = 37;
break;
}
_context8.next = 34;
return _inquirer2.default.createPromptModule()({
type: 'input',
name: 'newMain',
default: packageJSON.main,
message: 'Enter the relative path to your uncompiled main file'
});
case 34:
_ref2 = _context8.sent;
newMain = _ref2.newMain;
packageJSON.main = newMain;
case 37:
packageJSON.dependencies = packageJSON.dependencies || {};
packageJSON.devDependencies = packageJSON.devDependencies || {};
keys = (0, _keys2.default)(packageJSON.dependencies).concat((0, _keys2.default)(packageJSON.devDependencies));
buildToolPackages = {
'electron-builder': 'provides mostly equivalent functionality',
'electron-download': 'already uses this module as a transitive dependency',
'electron-installer-debian': 'already uses this module as a transitive dependency',
'electron-installer-dmg': 'already uses this module as a transitive dependency',
'electron-installer-flatpak': 'already uses this module as a transitive dependency',
'electron-installer-redhat': 'already uses this module as a transitive dependency',
'electron-osx-sign': 'already uses this module as a transitive dependency',
'electron-packager': 'already uses this module as a transitive dependency',
'electron-winstaller': 'already uses this module as a transitive dependency'
};
electronName = void 0;
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context8.prev = 45;
_iterator = (0, _getIterator3.default)(keys);
case 47:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context8.next = 64;
break;
}
key = _step.value;
if (!(key === 'electron' || key === 'electron-prebuilt')) {
_context8.next = 55;
break;
}
delete packageJSON.dependencies[key];
delete packageJSON.devDependencies[key];
electronName = key;
_context8.next = 61;
break;
case 55:
if (!buildToolPackages[key]) {
_context8.next = 61;
break;
}
explanation = buildToolPackages[key];
// eslint-disable-next-line max-len
_context8.next = 59;
return (0, _confirmIfInteractive2.default)(interactive, 'Do you want us to remove the "' + key + '" dependency in package.json? Electron Forge ' + explanation + '.');
case 59:
shouldRemoveDependency = _context8.sent;
if (shouldRemoveDependency) {
delete packageJSON.dependencies[key];
delete packageJSON.devDependencies[key];
}
case 61:
_iteratorNormalCompletion = true;
_context8.next = 47;
break;
case 64:
_context8.next = 70;
break;
case 66:
_context8.prev = 66;
_context8.t1 = _context8['catch'](45);
_didIteratorError = true;
_iteratorError = _context8.t1;
case 70:
_context8.prev = 70;
_context8.prev = 71;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 73:
_context8.prev = 73;
if (!_didIteratorError) {
_context8.next = 76;
break;
}
throw _iteratorError;
case 76:
return _context8.finish(73);
case 77:
return _context8.finish(70);
case 78:
packageJSON.scripts = packageJSON.scripts || {};
d('reading current scripts object:', packageJSON.scripts);
updatePackageScript = function () {
var _ref3 = (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee(scriptName, newValue) {
var shouldUpdate;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(packageJSON.scripts[scriptName] !== newValue)) {
_context.next = 5;
break;
}
_context.next = 3;
return (0, _confirmIfInteractive2.default)(interactive, 'Do you want us to update the "' + scriptName + '" script to instead call the electron-forge task "' + newValue + '"', updateScripts);
case 3:
shouldUpdate = _context.sent;
if (shouldUpdate) {
packageJSON.scripts[scriptName] = newValue;
}
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
}));
return function updatePackageScript(_x2, _x3) {
return _ref3.apply(this, arguments);
};
}();
_context8.next = 83;
return updatePackageScript('start', 'electron-forge start');
case 83:
_context8.next = 85;
return updatePackageScript('package', 'electron-forge package');
case 85:
_context8.next = 87;
return updatePackageScript('make', 'electron-forge make');
case 87:
d('forgified scripts object:', packageJSON.scripts);
writeChanges = function () {
var _ref4 = (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee3() {
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return (0, _oraHandler2.default)('Writing modified package.json file', (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee2() {
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return _fsExtra2.default.writeFile(_path2.default.resolve(dir, 'package.json'), (0, _stringify2.default)(packageJSON, null, 2) + '\n');
case 2:
case 'end':
return _context2.stop();
}
}
}, _callee2, undefined);
})));
case 2:
case 'end':
return _context3.stop();
}
}
}, _callee3, undefined);
}));
return function writeChanges() {
return _ref4.apply(this, arguments);
};
}();
electronVersion = void 0;
if (!electronName) {
_context8.next = 96;
break;
}
_context8.next = 93;
return (0, _readPackageJson2.default)(_path2.default.resolve(dir, 'node_modules', electronName));
case 93:
electronPackageJSON = _context8.sent;
electronVersion = electronPackageJSON.version;
packageJSON.devDependencies['electron-prebuilt-compile'] = electronVersion;
case 96:
_context8.next = 98;
return writeChanges();
case 98:
if (!electronName) {
_context8.next = 101;
break;
}
_context8.next = 101;
return (0, _oraHandler2.default)('Pruning deleted modules', (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee4() {
return _regenerator2.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
d('attempting to prune node_modules in:', dir);
_context4.next = 3;
return (0, _yarnOrNpm.yarnOrNpmSpawn)((0, _yarnOrNpm.hasYarn)() ? [] : ['prune'], {
cwd: dir,
stdio: 'ignore'
});
case 3:
case 'end':
return _context4.stop();
}
}
}, _callee4, undefined);
})));
case 101:
_context8.next = 103;
return (0, _oraHandler2.default)('Installing dependencies', (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee5() {
return _regenerator2.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
d('deleting old dependencies forcefully');
_context5.next = 3;
return _fsExtra2.default.remove(_path2.default.resolve(dir, 'node_modules/.bin/electron'));
case 3:
_context5.next = 5;
return _fsExtra2.default.remove(_path2.default.resolve(dir, 'node_modules/.bin/electron.cmd'));
case 5:
if (!electronName) {
_context5.next = 8;
break;
}
_context5.next = 8;
return _fsExtra2.default.remove(_path2.default.resolve(dir, 'node_modules', electronName));
case 8:
d('installing dependencies');
_context5.next = 11;
return (0, _installDependencies2.default)(dir, _initNpm.deps);
case 11:
d('installing devDependencies');
_context5.next = 14;
return (0, _installDependencies2.default)(dir, _initNpm.devDeps, true);
case 14:
d('installing exactDevDependencies');
_context5.next = 17;
return (0, _installDependencies2.default)(dir, _initNpm.exactDevDeps.map(function (dep) {
if (dep === 'electron-prebuild-compile') {
return dep + '@' + (electronVersion || 'latest');
}
return dep;
}), true, true);
case 17:
case 'end':
return _context5.stop();
}
}
}, _callee5, undefined);
})));
case 103:
_context8.next = 105;
return (0, _readPackageJson2.default)(dir);
case 105:
packageJSON = _context8.sent;
packageJSON.config = packageJSON.config || {};
_context8.next = 109;
return (0, _readPackageJson2.default)(_path2.default.resolve(__dirname, '../../tmpl'));
case 109:
templatePackageJSON = _context8.sent;
packageJSON.config.forge = templatePackageJSON.config.forge;
_context8.next = 113;
return writeChanges();
case 113:
_context8.next = 115;
return (0, _oraHandler2.default)('Fixing .gitignore', (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee6() {
var gitignore;
return _regenerator2.default.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
_context6.next = 2;
return _fsExtra2.default.pathExists(_path2.default.resolve(dir, '.gitignore'));
case 2:
if (!_context6.sent) {
_context6.next = 9;
break;
}
_context6.next = 5;
return _fsExtra2.default.readFile(_path2.default.resolve(dir, '.gitignore'));
case 5:
gitignore = _context6.sent;
if (gitignore.includes(outDir)) {
_context6.next = 9;
break;
}
_context6.next = 9;
return _fsExtra2.default.writeFile(_path2.default.resolve(dir, '.gitignore'), gitignore + '\n' + outDir + '/');
case 9:
case 'end':
return _context6.stop();
}
}
}, _callee6, undefined);
})));
case 115:
babelConfig = packageJSON.babel;
babelPath = _path2.default.resolve(dir, '.babelrc');
_context8.t2 = !babelConfig;
if (!_context8.t2) {
_context8.next = 122;
break;
}
_context8.next = 121;
return _fsExtra2.default.pathExists(babelPath);
case 121:
_context8.t2 = _context8.sent;
case 122:
if (!_context8.t2) {
_context8.next = 128;
break;
}
_context8.t3 = JSON;
_context8.next = 126;
return _fsExtra2.default.readFile(babelPath, 'utf8');
case 126:
_context8.t4 = _context8.sent;
babelConfig = _context8.t3.parse.call(_context8.t3, _context8.t4);
case 128:
if (!babelConfig) {
_context8.next = 132;
break;
}
_context8.next = 131;
return (0, _oraHandler2.default)('Porting original babel config', (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee7() {
var compileConfig, compilePath;
return _regenerator2.default.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
compileConfig = {};
compilePath = _path2.default.resolve(dir, '.compilerc');
_context7.next = 4;
return _fsExtra2.default.pathExists(compilePath);
case 4:
if (!_context7.sent) {
_context7.next = 10;
break;
}
_context7.t0 = JSON;
_context7.next = 8;
return _fsExtra2.default.readFile(compilePath, 'utf8');
case 8:
_context7.t1 = _context7.sent;
compileConfig = _context7.t0.parse.call(_context7.t0, _context7.t1);
case 10:
_context7.next = 12;
return _fsExtra2.default.writeFile(compilePath, (0, _stringify2.default)((0, _assign2.default)(compileConfig, {
'application/javascript': babelConfig
}), null, 2));
case 12:
case 'end':
return _context7.stop();
}
}
}, _callee7, undefined);
})));
case 131:
(0, _messages.info)(interactive, 'NOTE: You might be able to remove your `.compilerc` file completely if you are only using the `es2016` and `react` presets'.yellow);
case 132:
(0, _messages.info)(interactive, '\n\nWe have ATTEMPTED to convert your app to be in a format that electron-forge understands.\nNothing much will have changed but we added the ' + '"electron-prebuilt-compile"'.cyan + ' dependency. This is the dependency you must version bump to get newer versions of Electron.\n\n\nWe also tried to import any build tooling you already had but we can\'t get everything. You might need to convert any CLI/gulp/grunt tasks yourself.\n\nAlso please note if you are using `preload` scripts you need to follow the steps outlined at https://github.com/electron-userland/electron-forge/wiki/Using-%27preload%27-scripts\n\nThanks for using ' + '"electron-forge"'.green + '!!!');
case 133:
case 'end':
return _context8.stop();
}
}
}, _callee8, undefined, [[45, 66, 70, 78], [71,, 73, 77]]);
}));
return function () {
return _ref.apply(this, arguments);
};
}();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwaS9pbXBvcnQuanMiXSwibmFtZXMiOlsiZCIsInByb3ZpZGVkT3B0aW9ucyIsImRpciIsInByb2Nlc3MiLCJjd2QiLCJpbnRlcmFjdGl2ZSIsInVwZGF0ZVNjcmlwdHMiLCJvdXREaXIiLCJwYXRoRXhpc3RzIiwicmVzb2x2ZSIsImNvbmZpcm0iLCJleGl0IiwicGFja2FnZUpTT04iLCJjb25maWciLCJmb3JnZSIsImdyZWVuIiwic2hvdWxkQ29udGludWUiLCJzaG91bGRDaGFuZ2VNYWluIiwiY3JlYXRlUHJvbXB0TW9kdWxlIiwidHlwZSIsIm5hbWUiLCJkZWZhdWx0IiwibWFpbiIsIm1lc3NhZ2UiLCJuZXdNYWluIiwiZGVwZW5kZW5jaWVzIiwiZGV2RGVwZW5kZW5jaWVzIiwia2V5cyIsImNvbmNhdCIsImJ1aWxkVG9vbFBhY2thZ2VzIiwiZWxlY3Ryb25OYW1lIiwia2V5IiwiZXhwbGFuYXRpb24iLCJzaG91bGRSZW1vdmVEZXBlbmRlbmN5Iiwic2NyaXB0cyIsInVwZGF0ZVBhY2thZ2VTY3JpcHQiLCJzY3JpcHROYW1lIiwibmV3VmFsdWUiLCJzaG91bGRVcGRhdGUiLCJ3cml0ZUNoYW5nZXMiLCJ3cml0ZUZpbGUiLCJlbGVjdHJvblZlcnNpb24iLCJlbGVjdHJvblBhY2thZ2VKU09OIiwidmVyc2lvbiIsInN0ZGlvIiwicmVtb3ZlIiwibWFwIiwiZGVwIiwiX19kaXJuYW1lIiwidGVtcGxhdGVQYWNrYWdlSlNPTiIsInJlYWRGaWxlIiwiZ2l0aWdub3JlIiwiaW5jbHVkZXMiLCJiYWJlbENvbmZpZyIsImJhYmVsIiwiYmFiZWxQYXRoIiwiSlNPTiIsInBhcnNlIiwiY29tcGlsZUNvbmZpZyIsImNvbXBpbGVQYXRoIiwieWVsbG93IiwiY3lhbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUE7Ozs7QUFDQTs7QUFFQTs7OztBQUNBOztBQUNBOzs7O0FB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d0MsR0FFMUIsZUFBS2xELE9BQUwsQ0FBYVAsR0FBYixFQUFrQixZQUFsQixDQUYwQjtBQUFBO0FBQUEsNkJBR3BDLGtCQUFHTSxVQUFILENBQWNtRCxXQUFkLENBSG9DOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQUEscUNBSTVCSCxJQUo0QjtBQUFBO0FBQUEsNkJBSVgsa0JBQUdOLFFBQUgsQ0FBWVMsV0FBWixFQUF5QixNQUF6QixDQUpXOztBQUFBO0FBQUE7QUFJNUNELG1DQUo0QyxnQkFJdkJELEtBSnVCOztBQUFBO0FBQUE7QUFBQSw2QkFPeEMsa0JBQUdqQixTQUFILENBQWFtQixXQUFiLEVBQTBCLHlCQUFlLHNCQUFjRCxhQUFkLEVBQTZCO0FBQzFFLGtEQUEwQkw7QUFEZ0QsdUJBQTdCLENBQWYsRUFFNUIsSUFGNEIsRUFFdEIsQ0FGc0IsQ0FBMUIsQ0FQd0M7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsYUFBMUMsR0E3S0s7O0FBQUE7O0FBeUxYLGdDQUFLaEQsV0FBTCxFQUFrQiw2SEFBNkh1RCxNQUEvSTs7QUF6TFc7O0FBNExiLGdDQUFLdkQsV0FBTCxxSkFHZ0QsOEJBQThCd0QsSUFIOUUsMGNBWWlCLG1CQUFtQjlDLEtBWnBDOztBQTVMYTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxHIiwiZmlsZSI6ImFwaS9pbXBvcnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCBpbnF1aXJlciBmcm9tICdpbnF1aXJlcic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0IGluaXRHaXQgZnJvbSAnLi4vaW5pdC9pbml0LWdpdCc7XG5pbXBvcnQgeyBkZXBzLCBkZXZEZXBzLCBleGFjdERldkRlcHMgfSBmcm9tICcuLi9pbml0L2luaXQtbnBtJztcblxuaW1wb3J0IGFzeW5jT3JhIGZyb20gJy4uL3V0aWwvb3JhLWhhbmRsZXInO1xuaW1wb3J0IHsgaW5mbywgd2FybiB9IGZyb20gJy4uL3V0aWwvbWVzc2FnZXMnO1xuaW1wb3J0IGluc3RhbGxEZXBMaXN0IGZyb20gJy4uL3V0aWwvaW5zdGFsbC1kZXBlbmRlbmNpZXMnO1xuaW1wb3J0IHJlYWRQYWNrYWdlSlNPTiBmcm9tICcuLi91dGlsL3JlYWQtcGFja2FnZS1qc29uJztcbmltcG9ydCBjb25maXJtSWZJbnRlcmFjdGl2ZSBmcm9tICcuLi91dGlsL2NvbmZpcm0taWYtaW50ZXJhY3RpdmUnO1xuaW1wb3J0IHsgeWFybk9yTnBtU3Bhd24sIGhhc1lhcm4gfSBmcm9tICcuLi91dGlsL3lhcm4tb3ItbnBtJztcblxuY29uc3QgZCA9IGRlYnVnKCdlbGVjdHJvbi1mb3JnZTppbXBvcnQnKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBJbXBvcnRPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2Rpcj1wcm9jZXNzLmN3ZCgpXSBUaGUgcGF0aCB0byB0aGUgYXBwIHRvIGJlIGltcG9ydGVkXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtpbnRlcmFjdGl2ZT1mYWxzZV0gV2hldGhlciB0byB1c2Ugc2Vuc2libGUgZGVmYXVsdHMgb3IgcHJvbXB0IHRoZSB1c2VyIHZpc3VhbGx5XG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt1cGRhdGVTY3JpcHRzPXRydWVdIFdoZXRoZXIgdG8gdXBkYXRlIHRoZSBtb2R1bGVzIHBhY2thZ2UuanNvbiBzY3JpcHRzIHRvIGJlIGVsZWN0cm9uLWZvcmdlIGNvbW1hbmRzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW291dERpcj1gJHtkaXJ9L291dGBdIFRoZSBwYXRoIHRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyBnZW5lcmF0ZWQgZGlzdHJpYnV0YWJsZXNcbiAqL1xuXG4vKipcbiAqIEF0dGVtcHQgdG8gaW1wb3J0IGEgZ2l2ZW4gbW9kdWxlIGRpcmVjdG9yeSB0byB0aGUgRWxlY3Ryb24gRm9yZ2Ugc3RhbmRhcmQuXG4gKlxuICogLSBSZXBsYWNlcyB0aGUgcHJlYnVpbHQgZWxlY3Ryb24gcGFja2FnZSB3aXRoIHRoZSBvbmUgdGhhdCBpbnRlZ3JhdGVzIHdpdGggYGVsZWN0cm9uLWNvbXBpbGVgXG4gKiAtIFNldHMgdXAgYGdpdGAgYW5kIHRoZSBjb3JyZWN0IE5QTSBkZXBlbmRlbmNpZXNcbiAqIC0gQWRkcyBhIHRlbXBsYXRlIGZvcmdlIGNvbmZpZyB0byBgcGFja2FnZS5qc29uYFxuICpcbiAqIEBwYXJhbSB7SW1wb3J0T3B0aW9uc30gcHJvdmlkZWRPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIGltcG9ydCBtZXRob2RcbiAqIEByZXR1cm4ge1Byb21pc2V9IFdpbGwgcmVzb2x2ZSB3aGVuIHRoZSBpbXBvcnQgcHJvY2VzcyBpcyBjb21wbGV0ZVxuICovXG5leHBvcnQgZGVmYXVsdCBhc3luYyAocHJvdmlkZWRPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3QgeyBkaXIsIGludGVyYWN0aXZlLCB1cGRhdGVTY3JpcHRzIH0gPSBPYmplY3QuYXNzaWduKHtcbiAgICBkaXI6IHByb2Nlc3MuY3dkKCksXG4gICAgaW50ZXJhY3RpdmU6IGZhbHNlLFxuICAgIHVwZGF0ZVNjcmlwdHM6IHRydWUsXG4gIH0sIHByb3ZpZGVkT3B0aW9ucyk7XG5cbiAgY29uc3Qgb3V0RGlyID0gcHJvdmlkZWRPcHRpb25zLm91dERpciB8fCAnb3V0JztcbiAgYXN5bmNPcmEuaW50ZXJhY3RpdmUgPSBpbnRlcmFjdGl2ZTtcblxuICBkKGBBdHRlbXB0aW5nIHRvIGltcG9ydCBwcm9qZWN0IGluOiAke2Rpcn1gKTtcbiAgaWYgKCFhd2FpdCBmcy5wYXRoRXhpc3RzKGRpcikgfHwgIWF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5yZXNvbHZlKGRpciwgJ3BhY2thZ2UuanNvbicpKSkge1xuICAgIHRocm93IGBXZSBjb3VsZG4ndCBmaW5kIGEgcHJvamVjdCBpbjogJHtkaXJ9YDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gIGNvbnN0IGNvbmZpcm0gPSBhd2FpdCBjb25maXJtSWZJbnRlcmFjdGl2ZShpbnRlcmFjdGl2ZSwgYFdBUk5JTkc6IFdlIHdpbGwgbm93IGF0dGVtcHQgdG8gaW1wb3J0OiBcIiR7ZGlyfVwiLiAgVGhpcyB3aWxsIGludm9sdmUgbW9kaWZ5aW5nIHNvbWUgZmlsZXMsIGFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBjb250aW51ZT9gKTtcblxuICBpZiAoIWNvbmZpcm0pIHtcbiAgICBwcm9jZXNzLmV4aXQoMCk7XG4gIH1cblxuICBhd2FpdCBpbml0R2l0KGRpcik7XG5cbiAgbGV0IHBhY2thZ2VKU09OID0gYXdhaXQgcmVhZFBhY2thZ2VKU09OKGRpcik7XG4gIGlmIChwYWNrYWdlSlNPTi5jb25maWcgJiYgcGFja2FnZUpTT04uY29uZmlnLmZvcmdlKSB7XG4gICAgd2FybihpbnRlcmFjdGl2ZSwgJ0l0IGxvb2tzIGxpa2UgdGhpcyBwcm9qZWN0IGlzIGFscmVhZHkgY29uZmlndXJlZCBmb3IgXCJlbGVjdHJvbi1mb3JnZVwiJy5ncmVlbik7XG4gICAgY29uc3Qgc2hvdWxkQ29udGludWUgPSBhd2FpdCBjb25maXJtSWZJbnRlcmFjdGl2ZShpbnRlcmFjdGl2ZSwgJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBjb250aW51ZT8nKTtcblxuICAgIGlmICghc2hvdWxkQ29udGludWUpIHtcbiAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICB9XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICBjb25zdCBzaG91bGRDaGFuZ2VNYWluID0gYXdhaXQgY29uZmlybUlmSW50ZXJhY3RpdmUoaW50ZXJhY3RpdmUsICdEbyB5b3Ugd2FudCB1cyB0byBjaGFuZ2UgdGhlIFwibWFpblwiIGF0dHJpYnV0ZSBvZiB5b3VyIHBhY2thZ2UuanNvbj8gIElmIHlvdSBhcmUgY3VycmVudGx5IHVzaW5nIGJhYmVsIGFuZCBwb2ludGluZyB0byBhIFwiYnVpbGRcIiBkaXJlY3Rvcnkgc2F5IHllcy4nLCBmYWxzZSk7XG4gIGlmIChzaG91bGRDaGFuZ2VNYWluKSB7XG4gICAgY29uc3QgeyBuZXdNYWluIH0gPSBhd2FpdCBpbnF1aXJlci5jcmVhdGVQcm9tcHRNb2R1bGUoKSh7XG4gICAgICB0eXBlOiAnaW5wdXQnLFxuICAgICAgbmFtZTogJ25ld01haW4nLFxuICAgICAgZGVmYXVsdDogcGFja2FnZUpTT04ubWFpbixcbiAgICAgIG1lc3NhZ2U6ICdFbnRlciB0aGUgcmVsYXRpdmUgcGF0aCB0byB5b3VyIHVuY29tcGlsZWQgbWFpbiBmaWxlJyxcbiAgICB9KTtcbiAgICBwYWNrYWdlSlNPTi5tYWluID0gbmV3TWFpbjtcbiAgfVxuXG4gIHBhY2thZ2VKU09OLmRlcGVuZGVuY2llcyA9IHBhY2thZ2VKU09OLmRlcGVuZGVuY2llcyB8fCB7fTtcbiAgcGFja2FnZUpTT04uZGV2RGVwZW5kZW5jaWVzID0gcGFja2FnZUpTT04uZGV2RGVwZW5kZW5jaWVzIHx8IHt9O1xuXG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwYWNrYWdlSlNPTi5kZXBlbmRlbmNpZXMpLmNvbmNhdChPYmplY3Qua2V5cyhwYWNrYWdlSlNPTi5kZXZEZXBlbmRlbmNpZXMpKTtcbiAgY29uc3QgYnVpbGRUb29sUGFja2FnZXMgPSB7XG4gICAgJ2VsZWN0cm9uLWJ1aWxkZXInOiAncHJvdmlkZXMgbW9zdGx5IGVxdWl2YWxlbnQgZnVuY3Rpb25hbGl0eScsXG4gICAgJ2VsZWN0cm9uLWRvd25sb2FkJzogJ2FscmVhZHkgdXNlcyB0aGlzIG1vZHVsZSBhcyBhIHRyYW5zaXRpdmUgZGVwZW5kZW5jeScsXG4gICAgJ2VsZWN0cm9uLWluc3RhbGxlci1kZWJpYW4nOiAnYWxyZWFkeSB1c2VzIHRoaXMgbW9kdWxlIGFzIGEgdHJhbnNpdGl2ZSBkZXBlbmRlbmN5JyxcbiAgICAnZWxlY3Ryb24taW5zdGFsbGVyLWRtZyc6ICdhbHJlYWR5IHVzZXMgdGhpcyBtb2R1bGUgYXMgYSB0cmFuc2l0aXZlIGRlcGVuZGVuY3knLFxuICAgICdlbGVjdHJvbi1pbnN0YWxsZXItZmxhdHBhayc6ICdhbHJlYWR5IHVzZXMgdGhpcyBtb2R1bGUgYXMgYSB0cmFuc2l0aXZlIGRlcGVuZGVuY3knLFxuICAgICdlbGVjdHJvbi1pbnN0YWxsZXItcmVkaGF0JzogJ2FscmVhZHkgdXNlcyB0aGlzIG1vZHVsZSBhcyBhIHRyYW5zaXRpdmUgZGVwZW5kZW5jeScsXG4gICAgJ2VsZWN0cm9uLW9zeC1zaWduJzogJ2FscmVhZHkgdXNlcyB0aGlzIG1vZHVsZSBhcyBhIHRyYW5zaXRpdmUgZGVwZW5kZW5jeScsXG4gICAgJ2VsZWN0cm9uLXBhY2thZ2VyJzogJ2FscmVhZHkgdXNlcyB0aGlzIG1vZHVsZSBhcyBhIHRyYW5zaXRpdmUgZGVwZW5kZW5jeScsXG4gICAgJ2VsZWN0cm9uLXdpbnN0YWxsZXInOiAnYWxyZWFkeSB1c2VzIHRoaXMgbW9kdWxlIGFzIGEgdHJhbnNpdGl2ZSBkZXBlbmRlbmN5JyxcbiAgfTtcblxuICBsZXQgZWxlY3Ryb25OYW1lO1xuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgaWYgKGtleSA9PT0gJ2VsZWN0cm9uJyB8fCBrZXkgPT09ICdlbGVjdHJvbi1wcmVidWlsdCcpIHtcbiAgICAgIGRlbGV0ZSBwYWNrYWdlSlNPTi5kZXBlbmRlbmNpZXNba2V5XTtcbiAgICAgIGRlbGV0ZSBwYWNrYWdlSlNPTi5kZXZEZXBlbmRlbmNpZXNba2V5XTtcbiAgICAgIGVsZWN0cm9uTmFtZSA9IGtleTtcbiAgICB9IGVsc2UgaWYgKGJ1aWxkVG9vbFBhY2thZ2VzW2tleV0pIHtcbiAgICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gYnVpbGRUb29sUGFja2FnZXNba2V5XTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICBjb25zdCBzaG91bGRSZW1vdmVEZXBlbmRlbmN5ID0gYXdhaXQgY29uZmlybUlmSW50ZXJhY3RpdmUoaW50ZXJhY3RpdmUsIGBEbyB5b3Ugd2FudCB1cyB0byByZW1vdmUgdGhlIFwiJHtrZXl9XCIgZGVwZW5kZW5jeSBpbiBwYWNrYWdlLmpzb24/IEVsZWN0cm9uIEZvcmdlICR7ZXhwbGFuYXRpb259LmApO1xuXG4gICAgICBpZiAoc2hvdWxkUmVtb3ZlRGVwZW5kZW5jeSkge1xuICAgICAgICBkZWxldGUgcGFja2FnZUpTT04uZGVwZW5kZW5jaWVzW2tleV07XG4gICAgICAgIGRlbGV0ZSBwYWNrYWdlSlNPTi5kZXZEZXBlbmRlbmNpZXNba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYWNrYWdlSlNPTi5zY3JpcHRzID0gcGFja2FnZUpTT04uc2NyaXB0cyB8fCB7fTtcbiAgZCgncmVhZGluZyBjdXJyZW50IHNjcmlwdHMgb2JqZWN0OicsIHBhY2thZ2VKU09OLnNjcmlwdHMpO1xuXG4gIGNvbnN0IHVwZGF0ZVBhY2thZ2VTY3JpcHQgPSBhc3luYyAoc2NyaXB0TmFtZSwgbmV3VmFsdWUpID0+IHtcbiAgICBpZiAocGFja2FnZUpTT04uc2NyaXB0c1tzY3JpcHROYW1lXSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICBjb25zdCBzaG91bGRVcGRhdGUgPSBhd2FpdCBjb25maXJtSWZJbnRlcmFjdGl2ZShpbnRlcmFjdGl2ZSwgYERvIHlvdSB3YW50IHVzIHRvIHVwZGF0ZSB0aGUgXCIke3NjcmlwdE5hbWV9XCIgc2NyaXB0IHRvIGluc3RlYWQgY2FsbCB0aGUgZWxlY3Ryb24tZm9yZ2UgdGFzayBcIiR7bmV3VmFsdWV9XCJgLCB1cGRhdGVTY3JpcHRzKTtcbiAgICAgIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAgICAgcGFja2FnZUpTT04uc2NyaXB0c1tzY3JpcHROYW1lXSA9IG5ld1ZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBhd2FpdCB1cGRhdGVQYWNrYWdlU2NyaXB0KCdzdGFydCcsICdlbGVjdHJvbi1mb3JnZSBzdGFydCcpO1xuICBhd2FpdCB1cGRhdGVQYWNrYWdlU2NyaXB0KCdwYWNrYWdlJywgJ2VsZWN0cm9uLWZvcmdlIHBhY2thZ2UnKTtcbiAgYXdhaXQgdXBkYXRlUGFja2FnZVNjcmlwdCgnbWFrZScsICdlbGVjdHJvbi1mb3JnZSBtYWtlJyk7XG5cbiAgZCgnZm9yZ2lmaWVkIHNjcmlwdHMgb2JqZWN0OicsIHBhY2thZ2VKU09OLnNjcmlwdHMpO1xuXG4gIGNvbnN0IHdyaXRlQ2hhbmdlcyA9IGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBhc3luY09yYSgnV3JpdGluZyBtb2RpZmllZCBwYWNrYWdlLmpzb24gZmlsZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZShwYXRoLnJlc29sdmUoZGlyLCAncGFja2FnZS5qc29uJyksIGAke0pTT04uc3RyaW5naWZ5KHBhY2thZ2VKU09OLCBudWxsLCAyKX1cXG5gKTtcbiAgICB9KTtcbiAgfTtcblxuICBsZXQgZWxlY3Ryb25WZXJzaW9uO1xuICBpZiAoZWxlY3Ryb25OYW1lKSB7XG4gICAgY29uc3QgZWxlY3Ryb25QYWNrYWdlSlNPTiA9IGF3YWl0IHJlYWRQYWNrYWdlSlNPTihwYXRoLnJlc29sdmUoZGlyLCAnbm9kZV9tb2R1bGVzJywgZWxlY3Ryb25OYW1lKSk7XG4gICAgZWxlY3Ryb25WZXJzaW9uID0gZWxlY3Ryb25QYWNrYWdlSlNPTi52ZXJzaW9uO1xuICAgIHBhY2thZ2VKU09OLmRldkRlcGVuZGVuY2llc1snZWxlY3Ryb24tcHJlYnVpbHQtY29tcGlsZSddID0gZWxlY3Ryb25WZXJzaW9uO1xuICB9XG5cbiAgYXdhaXQgd3JpdGVDaGFuZ2VzKCk7XG5cbiAgaWYgKGVsZWN0cm9uTmFtZSkge1xuICAgIGF3YWl0IGFzeW5jT3JhKCdQcnVuaW5nIGRlbGV0ZWQgbW9kdWxlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGQoJ2F0dGVtcHRpbmcgdG8gcHJ1bmUgbm9kZV9tb2R1bGVzIGluOicsIGRpcik7XG4gICAgICBhd2FpdCB5YXJuT3JOcG1TcGF3bihoYXNZYXJuKCkgPyBbXSA6IFsncHJ1bmUnXSwge1xuICAgICAgICBjd2Q6IGRpcixcbiAgICAgICAgc3RkaW86ICdpZ25vcmUnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBhd2FpdCBhc3luY09yYSgnSW5zdGFsbGluZyBkZXBlbmRlbmNpZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgZCgnZGVsZXRpbmcgb2xkIGRlcGVuZGVuY2llcyBmb3JjZWZ1bGx5Jyk7XG4gICAgYXdhaXQgZnMucmVtb3ZlKHBhdGgucmVzb2x2ZShkaXIsICdub2RlX21vZHVsZXMvLmJpbi9lbGVjdHJvbicpKTtcbiAgICBhd2FpdCBmcy5yZW1vdmUocGF0aC5yZXNvbHZlKGRpciwgJ25vZGVfbW9kdWxlcy8uYmluL2VsZWN0cm9uLmNtZCcpKTtcblxuICAgIGlmIChlbGVjdHJvbk5hbWUpIHtcbiAgICAgIGF3YWl0IGZzLnJlbW92ZShwYXRoLnJlc29sdmUoZGlyLCAnbm9kZV9tb2R1bGVzJywgZWxlY3Ryb25OYW1lKSk7XG4gICAgfVxuXG4gICAgZCgnaW5zdGFsbGluZyBkZXBlbmRlbmNpZXMnKTtcbiAgICBhd2FpdCBpbnN0YWxsRGVwTGlzdChkaXIsIGRlcHMpO1xuXG4gICAgZCgnaW5zdGFsbGluZyBkZXZEZXBlbmRlbmNpZXMnKTtcbiAgICBhd2FpdCBpbnN0YWxsRGVwTGlzdChkaXIsIGRldkRlcHMsIHRydWUpO1xuXG4gICAgZCgnaW5zdGFsbGluZyBleGFjdERldkRlcGVuZGVuY2llcycpO1xuICAgIGF3YWl0IGluc3RhbGxEZXBMaXN0KGRpciwgZXhhY3REZXZEZXBzLm1hcCgoZGVwKSA9PiB7XG4gICAgICBpZiAoZGVwID09PSAnZWxlY3Ryb24tcHJlYnVpbGQtY29tcGlsZScpIHtcbiAgICAgICAgcmV0dXJuIGAke2RlcH1AJHtlbGVjdHJvblZlcnNpb24gfHwgJ2xhdGVzdCd9YDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGRlcDtcbiAgICB9KSwgdHJ1ZSwgdHJ1ZSk7XG4gIH0pO1xuXG4gIHBhY2thZ2VKU09OID0gYXdhaXQgcmVhZFBhY2thZ2VKU09OKGRpcik7XG5cbiAgcGFja2FnZUpTT04uY29uZmlnID0gcGFja2FnZUpTT04uY29uZmlnIHx8IHt9O1xuICBjb25zdCB0ZW1wbGF0ZVBhY2thZ2VKU09OID0gYXdhaXQgcmVhZFBhY2thZ2VKU09OKHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi8uLi90bXBsJykpO1xuICBwYWNrYWdlSlNPTi5jb25maWcuZm9yZ2UgPSB0ZW1wbGF0ZVBhY2thZ2VKU09OLmNvbmZpZy5mb3JnZTtcblxuICBhd2FpdCB3cml0ZUNoYW5nZXMoKTtcblxuICBhd2FpdCBhc3luY09yYSgnRml4aW5nIC5naXRpZ25vcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgaWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5yZXNvbHZlKGRpciwgJy5naXRpZ25vcmUnKSkpIHtcbiAgICAgIGNvbnN0IGdpdGlnbm9yZSA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGgucmVzb2x2ZShkaXIsICcuZ2l0aWdub3JlJykpO1xuICAgICAgaWYgKCFnaXRpZ25vcmUuaW5jbHVkZXMob3V0RGlyKSkge1xuICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUocGF0aC5yZXNvbHZlKGRpciwgJy5naXRpZ25vcmUnKSwgYCR7Z2l0aWdub3JlfVxcbiR7b3V0RGlyfS9gKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGxldCBiYWJlbENvbmZpZyA9IHBhY2thZ2VKU09OLmJhYmVsO1xuICBjb25zdCBiYWJlbFBhdGggPSBwYXRoLnJlc29sdmUoZGlyLCAnLmJhYmVscmMnKTtcbiAgaWYgKCFiYWJlbENvbmZpZyAmJiBhd2FpdCBmcy5wYXRoRXhpc3RzKGJhYmVsUGF0aCkpIHtcbiAgICBiYWJlbENvbmZpZyA9IEpTT04ucGFyc2UoYXdhaXQgZnMucmVhZEZpbGUoYmFiZWxQYXRoLCAndXRmOCcpKTtcbiAgfVxuXG4gIGlmIChiYWJlbENvbmZpZykge1xuICAgIGF3YWl0IGFzeW5jT3JhKCdQb3J0aW5nIG9yaWdpbmFsIGJhYmVsIGNvbmZpZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBjb21waWxlQ29uZmlnID0ge307XG4gICAgICBjb25zdCBjb21waWxlUGF0aCA9IHBhdGgucmVzb2x2ZShkaXIsICcuY29tcGlsZXJjJyk7XG4gICAgICBpZiAoYXdhaXQgZnMucGF0aEV4aXN0cyhjb21waWxlUGF0aCkpIHtcbiAgICAgICAgY29tcGlsZUNvbmZpZyA9IEpTT04ucGFyc2UoYXdhaXQgZnMucmVhZEZpbGUoY29tcGlsZVBhdGgsICd1dGY4JykpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUoY29tcGlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KE9iamVjdC5hc3NpZ24oY29tcGlsZUNvbmZpZywge1xuICAgICAgICAnYXBwbGljYXRpb24vamF2YXNjcmlwdCc6IGJhYmVsQ29uZmlnLFxuICAgICAgfSksIG51bGwsIDIpKTtcbiAgICB9KTtcblxuICAgIGluZm8oaW50ZXJhY3RpdmUsICdOT1RFOiBZb3UgbWlnaHQgYmUgYWJsZSB0byByZW1vdmUgeW91ciBgLmNvbXBpbGVyY2AgZmlsZSBjb21wbGV0ZWx5IGlmIHlvdSBhcmUgb25seSB1c2luZyB0aGUgYGVzMjAxNmAgYW5kIGByZWFjdGAgcHJlc2V0cycueWVsbG93KTtcbiAgfVxuXG4gIGluZm8oaW50ZXJhY3RpdmUsIGBcblxuV2UgaGF2ZSBBVFRFTVBURUQgdG8gY29udmVydCB5b3VyIGFwcCB0byBiZSBpbiBhIGZvcm1hdCB0aGF0IGVsZWN0cm9uLWZvcmdlIHVuZGVyc3RhbmRzLlxuTm90aGluZyBtdWNoIHdpbGwgaGF2ZSBjaGFuZ2VkIGJ1dCB3ZSBhZGRlZCB0aGUgJHsnXCJlbGVjdHJvbi1wcmVidWlsdC1jb21waWxlXCInLmN5YW59IGRlcGVuZGVuY3kuICBUaGlzIGlzIFxcXG50aGUgZGVwZW5kZW5jeSB5b3UgbXVzdCB2ZXJzaW9uIGJ1bXAgdG8gZ2V0IG5ld2VyIHZlcnNpb25zIG9mIEVsZWN0cm9uLlxuXG5cbldlIGFsc28gdHJpZWQgdG8gaW1wb3J0IGFueSBidWlsZCB0b29saW5nIHlvdSBhbHJlYWR5IGhhZCBidXQgd2UgY2FuJ3QgZ2V0IGV2ZXJ5dGhpbmcuICBZb3UgbWlnaHQgbmVlZCB0byBjb252ZXJ0IGFueSBDTEkvZ3VscC9ncnVudCB0YXNrcyB5b3Vyc2VsZi5cblxuQWxzbyBwbGVhc2Ugbm90ZSBpZiB5b3UgYXJlIHVzaW5nIFxcYHByZWxvYWRcXGAgc2NyaXB0cyB5b3UgbmVlZCB0byBmb2xsb3cgdGhlIHN0ZXBzIG91dGxpbmVkIFxcXG5hdCBodHRwczovL2dpdGh1Yi5jb20vZWxlY3Ryb24tdXNlcmxhbmQvZWxlY3Ryb24tZm9yZ2Uvd2lraS9Vc2luZy0lMjdwcmVsb2FkJTI3LXNjcmlwdHNcblxuVGhhbmtzIGZvciB1c2luZyAkeydcImVsZWN0cm9uLWZvcmdlXCInLmdyZWVufSEhIWApO1xufTtcbiJdfQ==