var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import mysql from 'mysql'; import config from 'config'; import Logger from "../Logger"; export function query(queryString, values, connection) { return __awaiter(this, void 0, void 0, function* () { return yield MysqlConnectionManager.query(queryString, values, connection); }); } export default class MysqlConnectionManager { static registerMigration(migration) { this.migrations.push(migration(this.migrations.length + 1)); } static prepare() { return __awaiter(this, void 0, void 0, function* () { if (config.get('mysql.create_database_automatically') === true) { const dbName = config.get('mysql.database'); Logger.info(`Creating database ${dbName}...`); const connection = mysql.createConnection({ host: config.get('mysql.host'), user: config.get('mysql.user'), password: config.get('mysql.password'), }); yield new Promise((resolve, reject) => { connection.query(`CREATE DATABASE IF NOT EXISTS ${dbName}`, (error) => { if (error !== null) { reject(error); } else { resolve(); } }); }); connection.end(); Logger.info(`Database ${dbName} created!`); } this.databaseReady = true; yield this.handleMigrations(); }); } static get pool() { if (this.currentPool === undefined) { this.currentPool = this.createPool(); } return this.currentPool; } static createPool() { return mysql.createPool({ connectionLimit: config.get('mysql.connectionLimit'), host: config.get('mysql.host'), user: config.get('mysql.user'), password: config.get('mysql.password'), database: config.get('mysql.database'), }); } static endPool() { return __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => { if (this.currentPool !== undefined) { this.currentPool.end(() => { Logger.info('Mysql connection pool ended.'); resolve(); }); this.currentPool = undefined; } else { resolve(); } }); }); } static query(queryString, values, connection) { return __awaiter(this, void 0, void 0, function* () { return yield new Promise((resolve, reject) => { Logger.dev('Mysql query:', queryString, '; values:', values); (connection ? connection : this.pool).query(queryString, values, (error, results, fields) => { if (error !== null) { reject(error); return; } resolve({ results: Array.isArray(results) ? results : [], fields: fields !== undefined ? fields : [], other: Array.isArray(results) ? null : results }); }); }); }); } static wrapTransaction(transaction) { return __awaiter(this, void 0, void 0, function* () { return yield new Promise((resolve, reject) => { this.pool.getConnection((err, connection) => { if (err) { reject(err); return; } connection.beginTransaction((err) => { if (err) { reject(err); this.pool.releaseConnection(connection); return; } transaction(connection).then(val => { connection.commit((err) => { if (err) { this.rejectAndRollback(connection, err, reject); this.pool.releaseConnection(connection); return; } this.pool.releaseConnection(connection); resolve(val); }); }).catch(err => { this.rejectAndRollback(connection, err, reject); this.pool.releaseConnection(connection); }); }); }); }); }); } static rejectAndRollback(connection, err, reject) { connection.rollback((rollbackErr) => { if (rollbackErr) { reject(err + '\n' + rollbackErr); } else { reject(err); } }); } static handleMigrations() { return __awaiter(this, void 0, void 0, function* () { let currentVersion = 0; try { const result = yield query('SELECT id FROM migrations ORDER BY id DESC LIMIT 1'); currentVersion = result.results[0].id; } catch (e) { if (e.code === 'ECONNREFUSED' || e.code !== 'ER_NO_SUCH_TABLE') { throw new Error('Cannot run migrations: ' + e.code); } } for (const migration of this.migrations) { if (yield migration.shouldRun(currentVersion)) { Logger.info('Running migration ', migration.version, migration.constructor.name); yield migration.install(); yield query('INSERT INTO migrations VALUES(?, ?, NOW())', [ migration.version, migration.constructor.name, ]); } } }); } } MysqlConnectionManager.databaseReady = false; MysqlConnectionManager.migrations = []; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTXlzcWxDb25uZWN0aW9uTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIuLyIsInNvdXJjZXMiOlsiZGIvTXlzcWxDb25uZWN0aW9uTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxPQUFPLEtBQW9DLE1BQU0sT0FBTyxDQUFDO0FBQ3pELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUU1QixPQUFPLE1BQU0sTUFBTSxXQUFXLENBQUM7QUFTL0IsTUFBTSxVQUFnQixLQUFLLENBQUMsV0FBbUIsRUFBRSxNQUFZLEVBQUUsVUFBdUI7O1FBQ2xGLE9BQU8sTUFBTSxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUMvRSxDQUFDO0NBQUE7QUFFRCxNQUFNLENBQUMsT0FBTyxPQUFPLHNCQUFzQjtJQUtoQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsU0FBeUM7UUFDckUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVNLE1BQU0sQ0FBTyxPQUFPOztZQUN2QixJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMscUNBQXFDLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQzVELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDNUMsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsTUFBTSxLQUFLLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixDQUFDO29CQUN0QyxJQUFJLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUM7b0JBQzlCLElBQUksRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQztvQkFDOUIsUUFBUSxFQUFFLE1B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QUMsSUFBSSxLQUFLLGtCQUFrQixFQUFFO29CQUM1RCxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFDdkQ7YUFDSjtZQUVELEtBQUssTUFBTSxTQUFTLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDckMsSUFBSSxNQUFNLFNBQVMsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEVBQUU7b0JBQzNDLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsU0FBUyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNqRixNQUFNLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDMUIsTUFBTSxLQUFLLENBQUMsNENBQTRDLEVBQUU7d0JBQ3RELFNBQVMsQ0FBQyxPQUFPO3dCQUNqQixTQUFTLENBQUMsV0FBVyxDQUFDLElBQUk7cUJBQzdCLENBQUMsQ0FBQztpQkFDTjthQUNKO1FBQ0wsQ0FBQztLQUFBOztBQXJKYyxvQ0FBYSxHQUFZLEtBQUssQ0FBQztBQUN0QixpQ0FBVSxHQUFnQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbXlzcWwsIHtDb25uZWN0aW9uLCBGaWVsZEluZm8sIFBvb2x9IGZyb20gJ215c3FsJztcbmltcG9ydCBjb25maWcgZnJvbSAnY29uZmlnJztcbmltcG9ydCBNaWdyYXRpb24gZnJvbSBcIi4vTWlncmF0aW9uXCI7XG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi9Mb2dnZXJcIjtcblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeVJlc3VsdCB7XG4gICAgcmVhZG9ubHkgcmVzdWx0czogYW55W107XG4gICAgcmVhZG9ubHkgZmllbGRzOiBGaWVsZEluZm9bXTtcbiAgICByZWFkb25seSBvdGhlcj86IGFueTtcbiAgICBmb3VuZFJvd3M/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBxdWVyeShxdWVyeVN0cmluZzogc3RyaW5nLCB2YWx1ZXM/OiBhbnksIGNvbm5lY3Rpb24/OiBDb25uZWN0aW9uKTogUHJvbWlzZTxRdWVyeVJlc3VsdD4ge1xuICAgIHJldHVybiBhd2FpdCBNeXNxbENvbm5lY3Rpb25NYW5hZ2VyLnF1ZXJ5KHF1ZXJ5U3RyaW5nLCB2YWx1ZXMsIGNvbm5lY3Rpb24pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNeXNxbENvbm5lY3Rpb25NYW5hZ2VyIHtcbiAgICBwcml2YXRlIHN0YXRpYyBjdXJyZW50UG9vbD86IFBvb2w7XG4gICAgcHJpdmF0ZSBzdGF0aWMgZGF0YWJhc2VSZWFkeTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IG1pZ3JhdGlvbnM6IE1pZ3JhdGlvbltdID0gW107XG5cbiAgICBwdWJsaWMgc3RhdGljIHJlZ2lzdGVyTWlncmF0aW9uKG1pZ3JhdGlvbjogKHZlcnNpb246IG51bWJlcikgPT4gTWlncmF0aW9uKSB7XG4gICAgICAgIHRoaXMubWlncmF0aW9ucy5wdXNoKG1pZ3JhdGlvbih0aGlzLm1pZ3JhdGlvbnMubGVuZ3RoICsgMSkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgYXN5bmMgcHJlcGFyZSgpIHtcbiAgICAgICAgaWYgKGNvbmZpZy5nZXQoJ215c3FsLmNyZWF0ZV9kYXRhYmFzZV9hdXRvbWF0aWNhbGx5JykgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRiTmFtZSA9IGNvbmZpZy5nZXQoJ215c3FsLmRhdGFiYXNlJyk7XG4gICAgICAgICAgICBMb2dnZXIuaW5mbyhgQ3JlYXRpbmcgZGF0YWJhc2UgJHtkYk5hbWV9Li4uYCk7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbXlzcWwuY3JlYXRlQ29ubmVjdGlvbih7XG4gICAgICAgICAgICAgICAgaG9zdDogY29uZmlnLmdldCgnbXlzcWwuaG9zdCcpLFxuICAgICAgICAgICAgICAgIHVzZXI6IGNvbmZpZy5nZXQoJ215c3FsLnVzZXInKSxcbiAgICAgICAgICAgICAgICBwYXNzd29yZDogY29uZmlnLmdldCgnbXlzcWwucGFzc3dvcmQnKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ucXVlcnkoYENSRUFURSBEQVRBQkFTRSBJRiBOT1QgRVhJU1RTICR7ZGJOYW1lfWAsIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29ubmVjdGlvbi5lbmQoKTtcbiAgICAgICAgICAgIExvZ2dlci5pbmZvKGBEYXRhYmFzZSAke2RiTmFtZX0gY3JlYXRlZCFgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRhdGFiYXNlUmVhZHkgPSB0cnVlO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlTWlncmF0aW9ucygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0IHBvb2woKTogUG9vbCB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRQb29sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFBvb2wgPSB0aGlzLmNyZWF0ZVBvb2woKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50UG9vbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBjcmVhdGVQb29sKCk6IFBvb2wge1xuICAgICAgICByZXR1cm4gbXlzcWwuY3JlYXRlUG9vbCh7XG4gICAgICAgICAgICBjb25uZWN0aW9uTGltaXQ6IGNvbmZpZy5nZXQoJ215c3FsLmNvbm5lY3Rpb25MaW1pdCcpLFxuICAgICAgICAgICAgaG9zdDogY29uZmlnLmdldCgnbXlzcWwuaG9zdCcpLFxuICAgICAgICAgICAgdXNlcjogY29uZmlnLmdldCgnbXlzcWwudXNlcicpLFxuICAgICAgICAgICAgcGFzc3dvcmQ6IGNvbmZpZy5nZXQoJ215c3FsLnBhc3N3b3JkJyksXG4gICAgICAgICAgICBkYXRhYmFzZTogY29uZmlnLmdldCgnbXlzcWwuZGF0YWJhc2UnKSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBlbmRQb29sKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50UG9vbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50UG9vbC5lbmQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuaW5mbygnTXlzcWwgY29ubmVjdGlvbiBwb29sIGVuZGVkLicpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50UG9vbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIHF1ZXJ5KHF1ZXJ5U3RyaW5nOiBzdHJpbmcsIHZhbHVlcz86IGFueSwgY29ubmVjdGlvbj86IENvbm5lY3Rpb24pOiBQcm9taXNlPFF1ZXJ5UmVzdWx0PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZTxRdWVyeVJlc3VsdD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgTG9nZ2VyLmRldignTXlzcWwgcXVlcnk6JywgcXVlcnlTdHJpbmcsICc7IHZhbHVlczonLCB2YWx1ZXMpO1xuICAgICAgICAgICAgKGNvbm5lY3Rpb24gPyBjb25uZWN0aW9uIDogdGhpcy5wb29sKS5xdWVyeShxdWVyeVN0cmluZywgdmFsdWVzLCAoZXJyb3IsIHJlc3VsdHMsIGZpZWxkcykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHM6IEFycmF5LmlzQXJyYXkocmVzdWx0cykgPyByZXN1bHRzIDogW10sXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkczogZmllbGRzICE9PSB1bmRlZmluZWQgPyBmaWVsZHMgOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgb3RoZXI6IEFycmF5LmlzQXJyYXkocmVzdWx0cykgPyBudWxsIDogcmVzdWx0c1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgYXN5bmMgd3JhcFRyYW5zYWN0aW9uPFQ+KHRyYW5zYWN0aW9uOiAoY29ubmVjdGlvbjogQ29ubmVjdGlvbikgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wb29sLmdldENvbm5lY3Rpb24oKGVyciwgY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmJlZ2luVHJhbnNhY3Rpb24oKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucG9vbC5yZWxlYXNlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pLnRoZW4odmFsID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uY29tbWl0KChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVqZWN0QW5kUm9sbGJhY2soY29ubmVjdGlvbiwgZXJyLCByZWplY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBvb2wucmVsZWFzZUNvbm5lY3Rpb24oY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBvb2wucmVsZWFzZUNvbm5lY3Rpb24oY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlamVjdEFuZFJvbGxiYWNrKGNvbm5lY3Rpb24sIGVyciwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucG9vbC5yZWxlYXNlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVqZWN0QW5kUm9sbGJhY2soY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgZXJyOiBhbnksIHJlamVjdDogKGVycjogYW55KSA9PiB2b2lkKSB7XG4gICAgICAgIGNvbm5lY3Rpb24ucm9sbGJhY2soKHJvbGxiYWNrRXJyKSA9PiB7XG4gICAgICAgICAgICBpZiAocm9sbGJhY2tFcnIpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyICsgJ1xcbicgKyByb2xsYmFja0Vycik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBhc3luYyBoYW5kbGVNaWdyYXRpb25zKCkge1xuICAgICAgICBsZXQgY3VycmVudFZlcnNpb24gPSAwO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBxdWVyeSgnU0VMRUNUIGlkIEZST00gbWlncmF0aW9ucyBPUkRFUiBCWSBpZCBERVNDIExJTUlUIDEnKTtcbiAgICAgICAgICAgIGN1cnJlbnRWZXJzaW9uID0gcmVzdWx0LnJlc3VsdHNbMF0uaWQ7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChlLmNvZGUgPT09ICdFQ09OTlJFRlVTRUQnIHx8IGUuY29kZSAhPT0gJ0VSX05PX1NVQ0hfVEFCTEUnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgcnVuIG1pZ3JhdGlvbnM6ICcgKyBlLmNvZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgdGhpcy5taWdyYXRpb25zKSB7XG4gICAgICAgICAgICBpZiAoYXdhaXQgbWlncmF0aW9uLnNob3VsZFJ1bihjdXJyZW50VmVyc2lvbikpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuaW5mbygnUnVubmluZyBtaWdyYXRpb24gJywgbWlncmF0aW9uLnZlcnNpb24sIG1pZ3JhdGlvbi5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb24uaW5zdGFsbCgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHF1ZXJ5KCdJTlNFUlQgSU5UTyBtaWdyYXRpb25zIFZBTFVFUyg/LCA/LCBOT1coKSknLCBbXG4gICAgICAgICAgICAgICAgICAgIG1pZ3JhdGlvbi52ZXJzaW9uLFxuICAgICAgICAgICAgICAgICAgICBtaWdyYXRpb24uY29uc3RydWN0b3IubmFtZSxcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn0iXX0=