Innovenergy_trunk/frontend/node_modules/testcafe/lib/api/test-controller/index.js

461 lines
80 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// TODO: Fix https://github.com/DevExpress/testcafe/issues/4139 to get rid of Pinkie
const pinkie_1 = __importDefault(require("pinkie"));
const lodash_1 = require("lodash");
const get_callsite_1 = require("../../errors/get-callsite");
const client_function_builder_1 = __importDefault(require("../../client-functions/client-function-builder"));
const assertion_1 = __importDefault(require("./assertion"));
const delegated_api_1 = require("../../utils/delegated-api");
const add_rendered_warning_1 = __importDefault(require("../../notifications/add-rendered-warning"));
const deprecated_1 = require("../../notifications/deprecated");
const actions_1 = require("../../test-run/commands/actions");
const browser_manipulation_1 = require("../../test-run/commands/browser-manipulation");
const observation_1 = require("../../test-run/commands/observation");
const execution_context_1 = require("./execution-context");
const types_1 = require("../../client-functions/types");
const test_run_proxy_1 = __importDefault(require("../../services/compiler/test-run-proxy"));
const test_run_1 = require("../../errors/test-run");
const assertion_2 = require("../../test-run/commands/assertion");
const callsite_1 = require("../../utils/callsite");
const re_executable_promise_1 = __importDefault(require("../../utils/re-executable-promise"));
const send_1 = require("../../test-run/request/send");
const runtime_1 = require("../../errors/runtime");
const types_2 = require("../../errors/types");
const custom_actions_1 = __importDefault(require("./custom-actions"));
const delegated_api_2 = __importDefault(require("./delegated-api"));
const originalThen = pinkie_1.default.resolve().then;
let inDebug = false;
class TestController {
constructor(testRun) {
var _a;
this._executionContext = null;
this.testRun = testRun;
this.executionChain = pinkie_1.default.resolve();
this.warningLog = testRun.warningLog;
this._customActions = new custom_actions_1.default(this, (_a = testRun === null || testRun === void 0 ? void 0 : testRun.opts) === null || _a === void 0 ? void 0 : _a.customActions);
this._addTestControllerToExecutionChain();
}
_addTestControllerToExecutionChain() {
this.executionChain._testController = this;
}
// NOTE: TestCafe executes actions and assertions asynchronously in the following cases:
// a) The `await` keyword that proceeds the method declaration triggers the `then` function of a Promise.
// b) The action is chained to another `awaited` method.
//
// In order to track missing `await` statements, TestCafe exposes a special Promise to the user.
// When TestCafe detects a missing `await` statement, it compares the method's callsite to the call site of the exposed Promise.
// This workaround is necessary for situations like these:
//
// var t2 = t.click('#btn1'); // <-- stores new callsiteWithoutAwait
// await t2; // <-- callsiteWithoutAwait = null
// t.click('#btn2'); // <-- stores new callsiteWithoutAwait
// await t2.click('#btn3'); // <-- without check it will set callsiteWithoutAwait = null, so we will lost tracking
_createExtendedPromise(promise, callsite) {
const extendedPromise = promise.then(lodash_1.identity);
const observedCallsites = this.testRun.observedCallsites;
const markCallsiteAwaited = () => observedCallsites.callsitesWithoutAwait.delete(callsite);
extendedPromise.then = function () {
markCallsiteAwaited();
return originalThen.apply(this, arguments);
};
(0, delegated_api_1.delegateAPI)(extendedPromise, TestController.API_LIST, {
handler: this,
proxyMethod: markCallsiteAwaited,
});
return extendedPromise;
}
_createCommand(CmdCtor, cmdArgs, callsite) {
try {
return new CmdCtor(cmdArgs, this.testRun);
}
catch (err) {
err.callsite = callsite;
throw err;
}
}
_enqueueTask(apiMethodName, createTaskExecutor, callsite) {
const executor = createTaskExecutor();
this.executionChain.then = originalThen;
this.executionChain = this.executionChain.then(executor);
this.testRun.observedCallsites.callsitesWithoutAwait.add(callsite);
this.executionChain = this._createExtendedPromise(this.executionChain, callsite);
this._addTestControllerToExecutionChain();
return this.executionChain;
}
enqueueCommand(CmdCtor, cmdArgs, validateCommandFn, callsite) {
callsite = callsite || (0, get_callsite_1.getCallsiteForMethod)(CmdCtor.methodName);
const command = this._createCommand(CmdCtor, cmdArgs, callsite);
if (typeof validateCommandFn === 'function')
validateCommandFn(this, command, callsite);
return this._enqueueTask(command.methodName, () => {
return () => {
return this.testRun.executeCommand(command, callsite)
.catch(err => {
this.executionChain = pinkie_1.default.resolve();
throw err;
});
};
}, callsite);
}
_validateMultipleWindowCommand(apiMethodName) {
const { disableMultipleWindows, activeWindowId } = this.testRun;
if (disableMultipleWindows)
throw new test_run_1.MultipleWindowsModeIsDisabledError(apiMethodName);
if (!activeWindowId)
throw new test_run_1.MultipleWindowsModeIsNotAvailableInRemoteBrowserError(apiMethodName);
}
getExecutionContext() {
if (!this._executionContext)
this._executionContext = (0, execution_context_1.createExecutionContext)(this.testRun);
return this._executionContext;
}
// API implementation
// We need implementation methods to obtain correct callsites. If we use plain API
// methods in chained wrappers then we will have callsite for the wrapped method
// in this file instead of chained method callsite in user code.
_ctx$getter() {
return this.testRun.ctx;
}
_ctx$setter(val) {
this.testRun.ctx = val;
return this.testRun.ctx;
}
_fixtureCtx$getter() {
return this.testRun.fixtureCtx;
}
_browser$getter() {
return this.testRun.browser;
}
_customActions$getter() {
return this._customActions || new custom_actions_1.default(this, this.testRun.opts.customActions);
}
[(0, delegated_api_2.default)(actions_1.DispatchEventCommand.methodName)](selector, eventName, options = {}) {
return this.enqueueCommand(actions_1.DispatchEventCommand, { selector, eventName, options, relatedTarget: options.relatedTarget });
}
_prepareCookieArguments(args, isSetCommand = false) {
const urlsArg = (0, lodash_1.castArray)(args[1]);
const urls = Array.isArray(urlsArg) && typeof urlsArg[0] === 'string' ? urlsArg : [];
const cookiesArg = urls.length ? args[0] : args;
const cookies = [];
(0, lodash_1.flattenDeep)((0, lodash_1.castArray)(cookiesArg)).forEach(cookie => {
if (isSetCommand && !cookie.name && typeof cookie === 'object')
Object.entries(cookie).forEach(([name, value]) => cookies.push({ name, value }));
else if (!isSetCommand && typeof cookie === 'string')
cookies.push({ name: cookie });
else
cookies.push(cookie);
});
return { urls, cookies };
}
[(0, delegated_api_2.default)(actions_1.GetCookiesCommand.methodName)](...args) {
return this.enqueueCommand(actions_1.GetCookiesCommand, this._prepareCookieArguments(args));
}
[(0, delegated_api_2.default)(actions_1.SetCookiesCommand.methodName)](...args) {
const { urls, cookies } = this._prepareCookieArguments(args, true);
return this.enqueueCommand(actions_1.SetCookiesCommand, { cookies, url: urls[0] });
}
[(0, delegated_api_2.default)(actions_1.DeleteCookiesCommand.methodName)](...args) {
return this.enqueueCommand(actions_1.DeleteCookiesCommand, this._prepareCookieArguments(args));
}
_prepareRequestArguments(bindOptions, ...args) {
const [url, options] = typeof args[0] === 'object' ? [args[0].url, args[0]] : args;
return {
url,
options: Object.assign({}, options, bindOptions),
};
}
_createRequestFunction(bindOptions = {}) {
const controller = this;
const callsite = (0, get_callsite_1.getCallsiteForMethod)(actions_1.RequestCommand.methodName);
if (!controller.testRun || controller.testRun instanceof test_run_proxy_1.default)
throw new runtime_1.RequestRuntimeError(callsite, types_2.RUNTIME_ERRORS.requestCannotResolveTestRun);
return function (...args) {
const cmdArgs = controller._prepareRequestArguments(bindOptions, ...args);
const command = controller._createCommand(actions_1.RequestCommand, cmdArgs, callsite);
const options = Object.assign(Object.assign({}, command.options), { url: command.url || command.options.url || '' });
const promise = re_executable_promise_1.default.fromFn(async () => {
return (0, send_1.sendRequestThroughAPI)(controller.testRun, options, callsite);
});
actions_1.RequestCommand.resultGetters.forEach(getter => {
Object.defineProperty(promise, getter, {
get: () => re_executable_promise_1.default.fromFn(async () => {
const response = await (0, send_1.sendRequestThroughAPI)(controller.testRun, options, callsite);
return response[getter];
}),
});
});
return promise;
};
}
_decorateRequestFunction(fn) {
actions_1.RequestCommand.extendedMethods.forEach(method => {
Object.defineProperty(fn, method, {
value: this._createRequestFunction({ method }),
});
});
}
[(0, delegated_api_2.default)(actions_1.RequestCommand.methodName, 'getter')]() {
const fn = this._createRequestFunction();
this._decorateRequestFunction(fn);
return fn;
}
[(0, delegated_api_2.default)(actions_1.ClickCommand.methodName)](selector, options) {
return this.enqueueCommand(actions_1.ClickCommand, { selector, options });
}
[(0, delegated_api_2.default)(actions_1.RightClickCommand.methodName)](selector, options) {
return this.enqueueCommand(actions_1.RightClickCommand, { selector, options });
}
[(0, delegated_api_2.default)(actions_1.DoubleClickCommand.methodName)](selector, options) {
return this.enqueueCommand(actions_1.DoubleClickCommand, { selector, options });
}
[(0, delegated_api_2.default)(actions_1.HoverCommand.methodName)](selector, options) {
return this.enqueueCommand(actions_1.HoverCommand, { selector, options });
}
[(0, delegated_api_2.default)(actions_1.DragCommand.methodName)](selector, dragOffsetX, dragOffsetY, options) {
return this.enqueueCommand(actions_1.DragCommand, { selector, dragOffsetX, dragOffsetY, options });
}
[(0, delegated_api_2.default)(actions_1.DragToElementCommand.methodName)](selector, destinationSelector, options) {
return this.enqueueCommand(actions_1.DragToElementCommand, { selector, destinationSelector, options });
}
_getSelectorForScroll(args) {
const selector = typeof args[0] === 'string' || (0, types_1.isSelector)(args[0]) ? args[0] : null;
if (selector)
args.shift();
else
// NOTE: here we use document.scrollingElement for old Safari versions
// document.documentElement does not work as expected on Mojave Safari 12.1/ High Sierra Safari 11.1
// eslint-disable-next-line no-undef
return () => document.scrollingElement || document.documentElement;
return selector;
}
_getPosition(args) {
const position = args.length === 1 && typeof args[0] === 'string' ? args[0] : null;
if (position)
args.shift();
return position;
}
[(0, delegated_api_2.default)(actions_1.ScrollCommand.methodName)](...args) {
let position = this._getPosition(args);
const selector = this._getSelectorForScroll(args);
let x = void 0;
let y = void 0;
let options = void 0;
if (typeof args[0] === 'string')
[position, options] = args;
if (typeof args[0] === 'number')
[x, y, options] = args;
return this.enqueueCommand(actions_1.ScrollCommand, { selector, x, y, position, options });
}
[(0, delegated_api_2.default)(actions_1.ScrollByCommand.methodName)](...args) {
const selector = this._getSelectorForScroll(args);
const [byX, byY, options] = args;
return this.enqueueCommand(actions_1.ScrollByCommand, { selector, byX, byY, options });
}
[(0, delegated_api_2.default)(actions_1.ScrollIntoViewCommand.methodName)](selector, options) {
return this.enqueueCommand(actions_1.ScrollIntoViewCommand, { selector, options });
}
[(0, delegated_api_2.default)(actions_1.TypeTextCommand.methodName)](selector, text, options) {
return this.enqueueCommand(actions_1.TypeTextCommand, { selector, text, options });
}
[(0, delegated_api_2.default)(actions_1.SelectTextCommand.methodName)](selector, startPos, endPos, options) {
return this.enqueueCommand(actions_1.SelectTextCommand, { selector, startPos, endPos, options });
}
[(0, delegated_api_2.default)(actions_1.SelectTextAreaContentCommand.methodName)](selector, startLine, startPos, endLine, endPos, options) {
return this.enqueueCommand(actions_1.SelectTextAreaContentCommand, {
selector,
startLine,
startPos,
endLine,
endPos,
options,
});
}
[(0, delegated_api_2.default)(actions_1.SelectEditableContentCommand.methodName)](startSelector, endSelector, options) {
return this.enqueueCommand(actions_1.SelectEditableContentCommand, {
startSelector,
endSelector,
options,
});
}
[(0, delegated_api_2.default)(actions_1.PressKeyCommand.methodName)](keys, options) {
return this.enqueueCommand(actions_1.PressKeyCommand, { keys, options });
}
[(0, delegated_api_2.default)(observation_1.WaitCommand.methodName)](timeout) {
return this.enqueueCommand(observation_1.WaitCommand, { timeout });
}
[(0, delegated_api_2.default)(actions_1.NavigateToCommand.methodName)](url) {
return this.enqueueCommand(actions_1.NavigateToCommand, { url });
}
[(0, delegated_api_2.default)(actions_1.SetFilesToUploadCommand.methodName)](selector, filePath) {
return this.enqueueCommand(actions_1.SetFilesToUploadCommand, { selector, filePath });
}
[(0, delegated_api_2.default)(actions_1.ClearUploadCommand.methodName)](selector) {
return this.enqueueCommand(actions_1.ClearUploadCommand, { selector });
}
[(0, delegated_api_2.default)(browser_manipulation_1.TakeScreenshotCommand.methodName)](options) {
if (options && typeof options !== 'object')
options = { path: options };
return this.enqueueCommand(browser_manipulation_1.TakeScreenshotCommand, options);
}
[(0, delegated_api_2.default)(browser_manipulation_1.TakeElementScreenshotCommand.methodName)](selector, ...args) {
const commandArgs = { selector };
if (args[1]) {
commandArgs.path = args[0];
commandArgs.options = args[1];
}
else if (typeof args[0] === 'object')
commandArgs.options = args[0];
else
commandArgs.path = args[0];
return this.enqueueCommand(browser_manipulation_1.TakeElementScreenshotCommand, commandArgs);
}
[(0, delegated_api_2.default)(browser_manipulation_1.ResizeWindowCommand.methodName)](width, height) {
return this.enqueueCommand(browser_manipulation_1.ResizeWindowCommand, { width, height });
}
[(0, delegated_api_2.default)(browser_manipulation_1.ResizeWindowToFitDeviceCommand.methodName)](device, options) {
return this.enqueueCommand(browser_manipulation_1.ResizeWindowToFitDeviceCommand, { device, options });
}
[(0, delegated_api_2.default)(browser_manipulation_1.MaximizeWindowCommand.methodName)]() {
return this.enqueueCommand(browser_manipulation_1.MaximizeWindowCommand);
}
[(0, delegated_api_2.default)(actions_1.SwitchToIframeCommand.methodName)](selector) {
return this.enqueueCommand(actions_1.SwitchToIframeCommand, { selector });
}
[(0, delegated_api_2.default)(actions_1.SwitchToMainWindowCommand.methodName)]() {
return this.enqueueCommand(actions_1.SwitchToMainWindowCommand);
}
[(0, delegated_api_2.default)(actions_1.OpenWindowCommand.methodName)](url) {
this._validateMultipleWindowCommand(actions_1.OpenWindowCommand.methodName);
return this.enqueueCommand(actions_1.OpenWindowCommand, { url });
}
[(0, delegated_api_2.default)(actions_1.CloseWindowCommand.methodName)](window) {
const windowId = (window === null || window === void 0 ? void 0 : window.id) || null;
this._validateMultipleWindowCommand(actions_1.CloseWindowCommand.methodName);
return this.enqueueCommand(actions_1.CloseWindowCommand, { windowId });
}
[(0, delegated_api_2.default)(actions_1.GetCurrentWindowCommand.methodName)]() {
this._validateMultipleWindowCommand(actions_1.GetCurrentWindowCommand.methodName);
return this.enqueueCommand(actions_1.GetCurrentWindowCommand);
}
[(0, delegated_api_2.default)(actions_1.SwitchToWindowCommand.methodName)](windowSelector) {
this._validateMultipleWindowCommand(actions_1.SwitchToWindowCommand.methodName);
let command;
let args;
if (typeof windowSelector === 'function') {
command = actions_1.SwitchToWindowByPredicateCommand;
args = { checkWindow: windowSelector };
}
else {
command = actions_1.SwitchToWindowCommand;
args = { windowId: windowSelector === null || windowSelector === void 0 ? void 0 : windowSelector.id };
}
return this.enqueueCommand(command, args);
}
[(0, delegated_api_2.default)(actions_1.SwitchToParentWindowCommand.methodName)]() {
this._validateMultipleWindowCommand(actions_1.SwitchToParentWindowCommand.methodName);
return this.enqueueCommand(actions_1.SwitchToParentWindowCommand);
}
[(0, delegated_api_2.default)(actions_1.SwitchToPreviousWindowCommand.methodName)]() {
this._validateMultipleWindowCommand(actions_1.SwitchToPreviousWindowCommand.methodName);
return this.enqueueCommand(actions_1.SwitchToPreviousWindowCommand);
}
_eval$(fn, options) {
if (!(0, lodash_1.isNil)(options))
options = (0, lodash_1.assign)({}, options, { boundTestRun: this });
const builder = new client_function_builder_1.default(fn, options, { instantiation: 'eval', execution: 'eval' });
const clientFn = builder.getFunction();
return clientFn();
}
[(0, delegated_api_2.default)(actions_1.SetNativeDialogHandlerCommand.methodName)](fn, options) {
return this.enqueueCommand(actions_1.SetNativeDialogHandlerCommand, {
dialogHandler: { fn, options },
});
}
[(0, delegated_api_2.default)(actions_1.GetNativeDialogHistoryCommand.methodName)]() {
const callsite = (0, get_callsite_1.getCallsiteForMethod)(actions_1.GetNativeDialogHistoryCommand.methodName);
const command = this._createCommand(actions_1.GetNativeDialogHistoryCommand, {}, callsite);
return this.testRun.executeCommand(command, callsite);
}
[(0, delegated_api_2.default)(actions_1.GetBrowserConsoleMessagesCommand.methodName)]() {
const callsite = (0, get_callsite_1.getCallsiteForMethod)(actions_1.GetBrowserConsoleMessagesCommand.methodName);
const command = this._createCommand(actions_1.GetBrowserConsoleMessagesCommand, {}, callsite);
return this.testRun.executeCommand(command, callsite);
}
checkForExcessiveAwaits(checkedCallsite, { actionId }) {
const snapshotPropertyCallsites = this.testRun.observedCallsites.snapshotPropertyCallsites;
const callsiteId = (0, callsite_1.getCallsiteId)(checkedCallsite);
// NOTE: If there are unasserted callsites, we should add all of them to awaitedSnapshotWarnings.
// The warnings themselves are raised after the test run in wrap-test-function
if (snapshotPropertyCallsites[callsiteId] && !snapshotPropertyCallsites[callsiteId].checked) {
for (const propertyCallsite of snapshotPropertyCallsites[callsiteId].callsites)
this.testRun.observedCallsites.awaitedSnapshotWarnings.set((0, callsite_1.getCallsiteStackFrameString)(propertyCallsite), { callsite: propertyCallsite, actionId });
delete snapshotPropertyCallsites[callsiteId];
}
else
snapshotPropertyCallsites[callsiteId] = { callsites: [], checked: true };
}
[(0, delegated_api_2.default)(assertion_2.AssertionCommand.methodName)](actual) {
const callsite = (0, get_callsite_1.getCallsiteForMethod)(assertion_2.AssertionCommand.methodName);
return new assertion_1.default(actual, this, callsite);
}
[(0, delegated_api_2.default)(observation_1.DebugCommand.methodName)]() {
// NOTE: do not need to enqueue the Debug command if we are in debugging mode.
// The Debug command will be executed by CDP.
// Also, we are forced to add empty function to the execution chain to preserve it.
return this.isCompilerServiceMode() ? this._enqueueTask(observation_1.DebugCommand.methodName, lodash_1.noop) : this.enqueueCommand(observation_1.DebugCommand);
}
[(0, delegated_api_2.default)(actions_1.SetTestSpeedCommand.methodName)](speed) {
return this.enqueueCommand(actions_1.SetTestSpeedCommand, { speed });
}
[(0, delegated_api_2.default)(actions_1.SetPageLoadTimeoutCommand.methodName)](duration) {
return this.enqueueCommand(actions_1.SetPageLoadTimeoutCommand, { duration }, (testController, command) => {
(0, add_rendered_warning_1.default)(testController.warningLog, { message: (0, deprecated_1.getDeprecationMessage)(deprecated_1.DEPRECATED.setPageLoadTimeout), actionId: command.actionId });
});
}
[(0, delegated_api_2.default)(actions_1.UseRoleCommand.methodName)](role) {
return this.enqueueCommand(actions_1.UseRoleCommand, { role });
}
[(0, delegated_api_2.default)(actions_1.SkipJsErrorsCommand.methodName)](options) {
return this.enqueueCommand(actions_1.SkipJsErrorsCommand, { options });
}
[(0, delegated_api_2.default)(actions_1.AddRequestHooksCommand.methodName)](...hooks) {
hooks = (0, lodash_1.flattenDeep)(hooks);
return this.enqueueCommand(actions_1.AddRequestHooksCommand, { hooks });
}
[(0, delegated_api_2.default)(actions_1.RemoveRequestHooksCommand.methodName)](...hooks) {
hooks = (0, lodash_1.flattenDeep)(hooks);
return this.enqueueCommand(actions_1.RemoveRequestHooksCommand, { hooks });
}
static enableDebugForNonDebugCommands() {
inDebug = true;
}
static disableDebugForNonDebugCommands() {
inDebug = false;
}
shouldStop(command) {
// NOTE: should never stop in not compliler debugging mode
if (!this.isCompilerServiceMode())
return false;
// NOTE: should always stop on Debug command
if (command === 'debug')
return true;
// NOTE: should stop on other actions after the `Next Action` button is clicked
if (inDebug) {
inDebug = false;
return true;
}
return false;
}
isCompilerServiceMode() {
return this.testRun instanceof test_run_proxy_1.default;
}
}
exports.default = TestController;
TestController.API_LIST = (0, delegated_api_1.getDelegatedAPIList)(TestController.prototype);
(0, delegated_api_1.delegateAPI)(TestController.prototype, TestController.API_LIST, { useCurrentCtxAsHandler: true });
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3Rlc3QtY29udHJvbGxlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9GQUFvRjtBQUNwRixvREFBNkI7QUFDN0IsbUNBT2dCO0FBRWhCLDREQUFpRTtBQUNqRSw2R0FBbUY7QUFDbkYsNERBQW9DO0FBQ3BDLDZEQUE2RTtBQUM3RSxvR0FBa0U7QUFDbEUsK0RBQW1GO0FBRW5GLDZEQXlDeUM7QUFFekMsdUZBTXNEO0FBRXRELHFFQUFnRjtBQUNoRiwyREFBOEU7QUFDOUUsd0RBQTBEO0FBQzFELDRGQUFrRTtBQUVsRSxvREFHK0I7QUFFL0IsaUVBQXFFO0FBQ3JFLG1EQUFrRjtBQUNsRiw4RkFBb0U7QUFDcEUsc0RBQW1GO0FBQ25GLGtEQUEyRDtBQUMzRCw4Q0FBb0Q7QUFDcEQsc0VBQTZDO0FBQzdDLG9FQUEyQztBQUUzQyxNQUFNLFlBQVksR0FBRyxnQkFBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQztBQUU1QyxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFFcEIsTUFBcUIsY0FBYztJQUMvQixZQUFhLE9BQU87O1FBQ2hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFFOUIsSUFBSSxDQUFDLE9BQU8sR0FBVSxPQUFPLENBQUM7UUFDOUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxnQkFBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxVQUFVLEdBQU8sT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUN6QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksd0JBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsSUFBSSwwQ0FBRSxhQUFhLENBQUMsQ0FBQztRQUU1RSxJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBRUQs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QUFxQjtRQUNqQixPQUFPLElBQUksQ0FBQyxPQUFPLFlBQVksd0JBQVksQ0FBQztJQUNoRCxDQUFDO0NBRUo7QUExakJELGlDQTBqQkM7QUFFRCxjQUFjLENBQUMsUUFBUSxHQUFHLElBQUEsbUNBQW1CLEVBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBRXhFLElBQUEsMkJBQVcsRUFBQyxjQUFjLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxzQkFBc0IsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVE9ETzogRml4IGh0dHBzOi8vZ2l0aHViLmNvbS9EZXZFeHByZXNzL3Rlc3RjYWZlL2lzc3Vlcy80MTM5IHRvIGdldCByaWQgb2YgUGlua2llXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwaW5raWUnO1xuaW1wb3J0IHtcbiAgICBpZGVudGl0eSxcbiAgICBhc3NpZ24sXG4gICAgaXNOaWwgYXMgaXNOdWxsT3JVbmRlZmluZWQsXG4gICAgZmxhdHRlbkRlZXAsXG4gICAgbm9vcCxcbiAgICBjYXN0QXJyYXksXG59IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCB7IGdldENhbGxzaXRlRm9yTWV0aG9kIH0gZnJvbSAnLi4vLi4vZXJyb3JzL2dldC1jYWxsc2l0ZSc7XG5pbXBvcnQgQ2xpZW50RnVuY3Rpb25CdWlsZGVyIGZyb20gJy4uLy4uL2NsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXInO1xuaW1wb3J0IEFzc2VydGlvbiBmcm9tICcuL2Fzc2VydGlvbic7XG5pbXBvcnQgeyBnZXREZWxlZ2F0ZWRBUElMaXN0LCBkZWxlZ2F0ZUFQSSB9IGZyb20gJy4uLy4uL3V0aWxzL2RlbGVnYXRlZC1hcGknO1xuaW1wb3J0IGFkZFdhcm5pbmcgZnJvbSAnLi4vLi4vbm90aWZpY2F0aW9ucy9hZGQtcmVuZGVyZWQtd2FybmluZyc7XG5pbXBvcnQgeyBnZXREZXByZWNhdGlvbk1lc3NhZ2UsIERFUFJFQ0FURUQgfSBmcm9tICcuLi8uLi9ub3RpZmljYXRpb25zL2RlcHJlY2F0ZWQnO1xuXG5pbXBvcnQge1xuICAgIENsaWNrQ29tbWFuZCxcbiAgICBSaWdodENsaWNrQ29tbWFuZCxcbiAgICBEb3VibGVDbGlja0NvbW1hbmQsXG4gICAgSG92ZXJDb21tYW5kLFxuICAgIERyYWdDb21tYW5kLFxuICAgIERyYWdUb0VsZW1lbnRDb21tYW5kLFxuICAgIFR5cGVUZXh0Q29tbWFuZCxcbiAgICBTZWxlY3RUZXh0Q29tbWFuZCxcbiAgICBTZWxlY3RUZXh0QXJlYUNvbnRlbnRDb21tYW5kLFxuICAgIFNlbGVjdEVkaXRhYmxlQ29udGVudENvbW1hbmQsXG4gICAgUHJlc3NLZXlDb21tYW5kLFxuICAgIE5hdmlnYXRlVG9Db21tYW5kLFxuICAgIFNldEZpbGVzVG9VcGxvYWRDb21tYW5kLFxuICAgIENsZWFyVXBsb2FkQ29tbWFuZCxcbiAgICBTd2l0Y2hUb0lmcmFtZUNvbW1hbmQsXG4gICAgU3dpdGNoVG9NYWluV2luZG93Q29tbWFuZCxcbiAgICBPcGVuV2luZG93Q29tbWFuZCxcbiAgICBDbG9zZVdpbmRvd0NvbW1hbmQsXG4gICAgR2V0Q3VycmVudFdpbmRvd0NvbW1hbmQsXG4gICAgU3dpdGNoVG9XaW5kb3dDb21tYW5kLFxuICAgIFN3aXRjaFRvV2luZG93QnlQcmVkaWNhdGVDb21tYW5kLFxuICAgIFN3aXRjaFRvUGFyZW50V2luZG93Q29tbWFuZCxcbiAgICBTd2l0Y2hUb1ByZXZpb3VzV2luZG93Q29tbWFuZCxcbiAgICBTZXROYXRpdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCxcbiAgICBHZXROYXRpdmVEaWFsb2dIaXN0b3J5Q29tbWFuZCxcbiAgICBHZXRCcm93c2VyQ29uc29sZU1lc3NhZ2VzQ29tbWFuZCxcbiAgICBTZXRUZXN0U3BlZWRDb21tYW5kLFxuICAgIFNldFBhZ2VMb2FkVGltZW91dENvbW1hbmQsXG4gICAgU2Nyb2xsQ29tbWFuZCxcbiAgICBTY3JvbGxCeUNvbW1hbmQsXG4gICAgU2Nyb2xsSW50b1ZpZXdDb21tYW5kLFxuICAgIFVzZVJvbGVDb21tYW5kLFxuICAgIERpc3BhdGNoRXZlbnRDb21tYW5kLFxuICAgIEdldENvb2tpZXNDb21tYW5kLFxuICAgIFNldENvb2tpZXNDb21tYW5kLFxuICAgIERlbGV0ZUNvb2tpZXNDb21tYW5kLFxuICAgIFJlcXVlc3RDb21tYW5kLFxuICAgIFNraXBKc0Vycm9yc0NvbW1hbmQsXG4gICAgQWRkUmVxdWVzdEhvb2tzQ29tbWFuZCxcbiAgICBSZW1vdmVSZXF1ZXN0SG9va3NDb21tYW5kLFxufSBmcm9tICcuLi8uLi90ZXN0LXJ1bi9jb21tYW5kcy9hY3Rpb25zJztcblxuaW1wb3J0IHtcbiAgICBUYWtlU2NyZWVuc2hvdENvbW1hbmQsXG4gICAgVGFrZUVsZW1lbnRTY3JlZW5zaG90Q29tbWFuZCxcbiAgICBSZXNpemVXaW5kb3dDb21tYW5kLFxuICAgIFJlc2l6ZVdpbmRvd1RvRml0RGV2aWNlQ29tbWFuZCxcbiAgICBNYXhpbWl6ZVdpbmRvd0NvbW1hbmQsXG59IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL2Jyb3dzZXItbWFuaXB1bGF0aW9uJztcblxuaW1wb3J0IHsgV2FpdENvbW1hbmQsIERlYnVnQ29tbWFuZCB9IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL29ic2VydmF0aW9uJztcbmltcG9ydCB7IGNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQgYXMgY3JlYXRlQ29udGV4dCB9IGZyb20gJy4vZXhlY3V0aW9uLWNvbnRleHQnO1xuaW1wb3J0IHsgaXNTZWxlY3RvciB9IGZyb20gJy4uLy4uL2NsaWVudC1mdW5jdGlvbnMvdHlwZXMnO1xuaW1wb3J0IFRlc3RSdW5Qcm94eSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jb21waWxlci90ZXN0LXJ1bi1wcm94eSc7XG5cbmltcG9ydCB7XG4gICAgTXVsdGlwbGVXaW5kb3dzTW9kZUlzRGlzYWJsZWRFcnJvcixcbiAgICBNdWx0aXBsZVdpbmRvd3NNb2RlSXNOb3RBdmFpbGFibGVJblJlbW90ZUJyb3dzZXJFcnJvcixcbn0gZnJvbSAnLi4vLi4vZXJyb3JzL3Rlc3QtcnVuJztcblxuaW1wb3J0IHsgQXNzZXJ0aW9uQ29tbWFuZCB9IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL2Fzc2VydGlvbic7XG5pbXBvcnQgeyBnZXRDYWxsc2l0ZUlkLCBnZXRDYWxsc2l0ZVN0YWNrRnJhbWVTdHJpbmcgfSBmcm9tICcuLi8uLi91dGlscy9jYWxsc2l0ZSc7XG5pbXBvcnQgUmVFeGVjdXRhYmxlUHJvbWlzZSBmcm9tICcuLi8uLi91dGlscy9yZS1leGVjdXRhYmxlLXByb21pc2UnO1xuaW1wb3J0IHsgc2VuZFJlcXVlc3RUaHJvdWdoQVBJIGFzIHNlbmRSZXF1ZXN0IH0gZnJvbSAnLi4vLi4vdGVzdC1ydW4vcmVxdWVzdC9zZW5kJztcbmltcG9ydCB7IFJlcXVlc3RSdW50aW1lRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uLy4uL2Vycm9ycy90eXBlcyc7XG5pbXBvcnQgQ3VzdG9tQWN0aW9ucyBmcm9tICcuL2N1c3RvbS1hY3Rpb25zJztcbmltcG9ydCBkZWxlZ2F0ZWRBUEkgZnJvbSAnLi9kZWxlZ2F0ZWQtYXBpJztcblxuY29uc3Qgb3JpZ2luYWxUaGVuID0gUHJvbWlzZS5yZXNvbHZlKCkudGhlbjtcblxubGV0IGluRGVidWcgPSBmYWxzZTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdENvbnRyb2xsZXIge1xuICAgIGNvbnN0cnVjdG9yICh0ZXN0UnVuKSB7XG4gICAgICAgIHRoaXMuX2V4ZWN1dGlvbkNvbnRleHQgPSBudWxsO1xuXG4gICAgICAgIHRoaXMudGVzdFJ1biAgICAgICAgPSB0ZXN0UnVuO1xuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIHRoaXMud2FybmluZ0xvZyAgICAgPSB0ZXN0UnVuLndhcm5pbmdMb2c7XG4gICAgICAgIHRoaXMuX2N1c3RvbUFjdGlvbnMgPSBuZXcgQ3VzdG9tQWN0aW9ucyh0aGlzLCB0ZXN0UnVuPy5vcHRzPy5jdXN0b21BY3Rpb25zKTtcblxuICAgICAgICB0aGlzLl9hZGRUZXN0Q29udHJvbGxlclRvRXhlY3V0aW9uQ2hhaW4oKTtcbiAgICB9XG5cbiAgICBfYWRkVGVzdENvbnRyb2xsZXJUb0V4ZWN1dGlvbkNoYWluICgpIHtcbiAgICAgICAgdGhpcy5leGVjdXRpb25DaGFpbi5fdGVzdENvbnRyb2xsZXIgPSB0aGlzO1xuICAgIH1cblxuICAgIC8vIE5PVEU6IFRlc3RDYWZlIGV4ZWN1dGVzIGFjdGlvbnMgYW5kIGFzc2VydGlvbnMgYXN5bmNocm9ub3VzbHkgaW4gdGhlIGZvbGxvd2luZyBjYXNlczpcbiAgICAvLyBhKSBUaGUgYGF3YWl0YCBrZXl3b3JkIHRoYXQgcHJvY2VlZHMgdGhlIG1ldGhvZCBkZWNsYXJhdGlvbiB0cmlnZ2VycyB0aGUgYHRoZW5gIGZ1bmN0aW9uIG9mIGEgUHJvbWlzZS5cbiAgICAvLyBiKSBUaGUgYWN0aW9uIGlzIGNoYWluZWQgdG8gYW5vdGhlciBgYXdhaXRlZGAgbWV0aG9kLlxuICAgIC8vXG4gICAgLy8gSW4gb3JkZXIgdG8gdHJhY2sgbWlzc2luZyBgYXdhaXRgIHN0YXRlbWVudHMsIFRlc3RDYWZlIGV4cG9zZXMgYSBzcGVjaWFsIFByb21pc2UgdG8gdGhlIHVzZXIuXG4gICAgLy8gV2hlbiBUZXN0Q2FmZSBkZXRlY3RzIGEgbWlzc2luZyBgYXdhaXRgIHN0YXRlbWVudCwgaXQgY29tcGFyZXMgdGhlIG1ldGhvZCdzIGNhbGxzaXRlIHRvIHRoZSBjYWxsIHNpdGUgb2YgdGhlIGV4cG9zZWQgUHJvbWlzZS5cbiAgICAvLyBUaGlzIHdvcmthcm91bmQgaXMgbmVjZXNzYXJ5IGZvciBzaXR1YXRpb25zIGxpa2UgdGhlc2U6XG4gICAgLy9cbiAgICAvLyB2YXIgdDIgPSB0LmNsaWNrKCcjYnRuMScpOyAvLyA8LS0gc3RvcmVzIG5ldyBjYWxsc2l0ZVdpdGhvdXRBd2FpdFxuICAgIC8vIGF3YWl0IHQyOyAgICAgICAgICAgICAgICAgIC8vIDwtLSBjYWxsc2l0ZVdpdGhvdXRBd2FpdCA9IG51bGxcbiAgICAvLyB0LmNsaWNrKCcjYnRuMicpOyAgICAgICAgICAvLyA8LS0gc3RvcmVzIG5ldyBjYWxsc2l0ZVdpdGhvdXRBd2FpdFxuICAgIC8vIGF3YWl0IHQyLmNsaWNrKCcjYnRuMycpOyAgIC8vIDwtLSB3aXRob3V0IGNoZWNrIGl0IHdpbGwgc2V0IGNhbGxzaXRlV2l0aG91dEF3YWl0ID0gbnVsbCwgc28gd2Ugd2lsbCBsb3N0IHRyYWNraW5nXG4gICAgX2NyZWF0ZUV4dGVuZGVkUHJvbWlzZSAocHJvbWlzZSwgY2FsbHNpdGUpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5kZWRQcm9taXNlICAgICA9IHByb21pc2UudGhlbihpZGVudGl0eSk7XG4gICAgICAgIGNvbnN0IG9ic2VydmVkQ2FsbHNpdGVzICAgPSB0aGlzLnRlc3RSdW4ub2JzZXJ2ZWRDYWxsc2l0ZXM7XG4gICAgICAgIGNvbnN0IG1hcmtDYWxsc2l0ZUF3YWl0ZWQgPSAoKSA9PiBvYnNlcnZlZENhbGxzaXRlcy5jYWxsc2l0ZXNXaXRob3V0QXdhaXQuZGVsZXRlKGNhbGxzaXRlKTtcblxuICAgICAgICBleHRlbmRlZFByb21pc2UudGhlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1hcmtDYWxsc2l0ZUF3YWl0ZWQoKTtcblxuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsVGhlbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGRlbGVnYXRlQVBJKGV4dGVuZGVkUHJvbWlzZSwgVGVzdENvbnRyb2xsZXIuQVBJX0xJU1QsIHtcbiAgICAgICAgICAgIGhhbmRsZXI6ICAgICB0aGlzLFxuICAgICAgICAgICAgcHJveHlNZXRob2Q6IG1hcmtDYWxsc2l0ZUF3YWl0ZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBleHRlbmRlZFByb21pc2U7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNvbW1hbmQgKENtZEN0b3IsIGNtZEFyZ3MsIGNhbGxzaXRlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IENtZEN0b3IoY21kQXJncywgdGhpcy50ZXN0UnVuKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBlcnIuY2FsbHNpdGUgPSBjYWxsc2l0ZTtcblxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2VucXVldWVUYXNrIChhcGlNZXRob2ROYW1lLCBjcmVhdGVUYXNrRXhlY3V0b3IsIGNhbGxzaXRlKSB7XG4gICAgICAgIGNvbnN0IGV4ZWN1dG9yID0gY3JlYXRlVGFza0V4ZWN1dG9yKCk7XG5cbiAgICAgICAgdGhpcy5leGVjdXRpb25DaGFpbi50aGVuID0gb3JpZ2luYWxUaGVuO1xuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluICAgICAgPSB0aGlzLmV4ZWN1dGlvbkNoYWluLnRoZW4oZXhlY3V0b3IpO1xuXG4gICAgICAgIHRoaXMudGVzdFJ1bi5vYnNlcnZlZENhbGxzaXRlcy5jYWxsc2l0ZXNXaXRob3V0QXdhaXQuYWRkKGNhbGxzaXRlKTtcblxuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluID0gdGhpcy5fY3JlYXRlRXh0ZW5kZWRQcm9taXNlKHRoaXMuZXhlY3V0aW9uQ2hhaW4sIGNhbGxzaXRlKTtcblxuICAgICAgICB0aGlzLl9hZGRUZXN0Q29udHJvbGxlclRvRXhlY3V0aW9uQ2hhaW4oKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRpb25DaGFpbjtcbiAgICB9XG5cbiAgICBlbnF1ZXVlQ29tbWFuZCAoQ21kQ3RvciwgY21kQXJncywgdmFsaWRhdGVDb21tYW5kRm4sIGNhbGxzaXRlKSB7XG4gICAgICAgIGNhbGxzaXRlID0gY2FsbHNpdGUgfHwgZ2V0Q2FsbHNpdGVGb3JNZXRob2QoQ21kQ3Rvci5tZXRob2ROYW1lKTtcblxuICAgICAgICBjb25zdCBjb21tYW5kICA9IHRoaXMuX2NyZWF0ZUNvbW1hbmQoQ21kQ3RvciwgY21kQXJncywgY2FsbHNpdGUpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsaWRhdGVDb21tYW5kRm4gPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICB2YWxpZGF0ZUNvbW1hbmRGbih0aGlzLCBjb21tYW5kLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVUYXNrKGNvbW1hbmQubWV0aG9kTmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50ZXN0UnVuLmV4ZWN1dGVDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXhlY3V0aW9uQ2hhaW4gPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sIGNhbGxzaXRlKTtcbiAgICB9XG5cbiAgICBfdmFsaWRhdGVNdWx0aXBsZVdpbmRvd0NvbW1hbmQgKGFwaU1ldGhvZE5hbWUpIHtcbiAgICAgICAgY29uc3QgeyBkaXNhYmxlTXVsdGlwbGVXaW5kb3dzLCBhY3RpdmVXaW5kb3dJZCB9ID0gdGhpcy50ZXN0UnVuO1xuXG4gICAgICAgIGlmIChkaXNhYmxlTXVsdGlwbGVXaW5kb3dzKVxuICAgICAgICAgICAgdGhyb3cgbmV3IE11bHRpcGxlV2luZG93c01vZGVJc0Rpc2FibGVkRXJyb3IoYXBpTWV0aG9kTmFtZSk7XG5cbiAgICAgICAgaWYgKCFhY3RpdmVXaW5kb3dJZClcbiAgICAgICAgICAgIHRocm93IG5ldyBNdWx0aXBsZVdpbmRvd3NNb2RlSXNOb3RBdmFpbGFibGVJblJlbW90ZUJyb3dzZXJFcnJvcihhcGlNZXRob2ROYW1lKTtcbiAgICB9XG5cbiAgICBnZXRFeGVjdXRpb25Db250ZXh0ICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9leGVjdXRpb25Db250ZXh0KVxuICAgICAgICAgICAgdGhpcy5fZXhlY3V0aW9uQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQodGhpcy50ZXN0UnVuKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZXhlY3V0aW9uQ29udGV4dDtcbiAgICB9XG5cbiAgICAvLyBBUEkgaW1wbGVtZW50YXRpb25cbiAgICAvLyBXZSBuZWVkIGltcGxlbWVudGF0aW9uIG1ldGhvZHMgdG8gb2J0YWluIGNvcnJlY3QgY2FsbHNpdGVzLiBJZiB3ZSB1c2UgcGxhaW4gQVBJXG4gICAgLy8gbWV0aG9kcyBpbiBjaGFpbmVkIHdyYXBwZXJzIHRoZW4gd2Ugd2lsbCBoYXZlIGNhbGxzaXRlIGZvciB0aGUgd3JhcHBlZCBtZXRob2RcbiAgICAvLyBpbiB0aGlzIGZpbGUgaW5zdGVhZCBvZiBjaGFpbmVkIG1ldGhvZCBjYWxsc2l0ZSBpbiB1c2VyIGNvZGUuXG4gICAgX2N0eCRnZXR0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXN0UnVuLmN0eDtcbiAgICB9XG5cbiAgICBfY3R4JHNldHRlciAodmFsKSB7XG4gICAgICAgIHRoaXMudGVzdFJ1bi5jdHggPSB2YWw7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bi5jdHg7XG4gICAgfVxuXG4gICAgX2ZpeHR1cmVDdHgkZ2V0dGVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bi5maXh0dXJlQ3R4O1xuICAgIH1cblxuICAgIF9icm93c2VyJGdldHRlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uYnJvd3NlcjtcbiAgICB9XG5cbiAgICBfY3VzdG9tQWN0aW9ucyRnZXR0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VzdG9tQWN0aW9ucyB8fCBuZXcgQ3VzdG9tQWN0aW9ucyh0aGlzLCB0aGlzLnRlc3RSdW4ub3B0cy5jdXN0b21BY3Rpb25zKTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKERpc3BhdGNoRXZlbnRDb21tYW5kLm1ldGhvZE5hbWUpXSAoc2VsZWN0b3IsIGV2ZW50TmFtZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKERpc3BhdGNoRXZlbnRDb21tYW5kLCB7IHNlbGVjdG9yLCBldmVudE5hbWUsIG9wdGlvbnMsIHJlbGF0ZWRUYXJnZXQ6IG9wdGlvbnMucmVsYXRlZFRhcmdldCB9KTtcbiAgICB9XG5cbiAgICBfcHJlcGFyZUNvb2tpZUFyZ3VtZW50cyAoYXJncywgaXNTZXRDb21tYW5kID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgdXJsc0FyZyA9IGNhc3RBcnJheShhcmdzWzFdKTtcbiAgICAgICAgY29uc3QgdXJscyAgICA9IEFycmF5LmlzQXJyYXkodXJsc0FyZykgJiYgdHlwZW9mIHVybHNBcmdbMF0gPT09ICdzdHJpbmcnID8gdXJsc0FyZyA6IFtdO1xuXG4gICAgICAgIGNvbnN0IGNvb2tpZXNBcmcgPSB1cmxzLmxlbmd0aCA/IGFyZ3NbMF0gOiBhcmdzO1xuICAgICAgICBjb25zdCBjb29raWVzICAgID0gW107XG5cbiAgICAgICAgZmxhdHRlbkRlZXAoY2FzdEFycmF5KGNvb2tpZXNBcmcpKS5mb3JFYWNoKGNvb2tpZSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNTZXRDb21tYW5kICYmICFjb29raWUubmFtZSAmJiB0eXBlb2YgY29va2llID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhjb29raWUpLmZvckVhY2goKFtuYW1lLCB2YWx1ZV0pID0+IGNvb2tpZXMucHVzaCh7IG5hbWUsIHZhbHVlIH0pKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKCFpc1NldENvbW1hbmQgJiYgdHlwZW9mIGNvb2tpZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgY29va2llcy5wdXNoKHsgbmFtZTogY29va2llIH0pO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvb2tpZXMucHVzaChjb29raWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyB1cmxzLCBjb29raWVzIH07XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShHZXRDb29raWVzQ29tbWFuZC5tZXRob2ROYW1lKV0gKC4uLmFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoR2V0Q29va2llc0NvbW1hbmQsIHRoaXMuX3ByZXBhcmVDb29raWVBcmd1bWVudHMoYXJncykpO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoU2V0Q29va2llc0NvbW1hbmQubWV0aG9kTmFtZSldICguLi5hcmdzKSB7XG4gICAgICAgIGNvbnN0IHsgdXJscywgY29va2llcyB9ID0gdGhpcy5fcHJlcGFyZUNvb2tpZUFyZ3VtZW50cyhhcmdzLCB0cnVlKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTZXRDb29raWVzQ29tbWFuZCwgeyBjb29raWVzLCB1cmw6IHVybHNbMF0gfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShEZWxldGVDb29raWVzQ29tbWFuZC5tZXRob2ROYW1lKV0gKC4uLmFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoRGVsZXRlQ29va2llc0NvbW1hbmQsIHRoaXMuX3ByZXBhcmVDb29raWVBcmd1bWVudHMoYXJncykpO1xuICAgIH1cblxuICAgIF9wcmVwYXJlUmVxdWVzdEFyZ3VtZW50cyAoYmluZE9wdGlvbnMsIC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgW3VybCwgb3B0aW9uc10gPSB0eXBlb2YgYXJnc1swXSA9PT0gJ29iamVjdCcgPyBbYXJnc1swXS51cmwsIGFyZ3NbMF1dIDogYXJncztcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywgYmluZE9wdGlvbnMpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIF9jcmVhdGVSZXF1ZXN0RnVuY3Rpb24gKGJpbmRPcHRpb25zID0ge30pIHtcbiAgICAgICAgY29uc3QgY29udHJvbGxlciA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlID0gZ2V0Q2FsbHNpdGVGb3JNZXRob2QoUmVxdWVzdENvbW1hbmQubWV0aG9kTmFtZSk7XG5cbiAgICAgICAgaWYgKCFjb250cm9sbGVyLnRlc3RSdW4gfHwgY29udHJvbGxlci50ZXN0UnVuIGluc3RhbmNlb2YgVGVzdFJ1blByb3h5KVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJlcXVlc3RSdW50aW1lRXJyb3IoY2FsbHNpdGUsIFJVTlRJTUVfRVJST1JTLnJlcXVlc3RDYW5ub3RSZXNvbHZlVGVzdFJ1bik7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgICAgICBjb25zdCBjbWRBcmdzID0gY29udHJvbGxlci5fcHJlcGFyZVJlcXVlc3RBcmd1bWVudHMoYmluZE9wdGlvbnMsIC4uLmFyZ3MpO1xuICAgICAgICAgICAgY29uc3QgY29tbWFuZCA9IGNvbnRyb2xsZXIuX2NyZWF0ZUNvbW1hbmQoUmVxdWVzdENvbW1hbmQsIGNtZEFyZ3MsIGNhbGxzaXRlKTtcblxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAuLi5jb21tYW5kLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgdXJsOiBjb21tYW5kLnVybCB8fCBjb21tYW5kLm9wdGlvbnMudXJsIHx8ICcnLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IFJlRXhlY3V0YWJsZVByb21pc2UuZnJvbUZuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VuZFJlcXVlc3QoY29udHJvbGxlci50ZXN0UnVuLCBvcHRpb25zLCBjYWxsc2l0ZSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgUmVxdWVzdENvbW1hbmQucmVzdWx0R2V0dGVycy5mb3JFYWNoKGdldHRlciA9PiB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2UsIGdldHRlciwge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IFJlRXhlY3V0YWJsZVByb21pc2UuZnJvbUZuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VuZFJlcXVlc3QoY29udHJvbGxlci50ZXN0UnVuLCBvcHRpb25zLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZVtnZXR0ZXJdO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBfZGVjb3JhdGVSZXF1ZXN0RnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIFJlcXVlc3RDb21tYW5kLmV4dGVuZGVkTWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZm4sIG1ldGhvZCwge1xuICAgICAgICAgICAgICAgIHZhbHVlOiB0aGlzLl9jcmVhdGVSZXF1ZXN0RnVuY3Rpb24oeyBtZXRob2QgfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShSZXF1ZXN0Q29tbWFuZC5tZXRob2ROYW1lLCAnZ2V0dGVyJyldICgpIHtcbiAgICAgICAgY29uc3QgZm4gPSB0aGlzLl9jcmVhdGVSZXF1ZXN0RnVuY3Rpb24oKTtcblxuICAgICAgICB0aGlzLl9kZWNvcmF0ZVJlcXVlc3RGdW5jdGlvbihmbik7XG5cbiAgICAgICAgcmV0dXJuIGZuO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoQ2xpY2tDb21tYW5kLm1ldGhvZE5hbWUpXSAoc2VsZWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoQ2xpY2tDb21tYW5kLCB7IHNlbGVjdG9yLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoUmlnaHRDbGlja0NvbW1hbmQubWV0aG9kTmFtZSldIChzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChSaWdodENsaWNrQ29tbWFuZCwgeyBzZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKERvdWJsZUNsaWNrQ29tbWFuZC5tZXRob2ROYW1lKV0gKHNlbGVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKERvdWJsZUNsaWNrQ29tbWFuZCwgeyBzZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKEhvdmVyQ29tbWFuZC5tZXRob2ROYW1lKV0gKHNlbGVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKEhvdmVyQ29tbWFuZCwgeyBzZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKERyYWdDb21tYW5kLm1ldGhvZE5hbWUpXSAoc2VsZWN0b3IsIGRyYWdPZmZzZXRYLCBkcmFnT2Zmc2V0WSwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChEcmFnQ29tbWFuZCwgeyBzZWxlY3RvciwgZHJhZ09mZnNldFgsIGRyYWdPZmZzZXRZLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoRHJhZ1RvRWxlbWVudENvbW1hbmQubWV0aG9kTmFtZSldIChzZWxlY3RvciwgZGVzdGluYXRpb25TZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChEcmFnVG9FbGVtZW50Q29tbWFuZCwgeyBzZWxlY3RvciwgZGVzdGluYXRpb25TZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBfZ2V0U2VsZWN0b3JGb3JTY3JvbGwgKGFyZ3MpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSB0eXBlb2YgYXJnc1swXSA9PT0gJ3N0cmluZycgfHwgaXNTZWxlY3RvcihhcmdzWzBdKSA/IGFyZ3NbMF0gOiBudWxsO1xuXG4gICAgICAgIGlmIChzZWxlY3RvcilcbiAgICAgICAgICAgIGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgLy8gTk9URTogaGVyZSB3ZSB1c2UgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCBmb3Igb2xkIFNhZmFyaSB2ZXJzaW9uc1xuICAgICAgICAgICAgLy8gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IGRvZXMgbm90IHdvcmsgYXMgZXhwZWN0ZWQgb24gTW9qYXZlIFNhZmFyaSAxMi4xLyBIaWdoIFNpZXJyYSBTYWZhcmkgMTEuMVxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHNlbGVjdG9yO1xuICAgIH1cblxuICAgIF9nZXRQb3NpdGlvbiAoYXJncykge1xuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGFyZ3MubGVuZ3RoID09PSAxICYmIHR5cGVvZiBhcmdzWzBdID09PSAnc3RyaW5nJyA/IGFyZ3NbMF0gOiBudWxsO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbilcbiAgICAgICAgICAgIGFyZ3Muc2hpZnQoKTtcblxuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShTY3JvbGxDb21tYW5kLm1ldGhvZE5hbWUpXSAoLi4uYXJncykge1xuICAgICAgICBsZXQgcG9zaXRpb24gPSB0aGlzLl9nZXRQb3NpdGlvbihhcmdzKTtcblxuICAgICAgICBjb25zdCBzZWxlY3RvciA9IHRoaXMuX2dldFNlbGVjdG9yRm9yU2Nyb2xsKGFyZ3MpO1xuXG4gICAgICAgIGxldCB4ICAgICAgID0gdm9pZCAwO1xuICAgICAgICBsZXQgeSAgICAgICA9IHZvaWQgMDtcbiAgICAgICAgbGV0IG9wdGlvbnMgPSB2b2lkIDA7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgIFsgcG9zaXRpb24sIG9wdGlvbnMgXSA9IGFyZ3M7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIFsgeCwgeSwgb3B0aW9ucyBdID0gYXJncztcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTY3JvbGxDb21tYW5kLCB7IHNlbGVjdG9yLCB4LCB5LCBwb3NpdGlvbiwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKFNjcm9sbEJ5Q29tbWFuZC5tZXRob2ROYW1lKV0gKC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSB0aGlzLl9nZXRTZWxlY3RvckZvclNjcm9sbChhcmdzKTtcblxuICAgICAgICBjb25zdCBbYnlYLCBieVksIG9wdGlvbnNdID0gYXJncztcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTY3JvbGxCeUNvbW1hbmQsIHsgc2VsZWN0b3IsIGJ5WCwgYnlZLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoU2Nyb2xsSW50b1ZpZXdDb21tYW5kLm1ldGhvZE5hbWUpXSAoc2VsZWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoU2Nyb2xsSW50b1ZpZXdDb21tYW5kLCB7IHNlbGVjdG9yLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoVHlwZVRleHRDb21tYW5kLm1ldGhvZE5hbWUpXSAoc2VsZWN0b3IsIHRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoVHlwZVRleHRDb21tYW5kLCB7IHNlbGVjdG9yLCB0ZXh0LCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoU2VsZWN0VGV4dENvbW1hbmQubWV0aG9kTmFtZSldIChzZWxlY3Rvciwgc3RhcnRQb3MsIGVuZFBvcywgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTZWxlY3RUZXh0Q29tbWFuZCwgeyBzZWxlY3Rvciwgc3RhcnRQb3MsIGVuZFBvcywgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKFNlbGVjdFRleHRBcmVhQ29udGVudENvbW1hbmQubWV0aG9kTmFtZSldIChzZWxlY3Rvciwgc3RhcnRMaW5lLCBzdGFydFBvcywgZW5kTGluZSwgZW5kUG9zLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFNlbGVjdFRleHRBcmVhQ29udGVudENvbW1hbmQsIHtcbiAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgc3RhcnRMaW5lLFxuICAgICAgICAgICAgc3RhcnRQb3MsXG4gICAgICAgICAgICBlbmRMaW5lLFxuICAgICAgICAgICAgZW5kUG9zLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShTZWxlY3RFZGl0YWJsZUNvbnRlbnRDb21tYW5kLm1ldGhvZE5hbWUpXSAoc3RhcnRTZWxlY3RvciwgZW5kU2VsZWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoU2VsZWN0RWRpdGFibGVDb250ZW50Q29tbWFuZCwge1xuICAgICAgICAgICAgc3RhcnRTZWxlY3RvcixcbiAgICAgICAgICAgIGVuZFNlbGVjdG9yLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShQcmVzc0tleUNvbW1hbmQubWV0aG9kTmFtZSldIChrZXlzLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFByZXNzS2V5Q29tbWFuZCwgeyBrZXlzLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoV2FpdENvbW1hbmQubWV0aG9kTmFtZSldICh0aW1lb3V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFdhaXRDb21tYW5kLCB7IHRpbWVvdXQgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShOYXZpZ2F0ZVRvQ29tbWFuZC5tZXRob2ROYW1lKV0gKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChOYXZpZ2F0ZVRvQ29tbWFuZCwgeyB1cmwgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShTZXRGaWxlc1RvVXBsb2FkQ29tbWFuZC5tZXRob2ROYW1lKV0gKHNlbGVjdG9yLCBmaWxlUGF0aCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTZXRGaWxlc1RvVXBsb2FkQ29tbWFuZCwgeyBzZWxlY3RvciwgZmlsZVBhdGggfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShDbGVhclVwbG9hZENvbW1hbmQubWV0aG9kTmFtZSldIChzZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChDbGVhclVwbG9hZENvbW1hbmQsIHsgc2VsZWN0b3IgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShUYWtlU2NyZWVuc2hvdENvbW1hbmQubWV0aG9kTmFtZSldIChvcHRpb25zKSB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7IHBhdGg6IG9wdGlvbnMgfTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChUYWtlU2NyZWVuc2hvdENvbW1hbmQsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoVGFrZUVsZW1lbnRTY3JlZW5zaG90Q29tbWFuZC5tZXRob2ROYW1lKV0gKHNlbGVjdG9yLCAuLi5hcmdzKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmRBcmdzID0geyBzZWxlY3RvciB9O1xuXG4gICAgICAgIGlmIChhcmdzWzFdKSB7XG4gICAgICAgICAgICBjb21tYW5kQXJncy5wYXRoICAgID0gYXJnc1swXTtcbiAgICAgICAgICAgIGNvbW1hbmRBcmdzLm9wdGlvbnMgPSBhcmdzWzFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIGNvbW1hbmRBcmdzLm9wdGlvbnMgPSBhcmdzWzBdO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb21tYW5kQXJncy5wYXRoID0gYXJnc1swXTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChUYWtlRWxlbWVudFNjcmVlbnNob3RDb21tYW5kLCBjb21tYW5kQXJncyk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShSZXNpemVXaW5kb3dDb21tYW5kLm1ldGhvZE5hbWUpXSAod2lkdGgsIGhlaWdodCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChSZXNpemVXaW5kb3dDb21tYW5kLCB7IHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShSZXNpemVXaW5kb3dUb0ZpdERldmljZUNvbW1hbmQubWV0aG9kTmFtZSldIChkZXZpY2UsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoUmVzaXplV2luZG93VG9GaXREZXZpY2VDb21tYW5kLCB7IGRldmljZSwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKE1heGltaXplV2luZG93Q29tbWFuZC5tZXRob2ROYW1lKV0gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChNYXhpbWl6ZVdpbmRvd0NvbW1hbmQpO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoU3dpdGNoVG9JZnJhbWVDb21tYW5kLm1ldGhvZE5hbWUpXSAoc2VsZWN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoU3dpdGNoVG9JZnJhbWVDb21tYW5kLCB7IHNlbGVjdG9yIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoU3dpdGNoVG9NYWluV2luZG93Q29tbWFuZC5tZXRob2ROYW1lKV0gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTd2l0Y2hUb01haW5XaW5kb3dDb21tYW5kKTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKE9wZW5XaW5kb3dDb21tYW5kLm1ldGhvZE5hbWUpXSAodXJsKSB7XG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlTXVsdGlwbGVXaW5kb3dDb21tYW5kKE9wZW5XaW5kb3dDb21tYW5kLm1ldGhvZE5hbWUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKE9wZW5XaW5kb3dDb21tYW5kLCB7IHVybCB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKENsb3NlV2luZG93Q29tbWFuZC5tZXRob2ROYW1lKV0gKHdpbmRvdykge1xuICAgICAgICBjb25zdCB3aW5kb3dJZCAgICAgID0gd2luZG93Py5pZCB8fCBudWxsO1xuXG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlTXVsdGlwbGVXaW5kb3dDb21tYW5kKENsb3NlV2luZG93Q29tbWFuZC5tZXRob2ROYW1lKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChDbG9zZVdpbmRvd0NvbW1hbmQsIHsgd2luZG93SWQgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShHZXRDdXJyZW50V2luZG93Q29tbWFuZC5tZXRob2ROYW1lKV0gKCkge1xuICAgICAgICB0aGlzLl92YWxpZGF0ZU11bHRpcGxlV2luZG93Q29tbWFuZChHZXRDdXJyZW50V2luZG93Q29tbWFuZC5tZXRob2ROYW1lKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChHZXRDdXJyZW50V2luZG93Q29tbWFuZCk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShTd2l0Y2hUb1dpbmRvd0NvbW1hbmQubWV0aG9kTmFtZSldICh3aW5kb3dTZWxlY3Rvcikge1xuICAgICAgICB0aGlzLl92YWxpZGF0ZU11bHRpcGxlV2luZG93Q29tbWFuZChTd2l0Y2hUb1dpbmRvd0NvbW1hbmQubWV0aG9kTmFtZSk7XG5cbiAgICAgICAgbGV0IGNvbW1hbmQ7XG4gICAgICAgIGxldCBhcmdzO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93U2VsZWN0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNvbW1hbmQgPSBTd2l0Y2hUb1dpbmRvd0J5UHJlZGljYXRlQ29tbWFuZDtcblxuICAgICAgICAgICAgYXJncyA9IHsgY2hlY2tXaW5kb3c6IHdpbmRvd1NlbGVjdG9yIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb21tYW5kID0gU3dpdGNoVG9XaW5kb3dDb21tYW5kO1xuXG4gICAgICAgICAgICBhcmdzID0geyB3aW5kb3dJZDogd2luZG93U2VsZWN0b3I/LmlkIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChjb21tYW5kLCBhcmdzKTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKFN3aXRjaFRvUGFyZW50V2luZG93Q29tbWFuZC5tZXRob2ROYW1lKV0gKCkge1xuICAgICAgICB0aGlzLl92YWxpZGF0ZU11bHRpcGxlV2luZG93Q29tbWFuZChTd2l0Y2hUb1BhcmVudFdpbmRvd0NvbW1hbmQubWV0aG9kTmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoU3dpdGNoVG9QYXJlbnRXaW5kb3dDb21tYW5kKTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKFN3aXRjaFRvUHJldmlvdXNXaW5kb3dDb21tYW5kLm1ldGhvZE5hbWUpXSAoKSB7XG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlTXVsdGlwbGVXaW5kb3dDb21tYW5kKFN3aXRjaFRvUHJldmlvdXNXaW5kb3dDb21tYW5kLm1ldGhvZE5hbWUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFN3aXRjaFRvUHJldmlvdXNXaW5kb3dDb21tYW5kKTtcbiAgICB9XG5cbiAgICBfZXZhbCQgKGZuLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQob3B0aW9ucykpXG4gICAgICAgICAgICBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRpb25zLCB7IGJvdW5kVGVzdFJ1bjogdGhpcyB9KTtcblxuICAgICAgICBjb25zdCBidWlsZGVyICA9IG5ldyBDbGllbnRGdW5jdGlvbkJ1aWxkZXIoZm4sIG9wdGlvbnMsIHsgaW5zdGFudGlhdGlvbjogJ2V2YWwnLCBleGVjdXRpb246ICdldmFsJyB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50Rm4gPSBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG5cbiAgICAgICAgcmV0dXJuIGNsaWVudEZuKCk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShTZXROYXRpdmVEaWFsb2dIYW5kbGVyQ29tbWFuZC5tZXRob2ROYW1lKV0gKGZuLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFNldE5hdGl2ZURpYWxvZ0hhbmRsZXJDb21tYW5kLCB7XG4gICAgICAgICAgICBkaWFsb2dIYW5kbGVyOiB7IGZuLCBvcHRpb25zIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoR2V0TmF0aXZlRGlhbG9nSGlzdG9yeUNvbW1hbmQubWV0aG9kTmFtZSldICgpIHtcbiAgICAgICAgY29uc3QgY2FsbHNpdGUgPSBnZXRDYWxsc2l0ZUZvck1ldGhvZChHZXROYXRpdmVEaWFsb2dIaXN0b3J5Q29tbWFuZC5tZXRob2ROYW1lKTtcbiAgICAgICAgY29uc3QgY29tbWFuZCAgPSB0aGlzLl9jcmVhdGVDb21tYW5kKEdldE5hdGl2ZURpYWxvZ0hpc3RvcnlDb21tYW5kLCB7fSwgY2FsbHNpdGUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoR2V0QnJvd3NlckNvbnNvbGVNZXNzYWdlc0NvbW1hbmQubWV0aG9kTmFtZSldICgpIHtcbiAgICAgICAgY29uc3QgY2FsbHNpdGUgPSBnZXRDYWxsc2l0ZUZvck1ldGhvZChHZXRCcm93c2VyQ29uc29sZU1lc3NhZ2VzQ29tbWFuZC5tZXRob2ROYW1lKTtcbiAgICAgICAgY29uc3QgY29tbWFuZCAgPSB0aGlzLl9jcmVhdGVDb21tYW5kKEdldEJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kLCB7fSwgY2FsbHNpdGUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIGNoZWNrRm9yRXhjZXNzaXZlQXdhaXRzIChjaGVja2VkQ2FsbHNpdGUsIHsgYWN0aW9uSWQgfSkge1xuICAgICAgICBjb25zdCBzbmFwc2hvdFByb3BlcnR5Q2FsbHNpdGVzID0gdGhpcy50ZXN0UnVuLm9ic2VydmVkQ2FsbHNpdGVzLnNuYXBzaG90UHJvcGVydHlDYWxsc2l0ZXM7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlSWQgICAgICAgICAgICAgICAgPSBnZXRDYWxsc2l0ZUlkKGNoZWNrZWRDYWxsc2l0ZSk7XG5cbiAgICAgICAgLy8gTk9URTogSWYgdGhlcmUgYXJlIHVuYXNzZXJ0ZWQgY2FsbHNpdGVzLCB3ZSBzaG91bGQgYWRkIGFsbCBvZiB0aGVtIHRvIGF3YWl0ZWRTbmFwc2hvdFdhcm5pbmdzLlxuICAgICAgICAvLyBUaGUgd2FybmluZ3MgdGhlbXNlbHZlcyBhcmUgcmFpc2VkIGFmdGVyIHRoZSB0ZXN0IHJ1biBpbiB3cmFwLXRlc3QtZnVuY3Rpb25cbiAgICAgICAgaWYgKHNuYXBzaG90UHJvcGVydHlDYWxsc2l0ZXNbY2FsbHNpdGVJZF0gJiYgIXNuYXBzaG90UHJvcGVydHlDYWxsc2l0ZXNbY2FsbHNpdGVJZF0uY2hlY2tlZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eUNhbGxzaXRlIG9mIHNuYXBzaG90UHJvcGVydHlDYWxsc2l0ZXNbY2FsbHNpdGVJZF0uY2FsbHNpdGVzKVxuICAgICAgICAgICAgICAgIHRoaXMudGVzdFJ1bi5vYnNlcnZlZENhbGxzaXRlcy5hd2FpdGVkU25hcHNob3RXYXJuaW5ncy5zZXQoZ2V0Q2FsbHNpdGVTdGFja0ZyYW1lU3RyaW5nKHByb3BlcnR5Q2FsbHNpdGUpLCB7IGNhbGxzaXRlOiBwcm9wZXJ0eUNhbGxzaXRlLCBhY3Rpb25JZCB9KTtcblxuICAgICAgICAgICAgZGVsZXRlIHNuYXBzaG90UHJvcGVydHlDYWxsc2l0ZXNbY2FsbHNpdGVJZF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgc25hcHNob3RQcm9wZXJ0eUNhbGxzaXRlc1tjYWxsc2l0ZUlkXSA9IHsgY2FsbHNpdGVzOiBbXSwgY2hlY2tlZDogdHJ1ZSB9O1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoQXNzZXJ0aW9uQ29tbWFuZC5tZXRob2ROYW1lKV0gKGFjdHVhbCkge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKEFzc2VydGlvbkNvbW1hbmQubWV0aG9kTmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBBc3NlcnRpb24oYWN0dWFsLCB0aGlzLCBjYWxsc2l0ZSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShEZWJ1Z0NvbW1hbmQubWV0aG9kTmFtZSldICgpIHtcbiAgICAgICAgLy8gTk9URTogZG8gbm90IG5lZWQgdG8gZW5xdWV1ZSB0aGUgRGVidWcgY29tbWFuZCBpZiB3ZSBhcmUgaW4gZGVidWdnaW5nIG1vZGUuXG4gICAgICAgIC8vIFRoZSBEZWJ1ZyBjb21tYW5kIHdpbGwgYmUgZXhlY3V0ZWQgYnkgQ0RQLlxuICAgICAgICAvLyBBbHNvLCB3ZSBhcmUgZm9yY2VkIHRvIGFkZCBlbXB0eSBmdW5jdGlvbiB0byB0aGUgZXhlY3V0aW9uIGNoYWluIHRvIHByZXNlcnZlIGl0LlxuICAgICAgICByZXR1cm4gdGhpcy5pc0NvbXBpbGVyU2VydmljZU1vZGUoKSA/IHRoaXMuX2VucXVldWVUYXNrKERlYnVnQ29tbWFuZC5tZXRob2ROYW1lLCBub29wKSA6IHRoaXMuZW5xdWV1ZUNvbW1hbmQoRGVidWdDb21tYW5kKTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKFNldFRlc3RTcGVlZENvbW1hbmQubWV0aG9kTmFtZSldIChzcGVlZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTZXRUZXN0U3BlZWRDb21tYW5kLCB7IHNwZWVkIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoU2V0UGFnZUxvYWRUaW1lb3V0Q29tbWFuZC5tZXRob2ROYW1lKV0gKGR1cmF0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFNldFBhZ2VMb2FkVGltZW91dENvbW1hbmQsIHsgZHVyYXRpb24gfSwgKHRlc3RDb250cm9sbGVyLCBjb21tYW5kKSA9PiB7XG4gICAgICAgICAgICBhZGRXYXJuaW5nKHRlc3RDb250cm9sbGVyLndhcm5pbmdMb2csIHsgbWVzc2FnZTogZ2V0RGVwcmVjYXRpb25NZXNzYWdlKERFUFJFQ0FURUQuc2V0UGFnZUxvYWRUaW1lb3V0KSwgYWN0aW9uSWQ6IGNvbW1hbmQuYWN0aW9uSWQgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIFtkZWxlZ2F0ZWRBUEkoVXNlUm9sZUNvbW1hbmQubWV0aG9kTmFtZSldIChyb2xlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVucXVldWVDb21tYW5kKFVzZVJvbGVDb21tYW5kLCB7IHJvbGUgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShTa2lwSnNFcnJvcnNDb21tYW5kLm1ldGhvZE5hbWUpXSAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChTa2lwSnNFcnJvcnNDb21tYW5kLCB7IG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgW2RlbGVnYXRlZEFQSShBZGRSZXF1ZXN0SG9va3NDb21tYW5kLm1ldGhvZE5hbWUpXSAoLi4uaG9va3MpIHtcbiAgICAgICAgaG9va3MgPSBmbGF0dGVuRGVlcChob29rcyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZW5xdWV1ZUNvbW1hbmQoQWRkUmVxdWVzdEhvb2tzQ29tbWFuZCwgeyBob29rcyB9KTtcbiAgICB9XG5cbiAgICBbZGVsZWdhdGVkQVBJKFJlbW92ZVJlcXVlc3RIb29rc0NvbW1hbmQubWV0aG9kTmFtZSldICguLi5ob29rcykge1xuICAgICAgICBob29rcyA9IGZsYXR0ZW5EZWVwKGhvb2tzKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lbnF1ZXVlQ29tbWFuZChSZW1vdmVSZXF1ZXN0SG9va3NDb21tYW5kLCB7IGhvb2tzIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBlbmFibGVEZWJ1Z0Zvck5vbkRlYnVnQ29tbWFuZHMgKCkge1xuICAgICAgICBpbkRlYnVnID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZGlzYWJsZURlYnVnRm9yTm9uRGVidWdDb21tYW5kcyAoKSB7XG4gICAgICAgIGluRGVidWcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzaG91bGRTdG9wIChjb21tYW5kKSB7XG4gICAgICAgIC8vIE5PVEU6IHNob3VsZCBuZXZlciBzdG9wIGluIG5vdCBjb21wbGlsZXIgZGVidWdnaW5nIG1vZGVcbiAgICAgICAgaWYgKCF0aGlzLmlzQ29tcGlsZXJTZXJ2aWNlTW9kZSgpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIE5PVEU6IHNob3VsZCBhbHdheXMgc3RvcCBvbiBEZWJ1ZyBjb21tYW5kXG4gICAgICAgIGlmIChjb21tYW5kID09PSAnZGVidWcnKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgLy8gTk9URTogc2hvdWxkIHN0b3Agb24gb3RoZXIgYWN0aW9ucyBhZnRlciB0aGUgYE5leHQgQWN0aW9uYCBidXR0b24gaXMgY2xpY2tlZFxuICAgICAgICBpZiAoaW5EZWJ1Zykge1xuICAgICAgICAgICAgaW5EZWJ1ZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpc0NvbXBpbGVyU2VydmljZU1vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXN0UnVuIGluc3RhbmNlb2YgVGVzdFJ1blByb3h5O1xuICAgIH1cblxufVxuXG5UZXN0Q29udHJvbGxlci5BUElfTElTVCA9IGdldERlbGVnYXRlZEFQSUxpc3QoVGVzdENvbnRyb2xsZXIucHJvdG90eXBlKTtcblxuZGVsZWdhdGVBUEkoVGVzdENvbnRyb2xsZXIucHJvdG90eXBlLCBUZXN0Q29udHJvbGxlci5BUElfTElTVCwgeyB1c2VDdXJyZW50Q3R4QXNIYW5kbGVyOiB0cnVlIH0pO1xuIl19