testcafe
Version:
Automated browser testing for the modern web development stack.
137 lines • 21.8 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const read_file_relative_1 = require("read-file-relative");
const http_1 = require("../../utils/http");
const remotes_queue_1 = __importDefault(require("./remotes-queue"));
// Const
const IDLE_PAGE_SCRIPT = read_file_relative_1.readSync('../../client/browser/idle-page/index.js');
const IDLE_PAGE_STYLE = read_file_relative_1.readSync('../../client/browser/idle-page/styles.css');
const IDLE_PAGE_LOGO = read_file_relative_1.readSync('../../client/browser/idle-page/logo.svg', true);
// Gateway
class BrowserConnectionGateway {
constructor(proxy, options = {}) {
this.connections = {};
this.remotesQueue = new remotes_queue_1.default();
this.domain = proxy.server1Info.domain;
this.connectUrl = `${this.domain}/browser/connect`;
this.retryTestPages = options.retryTestPages;
this._registerRoutes(proxy);
}
_dispatch(url, proxy, handler, method = 'GET') {
proxy[method](url, (req, res, si, params) => {
const connection = this.connections[params.id];
http_1.preventCaching(res);
if (connection)
handler(req, res, connection);
else
http_1.respond404(res);
});
}
_registerRoutes(proxy) {
this._dispatch('/browser/connect/{id}', proxy, BrowserConnectionGateway.onConnection);
this._dispatch('/browser/heartbeat/{id}', proxy, BrowserConnectionGateway.onHeartbeat);
this._dispatch('/browser/idle/{id}', proxy, BrowserConnectionGateway.onIdle);
this._dispatch('/browser/idle-forced/{id}', proxy, BrowserConnectionGateway.onIdleForced);
this._dispatch('/browser/status/{id}', proxy, BrowserConnectionGateway.onStatusRequest);
this._dispatch('/browser/status-done/{id}', proxy, BrowserConnectionGateway.onStatusRequestOnTestDone);
this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway.onInitScriptRequest);
this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway.onInitScriptResponse, 'POST');
proxy.GET('/browser/connect', (req, res) => this._connectNextRemoteBrowser(req, res));
proxy.GET('/browser/connect/', (req, res) => this._connectNextRemoteBrowser(req, res));
proxy.GET('/browser/assets/index.js', { content: IDLE_PAGE_SCRIPT, contentType: 'application/x-javascript' });
proxy.GET('/browser/assets/styles.css', { content: IDLE_PAGE_STYLE, contentType: 'text/css' });
proxy.GET('/browser/assets/logo.svg', { content: IDLE_PAGE_LOGO, contentType: 'image/svg+xml' });
}
// Helpers
static ensureConnectionReady(res, connection) {
if (!connection.ready) {
http_1.respond500(res, 'The connection is not ready yet.');
return false;
}
return true;
}
// Route handlers
static onConnection(req, res, connection) {
if (connection.ready)
http_1.respond500(res, 'The connection is already established.');
else {
const userAgent = req.headers['user-agent'];
connection.establish(userAgent);
http_1.redirect(res, connection.idleUrl);
}
}
static onHeartbeat(req, res, connection) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) {
const status = connection.heartbeat();
http_1.respondWithJSON(res, status);
}
}
static onIdle(req, res, connection) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection))
res.end(connection.renderIdlePage());
}
static async onIdleForced(req, res, connection) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) {
const status = await connection.getStatus(true);
http_1.redirect(res, status.url);
}
}
static async onStatusRequest(req, res, connection) {
return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, false);
}
static async onStatusRequestOnTestDone(req, res, connection) {
return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, true);
}
static async _onStatusRequestCore(req, res, connection, isTestDone) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) {
const status = await connection.getStatus(isTestDone);
http_1.respondWithJSON(res, status);
}
}
static onInitScriptRequest(req, res, connection) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) {
const script = connection.getInitScript();
http_1.respondWithJSON(res, script);
}
}
static onInitScriptResponse(req, res, connection) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) {
let data = '';
req.on('data', chunk => {
data += chunk;
});
req.on('end', () => {
connection.handleInitScriptResult(data);
res.end();
});
}
}
async _connectNextRemoteBrowser(req, res) {
http_1.preventCaching(res);
const remoteConnection = await this.remotesQueue.shift();
if (remoteConnection)
http_1.redirect(res, remoteConnection.url);
else
http_1.respond500(res, 'There are no available connections to establish.');
}
// API
startServingConnection(connection) {
this.connections[connection.id] = connection;
if (connection.browserInfo.providerName === 'remote')
this.remotesQueue.add(connection);
}
stopServingConnection(connection) {
delete this.connections[connection.id];
if (connection.browserInfo.providerName === 'remote')
this.remotesQueue.remove(connection);
}
close() {
Object.keys(this.connections).forEach(id => this.connections[id].close());
}
}
exports.default = BrowserConnectionGateway;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vZ2F0ZXdheS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDJEQUFzRDtBQUN0RCwyQ0FBcUc7QUFDckcsb0VBQTJDO0FBRzNDLFFBQVE7QUFDUixNQUFNLGdCQUFnQixHQUFHLDZCQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQztBQUN6RSxNQUFNLGVBQWUsR0FBSSw2QkFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7QUFDM0UsTUFBTSxjQUFjLEdBQUssNkJBQUksQ0FBQyx5Q0FBeUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUUvRSxVQUFVO0FBQ1YsTUFBcUIsd0JBQXdCO0lBQ3pDLFlBQWEsS0FBSyxFQUFFLE9BQU8sR0FBRyxFQUFFO1FBQzVCLElBQUksQ0FBQyxXQUFXLEdBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSx1QkFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBUyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUU3QyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sa0JBQWtCLENBQUM7UUFFbkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBRTdDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELFNBQVMsQ0FBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEdBQUcsS0FBSztRQUMxQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDeEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENB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aW1wb3J0IHsgcmVhZFN5bmMgYXMgcmVhZCB9IGZyb20gJ3JlYWQtZmlsZS1yZWxhdGl2ZSc7XG5pbXBvcnQgeyByZXNwb25kNDA0LCByZXNwb25kNTAwLCByZXNwb25kV2l0aEpTT04sIHJlZGlyZWN0LCBwcmV2ZW50Q2FjaGluZyB9IGZyb20gJy4uLy4uL3V0aWxzL2h0dHAnO1xuaW1wb3J0IFJlbW90ZXNRdWV1ZSBmcm9tICcuL3JlbW90ZXMtcXVldWUnO1xuXG5cbi8vIENvbnN0XG5jb25zdCBJRExFX1BBR0VfU0NSSVBUID0gcmVhZCgnLi4vLi4vY2xpZW50L2Jyb3dzZXIvaWRsZS1wYWdlL2luZGV4LmpzJyk7XG5jb25zdCBJRExFX1BBR0VfU1RZTEUgID0gcmVhZCgnLi4vLi4vY2xpZW50L2Jyb3dzZXIvaWRsZS1wYWdlL3N0eWxlcy5jc3MnKTtcbmNvbnN0IElETEVfUEFHRV9MT0dPICAgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2UvbG9nby5zdmcnLCB0cnVlKTtcblxuLy8gR2F0ZXdheVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5IHtcbiAgICBjb25zdHJ1Y3RvciAocHJveHksIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25zICA9IHt9O1xuICAgICAgICB0aGlzLnJlbW90ZXNRdWV1ZSA9IG5ldyBSZW1vdGVzUXVldWUoKTtcbiAgICAgICAgdGhpcy5kb21haW4gICAgICAgPSBwcm94eS5zZXJ2ZXIxSW5mby5kb21haW47XG5cbiAgICAgICAgdGhpcy5jb25uZWN0VXJsID0gYCR7dGhpcy5kb21haW59L2Jyb3dzZXIvY29ubmVjdGA7XG5cbiAgICAgICAgdGhpcy5yZXRyeVRlc3RQYWdlcyA9IG9wdGlvbnMucmV0cnlUZXN0UGFnZXM7XG5cbiAgICAgICAgdGhpcy5fcmVnaXN0ZXJSb3V0ZXMocHJveHkpO1xuICAgIH1cblxuICAgIF9kaXNwYXRjaCAodXJsLCBwcm94eSwgaGFuZGxlciwgbWV0aG9kID0gJ0dFVCcpIHtcbiAgICAgICAgcHJveHlbbWV0aG9kXSh1cmwsIChyZXEsIHJlcywgc2ksIHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuY29ubmVjdGlvbnNbcGFyYW1zLmlkXTtcblxuICAgICAgICAgICAgcHJldmVudENhY2hpbmcocmVzKTtcblxuICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb24pXG4gICAgICAgICAgICAgICAgaGFuZGxlcihyZXEsIHJlcywgY29ubmVjdGlvbik7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgcmVzcG9uZDQwNChyZXMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcmVnaXN0ZXJSb3V0ZXMgKHByb3h5KSB7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9jb25uZWN0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uQ29ubmVjdGlvbik7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9oZWFydGJlYXQve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25IZWFydGJlYXQpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaWRsZS97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vbklkbGUpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaWRsZS1mb3JjZWQve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25JZGxlRm9yY2VkKTtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL3N0YXR1cy97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vblN0YXR1c1JlcXVlc3QpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvc3RhdHVzLWRvbmUve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25TdGF0dXNSZXF1ZXN0T25UZXN0RG9uZSk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pbml0LXNjcmlwdC97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vbkluaXRTY3JpcHRSZXF1ZXN0KTtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL2luaXQtc2NyaXB0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uSW5pdFNjcmlwdFJlc3BvbnNlLCAnUE9TVCcpO1xuXG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvY29ubmVjdCcsIChyZXEsIHJlcykgPT4gdGhpcy5fY29ubmVjdE5leHRSZW1vdGVCcm93c2VyKHJlcSwgcmVzKSk7XG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvY29ubmVjdC8nLCAocmVxLCByZXMpID0+IHRoaXMuX2Nvbm5lY3ROZXh0UmVtb3RlQnJvd3NlcihyZXEsIHJlcykpO1xuXG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvYXNzZXRzL2luZGV4LmpzJywgeyBjb250ZW50OiBJRExFX1BBR0VfU0NSSVBULCBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL3gtamF2YXNjcmlwdCcgfSk7XG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvYXNzZXRzL3N0eWxlcy5jc3MnLCB7IGNvbnRlbnQ6IElETEVfUEFHRV9TVFlMRSwgY29udGVudFR5cGU6ICd0ZXh0L2NzcycgfSk7XG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvYXNzZXRzL2xvZ28uc3ZnJywgeyBjb250ZW50OiBJRExFX1BBR0VfTE9HTywgY29udGVudFR5cGU6ICdpbWFnZS9zdmcreG1sJyB9KTtcbiAgICB9XG5cbiAgICAvLyBIZWxwZXJzXG4gICAgc3RhdGljIGVuc3VyZUNvbm5lY3Rpb25SZWFkeSAocmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmICghY29ubmVjdGlvbi5yZWFkeSkge1xuICAgICAgICAgICAgcmVzcG9uZDUwMChyZXMsICdUaGUgY29ubmVjdGlvbiBpcyBub3QgcmVhZHkgeWV0LicpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG5cbiAgICAvLyBSb3V0ZSBoYW5kbGVyc1xuICAgIHN0YXRpYyBvbkNvbm5lY3Rpb24gKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmIChjb25uZWN0aW9uLnJlYWR5KVxuICAgICAgICAgICAgcmVzcG9uZDUwMChyZXMsICdUaGUgY29ubmVjdGlvbiBpcyBhbHJlYWR5IGVzdGFibGlzaGVkLicpO1xuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdXNlckFnZW50ID0gcmVxLmhlYWRlcnNbJ3VzZXItYWdlbnQnXTtcblxuICAgICAgICAgICAgY29ubmVjdGlvbi5lc3RhYmxpc2godXNlckFnZW50KTtcbiAgICAgICAgICAgIHJlZGlyZWN0KHJlcywgY29ubmVjdGlvbi5pZGxlVXJsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbkhlYXJ0YmVhdCAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gY29ubmVjdGlvbi5oZWFydGJlYXQoKTtcblxuICAgICAgICAgICAgcmVzcG9uZFdpdGhKU09OKHJlcywgc3RhdHVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbklkbGUgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmIChCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpXG4gICAgICAgICAgICByZXMuZW5kKGNvbm5lY3Rpb24ucmVuZGVySWRsZVBhZ2UoKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIG9uSWRsZUZvcmNlZCAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgY29ubmVjdGlvbi5nZXRTdGF0dXModHJ1ZSk7XG5cbiAgICAgICAgICAgIHJlZGlyZWN0KHJlcywgc3RhdHVzLnVybCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgYXN5bmMgb25TdGF0dXNSZXF1ZXN0IChyZXEsIHJlcywgY29ubmVjdGlvbikge1xuICAgICAgICByZXR1cm4gQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vblN0YXR1c1JlcXVlc3RDb3JlKHJlcSwgcmVzLCBjb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIG9uU3RhdHVzUmVxdWVzdE9uVGVzdERvbmUgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX29uU3RhdHVzUmVxdWVzdENvcmUocmVxLCByZXMsIGNvbm5lY3Rpb24sIHRydWUpO1xuICAgIH1cblxuICAgIHN0YXRpYyBhc3luYyBfb25TdGF0dXNSZXF1ZXN0Q29yZSAocmVxLCByZXMsIGNvbm5lY3Rpb24sIGlzVGVzdERvbmUpIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgY29ubmVjdGlvbi5nZXRTdGF0dXMoaXNUZXN0RG9uZSk7XG5cbiAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMsIHN0YXR1cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25Jbml0U2NyaXB0UmVxdWVzdCAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc2NyaXB0ID0gY29ubmVjdGlvbi5nZXRJbml0U2NyaXB0KCk7XG5cbiAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMsIHNjcmlwdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25Jbml0U2NyaXB0UmVzcG9uc2UgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmIChCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGxldCBkYXRhID0gJyc7XG5cbiAgICAgICAgICAgIHJlcS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICBkYXRhICs9IGNodW5rO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJlcS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaGFuZGxlSW5pdFNjcmlwdFJlc3VsdChkYXRhKTtcblxuICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgX2Nvbm5lY3ROZXh0UmVtb3RlQnJvd3NlciAocmVxLCByZXMpIHtcbiAgICAgICAgcHJldmVudENhY2hpbmcocmVzKTtcblxuICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gYXdhaXQgdGhpcy5yZW1vdGVzUXVldWUuc2hpZnQoKTtcblxuICAgICAgICBpZiAocmVtb3RlQ29ubmVjdGlvbilcbiAgICAgICAgICAgIHJlZGlyZWN0KHJlcywgcmVtb3RlQ29ubmVjdGlvbi51cmwpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXNwb25kNTAwKHJlcywgJ1RoZXJlIGFyZSBubyBhdmFpbGFibGUgY29ubmVjdGlvbnMgdG8gZXN0YWJsaXNoLicpO1xuICAgIH1cblxuICAgIC8vIEFQSVxuICAgIHN0YXJ0U2VydmluZ0Nvbm5lY3Rpb24gKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uc1tjb25uZWN0aW9uLmlkXSA9IGNvbm5lY3Rpb247XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24uYnJvd3NlckluZm8ucHJvdmlkZXJOYW1lID09PSAncmVtb3RlJylcbiAgICAgICAgICAgIHRoaXMucmVtb3Rlc1F1ZXVlLmFkZChjb25uZWN0aW9uKTtcbiAgICB9XG5cbiAgICBzdG9wU2VydmluZ0Nvbm5lY3Rpb24gKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNbY29ubmVjdGlvbi5pZF07XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24uYnJvd3NlckluZm8ucHJvdmlkZXJOYW1lID09PSAncmVtb3RlJylcbiAgICAgICAgICAgIHRoaXMucmVtb3Rlc1F1ZXVlLnJlbW92ZShjb25uZWN0aW9uKTtcbiAgICB9XG5cbiAgICBjbG9zZSAoKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuY29ubmVjdGlvbnMpLmZvckVhY2goaWQgPT4gdGhpcy5jb25uZWN0aW9uc1tpZF0uY2xvc2UoKSk7XG4gICAgfVxufVxuXG4iXX0=