Innovenergy_trunk/frontend/node_modules/testcafe/lib/test-run/index.js

1131 lines
197 KiB
JavaScript

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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 nanoid_1 = require("nanoid");
const read_file_relative_1 = require("read-file-relative");
const promisify_event_1 = __importDefault(require("promisify-event"));
const mustache_1 = __importDefault(require("mustache"));
const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
const debug_log_1 = __importDefault(require("./debug-log"));
const formattable_adapter_1 = __importDefault(require("../errors/test-run/formattable-adapter"));
const error_list_1 = __importDefault(require("../errors/error-list"));
const runtime_1 = require("../errors/runtime");
const test_run_1 = require("../errors/test-run/");
const client_messages_1 = __importDefault(require("./client-messages"));
const type_1 = __importDefault(require("./commands/type"));
const delay_1 = __importDefault(require("../utils/delay"));
const is_password_input_1 = __importDefault(require("../utils/is-password-input"));
const marker_symbol_1 = __importDefault(require("./marker-symbol"));
const test_run_tracker_1 = __importDefault(require("../api/test-run-tracker"));
const phase_1 = __importDefault(require("../role/phase"));
const plugin_host_1 = __importDefault(require("../reporter/plugin-host"));
const browser_console_messages_1 = __importDefault(require("./browser-console-messages"));
const warning_log_1 = __importDefault(require("../notifications/warning-log"));
const warning_message_1 = __importDefault(require("../notifications/warning-message"));
const testcafe_hammerhead_1 = require("testcafe-hammerhead");
const INJECTABLES = __importStar(require("../assets/injectables"));
const utils_1 = require("../custom-client-scripts/utils");
const get_url_1 = __importDefault(require("../custom-client-scripts/get-url"));
const string_1 = require("../utils/string");
const utils_2 = require("./commands/utils");
const actions_1 = require("./commands/actions");
const types_1 = require("../errors/types");
const process_test_fn_error_1 = __importDefault(require("../errors/process-test-fn-error"));
const hook_method_names_1 = __importDefault(require("../api/request-hooks/hook-method-names"));
const replicator_1 = require("../client-functions/replicator");
const session_controller_1 = __importDefault(require("./session-controller"));
const browser_manipulation_queue_1 = __importDefault(require("./browser-manipulation-queue"));
const observed_callsites_storage_1 = __importDefault(require("./observed-callsites-storage"));
const base_js_1 = require("./commands/base.js");
const get_assertion_timeout_1 = __importDefault(require("../utils/get-options/get-assertion-timeout"));
const phase_2 = __importDefault(require("./phase"));
const observation_1 = require("./commands/observation");
const marker_1 = require("../services/serialization/replicator/transforms/re-executable-promise-transform/marker");
const re_executable_promise_1 = __importDefault(require("../utils/re-executable-promise"));
const add_rendered_warning_1 = __importDefault(require("../notifications/add-rendered-warning"));
const get_browser_1 = __importDefault(require("../utils/get-browser"));
const executor_1 = __importDefault(require("../assertions/executor"));
const async_filter_1 = __importDefault(require("../utils/async-filter"));
const execute_fn_with_timeout_1 = __importDefault(require("../utils/execute-fn-with-timeout"));
const url_1 = require("url");
const skip_js_errors_1 = require("../api/skip-js-errors");
const factory_1 = require("./cookies/factory");
const factory_2 = require("./storages/factory");
const wrap_custom_action_1 = __importDefault(require("../api/wrap-custom-action"));
const role_provider_1 = require("./role-provider");
const lazyRequire = require('import-lazy')(require);
const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder');
const TestRunBookmark = lazyRequire('./bookmark');
const actionCommands = lazyRequire('./commands/actions');
const browserManipulationCommands = lazyRequire('./commands/browser-manipulation');
const serviceCommands = lazyRequire('./commands/service');
const observationCommands = lazyRequire('./commands/observation');
const { executeJsExpression, executeAsyncJsExpression } = lazyRequire('./execute-js-expression');
const TEST_RUN_TEMPLATE = (0, read_file_relative_1.readSync)('../client/test-run/index.js.mustache');
const IFRAME_TEST_RUN_TEMPLATE = (0, read_file_relative_1.readSync)('../client/test-run/iframe.js.mustache');
const TEST_DONE_CONFIRMATION_RESPONSE = 'test-done-confirmation';
const MAX_RESPONSE_DELAY = 3000;
const CHILD_WINDOW_READY_TIMEOUT = 30 * 1000;
const ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT = 'all-driver-tasks-added-to-queue';
const COMPILER_SERVICE_EVENTS = [
'setMock',
'setConfigureResponseEventOptions',
'setHeaderOnConfigureResponseEvent',
'removeHeaderOnConfigureResponseEvent',
];
class TestRun extends async_event_emitter_1.default {
constructor({ test, browserConnection, screenshotCapturer, globalWarningLog, opts, compilerService, messageBus, startRunExecutionTime }) {
super();
this._clientEnvironmentPrepared = false;
this[marker_symbol_1.default] = true;
this._messageBus = messageBus;
this.warningLog = new warning_log_1.default(globalWarningLog, warning_log_1.default.createAddWarningCallback(messageBus, this));
this.opts = opts;
this.test = test;
this.browserConnection = browserConnection;
this.unstable = false;
this.browser = (0, get_browser_1.default)(browserConnection);
this.phase = phase_2.default.initial;
this.driverTaskQueue = [];
this.testDoneCommandQueued = false;
this.activeDialogHandler = null;
this.activeIframeSelector = null;
this.speed = this.opts.speed;
this.pageLoadTimeout = this._getPageLoadTimeout(test, opts);
this.testExecutionTimeout = this._getTestExecutionTimeout(opts);
this.disablePageReloads = test.disablePageReloads || opts.disablePageReloads && test.disablePageReloads !== false;
this.disablePageCaching = test.disablePageCaching || opts.disablePageCaching;
this.disableMultipleWindows = opts.disableMultipleWindows;
this.requestTimeout = this._getRequestTimeout(test, opts);
this.session = session_controller_1.default.getSession(this);
this.consoleMessages = new browser_console_messages_1.default();
this.pendingRequest = null;
this.pendingPageError = null;
this.controller = null;
this.ctx = Object.create(null);
this.fixtureCtx = null;
this.testRunCtx = null;
this.currentRoleId = null;
this.usedRoleStates = Object.create(null);
this.errs = [];
this.lastDriverStatusId = null;
this.lastDriverStatusResponse = null;
this.fileDownloadingHandled = false;
this.resolveWaitForFileDownloadingPromise = null;
this.attachmentDownloadingHandled = false;
this.addingDriverTasksCount = 0;
this.debugging = this.opts.debugMode;
this.debugOnFail = this.opts.debugOnFail;
this.disableDebugBreakpoints = false;
this.debugReporterPluginHost = new plugin_host_1.default({ noColors: false });
this.browserManipulationQueue = new browser_manipulation_queue_1.default(browserConnection, screenshotCapturer, this.warningLog);
this.debugLog = new debug_log_1.default(this.browserConnection.userAgent);
this.quarantine = null;
this.debugLogger = this.opts.debugLogger;
this.observedCallsites = new observed_callsites_storage_1.default();
this.compilerService = compilerService;
this.asyncJsExpressionCallsites = new Map();
this.replicator = (0, replicator_1.createReplicator)([new replicator_1.SelectorNodeTransform()]);
this.disconnected = false;
this.errScreenshotPath = null;
this.startRunExecutionTime = startRunExecutionTime;
this.runExecutionTimeout = this._getRunExecutionTimeout(opts);
this._requestHookEventProvider = this._getRequestHookEventProvider();
this._roleProvider = this._getRoleProvider();
this._cookieProvider = factory_1.CookieProviderFactory.create(this, this.opts.experimentalProxyless);
this._storagesProvider = factory_2.StoragesProviderFactory.create(this, this.opts.experimentalProxyless);
this._addInjectables();
}
_getRequestHookEventProvider() {
if (!this.opts.experimentalProxyless)
return this.session.requestHookEventProvider;
return this._proxylessRequestPipeline.requestHookEventProvider;
}
saveStoragesSnapshot(storageSnapshot) {
if (this.opts.experimentalProxyless)
this._proxylessRequestPipeline.restoringStorages = storageSnapshot;
}
get _proxylessRequestPipeline() {
return this._proxyless.requestPipeline;
}
get _proxyless() {
const runtimeInfo = this.browserConnection.provider.plugin.openedBrowsers[this.browserConnection.id];
return runtimeInfo.proxyless;
}
_getRoleProvider() {
if (this.opts.experimentalProxyless)
return new role_provider_1.ProxylessRoleProvider(this);
return new role_provider_1.ProxyRoleProvider(this);
}
_getPageLoadTimeout(test, opts) {
var _a;
if (((_a = test.timeouts) === null || _a === void 0 ? void 0 : _a.pageLoadTimeout) !== void 0)
return test.timeouts.pageLoadTimeout;
return opts.pageLoadTimeout;
}
_getRequestTimeout(test, opts) {
var _a, _b;
return {
page: ((_a = test.timeouts) === null || _a === void 0 ? void 0 : _a.pageRequestTimeout) || opts.pageRequestTimeout,
ajax: ((_b = test.timeouts) === null || _b === void 0 ? void 0 : _b.ajaxRequestTimeout) || opts.ajaxRequestTimeout,
};
}
_getExecutionTimeout(timeout, error) {
return {
timeout,
rejectWith: error,
};
}
_getTestExecutionTimeout(opts) {
const testExecutionTimeout = opts.testExecutionTimeout || 0;
if (!testExecutionTimeout)
return null;
return this._getExecutionTimeout(testExecutionTimeout, new test_run_1.TestTimeoutError(testExecutionTimeout));
}
_getRunExecutionTimeout(opts) {
const runExecutionTimeout = opts.runExecutionTimeout || 0;
if (!runExecutionTimeout)
return null;
return this._getExecutionTimeout(runExecutionTimeout, new test_run_1.RunTimeoutError(runExecutionTimeout));
}
get restRunExecutionTimeout() {
if (!this.startRunExecutionTime || !this.runExecutionTimeout)
return null;
const currentTimeout = Math.max(this.runExecutionTimeout.timeout - (Date.now() - this.startRunExecutionTime.getTime()), 0);
return this._getExecutionTimeout(currentTimeout, this.runExecutionTimeout.rejectWith);
}
get executionTimeout() {
return this.restRunExecutionTimeout && (!this.testExecutionTimeout || this.restRunExecutionTimeout.timeout < this.testExecutionTimeout.timeout)
? this.restRunExecutionTimeout
: this.testExecutionTimeout || null;
}
_addClientScriptContentWarningsIfNecessary() {
const { empty, duplicatedContent } = (0, utils_1.findProblematicScripts)(this.test.clientScripts);
if (empty.length)
this.warningLog.addWarning(warning_message_1.default.clientScriptsWithEmptyContent);
if (duplicatedContent.length) {
const suffix = (0, string_1.getPluralSuffix)(duplicatedContent);
const duplicatedContentClientScriptsStr = (0, string_1.getConcatenatedValuesString)(duplicatedContent, '\n');
this.warningLog.addWarning(warning_message_1.default.clientScriptsWithDuplicatedContent, suffix, duplicatedContentClientScriptsStr);
}
}
_addInjectables() {
this._addClientScriptContentWarningsIfNecessary();
this.injectable.scripts.push(...INJECTABLES.SCRIPTS);
this.injectable.userScripts.push(...this.test.clientScripts.map(script => {
return {
url: (0, get_url_1.default)(script),
page: script.page,
};
}));
this.injectable.styles.push(INJECTABLES.TESTCAFE_UI_STYLES);
}
get id() {
return this.session.id;
}
get injectable() {
return this.session.injectable;
}
addQuarantineInfo(quarantine) {
this.quarantine = quarantine;
}
async _addRequestHook(hook) {
if (this.test.requestHooks.includes(hook))
return;
this.test.requestHooks.push(hook);
await this._initRequestHook(hook);
}
async _removeRequestHook(hook) {
if (!this.test.requestHooks.includes(hook))
return;
(0, lodash_1.pull)(this.test.requestHooks, hook);
await this._disposeRequestHook(hook);
}
async _initRequestHook(hook) {
hook._warningLog = this.warningLog;
await Promise.all(hook._requestFilterRules.map(rule => {
return this._requestHookEventProvider.addRequestEventListeners(rule, {
onRequest: hook.onRequest.bind(hook),
onConfigureResponse: hook._onConfigureResponse.bind(hook),
onResponse: hook.onResponse.bind(hook),
}, (err) => this._onRequestHookMethodError(err, hook._className));
}));
}
async _initRequestHookForCompilerService(hookId, hookClassName, rules) {
const testId = this.test.id;
await Promise.all(rules.map(rule => {
return this._requestHookEventProvider.addRequestEventListeners(rule, {
onRequest: (event) => { var _a; return (_a = this.compilerService) === null || _a === void 0 ? void 0 : _a.onRequestHookEvent({ testId, hookId, name: hook_method_names_1.default.onRequest, eventData: event }); },
onConfigureResponse: (event) => { var _a; return (_a = this.compilerService) === null || _a === void 0 ? void 0 : _a.onRequestHookEvent({ testId, hookId, name: hook_method_names_1.default._onConfigureResponse, eventData: event }); },
onResponse: (event) => { var _a; return (_a = this.compilerService) === null || _a === void 0 ? void 0 : _a.onRequestHookEvent({ testId, hookId, name: hook_method_names_1.default.onResponse, eventData: event }); },
}, err => this._onRequestHookMethodError(err, hookClassName));
}));
}
_onRequestHookMethodError(event, hookClassName) {
let err = event.error;
const isRequestHookNotImplementedMethodError = (err === null || err === void 0 ? void 0 : err.code) === types_1.TEST_RUN_ERRORS.requestHookNotImplementedError;
if (!isRequestHookNotImplementedMethodError)
err = new test_run_1.RequestHookUnhandledError(err, hookClassName, event.methodName);
this.addError(err);
}
async _disposeRequestHook(hook) {
hook._warningLog = null;
await Promise.all(hook._requestFilterRules.map(rule => {
return this._requestHookEventProvider.removeRequestEventListeners(rule);
}));
}
async _detachRequestEventListeners(rules) {
await Promise.all(rules.map(rule => {
return this._requestHookEventProvider.removeRequestEventListeners(rule);
}));
}
_subscribeOnCompilerServiceEvents() {
COMPILER_SERVICE_EVENTS.forEach(eventName => {
if (this.compilerService) {
this.compilerService.on(eventName, async (args) => {
// @ts-ignore
await this.session[eventName](...args);
});
}
});
if (this.compilerService) {
this.compilerService.on('addRequestEventListeners', async ({ hookId, hookClassName, rules }) => {
await this._initRequestHookForCompilerService(hookId, hookClassName, rules);
});
this.compilerService.on('removeRequestEventListeners', async ({ rules }) => {
await this._detachRequestEventListeners(rules);
});
}
}
async _initRequestHooks() {
if (this.compilerService) {
this._subscribeOnCompilerServiceEvents();
await Promise.all(this.test.requestHooks.map(hook => {
return this._initRequestHookForCompilerService(hook.id, hook._className, hook._requestFilterRules);
}));
}
else
await Promise.all(this.test.requestHooks.map(hook => this._initRequestHook(hook)));
}
_prepareSkipJsErrorsOption() {
const options = this.test.skipJsErrorsOptions !== void 0
? this.test.skipJsErrorsOptions
: this.opts.skipJsErrors || false;
return (0, skip_js_errors_1.prepareSkipJsErrorsOptions)(options);
}
// Hammerhead payload
async getPayloadScript() {
this.fileDownloadingHandled = false;
this.resolveWaitForFileDownloadingPromise = null;
const skipJsErrors = this._prepareSkipJsErrorsOption();
return mustache_1.default.render(TEST_RUN_TEMPLATE, {
testRunId: JSON.stringify(this.session.id),
browserId: JSON.stringify(this.browserConnection.id),
activeWindowId: JSON.stringify(this.activeWindowId),
browserHeartbeatRelativeUrl: JSON.stringify(this.browserConnection.heartbeatRelativeUrl),
browserStatusRelativeUrl: JSON.stringify(this.browserConnection.statusRelativeUrl),
browserStatusDoneRelativeUrl: JSON.stringify(this.browserConnection.statusDoneRelativeUrl),
browserIdleRelativeUrl: JSON.stringify(this.browserConnection.idleRelativeUrl),
browserActiveWindowIdUrl: JSON.stringify(this.browserConnection.activeWindowIdUrl),
browserCloseWindowUrl: JSON.stringify(this.browserConnection.closeWindowUrl),
browserOpenFileProtocolRelativeUrl: JSON.stringify(this.browserConnection.openFileProtocolRelativeUrl),
browserDispatchProxylessEventRelativeUrl: JSON.stringify(this.browserConnection.dispatchProxylessEventRelativeUrl),
userAgent: JSON.stringify(this.browserConnection.userAgent),
testName: JSON.stringify(this.test.name),
fixtureName: JSON.stringify(this.test.fixture.name),
selectorTimeout: this.opts.selectorTimeout,
pageLoadTimeout: this.pageLoadTimeout,
childWindowReadyTimeout: CHILD_WINDOW_READY_TIMEOUT,
skipJsErrors: JSON.stringify(skipJsErrors),
retryTestPages: this.opts.retryTestPages,
speed: this.speed,
dialogHandler: JSON.stringify(this.activeDialogHandler),
canUseDefaultWindowActions: JSON.stringify(await this.browserConnection.canUseDefaultWindowActions()),
proxyless: JSON.stringify(this.opts.experimentalProxyless),
domain: JSON.stringify(this.browserConnection.browserConnectionGateway.proxy.server1Info.domain),
});
}
async getIframePayloadScript() {
return mustache_1.default.render(IFRAME_TEST_RUN_TEMPLATE, {
testRunId: JSON.stringify(this.session.id),
selectorTimeout: this.opts.selectorTimeout,
pageLoadTimeout: this.pageLoadTimeout,
retryTestPages: !!this.opts.retryTestPages,
speed: this.speed,
dialogHandler: JSON.stringify(this.activeDialogHandler),
proxyless: JSON.stringify(this.opts.experimentalProxyless),
});
}
// Hammerhead handlers
getAuthCredentials() {
return this.test.authCredentials;
}
handleFileDownload() {
if (this.resolveWaitForFileDownloadingPromise) {
this.resolveWaitForFileDownloadingPromise(true);
this.resolveWaitForFileDownloadingPromise = null;
}
else
this.fileDownloadingHandled = true;
}
handleAttachment(data) {
if (data.isOpenedInNewWindow)
this.attachmentDownloadingHandled = true;
}
handlePageError(ctx, err) {
this.pendingPageError = new test_run_1.PageLoadError(err, ctx.reqOpts.url);
ctx.redirect(ctx.toProxyUrl(testcafe_hammerhead_1.SPECIAL_ERROR_PAGE));
}
// Test function execution
async _executeTestFn(phase, fn, timeout) {
this.phase = phase;
try {
await (0, execute_fn_with_timeout_1.default)(fn, timeout, this);
}
catch (err) {
await this._makeScreenshotOnFail();
this.addError(err);
return false;
}
finally {
this.errScreenshotPath = null;
}
return !this._addPendingPageErrorIfAny();
}
async _runBeforeHook() {
var _a, _b;
if (this.test.globalBeforeFn)
await this._executeTestFn(phase_2.default.inTestBeforeHook, this.test.globalBeforeFn, this.executionTimeout);
if (this.test.beforeFn)
return await this._executeTestFn(phase_2.default.inTestBeforeHook, this.test.beforeFn, this.executionTimeout);
if ((_a = this.test.fixture) === null || _a === void 0 ? void 0 : _a.beforeEachFn)
return await this._executeTestFn(phase_2.default.inFixtureBeforeEachHook, (_b = this.test.fixture) === null || _b === void 0 ? void 0 : _b.beforeEachFn, this.executionTimeout);
return true;
}
async _runAfterHook() {
var _a, _b;
if (this.test.afterFn)
await this._executeTestFn(phase_2.default.inTestAfterHook, this.test.afterFn, this.executionTimeout);
else if ((_a = this.test.fixture) === null || _a === void 0 ? void 0 : _a.afterEachFn)
await this._executeTestFn(phase_2.default.inFixtureAfterEachHook, (_b = this.test.fixture) === null || _b === void 0 ? void 0 : _b.afterEachFn, this.executionTimeout);
if (this.test.globalAfterFn)
await this._executeTestFn(phase_2.default.inTestAfterHook, this.test.globalAfterFn, this.executionTimeout);
}
async _finalizeTestRun(id) {
if (this.compilerService) {
const warnings = await this.compilerService.getWarningMessages({ testRunId: id });
warnings.forEach(warning => {
this.warningLog.addWarning(warning);
});
await this.compilerService.removeTestRunFromState({ testRunId: id });
}
test_run_tracker_1.default.removeActiveTestRun(id);
}
async start() {
test_run_tracker_1.default.addActiveTestRun(this);
await this.emit('start');
const onDisconnected = (err) => this._disconnect(err);
this.browserConnection.once('disconnected', onDisconnected);
await this.once('connected');
await this.emit('ready');
if (await this._runBeforeHook()) {
await this._executeTestFn(phase_2.default.inTest, this.test.fn, this.executionTimeout);
await this._runAfterHook();
}
if (this.disconnected)
return;
this.phase = phase_2.default.pendingFinalization;
this.browserConnection.removeListener('disconnected', onDisconnected);
if (this.errs.length && this.debugOnFail) {
const errStr = this.debugReporterPluginHost.formatError(this.errs[0]);
await this._enqueueSetBreakpointCommand(void 0, errStr);
}
await this.emit('before-done');
await this._internalExecuteCommand(new serviceCommands.TestDoneCommand());
this._addPendingPageErrorIfAny();
this._requestHookEventProvider.clearRequestEventListeners();
this.normalizeRequestHookErrors();
await this._finalizeTestRun(this.session.id);
await this.emit('done');
}
// Errors
_addPendingPageErrorIfAny() {
const error = this.pendingPageError;
if (error) {
this.addError(error);
this.pendingPageError = null;
return true;
}
return false;
}
_ensureErrorId(err) {
// @ts-ignore
err.id = err.id || (0, nanoid_1.nanoid)(7);
}
_createErrorAdapter(err) {
this._ensureErrorId(err);
return new formattable_adapter_1.default(err, {
userAgent: this.browserConnection.userAgent,
screenshotPath: this.errScreenshotPath || '',
testRunId: this.id,
testRunPhase: this.phase,
});
}
addError(err) {
const errList = (err instanceof error_list_1.default ? err.items : [err]);
errList.forEach(item => {
const adapter = this._createErrorAdapter(item);
this.errs.push(adapter);
});
}
normalizeRequestHookErrors() {
const requestHookErrors = (0, lodash_1.remove)(this.errs, e => e.code === types_1.TEST_RUN_ERRORS.requestHookNotImplementedError ||
e.code === types_1.TEST_RUN_ERRORS.requestHookUnhandledError);
if (!requestHookErrors.length)
return;
const uniqRequestHookErrors = (0, lodash_1.chain)(requestHookErrors)
.uniqBy(e => {
const err = e;
return err.hookClassName + err.methodName;
})
.sortBy(['hookClassName', 'methodName'])
.value();
this.errs = this.errs.concat(uniqRequestHookErrors);
}
// Task queue
_enqueueCommand(command, callsite) {
if (this.pendingRequest)
this._resolvePendingRequest(command);
return new Promise(async (resolve, reject) => {
this.addingDriverTasksCount--;
this.driverTaskQueue.push({ command, resolve, reject, callsite });
if (!this.addingDriverTasksCount)
await this.emit(ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT, this.driverTaskQueue.length);
});
}
get driverTaskQueueLength() {
return this.addingDriverTasksCount ? (0, promisify_event_1.default)(this, ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT) : Promise.resolve(this.driverTaskQueue.length);
}
async _enqueueBrowserConsoleMessagesCommand(command, callsite) {
await this._enqueueCommand(command, callsite);
const consoleMessageCopy = this.consoleMessages.getCopy();
// @ts-ignore
return consoleMessageCopy[String(this.activeWindowId)];
}
async _enqueueGetCookies(command) {
const { cookies, urls } = command;
return this._cookieProvider.getCookies(cookies, urls);
}
async _enqueueSetCookies(command) {
const cookies = command.cookies;
const url = command.url || await this.getCurrentUrl();
return this._cookieProvider.setCookies(cookies, url);
}
async _enqueueDeleteCookies(command) {
const { cookies, urls } = command;
return this._cookieProvider.deleteCookies(cookies, urls);
}
async _enqueueSetBreakpointCommand(callsite, error) {
if (this.debugLogger)
this.debugLogger.showBreakpoint(this.session.id, this.browserConnection.userAgent, callsite, error);
this.debugging = await this._internalExecuteCommand(new serviceCommands.SetBreakpointCommand(!!error, !!this.compilerService), callsite);
}
_removeAllNonServiceTasks() {
this.driverTaskQueue = this.driverTaskQueue.filter(driverTask => (0, utils_2.isServiceCommand)(driverTask.command));
this.browserManipulationQueue.removeAllNonServiceManipulations();
}
_handleDebugState(driverStatus) {
if (driverStatus.debug)
this.emit(driverStatus.debug);
}
// Current driver task
get currentDriverTask() {
return this.driverTaskQueue[0];
}
_resolveCurrentDriverTask(result) {
this.currentDriverTask.resolve(result);
this.driverTaskQueue.shift();
if (this.testDoneCommandQueued)
this._removeAllNonServiceTasks();
}
_rejectCurrentDriverTask(err) {
// @ts-ignore
err.callsite = err.callsite || this.currentDriverTask.callsite;
this.currentDriverTask.reject(err);
this._removeAllNonServiceTasks();
}
// Pending request
_clearPendingRequest() {
if (this.pendingRequest) {
clearTimeout(this.pendingRequest.responseTimeout);
this.pendingRequest = null;
}
}
_resolvePendingRequest(command) {
this.lastDriverStatusResponse = command;
if (this.pendingRequest)
this.pendingRequest.resolve(command);
this._clearPendingRequest();
}
// Handle driver request
_shouldResolveCurrentDriverTask(driverStatus) {
const currentCommand = this.currentDriverTask.command;
const isExecutingObservationCommand = currentCommand instanceof observationCommands.ExecuteSelectorCommand ||
currentCommand instanceof observation_1.ExecuteClientFunctionCommand;
const isDebugActive = currentCommand instanceof serviceCommands.SetBreakpointCommand;
const shouldExecuteCurrentCommand = driverStatus.isFirstRequestAfterWindowSwitching && (isExecutingObservationCommand || isDebugActive);
return !shouldExecuteCurrentCommand;
}
_fulfillCurrentDriverTask(driverStatus) {
var _a;
if (!this.currentDriverTask)
return;
if ((_a = driverStatus.warnings) === null || _a === void 0 ? void 0 : _a.length) {
driverStatus.warnings.forEach((warning) => {
(0, add_rendered_warning_1.default)(this.warningLog, warning_message_1.default[warning.type], this.currentDriverTask.callsite, ...warning.args);
});
}
if (driverStatus.executionError)
this._rejectCurrentDriverTask(driverStatus.executionError);
else if (this._shouldResolveCurrentDriverTask(driverStatus))
this._resolveCurrentDriverTask(driverStatus.result);
}
_handlePageErrorStatus(pageError) {
if (this.currentDriverTask && (0, utils_2.isCommandRejectableByPageError)(this.currentDriverTask.command)) {
this._rejectCurrentDriverTask(pageError);
this.pendingPageError = null;
return true;
}
this.pendingPageError = this.pendingPageError || pageError;
return false;
}
async _handleDriverRequest(driverStatus) {
const isTestDone = this.currentDriverTask && this.currentDriverTask.command.type ===
type_1.default.testDone;
const pageError = this.pendingPageError || driverStatus.pageError;
const currentTaskRejectedByError = pageError && this._handlePageErrorStatus(pageError);
this.consoleMessages.concat(driverStatus.consoleMessages);
this._handleDebugState(driverStatus);
if (!currentTaskRejectedByError && driverStatus.isCommandResult) {
if (isTestDone) {
this._resolveCurrentDriverTask();
return TEST_DONE_CONFIRMATION_RESPONSE;
}
this._fulfillCurrentDriverTask(driverStatus);
if (driverStatus.isPendingWindowSwitching)
return null;
}
return this._getCurrentDriverTaskCommand();
}
async _getCurrentDriverTaskCommand() {
if (!this.currentDriverTask)
return null;
const command = this.currentDriverTask.command;
if (command.type === type_1.default.navigateTo && command.stateSnapshot)
await this._roleProvider.useStateSnapshot(JSON.parse(command.stateSnapshot));
return command;
}
// Execute command
async _executeJsExpression(command) {
const resultVariableName = command.resultVariableName;
let expression = command.expression;
if (resultVariableName)
expression = `${resultVariableName} = ${expression}, ${resultVariableName}`;
if (this.compilerService) {
return this.compilerService.executeJsExpression({
expression,
testRunId: this.id,
options: { skipVisibilityCheck: false },
});
}
return executeJsExpression(expression, this, { skipVisibilityCheck: false });
}
async _executeAsyncJsExpression(command, callsite) {
if (this.compilerService) {
this.asyncJsExpressionCallsites.clear();
return this.compilerService.executeAsyncJsExpression({
expression: command.expression,
testRunId: this.id,
callsite,
});
}
return executeAsyncJsExpression(command.expression, this, callsite);
}
_redirectReExecutablePromiseExecutionToCompilerService(command) {
if (!this.compilerService)
return;
const self = this;
command.actual = re_executable_promise_1.default.fromFn(async () => {
var _a;
return (_a = self.compilerService) === null || _a === void 0 ? void 0 : _a.getAssertionActualValue({
testRunId: self.id,
commandId: command.id,
});
});
}
_redirectAssertionFnExecutionToCompilerService(executor) {
executor.fn = () => {
var _a;
return (_a = this.compilerService) === null || _a === void 0 ? void 0 : _a.executeAssertionFn({
testRunId: this.id,
commandId: executor.command.id,
});
};
}
async _executeAssertion(command, callsite) {
if (command.actual === Symbol.for(marker_1.RE_EXECUTABLE_PROMISE_MARKER_DESCRIPTION))
this._redirectReExecutablePromiseExecutionToCompilerService(command);
const assertionTimeout = (0, get_assertion_timeout_1.default)(command, this.opts);
const executor = new executor_1.default(command, assertionTimeout, callsite);
executor.once('start-assertion-retries', (timeout) => this._internalExecuteCommand(new serviceCommands.ShowAssertionRetriesStatusCommand(timeout)));
executor.once('end-assertion-retries', (success) => this._internalExecuteCommand(new serviceCommands.HideAssertionRetriesStatusCommand(success)));
executor.once('non-serializable-actual-value', this._redirectAssertionFnExecutionToCompilerService);
const executeFn = this.decoratePreventEmitActionEvents(() => executor.run(), { prevent: true });
return await executeFn();
}
_adjustConfigurationWithCommand(command) {
if (command.type === type_1.default.testDone) {
this.testDoneCommandQueued = true;
if (this.debugLogger)
this.debugLogger.hideBreakpoint(this.session.id);
}
else if (command.type === type_1.default.setNativeDialogHandler)
this.activeDialogHandler = command.dialogHandler;
else if (command.type === type_1.default.switchToIframe)
this.activeIframeSelector = command.selector;
else if (command.type === type_1.default.switchToMainWindow)
this.activeIframeSelector = null;
else if (command.type === type_1.default.setTestSpeed)
this.speed = command.speed;
else if (command.type === type_1.default.setPageLoadTimeout)
this.pageLoadTimeout = command.duration;
else if (command.type === type_1.default.debug)
this.debugging = true;
else if (command.type === type_1.default.disableDebug) {
this.debugLogger.hideBreakpoint(this.session.id);
this.debugging = false;
}
}
async _adjustScreenshotCommand(command) {
const browserId = this.browserConnection.id;
const { hasChromelessScreenshots } = await this.browserConnection.provider.hasCustomActionForBrowser(browserId);
if (!hasChromelessScreenshots)
command.generateScreenshotMark();
}
async _adjustCommandOptionsAndEnvironment(command, callsite) {
var _a;
if (((_a = command.options) === null || _a === void 0 ? void 0 : _a.confidential) !== void 0)
return;
if (command.type === type_1.default.typeText) {
const result = await this._internalExecuteCommand(command.selector, callsite);
if (!result)
return;
const node = this.replicator.decode(result);
command.options.confidential = (0, is_password_input_1.default)(node);
}
else if (command.type === type_1.default.pressKey) {
const result = await this._internalExecuteCommand(new serviceCommands.GetActiveElementCommand());
if (!result)
return;
const node = this.replicator.decode(result);
command.options.confidential = (0, is_password_input_1.default)(node);
}
else if (command instanceof observation_1.ExecuteClientFunctionCommandBase && !!this.compilerService && !this._clientEnvironmentPrepared) {
this._clientEnvironmentPrepared = true;
await this._internalExecuteCommand(new serviceCommands.PrepareClientEnvironmentInDebugMode(command.esmRuntime));
}
}
async _setBreakpointIfNecessary(command, callsite) {
if (!this.disableDebugBreakpoints && this.debugging && (0, utils_2.canSetDebuggerBreakpointBeforeCommand)(command))
await this._enqueueSetBreakpointCommand(callsite);
}
async executeCommand(command, callsite) {
return command instanceof base_js_1.ActionCommandBase
? this._executeActionCommand(command, callsite)
: this._internalExecuteCommand(command, callsite);
}
async _executeActionCommand(command, callsite) {
const actionArgs = { apiActionName: command.methodName, command };
let errorAdapter = null;
let error = null;
let result = null;
const start = new Date().getTime();
try {
await this._adjustCommandOptionsAndEnvironment(command, callsite);
}
catch (err) {
error = err;
}
await this.emitActionEvent('action-start', actionArgs);
try {
if (!error)
result = await this._internalExecuteCommand(command, callsite);
}
catch (err) {
if (this.phase === phase_2.default.pendingFinalization && err instanceof test_run_1.ExternalAssertionLibraryError)
(0, add_rendered_warning_1.default)(this.warningLog, { message: warning_message_1.default.unawaitedMethodWithAssertion, actionId: command.actionId }, callsite);
else
error = err;
}
const duration = new Date().getTime() - start;
if (error) {
// NOTE: check if error is TestCafeErrorList is specific for the `useRole` action
// if error is TestCafeErrorList we do not need to create an adapter,
// since error is already was processed in role initializer
if (!(error instanceof error_list_1.default)) {
await this._makeScreenshotOnFail(command.actionId);
errorAdapter = this._createErrorAdapter((0, process_test_fn_error_1.default)(error));
}
else
errorAdapter = error.adapter;
}
Object.assign(actionArgs, {
result,
duration,
err: errorAdapter,
});
await this.emitActionEvent('action-done', actionArgs);
if (error)
throw error;
return result;
}
async _internalExecuteCommand(command, callsite) {
this.debugLog.command(command);
if (this.pendingPageError && (0, utils_2.isCommandRejectableByPageError)(command))
return this._rejectCommandWithPageError(callsite);
if ((0, utils_2.isExecutableOnClientCommand)(command))
this.addingDriverTasksCount++;
this._adjustConfigurationWithCommand(command);
await this._setBreakpointIfNecessary(command, callsite);
if ((0, utils_2.isScreenshotCommand)(command)) {
if (this.opts.disableScreenshots) {
this.warningLog.addWarning({ message: warning_message_1.default.screenshotsDisabled, actionId: command.actionId });
return null;
}
await this._adjustScreenshotCommand(command);
}
if ((0, utils_2.isBrowserManipulationCommand)(command)) {
this.browserManipulationQueue.push(command);
if ((0, utils_2.isResizeWindowCommand)(command) && this.opts.videoPath)
this.warningLog.addWarning({ message: warning_message_1.default.videoBrowserResizing, actionId: command.actionId }, this.test.name);
}
if (command.type === type_1.default.wait)
return (0, delay_1.default)(command.timeout);
if (command.type === type_1.default.setPageLoadTimeout)
return null;
if (command.type === type_1.default.debug) {
// NOTE: In regular mode, it's possible to debug tests only using TestCafe UI ('Resume' and 'Next step' buttons).
// So, we should warn on trying to debug in headless mode.
// In compiler service mode, we can debug even in headless mode using any debugging tools. So, in this case, the warning is excessive.
const canDebug = !!this.compilerService || !this.browserConnection.isHeadlessBrowser();
if (canDebug)
return await this._enqueueSetBreakpointCommand(callsite, void 0);
this.debugging = false;
this.warningLog.addWarning({ message: warning_message_1.default.debugInHeadlessError, actionId: command.actionId });
return null;
}
if (command.type === type_1.default.useRole) {
let fn = () => this._useRole(command.role, callsite);
fn = this.decoratePreventEmitActionEvents(fn, { prevent: true });
fn = this.decorateDisableDebugBreakpoints(fn, { disable: true });
return await fn();
}
if (command.type === type_1.default.runCustomAction) {
const { fn, args } = command;
const wrappedFn = (0, wrap_custom_action_1.default)(fn);
return await wrappedFn(this, args);
}
if (command.type === type_1.default.assertion)
return this._executeAssertion(command, callsite);
if (command.type === type_1.default.executeExpression)
return await this._executeJsExpression(command);
if (command.type === type_1.default.executeAsyncExpression)
return this._executeAsyncJsExpression(command, callsite);
if (command.type === type_1.default.getBrowserConsoleMessages)
return this._enqueueBrowserConsoleMessagesCommand(command, callsite);
if (command.type === type_1.default.switchToPreviousWindow)
command.windowId = this.browserConnection.previousActiveWindowId;
if (command.type === type_1.default.switchToWindowByPredicate)
return this._switchToWindowByPredicate(command);
if (command.type === type_1.default.getCookies)
return this._enqueueGetCookies(command);
if (command.type === type_1.default.setCookies)
return this._enqueueSetCookies(command);
if (command.type === type_1.default.deleteCookies)
return this._enqueueDeleteCookies(command);
if (command.type === type_1.default.addRequestHooks)
return Promise.all(command.hooks.map(hook => this._addRequestHook(hook)));
if (command.type === type_1.default.removeRequestHooks)
return Promise.all(command.hooks.map(hook => this._removeRequestHook(hook)));
return this._enqueueCommand(command, callsite);
}
_rejectCommandWithPageError(callsite) {
const err = this.pendingPageError;
// @ts-ignore
err.callsite = callsite;
this.pendingPageError = null;
return Promise.reject(err);
}
_sendCloseChildWindowOnFileDownloadingCommand() {
return new actionCommands.CloseChildWindowOnFileDownloading();
}
async _makeScreenshotOnFail(failedActionId) {
const { screenshots } = this.opts;
if (!this.errScreenshotPath && (screenshots === null || screenshots === void 0 ? void 0 : screenshots.takeOnFails))
this.errScreenshotPath = await this._internalExecuteCommand(new browserManipulationCommands.TakeScreenshotOnFailCommand({ failedActionId }));
}
_decorateWithFlag(fn, flagName, value) {
return async () => {
// @ts-ignore
this[flagName] = value;
try {
return await fn();
}
finally {
// @ts-ignore
this[flagName] = !value;
}
};
}
decoratePreventEmitActionEvents(fn, { prevent }) {
return this._decorateWithFlag(fn, 'preventEmitActionEvents', prevent);
}
decorateDisableDebugBreakpoints(fn, { disable }) {
return this._decorateWithFlag(fn, 'disableDebugBreakpoints', disable);
}
// Role management
async getStateSnapshot() {
const state = await this._roleProvider.getStateSnapshot();
state.storages = await this._internalExecuteCommand(new serviceCommands.BackupStoragesCommand());
return state;
}
async _cleanUpCtxs() {
if (this.compilerService) {
await this.compilerService.setCtx({
testRunId: this.id,
value: Object.create(null),
});
await this.compilerService.setFixtureCtx({
testRunId: this.id,
value: Object.create(null),
});
}
else {
this.ctx = Object.create(null);
this.fixtureCtx = Object.create(null);
this.testRunCtx = Object.create(null);
}
}
async switchToCleanRun(url) {
await this._cleanUpCtxs();
this.consoleMessages = new browser_console_messages_1.default();
await this._roleProvider.useStateSnapshot(testcafe_hammerhead_1.StateSnapshot.empty());
if (this.speed !== this.opts.speed) {
const setSpeedCommand = new actionCommands.SetTestSpeedCommand({ speed: this.opts.speed });
await this._internalExecuteCommand(setSpeedCommand);
}
if (this.pageLoadTimeout !== this.opts.pageLoadTimeout) {
const setPageLoadTimeoutCommand = new actionCommands.SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout });
await this._internalExecuteCommand(setPageLoadTimeoutCommand);
}
await this.navigateToUrl(url, true);
if (this.activeDialogHandler) {
const removeDialogHandlerCommand = new actionCommands.SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } });
await this._internalExecuteCommand(removeDialogHandlerCommand);
}
}
async navigateToUrl(url, forceReload, stateSnapshot) {
const navigateCommand = new actionCommands.NavigateToCommand({ url, forceReload, stateSnapshot });
await this._internalExecuteCommand(navigateCommand);
}
async _getStateSnapshotFromRole(role) {
const prevPhase = this.phase;
if (role.phase === phase_1.default.initialized && role.initErr instanceof error_list_1.default && role.initErr.hasErrors)
role.initErr.adapter = this._createErrorAdapter(role.initErr.items[0]);
this.phase = phase_2.default.inRoleInitializer;
if (role.phase === phase_1.default.uninitialized)
await role.initialize(this);
else if (role.phase === phase_1.default.pendingInitialization)
await (0, promisify_event_1.default)(role, 'initialized');
if (role.initErr)
throw role.initErr;
this.phase = prevPhase;
return role.stateSnapshot;
}
async _useRole(role, callsite) {
if (this.phase === phase_2.default.inRoleInitializer)
throw new test_run_1.RoleSwitchInRoleInitializerError(callsite);
const bookmark = new TestRunBookmark(this, role);
await bookmark.init();
if (this.currentRoleId)
this.usedRoleStates[this.currentRoleId] = await this.getStateSnapshot();
const stateSnapshot = this.usedRoleStates[role.id] || await this._getStateSnapshotFromRole(role);
await this._roleProvider.useStateSnapshot(stateSnapshot);
this.currentRoleId = role.id;
await bookmark.restore(callsite, stateSnapshot);
}
async getCurrentUrl() {
const builder = new ClientFunctionBuilder(() => {
return window.location.href; // eslint-disable-line no-undef
}, { boundTestRun: this });
const getLocation = builder.getFunction();
return await getLocation();
}
async _switchToWindowByPredicate(command) {
const currentWindows = await this._internalExecuteCommand(new actions_1.GetCurrentWindowsCommand({}, this));
const windows = await (0, async_filter_1.default)(currentWindows, async (wnd) => {
try {
const predicateData = {
url: new url_1.URL(wnd.url),
title: wnd.title,
};
if (this.compilerService) {
const compilerServicePredicateData = Object.assign(predicateData, {
testRunId: this.id,
commandId: command.id,
});
return this.compilerService.checkWindow(compilerServicePredicateData);
}
return command.checkWindow(predicateData);
}
catch (e) {
throw new test_run_1.SwitchToWindowPredicateError(e.message);
}
});
if (!windows.length)
throw new test_run_1.WindowNotFoundError();
if (windows.length > 1)
this.warningLog.addWarning({ message: warning_message_1.default.multipleWindowsFoundByPredicate, actionId: command.actionId });
await this._internalExecuteCommand(new actions_1.SwitchToWindowCommand({ windowId: windows[0].id }, this));
}
_disconnect(err) {
this.disconnected = true;
if (this.currentDriverTask)
this._rejectCurrentDriverTask(err);
this.emit('disconnected', err);
test_run_tracker_1.default.removeActiveTestRun(this.session.id);
}
_handleFileDownloadingInNewWindowRequest() {
if (this.attachmentDownloadingHandled) {
this.attachmentDownloadingHandled = false;
return this._sendCloseChildWindowOnFileDownloadingCommand();
}
return null;
}
async emitActionEvent(eventName, args) {
// @ts-ignore
if (!this.preventEmitActionEvents)
await this.emit(eventName, args);
}
static isMultipleWindowsAllowed(testRun) {
const { disableMultipleWindows, test } = testRun;
return !disableMultipleWindows && !test.isLegacy && !!testRun.activeWindowId;
}
async initialize() {
await this._clearCookiesAndStorages();
await this._initRequestHooks();
if (!this.compilerService)
return;
await this.compilerService.initializeTestRunData({
testRunId: this.id,
testId: this.test.id,
browser: this.browser,
activeWindowId: this.activeWindowId,
messageBus: this._messageBus,
});
}
async _clearCookiesAndStorages() {
if (this.disablePageReloads)
return;
await this._cookieProvider.initialize();
await this._storagesProvider.initialize();
}
get activeWindowId() {
return this.browserConnection.activeWindowId;
}
// NOTE: this function is time-critical and must return ASAP to avoid client disconnection
async [client_messages_1.default.ready](msg) {
if (msg.status.isObservingFileDownloadingInNewWindow)
return this._handleFileDownloadingInNewWindowRequest();
this.debugLog.driverMessage(msg);
if (this.disconnected)
return Promise.reject(new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.testRunRequestInDisconnectedBrowser, this.browserConnection.browserInfo.alias));
this.emit('connected');
this._clearPendingRequest();
// NOTE: the driver sends the status for the second time if it didn't get a response at the
// first try. This is possible when the page was unloaded after the driver sent the status.
if (msg.status.id === this.lastDriverStatusId)
return this.lastDriverStatusResponse;
this.lastDriverStatusId = msg.status.id;
this.lastDriverStatusResponse = await this._handleDriverRequest(msg.status);
if (this.lastDriverStatusResponse || msg.status.isPendingWindowSwitching)
return this.lastDriverStatusResponse;
// NOTE: we send an empty response after the MAX_RESPONSE_DELAY timeout is exceeded to keep connection
// with the client and prevent the response timeout exception on the client side
const responseTimeout = setTimeout(() => this._resolvePendingRequest(null), MAX_RESPONSE_DELAY);
return new Promise((resolve, reject) => {
this.pendingRequest = { resolve, reject, responseTimeout };
});
}
async [client_messages_1.default.readyForBrowserManipulation](msg) {
this.debugLog.driverMessage(msg);
let result = null;
let error = null;
try {
result = await this.browserManipulationQueue.executePendingManipulation(msg, this._messageBus);
}
catch (err) {
if (err instanceof Error) {
error = {
name: err.name,
message: err.message,
stack: err.stack,
isInternalError: true,
};
}
else
error = err;
}
return { result, error };
}
async [client_messages_1.default.waitForFileDownload](msg) {
this.debugLog.driverMessage(msg);
return new Promise(resolve => {
if (this.fileDownloadingHandled) {
this.fileDownloadingHandled = false;
resolve(true);
}
else
this.resolveWaitForFileDownloadingPromise = resolve;
});
}
}
exports.default = TestRun;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC1ydW4vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUlnQjtBQUVoQixtQ0FBZ0M7QUFDaEMsMkRBQXNEO0FBQ3RELHNFQUE2QztBQUM3Qyx3REFBZ0M7QUFDaEMsdUZBQTZEO0FBQzdELDREQUEwQztBQUMxQyxpR0FBb0Y7QUFDcEYsc0VBQXFEO0FBQ3JELCtDQUFpRDtBQUVqRCxrREFVNkI7QUFFN0Isd0VBQWdEO0FBQ2hELDJEQUEyQztBQUMzQywyREFBbUM7QUFDbkMsbUZBQXlEO0FBQ3pELG9FQUE0QztBQUM1QywrRUFBcUQ7QUFDckQsMERBQXVDO0FBQ3ZDLDBFQUF5RDtBQUN6RCwwRkFBZ0U7QUFDaEUsK0VBQXNEO0FBQ3RELHVGQUErRDtBQUUvRCw2REFXNkI7QUFFN0IsbUVBQXFEO0FBQ3JELDBEQUF3RTtBQUN4RSwrRUFBd0U7QUFDeEUsNENBQStFO0FBRS9FLDRDQVEwQjtBQUUxQixnREFZNEI7QUFFNUIsMkNBQWtFO0FBQ2xFLDRGQUFpRTtBQUNqRSwrRkFBNEU7QUFDNUUsK0RBQXlGO0FBS3pGLDhFQUFxRDtBQUVyRCw4RkFBb0U7QUFDcEUsOEZBQW9FO0FBTXBFLGdEQUFvRTtBQUtwRSx1R0FBNkU7QUFNN0Usb0RBQW1DO0FBRW5DLHdEQUlnQztBQUVoQyxtSEFBa0o7QUFDbEosMkZBQWlFO0FBQ2pFLGlHQUF1RTtBQUN2RSx1RUFBOEM7QUFDOUMsc0VBQXVEO0FBQ3ZELHlFQUFnRDtBQUdoRCwrRkFBb0U7QUFDcEUsNkJBQTBCO0FBRTFCLDBEQUFtRTtBQUNuRSwrQ0FBMEQ7QUFHMUQsZ0RBQTZEO0FBRTdELG1GQUF5RDtBQUV6RCxtREFJeUI7QUFLekIsTUFBTSxXQUFXLEdBQW1CLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNwRSxNQUFN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QUFFLElBQUk7aUJBQ3hCLENBQUM7YUFDTDs7Z0JBRUcsS0FBSyxHQUFHLEdBQUcsQ0FBQztTQUNuQjtRQUVELE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVPLEtBQUssQ0FBQyxDQUFDLHlCQUFlLENBQUMsbUJBQW1CLENBQUMsQ0FBRSxHQUFrQjtRQUNuRSxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVqQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3pCLElBQUksSUFBSSxDQUFDLHNCQUFzQixFQUFFO2dCQUM3QixJQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDO2dCQUNwQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDakI7O2dCQUVHLElBQUksQ0FBQyxvQ0FBb0MsR0FBRyxPQUFPLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0NBQ0o7QUEvNUNELDBCQSs1Q0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIHB1bGwsXG4gICAgcmVtb3ZlLFxuICAgIGNoYWluLFxufSBmcm9tICdsb2Rhc2gnO1xuXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tICduYW5vaWQnO1xuaW1wb3J0IHsgcmVhZFN5bmMgYXMgcmVhZCB9IGZyb20gJ3JlYWQtZmlsZS1yZWxhdGl2ZSc7XG5pbXBvcnQgcHJvbWlzaWZ5RXZlbnQgZnJvbSAncHJvbWlzaWZ5LWV2ZW50JztcbmltcG9ydCBNdXN0YWNoZSBmcm9tICdtdXN0YWNoZSc7XG5pbXBvcnQgQXN5bmNFdmVudEVtaXR0ZXIgZnJvbSAnLi4vdXRpbHMvYXN5bmMtZXZlbnQtZW1pdHRlcic7XG5pbXBvcnQgVGVzdFJ1bkRlYnVnTG9nIGZyb20gJy4vZGVidWctbG9nJztcbmltcG9ydCBUZXN0UnVuRXJyb3JGb3JtYXR0YWJsZUFkYXB0ZXIgZnJvbSAnLi4vZXJyb3JzL3Rlc3QtcnVuL2Zvcm1hdHRhYmxlLWFkYXB0ZXInO1xuaW1wb3J0IFRlc3RDYWZlRXJyb3JMaXN0IGZyb20gJy4uL2Vycm9ycy9lcnJvci1saXN0JztcbmltcG9ydCB7IEdlbmVyYWxFcnJvciB9IGZyb20gJy4uL2Vycm9ycy9ydW50aW1lJztcblxuaW1wb3J0IHtcbiAgICBSZXF1ZXN0SG9va1VuaGFuZGxlZEVycm9yLFxuICAgIFBhZ2VMb2FkRXJyb3IsXG4gICAgUm9sZVN3aXRjaEluUm9sZUluaXRpYWxpemVyRXJyb3IsXG4gICAgU3dpdGNoVG9XaW5kb3dQcmVkaWNhdGVFcnJvcixcbiAgICBXaW5kb3dOb3RGb3VuZEVycm9yLFxuICAgIFJlcXVlc3RIb29rQmFzZUVycm9yLFxuICAgIFRlc3RUaW1lb3V0RXJyb3IsXG4gICAgRXh0ZXJuYWxBc3NlcnRpb25MaWJyYXJ5RXJyb3IsXG4gICAgUnVuVGltZW91dEVycm9yLFxufSBmcm9tICcuLi9lcnJvcnMvdGVzdC1ydW4vJztcblxuaW1wb3J0IENMSUVOVF9NRVNTQUdFUyBmcm9tICcuL2NsaWVudC1tZXNzYWdlcyc7XG5pbXBvcnQgQ09NTUFORF9UWVBFIGZyb20gJy4vY29tbWFuZHMvdHlwZSc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vdXRpbHMvZGVsYXknO1xuaW1wb3J0IGlzUGFzc3dvcmRJbnB1dCBmcm9tICcuLi91dGlscy9pcy1wYXNzd29yZC1pbnB1dCc7XG5pbXBvcnQgdGVzdFJ1bk1hcmtlciBmcm9tICcuL21hcmtlci1zeW1ib2wnO1xuaW1wb3J0IHRlc3RSdW5UcmFja2VyIGZyb20gJy4uL2FwaS90ZXN0LXJ1bi10cmFja2VyJztcbmltcG9ydCBST0xFX1BIQVNFIGZyb20gJy4uL3JvbGUvcGhhc2UnO1xuaW1wb3J0IFJlcG9ydGVyUGx1Z2luSG9zdCBmcm9tICcuLi9yZXBvcnRlci9wbHVnaW4taG9zdCc7XG5pbXBvcnQgQnJvd3NlckNvbnNvbGVNZXNzYWdlcyBmcm9tICcuL2Jyb3dzZXItY29uc29sZS1tZXNzYWdlcyc7XG5pbXBvcnQgV2FybmluZ0xvZyBmcm9tICcuLi9ub3RpZmljYXRpb25zL3dhcm5pbmctbG9nJztcbmltcG9ydCBXQVJOSU5HX01FU1NBR0UgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuXG5pbXBvcnQge1xuICAgIFN0YXRlU25hcHNob3QsXG4gICAgU1BFQ0lBTF9FUlJPUl9QQUdFLFxuICAgIFJlcXVlc3RGaWx0ZXJSdWxlLFxuICAgIEluamVjdGFibGVSZXNvdXJjZXMsXG4gICAgUmVxdWVzdEV2ZW50LFxuICAgIENvbmZpZ3VyZVJlc3BvbnNlRXZlbnQsXG4gICAgUmVzcG9uc2VFdmVudCxcbiAgICBSZXF1ZXN0SG9va01ldGhvZEVycm9yLFxuICAgIFN0b3JhZ2VzU25hcHNob3QsXG4gICAgUmVxdWVzdEhvb2tFdmVudFByb3ZpZGVyLFxufSBmcm9tICd0ZXN0Y2FmZS1oYW1tZXJoZWFkJztcblxuaW1wb3J0ICogYXMgSU5KRUNUQUJMRVMgZnJvbSAnLi4vYXNzZXRzL2luamVjdGFibGVzJztcbmltcG9ydCB7IGZpbmRQcm9ibGVtYXRpY1NjcmlwdHMgfSBmcm9tICcuLi9jdXN0b20tY2xpZW50LXNjcmlwdHMvdXRpbHMnO1xuaW1wb3J0IGdldEN1c3RvbUNsaWVudFNjcmlwdFVybCBmcm9tICcuLi9jdXN0b20tY2xpZW50LXNjcmlwdHMvZ2V0LXVybCc7XG5pbXBvcnQgeyBnZXRQbHVyYWxTdWZmaXgsIGdldENvbmNhdGVuYXRlZFZhbHVlc1N0cmluZyB9IGZyb20gJy4uL3V0aWxzL3N0cmluZyc7XG5cbmltcG9ydCB7XG4gICAgaXNDb21tYW5kUmVqZWN0YWJsZUJ5UGFnZUVycm9yLFxuICAgIGlzQnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmQsXG4gICAgaXNTY3JlZW5zaG90Q29tbWFuZCxcbiAgICBpc1NlcnZpY2VDb21tYW5kLFxuICAgIGNhblNldERlYnVnZ2VyQnJlYWtwb2ludEJlZm9yZUNvbW1hbmQsXG4gICAgaXNFeGVjdXRhYmxlT25DbGllbnRDb21tYW5kLFxuICAgIGlzUmVzaXplV2luZG93Q29tbWFuZCxcbn0gZnJvbSAnLi9jb21tYW5kcy91dGlscyc7XG5cbmltcG9ydCB7XG4gICAgRXhlY3V0ZUFzeW5jRXhwcmVzc2lvbkNvbW1hbmQsXG4gICAgRXhlY3V0ZUV4cHJlc3Npb25Db21tYW5kLFxuICAgIEdldEN1cnJlbnRXaW5kb3dzQ29tbWFuZCxcbiAgICBTd2l0Y2hUb1dpbmRvd0J5UHJlZGljYXRlQ29tbWFuZCxcbiAgICBTd2l0Y2hUb1dpbmRvd0NvbW1hbmQsXG4gICAgR2V0Q29va2llc0NvbW1hbmQsXG4gICAgU2V0Q29va2llc0NvbW1hbmQsXG4gICAgRGVsZXRlQ29va2llc0NvbW1hbmQsXG4gICAgQWRkUmVxdWVzdEhvb2tzQ29tbWFuZCxcbiAgICBSZW1vdmVSZXF1ZXN0SG9va3NDb21tYW5kLFxuICAgIFJ1bkN1c3RvbUFjdGlvbkNvbW1hbmQsXG59IGZyb20gJy4vY29tbWFuZHMvYWN0aW9ucyc7XG5cbmltcG9ydCB7IFJVTlRJTUVfRVJST1JTLCBURVNUX1JVTl9FUlJPUlMgfSBmcm9tICcuLi9lcnJvcnMvdHlwZXMnO1xuaW1wb3J0IHByb2Nlc3NUZXN0Rm5FcnJvciBmcm9tICcuLi9lcnJvcnMvcHJvY2Vzcy10ZXN0LWZuLWVycm9yJztcbmltcG9ydCBSZXF1ZXN0SG9va01ldGhvZE5hbWVzIGZyb20gJy4uL2FwaS9yZXF1ZXN0LWhvb2tzL2hvb2stbWV0aG9kLW5hbWVzJztcbmltcG9ydCB7IGNyZWF0ZVJlcGxpY2F0b3IsIFNlbGVjdG9yTm9kZVRyYW5zZm9ybSB9IGZyb20gJy4uL2NsaWVudC1mdW5jdGlvbnMvcmVwbGljYXRvcic7XG5pbXBvcnQgVGVzdCBmcm9tICcuLi9hcGkvc3RydWN0dXJlL3Rlc3QnO1xuaW1wb3J0IENhcHR1cmVyIGZyb20gJy4uL3NjcmVlbnNob3RzL2NhcHR1cmVyJztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuLi9jb25maWd1cmF0aW9uL2ludGVyZmFjZXMnO1xuaW1wb3J0IENvbXBpbGVyU2VydmljZSBmcm9tICcuLi9zZXJ2aWNlcy9jb21waWxlci9ob3N0JztcbmltcG9ydCBTZXNzaW9uQ29udHJvbGxlciBmcm9tICcuL3Nlc3Npb24tY29udHJvbGxlcic7XG5pbXBvcnQgVGVzdENvbnRyb2xsZXIgZnJvbSAnLi4vYXBpL3Rlc3QtY29udHJvbGxlcic7XG5pbXBvcnQgQnJvd3Nlck1hbmlwdWxhdGlvblF1ZXVlIGZyb20gJy4vYnJvd3Nlci1tYW5pcHVsYXRpb24tcXVldWUnO1xuaW1wb3J0IE9ic2VydmVkQ2FsbHNpdGVzU3RvcmFnZSBmcm9tICcuL29ic2VydmVkLWNhbGxzaXRlcy1zdG9yYWdlJztcbmltcG9ydCBDbGllbnRTY3JpcHQgZnJvbSAnLi4vY3VzdG9tLWNsaWVudC1zY3JpcHRzL2NsaWVudC1zY3JpcHQnO1xuaW1wb3J0IEJyb3dzZXJDb25uZWN0aW9uIGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbic7XG5pbXBvcnQgeyBRdWFyYW50aW5lIH0gZnJvbSAnLi4vdXRpbHMvZ2V0LW9wdGlvbnMvcXVhcmFudGluZSc7XG5pbXBvcnQgUmVxdWVzdEhvb2sgZnJvbSAnLi4vYXBpL3JlcXVlc3QtaG9va3MvaG9vayc7XG5pbXBvcnQgRHJpdmVyU3RhdHVzIGZyb20gJy4uL2NsaWVudC9kcml2ZXIvc3RhdHVzJztcbmltcG9ydCB7IENvbW1hbmRCYXNlLCBBY3Rpb25Db21tYW5kQmFzZSB9IGZyb20gJy4vY29tbWFuZHMvYmFzZS5qcyc7XG5pbXBvcnQgUm9sZSBmcm9tICcuLi9yb2xlL3JvbGUnO1xuaW1wb3J0IHsgVGVzdFJ1bkVycm9yQmFzZSB9IGZyb20gJy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgQ2FsbHNpdGVSZWNvcmQgfSBmcm9tICdjYWxsc2l0ZS1yZWNvcmQnO1xuaW1wb3J0IEV2ZW50RW1pdHRlciBmcm9tICdldmVudHMnO1xuaW1wb3J0IGdldEFzc2VydGlvblRpbWVvdXQgZnJvbSAnLi4vdXRpbHMvZ2V0LW9wdGlvbnMvZ2V0LWFzc2VydGlvbi10aW1lb3V0JztcbmltcG9ydCB7IEFzc2VydGlvbkNvbW1hbmQgfSBmcm9tICcuL2NvbW1hbmRzL2Fzc2VydGlvbic7XG5pbXBvcnQgeyBUYWtlU2NyZWVuc2hvdEJhc2VDb21tYW5kIH0gZnJvbSAnLi9jb21tYW5kcy9icm93c2VyLW1hbmlwdWxhdGlvbic7XG4vL0B0cy1pZ25vcmVcbmltcG9ydCB7IFRlc3RSdW4gYXMgTGVnYWN5VGVzdFJ1biB9IGZyb20gJ3Rlc3RjYWZlLWxlZ2FjeS1hcGknO1xuaW1wb3J0IHsgQXV0aENyZWRlbnRpYWxzIH0gZnJvbSAnLi4vYXBpL3N0cnVjdHVyZS9pbnRlcmZhY2VzJztcbmltcG9ydCBUZXN0UnVuUGhhc2UgZnJvbSAnLi9waGFzZSc7XG5cbmltcG9ydCB7XG4gICAgRXhlY3V0ZUNsaWVudEZ1bmN0aW9uQ29tbWFuZCxcbiAgICBFeGVjdXRlQ2xpZW50RnVuY3Rpb25Db21tYW5kQmFzZSxcbiAgICBFeGVjdXRlU2VsZWN0b3JDb21tYW5kLFxufSBmcm9tICcuL2NvbW1hbmRzL29ic2VydmF0aW9uJztcblxuaW1wb3J0IHsgUkVfRVhFQ1VUQUJMRV9QUk9NSVNFX01BUktFUl9ERVNDUklQVElPTiB9IGZyb20gJy4uL3NlcnZpY2VzL3NlcmlhbGl6YXRpb24vcmVwbGljYXRvci90cmFuc2Zvcm1zL3JlLWV4ZWN1dGFibGUtcHJvbWlzZS10cmFuc2Zvcm0vbWFya2VyJztcbmltcG9ydCBSZUV4ZWN1dGFibGVQcm9taXNlIGZyb20gJy4uL3V0aWxzL3JlLWV4ZWN1dGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgYWRkUmVuZGVyZWRXYXJuaW5nIGZyb20gJy4uL25vdGlmaWNhdGlvbnMvYWRkLXJlbmRlcmVkLXdhcm5pbmcnO1xuaW1wb3J0IGdldEJyb3dzZXIgZnJvbSAnLi4vdXRpbHMvZ2V0LWJyb3dzZXInO1xuaW1wb3J0IEFzc2VydGlvbkV4ZWN1dG9yIGZyb20gJy4uL2Fzc2VydGlvbnMvZXhlY3V0b3InO1xuaW1wb3J0IGFzeW5jRmlsdGVyIGZyb20gJy4uL3V0aWxzL2FzeW5jLWZpbHRlcic7XG5pbXBvcnQgRml4dHVyZSBmcm9tICcuLi9hcGkvc3RydWN0dXJlL2ZpeHR1cmUnO1xuaW1wb3J0IE1lc3NhZ2VCdXMgZnJvbSAnLi4vdXRpbHMvbWVzc2FnZS1idXMnO1xuaW1wb3J0IGV4ZWN1dGVGbldpdGhUaW1lb3V0IGZyb20gJy4uL3V0aWxzL2V4ZWN1dGUtZm4td2l0aC10aW1lb3V0JztcbmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7XG5pbXBvcnQgeyBDb29raWVPcHRpb25zIH0gZnJvbSAnLi9jb21tYW5kcy9vcHRpb25zJztcbmltcG9ydCB7IHByZXBhcmVTa2lwSnNFcnJvcnNPcHRpb25zIH0gZnJvbSAnLi4vYXBpL3NraXAtanMtZXJyb3JzJztcbmltcG9ydCB7IENvb2tpZVByb3ZpZGVyRmFjdG9yeSB9IGZyb20gJy4vY29va2llcy9mYWN0b3J5JztcbmltcG9ydCB7IENvb2tpZVByb3ZpZGVyIH0gZnJvbSAnLi9jb29raWVzL2Jhc2UnO1xuaW1wb3J0IHsgU3RvcmFnZXNQcm92aWRlciB9IGZyb20gJy4vc3RvcmFnZXMvYmFzZSc7XG5pbXBvcnQgeyBTdG9yYWdlc1Byb3ZpZGVyRmFjdG9yeSB9IGZyb20gJy4vc3RvcmFnZXMvZmFjdG9yeSc7XG5cbmltcG9ydCB3cmFwQ3VzdG9tQWN0aW9uIGZyb20gJy4uL2FwaS93cmFwLWN1c3RvbS1hY3Rpb24nO1xuXG5pbXBvcnQge1xuICAgIFByb3h5bGVzc1JvbGVQcm92aWRlcixcbiAgICBQcm94eVJvbGVQcm92aWRlcixcbiAgICBSb2xlUHJvdmlkZXIsXG59IGZyb20gJy4vcm9sZS1wcm92aWRlcic7XG5cbmltcG9ydCBQcm94eWxlc3NSZXF1ZXN0UGlwZWxpbmUgZnJvbSAnLi4vcHJveHlsZXNzL3JlcXVlc3QtcGlwZWxpbmUnO1xuaW1wb3J0IFByb3h5bGVzcyBmcm9tICcuLi9wcm94eWxlc3MnO1xuXG5jb25zdCBsYXp5UmVxdWlyZSAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCdpbXBvcnQtbGF6eScpKHJlcXVpcmUpO1xuY29uc3QgQ2xpZW50RnVuY3Rpb25CdWlsZGVyICAgICAgID0gbGF6eVJlcXVpcmUoJy4uL2NsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXInKTtcbmNvbnN0IFRlc3RSdW5Cb29rbWFyayAgICAgICAgICAgICA9IGxhenlSZXF1aXJlKCcuL2Jvb2ttYXJrJyk7XG5jb25zdCBhY3Rpb25Db21tYW5kcyAgICAgICAgICAgICAgPSBsYXp5UmVxdWlyZSgnLi9jb21tYW5kcy9hY3Rpb25zJyk7XG5jb25zdCBicm93c2VyTWFuaXB1bGF0aW9uQ29tbWFuZHMgPSBsYXp5UmVxdWlyZSgnLi9jb21tYW5kcy9icm93c2VyLW1hbmlwdWxhdGlvbicpO1xuY29uc3Qgc2VydmljZUNvbW1hbmRzICAgICAgICAgICAgID0gbGF6eVJlcXVpcmUoJy4vY29tbWFuZHMvc2VydmljZScpO1xuY29uc3Qgb2JzZXJ2YXRpb25Db21tYW5kcyAgICAgICAgID0gbGF6eVJlcXVpcmUoJy4vY29tbWFuZHMvb2JzZXJ2YXRpb24nKTtcblxuY29uc3QgeyBleGVjdXRlSnNFeHByZXNzaW9uLCBleGVjdXRlQXN5bmNKc0V4cHJlc3Npb24gfSA9IGxhenlSZXF1aXJlKCcuL2V4ZWN1dGUtanMtZXhwcmVzc2lvbicpO1xuXG5jb25zdCBURVNUX1JVTl9URU1QTEFURSAgICAgICAgICAgICAgID0gcmVhZCgnLi4vY2xpZW50L3Rlc3QtcnVuL2luZGV4LmpzLm11c3RhY2hlJykgYXMgc3RyaW5nO1xuY29uc3QgSUZSQU1FX1RFU1RfUlVOX1RFTVBMQVRFICAgICAgICA9IHJlYWQoJy4uL2NsaWVudC90ZXN0LXJ1bi9pZnJhbWUuanMubXVzdGFjaGUnKSBhcyBzdHJpbmc7XG5jb25zdCBURVNUX0RPTkVfQ09ORklSTUFUSU9OX1JFU1BPTlNFID0gJ3Rlc3QtZG9uZS1jb25maXJtYXRpb24nO1xuY29uc3QgTUFYX1JFU1BPTlNFX0RFTEFZICAgICAgICAgICAgICA9IDMwMDA7XG5jb25zdCBDSElMRF9XSU5ET1dfUkVBRFlfVElNRU9VVCAgICAgID0gMzAgKiAxMDAwO1xuXG5jb25zdCBBTExfRFJJVkVSX1RBU0tTX0FEREVEX1RPX1FVRVVFX0VWRU5UID0gJ2FsbC1kcml2ZXItdGFza3MtYWRkZWQtdG8tcXVldWUnO1xuXG5jb25zdCBDT01QSUxFUl9TRVJWSUNFX0VWRU5UUyA9IFtcbiAgICAnc2V0TW9jaycsXG4gICAgJ3NldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zJyxcbiAgICAnc2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50JyxcbiAgICAncmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50Jyxcbl07XG5cblxuaW50ZXJmYWNlIFRlc3RSdW5Jbml0IHtcbiAgICB0ZXN0OiBUZXN0O1xuICAgIGJyb3dzZXJDb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbjtcbiAgICBzY3JlZW5zaG90Q2FwdHVyZXI6IENhcHR1cmVyO1xuICAgIGdsb2JhbFdhcm5pbmdMb2c6IFdhcm5pbmdMb2c7XG4gICAgb3B0czogRGljdGlvbmFyeTxPcHRpb25WYWx1ZT47XG4gICAgY29tcGlsZXJTZXJ2aWNlPzogQ29tcGlsZXJTZXJ2aWNlO1xuICAgIG1lc3NhZ2VCdXM/OiBNZXNzYWdlQnVzO1xuICAgIHN0YXJ0UnVuRXhlY3V0aW9uVGltZT86IERhdGU7XG59XG5cbmludGVyZmFjZSBEcml2ZXJUYXNrIHtcbiAgICBjb21tYW5kOiBDb21tYW5kQmFzZTtcbiAgICByZXNvbHZlOiBGdW5jdGlvbjtcbiAgICByZWplY3Q6IEZ1bmN0aW9uO1xuICAgIGNhbGxzaXRlOiBDYWxsc2l0ZVJlY29yZDtcbn1cblxuaW50ZXJmYWNlIERyaXZlck1lc3NhZ2Uge1xuICAgIHN0YXR1czogRHJpdmVyU3RhdHVzO1xufVxuXG5pbnRlcmZhY2UgRHJpdmVyV2FybmluZyB7XG4gICAgdHlwZToga2V5b2YgdHlwZW9mIFdBUk5JTkdfTUVTU0FHRTtcbiAgICBhcmdzOiBzdHJpbmdbXTtcbn1cblxuaW50ZXJmYWNlIFJlcXVlc3RUaW1lb3V0IHtcbiAgICBwYWdlPzogbnVtYmVyO1xuICAgIGFqYXg/OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBFeGVjdXRpb25UaW1lb3V0IHtcbiAgICB0aW1lb3V0OiBudW1iZXI7XG4gICAgcmVqZWN0V2l0aDogVGVzdFRpbWVvdXRFcnJvciB8IFJ1blRpbWVvdXRFcnJvcjtcbn1cblxuaW50ZXJmYWNlIFBlbmRpbmdSZXF1ZXN0IHtcbiAgICByZXNwb25zZVRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAgIHJlc29sdmU6IEZ1bmN0aW9uO1xuICAgIHJlamVjdDogRnVuY3Rpb247XG59XG5cbmludGVyZmFjZSBCcm93c2VyTWFuaXB1bGF0aW9uUmVzdWx0IHtcbiAgICByZXN1bHQ6IHVua25vd247XG4gICAgZXJyb3I6IHVua25vd247XG59XG5cbmludGVyZmFjZSBPcGVuZWRXaW5kb3dJbmZvcm1hdGlvbiB7XG4gICAgaWQ6IHN0cmluZztcbiAgICB1cmw6IHN0cmluZztcbiAgICB0aXRsZTogc3RyaW5nO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0UnVuIGV4dGVuZHMgQXN5bmNFdmVudEVtaXR0ZXIge1xuICAgIHByaXZhdGUgW3Rlc3RSdW5NYXJrZXJdOiBib29sZWFuO1xuICAgIHB1YmxpYyByZWFkb25seSB3YXJuaW5nTG9nOiBXYXJuaW5nTG9nO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0czogRGljdGlvbmFyeTxPcHRpb25WYWx1ZT47XG4gICAgcHVibGljIHJlYWRvbmx5IHRlc3Q6IFRlc3Q7XG4gICAgcHVibGljIHJlYWRvbmx5IGJyb3dzZXJDb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbjtcbiAgICBwdWJsaWMgdW5zdGFibGU6IGJvb2xlYW47XG4gICAgcHVibGljIHBoYXNlOiBUZXN0UnVuUGhhc2U7XG4gICAgcHJpdmF0ZSBkcml2ZXJUYXNrUXVldWU6IERyaXZlclRhc2tbXTtcbiAgICBwcml2YXRlIHRlc3REb25lQ29tbWFuZFF1ZXVlZDogYm9vbGVhbjtcbiAgICBwdWJsaWMgYWN0aXZlRGlhbG9nSGFuZGxlcjogRXhlY3V0ZUNsaWVudEZ1bmN0aW9uQ29tbWFuZCB8IG51bGw7XG4gICAgcHVibGljIGFjdGl2ZUlmcmFtZVNlbGVjdG9yOiBFeGVjdXRlU2VsZWN0b3JDb21tYW5kIHwgbnVsbDtcbiAgICBwdWJsaWMgc3BlZWQ6IG51bWJlcjtcbiAgICBwdWJsaWMgcGFnZUxvYWRUaW1lb3V0OiBudW1iZXI7XG4gICAgcHJpdmF0ZSByZWFkb25seSB0ZXN0RXhlY3V0aW9uVGltZW91dDogRXhlY3V0aW9uVGltZW91dCB8IG51bGw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBydW5FeGVjdXRpb25UaW1lb3V0OiBFeGVjdXRpb25UaW1lb3V0IHwgbnVsbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRpc2FibGVQYWdlUmVsb2FkczogYm9vbGVhbjtcbiAgICBwcml2YXRlIGRpc2FibGVQYWdlQ2FjaGluZzogYm9vbGVhbjtcbiAgICBwcml2YXRlIGRpc2FibGVNdWx0aXBsZVdpbmRvd3M6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSByZXF1ZXN0VGltZW91dDogUmVxdWVzdFRpbWVvdXQ7XG4gICAgcHVibGljIHJlYWRvbmx5IHNlc3Npb246IFNlc3Npb25Db250cm9sbGVyO1xuICAgIHB1YmxpYyBjb25zb2xlTWVzc2FnZXM6IEJyb3dzZXJDb25zb2xlTWVzc2FnZXM7XG4gICAgcHJpdmF0ZSBwZW5kaW5nUmVxdWVzdDogUGVuZGluZ1JlcXVlc3QgfCBudWxsO1xuICAgIHB1YmxpYyBwZW5kaW5nUGFnZUVycm9yOiBQYWdlTG9hZEVycm9yIHwgRXJyb3IgfCBudWxsO1xuICAgIHB1YmxpYyBjb250cm9sbGVyOiBUZXN0Q29udHJvbGxlciB8IG51bGw7XG4gICAgcHVibGljIGN0eDogb2JqZWN0O1xuICAgIHB1YmxpYyBmaXh0dXJlQ3R4OiBvYmplY3QgfCBudWxsO1xuICAgIHB1YmxpYyB0ZXN0UnVuQ3R4OiBvYmplY3QgfCBudWxsO1xuICAgIHByaXZhdGUgY3VycmVudFJvbGVJZDogc3RyaW5nIHwgbnVsbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHVzZWRSb2xlU3RhdGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIHB1YmxpYyBlcnJzOiBUZXN0UnVuRXJyb3JGb3JtYXR0YWJsZUFkYXB0ZXJbXTtcbiAgICBwcml2YXRlIGxhc3REcml2ZXJTdGF0dXNJZDogc3RyaW5nIHwgbnVsbDtcbiAgICBwcml2YXRlIGxhc3REcml2ZXJTdGF0dXNSZXNwb25zZTogQ29tbWFuZEJhc2UgfCBudWxsIHwgc3RyaW5nO1xuICAgIHByaXZhdGUgZmlsZURvd25sb2FkaW5nSGFuZGxlZDogYm9vbGVhbjtcbiAgICBwcml2YXRlIGF0dGFjaG1lbnREb3dubG9hZGluZ0hhbmRsZWQ6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSByZXNvbHZlV2FpdEZvckZpbGVEb3dubG9hZGluZ1Byb21pc2U6IEZ1bmN0aW9uIHwgbnVsbDtcbiAgICBwcml2YXRlIGFkZGluZ0RyaXZlclRhc2tzQ291bnQ6IG51bWJlcjtcbiAgICBwdWJsaWMgZGVidWdnaW5nOiBib29sZWFuO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVidWdPbkZhaWw6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSByZWFkb25seSBkaXNhYmxlRGVidWdCcmVha3BvaW50czogYm9vbGVhbjtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlYnVnUmVwb3J0ZXJQbHVnaW5Ib3N0OiBSZXBvcnRlclBsdWdpbkhvc3Q7XG4gICAgcHJpdmF0ZSByZWFkb25seSBicm93c2VyTWFuaXB1bGF0aW9uUXVldWU6IEJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZTtcbiAgICBwcml2YXRlIGRlYnVnTG9nOiBUZXN0UnVuRGVidWdMb2c7XG4gICAgcHVibGljIHF1YXJhbnRpbmU6IFF1YXJhbnRpbmUgfCBudWxsO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVidWdMb2dnZXI6IGFueTtcbiAgICBwdWJsaWMgb2JzZXJ2ZWRDYWxsc2l0ZXM6IE9ic2VydmVkQ2FsbHNpdGVzU3RvcmFnZTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29tcGlsZXJTZXJ2aWNlPzogQ29tcGlsZXJTZXJ2aWNlO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVwbGljYXRvcjogYW55O1xuICAgIHByaXZhdGUgZGlzY29ubmVjdGVkOiBib29sZWFuO1xuICAgIHByaXZhdGUgZXJyU2NyZWVuc2hvdFBhdGg6IHN0cmluZyB8IG51bGw7XG4gICAgcHJpdmF0ZSBhc3luY0pzRXhwcmVzc2lvbkNhbGxzaXRlczogTWFwPHN0cmluZywgQ2FsbHNpdGVSZWNvcmQ+O1xuICAgIHB1YmxpYyByZWFkb25seSBicm93c2VyOiBCcm93c2VyO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2VCdXM/OiBNZXNzYWdlQnVzO1xuICAgIHByaXZhdGUgX2NsaWVudEVudmlyb25tZW50UHJlcGFyZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIF9jb29raWVQcm92aWRlcjogQ29va2llUHJvdmlkZXI7XG4gICAgcHJpdmF0ZSBfc3RvcmFnZXNQcm92aWRlcjogU3RvcmFnZXNQcm92aWRlcjtcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhcnRSdW5FeGVjdXRpb25UaW1lPzogRGF0ZTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yZXF1ZXN0SG9va0V2ZW50UHJvdmlkZXI6IFJlcXVlc3RIb29rRXZlbnRQcm92aWRlcjtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yb2xlUHJvdmlkZXI6IFJvbGVQcm92aWRlcjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvciAoeyB0ZXN0LCBicm93c2VyQ29ubmVjdGlvbiwgc2NyZWVuc2hvdENhcHR1cmVyLCBnbG9iYWxXYXJuaW5nTG9nLCBvcHRzLCBjb21waWxlclNlcnZpY2UsIG1lc3NhZ2VCdXMsIHN0YXJ0UnVuRXhlY3V0aW9uVGltZSB9OiBUZXN0UnVuSW5pdCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXNbdGVzdFJ1bk1hcmtlcl0gICAgPSB0cnVlO1xuICAgICAgICB0aGlzLl9tZXNzYWdlQnVzICAgICAgID0gbWVzc2FnZUJ1cztcbiAgICAgICAgdGhpcy53YXJuaW5nTG9nICAgICAgICA9IG5ldyBXYXJuaW5nTG9nKGdsb2JhbFdhcm5pbmdMb2csIFdhcm5pbmdMb2cuY3JlYXRlQWRkV2FybmluZ0NhbGxiYWNrKG1lc3NhZ2VCdXMsIHRoaXMpKTtcbiAgICAgICAgdGhpcy5vcHRzICAgICAgICAgICAgICA9IG9wdHM7XG4gICAgICAgIHRoaXMudGVzdCAgICAgICAgICAgICAgPSB0ZXN0O1xuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uID0gYnJvd3NlckNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMudW5zdGFibGUgICAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5icm93c2VyICAgICAgICAgICA9IGdldEJyb3dzZXIoYnJvd3NlckNvbm5lY3Rpb24pO1xuXG4gICAgICAgIHRoaXMucGhhc2UgPSBUZXN0UnVuUGhhc2UuaW5pdGlhbDtcblxuICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZSAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLnRlc3REb25lQ29tbWFuZFF1ZXVlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuYWN0aXZlRGlhbG9nSGFuZGxlciAgPSBudWxsO1xuICAgICAgICB0aGlzLmFjdGl2ZUlmcmFtZVNlbGVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5zcGVlZCAgICAgICAgICAgICAgICA9IHRoaXMub3B0cy5zcGVlZCBhcyBudW1iZXI7XG4gICAgICAgIHRoaXMucGFnZUxvYWRUaW1lb3V0ICAgICAgPSB0aGlzLl9nZXRQYWdlTG9hZFRpbWVvdXQodGVzdCwgb3B0cyk7XG4gICAgICAgIHRoaXMudGVzdEV4ZWN1dGlvblRpbWVvdXQgPSB0aGlzLl9nZXRUZXN0RXhlY3V0aW9uVGltZW91dChvcHRzKTtcblxuICAgICAgICB0aGlzLmRpc2FibGVQYWdlUmVsb2FkcyAgID0gdGVzdC5kaXNhYmxlUGFnZVJlbG9hZHMgfHwgb3B0cy5kaXNhYmxlUGFnZVJlbG9hZHMgYXMgYm9vbGVhbiAmJiB0ZXN0LmRpc2FibGVQYWdlUmVsb2FkcyAhPT0gZmFsc2U7XG4gICAgICAgIHRoaXMuZGlzYWJsZVBhZ2VDYWNoaW5nICAgPSB0ZXN0LmRpc2FibGVQYWdlQ2FjaGluZyB8fCBvcHRzLmRpc2FibGVQYWdlQ2FjaGluZyBhcyBib29sZWFuO1xuXG4gICAgICAgIHRoaXMuZGlzYWJsZU11bHRpcGxlV2luZG93cyA9IG9wdHMuZGlzYWJsZU11bHRpcGxlV2luZG93cyBhcyBib29sZWFuO1xuXG4gICAgICAgIHRoaXMucmVxdWVzdFRpbWVvdXQgPSB0aGlzLl9nZXRSZXF1ZXN0VGltZW91dCh0ZXN0LCBvcHRzKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24gPSBTZXNzaW9uQ29udHJvbGxlci5nZXRTZXNzaW9uKHRoaXMpO1xuXG4gICAgICAgIHRoaXMuY29uc29sZU1lc3NhZ2VzID0gbmV3IEJyb3dzZXJDb25zb2xlTWVzc2FnZXMoKTtcblxuICAgICAgICB0aGlzLnBlbmRpbmdSZXF1ZXN0ICAgPSBudWxsO1xuICAgICAgICB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgPSBudWxsO1xuXG4gICAgICAgIHRoaXMuY29udHJvbGxlciA9IG51bGw7XG4gICAgICAgIHRoaXMuY3R4ICAgICAgICA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuZml4dHVyZUN0eCA9IG51bGw7XG4gICAgICAgIHRoaXMudGVzdFJ1bkN0eCA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5jdXJyZW50Um9sZUlkICA9IG51bGw7XG4gICAgICAgIHRoaXMudXNlZFJvbGVTdGF0ZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgICAgIHRoaXMuZXJycyA9IFtdO1xuXG4gICAgICAgIHRoaXMubGFzdERyaXZlclN0YXR1c0lkICAgICAgID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0RHJpdmVyU3RhdHVzUmVzcG9uc2UgPSBudWxsO1xuXG4gICAgICAgIHRoaXMuZmlsZURvd25sb2FkaW5nSGFuZGxlZCAgICAgICAgICAgICAgID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlID0gbnVsbDtcblxuICAgICAgICB0aGlzLmF0dGFjaG1lbnREb3dubG9hZGluZ0hhbmRsZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLmFkZGluZ0RyaXZlclRhc2tzQ291bnQgPSAwO1xuXG4gICAgICAgIHRoaXMuZGVidWdnaW5nICAgICAgICAgICAgICAgPSB0aGlzLm9wdHMuZGVidWdNb2RlIGFzIGJvb2xlYW47XG4gICAgICAgIHRoaXMuZGVidWdPbkZhaWwgICAgICAgICAgICAgPSB0aGlzLm9wdHMuZGVidWdPbkZhaWwgYXMgYm9vbGVhbjtcbiAgICAgICAgdGhpcy5kaXNhYmxlRGVidWdCcmVha3BvaW50cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRlYnVnUmVwb3J0ZXJQbHVnaW5Ib3N0ID0gbmV3IFJlcG9ydGVyUGx1Z2luSG9zdCh7IG5vQ29sb3JzOiBmYWxzZSB9KTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZSA9IG5ldyBCcm93c2VyTWFuaXB1bGF0aW9uUXVldWUoYnJvd3NlckNvbm5lY3Rpb24sIHNjcmVlbnNob3RDYXB0dXJlciwgdGhpcy53YXJuaW5nTG9nKTtcblxuICAgICAgICB0aGlzLmRlYnVnTG9nID0gbmV3IFRlc3RSdW5EZWJ1Z0xvZyh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnVzZXJBZ2VudCk7XG5cbiAgICAgICAgdGhpcy5xdWFyYW50aW5lICA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlciA9IHRoaXMub3B0cy5kZWJ1Z0xvZ2dlcjtcblxuICAgICAgICB0aGlzLm9ic2VydmVkQ2FsbHNpdGVzICAgICAgICAgID0gbmV3IE9ic2VydmVkQ2FsbHNpdGVzU3RvcmFnZSgpO1xuICAgICAgICB0aGlzLmNvbXBpbGVyU2VydmljZSAgICAgICAgICAgID0gY29tcGlsZXJTZXJ2aWNlO1xuICAgICAgICB0aGlzLmFzeW5jSnNFeHByZXNzaW9uQ2FsbHNpdGVzID0gbmV3IE1hcDxzdHJpbmcsIENhbGxzaXRlUmVjb3JkPigpO1xuXG4gICAgICAgIHRoaXMucmVwbGljYXRvciA9IGNyZWF0ZVJlcGxpY2F0b3IoWyBuZXcgU2VsZWN0b3JOb2RlVHJhbnNmb3JtKCkgXSk7XG5cbiAgICAgICAgdGhpcy5kaXNjb25uZWN0ZWQgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVyclNjcmVlbnNob3RQYXRoID0gbnVsbDtcblxuICAgICAgICB0aGlzLnN0YXJ0UnVuRXhlY3V0aW9uVGltZSAgICAgPSBzdGFydFJ1bkV4ZWN1dGlvblRpbWU7XG4gICAgICAgIHRoaXMucnVuRXhlY3V0aW9uVGltZW91dCAgICAgICA9IHRoaXMuX2dldFJ1bkV4ZWN1dGlvblRpbWVvdXQob3B0cyk7XG4gICAgICAgIHRoaXMuX3JlcXVlc3RIb29rRXZlbnRQcm92aWRlciA9IHRoaXMuX2dldFJlcXVlc3RIb29rRXZlbnRQcm92aWRlcigpO1xuICAgICAgICB0aGlzLl9yb2xlUHJvdmlkZXIgICAgICAgICAgICAgPSB0aGlzLl9nZXRSb2xlUHJvdmlkZXIoKTtcblxuICAgICAgICB0aGlzLl9jb29raWVQcm92aWRlciAgID0gQ29va2llUHJvdmlkZXJGYWN0b3J5LmNyZWF0ZSh0aGlzLCB0aGlzLm9wdHMuZXhwZXJpbWVudGFsUHJveHlsZXNzIGFzIGJvb2xlYW4pO1xuICAgICAgICB0aGlzLl9zdG9yYWdlc1Byb3ZpZGVyID0gU3RvcmFnZXNQcm92aWRlckZhY3RvcnkuY3JlYXRlKHRoaXMsIHRoaXMub3B0cy5leHBlcmltZW50YWxQcm94eWxlc3MgYXMgYm9vbGVhbik7XG5cbiAgICAgICAgdGhpcy5fYWRkSW5qZWN0YWJsZXMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRSZXF1ZXN0SG9va0V2ZW50UHJvdmlkZXIgKCk6IFJlcXVlc3RIb29rRXZlbnRQcm92aWRlciB7XG4gICAgICAgIGlmICghdGhpcy5vcHRzLmV4cGVyaW1lbnRhbFByb3h5bGVzcylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlc3Npb24ucmVxdWVzdEhvb2tFdmVudFByb3ZpZGVyO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm94eWxlc3NSZXF1ZXN0UGlwZWxpbmUucmVxdWVzdEhvb2tFdmVudFByb3ZpZGVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBzYXZlU3RvcmFnZXNTbmFwc2hvdCAoc3RvcmFnZVNuYXBzaG90OiBTdG9yYWdlc1NuYXBzaG90KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMuZXhwZXJpbWVudGFsUHJveHlsZXNzKVxuICAgICAgICAgICAgdGhpcy5fcHJveHlsZXNzUmVxdWVzdFBpcGVsaW5lLnJlc3RvcmluZ1N0b3JhZ2VzID0gc3RvcmFnZVNuYXBzaG90O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0IF9wcm94eWxlc3NSZXF1ZXN0UGlwZWxpbmUgKCk6IFByb3h5bGVzc1JlcXVlc3RQaXBlbGluZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm94eWxlc3MucmVxdWVzdFBpcGVsaW5lO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0IF9wcm94eWxlc3MgKCk6IFByb3h5bGVzcyB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVJbmZvID0gdGhpcy5icm93c2VyQ29ubmVjdGlvbi5wcm92aWRlci5wbHVnaW4ub3BlbmVkQnJvd3NlcnNbdGhpcy5icm93c2VyQ29ubmVjdGlvbi5pZF07XG5cbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVJbmZvLnByb3h5bGVzcztcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRSb2xlUHJvdmlkZXIgKCk6IFJvbGVQcm92aWRlciB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMuZXhwZXJpbWVudGFsUHJveHlsZXNzKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm94eWxlc3NSb2xlUHJvdmlkZXIodGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eVJvbGVQcm92aWRlcih0aGlzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRQYWdlTG9hZFRpbWVvdXQgKHRlc3Q6IFRlc3QsIG9wdHM6IERpY3Rpb25hcnk8T3B0aW9uVmFsdWU+KTogbnVtYmVyIHtcbiAgICAgICAgaWYgKHRlc3QudGltZW91dHM/LnBhZ2VMb2FkVGltZW91dCAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgcmV0dXJuIHRlc3QudGltZW91dHMucGFnZUxvYWRUaW1lb3V0O1xuXG4gICAgICAgIHJldHVybiBvcHRzLnBhZ2VMb2FkVGltZW91dCBhcyBudW1iZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0UmVxdWVzdFRpbWVvdXQgKHRlc3Q6IFRlc3QsIG9wdHM6IERpY3Rpb25hcnk8T3B0aW9uVmFsdWU+KTogUmVxdWVzdFRpbWVvdXQge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGFnZTogdGVzdC50aW1lb3V0cz8ucGFnZVJlcXVlc3RUaW1lb3V0IHx8IG9wdHMucGFnZVJlcXVlc3RUaW1lb3V0IGFzIG51bWJlcixcbiAgICAgICAgICAgIGFqYXg6IHRlc3QudGltZW91dHM/LmFqYXhSZXF1ZXN0VGltZW91dCB8fCBvcHRzLmFqYXhSZXF1ZXN0VGltZW91dCBhcyBudW1iZXIsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0RXhlY3V0aW9uVGltZW91dCAodGltZW91dDogbnVtYmVyLCBlcnJvcjogVGVzdFRpbWVvdXRFcnJvciB8IFJ1blRpbWVvdXRFcnJvcik6IEV4ZWN1dGlvblRpbWVvdXQge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGltZW91dCxcbiAgICAgICAgICAgIHJlamVjdFdpdGg6IGVycm9yLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFRlc3RFeGVjdXRpb25UaW1lb3V0IChvcHRzOiBEaWN0aW9uYXJ5PE9wdGlvblZhbHVlPik6IEV4ZWN1dGlvblRpbWVvdXQgfCBudWxsIHtcbiAgICAgICAgY29uc3QgdGVzdEV4ZWN1dGlvblRpbWVvdXQgPSBvcHRzLnRlc3RFeGVjdXRpb25UaW1lb3V0IGFzIG51bWJlciB8fCAwO1xuXG4gICAgICAgIGlmICghdGVzdEV4ZWN1dGlvblRpbWVvdXQpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0RXhlY3V0aW9uVGltZW91dCh0ZXN0RXhlY3V0aW9uVGltZW91dCwgbmV3IFRlc3RUaW1lb3V0RXJyb3IodGVzdEV4ZWN1dGlvblRpbWVvdXQpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRSdW5FeGVjdXRpb25UaW1lb3V0IChvcHRzOiBEaWN0aW9uYXJ5PE9wdGlvblZhbHVlPik6IEV4ZWN1dGlvblRpbWVvdXQgfCBudWxsIHtcbiAgICAgICAgY29uc3QgcnVuRXhlY3V0aW9uVGltZW91dCA9IG9wdHMucnVuRXhlY3V0aW9uVGltZW91dCBhcyBudW1iZXIgfHwgMDtcblxuICAgICAgICBpZiAoIXJ1bkV4ZWN1dGlvblRpbWVvdXQpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0RXhlY3V0aW9uVGltZW91dChydW5FeGVjdXRpb25UaW1lb3V0LCBuZXcgUnVuVGltZW91dEVycm9yKHJ1bkV4ZWN1dGlvblRpbWVvdXQpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHJlc3RSdW5FeGVjdXRpb25UaW1lb3V0ICgpOiBFeGVjdXRpb25UaW1lb3V0IHwgbnVsbCB7XG4gICAgICAgIGlmICghdGhpcy5zdGFydFJ1bkV4ZWN1dGlvblRpbWUgfHwgIXRoaXMucnVuRXhlY3V0aW9uVGltZW91dClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lb3V0ID0gTWF0aC5tYXgodGhpcy5ydW5FeGVjdXRpb25UaW1lb3V0LnRpbWVvdXQgLSAoRGF0ZS5ub3coKSAtIHRoaXMuc3RhcnRSdW5FeGVjdXRpb25UaW1lLmdldFRpbWUoKSksIDApO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRFeGVjdXRpb25UaW1lb3V0KGN1cnJlbnRUaW1lb3V0LCB0aGlzLnJ1bkV4ZWN1dGlvblRpbWVvdXQucmVqZWN0V2l0aCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBleGVjdXRpb25UaW1lb3V0ICgpOiBFeGVjdXRpb25UaW1lb3V0IHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc3RSdW5FeGVjdXRpb25UaW1lb3V0ICYmICghdGhpcy50ZXN0RXhlY3V0aW9uVGltZW91dCB8fCB0aGlzLnJlc3RSdW5FeGVjdXRpb25UaW1lb3V0LnRpbWVvdXQgPCB0aGlzLnRlc3RFeGVjdXRpb25UaW1lb3V0LnRpbWVvdXQpXG4gICAgICAgICAgICA/IHRoaXMucmVzdFJ1bkV4ZWN1dGlvblRpbWVvdXRcbiAgICAgICAgICAgIDogdGhpcy50ZXN0RXhlY3V0aW9uVGltZW91dCB8fCBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2FkZENsaWVudFNjcmlwdENvbnRlbnRXYXJuaW5nc0lmTmVjZXNzYXJ5ICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgeyBlbXB0eSwgZHVwbGljYXRlZENvbnRlbnQgfSA9IGZpbmRQcm9ibGVtYXRpY1NjcmlwdHModGhpcy50ZXN0LmNsaWVudFNjcmlwdHMgYXMgQ2xpZW50U2NyaXB0W10pO1xuXG4gICAgICAgIGlmIChlbXB0eS5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UuY2xpZW50U2NyaXB0c1dpdGhFbXB0eUNvbnRlbnQpO1xuXG4gICAgICAgIGlmIChkdXBsaWNhdGVkQ29udGVudC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1ZmZpeCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGdldFBsdXJhbFN1ZmZpeChkdXBsaWNhdGVkQ29udGVudCk7XG4gICAgICAgICAgICBjb25zdCBkdXBsaWNhdGVkQ29udGVudENsaWVudFNjcmlwdHNTdHIgPSBnZXRDb25jYXRlbmF0ZWRWYWx1ZXNTdHJpbmcoZHVwbGljYXRlZENvbnRlbnQsICdcXG4nKTtcblxuICAgICAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoV0FSTklOR19NRVNTQUdFLmNsaWVudFNjcmlwdHNXaXRoRHVwbGljYXRlZENvbnRlbnQsIHN1ZmZpeCwgZHVwbGljYXRlZENvbnRlbnRDbGllbnRTY3JpcHRzU3RyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2FkZEluamVjdGFibGVzICgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fYWRkQ2xpZW50U2NyaXB0Q29udGVudFdhcm5pbmdzSWZOZWNlc3NhcnkoKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnNjcmlwdHMucHVzaCguLi5JTkpFQ1RBQkxFUy5TQ1JJUFRTKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnVzZXJTY3JpcHRzLnB1c2goLi4udGhpcy50ZXN0LmNsaWVudFNjcmlwdHMubWFwKHNjcmlwdCA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHVybDogIGdldEN1c3RvbUNsaWVudFNjcmlwdFVybChzY3JpcHQgYXMgQ2xpZW50U2NyaXB0KSxcbiAgICAgICAgICAgICAgICBwYWdlOiBzY3JpcHQucGFnZSBhcyBSZXF1ZXN0RmlsdGVyUnVsZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnN0eWxlcy5wdXNoKElOSkVDVEFCTEVTLlRFU1RDQUZFX1VJX1NUWUxFUyk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpZCAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi5pZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGluamVjdGFibGUgKCk6IEluamVjdGFibGVSZXNvdXJjZXMge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLmluamVjdGFibGU7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFF1YXJhbnRpbmVJbmZvIChxdWFyYW50aW5lOiBRdWFyYW50aW5lKTogdm9pZCB7XG4gICAgICAgIHRoaXMucXVhcmFudGluZSA9IHF1YXJhbnRpbmU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfYWRkUmVxdWVzdEhvb2sgKGhvb2s6IFJlcXVlc3RIb29rKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLnRlc3QucmVxdWVzdEhvb2tzLmluY2x1ZGVzKGhvb2spKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMudGVzdC5yZXF1ZXN0SG9va3MucHVzaChob29rKTtcbiAgICAgICAgYXdhaXQgdGhpcy5faW5pdFJlcXVlc3RIb29rKGhvb2spO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3JlbW92ZVJlcXVlc3RIb29rIChob29rOiBSZXF1ZXN0SG9vayk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMudGVzdC5yZXF1ZXN0SG9va3MuaW5jbHVkZXMoaG9vaykpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgcHVsbCh0aGlzLnRlc3QucmVxdWVzdEhvb2tzLCBob29rKTtcbiAgICAgICAgYXdhaXQgdGhpcy5fZGlzcG9zZVJlcXVlc3RIb29rKGhvb2spO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2luaXRSZXF1ZXN0SG9vayAoaG9vazogUmVxdWVzdEhvb2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaG9vay5fd2FybmluZ0xvZyA9IHRoaXMud2FybmluZ0xvZztcblxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChob29rLl9yZXF1ZXN0RmlsdGVyUnVsZXMubWFwKHJ1bGUgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RIb29rRXZlbnRQcm92aWRlci5hZGRSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMocnVsZSwge1xuICAgICAgICAgICAgICAgIG9uUmVxdWVzdDogICAgICAgICAgIGhvb2sub25SZXF1ZXN0LmJpbmQoaG9vayksXG4gICAgICAgICAgICAgICAgb25Db25maWd1cmVSZXNwb25zZTogaG9vay5fb25Db25maWd1cmVSZXNwb25zZS5iaW5kKGhvb2spLFxuICAgICAgICAgICAgICAgIG9uUmVzcG9uc2U6ICAgICAgICAgIGhvb2sub25SZXNwb25zZS5iaW5kKGhvb2spLFxuICAgICAgICAgICAgfSwgKGVycjogUmVxdWVzdEhvb2tNZXRob2RFcnJvcikgPT4gdGhpcy5fb25SZXF1ZXN0SG9va01ldGhvZEVycm9yKGVyciwgaG9vay5fY2xhc3NOYW1lKSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9pbml0UmVxdWVzdEhvb2tGb3JDb21waWxlclNlcnZpY2UgKGhvb2tJZDogc3RyaW5nLCBob29rQ2xhc3NOYW1lOiBzdHJpbmcsIHJ1bGVzOiBSZXF1ZXN0RmlsdGVyUnVsZVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHRlc3RJZCA9IHRoaXMudGVzdC5pZDtcblxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChydWxlcy5tYXAocnVsZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVxdWVzdEhvb2tFdmVudFByb3ZpZGVyLmFkZFJlcXVlc3RFdmVudExpc3RlbmVycyhydWxlLCB7XG4gICAgICAgICAgICAgICAgb25SZXF1ZXN0OiAgICAgICAgICAgKGV2ZW50OiBSZXF1ZXN0RXZlbnQpID0+IHRoaXMuY29tcGlsZXJTZXJ2aWNlPy5vblJlcXVlc3RIb29rRXZlbnQoeyB0ZXN0SWQsIGhvb2tJZCwgbmFtZTogUmVxdWVzdEhvb2tNZXRob2ROYW1lcy5vblJlcXVlc3QsIGV2ZW50RGF0YTogZXZlbnQgfSksXG4gICAgICAgICAgICAgICAgb25Db25maWd1cmVSZXNwb25zZTogKGV2ZW50OiBDb25maWd1cmVSZXNwb25zZUV2ZW50KSA9PiB0aGlzLmNvbXBpbGVyU2VydmljZT8ub25SZXF1ZXN0SG9va0V2ZW50KHsgdGVzdElkLCBob29rSWQsIG5hbWU6IFJlcXVlc3RIb29rTWV0aG9kTmFtZXMuX29uQ29uZmlndXJlUmVzcG9uc2UsIGV2ZW50RGF0YTogZXZlbnQgfSksXG4gICAgICAgICAgICAgICAgb25SZXNwb25zZTogICAgICAgICAgKGV2ZW50OiBSZXNwb25zZUV2ZW50KSA9PiB0aGlzLmNvbXBpbGVyU2VydmljZT8ub25SZXF1ZXN0SG9va0V2ZW50KHsgdGVzdElkLCBob29rSWQsIG5hbWU6IFJlcXVlc3RIb29rTWV0aG9kTmFtZXMub25SZXNwb25zZSwgZXZlbnREYXRhOiBldmVudCB9KSxcbiAgICAgICAgICAgIH0sIGVyciA9PiB0aGlzLl9vblJlcXVlc3RIb29rTWV0aG9kRXJyb3IoZXJyLCBob29rQ2xhc3NOYW1lKSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9vblJlcXVlc3RIb29rTWV0aG9kRXJyb3IgKGV2ZW50OiBSZXF1ZXN0SG9va01ldGhvZEVycm9yLCBob29rQ2xhc3NOYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgbGV0IGVycjogRXJyb3IgfCBUZXN0UnVuRXJyb3JCYXNlICAgICAgICAgICAgPSBldmVudC5lcnJvcjtcbiAgICAgICAgY29uc3QgaXNSZXF1ZXN0SG9va05vdEltcGxlbWVudGVkTWV0aG9kRXJyb3IgPSAoZXJyIGFzIHVua25vd24gYXMgVGVzdFJ1bkVycm9yQmFzZSk/LmNvZGUgPT09IFRFU1RfUlVOX0VSUk9SUy5yZXF1ZXN0SG9va05vdEltcGxlbWVudGVkRXJyb3I7XG5cbiAgICAgICAgaWYgKCFpc1JlcXVlc3RIb29rTm90SW1wbGVtZW50ZWRNZXRob2RFcnJvcilcbiAgICAgICAgICAgIGVyciA9IG5ldyBSZXF1ZXN0SG9va1VuaGFuZGxlZEVycm9yKGVyciwgaG9va0NsYXNzTmFtZSwgZXZlbnQubWV0aG9kTmFtZSk7XG5cbiAgICAgICAgdGhpcy5hZGRFcnJvcihlcnIpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2Rpc3Bvc2VSZXF1ZXN0SG9vayAoaG9vazogUmVxdWVzdEhvb2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaG9vay5fd2FybmluZ0xvZyA9IG51bGw7XG5cbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoaG9vay5fcmVxdWVzdEZpbHRlclJ1bGVzLm1hcChydWxlID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZXF1ZXN0SG9va0V2ZW50UHJvdmlkZXIucmVtb3ZlUmVxdWVzdEV2ZW50TGlzdGVuZXJzKHJ1bGUpO1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfZGV0YWNoUmVxdWVzdEV2ZW50TGlzdGVuZXJzIChydWxlczogUmVxdWVzdEZpbHRlclJ1bGVbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChydWxlcy5tYXAocnVsZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVxdWVzdEhvb2tFdmVudFByb3ZpZGVyLnJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVycyhydWxlKTtcbiAgICAgICAgfSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3N1YnNjcmliZU9uQ29tcGlsZXJTZXJ2aWNlRXZlbnRzICgpOiB2b2lkIHtcbiAgICAgICAgQ09NUElMRVJfU0VSVklDRV9FVkVOVFMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29tcGlsZXJTZXJ2aWNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb21waWxlclNlcnZpY2Uub24oZXZlbnROYW1lLCBhc3luYyBhcmdzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNlc3Npb25bZXZlbnROYW1lXSguLi5hcmdzKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMuY29tcGlsZXJTZXJ2aWNlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBpbGVyU2VydmljZS5vbignYWRkUmVxdWVzdEV2ZW50TGlzdGVuZXJzJywgYXN5bmMgKHsgaG9va0lkLCBob29rQ2xhc3NOYW1lLCBydWxlcyB9KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5faW5pdFJlcXVlc3RIb29rRm9yQ29tcGlsZXJTZXJ2aWNlKGhvb2tJZCwgaG9va0NsYXNzTmFtZSwgcnVsZXMpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuY29tcGlsZXJTZXJ2aWNlLm9uKCdyZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMnLCBhc3luYyAoeyBydWxlcyB9KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fZGV0YWNoUmVxdWVzdEV2ZW50TGlzdGVuZXJzKHJ1bGVzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfaW5pdFJlcXVlc3RIb29rcyAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmNvbXBpbGVyU2VydmljZSkge1xuICAgICAgICAgICAgdGhpcy5fc3Vic2NyaWJlT25Db21waWxlclNlcnZpY2VFdmVudHMoKTtcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMudGVzdC5yZXF1ZXN0SG9va3MubWFwKGhvb2sgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbml0UmVxdWVzdEhvb2tGb3JDb21waWxlclNlcnZpY2UoaG9vay5pZCwgaG9vay5fY2xhc3NOYW1lLCBob29rLl9yZXF1ZXN0RmlsdGVyUnVsZXMpO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMudGVzdC5yZXF1ZXN0SG9va3MubWFwKGhvb2sgPT4gdGhpcy5faW5pdFJlcXVlc3RIb29rKGhvb2spKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcHJlcGFyZVNraXBKc0Vycm9yc09wdGlvbiAoKTogYm9vbGVhbiB8IEV4ZWN1dGVDbGllbnRGdW5jdGlvbkNvbW1hbmQge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy50ZXN0LnNraXBKc0Vycm9yc09wdGlvbnMgIT09IHZvaWQgMFxuICAgICAgICAgICAgPyB0aGlzLnRlc3Quc2tpcEpzRXJyb3JzT3B0aW9uc1xuICAgICAgICAgICAgOiB0aGlzLm9wdHMuc2tpcEpzRXJyb3JzIGFzIFNraXBKc0Vycm9yc09wdGlvbnNPYmplY3QgfCBib29sZWFuIHx8IGZhbHNlO1xuXG4gICAgICAgIHJldHVybiBwcmVwYXJlU2tpcEpzRXJyb3JzT3B0aW9ucyhvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvLyBIYW1tZXJoZWFkIHBheWxvYWRcbiAgICBwdWJsaWMgYXN5bmMgZ2V0UGF5bG9hZFNjcmlwdCAoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgdGhpcy5maWxlRG93bmxvYWRpbmdIYW5kbGVkICAgICAgICAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXNvbHZlV2FpdEZvckZpbGVEb3dubG9hZGluZ1Byb21pc2UgPSBudWxsO1xuXG4gICAgICAgIGNvbnN0IHNraXBKc0Vycm9ycyA9IHRoaXMuX3ByZXBhcmVTa2lwSnNFcnJvcnNPcHRpb24oKTtcblxuICAgICAgICByZXR1cm4gTXVzdGFjaGUucmVuZGVyKFRFU1RfUlVOX1RFTVBMQVRFLCB7XG4gICAgICAgICAgICB0ZXN0UnVuSWQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnNlc3Npb24uaWQpLFxuICAgICAgICAgICAgYnJvd3NlcklkOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi5pZCksXG4gICAgICAgICAgICBhY3RpdmVXaW5kb3dJZDogICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmFjdGl2ZVdpbmRvd0lkKSxcbiAgICAgICAgICAgIGJyb3dzZXJIZWFydGJlYXRSZWxhdGl2ZVVybDogICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uaGVhcnRiZWF0UmVsYXRpdmVVcmwpLFxuICAgICAgICAgICAgYnJvd3NlclN0YXR1c1JlbGF0aXZlVXJsOiAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi5zdGF0dXNSZWxhdGl2ZVVybCksXG4gICAgICAgICAgICBicm93c2VyU3RhdHVzRG9uZVJlbGF0aXZlVXJsOiAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnN0YXR1c0RvbmVSZWxhdGl2ZVVybCksXG4gICAgICAgICAgICBicm93c2VySWRsZVJlbGF0aXZlVXJsOiAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmlkbGVSZWxhdGl2ZVVybCksXG4gICAgICAgICAgICBicm93c2VyQWN0aXZlV2luZG93SWRVcmw6ICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmFjdGl2ZVdpbmRvd0lkVXJsKSxcbiAgICAgICAgICAgIGJyb3dzZXJDbG9zZVdpbmRvd1VybDogICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uY2xvc2VXaW5kb3dVcmwpLFxuICAgICAgICAgICAgYnJvd3Nlck9wZW5GaWxlUHJvdG9jb2xSZWxhdGl2ZVVybDogICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi5vcGVuRmlsZVByb3RvY29sUmVsYXRpdmVVcmwpLFxuICAgICAgICAgICAgYnJvd3NlckRpc3BhdGNoUHJveHlsZXNzRXZlbnRSZWxhdGl2ZVVybDogSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi5kaXNwYXRjaFByb3h5bGVzc0V2ZW50UmVsYXRpdmVVcmwpLFxuICAgICAgICAgICAgdXNlckFnZW50OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi51c2VyQWdlbnQpLFxuICAgICAgICAgICAgdGVzdE5hbWU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy50ZXN0Lm5hbWUpLFxuICAgICAgICAgICAgZml4dHVyZU5hbWU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoKHRoaXMudGVzdC5maXh0dXJlIGFzIEZpeHR1cmUpLm5hbWUpLFxuICAgICAgICAgICAgc2VsZWN0b3JUaW1lb3V0OiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLnNlbGVjdG9yVGltZW91dCxcbiAgICAgICAgICAgIHBhZ2VMb2FkVGltZW91dDogICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFnZUxvYWRUaW1lb3V0LFxuICAgICAgICAgICAgY2hpbGRXaW5kb3dSZWFkeVRpbWVvdXQ6ICAgICAgICAgICAgICAgICAgQ0hJTERfV0lORE9XX1JFQURZX1RJTUVPVVQsXG4gICAgICAgICAgICBza2lwSnNFcnJvcnM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShza2lwSnNFcnJvcnMpLFxuICAgICAgICAgICAgcmV0cnlUZXN0UGFnZXM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLnJldHJ5VGVzdFBhZ2VzLFxuICAgICAgICAgICAgc3BlZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGVlZCxcbiAgICAgICAgICAgIGRpYWxvZ0hhbmRsZXI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYWN0aXZlRGlhbG9nSGFuZGxlciksXG4gICAgICAgICAgICBjYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9uczogICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShhd2FpdCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmNhblVzZURlZmF1bHRXaW5kb3dBY3Rpb25zKCkpLFxuICAgICAgICAgICAgcHJveHlsZXNzOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5vcHRzLmV4cGVyaW1lbnRhbFByb3h5bGVzcyksXG4gICAgICAgICAgICBkb21haW46ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5wcm94eS5zZXJ2ZXIxSW5mby5kb21haW4pLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SWZyYW1lUGF5bG9hZFNjcmlwdCAoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIE11c3RhY2hlLnJlbmRlcihJRlJBTUVfVEVTVF9SVU5fVEVNUExBVEUsIHtcbiAgICAgICAgICAgIHRlc3RSdW5JZDogICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5zZXNzaW9uLmlkKSxcbiAgICAgICAgICAgIHNlbGVjdG9yVGltZW91dDogdGhpcy5vcHRzLnNlbGVjdG9yVGltZW91dCxcbiAgICAgICAgICAgIHBhZ2VMb2FkVGltZW91dDogdGhpcy5wYWdlTG9hZFRpbWVvdXQsXG4gICAgICAgICAgICByZXRyeVRlc3RQYWdlczogICEhdGhpcy5vcHRzLnJldHJ5VGVzdFBhZ2VzLFxuICAgICAgICAgICAgc3BlZWQ6ICAgICAgICAgICB0aGlzLnNwZWVkLFxuICAgICAgICAgICAgZGlhbG9nSGFuZGxlcjogICBKU09OLnN0cmluZ2lmeSh0aGlzLmFjdGl2ZURpYWxvZ0hhbmRsZXIpLFxuICAgICAgICAgICAgcHJveHlsZXNzOiAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLm9wdHMuZXhwZXJpbWVudGFsUHJveHlsZXNzKSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSGFtbWVyaGVhZCBoYW5kbGVyc1xuICAgIHB1YmxpYyBnZXRBdXRoQ3JlZGVudGlhbHMgKCk6IG51bGwgfCBBdXRoQ3JlZGVudGlhbHMge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXN0LmF1dGhDcmVkZW50aWFscztcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFuZGxlRmlsZURvd25sb2FkICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlKSB7XG4gICAgICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSh0cnVlKTtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVBdHRhY2htZW50IChkYXRhOiB7IGlzT3BlbmVkSW5OZXdXaW5kb3c6IGJvb2xlYW4gfSk6IHZvaWQge1xuICAgICAgICBpZiAoZGF0YS5pc09wZW5lZEluTmV3V2luZG93KVxuICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50RG93bmxvYWRpbmdIYW5kbGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFuZGxlUGFnZUVycm9yIChjdHg6IGFueSwgZXJyOiBFcnJvcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgPSBuZXcgUGFnZUxvYWRFcnJvcihlcnIsIGN0eC5yZXFPcHRzLnVybCk7XG5cbiAgICAgICAgY3R4LnJlZGlyZWN0KGN0eC50b1Byb3h5VXJsKFNQRUNJQUxfRVJST1JfUEFHRSkpO1xuICAgIH1cblxuICAgIC8vIFRlc3QgZnVuY3Rpb24gZXhlY3V0aW9uXG4gICAgcHJpdmF0ZSBhc3luYyBfZXhlY3V0ZVRlc3RGbiAocGhhc2U6IFRlc3RSdW5QaGFzZSwgZm46IEZ1bmN0aW9uLCB0aW1lb3V0OiBFeGVjdXRpb25UaW1lb3V0IHwgbnVsbCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICB0aGlzLnBoYXNlID0gcGhhc2U7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGV4ZWN1dGVGbldpdGhUaW1lb3V0KGZuLCB0aW1lb3V0LCB0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX21ha2VTY3JlZW5zaG90T25GYWlsKCk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkRXJyb3IoZXJyKTtcblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5lcnJTY3JlZW5zaG90UGF0aCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gIXRoaXMuX2FkZFBlbmRpbmdQYWdlRXJyb3JJZkFueSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3J1bkJlZm9yZUhvb2sgKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBpZiAodGhpcy50ZXN0Lmdsb2JhbEJlZm9yZUZuKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5fZXhlY3V0ZVRlc3RGbihUZXN0UnVuUGhhc2UuaW5UZXN0QmVmb3JlSG9vaywgdGhpcy50ZXN0Lmdsb2JhbEJlZm9yZUZuLCB0aGlzLmV4ZWN1dGlvblRpbWVvdXQpO1xuXG4gICAgICAgIGlmICh0aGlzLnRlc3QuYmVmb3JlRm4pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZXhlY3V0ZVRlc3RGbihUZXN0UnVuUGhhc2UuaW5UZXN0QmVmb3JlSG9vaywgdGhpcy50ZXN0LmJlZm9yZUZuLCB0aGlzLmV4ZWN1dGlvblRpbWVvdXQpO1xuXG4gICAgICAgIGlmICh0aGlzLnRlc3QuZml4dHVyZT8uYmVmb3JlRWFjaEZuKVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX2V4ZWN1dGVUZXN0Rm4oVGVzdFJ1blBoYXNlLmluRml4dHVyZUJlZm9yZUVhY2hIb29rLCB0aGlzLnRlc3QuZml4dHVyZT8uYmVmb3JlRWFjaEZuLCB0aGlzLmV4ZWN1dGlvblRpbWVvdXQpO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3J1bkFmdGVySG9vayAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLnRlc3QuYWZ0ZXJGbilcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2V4ZWN1dGVUZXN0Rm4oVGVzdFJ1blBoYXNlLmluVGVzdEFmdGVySG9vaywgdGhpcy50ZXN0LmFmdGVyRm4sIHRoaXMuZXhlY3V0aW9uVGltZW91dCk7XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudGVzdC5maXh0dXJlPy5hZnRlckVhY2hGbilcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2V4ZWN1dGVUZXN0Rm4oVGVzdFJ1blBoYXNlLmluRml4dHVyZUFmdGVyRWFjaEhvb2ssIHRoaXMudGVzdC5maXh0dXJlPy5hZnRlckVhY2hGbiwgdGhpcy5leGVjdXRpb25UaW1lb3V0KTtcblxuICAgICAgICBpZiAodGhpcy50ZXN0Lmdsb2JhbEFmdGVyRm4pXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9leGVjdXRlVGVzdEZuKFRlc3RSdW5QaGFzZS5pblRlc3RBZnRlckhvb2ssIHRoaXMudGVzdC5nbG9iYWxBZnRlckZuLCB0aGlzLmV4ZWN1dGlvblRpbWVvdXQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2ZpbmFsaXplVGVzdFJ1biAoaWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5jb21waWxlclNlcnZpY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHdhcm5pbmdzID0gYXdhaXQgdGhpcy5jb21waWxlclNlcnZpY2UuZ2V0V2FybmluZ01lc3NhZ2VzKHsgdGVzdFJ1bklkOiBpZCB9KTtcblxuICAgICAgICAgICAgd2FybmluZ3MuZm9yRWFjaCh3YXJuaW5nID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyh3YXJuaW5nKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbXBpbGVyU2VydmljZS5yZW1vdmVUZXN0UnVuRnJvbVN0YXRlKHsgdGVzdFJ1bklkOiBpZCB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRlc3RSdW5UcmFja2VyLnJlbW92ZUFjdGl2ZVRlc3RSdW4oaWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzdGFydCAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRlc3RSdW5UcmFja2VyLmFkZEFjdGl2ZVRlc3RSdW4odGhpcyk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdzdGFydCcpO1xuXG4gICAgICAgIGNvbnN0IG9uRGlzY29ubmVjdGVkID0gKGVycjogRXJyb3IpOiB2b2lkID0+IHRoaXMuX2Rpc2Nvbm5lY3QoZXJyKTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLm9uY2UoJ2Rpc2Nvbm5lY3RlZCcsIG9uRGlzY29ubmVjdGVkKTtcblxuICAgICAgICBhd2FpdCB0aGlzLm9uY2UoJ2Nvbm5lY3RlZCcpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuZW1pdCgncmVhZHknKTtcblxuICAgICAgICBpZiAoYXdhaXQgdGhpcy5fcnVuQmVmb3JlSG9vaygpKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9leGVjdXRlVGVzdEZuKFRlc3RSdW5QaGFzZS5pblRlc3QsIHRoaXMudGVzdC5mbiBhcyBGdW5jdGlvbiwgdGhpcy5leGVjdXRpb25UaW1lb3V0KTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX3J1bkFmdGVySG9vaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGlzY29ubmVjdGVkKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMucGhhc2UgPSBUZXN0UnVuUGhhc2UucGVuZGluZ0ZpbmFsaXphdGlvbjtcblxuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnJlbW92ZUxpc3RlbmVyKCdkaXNjb25uZWN0ZWQnLCBvbkRpc2Nvbm5lY3RlZCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZXJycy5sZW5ndGggJiYgdGhpcy5kZWJ1Z09uRmFpbCkge1xuICAgICAgICAgICAgY29uc3QgZXJyU3RyID0gdGhpcy5kZWJ1Z1JlcG9ydGVyUGx1Z2luSG9zdC5mb3JtYXRFcnJvcih0aGlzLmVycnNbMF0pO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbnF1ZXVlU2V0QnJlYWtwb2ludENvbW1hbmQodm9pZCAwLCBlcnJTdHIpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdiZWZvcmUtZG9uZScpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX2ludGVybmFsRXhlY3V0ZUNvbW1hbmQobmV3IHNlcnZpY2VDb21tYW5kcy5UZXN0RG9uZUNvbW1hbmQoKSk7XG5cbiAgICAgICAgdGhpcy5fYWRkUGVuZGluZ1BhZ2VFcnJvcklmQW55KCk7XG4gICAgICAgIHRoaXMuX3JlcXVlc3RIb29rRXZlbnRQcm92aWRlci5jbGVhclJlcXVlc3RFdmVudExpc3RlbmVycygpO1xuICAgICAgICB0aGlzLm5vcm1hbGl6ZVJlcXVlc3RIb29rRXJyb3JzKCk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fZmluYWxpemVUZXN0UnVuKHRoaXMuc2Vzc2lvbi5pZCk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdkb25lJyk7XG4gICAgfVxuXG4gICAgLy8gRXJyb3JzXG4gICAgcHJpdmF0ZSBfYWRkUGVuZGluZ1BhZ2VFcnJvcklmQW55ICgpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSB0aGlzLnBlbmRpbmdQYWdlRXJyb3I7XG5cbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEVycm9yKGVycm9yKTtcblxuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbnVsbDtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZW5zdXJlRXJyb3JJZCAoZXJyOiBFcnJvcik6IHZvaWQge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGVyci5pZCA9IGVyci5pZCB8fCBuYW5vaWQoNyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JlYXRlRXJyb3JBZGFwdGVyIChlcnI6IEVycm9yKTogVGVzdFJ1bkVycm9yRm9ybWF0dGFibGVBZGFwdGVyIHtcbiAgICAgICAgdGhpcy5fZW5zdXJlRXJyb3JJZChlcnIpO1xuXG4gICAgICAgIHJldHVybiBuZXcgVGVzdFJ1bkVycm9yRm9ybWF0dGFibGVBZGFwdGVyKGVyciwge1xuICAgICAgICAgICAgdXNlckFnZW50OiAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb24udXNlckFnZW50LFxuICAgICAgICAgICAgc2NyZWVuc2hvdFBhdGg6IHRoaXMuZXJyU2NyZWVuc2hvdFBhdGggfHwgJycsXG4gICAgICAgICAgICB0ZXN0UnVuSWQ6ICAgICAgdGhpcy5pZCxcbiAgICAgICAgICAgIHRlc3RSdW5QaGFzZTogICB0aGlzLnBoYXNlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkRXJyb3IgKGVycjogRXJyb3IgfCBUZXN0Q2FmZUVycm9yTGlzdCB8IFRlc3RSdW5FcnJvckJhc2UpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZXJyTGlzdCA9IChlcnIgaW5zdGFuY2VvZiBUZXN0Q2FmZUVycm9yTGlzdCA/IGVyci5pdGVtcyA6IFtlcnJdKSBhcyBFcnJvcltdO1xuXG4gICAgICAgIGVyckxpc3QuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLl9jcmVhdGVFcnJvckFkYXB0ZXIoaXRlbSk7XG5cbiAgICAgICAgICAgIHRoaXMuZXJycy5wdXNoKGFkYXB0ZXIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbm9ybWFsaXplUmVxdWVzdEhvb2tFcnJvcnMgKCk6IHZvaWQge1xuICAgICAgICBjb25zdCByZXF1ZXN0SG9va0Vycm9ycyA9IHJlbW92ZSh0aGlzLmVycnMsIGUgPT5cbiAgICAgICAgICAgIChlIGFzIHVua25vd24gYXMgVGVzdFJ1bkVycm9yQmFzZSkuY29kZSA9PT0gVEVTVF9SVU5fRVJST1JTLnJlcXVlc3RIb29rTm90SW1wbGVtZW50ZWRFcnJvciB8fFxuICAgICAgICAgICAgKGUgYXMgdW5rbm93biBhcyBUZXN0UnVuRXJyb3JCYXNlKS5jb2RlID09PSBURVNUX1JVTl9FUlJPUlMucmVxdWVzdEhvb2tVbmhhbmRsZWRFcnJvcik7XG5cbiAgICAgICAgaWYgKCFyZXF1ZXN0SG9va0Vycm9ycy5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgdW5pcVJlcXVlc3RIb29rRXJyb3JzID0gY2hhaW4ocmVxdWVzdEhvb2tFcnJvcnMpXG4gICAgICAgICAgICAudW5pcUJ5KGUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IGUgYXMgdW5rbm93biBhcyBSZXF1ZXN0SG9va0Jhc2VFcnJvcjtcblxuICAgICAgICAgICAgICAgIHJldHVybiBlcnIuaG9va0NsYXNzTmFtZSArIGVyci5tZXRob2ROYW1lO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5zb3J0QnkoWydob29rQ2xhc3NOYW1lJywgJ21ldGhvZE5hbWUnXSlcbiAgICAgICAgICAgIC52YWx1ZSgpO1xuXG4gICAgICAgIHRoaXMuZXJycyA9IHRoaXMuZXJycy5jb25jYXQodW5pcVJlcXVlc3RIb29rRXJyb3JzKTtcbiAgICB9XG5cbiAgICAvLyBUYXNrIHF1ZXVlXG4gICAgcHJpdmF0ZSBfZW5xdWV1ZUNvbW1hbmQgKGNvbW1hbmQ6IENvbW1hbmRCYXNlLCBjYWxsc2l0ZTogQ2FsbHNpdGVSZWNvcmQpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ1JlcXVlc3QpXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlUGVuZGluZ1JlcXVlc3QoY29tbWFuZCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgICAgICB0aGlzLmFkZGluZ0RyaXZlclRhc2tzQ291bnQtLTtcbiAgICAgICAgICAgIHRoaXMuZHJpdmVyVGFza1F1ZXVlLnB1c2goeyBjb21tYW5kLCByZXNvbHZlLCByZWplY3QsIGNhbGxzaXRlIH0pO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuYWRkaW5nRHJpdmVyVGFza3NDb3VudClcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoQUxMX0RSSVZFUl9UQVNLU19BRERFRF9UT19RVUVVRV9FVkVOVCwgdGhpcy5kcml2ZXJUYXNrUXVldWUubGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBkcml2ZXJUYXNrUXVldWVMZW5ndGggKCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZGluZ0RyaXZlclRhc2tzQ291bnQgPyBwcm9taXNpZnlFdmVudCh0aGlzIGFzIHVua25vd24gYXMgRXZlbnRFbWl0dGVyLCBBTExfRFJJVkVSX1RBU0tTX0FEREVEX1RPX1FVRVVFX0VWRU5UKSA6IFByb21pc2UucmVzb2x2ZSh0aGlzLmRyaXZlclRhc2tRdWV1ZS5sZW5ndGgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBfZW5xdWV1ZUJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kIChjb21tYW5kOiBDb21tYW5kQmFzZSwgY2FsbHNpdGU6IENhbGxzaXRlUmVjb3JkKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2VucXVldWVDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKTtcblxuICAgICAgICBjb25zdCBjb25zb2xlTWVzc2FnZUNvcHkgPSB0aGlzLmNvbnNvbGVNZXNzYWdlcy5nZXRDb3B5KCk7XG5cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByZXR1cm4gY29uc29sZU1lc3NhZ2VDb3B5W1N0cmluZyh0aGlzLmFjdGl2ZVdpbmRvd0lkKV07XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIF9lbnF1ZXVlR2V0Q29va2llcyAoY29tbWFuZDogR2V0Q29va2llc0NvbW1hbmQpOiBQcm9taXNlPFBhcnRpYWw8Q29va2llT3B0aW9ucz5bXT4ge1xuICAgICAgICBjb25zdCB7IGNvb2tpZXMsIHVybHMgfSA9IGNvbW1hbmQ7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nvb2tpZVByb3ZpZGVyLmdldENvb2tpZXMoY29va2llcywgdXJscyk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIF9lbnF1ZXVlU2V0Q29va2llcyAoY29tbWFuZDogU2V0Q29va2llc0NvbW1hbmQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgY29va2llcyA9IGNvbW1hbmQuY29va2llcztcbiAgICAgICAgY29uc3QgdXJsICAgICA9IGNvbW1hbmQudXJsIHx8IGF3YWl0IHRoaXMuZ2V0Q3VycmVudFVybCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9jb29raWVQcm92aWRlci5zZXRDb29raWVzKGNvb2tpZXMsIHVybCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIF9lbnF1ZXVlRGVsZXRlQ29va2llcyAoY29tbWFuZDogRGVsZXRlQ29va2llc0NvbW1hbmQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgeyBjb29raWVzLCB1cmxzIH0gPSBjb21tYW5kO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9jb29raWVQcm92aWRlci5kZWxldGVDb29raWVzKGNvb2tpZXMsIHVybHMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2VucXVldWVTZXRCcmVha3BvaW50Q29tbWFuZCAoY2FsbHNpdGU6IENhbGxzaXRlUmVjb3JkIHwgdW5kZWZpbmVkLCBlcnJvcj86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5kZWJ1Z0xvZ2dlcilcbiAgICAgICAgICAgIHRoaXMuZGVidWdMb2dnZXIuc2hvd0JyZWFrcG9pbnQodGhpcy5zZXNzaW9uLmlkLCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnVzZXJBZ2VudCwgY2FsbHNpdGUsIGVycm9yKTtcblxuICAgICAgICB0aGlzLmRlYnVnZ2luZyA9IGF3YWl0IHRoaXMuX2ludGVybmFsRXhlY3V0ZUNvbW1hbmQobmV3IHNlcnZpY2VDb21tYW5kcy5TZXRCcmVha3BvaW50Q29tbWFuZCghIWVycm9yLCAhIXRoaXMuY29tcGlsZXJTZXJ2aWNlKSwgY2FsbHNpdGUpIGFzIGJvb2xlYW47XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVtb3ZlQWxsTm9uU2VydmljZVRhc2tzICgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kcml2ZXJUYXNrUXVldWUgPSB0aGlzLmRyaXZlclRhc2tRdWV1ZS5maWx0ZXIoZHJpdmVyVGFzayA9PiBpc1NlcnZpY2VDb21tYW5kKGRyaXZlclRhc2suY29tbWFuZCkpO1xuXG4gICAgICAgIHRoaXMuYnJvd3Nlck1hbmlwdWxhdGlvblF1ZXVlLnJlbW92ZUFsbE5vblNlcnZpY2VNYW5pcHVsYXRpb25zKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaGFuZGxlRGVidWdTdGF0ZSAoZHJpdmVyU3RhdHVzOiBEcml2ZXJTdGF0dXMpOiB2b2lkIHtcbiAgICAgICAgaWYgKGRyaXZlclN0YXR1cy5kZWJ1ZylcbiAgICAgICAgICAgIHRoaXMuZW1pdChkcml2ZXJTdGF0dXMuZGVidWcpO1xuICAgIH1cblxuICAgIC8vIEN1cnJlbnQgZHJpdmVyIHRhc2tcbiAgICBwdWJsaWMgZ2V0IGN1cnJlbnREcml2ZXJUYXNrICgpOiBEcml2ZXJUYXNrIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZHJpdmVyVGFza1F1ZXVlWzBdO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Jlc29sdmVDdXJyZW50RHJpdmVyVGFzayAocmVzdWx0PzogdW5rbm93bik6IHZvaWQge1xuICAgICAgICB0aGlzLmN1cnJlbnREcml2ZXJUYXNrLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgdGhpcy5kcml2ZXJUYXNrUXVldWUuc2hpZnQoKTtcblxuICAgICAgICBpZiAodGhpcy50ZXN0RG9uZUNvbW1hbmRRdWV1ZWQpXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZWplY3RDdXJyZW50RHJpdmVyVGFzayAoZXJyOiBFcnJvcik6IHZvaWQge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGVyci5jYWxsc2l0ZSA9IGVyci5jYWxsc2l0ZSB8fCB0aGlzLmN1cnJlbnREcml2ZXJUYXNrLmNhbGxzaXRlO1xuXG4gICAgICAgIHRoaXMuY3VycmVudERyaXZlclRhc2sucmVqZWN0KGVycik7XG4gICAgICAgIHRoaXMuX3JlbW92ZUFsbE5vblNlcnZpY2VUYXNrcygpO1xuICAgIH1cblxuICAgIC8vIFBlbmRpbmcgcmVxdWVzdFxuICAgIHByaXZhdGUgX2NsZWFyUGVuZGluZ1JlcXVlc3QgKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nUmVxdWVzdCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGVuZGluZ1JlcXVlc3QucmVzcG9uc2VUaW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1JlcXVlc3QgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVzb2x2ZVBlbmRpbmdSZXF1ZXN0IChjb21tYW5kOiBDb21tYW5kQmFzZSB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sYXN0RHJpdmVyU3RhdHVzUmVzcG9uc2UgPSBjb21tYW5kO1xuXG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdSZXF1ZXN0KVxuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdC5yZXNvbHZlKGNvbW1hbmQpO1xuXG4gICAgICAgIHRoaXMuX2NsZWFyUGVuZGluZ1JlcXVlc3QoKTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgZHJpdmVyIHJlcXVlc3RcbiAgICBwcml2YXRlIF9zaG91bGRSZXNvbHZlQ3VycmVudERyaXZlclRhc2sgKGRyaXZlclN0YXR1czogRHJpdmVyU3RhdHVzKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDb21tYW5kID0gdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kO1xuXG4gICAgICAgIGNvbnN0IGlzRXhlY3V0aW5nT2JzZXJ2YXRpb25Db21tYW5kID0gY3VycmVudENvbW1hbmQgaW5zdGFuY2VvZiBvYnNlcnZhdGlvbkNvbW1hbmRzLkV4ZWN1dGVTZWxlY3RvckNvbW1hbmQgfHxcbiAgICAgICAgICAgIGN1cnJlbnRDb21tYW5kIGluc3RhbmNlb2YgRXhlY3V0ZUNsaWVudEZ1bmN0aW9uQ29tbWFuZDtcblxuICAgICAgICBjb25zdCBpc0RlYnVnQWN0aXZlID0gY3VycmVudENvbW1hbmQgaW5zdGFuY2VvZiBzZXJ2aWNlQ29tbWFuZHMuU2V0QnJlYWtwb2ludENvbW1hbmQ7XG5cbiAgICAgICAgY29uc3Qgc2hvdWxkRXhlY3V0ZUN1cnJlbnRDb21tYW5kID1cbiAgICAgICAgICAgIGRyaXZlclN0YXR1cy5pc0ZpcnN0UmVxdWVzdEFmdGVyV2luZG93U3dpdGNoaW5nICYmIChpc0V4ZWN1dGluZ09ic2VydmF0aW9uQ29tbWFuZCB8fCBpc0RlYnVnQWN0aXZlKTtcblxuICAgICAgICByZXR1cm4gIXNob3VsZEV4ZWN1dGVDdXJyZW50Q29tbWFuZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9mdWxmaWxsQ3VycmVudERyaXZlclRhc2sgKGRyaXZlclN0YXR1czogRHJpdmVyU3RhdHVzKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5jdXJyZW50RHJpdmVyVGFzaylcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBpZiAoZHJpdmVyU3RhdHVzLndhcm5pbmdzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRyaXZlclN0YXR1cy53YXJuaW5ncy5mb3JFYWNoKCh3YXJuaW5nOiBEcml2ZXJXYXJuaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgYWRkUmVuZGVyZWRXYXJuaW5nKHRoaXMud2FybmluZ0xvZywgV0FSTklOR19NRVNTQUdFW3dhcm5pbmcudHlwZV0sIHRoaXMuY3VycmVudERyaXZlclRhc2suY2FsbHNpdGUsIC4uLndhcm5pbmcuYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkcml2ZXJTdGF0dXMuZXhlY3V0aW9uRXJyb3IpXG4gICAgICAgICAgICB0aGlzLl9yZWplY3RDdXJyZW50RHJpdmVyVGFzayhkcml2ZXJTdGF0dXMuZXhlY3V0aW9uRXJyb3IpO1xuICAgICAgICBlbHNlIGlmICh0aGlzLl9zaG91bGRSZXNvbHZlQ3VycmVudERyaXZlclRhc2soZHJpdmVyU3RhdHVzKSlcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVDdXJyZW50RHJpdmVyVGFzayhkcml2ZXJTdGF0dXMucmVzdWx0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9oYW5kbGVQYWdlRXJyb3JTdGF0dXMgKHBhZ2VFcnJvcjogRXJyb3IpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudERyaXZlclRhc2sgJiYgaXNDb21tYW5kUmVqZWN0YWJsZUJ5UGFnZUVycm9yKHRoaXMuY3VycmVudERyaXZlclRhc2suY29tbWFuZCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdEN1cnJlbnREcml2ZXJUYXNrKHBhZ2VFcnJvcik7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgPSBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucGVuZGluZ1BhZ2VFcnJvciA9IHRoaXMucGVuZGluZ1BhZ2VFcnJvciB8fCBwYWdlRXJyb3I7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2hhbmRsZURyaXZlclJlcXVlc3QgKGRyaXZlclN0YXR1czogRHJpdmVyU3RhdHVzKTogUHJvbWlzZTxDb21tYW5kQmFzZSB8IG51bGwgfCBzdHJpbmc+IHtcbiAgICAgICAgY29uc3QgaXNUZXN0RG9uZSAgICAgICAgICAgICAgICAgPSB0aGlzLmN1cnJlbnREcml2ZXJUYXNrICYmIHRoaXMuY3VycmVudERyaXZlclRhc2suY29tbWFuZC50eXBlID09PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTU1BTkRfVFlQRS50ZXN0RG9uZTtcbiAgICAgICAgY29uc3QgcGFnZUVycm9yICAgICAgICAgICAgICAgICAgPSB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgfHwgZHJpdmVyU3RhdHVzLnBhZ2VFcnJvcjtcbiAgICAgICAgY29uc3QgY3VycmVudFRhc2tSZWplY3RlZEJ5RXJyb3IgPSBwYWdlRXJyb3IgJiYgdGhpcy5faGFuZGxlUGFnZUVycm9yU3RhdHVzKHBhZ2VFcnJvcik7XG5cbiAgICAgICAgdGhpcy5jb25zb2xlTWVzc2FnZXMuY29uY2F0KGRyaXZlclN0YXR1cy5jb25zb2xlTWVzc2FnZXMpO1xuXG4gICAgICAgIHRoaXMuX2hhbmRsZURlYnVnU3RhdGUoZHJpdmVyU3RhdHVzKTtcblxuICAgICAgICBpZiAoIWN1cnJlbnRUYXNrUmVqZWN0ZWRCeUVycm9yICYmIGRyaXZlclN0YXR1cy5pc0NvbW1hbmRSZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChpc1Rlc3REb25lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUN1cnJlbnREcml2ZXJUYXNrKCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gVEVTVF9ET05FX0NPTkZJUk1BVElPTl9SRVNQT05TRTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fZnVsZmlsbEN1cnJlbnREcml2ZXJUYXNrKGRyaXZlclN0YXR1cyk7XG5cbiAgICAgICAgICAgIGlmIChkcml2ZXJTdGF0dXMuaXNQZW5kaW5nV2luZG93U3dpdGNoaW5nKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnJlbnREcml2ZXJUYXNrQ29tbWFuZCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2dldEN1cnJlbnREcml2ZXJUYXNrQ29tbWFuZCAoKTogUHJvbWlzZTxDb21tYW5kQmFzZSB8IG51bGw+IHtcbiAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnREcml2ZXJUYXNrKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgY29tbWFuZCA9IHRoaXMuY3VycmVudERyaXZlclRhc2suY29tbWFuZDtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUubmF2aWdhdGVUbyAmJiAoY29tbWFuZCBhcyBhbnkpLnN0YXRlU25hcHNob3QpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9yb2xlUHJvdmlkZXIudXNlU3RhdGVTbmFwc2hvdChKU09OLnBhcnNlKChjb21tYW5kIGFzIGFueSkuc3RhdGVTbmFwc2hvdCkpO1xuXG4gICAgICAgIHJldHVybiBjb21tYW5kO1xuICAgIH1cblxuICAgIC8vIEV4ZWN1dGUgY29tbWFuZFxuICAgIHByaXZhdGUgYXN5bmMgX2V4ZWN1dGVKc0V4cHJlc3Npb24gKGNvbW1hbmQ6IEV4ZWN1dGVFeHByZXNzaW9uQ29tbWFuZCk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICBjb25zdCByZXN1bHRWYXJpYWJsZU5hbWUgPSBjb21tYW5kLnJlc3VsdFZhcmlhYmxlTmFtZTtcbiAgICAgICAgbGV0IGV4cHJlc3Npb24gICAgICAgICAgID0gY29tbWFuZC5leHByZXNzaW9uO1xuXG4gICAgICAgIGlmIChyZXN1bHRWYXJpYWJsZU5hbWUpXG4gICAgICAgICAgICBleHByZXNzaW9uID0gYCR7cmVzdWx0VmFyaWFibGVOYW1lfSA9ICR7ZXhwcmVzc2lvbn0sICR7cmVzdWx0VmFyaWFibGVOYW1lfWA7XG5cbiAgICAgICAgaWYgKHRoaXMuY29tcGlsZXJTZXJ2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlclNlcnZpY2UuZXhlY3V0ZUpzRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbixcbiAgICAgICAgICAgICAgICB0ZXN0UnVuSWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogICB7IHNraXBWaXNpYmlsaXR5Q2hlY2s6IGZhbHNlIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBleGVjdXRlSnNFeHByZXNzaW9uKGV4cHJlc3Npb24sIHRoaXMsIHsgc2tpcFZpc2liaWxpdHlDaGVjazogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfZXhlY3V0ZUFzeW5jSnNFeHByZXNzaW9uIChjb21tYW5kOiBFeGVjdXRlQXN5bmNFeHByZXNzaW9uQ29tbWFuZCwgY2FsbHNpdGU/OiBzdHJpbmcpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgaWYgKHRoaXMuY29tcGlsZXJTZXJ2aWNlKSB7XG4gICAgICAgICAgICB0aGlzLmFzeW5jSnNFeHByZXNzaW9uQ2FsbHNpdGVzLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVyU2VydmljZS5leGVjdXRlQXN5bmNKc0V4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGNvbW1hbmQuZXhwcmVzc2lvbixcbiAgICAgICAgICAgICAgICB0ZXN0UnVuSWQ6ICB0aGlzLmlkLFxuICAgICAgICAgICAgICAgIGNhbGxzaXRlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXhlY3V0ZUFzeW5jSnNFeHByZXNzaW9uKGNvbW1hbmQuZXhwcmVzc2lvbiwgdGhpcywgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3JlZGlyZWN0UmVFeGVjdXRhYmxlUHJvbWlzZUV4ZWN1dGlvblRvQ29tcGlsZXJTZXJ2aWNlIChjb21tYW5kOiBBc3NlcnRpb25Db21tYW5kKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5jb21waWxlclNlcnZpY2UpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgY29tbWFuZC5hY3R1YWwgPSBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5jb21waWxlclNlcnZpY2U/LmdldEFzc2VydGlvbkFjdHVhbFZhbHVlKHtcbiAgICAgICAgICAgICAgICB0ZXN0UnVuSWQ6IHNlbGYuaWQsXG4gICAgICAgICAgICAgICAgY29tbWFuZElkOiBjb21tYW5kLmlkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3JlZGlyZWN0QXNzZXJ0aW9uRm5FeGVjdXRpb25Ub0NvbXBpbGVyU2VydmljZSAoZXhlY3V0b3I6IEFzc2VydGlvbkV4ZWN1dG9yKTogdm9pZCB7XG4gICAgICAgIGV4ZWN1dG9yLmZuID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZXJTZXJ2aWNlPy5leGVjdXRlQXNzZXJ0aW9uRm4oe1xuICAgICAgICAgICAgICAgIHRlc3RSdW5JZDogdGhpcy5pZCxcbiAgICAgICAgICAgICAgICBjb21tYW5kSWQ6IGV4ZWN1dG9yLmNvbW1hbmQuaWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9leGVjdXRlQXNzZXJ0aW9uIChjb21tYW5kOiBBc3NlcnRpb25Db21tYW5kLCBjYWxsc2l0ZTogQ2FsbHNpdGVSZWNvcmQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKGNvbW1hbmQuYWN0dWFsID09PSBTeW1ib2wuZm9yKFJFX0VYRUNVVEFCTEVfUFJPTUlTRV9NQVJLRVJfREVTQ1JJUFRJT04pKVxuICAgICAgICAgICAgdGhpcy5fcmVkaXJlY3RSZUV4ZWN1dGFibGVQcm9taXNlRXhlY3V0aW9uVG9Db21waWxlclNlcnZpY2UoY29tbWFuZCk7XG5cbiAgICAgICAgY29uc3QgYXNzZXJ0aW9uVGltZW91dCA9IGdldEFzc2VydGlvblRpbWVvdXQoY29tbWFuZCwgdGhpcy5vcHRzKTtcbiAgICAgICAgY29uc3QgZXhlY3V0b3IgICAgICAgICA9IG5ldyBBc3NlcnRpb25FeGVjdXRvcihjb21tYW5kLCBhc3NlcnRpb25UaW1lb3V0LCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgZXhlY3V0b3Iub25jZSgnc3RhcnQtYXNzZXJ0aW9uLXJldHJpZXMnLCAodGltZW91dDogbnVtYmVyKSA9PiB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKG5ldyBzZXJ2aWNlQ29tbWFuZHMuU2hvd0Fzc2VydGlvblJldHJpZXNTdGF0dXNDb21tYW5kKHRpbWVvdXQpKSk7XG4gICAgICAgIGV4ZWN1dG9yLm9uY2UoJ2VuZC1hc3NlcnRpb24tcmV0cmllcycsIChzdWNjZXNzOiBib29sZWFuKSA9PiB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKG5ldyBzZXJ2aWNlQ29tbWFuZHMuSGlkZUFzc2VydGlvblJldHJpZXNTdGF0dXNDb21tYW5kKHN1Y2Nlc3MpKSk7XG4gICAgICAgIGV4ZWN1dG9yLm9uY2UoJ25vbi1zZXJpYWxpemFibGUtYWN0dWFsLXZhbHVlJywgdGhpcy5fcmVkaXJlY3RBc3NlcnRpb25GbkV4ZWN1dGlvblRvQ29tcGlsZXJTZXJ2aWNlKTtcblxuICAgICAgICBjb25zdCBleGVjdXRlRm4gPSB0aGlzLmRlY29yYXRlUHJldmVudEVtaXRBY3Rpb25FdmVudHMoKCkgPT4gZXhlY3V0b3IucnVuKCksIHsgcHJldmVudDogdHJ1ZSB9KTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgZXhlY3V0ZUZuKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfYWRqdXN0Q29uZmlndXJhdGlvbldpdGhDb21tYW5kIChjb21tYW5kOiBDb21tYW5kQmFzZSk6IHZvaWQge1xuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUudGVzdERvbmUpIHtcbiAgICAgICAgICAgIHRoaXMudGVzdERvbmVDb21tYW5kUXVldWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnTG9nZ2VyKVxuICAgICAgICAgICAgICAgIHRoaXMuZGVidWdMb2dnZXIuaGlkZUJyZWFrcG9pbnQodGhpcy5zZXNzaW9uLmlkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldE5hdGl2ZURpYWxvZ0hhbmRsZXIpXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZURpYWxvZ0hhbmRsZXIgPSAoY29tbWFuZCBhcyBhbnkpLmRpYWxvZ0hhbmRsZXI7XG5cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuc3dpdGNoVG9JZnJhbWUpXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZUlmcmFtZVNlbGVjdG9yID0gKGNvbW1hbmQgYXMgYW55KS5zZWxlY3RvcjtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5zd2l0Y2hUb01haW5XaW5kb3cpXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZUlmcmFtZVNlbGVjdG9yID0gbnVsbDtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5zZXRUZXN0U3BlZWQpXG4gICAgICAgICAgICB0aGlzLnNwZWVkID0gKGNvbW1hbmQgYXMgYW55KS5zcGVlZDtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5zZXRQYWdlTG9hZFRpbWVvdXQpXG4gICAgICAgICAgICB0aGlzLnBhZ2VMb2FkVGltZW91dCA9IChjb21tYW5kIGFzIGFueSkuZHVyYXRpb247XG5cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZGVidWcpXG4gICAgICAgICAgICB0aGlzLmRlYnVnZ2luZyA9IHRydWU7XG5cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZGlzYWJsZURlYnVnKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnTG9nZ2VyLmhpZGVCcmVha3BvaW50KHRoaXMuc2Vzc2lvbi5pZCk7XG5cbiAgICAgICAgICAgIHRoaXMuZGVidWdnaW5nID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2FkanVzdFNjcmVlbnNob3RDb21tYW5kIChjb21tYW5kOiBUYWtlU2NyZWVuc2hvdEJhc2VDb21tYW5kKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IGJyb3dzZXJJZCAgICAgICAgICAgICAgICAgICAgPSB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmlkO1xuICAgICAgICBjb25zdCB7IGhhc0Nocm9tZWxlc3NTY3JlZW5zaG90cyB9ID0gYXdhaXQgdGhpcy5icm93c2VyQ29ubmVjdGlvbi5wcm92aWRlci5oYXNDdXN0b21BY3Rpb25Gb3JCcm93c2VyKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgaWYgKCFoYXNDaHJvbWVsZXNzU2NyZWVuc2hvdHMpXG4gICAgICAgICAgICBjb21tYW5kLmdlbmVyYXRlU2NyZWVuc2hvdE1hcmsoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgX2FkanVzdENvbW1hbmRPcHRpb25zQW5kRW52aXJvbm1lbnQgKGNvbW1hbmQ6IENvbW1hbmRCYXNlLCBjYWxsc2l0ZTogQ2FsbHNpdGVSZWNvcmQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKChjb21tYW5kIGFzIGFueSkub3B0aW9ucz8uY29uZmlkZW50aWFsICE9PSB2b2lkIDApXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnR5cGVUZXh0KSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKChjb21tYW5kIGFzIGFueSkuc2VsZWN0b3IsIGNhbGxzaXRlKTtcblxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCBub2RlID0gdGhpcy5yZXBsaWNhdG9yLmRlY29kZShyZXN1bHQpO1xuXG4gICAgICAgICAgICAoY29tbWFuZCBhcyBhbnkpLm9wdGlvbnMuY29uZmlkZW50aWFsID0gaXNQYXNzd29yZElucHV0KG5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUucHJlc3NLZXkpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX2ludGVybmFsRXhlY3V0ZUNvbW1hbmQobmV3IHNlcnZpY2VDb21tYW5kcy5HZXRBY3RpdmVFbGVtZW50Q29tbWFuZCgpKTtcblxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCBub2RlID0gdGhpcy5yZXBsaWNhdG9yLmRlY29kZShyZXN1bHQpO1xuXG4gICAgICAgICAgICAoY29tbWFuZCBhcyBhbnkpLm9wdGlvbnMuY29uZmlkZW50aWFsID0gaXNQYXNzd29yZElucHV0KG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQgaW5zdGFuY2VvZiBFeGVjdXRlQ2xpZW50RnVuY3Rpb25Db21tYW5kQmFzZSAmJiAhIXRoaXMuY29tcGlsZXJTZXJ2aWNlICYmICF0aGlzLl9jbGllbnRFbnZpcm9ubWVudFByZXBhcmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9jbGllbnRFbnZpcm9ubWVudFByZXBhcmVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5faW50ZXJuYWxFeGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLlByZXBhcmVDbGllbnRFbnZpcm9ubWVudEluRGVidWdNb2RlKGNvbW1hbmQuZXNtUnVudGltZSkpO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgX3NldEJyZWFrcG9pbnRJZk5lY2Vzc2FyeSAoY29tbWFuZDogQ29tbWFuZEJhc2UsIGNhbGxzaXRlPzogQ2FsbHNpdGVSZWNvcmQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLmRpc2FibGVEZWJ1Z0JyZWFrcG9pbnRzICYmIHRoaXMuZGVidWdnaW5nICYmIGNhblNldERlYnVnZ2VyQnJlYWtwb2ludEJlZm9yZUNvbW1hbmQoY29tbWFuZCkpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbnF1ZXVlU2V0QnJlYWtwb2ludENvbW1hbmQoY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBleGVjdXRlQ29tbWFuZCAoY29tbWFuZDogQ29tbWFuZEJhc2UgfCBBY3Rpb25Db21tYW5kQmFzZSwgY2FsbHNpdGU/OiBzdHJpbmcgfCBDYWxsc2l0ZVJlY29yZCk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZCBpbnN0YW5jZW9mIEFjdGlvbkNvbW1hbmRCYXNlXG4gICAgICAgICAgICA/IHRoaXMuX2V4ZWN1dGVBY3Rpb25Db21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlIGFzIENhbGxzaXRlUmVjb3JkKVxuICAgICAgICAgICAgOiB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgX2V4ZWN1dGVBY3Rpb25Db21tYW5kIChjb21tYW5kOiBBY3Rpb25Db21tYW5kQmFzZSwgY2FsbHNpdGU6IENhbGxzaXRlUmVjb3JkKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkFyZ3MgPSB7IGFwaUFjdGlvbk5hbWU6IGNvbW1hbmQubWV0aG9kTmFtZSwgY29tbWFuZCB9O1xuXG4gICAgICAgIGxldCBlcnJvckFkYXB0ZXIgPSBudWxsO1xuICAgICAgICBsZXQgZXJyb3IgICAgICAgID0gbnVsbDtcbiAgICAgICAgbGV0IHJlc3VsdCAgICAgICA9IG51bGw7XG5cbiAgICAgICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fYWRqdXN0Q29tbWFuZE9wdGlvbnNBbmRFbnZpcm9ubWVudChjb21tYW5kLCBjYWxsc2l0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXRBY3Rpb25FdmVudCgnYWN0aW9uLXN0YXJ0JywgYWN0aW9uQXJncyk7XG5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFlcnJvcilcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5waGFzZSA9PT0gVGVzdFJ1blBoYXNlLnBlbmRpbmdGaW5hbGl6YXRpb24gJiYgZXJyIGluc3RhbmNlb2YgRXh0ZXJuYWxBc3NlcnRpb25MaWJyYXJ5RXJyb3IpXG4gICAgICAgICAgICAgICAgYWRkUmVuZGVyZWRXYXJuaW5nKHRoaXMud2FybmluZ0xvZywgeyBtZXNzYWdlOiBXQVJOSU5HX01FU1NBR0UudW5hd2FpdGVkTWV0aG9kV2l0aEFzc2VydGlvbiwgYWN0aW9uSWQ6IGNvbW1hbmQuYWN0aW9uSWQgfSwgY2FsbHNpdGUpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHN0YXJ0O1xuXG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgLy8gTk9URTogY2hlY2sgaWYgZXJyb3IgaXMgVGVzdENhZmVFcnJvckxpc3QgaXMgc3BlY2lmaWMgZm9yIHRoZSBgdXNlUm9sZWAgYWN0aW9uXG4gICAgICAgICAgICAvLyBpZiBlcnJvciBpcyBUZXN0Q2FmZUVycm9yTGlzdCB3ZSBkbyBub3QgbmVlZCB0byBjcmVhdGUgYW4gYWRhcHRlcixcbiAgICAgICAgICAgIC8vIHNpbmNlIGVycm9yIGlzIGFscmVhZHkgd2FzIHByb2Nlc3NlZCBpbiByb2xlIGluaXRpYWxpemVyXG4gICAgICAgICAgICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFRlc3RDYWZlRXJyb3JMaXN0KSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuX21ha2VTY3JlZW5zaG90T25GYWlsKGNvbW1hbmQuYWN0aW9uSWQpO1xuXG4gICAgICAgICAgICAgICAgZXJyb3JBZGFwdGVyID0gdGhpcy5fY3JlYXRlRXJyb3JBZGFwdGVyKHByb2Nlc3NUZXN0Rm5FcnJvcihlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGVycm9yQWRhcHRlciA9IGVycm9yLmFkYXB0ZXI7XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3QuYXNzaWduKGFjdGlvbkFyZ3MsIHtcbiAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgIGR1cmF0aW9uLFxuICAgICAgICAgICAgZXJyOiBlcnJvckFkYXB0ZXIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuZW1pdEFjdGlvbkV2ZW50KCdhY3Rpb24tZG9uZScsIGFjdGlvbkFyZ3MpO1xuXG4gICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIF9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kIChjb21tYW5kOiBDb21tYW5kQmFzZSwgY2FsbHNpdGU/OiBDYWxsc2l0ZVJlY29yZCB8IHN0cmluZyk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICB0aGlzLmRlYnVnTG9nLmNvbW1hbmQoY29tbWFuZCk7XG5cbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ1BhZ2VFcnJvciAmJiBpc0NvbW1hbmRSZWplY3RhYmxlQnlQYWdlRXJyb3IoY29tbWFuZCkpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVqZWN0Q29tbWFuZFdpdGhQYWdlRXJyb3IoY2FsbHNpdGUgYXMgQ2FsbHNpdGVSZWNvcmQpO1xuXG4gICAgICAgIGlmIChpc0V4ZWN1dGFibGVPbkNsaWVudENvbW1hbmQoY29tbWFuZCkpXG4gICAgICAgICAgICB0aGlzLmFkZGluZ0RyaXZlclRhc2tzQ291bnQrKztcblxuICAgICAgICB0aGlzLl9hZGp1c3RDb25maWd1cmF0aW9uV2l0aENvbW1hbmQoY29tbWFuZCk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2V0QnJlYWtwb2ludElmTmVjZXNzYXJ5KGNvbW1hbmQsIGNhbGxzaXRlIGFzIENhbGxzaXRlUmVjb3JkKTtcblxuICAgICAgICBpZiAoaXNTY3JlZW5zaG90Q29tbWFuZChjb21tYW5kKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kaXNhYmxlU2NyZWVuc2hvdHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyh7IG1lc3NhZ2U6IFdBUk5JTkdfTUVTU0FHRS5zY3JlZW5zaG90c0Rpc2FibGVkLCBhY3Rpb25JZDogY29tbWFuZC5hY3Rpb25JZCB9KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9hZGp1c3RTY3JlZW5zaG90Q29tbWFuZChjb21tYW5kIGFzIFRha2VTY3JlZW5zaG90QmFzZUNvbW1hbmQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmQoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIHRoaXMuYnJvd3Nlck1hbmlwdWxhdGlvblF1ZXVlLnB1c2goY29tbWFuZCk7XG5cbiAgICAgICAgICAgIGlmIChpc1Jlc2l6ZVdpbmRvd0NvbW1hbmQoY29tbWFuZCkgJiYgdGhpcy5vcHRzLnZpZGVvUGF0aClcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyh7IG1lc3NhZ2U6IFdBUk5JTkdfTUVTU0FHRS52aWRlb0Jyb3dzZXJSZXNpemluZywgYWN0aW9uSWQ6IGNvbW1hbmQuYWN0aW9uSWQgfSwgdGhpcy50ZXN0Lm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLndhaXQpXG4gICAgICAgICAgICByZXR1cm4gZGVsYXkoKGNvbW1hbmQgYXMgYW55KS50aW1lb3V0KTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuc2V0UGFnZUxvYWRUaW1lb3V0KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLmRlYnVnKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBJbiByZWd1bGFyIG1vZGUsIGl0J3MgcG9zc2libGUgdG8gZGVidWcgdGVzdHMgb25seSB1c2luZyBUZXN0Q2FmZSBVSSAoJ1Jlc3VtZScgYW5kICdOZXh0IHN0ZXAnIGJ1dHRvbnMpLlxuICAgICAgICAgICAgLy8gU28sIHdlIHNob3VsZCB3YXJuIG9uIHRyeWluZyB0byBkZWJ1ZyBpbiBoZWFkbGVzcyBtb2RlLlxuICAgICAgICAgICAgLy8gSW4gY29tcGlsZXIgc2VydmljZSBtb2RlLCB3ZSBjYW4gZGVidWcgZXZlbiBpbiBoZWFkbGVzcyBtb2RlIHVzaW5nIGFueSBkZWJ1Z2dpbmcgdG9vbHMuIFNvLCBpbiB0aGlzIGNhc2UsIHRoZSB3YXJuaW5nIGlzIGV4Y2Vzc2l2ZS5cbiAgICAgICAgICAgIGNvbnN0IGNhbkRlYnVnID0gISF0aGlzLmNvbXBpbGVyU2VydmljZSB8fCAhdGhpcy5icm93c2VyQ29ubmVjdGlvbi5pc0hlYWRsZXNzQnJvd3NlcigpO1xuXG4gICAgICAgICAgICBpZiAoY2FuRGVidWcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX2VucXVldWVTZXRCcmVha3BvaW50Q29tbWFuZChjYWxsc2l0ZSBhcyBDYWxsc2l0ZVJlY29yZCwgdm9pZCAwKTtcblxuICAgICAgICAgICAgdGhpcy5kZWJ1Z2dpbmcgPSBmYWxzZTtcblxuICAgICAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoeyBtZXNzYWdlOiBXQVJOSU5HX01FU1NBR0UuZGVidWdJbkhlYWRsZXNzRXJyb3IsIGFjdGlvbklkOiBjb21tYW5kLmFjdGlvbklkIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS51c2VSb2xlKSB7XG4gICAgICAgICAgICBsZXQgZm4gPSAoKTogUHJvbWlzZTx2b2lkPiA9PiB0aGlzLl91c2VSb2xlKChjb21tYW5kIGFzIGFueSkucm9sZSwgY2FsbHNpdGUgYXMgQ2FsbHNpdGVSZWNvcmQpO1xuXG4gICAgICAgICAgICBmbiA9IHRoaXMuZGVjb3JhdGVQcmV2ZW50RW1pdEFjdGlvbkV2ZW50cyhmbiwgeyBwcmV2ZW50OiB0cnVlIH0pO1xuICAgICAgICAgICAgZm4gPSB0aGlzLmRlY29yYXRlRGlzYWJsZURlYnVnQnJlYWtwb2ludHMoZm4sIHsgZGlzYWJsZTogdHJ1ZSB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUucnVuQ3VzdG9tQWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCB7IGZuLCBhcmdzIH0gPSBjb21tYW5kIGFzIFJ1bkN1c3RvbUFjdGlvbkNvbW1hbmQ7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkRm4gICAgPSB3cmFwQ3VzdG9tQWN0aW9uKGZuKTtcblxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHdyYXBwZWRGbih0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5hc3NlcnRpb24pXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhlY3V0ZUFzc2VydGlvbihjb21tYW5kIGFzIEFzc2VydGlvbkNvbW1hbmQsIGNhbGxzaXRlIGFzIENhbGxzaXRlUmVjb3JkKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZXhlY3V0ZUV4cHJlc3Npb24pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZXhlY3V0ZUpzRXhwcmVzc2lvbihjb21tYW5kIGFzIEV4ZWN1dGVFeHByZXNzaW9uQ29tbWFuZCk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLmV4ZWN1dGVBc3luY0V4cHJlc3Npb24pXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhlY3V0ZUFzeW5jSnNFeHByZXNzaW9uKGNvbW1hbmQgYXMgRXhlY3V0ZUFzeW5jRXhwcmVzc2lvbkNvbW1hbmQsIGNhbGxzaXRlIGFzIHN0cmluZyk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLmdldEJyb3dzZXJDb25zb2xlTWVzc2FnZXMpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlIGFzIENhbGxzaXRlUmVjb3JkKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuc3dpdGNoVG9QcmV2aW91c1dpbmRvdylcbiAgICAgICAgICAgIChjb21tYW5kIGFzIGFueSkud2luZG93SWQgPSB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnByZXZpb3VzQWN0aXZlV2luZG93SWQ7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnN3aXRjaFRvV2luZG93QnlQcmVkaWNhdGUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3dpdGNoVG9XaW5kb3dCeVByZWRpY2F0ZShjb21tYW5kIGFzIFN3aXRjaFRvV2luZG93QnlQcmVkaWNhdGVDb21tYW5kKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZ2V0Q29va2llcylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlR2V0Q29va2llcyhjb21tYW5kIGFzIEdldENvb2tpZXNDb21tYW5kKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuc2V0Q29va2llcylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlU2V0Q29va2llcyhjb21tYW5kIGFzIFNldENvb2tpZXNDb21tYW5kKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZGVsZXRlQ29va2llcylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlRGVsZXRlQ29va2llcyhjb21tYW5kIGFzIERlbGV0ZUNvb2tpZXNDb21tYW5kKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuYWRkUmVxdWVzdEhvb2tzKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKChjb21tYW5kIGFzIEFkZFJlcXVlc3RIb29rc0NvbW1hbmQpLmhvb2tzLm1hcChob29rID0+IHRoaXMuX2FkZFJlcXVlc3RIb29rKGhvb2spKSk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnJlbW92ZVJlcXVlc3RIb29rcylcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbCgoY29tbWFuZCBhcyBSZW1vdmVSZXF1ZXN0SG9va3NDb21tYW5kKS5ob29rcy5tYXAoaG9vayA9PiB0aGlzLl9yZW1vdmVSZXF1ZXN0SG9vayhob29rKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZChjb21tYW5kLCBjYWxsc2l0ZSBhcyBDYWxsc2l0ZVJlY29yZCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVqZWN0Q29tbWFuZFdpdGhQYWdlRXJyb3IgKGNhbGxzaXRlPzogQ2FsbHNpdGVSZWNvcmQpOiBQcm9taXNlPEVycm9yPiB7XG4gICAgICAgIGNvbnN0IGVyciA9IHRoaXMucGVuZGluZ1BhZ2VFcnJvcjtcblxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGVyci5jYWxsc2l0ZSAgICAgICAgICA9IGNhbGxzaXRlO1xuICAgICAgICB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3NlbmRDbG9zZUNoaWxkV2luZG93T25GaWxlRG93bmxvYWRpbmdDb21tYW5kICgpOiBDb21tYW5kQmFzZSB7XG4gICAgICAgIHJldHVybiBuZXcgYWN0aW9uQ29tbWFuZHMuQ2xvc2VDaGlsZFdpbmRvd09uRmlsZURvd25sb2FkaW5nKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIF9tYWtlU2NyZWVuc2hvdE9uRmFpbCAoZmFpbGVkQWN0aW9uSWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgeyBzY3JlZW5zaG90cyB9ID0gdGhpcy5vcHRzO1xuXG4gICAgICAgIGlmICghdGhpcy5lcnJTY3JlZW5zaG90UGF0aCAmJiAoc2NyZWVuc2hvdHMgYXMgU2NyZWVuc2hvdE9wdGlvblZhbHVlKT8udGFrZU9uRmFpbHMpXG4gICAgICAgICAgICB0aGlzLmVyclNjcmVlbnNob3RQYXRoID0gYXdhaXQgdGhpcy5faW50ZXJuYWxFeGVjdXRlQ29tbWFuZChuZXcgYnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmRzLlRha2VTY3JlZW5zaG90T25GYWlsQ29tbWFuZCh7IGZhaWxlZEFjdGlvbklkIH0pKSBhcyBzdHJpbmc7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZGVjb3JhdGVXaXRoRmxhZyAoZm46IEZ1bmN0aW9uLCBmbGFnTmFtZTogc3RyaW5nLCB2YWx1ZTogYm9vbGVhbik6ICgpID0+IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgdGhpc1tmbGFnTmFtZV0gPSB2YWx1ZTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgZm4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICB0aGlzW2ZsYWdOYW1lXSA9ICF2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVjb3JhdGVQcmV2ZW50RW1pdEFjdGlvbkV2ZW50cyAoZm46IEZ1bmN0aW9uLCB7IHByZXZlbnQgfTogeyBwcmV2ZW50OiBib29sZWFuIH0pOiAoKSA9PiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29yYXRlV2l0aEZsYWcoZm4sICdwcmV2ZW50RW1pdEFjdGlvbkV2ZW50cycsIHByZXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWNvcmF0ZURpc2FibGVEZWJ1Z0JyZWFrcG9pbnRzIChmbjogRnVuY3Rpb24sIHsgZGlzYWJsZSB9OiB7IGRpc2FibGU6IGJvb2xlYW4gfSk6ICgpID0+IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb3JhdGVXaXRoRmxhZyhmbiwgJ2Rpc2FibGVEZWJ1Z0JyZWFrcG9pbnRzJywgZGlzYWJsZSk7XG4gICAgfVxuXG4gICAgLy8gUm9sZSBtYW5hZ2VtZW50XG4gICAgcHVibGljIGFzeW5jIGdldFN0YXRlU25hcHNob3QgKCk6IFByb21pc2U8U3RhdGVTbmFwc2hvdD4ge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGF3YWl0IHRoaXMuX3JvbGVQcm92aWRlci5nZXRTdGF0ZVNuYXBzaG90KCk7XG5cbiAgICAgICAgc3RhdGUuc3RvcmFnZXMgPSBhd2FpdCB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKG5ldyBzZXJ2aWNlQ29tbWFuZHMuQmFja3VwU3RvcmFnZXNDb21tYW5kKCkpIGFzIFN0b3JhZ2VzU25hcHNob3Q7XG5cbiAgICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2NsZWFuVXBDdHhzICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuY29tcGlsZXJTZXJ2aWNlKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbXBpbGVyU2VydmljZS5zZXRDdHgoe1xuICAgICAgICAgICAgICAgIHRlc3RSdW5JZDogdGhpcy5pZCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogICAgIE9iamVjdC5jcmVhdGUobnVsbCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29tcGlsZXJTZXJ2aWNlLnNldEZpeHR1cmVDdHgoe1xuICAgICAgICAgICAgICAgIHRlc3RSdW5JZDogdGhpcy5pZCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogICAgIE9iamVjdC5jcmVhdGUobnVsbCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY3R4ICAgICAgICA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgICB0aGlzLmZpeHR1cmVDdHggPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgICAgdGhpcy50ZXN0UnVuQ3R4ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzd2l0Y2hUb0NsZWFuUnVuICh1cmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLl9jbGVhblVwQ3R4cygpO1xuXG4gICAgICAgIHRoaXMuY29uc29sZU1lc3NhZ2VzID0gbmV3IEJyb3dzZXJDb25zb2xlTWVzc2FnZXMoKTtcblxuICAgICAgICBhd2FpdCB0aGlzLl9yb2xlUHJvdmlkZXIudXNlU3RhdGVTbmFwc2hvdChTdGF0ZVNuYXBzaG90LmVtcHR5KCkpO1xuXG4gICAgICAgIGlmICh0aGlzLnNwZWVkICE9PSB0aGlzLm9wdHMuc3BlZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHNldFNwZWVkQ29tbWFuZCA9IG5ldyBhY3Rpb25Db21tYW5kcy5TZXRUZXN0U3BlZWRDb21tYW5kKHsgc3BlZWQ6IHRoaXMub3B0cy5zcGVlZCB9KTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5faW50ZXJuYWxFeGVjdXRlQ29tbWFuZChzZXRTcGVlZENvbW1hbmQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucGFnZUxvYWRUaW1lb3V0ICE9PSB0aGlzLm9wdHMucGFnZUxvYWRUaW1lb3V0KSB7XG4gICAgICAgICAgICBjb25zdCBzZXRQYWdlTG9hZFRpbWVvdXRDb21tYW5kID0gbmV3IGFjdGlvbkNvbW1hbmRzLlNldFBhZ2VMb2FkVGltZW91dENvbW1hbmQoeyBkdXJhdGlvbjogdGhpcy5vcHRzLnBhZ2VMb2FkVGltZW91dCB9KTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5faW50ZXJuYWxFeGVjdXRlQ29tbWFuZChzZXRQYWdlTG9hZFRpbWVvdXRDb21tYW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMubmF2aWdhdGVUb1VybCh1cmwsIHRydWUpO1xuXG4gICAgICAgIGlmICh0aGlzLmFjdGl2ZURpYWxvZ0hhbmRsZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZURpYWxvZ0hhbmRsZXJDb21tYW5kID0gbmV3IGFjdGlvbkNvbW1hbmRzLlNldE5hdGl2ZURpYWxvZ0hhbmRsZXJDb21tYW5kKHsgZGlhbG9nSGFuZGxlcjogeyBmbjogbnVsbCB9IH0pO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKHJlbW92ZURpYWxvZ0hhbmRsZXJDb21tYW5kKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBuYXZpZ2F0ZVRvVXJsICh1cmw6IHN0cmluZywgZm9yY2VSZWxvYWQ6IGJvb2xlYW4sIHN0YXRlU25hcHNob3Q/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgbmF2aWdhdGVDb21tYW5kID0gbmV3IGFjdGlvbkNvbW1hbmRzLk5hdmlnYXRlVG9Db21tYW5kKHsgdXJsLCBmb3JjZVJlbG9hZCwgc3RhdGVTbmFwc2hvdCB9KTtcblxuICAgICAgICBhd2FpdCB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKG5hdmlnYXRlQ29tbWFuZCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfZ2V0U3RhdGVTbmFwc2hvdEZyb21Sb2xlIChyb2xlOiBSb2xlKTogUHJvbWlzZTxTdGF0ZVNuYXBzaG90PiB7XG4gICAgICAgIGNvbnN0IHByZXZQaGFzZSA9IHRoaXMucGhhc2U7XG5cbiAgICAgICAgaWYgKHJvbGUucGhhc2UgPT09IFJPTEVfUEhBU0UuaW5pdGlhbGl6ZWQgJiYgcm9sZS5pbml0RXJyIGluc3RhbmNlb2YgVGVzdENhZmVFcnJvckxpc3QgJiYgcm9sZS5pbml0RXJyLmhhc0Vycm9ycylcbiAgICAgICAgICAgIHJvbGUuaW5pdEVyci5hZGFwdGVyID0gdGhpcy5fY3JlYXRlRXJyb3JBZGFwdGVyKHJvbGUuaW5pdEVyci5pdGVtc1swXSk7XG5cbiAgICAgICAgdGhpcy5waGFzZSA9IFRlc3RSdW5QaGFzZS5pblJvbGVJbml0aWFsaXplcjtcblxuICAgICAgICBpZiAocm9sZS5waGFzZSA9PT0gUk9MRV9QSEFTRS51bmluaXRpYWxpemVkKVxuICAgICAgICAgICAgYXdhaXQgcm9sZS5pbml0aWFsaXplKHRoaXMpO1xuXG4gICAgICAgIGVsc2UgaWYgKHJvbGUucGhhc2UgPT09IFJPTEVfUEhBU0UucGVuZGluZ0luaXRpYWxpemF0aW9uKVxuICAgICAgICAgICAgYXdhaXQgcHJvbWlzaWZ5RXZlbnQocm9sZSwgJ2luaXRpYWxpemVkJyk7XG5cbiAgICAgICAgaWYgKHJvbGUuaW5pdEVycilcbiAgICAgICAgICAgIHRocm93IHJvbGUuaW5pdEVycjtcblxuICAgICAgICB0aGlzLnBoYXNlID0gcHJldlBoYXNlO1xuXG4gICAgICAgIHJldHVybiByb2xlLnN0YXRlU25hcHNob3Q7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfdXNlUm9sZSAocm9sZTogUm9sZSwgY2FsbHNpdGU6IENhbGxzaXRlUmVjb3JkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLnBoYXNlID09PSBUZXN0UnVuUGhhc2UuaW5Sb2xlSW5pdGlhbGl6ZXIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUm9sZVN3aXRjaEluUm9sZUluaXRpYWxpemVyRXJyb3IoY2FsbHNpdGUpO1xuXG4gICAgICAgIGNvbnN0IGJvb2ttYXJrID0gbmV3IFRlc3RSdW5Cb29rbWFyayh0aGlzLCByb2xlKTtcblxuICAgICAgICBhd2FpdCBib29rbWFyay5pbml0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFJvbGVJZClcbiAgICAgICAgICAgIHRoaXMudXNlZFJvbGVTdGF0ZXNbdGhpcy5jdXJyZW50Um9sZUlkXSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGVTbmFwc2hvdCgpO1xuXG4gICAgICAgIGNvbnN0IHN0YXRlU25hcHNob3QgPSB0aGlzLnVzZWRSb2xlU3RhdGVzW3JvbGUuaWRdIHx8IGF3YWl0IHRoaXMuX2dldFN0YXRlU25hcHNob3RGcm9tUm9sZShyb2xlKTtcblxuICAgICAgICBhd2FpdCB0aGlzLl9yb2xlUHJvdmlkZXIudXNlU3RhdGVTbmFwc2hvdChzdGF0ZVNuYXBzaG90KTtcblxuICAgICAgICB0aGlzLmN1cnJlbnRSb2xlSWQgPSByb2xlLmlkO1xuXG4gICAgICAgIGF3YWl0IGJvb2ttYXJrLnJlc3RvcmUoY2FsbHNpdGUsIHN0YXRlU25hcHNob3QpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRDdXJyZW50VXJsICgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gbmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gd2luZG93LmxvY2F0aW9uLmhyZWY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiAgICAgICAgfSwgeyBib3VuZFRlc3RSdW46IHRoaXMgfSk7XG5cbiAgICAgICAgY29uc3QgZ2V0TG9jYXRpb24gPSBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IGdldExvY2F0aW9uKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfc3dpdGNoVG9XaW5kb3dCeVByZWRpY2F0ZSAoY29tbWFuZDogU3dpdGNoVG9XaW5kb3dCeVByZWRpY2F0ZUNvbW1hbmQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgY3VycmVudFdpbmRvd3MgPSBhd2FpdCB0aGlzLl9pbnRlcm5hbEV4ZWN1dGVDb21tYW5kKG5ldyBHZXRDdXJyZW50V2luZG93c0NvbW1hbmQoe30sIHRoaXMpIGFzIENvbW1hbmRCYXNlKSBhcyBPcGVuZWRXaW5kb3dJbmZvcm1hdGlvbltdO1xuXG4gICAgICAgIGNvbnN0IHdpbmRvd3MgPSBhd2FpdCBhc3luY0ZpbHRlcjxPcGVuZWRXaW5kb3dJbmZvcm1hdGlvbj4oY3VycmVudFdpbmRvd3MsIGFzeW5jIHduZCA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByZWRpY2F0ZURhdGEgPSB7XG4gICAgICAgICAgICAgICAgICAgIHVybDogICBuZXcgVVJMKHduZC51cmwpLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogd25kLnRpdGxlLFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb21waWxlclNlcnZpY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tcGlsZXJTZXJ2aWNlUHJlZGljYXRlRGF0YSA9IE9iamVjdC5hc3NpZ24ocHJlZGljYXRlRGF0YSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVzdFJ1bklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZElkOiBjb21tYW5kLmlkLFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlclNlcnZpY2UuY2hlY2tXaW5kb3coY29tcGlsZXJTZXJ2aWNlUHJlZGljYXRlRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbW1hbmQuY2hlY2tXaW5kb3cocHJlZGljYXRlRGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN3aXRjaFRvV2luZG93UHJlZGljYXRlRXJyb3IoZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCF3aW5kb3dzLmxlbmd0aClcbiAgICAgICAgICAgIHRocm93IG5ldyBXaW5kb3dOb3RGb3VuZEVycm9yKCk7XG5cbiAgICAgICAgaWYgKHdpbmRvd3MubGVuZ3RoID4gMSlcbiAgICAgICAgICAgIHRoaXMud2FybmluZ0xvZy5hZGRXYXJuaW5nKHsgbWVzc2FnZTogV0FSTklOR19NRVNTQUdFLm11bHRpcGxlV2luZG93c0ZvdW5kQnlQcmVkaWNhdGUsIGFjdGlvbklkOiBjb21tYW5kLmFjdGlvbklkIH0pO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX2ludGVybmFsRXhlY3V0ZUNvbW1hbmQobmV3IFN3aXRjaFRvV2luZG93Q29tbWFuZCh7IHdpbmRvd0lkOiB3aW5kb3dzWzBdLmlkIH0sIHRoaXMpIGFzIENvbW1hbmRCYXNlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9kaXNjb25uZWN0IChlcnI6IEVycm9yKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50RHJpdmVyVGFzaylcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdEN1cnJlbnREcml2ZXJUYXNrKGVycik7XG5cbiAgICAgICAgdGhpcy5lbWl0KCdkaXNjb25uZWN0ZWQnLCBlcnIpO1xuXG4gICAgICAgIHRlc3RSdW5UcmFja2VyLnJlbW92ZUFjdGl2ZVRlc3RSdW4odGhpcy5zZXNzaW9uLmlkKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9oYW5kbGVGaWxlRG93bmxvYWRpbmdJbk5ld1dpbmRvd1JlcXVlc3QgKCk6IENvbW1hbmRCYXNlIHwgbnVsbCB7XG4gICAgICAgIGlmICh0aGlzLmF0dGFjaG1lbnREb3dubG9hZGluZ0hhbmRsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudERvd25sb2FkaW5nSGFuZGxlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2VuZENsb3NlQ2hpbGRXaW5kb3dPbkZpbGVEb3dubG9hZGluZ0NvbW1hbmQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBlbWl0QWN0aW9uRXZlbnQgKGV2ZW50TmFtZTogc3RyaW5nLCBhcmdzOiB1bmtub3duKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgaWYgKCF0aGlzLnByZXZlbnRFbWl0QWN0aW9uRXZlbnRzKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KGV2ZW50TmFtZSwgYXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBpc011bHRpcGxlV2luZG93c0FsbG93ZWQgKHRlc3RSdW46IFRlc3RSdW4pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgeyBkaXNhYmxlTXVsdGlwbGVXaW5kb3dzLCB0ZXN0IH0gPSB0ZXN0UnVuO1xuXG4gICAgICAgIHJldHVybiAhZGlzYWJsZU11bHRpcGxlV2luZG93cyAmJiAhKHRlc3QgYXMgTGVnYWN5VGVzdFJ1bikuaXNMZWdhY3kgJiYgISF0ZXN0UnVuLmFjdGl2ZVdpbmRvd0lkO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBpbml0aWFsaXplICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5fY2xlYXJDb29raWVzQW5kU3RvcmFnZXMoKTtcblxuICAgICAgICBhd2FpdCB0aGlzLl9pbml0UmVxdWVzdEhvb2tzKCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmNvbXBpbGVyU2VydmljZSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBhd2FpdCB0aGlzLmNvbXBpbGVyU2VydmljZS5pbml0aWFsaXplVGVzdFJ1bkRhdGEoe1xuICAgICAgICAgICAgdGVzdFJ1bklkOiAgICAgIHRoaXMuaWQsXG4gICAgICAgICAgICB0ZXN0SWQ6ICAgICAgICAgdGhpcy50ZXN0LmlkLFxuICAgICAgICAgICAgYnJvd3NlcjogICAgICAgIHRoaXMuYnJvd3NlcixcbiAgICAgICAgICAgIGFjdGl2ZVdpbmRvd0lkOiB0aGlzLmFjdGl2ZVdpbmRvd0lkLFxuICAgICAgICAgICAgbWVzc2FnZUJ1czogICAgIHRoaXMuX21lc3NhZ2VCdXMsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2NsZWFyQ29va2llc0FuZFN0b3JhZ2VzICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZVBhZ2VSZWxvYWRzKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX2Nvb2tpZVByb3ZpZGVyLmluaXRpYWxpemUoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5fc3RvcmFnZXNQcm92aWRlci5pbml0aWFsaXplKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhY3RpdmVXaW5kb3dJZCAoKTogbnVsbCB8IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmFjdGl2ZVdpbmRvd0lkO1xuICAgIH1cblxuICAgIC8vIE5PVEU6IHRoaXMgZnVuY3Rpb24gaXMgdGltZS1jcml0aWNhbCBhbmQgbXVzdCByZXR1cm4gQVNBUCB0byBhdm9pZCBjbGllbnQgZGlzY29ubmVjdGlvblxuICAgIHByaXZhdGUgYXN5bmMgW0NMSUVOVF9NRVNTQUdFUy5yZWFkeV0gKG1zZzogRHJpdmVyTWVzc2FnZSk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICBpZiAobXNnLnN0YXR1cy5pc09ic2VydmluZ0ZpbGVEb3dubG9hZGluZ0luTmV3V2luZG93KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUZpbGVEb3dubG9hZGluZ0luTmV3V2luZG93UmVxdWVzdCgpO1xuXG4gICAgICAgIHRoaXMuZGVidWdMb2cuZHJpdmVyTWVzc2FnZShtc2cpO1xuXG4gICAgICAgIGlmICh0aGlzLmRpc2Nvbm5lY3RlZClcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgR2VuZXJhbEVycm9yKFJVTlRJTUVfRVJST1JTLnRlc3RSdW5SZXF1ZXN0SW5EaXNjb25uZWN0ZWRCcm93c2VyLCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmJyb3dzZXJJbmZvLmFsaWFzKSk7XG5cbiAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0ZWQnKTtcblxuICAgICAgICB0aGlzLl9jbGVhclBlbmRpbmdSZXF1ZXN0KCk7XG5cbiAgICAgICAgLy8gTk9URTogdGhlIGRyaXZlciBzZW5kcyB0aGUgc3RhdHVzIGZvciB0aGUgc2Vjb25kIHRpbWUgaWYgaXQgZGlkbid0IGdldCBhIHJlc3BvbnNlIGF0IHRoZVxuICAgICAgICAvLyBmaXJzdCB0cnkuIFRoaXMgaXMgcG9zc2libGUgd2hlbiB0aGUgcGFnZSB3YXMgdW5sb2FkZWQgYWZ0ZXIgdGhlIGRyaXZlciBzZW50IHRoZSBzdGF0dXMuXG4gICAgICAgIGlmIChtc2cuc3RhdHVzLmlkID09PSB0aGlzLmxhc3REcml2ZXJTdGF0dXNJZClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZTtcblxuICAgICAgICB0aGlzLmxhc3REcml2ZXJTdGF0dXNJZCAgICAgICA9IG1zZy5zdGF0dXMuaWQ7XG4gICAgICAgIHRoaXMubGFzdERyaXZlclN0YXR1c1Jlc3BvbnNlID0gYXdhaXQgdGhpcy5faGFuZGxlRHJpdmVyUmVxdWVzdChtc2cuc3RhdHVzKTtcblxuICAgICAgICBpZiAodGhpcy5sYXN0RHJpdmVyU3RhdHVzUmVzcG9uc2UgfHwgbXNnLnN0YXR1cy5pc1BlbmRpbmdXaW5kb3dTd2l0Y2hpbmcpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sYXN0RHJpdmVyU3RhdHVzUmVzcG9uc2U7XG5cbiAgICAgICAgLy8gTk9URTogd2Ugc2VuZCBhbiBlbXB0eSByZXNwb25zZSBhZnRlciB0aGUgTUFYX1JFU1BPTlNFX0RFTEFZIHRpbWVvdXQgaXMgZXhjZWVkZWQgdG8ga2VlcCBjb25uZWN0aW9uXG4gICAgICAgIC8vIHdpdGggdGhlIGNsaWVudCBhbmQgcHJldmVudCB0aGUgcmVzcG9uc2UgdGltZW91dCBleGNlcHRpb24gb24gdGhlIGNsaWVudCBzaWRlXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fcmVzb2x2ZVBlbmRpbmdSZXF1ZXN0KG51bGwpLCBNQVhfUkVTUE9OU0VfREVMQVkpO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdSZXF1ZXN0ID0geyByZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlVGltZW91dCB9O1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIFtDTElFTlRfTUVTU0FHRVMucmVhZHlGb3JCcm93c2VyTWFuaXB1bGF0aW9uXSAobXNnOiBEcml2ZXJNZXNzYWdlKTogUHJvbWlzZTxCcm93c2VyTWFuaXB1bGF0aW9uUmVzdWx0PiB7XG4gICAgICAgIHRoaXMuZGVidWdMb2cuZHJpdmVyTWVzc2FnZShtc2cpO1xuXG4gICAgICAgIGxldCByZXN1bHQgPSBudWxsO1xuICAgICAgICBsZXQgZXJyb3IgID0gbnVsbDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgdGhpcy5icm93c2VyTWFuaXB1bGF0aW9uUXVldWUuZXhlY3V0ZVBlbmRpbmdNYW5pcHVsYXRpb24obXNnLCB0aGlzLl9tZXNzYWdlQnVzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBlcnJvciA9IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogICAgICAgICAgICBlcnIubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogICAgICAgICBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgc3RhY2s6ICAgICAgICAgICBlcnIuc3RhY2ssXG4gICAgICAgICAgICAgICAgICAgIGlzSW50ZXJuYWxFcnJvcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHsgcmVzdWx0LCBlcnJvciB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgW0NMSUVOVF9NRVNTQUdFUy53YWl0Rm9yRmlsZURvd25sb2FkXSAobXNnOiBEcml2ZXJNZXNzYWdlKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHRoaXMuZGVidWdMb2cuZHJpdmVyTWVzc2FnZShtc2cpO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIl19