"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter")); const test_run_controller_1 = __importDefault(require("./test-run-controller")); const session_controller_1 = __importDefault(require("../test-run/session-controller")); const browser_job_result_1 = __importDefault(require("./browser-job-result")); const test_run_hook_controller_1 = __importDefault(require("./test-run-hook-controller")); var BrowserJobStatus; (function (BrowserJobStatus) { BrowserJobStatus[BrowserJobStatus["initialized"] = 0] = "initialized"; BrowserJobStatus[BrowserJobStatus["starting"] = 1] = "starting"; BrowserJobStatus[BrowserJobStatus["started"] = 2] = "started"; })(BrowserJobStatus || (BrowserJobStatus = {})); class BrowserJob extends async_event_emitter_1.default { constructor({ tests, browserConnections, proxy, screenshots, warningLog, fixtureHookController, opts, compilerService, messageBus, }) { var _a; super(); this._status = BrowserJobStatus.initialized; this._startTime = new Date(); this._total = 0; this._passed = 0; this._opts = opts; this._proxy = proxy; this.browserConnections = browserConnections; this._screenshots = screenshots; this.warningLog = warningLog; this.fixtureHookController = fixtureHookController; this._result = null; this._messageBus = messageBus; this._testRunHook = new test_run_hook_controller_1.default(tests, (_a = opts.hooks) === null || _a === void 0 ? void 0 : _a.testRun); this._testRunControllerQueue = tests.map((test, index) => this._createTestRunController(test, index, compilerService)); this._completionQueue = []; this._reportsPending = []; this._connectionErrorListener = (error) => this._setResult(browser_job_result_1.default.errored, error); this._resolveWaitingLastTestInFixture = null; this.browserConnections.map(bc => bc.once('error', this._connectionErrorListener)); } _createTestRunController(test, index, compilerService) { const testRunController = new test_run_controller_1.default({ test, index: index + 1, proxy: this._proxy, screenshots: this._screenshots, warningLog: this.warningLog, fixtureHookController: this.fixtureHookController, opts: this._opts, messageBus: this._messageBus, compilerService, testRunHook: this._testRunHook, }); testRunController.on('test-run-create', async (testRunInfo) => { await this.emit('test-run-create', testRunInfo); }); testRunController.on('test-run-ready', async () => { await this.emit('test-run-ready', testRunController); }); testRunController.on('test-run-restart', async () => this._onTestRunRestart(testRunController)); testRunController.on('test-run-before-done', async () => { await this.emit('test-run-before-done', testRunController); }); testRunController.on('test-run-done', async () => this._onTestRunDone(testRunController)); testRunController.on('test-action-done', async (args) => { await this.emit('test-action-done', args); }); return testRunController; } async _setResult(status, data) { if (this._result) return; this._result = { status, data }; this.browserConnections.forEach(bc => bc.removeListener('error', this._connectionErrorListener)); await Promise.all(this.browserConnections.map(bc => bc.reportJobResult(this._result.status, this._result.data))); } _addToCompletionQueue(testRunInfo) { this._completionQueue.push(testRunInfo); } _removeFromCompletionQueue(testRunInfo) { (0, lodash_1.pull)(this._completionQueue, testRunInfo); } async _onTestRunRestart(testRunController) { this._removeFromCompletionQueue(testRunController); this._testRunControllerQueue.unshift(testRunController); await this.emit('test-run-restart', testRunController); } async _onTestRunDone(testRunController) { this._total++; if (!testRunController.testRun.errs.length) this._passed++; while (this._completionQueue.length && this._completionQueue[0].done) { testRunController = this._completionQueue.shift(); await this.emit('test-run-done', testRunController.testRun); (0, lodash_1.pull)(this._reportsPending, testRunController); if (!this._reportsPending.length && this._resolveWaitingLastTestInFixture) { this._resolveWaitingLastTestInFixture(); this._resolveWaitingLastTestInFixture = null; } } if (!this._completionQueue.length && !this.hasQueuedTestRuns) { if (!this._opts.live) session_controller_1.default.closeSession(testRunController.testRun); this ._setResult(browser_job_result_1.default.done, { total: this._total, passed: this._passed }) .then(() => this.emit('done')); } } async _isNextTestRunAvailable(testRunController) { // NOTE: event task start is currently executing, // so test run is temporary blocked if (this._status === BrowserJobStatus.starting) return false; // NOTE: before hook for test run fixture is currently // executing, so test run is temporary blocked const isBlocked = testRunController.blocked; const isConcurrency = this._opts.concurrency > 1; const hasIncompleteTestRuns = this._completionQueue.some(controller => !controller.done); const needWaitLastTestInFixture = this._reportsPending.some(controller => controller.test.fixture !== testRunController.test.fixture); if (isBlocked || (hasIncompleteTestRuns || needWaitLastTestInFixture) && !isConcurrency) { const disablePageReloads = testRunController.test.disablePageReloads || this._opts.disablePageReloads && testRunController.test.disablePageReloads !== false; if (!needWaitLastTestInFixture || !disablePageReloads) return false; // NOTE: if we have `disablePageReloads` enabled and the next test is from next // fixture, then we need to wait until all reporters finished to prevent // redirecting to the `idle` page await new Promise(resolve => { this._resolveWaitingLastTestInFixture = resolve; }); } return true; } // API get hasQueuedTestRuns() { return !!this._testRunControllerQueue.length; } get currentTestRun() { return this._completionQueue.length ? this._completionQueue[0].testRun : null; } async popNextTestRunInfo(connection) { while (this._testRunControllerQueue.length) { const testRunController = this._testRunControllerQueue[0]; const isNextTestRunAvailable = await this._isNextTestRunAvailable(testRunController); if (!isNextTestRunAvailable) break; this._reportsPending.push(testRunController); this._testRunControllerQueue.shift(); this._addToCompletionQueue(testRunController); if (this._status === BrowserJobStatus.initialized) { this._status = BrowserJobStatus.starting; this._startTime = new Date(); await this.emit('start', this._startTime); this._status = BrowserJobStatus.started; } const testRunUrl = await testRunController.start(connection, this._startTime); if (testRunUrl) { return { testRunId: testRunController.testRun.id, url: testRunUrl, }; } } return null; } abort() { this.clearListeners(); this._setResult(browser_job_result_1.default.aborted); this.browserConnections.map(bc => bc.removeJob(this)); } } exports.default = BrowserJob; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVubmVyL2Jyb3dzZXItam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQXdDO0FBQ3hDLHVGQUE2RDtBQUM3RCxnRkFBc0Q7QUFDdEQsd0ZBQStEO0FBUS9ELDhFQUFvRDtBQUlwRCwwRkFBK0Q7QUFXL0QsSUFBSyxnQkFBbUQ7QUFBeEQsV0FBSyxnQkFBZ0I7SUFBRyxxRUFBVyxDQUFBO0lBQUUsK0RBQVEsQ0FBQTtJQUFFLDZEQUFPLENBQUE7QUFBQyxDQUFDLEVBQW5ELGdCQUFnQixLQUFoQixnQkFBZ0IsUUFBbUM7QUFFeEQsTUFBcUIsVUFBVyxTQUFRLDZCQUFpQjtJQW9CckQsWUFBb0IsRUFDaEIsS0FBSyxFQUNMLGtCQUFrQixFQUNsQixLQUFLLEVBQ0wsV0FBVyxFQUNYLFVBQVUsRUFDVixxQkFBcUIsRUFDckIsSUFBSSxFQUNKLGVBQWUsRUFDZixVQUFVLEdBQ0c7O1FBQ2IsS0FBSyxFQUFFLENBQUM7UUFFUixJQUFJLENBQUMsT0FBTyxHQUFHLGdCQUFnQixDQUFDLFdBQVcsQ0FBQztRQUM1QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFFN0IsSUFBSSxDQUFDLE1BQU0sR0FBa0IsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLEdBQWlCLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsS0FBSyxHQUFtQixJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBa0IsS0FBSyxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0IsR0FBTSxrQkFBa0IsQ0FBQztRQUNoRCxJQUFJLENBQUMsWUFBWSxHQUFZLFdBQVcsQ0FBQztRQUN6QyxJQUFJLENBQUMsVUFBVSxHQUFjLFVBQVUsQ0FBQztRQUN4QyxJQUFJLENBQUMscUJBQXFCLEdBQUcscUJBQXFCLENBQUM7UUFDbkQsSUFBSSxDQUFDLE9BQU8sR0FBaUIsSUFBSSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxXQUFXLEdBQWEsVUFBVSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxZQUFZLEdBQVksSUFBSSxrQ0FBcUIsQ0FBQyxLQUFLLEVBQUUsTUFBQyxJQUFJLENBQUMsS0FBcUIsMENBQUUsT0FBTyxDQUFDLENBQUM7UUFFcEcsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO1FBRXZILElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDM0IsSUFBSSxDQUFDLGVBQWUsR0FBSSxFQUFFLENBQUM7UUFFM0IsSUFBSSxDQUFDLHdCQUF3QixHQUFHLENBQUMsS0FBWSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLDRCQUFnQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVuRyxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDO1FBRTdDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFTyx3QkFBd0IsQ0FBRSxJQUFVLEVBQUUsS0FBYSxFQUFFLGVBQWlDO1FBQzFGLE1BQU0saUJBQWlCLEdBQUcsSUFBSSw2QkFBaUIsQ0FBQztZQUM1QyxJQUFJO1lBQ0osS0FBSyxFQUFrQixLQUFLLEdBQUcsQ0FBQztZQUNoQyxLQUFLLEVBQWtCLElBQUksQ0FBQyxNQUFNO1lBQ2xDLFdBQVcsRUFBWSxJQUFJLENBQUMsWUFBWTtZQUN4QyxVQUFVLEVBQWEsSUFBSSxDQUFDLFVBQVU7WUFDdEMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLHFCQUFxQjtZQUNqRCxJQUFJLEVBQW1CLElBQUksQ0FBQyxLQUFLO1lBQ2pDLFVBQVUsRUFBYSxJQUFJLENBQUMsV0FBVztZQUN2QyxlQUFlO1lBQ2YsV0FBVyxFQUFZLElBQUksQ0FBQyxZQUFZO1NBQzNDLENBQUMsQ0FBQztRQUVILGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLEVBQUMsV0FBVyxFQUFDLEVBQUU7WUFDeEQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQyxDQUFDO1FBQ0gsaUJBQWlCLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3pELENBQUMsQ0FBQyxDQUFDO1FBQ0gsaUJBQWlCLENBQUMsRUFBRSxDQUFDLGtCQUFrQixFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztRQUNoRyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsc0JBQXNCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDcEQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFDL0QsQ0FBQyxDQUFDLENBQUM7UUFDSCxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsZUFBZSxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7UUFFMUYsaUJBQWlCLENBQUMsRUFBRSxDQUFDLGtCQUFrQixFQUFFLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtZQUNsRCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGlCQUFpQixDQUFDO0lBQzdCLENBQUM7SUFFTyxLQUFLLENBQUMsVUFBVSxDQUFFLE1BQXdCLEVBQUUsSUFBVTtRQUMxRCxJQUFJLElBQUksQ0FBQyxPQUFPO1lBQ1osT0FBTztRQUVYLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFFaEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7UUFFakcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFFLElBQUksQ0FBQyxPQUFnQyxDQUFDLE1BQU0sRUFBRyxJQUFJLENBQUMsT0FBZ0MsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekssQ0FBQztJQUVPLHFCQUFxQixDQUFFLFdBQThCO1FBQ3pELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVPLDBCQUEwQixDQUFFLFdBQThCO1FBQzlELElBQUEsYUFBTSxFQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU8sS0FBSyxDQUFDLGlCQUFpQixDQUFFLGlCQUFvQztRQUNqRSxJQUFJLENBQUMsMEJBQTBCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFeEQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVPLEtBQUssQ0FBQyxjQUFjLENBQUUsaUJBQW9DO1FBQzlELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU07WUFDdEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRW5CLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFO1lBQ2xFLGlCQUFpQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQXVCLENBQUM7WUFFdkUsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU1RCxJQUFBLGFBQU0sRUFBQyxJQUFJLENBQUMsZUFBZSxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFFaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtnQkFDdkUsSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7Z0JBRXhDLElBQUksQ0FBQyxnQ0FBZ0MsR0FBRyxJQUFJLENBQUM7YUFDaEQ7U0FDSjtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLDRCQUFpQixDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU5RCxJQUFJO2lCQUNDLFVBQVUsQ0FBQyw0QkFBZ0IsQ0FBQyxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2lCQUMvRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ3RDO0lBQ0wsQ0FBQztJQUVPLEtBQUssQ0FBQyx1QkFBdUIsQ0FBRSxpQkFBb0M7UUFDdkUsaURBQWlEO1FBQ2pELG1DQUFtQztRQUNuQyxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssZ0JBQWdCLENBQUMsUUFBUTtZQUMxQyxPQUFPLEtBQUssQ0FBQztRQUVqQixzREFBc0Q7UUFDdEQsOENBQThDO1FBQzlDLE1BQU0sU0FBUyxHQUFtQixpQkFBaUIsQ0FBQyxPQUFPLENBQUM7UUFDNUQsTUFBTSxhQUFhLEdBQWUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFxQixHQUFHLENBQUMsQ0FBQztRQUN2RSxNQUFNLHFCQUFxQixHQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3RixNQUFNLHlCQUF5QixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXRJLElBQUksU0FBUyxJQUFJLENBQUMscUJBQXFCLElBQUkseUJBQXlCLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNyRixNQUFNLGtCQUFrQixHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxrQkFBa0I7Z0JBQ2hFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLGtCQUFrQixLQUFLLEtBQUssQ0FBQztZQUV6RixJQUFJLENBQUMseUJBQXlCLElBQUksQ0FBQyxrQkFBa0I7Z0JBQ2pELE9BQU8sS0FBSyxDQUFDO1lBRWpCLCtFQUErRTtZQUMvRSx3RUFBd0U7WUFDeEUsaUNBQWlDO1lBQ2pDLE1BQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyxnQ0FBZ0MsR0FBRyxPQUFPLENBQUM7WUFDcEQsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNO0lBQ04sSUFBVyxpQkFBaUI7UUFDeEIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQztJQUNqRCxDQUFDO0lBRUQsSUFBVyxjQUFjO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2xGLENBQUM7SUFFTSxLQUFLLENBQUMsa0JBQWtCLENBQUUsVUFBNkI7UUFDMUQsT0FBTyxJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxFQUFFO1lBQ3hDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTFELE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUVyRixJQUFJLENBQUMsc0JBQXNCO2dCQUN2QixNQUFNO1lBRVYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFFOUMsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLGdCQUFnQixDQUFDLFdBQVcsRUFBRTtnQkFDL0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxVQUFVLEdBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFFL0IsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBRTFDLElBQUksQ0FBQyxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO2FBQzNDO1lBRUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUU5RSxJQUFJLFVBQVUsRUFBRTtnQkFDWixPQUFPO29CQUNILFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsRUFBRTtvQkFDdkMsR0FBRyxFQUFRLFVBQVU7aUJBQ3hCLENBQUM7YUFDTDtTQUNKO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVNLEtBQUs7UUFDUixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyw0QkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FDSjtBQXJPRCw2QkFxT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwdWxsIGFzIHJlbW92ZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgQXN5bmNFdmVudEVtaXR0ZXIgZnJvbSAnLi4vdXRpbHMvYXN5bmMtZXZlbnQtZW1pdHRlcic7XG5pbXBvcnQgVGVzdFJ1bkNvbnRyb2xsZXIgZnJvbSAnLi90ZXN0LXJ1bi1jb250cm9sbGVyJztcbmltcG9ydCBTZXNzaW9uQ29udHJvbGxlciBmcm9tICcuLi90ZXN0LXJ1bi9zZXNzaW9uLWNvbnRyb2xsZXInO1xuaW1wb3J0IEJyb3dzZXJDb25uZWN0aW9uIGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbic7XG5pbXBvcnQgeyBQcm94eSB9IGZyb20gJ3Rlc3RjYWZlLWhhbW1lcmhlYWQnO1xuaW1wb3J0IFRlc3QgZnJvbSAnLi4vYXBpL3N0cnVjdHVyZS90ZXN0JztcbmltcG9ydCBTY3JlZW5zaG90cyBmcm9tICcuLi9zY3JlZW5zaG90cyc7XG5pbXBvcnQgV2FybmluZ0xvZyBmcm9tICcuLi9ub3RpZmljYXRpb25zL3dhcm5pbmctbG9nJztcbmltcG9ydCBGaXh0dXJlSG9va0NvbnRyb2xsZXIgZnJvbSAnLi9maXh0dXJlLWhvb2stY29udHJvbGxlcic7XG5pbXBvcnQgeyBEaWN0aW9uYXJ5IH0gZnJvbSAnLi4vY29uZmlndXJhdGlvbi9pbnRlcmZhY2VzJztcbmltcG9ydCBCcm93c2VySm9iUmVzdWx0IGZyb20gJy4vYnJvd3Nlci1qb2ItcmVzdWx0JztcbmltcG9ydCBDb21waWxlclNlcnZpY2UgZnJvbSAnLi4vc2VydmljZXMvY29tcGlsZXIvaG9zdCc7XG5pbXBvcnQgeyBCcm93c2VySm9iSW5pdCB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgTWVzc2FnZUJ1cyBmcm9tICcuLi91dGlscy9tZXNzYWdlLWJ1cyc7XG5pbXBvcnQgVGVzdFJ1bkhvb2tDb250cm9sbGVyIGZyb20gJy4vdGVzdC1ydW4taG9vay1jb250cm9sbGVyJztcbmltcG9ydCBUZXN0UnVuIGZyb20gJy4uL3Rlc3QtcnVuJztcbi8vIEB0cy1pZ25vcmVcbmltcG9ydCB7IFRlc3RSdW4gYXMgTGVnYWN5VGVzdFJ1biB9IGZyb20gJ3Rlc3RjYWZlLWxlZ2FjeS1hcGknO1xuaW1wb3J0IHsgTmV4dFRlc3RSdW5JbmZvIH0gZnJvbSAnLi4vc2hhcmVkL3R5cGVzJztcblxuaW50ZXJmYWNlIEJyb3dzZXJKb2JSZXN1bHRJbmZvIHtcbiAgICBzdGF0dXM6IEJyb3dzZXJKb2JSZXN1bHQ7XG4gICAgZGF0YT86IGFueTtcbn1cblxuZW51bSBCcm93c2VySm9iU3RhdHVzIHsgaW5pdGlhbGl6ZWQsIHN0YXJ0aW5nLCBzdGFydGVkIH1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnJvd3NlckpvYiBleHRlbmRzIEFzeW5jRXZlbnRFbWl0dGVyIHtcbiAgICBwcml2YXRlIF9zdGF0dXM6IEJyb3dzZXJKb2JTdGF0dXM7XG4gICAgcHJpdmF0ZSBfc3RhcnRUaW1lOiBEYXRlO1xuICAgIHByaXZhdGUgX3RvdGFsOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBfcGFzc2VkOiBudW1iZXI7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfb3B0czogRGljdGlvbmFyeTxPcHRpb25WYWx1ZT47XG4gICAgcHJpdmF0ZSByZWFkb25seSBfcHJveHk6IFByb3h5O1xuICAgIHB1YmxpYyByZWFkb25seSBicm93c2VyQ29ubmVjdGlvbnM6IEJyb3dzZXJDb25uZWN0aW9uW107XG4gICAgcHJpdmF0ZSByZWFkb25seSBfc2NyZWVuc2hvdHM6IFNjcmVlbnNob3RzO1xuICAgIHB1YmxpYyByZWFkb25seSB3YXJuaW5nTG9nOiBXYXJuaW5nTG9nO1xuICAgIHB1YmxpYyByZWFkb25seSBmaXh0dXJlSG9va0NvbnRyb2xsZXI6IEZpeHR1cmVIb29rQ29udHJvbGxlcjtcbiAgICBwcml2YXRlIF9yZXN1bHQ6IEJyb3dzZXJKb2JSZXN1bHRJbmZvIHwgbnVsbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF90ZXN0UnVuQ29udHJvbGxlclF1ZXVlOiBUZXN0UnVuQ29udHJvbGxlcltdO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3JlcG9ydHNQZW5kaW5nOiBUZXN0UnVuQ29udHJvbGxlcltdO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2Nvbm5lY3Rpb25FcnJvckxpc3RlbmVyOiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbXBsZXRpb25RdWV1ZTogVGVzdFJ1bkNvbnRyb2xsZXJbXTtcbiAgICBwcml2YXRlIF9yZXNvbHZlV2FpdGluZ0xhc3RUZXN0SW5GaXh0dXJlOiBGdW5jdGlvbiB8IG51bGw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZUJ1czogTWVzc2FnZUJ1cztcbiAgICBwcml2YXRlIHJlYWRvbmx5IF90ZXN0UnVuSG9vazogVGVzdFJ1bkhvb2tDb250cm9sbGVyO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yICh7XG4gICAgICAgIHRlc3RzLFxuICAgICAgICBicm93c2VyQ29ubmVjdGlvbnMsXG4gICAgICAgIHByb3h5LFxuICAgICAgICBzY3JlZW5zaG90cyxcbiAgICAgICAgd2FybmluZ0xvZyxcbiAgICAgICAgZml4dHVyZUhvb2tDb250cm9sbGVyLFxuICAgICAgICBvcHRzLFxuICAgICAgICBjb21waWxlclNlcnZpY2UsXG4gICAgICAgIG1lc3NhZ2VCdXMsXG4gICAgfTogQnJvd3NlckpvYkluaXQpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLl9zdGF0dXMgPSBCcm93c2VySm9iU3RhdHVzLmluaXRpYWxpemVkO1xuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgIHRoaXMuX3RvdGFsICAgICAgICAgICAgICAgID0gMDtcbiAgICAgICAgdGhpcy5fcGFzc2VkICAgICAgICAgICAgICAgPSAwO1xuICAgICAgICB0aGlzLl9vcHRzICAgICAgICAgICAgICAgICA9IG9wdHM7XG4gICAgICAgIHRoaXMuX3Byb3h5ICAgICAgICAgICAgICAgID0gcHJveHk7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zICAgID0gYnJvd3NlckNvbm5lY3Rpb25zO1xuICAgICAgICB0aGlzLl9zY3JlZW5zaG90cyAgICAgICAgICA9IHNjcmVlbnNob3RzO1xuICAgICAgICB0aGlzLndhcm5pbmdMb2cgICAgICAgICAgICA9IHdhcm5pbmdMb2c7XG4gICAgICAgIHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyID0gZml4dHVyZUhvb2tDb250cm9sbGVyO1xuICAgICAgICB0aGlzLl9yZXN1bHQgICAgICAgICAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuX21lc3NhZ2VCdXMgICAgICAgICAgID0gbWVzc2FnZUJ1cztcbiAgICAgICAgdGhpcy5fdGVzdFJ1bkhvb2sgICAgICAgICAgPSBuZXcgVGVzdFJ1bkhvb2tDb250cm9sbGVyKHRlc3RzLCAob3B0cy5ob29rcyBhcyBHbG9iYWxIb29rcyk/LnRlc3RSdW4pO1xuXG4gICAgICAgIHRoaXMuX3Rlc3RSdW5Db250cm9sbGVyUXVldWUgPSB0ZXN0cy5tYXAoKHRlc3QsIGluZGV4KSA9PiB0aGlzLl9jcmVhdGVUZXN0UnVuQ29udHJvbGxlcih0ZXN0LCBpbmRleCwgY29tcGlsZXJTZXJ2aWNlKSk7XG5cbiAgICAgICAgdGhpcy5fY29tcGxldGlvblF1ZXVlID0gW107XG4gICAgICAgIHRoaXMuX3JlcG9ydHNQZW5kaW5nICA9IFtdO1xuXG4gICAgICAgIHRoaXMuX2Nvbm5lY3Rpb25FcnJvckxpc3RlbmVyID0gKGVycm9yOiBFcnJvcikgPT4gdGhpcy5fc2V0UmVzdWx0KEJyb3dzZXJKb2JSZXN1bHQuZXJyb3JlZCwgZXJyb3IpO1xuXG4gICAgICAgIHRoaXMuX3Jlc29sdmVXYWl0aW5nTGFzdFRlc3RJbkZpeHR1cmUgPSBudWxsO1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLm1hcChiYyA9PiBiYy5vbmNlKCdlcnJvcicsIHRoaXMuX2Nvbm5lY3Rpb25FcnJvckxpc3RlbmVyKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JlYXRlVGVzdFJ1bkNvbnRyb2xsZXIgKHRlc3Q6IFRlc3QsIGluZGV4OiBudW1iZXIsIGNvbXBpbGVyU2VydmljZT86IENvbXBpbGVyU2VydmljZSk6IFRlc3RSdW5Db250cm9sbGVyIHtcbiAgICAgICAgY29uc3QgdGVzdFJ1bkNvbnRyb2xsZXIgPSBuZXcgVGVzdFJ1bkNvbnRyb2xsZXIoe1xuICAgICAgICAgICAgdGVzdCxcbiAgICAgICAgICAgIGluZGV4OiAgICAgICAgICAgICAgICAgaW5kZXggKyAxLFxuICAgICAgICAgICAgcHJveHk6ICAgICAgICAgICAgICAgICB0aGlzLl9wcm94eSxcbiAgICAgICAgICAgIHNjcmVlbnNob3RzOiAgICAgICAgICAgdGhpcy5fc2NyZWVuc2hvdHMsXG4gICAgICAgICAgICB3YXJuaW5nTG9nOiAgICAgICAgICAgIHRoaXMud2FybmluZ0xvZyxcbiAgICAgICAgICAgIGZpeHR1cmVIb29rQ29udHJvbGxlcjogdGhpcy5maXh0dXJlSG9va0NvbnRyb2xsZXIsXG4gICAgICAgICAgICBvcHRzOiAgICAgICAgICAgICAgICAgIHRoaXMuX29wdHMsXG4gICAgICAgICAgICBtZXNzYWdlQnVzOiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VCdXMsXG4gICAgICAgICAgICBjb21waWxlclNlcnZpY2UsXG4gICAgICAgICAgICB0ZXN0UnVuSG9vazogICAgICAgICAgIHRoaXMuX3Rlc3RSdW5Ib29rLFxuICAgICAgICB9KTtcblxuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tY3JlYXRlJywgYXN5bmMgdGVzdFJ1bkluZm8gPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1jcmVhdGUnLCB0ZXN0UnVuSW5mbyk7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tcmVhZHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLXJlYWR5JywgdGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIub24oJ3Rlc3QtcnVuLXJlc3RhcnQnLCBhc3luYyAoKSA9PiB0aGlzLl9vblRlc3RSdW5SZXN0YXJ0KHRlc3RSdW5Db250cm9sbGVyKSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1iZWZvcmUtZG9uZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tYmVmb3JlLWRvbmUnLCB0ZXN0UnVuQ29udHJvbGxlcik7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tZG9uZScsIGFzeW5jICgpID0+IHRoaXMuX29uVGVzdFJ1bkRvbmUodGVzdFJ1bkNvbnRyb2xsZXIpKTtcblxuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1hY3Rpb24tZG9uZScsIGFzeW5jIGFyZ3MgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LWFjdGlvbi1kb25lJywgYXJncyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0ZXN0UnVuQ29udHJvbGxlcjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9zZXRSZXN1bHQgKHN0YXR1czogQnJvd3NlckpvYlJlc3VsdCwgZGF0YT86IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5fcmVzdWx0KVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuX3Jlc3VsdCA9IHsgc3RhdHVzLCBkYXRhIH07XG5cbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbnMuZm9yRWFjaChiYyA9PiBiYy5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCB0aGlzLl9jb25uZWN0aW9uRXJyb3JMaXN0ZW5lcikpO1xuXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLm1hcChiYyA9PiBiYy5yZXBvcnRKb2JSZXN1bHQoKHRoaXMuX3Jlc3VsdCBhcyBCcm93c2VySm9iUmVzdWx0SW5mbykuc3RhdHVzLCAodGhpcy5fcmVzdWx0IGFzIEJyb3dzZXJKb2JSZXN1bHRJbmZvKS5kYXRhKSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2FkZFRvQ29tcGxldGlvblF1ZXVlICh0ZXN0UnVuSW5mbzogVGVzdFJ1bkNvbnRyb2xsZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fY29tcGxldGlvblF1ZXVlLnB1c2godGVzdFJ1bkluZm8pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3JlbW92ZUZyb21Db21wbGV0aW9uUXVldWUgKHRlc3RSdW5JbmZvOiBUZXN0UnVuQ29udHJvbGxlcik6IHZvaWQge1xuICAgICAgICByZW1vdmUodGhpcy5fY29tcGxldGlvblF1ZXVlLCB0ZXN0UnVuSW5mbyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfb25UZXN0UnVuUmVzdGFydCAodGVzdFJ1bkNvbnRyb2xsZXI6IFRlc3RSdW5Db250cm9sbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuX3JlbW92ZUZyb21Db21wbGV0aW9uUXVldWUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgICAgICB0aGlzLl90ZXN0UnVuQ29udHJvbGxlclF1ZXVlLnVuc2hpZnQodGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tcmVzdGFydCcsIHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9vblRlc3RSdW5Eb25lICh0ZXN0UnVuQ29udHJvbGxlcjogVGVzdFJ1bkNvbnRyb2xsZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5fdG90YWwrKztcblxuICAgICAgICBpZiAoIXRlc3RSdW5Db250cm9sbGVyLnRlc3RSdW4uZXJycy5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLl9wYXNzZWQrKztcblxuICAgICAgICB3aGlsZSAodGhpcy5fY29tcGxldGlvblF1ZXVlLmxlbmd0aCAmJiB0aGlzLl9jb21wbGV0aW9uUXVldWVbMF0uZG9uZSkge1xuICAgICAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIgPSB0aGlzLl9jb21wbGV0aW9uUXVldWUuc2hpZnQoKSBhcyBUZXN0UnVuQ29udHJvbGxlcjtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1kb25lJywgdGVzdFJ1bkNvbnRyb2xsZXIudGVzdFJ1bik7XG5cbiAgICAgICAgICAgIHJlbW92ZSh0aGlzLl9yZXBvcnRzUGVuZGluZywgdGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuX3JlcG9ydHNQZW5kaW5nLmxlbmd0aCAmJiB0aGlzLl9yZXNvbHZlV2FpdGluZ0xhc3RUZXN0SW5GaXh0dXJlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZVdhaXRpbmdMYXN0VGVzdEluRml4dHVyZSgpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZVdhaXRpbmdMYXN0VGVzdEluRml4dHVyZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2NvbXBsZXRpb25RdWV1ZS5sZW5ndGggJiYgIXRoaXMuaGFzUXVldWVkVGVzdFJ1bnMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fb3B0cy5saXZlKVxuICAgICAgICAgICAgICAgIFNlc3Npb25Db250cm9sbGVyLmNsb3NlU2Vzc2lvbih0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuKTtcblxuICAgICAgICAgICAgdGhpc1xuICAgICAgICAgICAgICAgIC5fc2V0UmVzdWx0KEJyb3dzZXJKb2JSZXN1bHQuZG9uZSwgeyB0b3RhbDogdGhpcy5fdG90YWwsIHBhc3NlZDogdGhpcy5fcGFzc2VkIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5lbWl0KCdkb25lJykpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfaXNOZXh0VGVzdFJ1bkF2YWlsYWJsZSAodGVzdFJ1bkNvbnRyb2xsZXI6IFRlc3RSdW5Db250cm9sbGVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIC8vIE5PVEU6IGV2ZW50IHRhc2sgc3RhcnQgaXMgY3VycmVudGx5IGV4ZWN1dGluZyxcbiAgICAgICAgLy8gc28gdGVzdCBydW4gaXMgdGVtcG9yYXJ5IGJsb2NrZWRcbiAgICAgICAgaWYgKHRoaXMuX3N0YXR1cyA9PT0gQnJvd3NlckpvYlN0YXR1cy5zdGFydGluZylcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBOT1RFOiBiZWZvcmUgaG9vayBmb3IgdGVzdCBydW4gZml4dHVyZSBpcyBjdXJyZW50bHlcbiAgICAgICAgLy8gZXhlY3V0aW5nLCBzbyB0ZXN0IHJ1biBpcyB0ZW1wb3JhcnkgYmxvY2tlZFxuICAgICAgICBjb25zdCBpc0Jsb2NrZWQgICAgICAgICAgICAgICAgID0gdGVzdFJ1bkNvbnRyb2xsZXIuYmxvY2tlZDtcbiAgICAgICAgY29uc3QgaXNDb25jdXJyZW5jeSAgICAgICAgICAgICA9IHRoaXMuX29wdHMuY29uY3VycmVuY3kgYXMgbnVtYmVyID4gMTtcbiAgICAgICAgY29uc3QgaGFzSW5jb21wbGV0ZVRlc3RSdW5zICAgICA9IHRoaXMuX2NvbXBsZXRpb25RdWV1ZS5zb21lKGNvbnRyb2xsZXIgPT4gIWNvbnRyb2xsZXIuZG9uZSk7XG4gICAgICAgIGNvbnN0IG5lZWRXYWl0TGFzdFRlc3RJbkZpeHR1cmUgPSB0aGlzLl9yZXBvcnRzUGVuZGluZy5zb21lKGNvbnRyb2xsZXIgPT4gY29udHJvbGxlci50ZXN0LmZpeHR1cmUgIT09IHRlc3RSdW5Db250cm9sbGVyLnRlc3QuZml4dHVyZSk7XG5cbiAgICAgICAgaWYgKGlzQmxvY2tlZCB8fCAoaGFzSW5jb21wbGV0ZVRlc3RSdW5zIHx8IG5lZWRXYWl0TGFzdFRlc3RJbkZpeHR1cmUpICYmICFpc0NvbmN1cnJlbmN5KSB7XG4gICAgICAgICAgICBjb25zdCBkaXNhYmxlUGFnZVJlbG9hZHMgPSB0ZXN0UnVuQ29udHJvbGxlci50ZXN0LmRpc2FibGVQYWdlUmVsb2FkcyB8fFxuICAgICAgICAgICAgICAgIHRoaXMuX29wdHMuZGlzYWJsZVBhZ2VSZWxvYWRzICYmIHRlc3RSdW5Db250cm9sbGVyLnRlc3QuZGlzYWJsZVBhZ2VSZWxvYWRzICE9PSBmYWxzZTtcblxuICAgICAgICAgICAgaWYgKCFuZWVkV2FpdExhc3RUZXN0SW5GaXh0dXJlIHx8ICFkaXNhYmxlUGFnZVJlbG9hZHMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBOT1RFOiBpZiB3ZSBoYXZlIGBkaXNhYmxlUGFnZVJlbG9hZHNgIGVuYWJsZWQgYW5kIHRoZSBuZXh0IHRlc3QgaXMgZnJvbSBuZXh0XG4gICAgICAgICAgICAvLyBmaXh0dXJlLCB0aGVuIHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBhbGwgcmVwb3J0ZXJzIGZpbmlzaGVkIHRvIHByZXZlbnRcbiAgICAgICAgICAgIC8vIHJlZGlyZWN0aW5nIHRvIHRoZSBgaWRsZWAgcGFnZVxuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZVdhaXRpbmdMYXN0VGVzdEluRml4dHVyZSA9IHJlc29sdmU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEFQSVxuICAgIHB1YmxpYyBnZXQgaGFzUXVldWVkVGVzdFJ1bnMgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLl90ZXN0UnVuQ29udHJvbGxlclF1ZXVlLmxlbmd0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGN1cnJlbnRUZXN0UnVuICgpOiBMZWdhY3lUZXN0UnVuIHwgVGVzdFJ1biB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tcGxldGlvblF1ZXVlLmxlbmd0aCA/IHRoaXMuX2NvbXBsZXRpb25RdWV1ZVswXS50ZXN0UnVuIDogbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcG9wTmV4dFRlc3RSdW5JbmZvIChjb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbik6IFByb21pc2U8TmV4dFRlc3RSdW5JbmZvIHwgbnVsbD4ge1xuICAgICAgICB3aGlsZSAodGhpcy5fdGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHRlc3RSdW5Db250cm9sbGVyID0gdGhpcy5fdGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZVswXTtcblxuICAgICAgICAgICAgY29uc3QgaXNOZXh0VGVzdFJ1bkF2YWlsYWJsZSA9IGF3YWl0IHRoaXMuX2lzTmV4dFRlc3RSdW5BdmFpbGFibGUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgICAgICBpZiAoIWlzTmV4dFRlc3RSdW5BdmFpbGFibGUpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIHRoaXMuX3JlcG9ydHNQZW5kaW5nLnB1c2godGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgdGhpcy5fdGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgdGhpcy5fYWRkVG9Db21wbGV0aW9uUXVldWUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdHVzID09PSBCcm93c2VySm9iU3RhdHVzLmluaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdHVzID0gQnJvd3NlckpvYlN0YXR1cy5zdGFydGluZztcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydFRpbWUgICA9IG5ldyBEYXRlKCk7XG5cbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3N0YXJ0JywgdGhpcy5fc3RhcnRUaW1lKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXR1cyA9IEJyb3dzZXJKb2JTdGF0dXMuc3RhcnRlZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGVzdFJ1blVybCA9IGF3YWl0IHRlc3RSdW5Db250cm9sbGVyLnN0YXJ0KGNvbm5lY3Rpb24sIHRoaXMuX3N0YXJ0VGltZSk7XG5cbiAgICAgICAgICAgIGlmICh0ZXN0UnVuVXJsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdGVzdFJ1bklkOiB0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuLmlkLFxuICAgICAgICAgICAgICAgICAgICB1cmw6ICAgICAgIHRlc3RSdW5VcmwsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHB1YmxpYyBhYm9ydCAoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2xlYXJMaXN0ZW5lcnMoKTtcbiAgICAgICAgdGhpcy5fc2V0UmVzdWx0KEJyb3dzZXJKb2JSZXN1bHQuYWJvcnRlZCk7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLm1hcChiYyA9PiBiYy5yZW1vdmVKb2IodGhpcykpO1xuICAgIH1cbn1cbiJdfQ==