UNPKG

appium-doctor

Version:

Test environment for fitness to run Appium

279 lines (190 loc) 23.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.FixSkippedError = exports.DoctorCheck = exports.Doctor = void 0; require("source-map-support/register"); require("@colors/colors"); var _lodash = _interopRequireDefault(require("lodash")); var _logger = _interopRequireDefault(require("./logger")); var _package = require("../../package.json"); class FixSkippedError extends Error {} exports.FixSkippedError = FixSkippedError; class DoctorCheck { constructor(opts = {}) { this.autofix = !!opts.autofix; } diagnose() { throw new Error('Not Implemented!'); } fix() { throw new Error('Not Implemented!'); } } exports.DoctorCheck = DoctorCheck; class Doctor { constructor() { this.checks = []; this.checkOptionals = []; this.toFix = []; this.toFixOptionals = []; } register(checks) { checks = Array.isArray(checks) ? checks : [checks]; this.checks = this.checks.concat(checks); } async diagnose() { _logger.default.info(`### Diagnostic for ${'necessary'.green} dependencies starting ###`); this.toFix = []; for (const check of this.checks) { const res = await check.diagnose(); if (res.optional) { this.checkOptionals.push(check); continue; } await this.diagnosticResultMessage(res, this.toFix, check); } _logger.default.info(`### Diagnostic for necessary dependencies completed, ${await this.fixMessage(this.toFix.length)}. ###`); _logger.default.info(''); _logger.default.info(`### Diagnostic for ${'optional'.yellow} dependencies starting ###`); this.toFixOptionals = []; for (const checkOptional of this.checkOptionals) { await this.diagnosticResultMessage(await checkOptional.diagnose(), this.toFixOptionals, checkOptional); } _logger.default.info(`### Diagnostic for optional dependencies completed, ${await this.fixMessage(this.toFixOptionals.length, true)}. ###`); _logger.default.info(''); } async reportManualFixes(fix, fixOptioal) { const manualFixes = _lodash.default.filter(fix, f => { var _f$check; return !(f !== null && f !== void 0 && (_f$check = f.check) !== null && _f$check !== void 0 && _f$check.autofix); }); const manualFixesOptional = _lodash.default.filter(fixOptioal, f => { var _f$check2; return !(f !== null && f !== void 0 && (_f$check2 = f.check) !== null && _f$check2 !== void 0 && _f$check2.autofix); }); if (manualFixes.length > 0) { _logger.default.info('### Manual Fixes Needed ###'); _logger.default.info('The configuration cannot be automatically fixed, please do the following first:'); const fixMessages = []; for (const f of manualFixes) { fixMessages.push(await f.check.fix()); } for (const m of _lodash.default.uniq(fixMessages)) { _logger.default.warn(` \u279C ${m}`); } _logger.default.info(''); } if (manualFixesOptional.length > 0) { _logger.default.info('### Optional Manual Fixes ###'); _logger.default.info('The configuration can install optionally. Please do the following manually:'); const fixMessages = []; for (const f of manualFixesOptional) { fixMessages.push(await f.check.fix()); } for (const m of _lodash.default.uniq(fixMessages)) { _logger.default.warn(` \u279C ${m}`); } _logger.default.info(''); } if (manualFixes.length > 0 || manualFixesOptional.length > 0) { _logger.default.info('###'); _logger.default.info(''); _logger.default.info('Bye! Run appium-doctor again when all manual fixes have been applied!'); _logger.default.info(''); return true; } return false; } async runAutoFix(f) { _logger.default.info(`### Fixing: ${f.error} ###`); try { await f.check.fix(); } catch (err) { if (err instanceof FixSkippedError) { _logger.default.info(`### Skipped fix ###`); return; } else { _logger.default.warn(`${err}`.replace(/\n$/g, '')); _logger.default.info(`### Fix did not succeed ###`); return; } } _logger.default.info('Checking if this was fixed:'); let res = await f.check.diagnose(); if (res.ok) { f.fixed = true; _logger.default.info(` ${'\u2714'.green} ${res.message}`); _logger.default.info(`### Fix was successfully applied ###`); } else { _logger.default.info(` ${'\u2716'.red} ${res.message}`); _logger.default.info(`### Fix was applied but issue remains ###`); } } async runAutoFixes() { let autoFixes = _lodash.default.filter(this.toFix, f => { var _f$check3; return f === null || f === void 0 ? void 0 : (_f$check3 = f.check) === null || _f$check3 === void 0 ? void 0 : _f$check3.autofix; }); for (let f of autoFixes) { await this.runAutoFix(f); _logger.default.info(''); } if (_lodash.default.find(autoFixes, f => !f.fixed)) { _logger.default.info('Bye! A few issues remain, fix manually and/or rerun appium-doctor!'); } else { _logger.default.info('Bye! All issues have been fixed!'); } _logger.default.info(''); } async run() { _logger.default.warn('[Deprecated] Please use appium-doctor installed with "npm install @appium/doctor --location=global"'); _logger.default.info(`Appium Doctor v.${_package.version}`); await this.diagnose(); if (await this.reportSuccess(this.toFix.length, this.toFixOptionals.length)) { return; } if (await this.reportManualFixes(this.toFix, this.toFixOptionals)) { return; } await this.runAutoFixes(); } async diagnosticResultMessage(result, toFixList, check) { if (result.ok) { _logger.default.info(` ${'\u2714'.green} ${result.message}`); } else { const errorMessage = result.optional ? ` ${'\u2716'.yellow} ${result.message}` : ` ${'\u2716'.red} ${result.message}`; _logger.default.warn(errorMessage); toFixList.push({ error: errorMessage, check }); } } async fixMessage(length, optional = false) { let message; switch (length) { case 0: message = 'no fix'; break; case 1: message = 'one fix'; break; default: message = `${length} fixes`; } return `${message} ${optional ? 'possible' : 'needed'}`; } async reportSuccess(length, lengthOptional) { if (length === 0 && lengthOptional === 0) { _logger.default.info('Everything looks good, bye!'); _logger.default.info(''); return true; } else { return false; } } } exports.Doctor = Doctor;require('source-map-support').install(); //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliL2RvY3Rvci5qcyIsIm5hbWVzIjpbIkZpeFNraXBwZWRFcnJvciIsIkVycm9yIiwiRG9jdG9yQ2hlY2siLCJjb25zdHJ1Y3RvciIsIm9wdHMiLCJhdXRvZml4IiwiZGlhZ25vc2UiLCJmaXgiLCJEb2N0b3IiLCJjaGVja3MiLCJjaGVja09wdGlvbmFscyIsInRvRml4IiwidG9GaXhPcHRpb25hbHMiLCJyZWdpc3RlciIsIkFycmF5IiwiaXNBcnJheSIsImNvbmNhdCIsImxvZyIsImluZm8iLCJncmVlbiIsImNoZWNrIiwicmVzIiwib3B0aW9uYWwiLCJwdXNoIiwiZGlhZ25vc3RpY1Jlc3VsdE1lc3NhZ2UiLCJmaXhNZXNzYWdlIiwibGVuZ3RoIiwieWVsbG93IiwiY2hlY2tPcHRpb25hbCIsInJlcG9ydE1hbnVhbEZpeGVzIiwiZml4T3B0aW9hbCIsIm1hbnVhbEZpeGVzIiwiXyIsImZpbHRlciIsImYiLCJtYW51YWxGaXhlc09wdGlvbmFsIiwiZml4TWVzc2FnZXMiLCJtIiwidW5pcSIsIndhcm4iLCJydW5BdXRvRml4IiwiZXJyb3IiLCJlcnIiLCJyZXBsYWNlIiwib2siLCJmaXhlZCIsIm1lc3NhZ2UiLCJyZWQiLCJydW5BdXRvRml4ZXMiLCJhdXRvRml4ZXMiLCJmaW5kIiwicnVuIiwidmVyc2lvbiIsInJlcG9ydFN1Y2Nlc3MiLCJyZXN1bHQiLCJ0b0ZpeExpc3QiLCJlcnJvck1lc3NhZ2UiLCJsZW5ndGhPcHRpb25hbCJdLCJzb3VyY2VSb290IjoiLi4vLi4iLCJzb3VyY2VzIjpbImxpYi9kb2N0b3IuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdAY29sb3JzL2NvbG9ycyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi4vLi4vcGFja2FnZS5qc29uJzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBpbXBvcnQvbm8tdW5yZXNvbHZlZFxuXG5cbmNsYXNzIEZpeFNraXBwZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cblxuY2xhc3MgRG9jdG9yQ2hlY2sge1xuICBjb25zdHJ1Y3RvciAob3B0cyA9IHt9KSB7XG4gICAgdGhpcy5hdXRvZml4ID0gISFvcHRzLmF1dG9maXg7XG4gIH1cblxuICBkaWFnbm9zZSAoKSB7IHRocm93IG5ldyBFcnJvcignTm90IEltcGxlbWVudGVkIScpOyB9XG5cbiAgZml4ICgpIHtcbiAgICAvLyByZXR1cm4gc3RyaW5nIGZvciBtYW51YWwgZml4ZXMuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgSW1wbGVtZW50ZWQhJyk7XG4gIH1cbn1cblxuY2xhc3MgRG9jdG9yIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHRoaXMuY2hlY2tzID0gW107XG4gICAgdGhpcy5jaGVja09wdGlvbmFscyA9IFtdO1xuICAgIHRoaXMudG9GaXggPSBbXTtcbiAgICB0aGlzLnRvRml4T3B0aW9uYWxzID0gW107XG4gIH1cblxuICByZWdpc3RlciAoY2hlY2tzKSB7XG4gICAgY2hlY2tzID0gQXJyYXkuaXNBcnJheShjaGVja3MpID8gY2hlY2tzIDogW2NoZWNrc107XG4gICAgdGhpcy5jaGVja3MgPSB0aGlzLmNoZWNrcy5jb25jYXQoY2hlY2tzKTtcbiAgfVxuXG4gIGFzeW5jIGRpYWdub3NlICgpIHtcbiAgICBsb2cuaW5mbyhgIyMjIERpYWdub3N0aWMgZm9yICR7J25lY2Vzc2FyeScuZ3JlZW59IGRlcGVuZGVuY2llcyBzdGFydGluZyAjIyNgKTtcbiAgICB0aGlzLnRvRml4ID0gW107XG4gICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLmNoZWNrcykge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgY2hlY2suZGlhZ25vc2UoKTtcbiAgICAgIGlmIChyZXMub3B0aW9uYWwpIHtcbiAgICAgICAgdGhpcy5jaGVja09wdGlvbmFscy5wdXNoKGNoZWNrKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmRpYWdub3N0aWNSZXN1bHRNZXNzYWdlKHJlcywgdGhpcy50b0ZpeCwgY2hlY2spO1xuICAgIH1cbiAgICBsb2cuaW5mbyhgIyMjIERpYWdub3N0aWMgZm9yIG5lY2Vzc2FyeSBkZXBlbmRlbmNpZXMgY29tcGxldGVkLCAke2F3YWl0IHRoaXMuZml4TWVzc2FnZSh0aGlzLnRvRml4Lmxlbmd0aCl9LiAjIyNgKTtcbiAgICBsb2cuaW5mbygnJyk7XG5cbiAgICBsb2cuaW5mbyhgIyMjIERpYWdub3N0aWMgZm9yICR7J29wdGlvbmFsJy55ZWxsb3d9IGRlcGVuZGVuY2llcyBzdGFydGluZyAjIyNgKTtcbiAgICB0aGlzLnRvRml4T3B0aW9uYWxzID0gW107XG4gICAgZm9yIChjb25zdCBjaGVja09wdGlvbmFsIG9mIHRoaXMuY2hlY2tPcHRpb25hbHMpIHtcbiAgICAgIGF3YWl0IHRoaXMuZGlhZ25vc3RpY1Jlc3VsdE1lc3NhZ2UoYXdhaXQgY2hlY2tPcHRpb25hbC5kaWFnbm9zZSgpLCB0aGlzLnRvRml4T3B0aW9uYWxzLCBjaGVja09wdGlvbmFsKTtcbiAgICB9XG4gICAgbG9nLmluZm8oYCMjIyBEaWFnbm9zdGljIGZvciBvcHRpb25hbCBkZXBlbmRlbmNpZXMgY29tcGxldGVkLCAke2F3YWl0IHRoaXMuZml4TWVzc2FnZSh0aGlzLnRvRml4T3B0aW9uYWxzLmxlbmd0aCwgdHJ1ZSl9LiAjIyNgKTtcbiAgICBsb2cuaW5mbygnJyk7XG4gIH1cblxuICBhc3luYyByZXBvcnRNYW51YWxGaXhlcyAoZml4LCBmaXhPcHRpb2FsKSB7XG4gICAgY29uc3QgbWFudWFsRml4ZXMgPSBfLmZpbHRlcihmaXgsIChmKSA9PiAhZj8uY2hlY2s/LmF1dG9maXgpO1xuICAgIGNvbnN0IG1hbnVhbEZpeGVzT3B0aW9uYWwgPSBfLmZpbHRlcihmaXhPcHRpb2FsLCAoZikgPT4gIWY/LmNoZWNrPy5hdXRvZml4KTtcblxuICAgIGlmIChtYW51YWxGaXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICBsb2cuaW5mbygnIyMjIE1hbnVhbCBGaXhlcyBOZWVkZWQgIyMjJyk7XG4gICAgICBsb2cuaW5mbygnVGhlIGNvbmZpZ3VyYXRpb24gY2Fubm90IGJlIGF1dG9tYXRpY2FsbHkgZml4ZWQsIHBsZWFzZSBkbyB0aGUgZm9sbG93aW5nIGZpcnN0OicpO1xuICAgICAgLy8gZm9yIG1hbnVhbCBmaXhlcywgdGhlIGZpeCBtZXRob2QgYWx3YXlzIHJldHVybiBhIHN0cmluZ1xuICAgICAgY29uc3QgZml4TWVzc2FnZXMgPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZiBvZiBtYW51YWxGaXhlcykge1xuICAgICAgICBmaXhNZXNzYWdlcy5wdXNoKGF3YWl0IGYuY2hlY2suZml4KCkpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBtIG9mIF8udW5pcShmaXhNZXNzYWdlcykpIHtcbiAgICAgICAgbG9nLndhcm4oYCBcXHUyNzlDICR7bX1gKTtcbiAgICAgIH1cbiAgICAgIGxvZy5pbmZvKCcnKTtcbiAgICB9XG4gICAgaWYgKG1hbnVhbEZpeGVzT3B0aW9uYWwubGVuZ3RoID4gMCkge1xuICAgICAgbG9nLmluZm8oJyMjIyBPcHRpb25hbCBNYW51YWwgRml4ZXMgIyMjJyk7XG4gICAgICBsb2cuaW5mbygnVGhlIGNvbmZpZ3VyYXRpb24gY2FuIGluc3RhbGwgb3B0aW9uYWxseS4gUGxlYXNlIGRvIHRoZSBmb2xsb3dpbmcgbWFudWFsbHk6Jyk7XG4gICAgICAvLyBmb3IgbWFudWFsIGZpeGVzLCB0aGUgZml4IG1ldGhvZCBhbHdheXMgcmV0dXJuIGEgc3RyaW5nXG4gICAgICBjb25zdCBmaXhNZXNzYWdlcyA9IFtdO1xuICAgICAgZm9yIChjb25zdCBmIG9mIG1hbnVhbEZpeGVzT3B0aW9uYWwpIHtcbiAgICAgICAgZml4TWVzc2FnZXMucHVzaChhd2FpdCBmLmNoZWNrLmZpeCgpKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgbSBvZiBfLnVuaXEoZml4TWVzc2FnZXMpKSB7XG4gICAgICAgIGxvZy53YXJuKGAgXFx1Mjc5QyAke219YCk7XG4gICAgICB9XG4gICAgICBsb2cuaW5mbygnJyk7XG4gICAgfVxuXG4gICAgaWYgKG1hbnVhbEZpeGVzLmxlbmd0aCA+IDAgfHwgbWFudWFsRml4ZXNPcHRpb25hbC5sZW5ndGggPiAwKSB7XG4gICAgICBsb2cuaW5mbygnIyMjJyk7XG4gICAgICBsb2cuaW5mbygnJyk7XG4gICAgICBsb2cuaW5mbygnQnllISBSdW4gYXBwaXVtLWRvY3RvciBhZ2FpbiB3aGVuIGFsbCBtYW51YWwgZml4ZXMgaGF2ZSBiZWVuIGFwcGxpZWQhJyk7XG4gICAgICBsb2cuaW5mbygnJyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgcnVuQXV0b0ZpeCAoZikge1xuICAgIGxvZy5pbmZvKGAjIyMgRml4aW5nOiAke2YuZXJyb3J9ICMjI2ApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmLmNoZWNrLmZpeCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEZpeFNraXBwZWRFcnJvcikge1xuICAgICAgICBsb2cuaW5mbyhgIyMjIFNraXBwZWQgZml4ICMjI2ApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2cud2FybihgJHtlcnJ9YC5yZXBsYWNlKC9cXG4kL2csICcnKSk7XG4gICAgICAgIGxvZy5pbmZvKGAjIyMgRml4IGRpZCBub3Qgc3VjY2VlZCAjIyNgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBsb2cuaW5mbygnQ2hlY2tpbmcgaWYgdGhpcyB3YXMgZml4ZWQ6Jyk7XG4gICAgbGV0IHJlcyA9IGF3YWl0IGYuY2hlY2suZGlhZ25vc2UoKTtcbiAgICBpZiAocmVzLm9rKSB7XG4gICAgICBmLmZpeGVkID0gdHJ1ZTtcbiAgICAgIGxvZy5pbmZvKGAgJHsnXFx1MjcxNCcuZ3JlZW59ICR7cmVzLm1lc3NhZ2V9YCk7XG4gICAgICBsb2cuaW5mbyhgIyMjIEZpeCB3YXMgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgIyMjYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZy5pbmZvKGAgJHsnXFx1MjcxNicucmVkfSAke3Jlcy5tZXNzYWdlfWApO1xuICAgICAgbG9nLmluZm8oYCMjIyBGaXggd2FzIGFwcGxpZWQgYnV0IGlzc3VlIHJlbWFpbnMgIyMjYCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcnVuQXV0b0ZpeGVzICgpIHtcbiAgICBsZXQgYXV0b0ZpeGVzID0gXy5maWx0ZXIodGhpcy50b0ZpeCwgKGYpID0+IGY/LmNoZWNrPy5hdXRvZml4KTtcbiAgICBmb3IgKGxldCBmIG9mIGF1dG9GaXhlcykge1xuICAgICAgYXdhaXQgdGhpcy5ydW5BdXRvRml4KGYpO1xuICAgICAgbG9nLmluZm8oJycpO1xuICAgIH1cbiAgICBpZiAoXy5maW5kKGF1dG9GaXhlcywgKGYpID0+ICFmLmZpeGVkKSkge1xuICAgICAgLy8gYSBmZXcgaXNzdWVzIHJlbWFpbi5cbiAgICAgIGxvZy5pbmZvKCdCeWUhIEEgZmV3IGlzc3VlcyByZW1haW4sIGZpeCBtYW51YWxseSBhbmQvb3IgcmVydW4gYXBwaXVtLWRvY3RvciEnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbm90aGluZyBsZWZ0IHRvIGZpeC5cbiAgICAgIGxvZy5pbmZvKCdCeWUhIEFsbCBpc3N1ZXMgaGF2ZSBiZWVuIGZpeGVkIScpO1xuICAgIH1cbiAgICBsb2cuaW5mbygnJyk7XG4gIH1cblxuICBhc3luYyBydW4gKCkge1xuICAgIGxvZy53YXJuKCdbRGVwcmVjYXRlZF0gUGxlYXNlIHVzZSBhcHBpdW0tZG9jdG9yIGluc3RhbGxlZCB3aXRoIFwibnBtIGluc3RhbGwgQGFwcGl1bS9kb2N0b3IgLS1sb2NhdGlvbj1nbG9iYWxcIicpO1xuICAgIGxvZy5pbmZvKGBBcHBpdW0gRG9jdG9yIHYuJHt2ZXJzaW9ufWApO1xuICAgIGF3YWl0IHRoaXMuZGlhZ25vc2UoKTtcbiAgICBpZiAoYXdhaXQgdGhpcy5yZXBvcnRTdWNjZXNzKHRoaXMudG9GaXgubGVuZ3RoLCB0aGlzLnRvRml4T3B0aW9uYWxzLmxlbmd0aCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGF3YWl0IHRoaXMucmVwb3J0TWFudWFsRml4ZXModGhpcy50b0ZpeCwgdGhpcy50b0ZpeE9wdGlvbmFscykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5ydW5BdXRvRml4ZXMoKTtcbiAgfVxuXG4gIC8vLy8gZ2VuZXJhdGluZyBtZXNzYWdlc1xuICBhc3luYyBkaWFnbm9zdGljUmVzdWx0TWVzc2FnZSAocmVzdWx0LCB0b0ZpeExpc3QsIGNoZWNrKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgIGlmIChyZXN1bHQub2spIHtcbiAgICAgIGxvZy5pbmZvKGAgJHsnXFx1MjcxNCcuZ3JlZW59ICR7cmVzdWx0Lm1lc3NhZ2V9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IHJlc3VsdC5vcHRpb25hbCA/IGAgJHsnXFx1MjcxNicueWVsbG93fSAke3Jlc3VsdC5tZXNzYWdlfWAgOiBgICR7J1xcdTI3MTYnLnJlZH0gJHtyZXN1bHQubWVzc2FnZX1gO1xuICAgICAgbG9nLndhcm4oZXJyb3JNZXNzYWdlKTtcbiAgICAgIHRvRml4TGlzdC5wdXNoKHtcbiAgICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZSxcbiAgICAgICAgY2hlY2tcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZpeE1lc3NhZ2UgKGxlbmd0aCwgb3B0aW9uYWwgPSBmYWxzZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlcXVpcmUtYXdhaXRcbiAgICBsZXQgbWVzc2FnZTtcbiAgICBzd2l0Y2ggKGxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICBtZXNzYWdlID0gJ25vIGZpeCc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICBtZXNzYWdlID0gJ29uZSBmaXgnO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG1lc3NhZ2UgPSBgJHtsZW5ndGh9IGZpeGVzYDtcbiAgICB9XG4gICAgcmV0dXJuIGAke21lc3NhZ2V9ICR7b3B0aW9uYWwgPyAncG9zc2libGUnIDogJ25lZWRlZCd9YDtcbiAgfVxuXG4gIGFzeW5jIHJlcG9ydFN1Y2Nlc3MgKGxlbmd0aCwgbGVuZ3RoT3B0aW9uYWwpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgaWYgKGxlbmd0aCA9PT0gMCAmJiBsZW5ndGhPcHRpb25hbCA9PT0gMCkge1xuICAgICAgbG9nLmluZm8oJ0V2ZXJ5dGhpbmcgbG9va3MgZ29vZCwgYnllIScpO1xuICAgICAgbG9nLmluZm8oJycpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHsgRG9jdG9yLCBEb2N0b3JDaGVjaywgRml4U2tpcHBlZEVycm9yIH07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsTUFBTUEsZUFBTixTQUE4QkMsS0FBOUIsQ0FBb0M7Ozs7QUFHcEMsTUFBTUMsV0FBTixDQUFrQjtFQUNoQkMsV0FBVyxDQUFFQyxJQUFJLEdBQUcsRUFBVCxFQUFhO0lBQ3RCLEtBQUtDLE9BQUwsR0FBZSxDQUFDLENBQUNELElBQUksQ0FBQ0MsT0FBdEI7RUFDRDs7RUFFREMsUUFBUSxHQUFJO0lBQUUsTUFBTSxJQUFJTCxLQUFKLENBQVUsa0JBQVYsQ0FBTjtFQUFzQzs7RUFFcERNLEdBQUcsR0FBSTtJQUVMLE1BQU0sSUFBSU4sS0FBSixDQUFVLGtCQUFWLENBQU47RUFDRDs7QUFWZTs7OztBQWFsQixNQUFNTyxNQUFOLENBQWE7RUFDWEwsV0FBVyxHQUFJO0lBQ2IsS0FBS00sTUFBTCxHQUFjLEVBQWQ7SUFDQSxLQUFLQyxjQUFMLEdBQXNCLEVBQXRCO0lBQ0EsS0FBS0MsS0FBTCxHQUFhLEVBQWI7SUFDQSxLQUFLQyxjQUFMLEdBQXNCLEVBQXRCO0VBQ0Q7O0VBRURDLFFBQVEsQ0FBRUosTUFBRixFQUFVO0lBQ2hCQSxNQUFNLEdBQUdLLEtBQUssQ0FBQ0MsT0FBTixDQUFjTixNQUFkLElBQXdCQSxNQUF4QixHQUFpQyxDQUFDQSxNQUFELENBQTFDO0lBQ0EsS0FBS0EsTUFBTCxHQUFjLEtBQUtBLE1BQUwsQ0FBWU8sTUFBWixDQUFtQlAsTUFBbkIsQ0FBZDtFQUNEOztFQUVhLE1BQVJILFFBQVEsR0FBSTtJQUNoQlcsZUFBQSxDQUFJQyxJQUFKLENBQVUsc0JBQXFCLFlBQVlDLEtBQU0sNEJBQWpEOztJQUNBLEtBQUtSLEtBQUwsR0FBYSxFQUFiOztJQUNBLEtBQUssTUFBTVMsS0FBWCxJQUFvQixLQUFLWCxNQUF6QixFQUFpQztNQUMvQixNQUFNWSxHQUFHLEdBQUcsTUFBTUQsS0FBSyxDQUFDZCxRQUFOLEVBQWxCOztNQUNBLElBQUllLEdBQUcsQ0FBQ0MsUUFBUixFQUFrQjtRQUNoQixLQUFLWixjQUFMLENBQW9CYSxJQUFwQixDQUF5QkgsS0FBekI7UUFDQTtNQUNEOztNQUNELE1BQU0sS0FBS0ksdUJBQUwsQ0FBNkJILEdBQTdCLEVBQWtDLEtBQUtWLEtBQXZDLEVBQThDUyxLQUE5QyxDQUFOO0lBQ0Q7O0lBQ0RILGVBQUEsQ0FBSUMsSUFBSixDQUFVLHdEQUF1RCxNQUFNLEtBQUtPLFVBQUwsQ0FBZ0IsS0FBS2QsS0FBTCxDQUFXZSxNQUEzQixDQUFtQyxPQUExRzs7SUFDQVQsZUFBQSxDQUFJQyxJQUFKLENBQVMsRUFBVDs7SUFFQUQsZUFBQSxDQUFJQyxJQUFKLENBQVUsc0JBQXFCLFdBQVdTLE1BQU8sNEJBQWpEOztJQUNBLEtBQUtmLGNBQUwsR0FBc0IsRUFBdEI7O0lBQ0EsS0FBSyxNQUFNZ0IsYUFBWCxJQUE0QixLQUFLbEIsY0FBakMsRUFBaUQ7TUFDL0MsTUFBTSxLQUFLYyx1QkFBTCxDQUE2QixNQUFNSSxhQUFhLENBQUN0QixRQUFkLEVBQW5DLEVBQTZELEtBQUtNLGNBQWxFLEVBQWtGZ0IsYUFBbEYsQ0FBTjtJQUNEOztJQUNEWCxlQUFBLENBQUlDLElBQUosQ0FBVSx1REFBc0QsTUFBTSxLQUFLTyxVQUFMLENBQWdCLEtBQUtiLGNBQUwsQ0FBb0JjLE1BQXBDLEVBQTRDLElBQTVDLENBQWtELE9BQXhIOztJQUNBVCxlQUFBLENBQUlDLElBQUosQ0FBUyxFQUFUO0VBQ0Q7O0VBRXNCLE1BQWpCVyxpQkFBaUIsQ0FBRXRCLEdBQUYsRUFBT3VCLFVBQVAsRUFBbUI7SUFDeEMsTUFBTUMsV0FBVyxHQUFHQyxlQUFBLENBQUVDLE1BQUYsQ0FBUzFCLEdBQVQsRUFBZTJCLENBQUQ7TUFBQTs7TUFBQSxPQUFPLEVBQUNBLENBQUQsYUFBQ0EsQ0FBRCwyQkFBQ0EsQ0FBQyxDQUFFZCxLQUFKLHFDQUFDLFNBQVVmLE9BQVgsQ0FBUDtJQUFBLENBQWQsQ0FBcEI7O0lBQ0EsTUFBTThCLG1CQUFtQixHQUFHSCxlQUFBLENBQUVDLE1BQUYsQ0FBU0gsVUFBVCxFQUFzQkksQ0FBRDtNQUFBOztNQUFBLE9BQU8sRUFBQ0EsQ0FBRCxhQUFDQSxDQUFELDRCQUFDQSxDQUFDLENBQUVkLEtBQUosc0NBQUMsVUFBVWYsT0FBWCxDQUFQO0lBQUEsQ0FBckIsQ0FBNUI7O0lBRUEsSUFBSTBCLFdBQVcsQ0FBQ0wsTUFBWixHQUFxQixDQUF6QixFQUE0QjtNQUMxQlQsZUFBQSxDQUFJQyxJQUFKLENBQVMsNkJBQVQ7O01BQ0FELGVBQUEsQ0FBSUMsSUFBSixDQUFTLGlGQUFUOztNQUVBLE1BQU1rQixXQUFXLEdBQUcsRUFBcEI7O01BQ0EsS0FBSyxNQUFNRixDQUFYLElBQWdCSCxXQUFoQixFQUE2QjtRQUMzQkssV0FBVyxDQUFDYixJQUFaLENBQWlCLE1BQU1XLENBQUMsQ0FBQ2QsS0FBRixDQUFRYixHQUFSLEVBQXZCO01BQ0Q7O01BQ0QsS0FBSyxNQUFNOEIsQ0FBWCxJQUFnQkwsZUFBQSxDQUFFTSxJQUFGLENBQU9GLFdBQVAsQ0FBaEIsRUFBcUM7UUFDbkNuQixlQUFBLENBQUlzQixJQUFKLENBQVUsV0FBVUYsQ0FBRSxFQUF0QjtNQUNEOztNQUNEcEIsZUFBQSxDQUFJQyxJQUFKLENBQVMsRUFBVDtJQUNEOztJQUNELElBQUlpQixtQkFBbUIsQ0FBQ1QsTUFBcEIsR0FBNkIsQ0FBakMsRUFBb0M7TUFDbENULGVBQUEsQ0FBSUMsSUFBSixDQUFTLCtCQUFUOztNQUNBRCxlQUFBLENBQUlDLElBQUosQ0FBUyw2RUFBVDs7TUFFQSxNQUFNa0IsV0FBVyxHQUFHLEVBQXBCOztNQUNBLEtBQUssTUFBTUYsQ0FBWCxJQUFnQkMsbUJBQWhCLEVBQXFDO1FBQ25DQyxXQUFXLENBQUNiLElBQVosQ0FBaUIsTUFBTVcsQ0FBQyxDQUFDZCxLQUFGLENBQVFiLEdBQVIsRUFBdkI7TUFDRDs7TUFDRCxLQUFLLE1BQU04QixDQUFYLElBQWdCTCxlQUFBLENBQUVNLElBQUYsQ0FBT0YsV0FBUCxDQUFoQixFQUFxQztRQUNuQ25CLGVBQUEsQ0FBSXNCLElBQUosQ0FBVSxXQUFVRixDQUFFLEVBQXRCO01BQ0Q7O01BQ0RwQixlQUFBLENBQUlDLElBQUosQ0FBUyxFQUFUO0lBQ0Q7O0lBRUQsSUFBSWEsV0FBVyxDQUFDTCxNQUFaLEdBQXFCLENBQXJCLElBQTBCUyxtQkFBbUIsQ0FBQ1QsTUFBcEIsR0FBNkIsQ0FBM0QsRUFBOEQ7TUFDNURULGVBQUEsQ0FBSUMsSUFBSixDQUFTLEtBQVQ7O01BQ0FELGVBQUEsQ0FBSUMsSUFBSixDQUFTLEVBQVQ7O01BQ0FELGVBQUEsQ0FBSUMsSUFBSixDQUFTLHVFQUFUOztNQUNBRCxlQUFBLENBQUlDLElBQUosQ0FBUyxFQUFUOztNQUNBLE9BQU8sSUFBUDtJQUNEOztJQUNELE9BQU8sS0FBUDtFQUNEOztFQUVlLE1BQVZzQixVQUFVLENBQUVOLENBQUYsRUFBSztJQUNuQmpCLGVBQUEsQ0FBSUMsSUFBSixDQUFVLGVBQWNnQixDQUFDLENBQUNPLEtBQU0sTUFBaEM7O0lBQ0EsSUFBSTtNQUNGLE1BQU1QLENBQUMsQ0FBQ2QsS0FBRixDQUFRYixHQUFSLEVBQU47SUFDRCxDQUZELENBRUUsT0FBT21DLEdBQVAsRUFBWTtNQUNaLElBQUlBLEdBQUcsWUFBWTFDLGVBQW5CLEVBQW9DO1FBQ2xDaUIsZUFBQSxDQUFJQyxJQUFKLENBQVUscUJBQVY7O1FBQ0E7TUFDRCxDQUhELE1BR087UUFDTEQsZUFBQSxDQUFJc0IsSUFBSixDQUFVLEdBQUVHLEdBQUksRUFBUCxDQUFTQyxPQUFULENBQWlCLE1BQWpCLEVBQXlCLEVBQXpCLENBQVQ7O1FBQ0ExQixlQUFBLENBQUlDLElBQUosQ0FBVSw2QkFBVjs7UUFDQTtNQUNEO0lBQ0Y7O0lBQ0RELGVBQUEsQ0FBSUMsSUFBSixDQUFTLDZCQUFUOztJQUNBLElBQUlHLEdBQUcsR0FBRyxNQUFNYSxDQUFDLENBQUNkLEtBQUYsQ0FBUWQsUUFBUixFQUFoQjs7SUFDQSxJQUFJZSxHQUFHLENBQUN1QixFQUFSLEVBQVk7TUFDVlYsQ0FBQyxDQUFDVyxLQUFGLEdBQVUsSUFBVjs7TUFDQTVCLGVBQUEsQ0FBSUMsSUFBSixDQUFVLElBQUcsU0FBU0MsS0FBTSxJQUFHRSxHQUFHLENBQUN5QixPQUFRLEVBQTNDOztNQUNBN0IsZUFBQSxDQUFJQyxJQUFKLENBQVUsc0NBQVY7SUFDRCxDQUpELE1BSU87TUFDTEQsZUFBQSxDQUFJQyxJQUFKLENBQVUsSUFBRyxTQUFTNkIsR0FBSSxJQUFHMUIsR0FBRyxDQUFDeUIsT0FBUSxFQUF6Qzs7TUFDQTdCLGVBQUEsQ0FBSUMsSUFBSixDQUFVLDJDQUFWO0lBQ0Q7RUFDRjs7RUFFaUIsTUFBWjhCLFlBQVksR0FBSTtJQUNwQixJQUFJQyxTQUFTLEdBQUdqQixlQUFBLENBQUVDLE1BQUYsQ0FBUyxLQUFLdEIsS0FBZCxFQUFzQnVCLENBQUQ7TUFBQTs7TUFBQSxPQUFPQSxDQUFQLGFBQU9BLENBQVAsb0NBQU9BLENBQUMsQ0FBRWQsS0FBViw4Q0FBTyxVQUFVZixPQUFqQjtJQUFBLENBQXJCLENBQWhCOztJQUNBLEtBQUssSUFBSTZCLENBQVQsSUFBY2UsU0FBZCxFQUF5QjtNQUN2QixNQUFNLEtBQUtULFVBQUwsQ0FBZ0JOLENBQWhCLENBQU47O01BQ0FqQixlQUFBLENBQUlDLElBQUosQ0FBUyxFQUFUO0lBQ0Q7O0lBQ0QsSUFBSWMsZUFBQSxDQUFFa0IsSUFBRixDQUFPRCxTQUFQLEVBQW1CZixDQUFELElBQU8sQ0FBQ0EsQ0FBQyxDQUFDVyxLQUE1QixDQUFKLEVBQXdDO01BRXRDNUIsZUFBQSxDQUFJQyxJQUFKLENBQVMsb0VBQVQ7SUFDRCxDQUhELE1BR087TUFFTEQsZUFBQSxDQUFJQyxJQUFKLENBQVMsa0NBQVQ7SUFDRDs7SUFDREQsZUFBQSxDQUFJQyxJQUFKLENBQVMsRUFBVDtFQUNEOztFQUVRLE1BQUhpQyxHQUFHLEdBQUk7SUFDWGxDLGVBQUEsQ0FBSXNCLElBQUosQ0FBUyxxR0FBVDs7SUFDQXRCLGVBQUEsQ0FBSUMsSUFBSixDQUFVLG1CQUFrQmtDLGdCQUFRLEVBQXBDOztJQUNBLE1BQU0sS0FBSzlDLFFBQUwsRUFBTjs7SUFDQSxJQUFJLE1BQU0sS0FBSytDLGFBQUwsQ0FBbUIsS0FBSzFDLEtBQUwsQ0FBV2UsTUFBOUIsRUFBc0MsS0FBS2QsY0FBTCxDQUFvQmMsTUFBMUQsQ0FBVixFQUE2RTtNQUMzRTtJQUNEOztJQUNELElBQUksTUFBTSxLQUFLRyxpQkFBTCxDQUF1QixLQUFLbEIsS0FBNUIsRUFBbUMsS0FBS0MsY0FBeEMsQ0FBVixFQUFtRTtNQUNqRTtJQUNEOztJQUNELE1BQU0sS0FBS29DLFlBQUwsRUFBTjtFQUNEOztFQUc0QixNQUF2QnhCLHVCQUF1QixDQUFFOEIsTUFBRixFQUFVQyxTQUFWLEVBQXFCbkMsS0FBckIsRUFBNEI7SUFDdkQsSUFBSWtDLE1BQU0sQ0FBQ1YsRUFBWCxFQUFlO01BQ2IzQixlQUFBLENBQUlDLElBQUosQ0FBVSxJQUFHLFNBQVNDLEtBQU0sSUFBR21DLE1BQU0sQ0FBQ1IsT0FBUSxFQUE5QztJQUNELENBRkQsTUFFTztNQUNMLE1BQU1VLFlBQVksR0FBR0YsTUFBTSxDQUFDaEMsUUFBUCxHQUFtQixJQUFHLFNBQVNLLE1BQU8sSUFBRzJCLE1BQU0sQ0FBQ1IsT0FBUSxFQUF4RCxHQUE2RCxJQUFHLFNBQVNDLEdBQUksSUFBR08sTUFBTSxDQUFDUixPQUFRLEVBQXBIOztNQUNBN0IsZUFBQSxDQUFJc0IsSUFBSixDQUFTaUIsWUFBVDs7TUFDQUQsU0FBUyxDQUFDaEMsSUFBVixDQUFlO1FBQ2JrQixLQUFLLEVBQUVlLFlBRE07UUFFYnBDO01BRmEsQ0FBZjtJQUlEO0VBQ0Y7O0VBRWUsTUFBVkssVUFBVSxDQUFFQyxNQUFGLEVBQVVKLFFBQVEsR0FBRyxLQUFyQixFQUE0QjtJQUMxQyxJQUFJd0IsT0FBSjs7SUFDQSxRQUFRcEIsTUFBUjtNQUNFLEtBQUssQ0FBTDtRQUNFb0IsT0FBTyxHQUFHLFFBQVY7UUFDQTs7TUFDRixLQUFLLENBQUw7UUFDRUEsT0FBTyxHQUFHLFNBQVY7UUFDQTs7TUFDRjtRQUNFQSxPQUFPLEdBQUksR0FBRXBCLE1BQU8sUUFBcEI7SUFSSjs7SUFVQSxPQUFRLEdBQUVvQixPQUFRLElBQUd4QixRQUFRLEdBQUcsVUFBSCxHQUFnQixRQUFTLEVBQXREO0VBQ0Q7O0VBRWtCLE1BQWIrQixhQUFhLENBQUUzQixNQUFGLEVBQVUrQixjQUFWLEVBQTBCO0lBQzNDLElBQUkvQixNQUFNLEtBQUssQ0FBWCxJQUFnQitCLGNBQWMsS0FBSyxDQUF2QyxFQUEwQztNQUN4Q3hDLGVBQUEsQ0FBSUMsSUFBSixDQUFTLDZCQUFUOztNQUNBRCxlQUFBLENBQUlDLElBQUosQ0FBUyxFQUFUOztNQUNBLE9BQU8sSUFBUDtJQUNELENBSkQsTUFJTztNQUNMLE9BQU8sS0FBUDtJQUNEO0VBQ0Y7O0FBektVIn0=