118 lines
21 KiB
JavaScript
118 lines
21 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const events_1 = require("events");
|
|
const time_limit_promise_1 = __importDefault(require("time-limit-promise"));
|
|
const promisify_event_1 = __importDefault(require("promisify-event"));
|
|
const lodash_1 = require("lodash");
|
|
const runtime_1 = require("../errors/runtime");
|
|
const types_1 = require("../errors/types");
|
|
const status_1 = __importDefault(require("../browser/connection/status"));
|
|
const get_hints_1 = __importDefault(require("../browser/connection/get-hints"));
|
|
const string_1 = require("../utils/string");
|
|
const RELEASE_TIMEOUT = 10000;
|
|
const COUNT_OWN_AND_OUTER_LISTENERS = 3;
|
|
class BrowserSet extends events_1.EventEmitter {
|
|
constructor(browserConnectionGroups, options) {
|
|
super();
|
|
this._pendingReleases = [];
|
|
this.browserConnectionGroups = browserConnectionGroups;
|
|
this._browserConnections = (0, lodash_1.flatten)(browserConnectionGroups);
|
|
this._options = options;
|
|
this._browserErrorHandler = (error) => this.emit('error', error);
|
|
this._browserConnections.forEach(bc => bc.on('error', this._browserErrorHandler));
|
|
// NOTE: We're setting an empty error handler, because Node kills the process on an 'error' event
|
|
// if there is no handler. See: https://nodejs.org/api/events.html#events_class_events_eventemitter
|
|
this.on('error', lodash_1.noop);
|
|
this.setMaxListeners(COUNT_OWN_AND_OUTER_LISTENERS + this._browserConnections.length);
|
|
}
|
|
static async _waitIdle(bc) {
|
|
if (bc.idle || !bc.isReady())
|
|
return;
|
|
await (0, promisify_event_1.default)(bc, 'idle');
|
|
}
|
|
static async _closeConnection(bc) {
|
|
if (bc.status === status_1.default.closed || bc.status === status_1.default.closing)
|
|
return;
|
|
await bc.close();
|
|
}
|
|
async _waitConnectionOpened(bc) {
|
|
const openedTimeout = this._options.browserInitTimeout || await bc.getDefaultBrowserInitTimeout();
|
|
const timeoutErr = new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotEstablishBrowserConnection);
|
|
const openedOrError = Promise.race([
|
|
(0, promisify_event_1.default)(this, 'error'),
|
|
(0, promisify_event_1.default)(bc, 'opened'),
|
|
]);
|
|
return (0, time_limit_promise_1.default)(openedOrError, openedTimeout, { rejectWith: timeoutErr });
|
|
}
|
|
async _waitConnectionsOpened() {
|
|
return Promise.all(this._browserConnections
|
|
.filter(bc => bc.status !== status_1.default.opened)
|
|
.map(notOpenedConnection => this._waitConnectionOpened(notOpenedConnection)));
|
|
}
|
|
_checkForDisconnections() {
|
|
const disconnectedUserAgents = this._browserConnections
|
|
.filter(bc => bc.status === status_1.default.closed)
|
|
.map(bc => bc.userAgent);
|
|
if (disconnectedUserAgents.length)
|
|
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotRunAgainstDisconnectedBrowsers, disconnectedUserAgents.join(', '));
|
|
}
|
|
async prepareConnections() {
|
|
await this._checkForDisconnections();
|
|
await this._waitConnectionsOpened();
|
|
}
|
|
// NOTE: creates and prepares BrowserSet instance with given browser connections
|
|
static async from(browserConnections, opts) {
|
|
const browserSet = new BrowserSet(browserConnections, opts);
|
|
try {
|
|
const prepareConnections = browserSet.prepareConnections();
|
|
const browserSetError = (0, promisify_event_1.default)(browserSet, 'error');
|
|
await Promise.race([prepareConnections, browserSetError]);
|
|
return browserSet;
|
|
}
|
|
catch (e) {
|
|
const finalError = e.code === types_1.RUNTIME_ERRORS.cannotEstablishBrowserConnection
|
|
? browserSet.createBrowserConnectionError(e)
|
|
: e;
|
|
await browserSet.dispose();
|
|
throw finalError;
|
|
}
|
|
}
|
|
createBrowserConnectionError(error) {
|
|
const notOpenedConnections = this._browserConnections.filter(bc => bc.status !== status_1.default.opened);
|
|
const numOfAllConnections = this._browserConnections.length;
|
|
const numOfNotOpenedConnections = notOpenedConnections.length;
|
|
const listOfNotOpenedConnections = (0, string_1.createList)(notOpenedConnections.map(bc => bc.browserInfo.alias));
|
|
const listOfHints = (0, string_1.createList)((0, get_hints_1.default)(this._browserConnections, this._options));
|
|
return new runtime_1.BrowserConnectionError(error.message, numOfNotOpenedConnections, numOfAllConnections, listOfNotOpenedConnections, listOfHints);
|
|
}
|
|
async releaseConnection(bc) {
|
|
if (!this._browserConnections.includes(bc))
|
|
return;
|
|
(0, lodash_1.pull)(this._browserConnections, bc);
|
|
bc.removeListener('error', this._browserErrorHandler);
|
|
const appropriateStateSwitch = bc.permanent ?
|
|
BrowserSet._waitIdle(bc) :
|
|
BrowserSet._closeConnection(bc);
|
|
const release = (0, time_limit_promise_1.default)(appropriateStateSwitch, RELEASE_TIMEOUT)
|
|
.then(() => (0, lodash_1.pull)(this._pendingReleases, release));
|
|
this._pendingReleases.push(release);
|
|
return release; // eslint-disable-line consistent-return
|
|
}
|
|
async dispose() {
|
|
// NOTE: When browserConnection is cancelled, it is removed from
|
|
// the this.connections array, which leads to shifting indexes
|
|
// towards the beginning. So, we must copy the array in order to iterate it,
|
|
// or we can perform iteration from the end to the beginning.
|
|
await this._browserConnections.reduceRight(async (_, bc) => {
|
|
await this.releaseConnection(bc);
|
|
return bc;
|
|
}, Promise.resolve({}));
|
|
await Promise.all(this._pendingReleases);
|
|
}
|
|
}
|
|
exports.default = BrowserSet;
|
|
module.exports = exports.default;
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1zZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVubmVyL2Jyb3dzZXItc2V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQXNDO0FBQ3RDLDRFQUF1RDtBQUN2RCxzRUFBNkM7QUFDN0MsbUNBSWdCO0FBRWhCLCtDQUF5RTtBQUN6RSwyQ0FBaUQ7QUFFakQsMEVBQW1FO0FBRW5FLGdGQUF3RTtBQUN4RSw0Q0FBNkM7QUFFN0MsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDO0FBRTlCLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxDQUFDO0FBRXhDLE1BQXFCLFVBQVcsU0FBUSxxQkFBWTtJQU9oRCxZQUFvQix1QkFBOEMsRUFBRSxPQUEwQjtRQUMxRixLQUFLLEVBQUUsQ0FBQztRQUVSLElBQUksQ0FBQyxnQkFBZ0IsR0FBVyxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLHVCQUF1QixHQUFJLHVCQUF1QixDQUFDO1FBQ3hELElBQUksQ0FBQyxtQkFBbUIsR0FBUSxJQUFBLGdCQUFPLEVBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsUUFBUSxHQUFtQixPQUFPLENBQUM7UUFFeEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLENBQUMsS0FBWSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV4RSxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQztRQUVsRixpR0FBaUc7UUFDakcsbUdBQW1HO1FBQ25HLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLGFBQUksQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxD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O0NBQ0o7QUFsSkQsNkJBa0pDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCBnZXRUaW1lTGltaXRlZFByb21pc2UgZnJvbSAndGltZS1saW1pdC1wcm9taXNlJztcbmltcG9ydCBwcm9taXNpZnlFdmVudCBmcm9tICdwcm9taXNpZnktZXZlbnQnO1xuaW1wb3J0IHtcbiAgICBmbGF0dGVuLFxuICAgIG5vb3AsXG4gICAgcHVsbCBhcyByZW1vdmUsXG59IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCB7IEJyb3dzZXJDb25uZWN0aW9uRXJyb3IsIEdlbmVyYWxFcnJvciB9IGZyb20gJy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCB7IFJVTlRJTUVfRVJST1JTIH0gZnJvbSAnLi4vZXJyb3JzL3R5cGVzJztcbmltcG9ydCBCcm93c2VyQ29ubmVjdGlvbiBmcm9tICcuLi9icm93c2VyL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzIGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbi9zdGF0dXMnO1xuaW1wb3J0IHsgQnJvd3NlclNldE9wdGlvbnMgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IGdldEJyb3dzZXJDb25uZWN0aW9uSGludHMgZnJvbSAnLi4vYnJvd3Nlci9jb25uZWN0aW9uL2dldC1oaW50cyc7XG5pbXBvcnQgeyBjcmVhdGVMaXN0IH0gZnJvbSAnLi4vdXRpbHMvc3RyaW5nJztcblxuY29uc3QgUkVMRUFTRV9USU1FT1VUID0gMTAwMDA7XG5cbmNvbnN0IENPVU5UX09XTl9BTkRfT1VURVJfTElTVEVORVJTID0gMztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnJvd3NlclNldCBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfYnJvd3NlckNvbm5lY3Rpb25zOiBCcm93c2VyQ29ubmVjdGlvbltdO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2Jyb3dzZXJFcnJvckhhbmRsZXI6IChlcnJvcjogRXJyb3IpID0+IHZvaWQ7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfcGVuZGluZ1JlbGVhc2VzOiBQcm9taXNlPHZvaWQ+W107XG4gICAgcHJpdmF0ZSByZWFkb25seSBfb3B0aW9uczogQnJvd3NlclNldE9wdGlvbnM7XG4gICAgcHVibGljIGJyb3dzZXJDb25uZWN0aW9uR3JvdXBzOiBCcm93c2VyQ29ubmVjdGlvbltdW107XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKGJyb3dzZXJDb25uZWN0aW9uR3JvdXBzOiBCcm93c2VyQ29ubmVjdGlvbltdW10sIG9wdGlvbnM6IEJyb3dzZXJTZXRPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5fcGVuZGluZ1JlbGVhc2VzICAgICAgICAgPSBbXTtcbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbkdyb3VwcyAgPSBicm93c2VyQ29ubmVjdGlvbkdyb3VwcztcbiAgICAgICAgdGhpcy5fYnJvd3NlckNvbm5lY3Rpb25zICAgICAgPSBmbGF0dGVuKGJyb3dzZXJDb25uZWN0aW9uR3JvdXBzKTtcbiAgICAgICAgdGhpcy5fb3B0aW9ucyAgICAgICAgICAgICAgICAgPSBvcHRpb25zO1xuXG4gICAgICAgIHRoaXMuX2Jyb3dzZXJFcnJvckhhbmRsZXIgPSAoZXJyb3I6IEVycm9yKSA9PiB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuXG4gICAgICAgIHRoaXMuX2Jyb3dzZXJDb25uZWN0aW9ucy5mb3JFYWNoKGJjID0+IGJjLm9uKCdlcnJvcicsIHRoaXMuX2Jyb3dzZXJFcnJvckhhbmRsZXIpKTtcblxuICAgICAgICAvLyBOT1RFOiBXZSdyZSBzZXR0aW5nIGFuIGVtcHR5IGVycm9yIGhhbmRsZXIsIGJlY2F1c2UgTm9kZSBraWxscyB0aGUgcHJvY2VzcyBvbiBhbiAnZXJyb3InIGV2ZW50XG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGhhbmRsZXIuIFNlZTogaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9ldmVudHMuaHRtbCNldmVudHNfY2xhc3NfZXZlbnRzX2V2ZW50ZW1pdHRlclxuICAgICAgICB0aGlzLm9uKCdlcnJvcicsIG5vb3ApO1xuICAgICAgICB0aGlzLnNldE1heExpc3RlbmVycyhDT1VOVF9PV05fQU5EX09VVEVSX0xJU1RFTkVSUyArIHRoaXMuX2Jyb3dzZXJDb25uZWN0aW9ucy5sZW5ndGgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGFzeW5jIF93YWl0SWRsZSAoYmM6IEJyb3dzZXJDb25uZWN0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChiYy5pZGxlIHx8ICFiYy5pc1JlYWR5KCkpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgYXdhaXQgcHJvbWlzaWZ5RXZlbnQoYmMsICdpZGxlJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgX2Nsb3NlQ29ubmVjdGlvbiAoYmM6IEJyb3dzZXJDb25uZWN0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChiYy5zdGF0dXMgPT09IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzLmNsb3NlZCB8fCBiYy5zdGF0dXMgPT09IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzLmNsb3NpbmcpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgYXdhaXQgYmMuY2xvc2UoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF93YWl0Q29ubmVjdGlvbk9wZW5lZCAoYmM6IEJyb3dzZXJDb25uZWN0aW9uKTogUHJvbWlzZTxCcm93c2VyQ29ubmVjdGlvbj4ge1xuICAgICAgICBjb25zdCBvcGVuZWRUaW1lb3V0ID0gdGhpcy5fb3B0aW9ucy5icm93c2VySW5pdFRpbWVvdXQgfHwgYXdhaXQgYmMuZ2V0RGVmYXVsdEJyb3dzZXJJbml0VGltZW91dCgpO1xuICAgICAgICBjb25zdCB0aW1lb3V0RXJyICAgID0gbmV3IEdlbmVyYWxFcnJvcihSVU5USU1FX0VSUk9SUy5jYW5ub3RFc3RhYmxpc2hCcm93c2VyQ29ubmVjdGlvbik7XG4gICAgICAgIGNvbnN0IG9wZW5lZE9yRXJyb3IgPSBQcm9taXNlLnJhY2UoW1xuICAgICAgICAgICAgcHJvbWlzaWZ5RXZlbnQodGhpcywgJ2Vycm9yJyksXG4gICAgICAgICAgICBwcm9taXNpZnlFdmVudChiYywgJ29wZW5lZCcpLFxuICAgICAgICBdKTtcblxuICAgICAgICByZXR1cm4gZ2V0VGltZUxpbWl0ZWRQcm9taXNlKG9wZW5lZE9yRXJyb3IsIG9wZW5lZFRpbWVvdXQsIHsgcmVqZWN0V2l0aDogdGltZW91dEVyciB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF93YWl0Q29ubmVjdGlvbnNPcGVuZWQgKCk6IFByb21pc2U8QnJvd3NlckNvbm5lY3Rpb25bXT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICB0aGlzLl9icm93c2VyQ29ubmVjdGlvbnNcbiAgICAgICAgICAgICAgICAuZmlsdGVyKGJjID0+IGJjLnN0YXR1cyAhPT0gQnJvd3NlckNvbm5lY3Rpb25TdGF0dXMub3BlbmVkKVxuICAgICAgICAgICAgICAgIC5tYXAobm90T3BlbmVkQ29ubmVjdGlvbiA9PiB0aGlzLl93YWl0Q29ubmVjdGlvbk9wZW5lZChub3RPcGVuZWRDb25uZWN0aW9uKSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jaGVja0ZvckRpc2Nvbm5lY3Rpb25zICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdGVkVXNlckFnZW50cyA9IHRoaXMuX2Jyb3dzZXJDb25uZWN0aW9uc1xuICAgICAgICAgICAgLmZpbHRlcihiYyA9PiBiYy5zdGF0dXMgPT09IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzLmNsb3NlZClcbiAgICAgICAgICAgIC5tYXAoYmMgPT4gYmMudXNlckFnZW50KTtcblxuICAgICAgICBpZiAoZGlzY29ubmVjdGVkVXNlckFnZW50cy5sZW5ndGgpXG4gICAgICAgICAgICB0aHJvdyBuZXcgR2VuZXJhbEVycm9yKFJVTlRJTUVfRVJST1JTLmNhbm5vdFJ1bkFnYWluc3REaXNjb25uZWN0ZWRCcm93c2VycywgZGlzY29ubmVjdGVkVXNlckFnZW50cy5qb2luKCcsICcpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcHJlcGFyZUNvbm5lY3Rpb25zICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5fY2hlY2tGb3JEaXNjb25uZWN0aW9ucygpO1xuICAgICAgICBhd2FpdCB0aGlzLl93YWl0Q29ubmVjdGlvbnNPcGVuZWQoKTtcbiAgICB9XG5cbiAgICAvLyBOT1RFOiBjcmVhdGVzIGFuZCBwcmVwYXJlcyBCcm93c2VyU2V0IGluc3RhbmNlIHdpdGggZ2l2ZW4gYnJvd3NlciBjb25uZWN0aW9uc1xuICAgIHB1YmxpYyBzdGF0aWMgYXN5bmMgZnJvbSAoYnJvd3NlckNvbm5lY3Rpb25zOiBCcm93c2VyQ29ubmVjdGlvbltdW10sIG9wdHM6IEJyb3dzZXJTZXRPcHRpb25zKTogUHJvbWlzZTxCcm93c2VyU2V0PiB7XG4gICAgICAgIGNvbnN0IGJyb3dzZXJTZXQgPSBuZXcgQnJvd3NlclNldChicm93c2VyQ29ubmVjdGlvbnMsIG9wdHMpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwcmVwYXJlQ29ubmVjdGlvbnMgPSBicm93c2VyU2V0LnByZXBhcmVDb25uZWN0aW9ucygpO1xuICAgICAgICAgICAgY29uc3QgYnJvd3NlclNldEVycm9yICAgID0gcHJvbWlzaWZ5RXZlbnQoYnJvd3NlclNldCwgJ2Vycm9yJyk7XG5cbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UucmFjZShbIHByZXBhcmVDb25uZWN0aW9ucywgYnJvd3NlclNldEVycm9yIF0pO1xuXG4gICAgICAgICAgICByZXR1cm4gYnJvd3NlclNldDtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBjb25zdCBmaW5hbEVycm9yID0gZS5jb2RlID09PSBSVU5USU1FX0VSUk9SUy5jYW5ub3RFc3RhYmxpc2hCcm93c2VyQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgID8gYnJvd3NlclNldC5jcmVhdGVCcm93c2VyQ29ubmVjdGlvbkVycm9yKGUpXG4gICAgICAgICAgICAgICAgOiBlO1xuXG4gICAgICAgICAgICBhd2FpdCBicm93c2VyU2V0LmRpc3Bvc2UoKTtcblxuICAgICAgICAgICAgdGhyb3cgZmluYWxFcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVCcm93c2VyQ29ubmVjdGlvbkVycm9yIChlcnJvcjogRXJyb3IpOiBCcm93c2VyQ29ubmVjdGlvbkVycm9yIHtcbiAgICAgICAgY29uc3Qgbm90T3BlbmVkQ29ubmVjdGlvbnMgPSB0aGlzLl9icm93c2VyQ29ubmVjdGlvbnMuZmlsdGVyKGJjID0+IGJjLnN0YXR1cyAhPT0gQnJvd3NlckNvbm5lY3Rpb25TdGF0dXMub3BlbmVkKTtcblxuICAgICAgICBjb25zdCBudW1PZkFsbENvbm5lY3Rpb25zICAgICAgID0gdGhpcy5fYnJvd3NlckNvbm5lY3Rpb25zLmxlbmd0aDtcbiAgICAgICAgY29uc3QgbnVtT2ZOb3RPcGVuZWRDb25uZWN0aW9ucyA9IG5vdE9wZW5lZENvbm5lY3Rpb25zLmxlbmd0aDtcblxuICAgICAgICBjb25zdCBsaXN0T2ZOb3RPcGVuZWRDb25uZWN0aW9ucyA9IGNyZWF0ZUxpc3Qobm90T3BlbmVkQ29ubmVjdGlvbnMubWFwKGJjID0+IGJjLmJyb3dzZXJJbmZvLmFsaWFzKSk7XG4gICAgICAgIGNvbnN0IGxpc3RPZkhpbnRzICAgICAgICAgICAgICAgID0gY3JlYXRlTGlzdChnZXRCcm93c2VyQ29ubmVjdGlvbkhpbnRzKHRoaXMuX2Jyb3dzZXJDb25uZWN0aW9ucywgdGhpcy5fb3B0aW9ucykpO1xuXG4gICAgICAgIHJldHVybiBuZXcgQnJvd3NlckNvbm5lY3Rpb25FcnJvcihcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgICBudW1PZk5vdE9wZW5lZENvbm5lY3Rpb25zLFxuICAgICAgICAgICAgbnVtT2ZBbGxDb25uZWN0aW9ucyxcbiAgICAgICAgICAgIGxpc3RPZk5vdE9wZW5lZENvbm5lY3Rpb25zLFxuICAgICAgICAgICAgbGlzdE9mSGludHNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVsZWFzZUNvbm5lY3Rpb24gKGJjOiBCcm93c2VyQ29ubmVjdGlvbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuX2Jyb3dzZXJDb25uZWN0aW9ucy5pbmNsdWRlcyhiYykpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgcmVtb3ZlKHRoaXMuX2Jyb3dzZXJDb25uZWN0aW9ucywgYmMpO1xuXG4gICAgICAgIGJjLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIHRoaXMuX2Jyb3dzZXJFcnJvckhhbmRsZXIpO1xuXG4gICAgICAgIGNvbnN0IGFwcHJvcHJpYXRlU3RhdGVTd2l0Y2ggPSBiYy5wZXJtYW5lbnQgP1xuICAgICAgICAgICAgQnJvd3NlclNldC5fd2FpdElkbGUoYmMpIDpcbiAgICAgICAgICAgIEJyb3dzZXJTZXQuX2Nsb3NlQ29ubmVjdGlvbihiYyk7XG5cbiAgICAgICAgY29uc3QgcmVsZWFzZSA9IGdldFRpbWVMaW1pdGVkUHJvbWlzZShhcHByb3ByaWF0ZVN0YXRlU3dpdGNoLCBSRUxFQVNFX1RJTUVPVVQpXG4gICAgICAgICAgICAudGhlbigoKSA9PiByZW1vdmUodGhpcy5fcGVuZGluZ1JlbGVhc2VzLCByZWxlYXNlKSkgYXMgUHJvbWlzZTx2b2lkPjtcblxuICAgICAgICB0aGlzLl9wZW5kaW5nUmVsZWFzZXMucHVzaChyZWxlYXNlKTtcblxuICAgICAgICByZXR1cm4gcmVsZWFzZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBkaXNwb3NlICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gTk9URTogV2hlbiBicm93c2VyQ29ubmVjdGlvbiBpcyBjYW5jZWxsZWQsIGl0IGlzIHJlbW92ZWQgZnJvbVxuICAgICAgICAvLyB0aGUgdGhpcy5jb25uZWN0aW9ucyBhcnJheSwgd2hpY2ggbGVhZHMgdG8gc2hpZnRpbmcgaW5kZXhlc1xuICAgICAgICAvLyB0b3dhcmRzIHRoZSBiZWdpbm5pbmcuIFNvLCB3ZSBtdXN0IGNvcHkgdGhlIGFycmF5IGluIG9yZGVyIHRvIGl0ZXJhdGUgaXQsXG4gICAgICAgIC8vIG9yIHdlIGNhbiBwZXJmb3JtIGl0ZXJhdGlvbiBmcm9tIHRoZSBlbmQgdG8gdGhlIGJlZ2lubmluZy5cbiAgICAgICAgYXdhaXQgdGhpcy5fYnJvd3NlckNvbm5lY3Rpb25zLnJlZHVjZVJpZ2h0KGFzeW5jIChfLCBiYykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWxlYXNlQ29ubmVjdGlvbihiYyk7XG5cbiAgICAgICAgICAgIHJldHVybiBiYztcbiAgICAgICAgfSwgUHJvbWlzZS5yZXNvbHZlKHt9KSk7XG5cbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodGhpcy5fcGVuZGluZ1JlbGVhc2VzKTtcbiAgICB9XG59XG4iXX0=
|