UNPKG

110 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5var __importStar = (this && this.__importStar) || function (mod) {
6 if (mod && mod.__esModule) return mod;
7 var result = {};
8 if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
9 result["default"] = mod;
10 return result;
11};
12Object.defineProperty(exports, "__esModule", { value: true });
13const lodash_1 = require("lodash");
14const read_file_relative_1 = require("read-file-relative");
15const promisify_event_1 = __importDefault(require("promisify-event"));
16const mustache_1 = __importDefault(require("mustache"));
17const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
18const debug_log_1 = __importDefault(require("./debug-log"));
19const formattable_adapter_1 = __importDefault(require("../errors/test-run/formattable-adapter"));
20const error_list_1 = __importDefault(require("../errors/error-list"));
21const test_run_1 = require("../errors/test-run/");
22const phase_1 = __importDefault(require("./phase"));
23const client_messages_1 = __importDefault(require("./client-messages"));
24const type_1 = __importDefault(require("./commands/type"));
25const delay_1 = __importDefault(require("../utils/delay"));
26const marker_symbol_1 = __importDefault(require("./marker-symbol"));
27const test_run_tracker_1 = __importDefault(require("../api/test-run-tracker"));
28const phase_2 = __importDefault(require("../role/phase"));
29const plugin_host_1 = __importDefault(require("../reporter/plugin-host"));
30const browser_console_messages_1 = __importDefault(require("./browser-console-messages"));
31const unstable_network_mode_1 = require("../browser/connection/unstable-network-mode");
32const warning_log_1 = __importDefault(require("../notifications/warning-log"));
33const warning_message_1 = __importDefault(require("../notifications/warning-message"));
34const testcafe_hammerhead_1 = require("testcafe-hammerhead");
35const actions_1 = require("./commands/actions");
36const INJECTABLES = __importStar(require("../assets/injectables"));
37const utils_1 = require("../custom-client-scripts/utils");
38const get_url_1 = __importDefault(require("../custom-client-scripts/get-url"));
39const string_1 = require("../utils/string");
40const utils_2 = require("./commands/utils");
41const types_1 = require("../errors/types");
42const lazyRequire = require('import-lazy')(require);
43const SessionController = lazyRequire('./session-controller');
44const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder');
45const BrowserManipulationQueue = lazyRequire('./browser-manipulation-queue');
46const TestRunBookmark = lazyRequire('./bookmark');
47const AssertionExecutor = lazyRequire('../assertions/executor');
48const actionCommands = lazyRequire('./commands/actions');
49const browserManipulationCommands = lazyRequire('./commands/browser-manipulation');
50const serviceCommands = lazyRequire('./commands/service');
51const { executeJsExpression, executeAsyncJsExpression } = lazyRequire('./execute-js-expression');
52const TEST_RUN_TEMPLATE = read_file_relative_1.readSync('../client/test-run/index.js.mustache');
53const IFRAME_TEST_RUN_TEMPLATE = read_file_relative_1.readSync('../client/test-run/iframe.js.mustache');
54const TEST_DONE_CONFIRMATION_RESPONSE = 'test-done-confirmation';
55const MAX_RESPONSE_DELAY = 3000;
56const CHILD_WINDOW_READY_TIMEOUT = 30 * 1000;
57const ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT = 'all-driver-tasks-added-to-queue';
58class TestRun extends async_event_emitter_1.default {
59 constructor(test, browserConnection, screenshotCapturer, globalWarningLog, opts) {
60 super();
61 this[marker_symbol_1.default] = true;
62 this.warningLog = new warning_log_1.default(globalWarningLog);
63 this.opts = opts;
64 this.test = test;
65 this.browserConnection = browserConnection;
66 this.phase = phase_1.default.initial;
67 this.driverTaskQueue = [];
68 this.testDoneCommandQueued = false;
69 this.activeDialogHandler = null;
70 this.activeIframeSelector = null;
71 this.speed = this.opts.speed;
72 this.pageLoadTimeout = this.opts.pageLoadTimeout;
73 this.disablePageReloads = test.disablePageReloads || opts.disablePageReloads && test.disablePageReloads !==
74 false;
75 this.disablePageCaching = test.disablePageCaching || opts.disablePageCaching;
76 this.allowMultipleWindows = opts.allowMultipleWindows;
77 this.session = SessionController.getSession(this);
78 this.consoleMessages = new browser_console_messages_1.default();
79 this.pendingRequest = null;
80 this.pendingPageError = null;
81 this.controller = null;
82 this.ctx = Object.create(null);
83 this.fixtureCtx = null;
84 this.currentRoleId = null;
85 this.usedRoleStates = Object.create(null);
86 this.errs = [];
87 this.lastDriverStatusId = null;
88 this.lastDriverStatusResponse = null;
89 this.fileDownloadingHandled = false;
90 this.resolveWaitForFileDownloadingPromise = null;
91 this.addingDriverTasksCount = 0;
92 this.debugging = this.opts.debugMode;
93 this.debugOnFail = this.opts.debugOnFail;
94 this.disableDebugBreakpoints = false;
95 this.debugReporterPluginHost = new plugin_host_1.default({ noColors: false });
96 this.browserManipulationQueue = new BrowserManipulationQueue(browserConnection, screenshotCapturer, this.warningLog);
97 this.debugLog = new debug_log_1.default(this.browserConnection.userAgent);
98 this.quarantine = null;
99 this.debugLogger = this.opts.debugLogger;
100 this._addInjectables();
101 this._initRequestHooks();
102 }
103 _addClientScriptContentWarningsIfNecessary() {
104 const { empty, duplicatedContent } = utils_1.findProblematicScripts(this.test.clientScripts);
105 if (empty.length)
106 this.warningLog.addWarning(warning_message_1.default.clientScriptsWithEmptyContent);
107 if (duplicatedContent.length) {
108 const suffix = string_1.getPluralSuffix(duplicatedContent);
109 const duplicatedContentClientScriptsStr = string_1.getConcatenatedValuesString(duplicatedContent, ',\n ');
110 this.warningLog.addWarning(warning_message_1.default.clientScriptsWithDuplicatedContent, suffix, duplicatedContentClientScriptsStr);
111 }
112 }
113 _addInjectables() {
114 this._addClientScriptContentWarningsIfNecessary();
115 this.injectable.scripts.push(...INJECTABLES.SCRIPTS);
116 this.injectable.userScripts.push(...this.test.clientScripts.map(script => {
117 return {
118 url: get_url_1.default(script),
119 page: script.page
120 };
121 }));
122 this.injectable.styles.push(INJECTABLES.TESTCAFE_UI_STYLES);
123 }
124 get id() {
125 return this.session.id;
126 }
127 get injectable() {
128 return this.session.injectable;
129 }
130 addQuarantineInfo(quarantine) {
131 this.quarantine = quarantine;
132 }
133 addRequestHook(hook) {
134 if (this.requestHooks.indexOf(hook) !== -1)
135 return;
136 this.requestHooks.push(hook);
137 this._initRequestHook(hook);
138 }
139 removeRequestHook(hook) {
140 if (this.requestHooks.indexOf(hook) === -1)
141 return;
142 lodash_1.pull(this.requestHooks, hook);
143 this._disposeRequestHook(hook);
144 }
145 _initRequestHook(hook) {
146 hook.warningLog = this.warningLog;
147 hook._instantiateRequestFilterRules();
148 hook._instantiatedRequestFilterRules.forEach(rule => {
149 this.session.addRequestEventListeners(rule, {
150 onRequest: hook.onRequest.bind(hook),
151 onConfigureResponse: hook._onConfigureResponse.bind(hook),
152 onResponse: hook.onResponse.bind(hook)
153 }, err => this._onRequestHookMethodError(err, hook));
154 });
155 }
156 _onRequestHookMethodError(event, hook) {
157 let err = event.error;
158 const isRequestHookNotImplementedMethodError = err instanceof test_run_1.RequestHookNotImplementedMethodError;
159 if (!isRequestHookNotImplementedMethodError) {
160 const hookClassName = hook.constructor.name;
161 err = new test_run_1.RequestHookUnhandledError(err, hookClassName, event.methodName);
162 }
163 this.addError(err);
164 }
165 _disposeRequestHook(hook) {
166 hook.warningLog = null;
167 hook._instantiatedRequestFilterRules.forEach(rule => {
168 this.session.removeRequestEventListeners(rule);
169 });
170 }
171 _initRequestHooks() {
172 this.requestHooks = Array.from(this.test.requestHooks);
173 this.requestHooks.forEach(hook => this._initRequestHook(hook));
174 }
175 // Hammerhead payload
176 _getPayloadScript() {
177 this.fileDownloadingHandled = false;
178 this.resolveWaitForFileDownloadingPromise = null;
179 return mustache_1.default.render(TEST_RUN_TEMPLATE, {
180 testRunId: JSON.stringify(this.session.id),
181 browserId: JSON.stringify(this.browserConnection.id),
182 browserHeartbeatRelativeUrl: JSON.stringify(this.browserConnection.heartbeatRelativeUrl),
183 browserStatusRelativeUrl: JSON.stringify(this.browserConnection.statusRelativeUrl),
184 browserStatusDoneRelativeUrl: JSON.stringify(this.browserConnection.statusDoneRelativeUrl),
185 browserActiveWindowIdUrl: JSON.stringify(this.browserConnection.activeWindowIdUrl),
186 userAgent: JSON.stringify(this.browserConnection.userAgent),
187 testName: JSON.stringify(this.test.name),
188 fixtureName: JSON.stringify(this.test.fixture.name),
189 selectorTimeout: this.opts.selectorTimeout,
190 pageLoadTimeout: this.pageLoadTimeout,
191 childWindowReadyTimeout: CHILD_WINDOW_READY_TIMEOUT,
192 skipJsErrors: this.opts.skipJsErrors,
193 retryTestPages: this.opts.retryTestPages,
194 speed: this.speed,
195 dialogHandler: JSON.stringify(this.activeDialogHandler)
196 });
197 }
198 _getIframePayloadScript() {
199 return mustache_1.default.render(IFRAME_TEST_RUN_TEMPLATE, {
200 testRunId: JSON.stringify(this.session.id),
201 selectorTimeout: this.opts.selectorTimeout,
202 pageLoadTimeout: this.pageLoadTimeout,
203 retryTestPages: !!this.opts.retryTestPages,
204 speed: this.speed,
205 dialogHandler: JSON.stringify(this.activeDialogHandler)
206 });
207 }
208 // Hammerhead handlers
209 getAuthCredentials() {
210 return this.test.authCredentials;
211 }
212 handleFileDownload() {
213 if (this.resolveWaitForFileDownloadingPromise) {
214 this.resolveWaitForFileDownloadingPromise(true);
215 this.resolveWaitForFileDownloadingPromise = null;
216 }
217 else
218 this.fileDownloadingHandled = true;
219 }
220 handlePageError(ctx, err) {
221 if (ctx.req.headers[unstable_network_mode_1.UNSTABLE_NETWORK_MODE_HEADER]) {
222 ctx.closeWithError(500, err.toString());
223 return;
224 }
225 this.pendingPageError = new test_run_1.PageLoadError(err, ctx.reqOpts.url);
226 ctx.redirect(ctx.toProxyUrl(testcafe_hammerhead_1.SPECIAL_ERROR_PAGE));
227 }
228 // Test function execution
229 async _executeTestFn(phase, fn) {
230 this.phase = phase;
231 try {
232 await fn(this);
233 }
234 catch (err) {
235 let screenshotPath = null;
236 const { screenshots } = this.opts;
237 if (screenshots && screenshots.takeOnFails)
238 screenshotPath = await this.executeCommand(new browserManipulationCommands.TakeScreenshotOnFailCommand());
239 this.addError(err, screenshotPath);
240 return false;
241 }
242 return !this._addPendingPageErrorIfAny();
243 }
244 async _runBeforeHook() {
245 if (this.test.beforeFn)
246 return await this._executeTestFn(phase_1.default.inTestBeforeHook, this.test.beforeFn);
247 if (this.test.fixture.beforeEachFn)
248 return await this._executeTestFn(phase_1.default.inFixtureBeforeEachHook, this.test.fixture.beforeEachFn);
249 return true;
250 }
251 async _runAfterHook() {
252 if (this.test.afterFn)
253 return await this._executeTestFn(phase_1.default.inTestAfterHook, this.test.afterFn);
254 if (this.test.fixture.afterEachFn)
255 return await this._executeTestFn(phase_1.default.inFixtureAfterEachHook, this.test.fixture.afterEachFn);
256 return true;
257 }
258 async start() {
259 test_run_tracker_1.default.activeTestRuns[this.session.id] = this;
260 await this.emit('start');
261 const onDisconnected = err => this._disconnect(err);
262 this.browserConnection.once('disconnected', onDisconnected);
263 await this.once('connected');
264 await this.emit('ready');
265 if (await this._runBeforeHook()) {
266 await this._executeTestFn(phase_1.default.inTest, this.test.fn);
267 await this._runAfterHook();
268 }
269 if (this.disconnected)
270 return;
271 this.browserConnection.removeListener('disconnected', onDisconnected);
272 if (this.errs.length && this.debugOnFail)
273 await this._enqueueSetBreakpointCommand(null, this.debugReporterPluginHost.formatError(this.errs[0]));
274 await this.emit('before-done');
275 await this.executeCommand(new serviceCommands.TestDoneCommand());
276 this._addPendingPageErrorIfAny();
277 this.session.clearRequestEventListeners();
278 this.normalizeRequestHookErrors();
279 delete test_run_tracker_1.default.activeTestRuns[this.session.id];
280 await this.emit('done');
281 }
282 // Errors
283 _addPendingPageErrorIfAny() {
284 if (this.pendingPageError) {
285 this.addError(this.pendingPageError);
286 this.pendingPageError = null;
287 return true;
288 }
289 return false;
290 }
291 _createErrorAdapter(err, screenshotPath) {
292 return new formattable_adapter_1.default(err, {
293 userAgent: this.browserConnection.userAgent,
294 screenshotPath: screenshotPath || '',
295 testRunPhase: this.phase
296 });
297 }
298 addError(err, screenshotPath) {
299 const errList = err instanceof error_list_1.default ? err.items : [err];
300 errList.forEach(item => {
301 const adapter = this._createErrorAdapter(item, screenshotPath);
302 this.errs.push(adapter);
303 });
304 }
305 normalizeRequestHookErrors() {
306 const requestHookErrors = lodash_1.remove(this.errs, e => e.code === types_1.TEST_RUN_ERRORS.requestHookNotImplementedError ||
307 e.code === types_1.TEST_RUN_ERRORS.requestHookUnhandledError);
308 if (!requestHookErrors.length)
309 return;
310 const uniqRequestHookErrors = lodash_1.chain(requestHookErrors)
311 .uniqBy(e => e.hookClassName + e.methodName)
312 .sortBy(['hookClassName', 'methodName'])
313 .value();
314 this.errs = this.errs.concat(uniqRequestHookErrors);
315 }
316 // Task queue
317 _enqueueCommand(command, callsite) {
318 if (this.pendingRequest)
319 this._resolvePendingRequest(command);
320 return new Promise(async (resolve, reject) => {
321 this.addingDriverTasksCount--;
322 this.driverTaskQueue.push({ command, resolve, reject, callsite });
323 if (!this.addingDriverTasksCount)
324 await this.emit(ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT, this.driverTaskQueue.length);
325 });
326 }
327 get driverTaskQueueLength() {
328 return this.addingDriverTasksCount ? promisify_event_1.default(this, ALL_DRIVER_TASKS_ADDED_TO_QUEUE_EVENT) : Promise.resolve(this.driverTaskQueue.length);
329 }
330 async _enqueueBrowserConsoleMessagesCommand(command, callsite) {
331 await this._enqueueCommand(command, callsite);
332 const consoleMessageCopy = this.consoleMessages.getCopy();
333 return consoleMessageCopy[this.browserConnection.activeWindowId];
334 }
335 async _enqueueSetBreakpointCommand(callsite, error) {
336 if (this.browserConnection.isHeadlessBrowser()) {
337 this.warningLog.addWarning(warning_message_1.default.debugInHeadlessError);
338 return;
339 }
340 if (this.debugLogger)
341 this.debugLogger.showBreakpoint(this.session.id, this.browserConnection.userAgent, callsite, error);
342 this.debugging = await this.executeCommand(new serviceCommands.SetBreakpointCommand(!!error), callsite);
343 }
344 _removeAllNonServiceTasks() {
345 this.driverTaskQueue = this.driverTaskQueue.filter(driverTask => utils_2.isServiceCommand(driverTask.command));
346 this.browserManipulationQueue.removeAllNonServiceManipulations();
347 }
348 // Current driver task
349 get currentDriverTask() {
350 return this.driverTaskQueue[0];
351 }
352 _resolveCurrentDriverTask(result) {
353 this.currentDriverTask.resolve(result);
354 this.driverTaskQueue.shift();
355 if (this.testDoneCommandQueued)
356 this._removeAllNonServiceTasks();
357 }
358 _rejectCurrentDriverTask(err) {
359 err.callsite = err.callsite || this.currentDriverTask.callsite;
360 this.currentDriverTask.reject(err);
361 this._removeAllNonServiceTasks();
362 }
363 // Pending request
364 _clearPendingRequest() {
365 if (this.pendingRequest) {
366 clearTimeout(this.pendingRequest.responseTimeout);
367 this.pendingRequest = null;
368 }
369 }
370 _resolvePendingRequest(command) {
371 this.lastDriverStatusResponse = command;
372 this.pendingRequest.resolve(command);
373 this._clearPendingRequest();
374 }
375 // Handle driver request
376 _fulfillCurrentDriverTask(driverStatus) {
377 if (!this.currentDriverTask)
378 return;
379 if (driverStatus.executionError)
380 this._rejectCurrentDriverTask(driverStatus.executionError);
381 else
382 this._resolveCurrentDriverTask(driverStatus.result);
383 }
384 _handlePageErrorStatus(pageError) {
385 if (this.currentDriverTask && utils_2.isCommandRejectableByPageError(this.currentDriverTask.command)) {
386 this._rejectCurrentDriverTask(pageError);
387 this.pendingPageError = null;
388 return true;
389 }
390 this.pendingPageError = this.pendingPageError || pageError;
391 return false;
392 }
393 _handleDriverRequest(driverStatus) {
394 const isTestDone = this.currentDriverTask && this.currentDriverTask.command.type ===
395 type_1.default.testDone;
396 const pageError = this.pendingPageError || driverStatus.pageError;
397 const currentTaskRejectedByError = pageError && this._handlePageErrorStatus(pageError);
398 if (this.disconnected)
399 return new Promise((_, reject) => reject());
400 this.consoleMessages.concat(driverStatus.consoleMessages);
401 if (!currentTaskRejectedByError && driverStatus.isCommandResult) {
402 if (isTestDone) {
403 this._resolveCurrentDriverTask();
404 return TEST_DONE_CONFIRMATION_RESPONSE;
405 }
406 this._fulfillCurrentDriverTask(driverStatus);
407 if (driverStatus.isPendingWindowSwitching)
408 return null;
409 }
410 return this._getCurrentDriverTaskCommand();
411 }
412 _getCurrentDriverTaskCommand() {
413 if (!this.currentDriverTask)
414 return null;
415 const command = this.currentDriverTask.command;
416 if (command.type === type_1.default.navigateTo && command.stateSnapshot)
417 this.session.useStateSnapshot(JSON.parse(command.stateSnapshot));
418 return command;
419 }
420 // Execute command
421 _executeJsExpression(command) {
422 const resultVariableName = command.resultVariableName;
423 let expression = command.expression;
424 if (resultVariableName)
425 expression = `${resultVariableName} = ${expression}, ${resultVariableName}`;
426 return executeJsExpression(expression, this, { skipVisibilityCheck: false });
427 }
428 async _executeAssertion(command, callsite) {
429 const assertionTimeout = command.options.timeout ===
430 void 0 ? this.opts.assertionTimeout : command.options.timeout;
431 const executor = new AssertionExecutor(command, assertionTimeout, callsite);
432 executor.once('start-assertion-retries', timeout => this.executeCommand(new serviceCommands.ShowAssertionRetriesStatusCommand(timeout)));
433 executor.once('end-assertion-retries', success => this.executeCommand(new serviceCommands.HideAssertionRetriesStatusCommand(success)));
434 const executeFn = this.decoratePreventEmitActionEvents(() => executor.run(), { prevent: true });
435 return await executeFn();
436 }
437 _adjustConfigurationWithCommand(command) {
438 if (command.type === type_1.default.testDone) {
439 this.testDoneCommandQueued = true;
440 if (this.debugLogger)
441 this.debugLogger.hideBreakpoint(this.session.id);
442 }
443 else if (command.type === type_1.default.setNativeDialogHandler)
444 this.activeDialogHandler = command.dialogHandler;
445 else if (command.type === type_1.default.switchToIframe)
446 this.activeIframeSelector = command.selector;
447 else if (command.type === type_1.default.switchToMainWindow)
448 this.activeIframeSelector = null;
449 else if (command.type === type_1.default.setTestSpeed)
450 this.speed = command.speed;
451 else if (command.type === type_1.default.setPageLoadTimeout)
452 this.pageLoadTimeout = command.duration;
453 else if (command.type === type_1.default.debug)
454 this.debugging = true;
455 }
456 async _adjustScreenshotCommand(command) {
457 const browserId = this.browserConnection.id;
458 const { hasChromelessScreenshots } = await this.browserConnection.provider.hasCustomActionForBrowser(browserId);
459 if (!hasChromelessScreenshots)
460 command.generateScreenshotMark();
461 }
462 async _setBreakpointIfNecessary(command, callsite) {
463 if (!this.disableDebugBreakpoints && this.debugging && utils_2.canSetDebuggerBreakpointBeforeCommand(command))
464 await this._enqueueSetBreakpointCommand(callsite);
465 }
466 async executeAction(actionName, command, callsite) {
467 let error = null;
468 let result = null;
469 await this.emitActionStart(actionName, command);
470 try {
471 result = await this.executeCommand(command, callsite);
472 }
473 catch (err) {
474 error = err;
475 }
476 await this.emitActionDone(actionName, command, error);
477 if (error)
478 throw error;
479 return result;
480 }
481 async executeCommand(command, callsite) {
482 this.debugLog.command(command);
483 if (this.pendingPageError && utils_2.isCommandRejectableByPageError(command))
484 return this._rejectCommandWithPageError(callsite);
485 if (utils_2.isExecutableOnClientCommand(command))
486 this.addingDriverTasksCount++;
487 this._adjustConfigurationWithCommand(command);
488 await this._setBreakpointIfNecessary(command, callsite);
489 if (utils_2.isScreenshotCommand(command)) {
490 if (this.opts.disableScreenshots) {
491 this.warningLog.addWarning(warning_message_1.default.screenshotsDisabled);
492 return null;
493 }
494 await this._adjustScreenshotCommand(command);
495 }
496 if (utils_2.isBrowserManipulationCommand(command)) {
497 this.browserManipulationQueue.push(command);
498 if (utils_2.isResizeWindowCommand(command) && this.opts.videoPath)
499 this.warningLog.addWarning(warning_message_1.default.videoBrowserResizing, this.test.name);
500 }
501 if (command.type === type_1.default.wait)
502 return delay_1.default(command.timeout);
503 if (command.type === type_1.default.setPageLoadTimeout)
504 return null;
505 if (command.type === type_1.default.debug)
506 return await this._enqueueSetBreakpointCommand(callsite);
507 if (command.type === type_1.default.useRole) {
508 let fn = () => this._useRole(command.role, callsite);
509 fn = this.decoratePreventEmitActionEvents(fn, { prevent: true });
510 fn = this.decorateDisableDebugBreakpoints(fn, { disable: true });
511 return await fn();
512 }
513 if (command.type === type_1.default.assertion)
514 return this._executeAssertion(command, callsite);
515 if (command.type === type_1.default.executeExpression)
516 return await this._executeJsExpression(command, callsite);
517 if (command.type === type_1.default.executeAsyncExpression)
518 return await executeAsyncJsExpression(command.expression, this, callsite);
519 if (command.type === type_1.default.getBrowserConsoleMessages)
520 return await this._enqueueBrowserConsoleMessagesCommand(command, callsite);
521 return this._enqueueCommand(command, callsite);
522 }
523 _rejectCommandWithPageError(callsite) {
524 const err = this.pendingPageError;
525 err.callsite = callsite;
526 this.pendingPageError = null;
527 return Promise.reject(err);
528 }
529 _decorateWithFlag(fn, flagName, value) {
530 return async () => {
531 this[flagName] = value;
532 try {
533 return await fn();
534 }
535 catch (err) {
536 throw err;
537 }
538 finally {
539 this[flagName] = !value;
540 }
541 };
542 }
543 decoratePreventEmitActionEvents(fn, { prevent }) {
544 return this._decorateWithFlag(fn, 'preventEmitActionEvents', prevent);
545 }
546 decorateDisableDebugBreakpoints(fn, { disable }) {
547 return this._decorateWithFlag(fn, 'disableDebugBreakpoints', disable);
548 }
549 // Role management
550 async getStateSnapshot() {
551 const state = this.session.getStateSnapshot();
552 state.storages = await this.executeCommand(new serviceCommands.BackupStoragesCommand());
553 return state;
554 }
555 async switchToCleanRun(url) {
556 this.ctx = Object.create(null);
557 this.fixtureCtx = Object.create(null);
558 this.consoleMessages = new browser_console_messages_1.default();
559 this.session.useStateSnapshot(testcafe_hammerhead_1.StateSnapshot.empty());
560 if (this.speed !== this.opts.speed) {
561 const setSpeedCommand = new actionCommands.SetTestSpeedCommand({ speed: this.opts.speed });
562 await this.executeCommand(setSpeedCommand);
563 }
564 if (this.pageLoadTimeout !== this.opts.pageLoadTimeout) {
565 const setPageLoadTimeoutCommand = new actionCommands.SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout });
566 await this.executeCommand(setPageLoadTimeoutCommand);
567 }
568 await this.navigateToUrl(url, true);
569 if (this.activeDialogHandler) {
570 const removeDialogHandlerCommand = new actionCommands.SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } });
571 await this.executeCommand(removeDialogHandlerCommand);
572 }
573 }
574 async navigateToUrl(url, forceReload, stateSnapshot) {
575 const navigateCommand = new actions_1.NavigateToCommand({ url, forceReload, stateSnapshot });
576 await this.executeCommand(navigateCommand);
577 }
578 async _getStateSnapshotFromRole(role) {
579 const prevPhase = this.phase;
580 this.phase = phase_1.default.inRoleInitializer;
581 if (role.phase === phase_2.default.uninitialized)
582 await role.initialize(this);
583 else if (role.phase === phase_2.default.pendingInitialization)
584 await promisify_event_1.default(role, 'initialized');
585 if (role.initErr)
586 throw role.initErr;
587 this.phase = prevPhase;
588 return role.stateSnapshot;
589 }
590 async _useRole(role, callsite) {
591 if (this.phase === phase_1.default.inRoleInitializer)
592 throw new test_run_1.RoleSwitchInRoleInitializerError(callsite);
593 const bookmark = new TestRunBookmark(this, role);
594 await bookmark.init();
595 if (this.currentRoleId)
596 this.usedRoleStates[this.currentRoleId] = await this.getStateSnapshot();
597 const stateSnapshot = this.usedRoleStates[role.id] || await this._getStateSnapshotFromRole(role);
598 this.session.useStateSnapshot(stateSnapshot);
599 this.currentRoleId = role.id;
600 await bookmark.restore(callsite, stateSnapshot);
601 }
602 // Get current URL
603 async getCurrentUrl() {
604 const builder = new ClientFunctionBuilder(() => {
605 /* eslint-disable no-undef */
606 return window.location.href;
607 /* eslint-enable no-undef */
608 }, { boundTestRun: this });
609 const getLocation = builder.getFunction();
610 return await getLocation();
611 }
612 _disconnect(err) {
613 this.disconnected = true;
614 if (this.currentDriverTask)
615 this._rejectCurrentDriverTask(err);
616 this.emit('disconnected', err);
617 delete test_run_tracker_1.default.activeTestRuns[this.session.id];
618 }
619 async emitActionStart(apiActionName, command) {
620 if (!this.preventEmitActionEvents)
621 await this.emit('action-start', { command, apiActionName });
622 }
623 async emitActionDone(apiActionName, command, errors) {
624 if (!this.preventEmitActionEvents)
625 await this.emit('action-done', { command, apiActionName, errors });
626 }
627}
628exports.default = TestRun;
629// Service message handlers
630const ServiceMessages = TestRun.prototype;
631// NOTE: this function is time-critical and must return ASAP to avoid client disconnection
632ServiceMessages[client_messages_1.default.ready] = function (msg) {
633 this.debugLog.driverMessage(msg);
634 this.emit('connected');
635 this._clearPendingRequest();
636 // NOTE: the driver sends the status for the second time if it didn't get a response at the
637 // first try. This is possible when the page was unloaded after the driver sent the status.
638 if (msg.status.id === this.lastDriverStatusId)
639 return this.lastDriverStatusResponse;
640 this.lastDriverStatusId = msg.status.id;
641 this.lastDriverStatusResponse = this._handleDriverRequest(msg.status);
642 if (this.lastDriverStatusResponse || msg.status.isPendingWindowSwitching)
643 return this.lastDriverStatusResponse;
644 // NOTE: we send an empty response after the MAX_RESPONSE_DELAY timeout is exceeded to keep connection
645 // with the client and prevent the response timeout exception on the client side
646 const responseTimeout = setTimeout(() => this._resolvePendingRequest(null), MAX_RESPONSE_DELAY);
647 return new Promise((resolve, reject) => {
648 this.pendingRequest = { resolve, reject, responseTimeout };
649 });
650};
651ServiceMessages[client_messages_1.default.readyForBrowserManipulation] = async function (msg) {
652 this.debugLog.driverMessage(msg);
653 let result = null;
654 let error = null;
655 try {
656 result = await this.browserManipulationQueue.executePendingManipulation(msg);
657 }
658 catch (err) {
659 error = err;
660 }
661 return { result, error };
662};
663ServiceMessages[client_messages_1.default.waitForFileDownload] = function (msg) {
664 this.debugLog.driverMessage(msg);
665 return new Promise(resolve => {
666 if (this.fileDownloadingHandled) {
667 this.fileDownloadingHandled = false;
668 resolve(true);
669 }
670 else
671 this.resolveWaitForFileDownloadingPromise = resolve;
672 });
673};
674module.exports = exports.default;
675//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC1ydW4vaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsbUNBQTZDO0FBQzdDLDJEQUFzRDtBQUN0RCxzRUFBNkM7QUFDN0Msd0RBQWdDO0FBQ2hDLHVGQUE2RDtBQUM3RCw0REFBMEM7QUFDMUMsaUdBQW9GO0FBQ3BGLHNFQUFxRDtBQUNyRCxrREFLNkI7QUFDN0Isb0RBQTRCO0FBQzVCLHdFQUFnRDtBQUNoRCwyREFBMkM7QUFDM0MsMkRBQW1DO0FBQ25DLG9FQUE0QztBQUM1QywrRUFBcUQ7QUFDckQsMERBQXVDO0FBQ3ZDLDBFQUF5RDtBQUN6RCwwRkFBZ0U7QUFDaEUsdUZBQTJGO0FBQzNGLCtFQUFzRDtBQUN0RCx1RkFBK0Q7QUFDL0QsNkRBQXdFO0FBQ3hFLGdEQUF1RDtBQUN2RCxtRUFBcUQ7QUFDckQsMERBQXdFO0FBQ3hFLCtFQUF3RTtBQUN4RSw0Q0FBK0U7QUFFL0UsNENBUTBCO0FBRTFCLDJDQUFrRDtBQUVsRCxNQUFNLFdBQVcsR0FBbUIsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BFLE1BQU0saUJBQWlCLEdBQWEsV0FBVyxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFDeEUsTUFBTSxxQkFBcUIsR0FBUyxXQUFXLENBQUMsNkNBQTZDLENBQUMsQ0FBQztBQUMvRixNQUFNLHdCQUF3QixHQUFNLFdBQVcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0FBQ2hGLE1BQU0sZUFBZSxHQUFlLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM5RCxNQUFNLGlCQUFpQixHQUFhLFdBQVcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQzFFLE1BQU0sY0FBYyxHQUFnQixXQUFXLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQUN0RSxNQUFNLDJCQUEyQixHQUFHLFdBQVcsQ0FBQyxpQ0FBaUMsQ0FB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QUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDN0IsQ0FBQyxDQUFDO0FBRUYsZUFBZSxDQUFDLHlCQUFlLENBQUMsbUJBQW1CLENBQUMsR0FBRyxVQUFVLEdBQUc7SUFDaEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFakMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN6QixJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUM3QixJQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDO1lBQ3BDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNqQjs7WUFFRyxJQUFJLENBQUMsb0NBQW9DLEdBQUcsT0FBTyxDQUFDO0lBQzVELENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHVsbCwgcmVtb3ZlLCBjaGFpbiB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyByZWFkU3luYyBhcyByZWFkIH0gZnJvbSAncmVhZC1maWxlLXJlbGF0aXZlJztcbmltcG9ydCBwcm9taXNpZnlFdmVudCBmcm9tICdwcm9taXNpZnktZXZlbnQnO1xuaW1wb3J0IE11c3RhY2hlIGZyb20gJ211c3RhY2hlJztcbmltcG9ydCBBc3luY0V2ZW50RW1pdHRlciBmcm9tICcuLi91dGlscy9hc3luYy1ldmVudC1lbWl0dGVyJztcbmltcG9ydCBUZXN0UnVuRGVidWdMb2cgZnJvbSAnLi9kZWJ1Zy1sb2cnO1xuaW1wb3J0IFRlc3RSdW5FcnJvckZvcm1hdHRhYmxlQWRhcHRlciBmcm9tICcuLi9lcnJvcnMvdGVzdC1ydW4vZm9ybWF0dGFibGUtYWRhcHRlcic7XG5pbXBvcnQgVGVzdENhZmVFcnJvckxpc3QgZnJvbSAnLi4vZXJyb3JzL2Vycm9yLWxpc3QnO1xuaW1wb3J0IHtcbiAgICBSZXF1ZXN0SG9va1VuaGFuZGxlZEVycm9yLFxuICAgIFBhZ2VMb2FkRXJyb3IsXG4gICAgUmVxdWVzdEhvb2tOb3RJbXBsZW1lbnRlZE1ldGhvZEVycm9yLFxuICAgIFJvbGVTd2l0Y2hJblJvbGVJbml0aWFsaXplckVycm9yXG59IGZyb20gJy4uL2Vycm9ycy90ZXN0LXJ1bi8nO1xuaW1wb3J0IFBIQVNFIGZyb20gJy4vcGhhc2UnO1xuaW1wb3J0IENMSUVOVF9NRVNTQUdFUyBmcm9tICcuL2NsaWVudC1tZXNzYWdlcyc7XG5pbXBvcnQgQ09NTUFORF9UWVBFIGZyb20gJy4vY29tbWFuZHMvdHlwZSc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vdXRpbHMvZGVsYXknO1xuaW1wb3J0IHRlc3RSdW5NYXJrZXIgZnJvbSAnLi9tYXJrZXItc3ltYm9sJztcbmltcG9ydCB0ZXN0UnVuVHJhY2tlciBmcm9tICcuLi9hcGkvdGVzdC1ydW4tdHJhY2tlcic7XG5pbXBvcnQgUk9MRV9QSEFTRSBmcm9tICcuLi9yb2xlL3BoYXNlJztcbmltcG9ydCBSZXBvcnRlclBsdWdpbkhvc3QgZnJvbSAnLi4vcmVwb3J0ZXIvcGx1Z2luLWhvc3QnO1xuaW1wb3J0IEJyb3dzZXJDb25zb2xlTWVzc2FnZXMgZnJvbSAnLi9icm93c2VyLWNvbnNvbGUtbWVzc2FnZXMnO1xuaW1wb3J0IHsgVU5TVEFCTEVfTkVUV09SS19NT0RFX0hFQURFUiB9IGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbi91bnN0YWJsZS1uZXR3b3JrLW1vZGUnO1xuaW1wb3J0IFdhcm5pbmdMb2cgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLWxvZyc7XG5pbXBvcnQgV0FSTklOR19NRVNTQUdFIGZyb20gJy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1tZXNzYWdlJztcbmltcG9ydCB7IFN0YXRlU25hcHNob3QsIFNQRUNJQUxfRVJST1JfUEFHRSB9IGZyb20gJ3Rlc3RjYWZlLWhhbW1lcmhlYWQnO1xuaW1wb3J0IHsgTmF2aWdhdGVUb0NvbW1hbmQgfSBmcm9tICcuL2NvbW1hbmRzL2FjdGlvbnMnO1xuaW1wb3J0ICogYXMgSU5KRUNUQUJMRVMgZnJvbSAnLi4vYXNzZXRzL2luamVjdGFibGVzJztcbmltcG9ydCB7IGZpbmRQcm9ibGVtYXRpY1NjcmlwdHMgfSBmcm9tICcuLi9jdXN0b20tY2xpZW50LXNjcmlwdHMvdXRpbHMnO1xuaW1wb3J0IGdldEN1c3RvbUNsaWVudFNjcmlwdFVybCBmcm9tICcuLi9jdXN0b20tY2xpZW50LXNjcmlwdHMvZ2V0LXVybCc7XG5pbXBvcnQgeyBnZXRQbHVyYWxTdWZmaXgsIGdldENvbmNhdGVuYXRlZFZhbHVlc1N0cmluZyB9IGZyb20gJy4uL3V0aWxzL3N0cmluZyc7XG5cbmltcG9ydCB7XG4gICAgaXNDb21tYW5kUmVqZWN0YWJsZUJ5UGFnZUVycm9yLFxuICAgIGlzQnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmQsXG4gICAgaXNTY3JlZW5zaG90Q29tbWFuZCxcbiAgICBpc1NlcnZpY2VDb21tYW5kLFxuICAgIGNhblNldERlYnVnZ2VyQnJlYWtwb2ludEJlZm9yZUNvbW1hbmQsXG4gICAgaXNFeGVjdXRhYmxlT25DbGllbnRDb21tYW5kLFxuICAgIGlzUmVzaXplV2luZG93Q29tbWFuZFxufSBmcm9tICcuL2NvbW1hbmRzL3V0aWxzJztcblxuaW1wb3J0IHsgVEVTVF9SVU5fRVJST1JTIH0gZnJvbSAnLi4vZXJyb3JzL3R5cGVzJztcblxuY29uc3QgbGF6eVJlcXVpcmUgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnaW1wb3J0LWxhenknKShyZXF1aXJlKTtcbmNvbnN0IFNlc3Npb25Db250cm9sbGVyICAgICAgICAgICA9IGxhenlSZXF1aXJlKCcuL3Nlc3Npb24tY29udHJvbGxlcicpO1xuY29uc3QgQ2xpZW50RnVuY3Rpb25CdWlsZGVyICAgICAgID0gbGF6eVJlcXVpcmUoJy4uL2NsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXInKTtcbmNvbnN0IEJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZSAgICA9IGxhenlSZXF1aXJlKCcuL2Jyb3dzZXItbWFuaXB1bGF0aW9uLXF1ZXVlJyk7XG5jb25zdCBUZXN0UnVuQm9va21hcmsgICAgICAgICAgICAgPSBsYXp5UmVxdWlyZSgnLi9ib29rbWFyaycpO1xuY29uc3QgQXNzZXJ0aW9uRXhlY3V0b3IgICAgICAgICAgID0gbGF6eVJlcXVpcmUoJy4uL2Fzc2VydGlvbnMvZXhlY3V0b3InKTtcbmNvbnN0IGFjdGlvbkNvbW1hbmRzICAgICAgICAgICAgICA9IGxhenlSZXF1aXJlKCcuL2NvbW1hbmRzL2FjdGlvbnMnKTtcbmNvbnN0IGJyb3dzZXJNYW5pcHVsYXRpb25Db21tYW5kcyA9IGxhenlSZXF1aXJlKCcuL2NvbW1hbmRzL2Jyb3dzZXItbWFuaXB1bGF0aW9uJyk7XG5jb25zdCBzZXJ2aWNlQ29tbWFuZHMgICAgICAgICAgICAgPSBsYXp5UmVxdWlyZSgnLi9jb21tYW5kcy9zZXJ2aWNlJyk7XG5cbmNvbnN0IHsgZXhlY3V0ZUpzRXhwcmVzc2lvbiwgZXhlY3V0ZUFzeW5jSnNFeHByZXNzaW9uIH0gPSBsYXp5UmVxdWlyZSgnLi9leGVjdXRlLWpzLWV4cHJlc3Npb24nKTtcblxuY29uc3QgVEVTVF9SVU5fVEVNUExBVEUgICAgICAgICAgICAgICA9IHJlYWQoJy4uL2NsaWVudC90ZXN0LXJ1bi9pbmRleC5qcy5tdXN0YWNoZScpO1xuY29uc3QgSUZSQU1FX1RFU1RfUlVOX1RFTVBMQVRFICAgICAgICA9IHJlYWQoJy4uL2NsaWVudC90ZXN0LXJ1bi9pZnJhbWUuanMubXVzdGFjaGUnKTtcbmNvbnN0IFRFU1RfRE9ORV9DT05GSVJNQVRJT05fUkVTUE9OU0UgPSAndGVzdC1kb25lLWNvbmZpcm1hdGlvbic7XG5jb25zdCBNQVhfUkVTUE9OU0VfREVMQVkgICAgICAgICAgICAgID0gMzAwMDtcbmNvbnN0IENISUxEX1dJTkRPV19SRUFEWV9USU1FT1VUICAgICAgPSAzMCAqIDEwMDA7XG5cbmNvbnN0IEFMTF9EUklWRVJfVEFTS1NfQURERURfVE9fUVVFVUVfRVZFTlQgPSAnYWxsLWRyaXZlci10YXNrcy1hZGRlZC10by1xdWV1ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RSdW4gZXh0ZW5kcyBBc3luY0V2ZW50RW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IgKHRlc3QsIGJyb3dzZXJDb25uZWN0aW9uLCBzY3JlZW5zaG90Q2FwdHVyZXIsIGdsb2JhbFdhcm5pbmdMb2csIG9wdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW3Rlc3RSdW5NYXJrZXJdID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLndhcm5pbmdMb2cgPSBuZXcgV2FybmluZ0xvZyhnbG9iYWxXYXJuaW5nTG9nKTtcblxuICAgICAgICB0aGlzLm9wdHMgICAgICAgICAgICAgID0gb3B0cztcbiAgICAgICAgdGhpcy50ZXN0ICAgICAgICAgICAgICA9IHRlc3Q7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb24gPSBicm93c2VyQ29ubmVjdGlvbjtcblxuICAgICAgICB0aGlzLnBoYXNlID0gUEhBU0UuaW5pdGlhbDtcblxuICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZSAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLnRlc3REb25lQ29tbWFuZFF1ZXVlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuYWN0aXZlRGlhbG9nSGFuZGxlciAgPSBudWxsO1xuICAgICAgICB0aGlzLmFjdGl2ZUlmcmFtZVNlbGVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5zcGVlZCAgICAgICAgICAgICAgICA9IHRoaXMub3B0cy5zcGVlZDtcbiAgICAgICAgdGhpcy5wYWdlTG9hZFRpbWVvdXQgICAgICA9IHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQ7XG5cbiAgICAgICAgdGhpcy5kaXNhYmxlUGFnZVJlbG9hZHMgICA9IHRlc3QuZGlzYWJsZVBhZ2VSZWxvYWRzIHx8IG9wdHMuZGlzYWJsZVBhZ2VSZWxvYWRzICYmIHRlc3QuZGlzYWJsZVBhZ2VSZWxvYWRzICE9PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2U7XG4gICAgICAgIHRoaXMuZGlzYWJsZVBhZ2VDYWNoaW5nICAgPSB0ZXN0LmRpc2FibGVQYWdlQ2FjaGluZyB8fCBvcHRzLmRpc2FibGVQYWdlQ2FjaGluZztcbiAgICAgICAgdGhpcy5hbGxvd011bHRpcGxlV2luZG93cyA9IG9wdHMuYWxsb3dNdWx0aXBsZVdpbmRvd3M7XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uID0gU2Vzc2lvbkNvbnRyb2xsZXIuZ2V0U2Vzc2lvbih0aGlzKTtcblxuICAgICAgICB0aGlzLmNvbnNvbGVNZXNzYWdlcyA9IG5ldyBCcm93c2VyQ29uc29sZU1lc3NhZ2VzKCk7XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdCAgID0gbnVsbDtcbiAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbnVsbDtcblxuICAgICAgICB0aGlzLmNvbnRyb2xsZXIgPSBudWxsO1xuICAgICAgICB0aGlzLmN0eCAgICAgICAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmZpeHR1cmVDdHggPSBudWxsO1xuXG4gICAgICAgIHRoaXMuY3VycmVudFJvbGVJZCAgPSBudWxsO1xuICAgICAgICB0aGlzLnVzZWRSb2xlU3RhdGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgICB0aGlzLmVycnMgPSBbXTtcblxuICAgICAgICB0aGlzLmxhc3REcml2ZXJTdGF0dXNJZCAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMubGFzdERyaXZlclN0YXR1c1Jlc3BvbnNlID0gbnVsbDtcblxuICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgICAgICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50ID0gMDtcblxuICAgICAgICB0aGlzLmRlYnVnZ2luZyAgICAgICAgICAgICAgID0gdGhpcy5vcHRzLmRlYnVnTW9kZTtcbiAgICAgICAgdGhpcy5kZWJ1Z09uRmFpbCAgICAgICAgICAgICA9IHRoaXMub3B0cy5kZWJ1Z09uRmFpbDtcbiAgICAgICAgdGhpcy5kaXNhYmxlRGVidWdCcmVha3BvaW50cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRlYnVnUmVwb3J0ZXJQbHVnaW5Ib3N0ID0gbmV3IFJlcG9ydGVyUGx1Z2luSG9zdCh7IG5vQ29sb3JzOiBmYWxzZSB9KTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZSA9IG5ldyBCcm93c2VyTWFuaXB1bGF0aW9uUXVldWUoYnJvd3NlckNvbm5lY3Rpb24sIHNjcmVlbnNob3RDYXB0dXJlciwgdGhpcy53YXJuaW5nTG9nKTtcblxuICAgICAgICB0aGlzLmRlYnVnTG9nID0gbmV3IFRlc3RSdW5EZWJ1Z0xvZyh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnVzZXJBZ2VudCk7XG5cbiAgICAgICAgdGhpcy5xdWFyYW50aW5lICA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlciA9IHRoaXMub3B0cy5kZWJ1Z0xvZ2dlcjtcblxuICAgICAgICB0aGlzLl9hZGRJbmplY3RhYmxlcygpO1xuICAgICAgICB0aGlzLl9pbml0UmVxdWVzdEhvb2tzKCk7XG4gICAgfVxuXG4gICAgX2FkZENsaWVudFNjcmlwdENvbnRlbnRXYXJuaW5nc0lmTmVjZXNzYXJ5ICgpIHtcbiAgICAgICAgY29uc3QgeyBlbXB0eSwgZHVwbGljYXRlZENvbnRlbnQgfSA9IGZpbmRQcm9ibGVtYXRpY1NjcmlwdHModGhpcy50ZXN0LmNsaWVudFNjcmlwdHMpO1xuXG4gICAgICAgIGlmIChlbXB0eS5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UuY2xpZW50U2NyaXB0c1dpdGhFbXB0eUNvbnRlbnQpO1xuXG4gICAgICAgIGlmIChkdXBsaWNhdGVkQ29udGVudC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1ZmZpeCAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGdldFBsdXJhbFN1ZmZpeChkdXBsaWNhdGVkQ29udGVudCk7XG4gICAgICAgICAgICBjb25zdCBkdXBsaWNhdGVkQ29udGVudENsaWVudFNjcmlwdHNTdHIgPSBnZXRDb25jYXRlbmF0ZWRWYWx1ZXNTdHJpbmcoZHVwbGljYXRlZENvbnRlbnQsICcsXFxuICcpO1xuXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UuY2xpZW50U2NyaXB0c1dpdGhEdXBsaWNhdGVkQ29udGVudCwgc3VmZml4LCBkdXBsaWNhdGVkQ29udGVudENsaWVudFNjcmlwdHNTdHIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FkZEluamVjdGFibGVzICgpIHtcbiAgICAgICAgdGhpcy5fYWRkQ2xpZW50U2NyaXB0Q29udGVudFdhcm5pbmdzSWZOZWNlc3NhcnkoKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnNjcmlwdHMucHVzaCguLi5JTkpFQ1RBQkxFUy5TQ1JJUFRTKTtcbiAgICAgICAgdGhpcy5pbmplY3RhYmxlLnVzZXJTY3JpcHRzLnB1c2goLi4udGhpcy50ZXN0LmNsaWVudFNjcmlwdHMubWFwKHNjcmlwdCA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHVybDogIGdldEN1c3RvbUNsaWVudFNjcmlwdFVybChzY3JpcHQpLFxuICAgICAgICAgICAgICAgIHBhZ2U6IHNjcmlwdC5wYWdlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuaW5qZWN0YWJsZS5zdHlsZXMucHVzaChJTkpFQ1RBQkxFUy5URVNUQ0FGRV9VSV9TVFlMRVMpO1xuICAgIH1cblxuICAgIGdldCBpZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlc3Npb24uaWQ7XG4gICAgfVxuXG4gICAgZ2V0IGluamVjdGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLmluamVjdGFibGU7XG4gICAgfVxuXG4gICAgYWRkUXVhcmFudGluZUluZm8gKHF1YXJhbnRpbmUpIHtcbiAgICAgICAgdGhpcy5xdWFyYW50aW5lID0gcXVhcmFudGluZTtcbiAgICB9XG5cbiAgICBhZGRSZXF1ZXN0SG9vayAoaG9vaykge1xuICAgICAgICBpZiAodGhpcy5yZXF1ZXN0SG9va3MuaW5kZXhPZihob29rKSAhPT0gLTEpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5yZXF1ZXN0SG9va3MucHVzaChob29rKTtcbiAgICAgICAgdGhpcy5faW5pdFJlcXVlc3RIb29rKGhvb2spO1xuICAgIH1cblxuICAgIHJlbW92ZVJlcXVlc3RIb29rIChob29rKSB7XG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3RIb29rcy5pbmRleE9mKGhvb2spID09PSAtMSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBwdWxsKHRoaXMucmVxdWVzdEhvb2tzLCBob29rKTtcbiAgICAgICAgdGhpcy5fZGlzcG9zZVJlcXVlc3RIb29rKGhvb2spO1xuICAgIH1cblxuICAgIF9pbml0UmVxdWVzdEhvb2sgKGhvb2spIHtcbiAgICAgICAgaG9vay53YXJuaW5nTG9nID0gdGhpcy53YXJuaW5nTG9nO1xuXG4gICAgICAgIGhvb2suX2luc3RhbnRpYXRlUmVxdWVzdEZpbHRlclJ1bGVzKCk7XG4gICAgICAgIGhvb2suX2luc3RhbnRpYXRlZFJlcXVlc3RGaWx0ZXJSdWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmFkZFJlcXVlc3RFdmVudExpc3RlbmVycyhydWxlLCB7XG4gICAgICAgICAgICAgICAgb25SZXF1ZXN0OiAgICAgICAgICAgaG9vay5vblJlcXVlc3QuYmluZChob29rKSxcbiAgICAgICAgICAgICAgICBvbkNvbmZpZ3VyZVJlc3BvbnNlOiBob29rLl9vbkNvbmZpZ3VyZVJlc3BvbnNlLmJpbmQoaG9vayksXG4gICAgICAgICAgICAgICAgb25SZXNwb25zZTogICAgICAgICAgaG9vay5vblJlc3BvbnNlLmJpbmQoaG9vaylcbiAgICAgICAgICAgIH0sIGVyciA9PiB0aGlzLl9vblJlcXVlc3RIb29rTWV0aG9kRXJyb3IoZXJyLCBob29rKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9vblJlcXVlc3RIb29rTWV0aG9kRXJyb3IgKGV2ZW50LCBob29rKSB7XG4gICAgICAgIGxldCBlcnIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gZXZlbnQuZXJyb3I7XG4gICAgICAgIGNvbnN0IGlzUmVxdWVzdEhvb2tOb3RJbXBsZW1lbnRlZE1ldGhvZEVycm9yID0gZXJyIGluc3RhbmNlb2YgUmVxdWVzdEhvb2tOb3RJbXBsZW1lbnRlZE1ldGhvZEVycm9yO1xuXG4gICAgICAgIGlmICghaXNSZXF1ZXN0SG9va05vdEltcGxlbWVudGVkTWV0aG9kRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGhvb2tDbGFzc05hbWUgPSBob29rLmNvbnN0cnVjdG9yLm5hbWU7XG5cbiAgICAgICAgICAgIGVyciA9IG5ldyBSZXF1ZXN0SG9va1VuaGFuZGxlZEVycm9yKGVyciwgaG9va0NsYXNzTmFtZSwgZXZlbnQubWV0aG9kTmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFkZEVycm9yKGVycik7XG4gICAgfVxuXG4gICAgX2Rpc3Bvc2VSZXF1ZXN0SG9vayAoaG9vaykge1xuICAgICAgICBob29rLndhcm5pbmdMb2cgPSBudWxsO1xuXG4gICAgICAgIGhvb2suX2luc3RhbnRpYXRlZFJlcXVlc3RGaWx0ZXJSdWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVycyhydWxlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2luaXRSZXF1ZXN0SG9va3MgKCkge1xuICAgICAgICB0aGlzLnJlcXVlc3RIb29rcyA9IEFycmF5LmZyb20odGhpcy50ZXN0LnJlcXVlc3RIb29rcyk7XG5cbiAgICAgICAgdGhpcy5yZXF1ZXN0SG9va3MuZm9yRWFjaChob29rID0+IHRoaXMuX2luaXRSZXF1ZXN0SG9vayhob29rKSk7XG4gICAgfVxuXG4gICAgLy8gSGFtbWVyaGVhZCBwYXlsb2FkXG4gICAgX2dldFBheWxvYWRTY3JpcHQgKCkge1xuICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgICAgICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSA9IG51bGw7XG5cbiAgICAgICAgcmV0dXJuIE11c3RhY2hlLnJlbmRlcihURVNUX1JVTl9URU1QTEFURSwge1xuICAgICAgICAgICAgdGVzdFJ1bklkOiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5zZXNzaW9uLmlkKSxcbiAgICAgICAgICAgIGJyb3dzZXJJZDogICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uaWQpLFxuICAgICAgICAgICAgYnJvd3NlckhlYXJ0YmVhdFJlbGF0aXZlVXJsOiAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi5oZWFydGJlYXRSZWxhdGl2ZVVybCksXG4gICAgICAgICAgICBicm93c2VyU3RhdHVzUmVsYXRpdmVVcmw6ICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnN0YXR1c1JlbGF0aXZlVXJsKSxcbiAgICAgICAgICAgIGJyb3dzZXJTdGF0dXNEb25lUmVsYXRpdmVVcmw6IEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uc3RhdHVzRG9uZVJlbGF0aXZlVXJsKSxcbiAgICAgICAgICAgIGJyb3dzZXJBY3RpdmVXaW5kb3dJZFVybDogICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uYWN0aXZlV2luZG93SWRVcmwpLFxuICAgICAgICAgICAgdXNlckFnZW50OiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5icm93c2VyQ29ubmVjdGlvbi51c2VyQWdlbnQpLFxuICAgICAgICAgICAgdGVzdE5hbWU6ICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy50ZXN0Lm5hbWUpLFxuICAgICAgICAgICAgZml4dHVyZU5hbWU6ICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy50ZXN0LmZpeHR1cmUubmFtZSksXG4gICAgICAgICAgICBzZWxlY3RvclRpbWVvdXQ6ICAgICAgICAgICAgICB0aGlzLm9wdHMuc2VsZWN0b3JUaW1lb3V0LFxuICAgICAgICAgICAgcGFnZUxvYWRUaW1lb3V0OiAgICAgICAgICAgICAgdGhpcy5wYWdlTG9hZFRpbWVvdXQsXG4gICAgICAgICAgICBjaGlsZFdpbmRvd1JlYWR5VGltZW91dDogICAgICBDSElMRF9XSU5ET1dfUkVBRFlfVElNRU9VVCxcbiAgICAgICAgICAgIHNraXBKc0Vycm9yczogICAgICAgICAgICAgICAgIHRoaXMub3B0cy5za2lwSnNFcnJvcnMsXG4gICAgICAgICAgICByZXRyeVRlc3RQYWdlczogICAgICAgICAgICAgICB0aGlzLm9wdHMucmV0cnlUZXN0UGFnZXMsXG4gICAgICAgICAgICBzcGVlZDogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVkLFxuICAgICAgICAgICAgZGlhbG9nSGFuZGxlcjogICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5hY3RpdmVEaWFsb2dIYW5kbGVyKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfZ2V0SWZyYW1lUGF5bG9hZFNjcmlwdCAoKSB7XG4gICAgICAgIHJldHVybiBNdXN0YWNoZS5yZW5kZXIoSUZSQU1FX1RFU1RfUlVOX1RFTVBMQVRFLCB7XG4gICAgICAgICAgICB0ZXN0UnVuSWQ6ICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuc2Vzc2lvbi5pZCksXG4gICAgICAgICAgICBzZWxlY3RvclRpbWVvdXQ6IHRoaXMub3B0cy5zZWxlY3RvclRpbWVvdXQsXG4gICAgICAgICAgICBwYWdlTG9hZFRpbWVvdXQ6IHRoaXMucGFnZUxvYWRUaW1lb3V0LFxuICAgICAgICAgICAgcmV0cnlUZXN0UGFnZXM6ICAhIXRoaXMub3B0cy5yZXRyeVRlc3RQYWdlcyxcbiAgICAgICAgICAgIHNwZWVkOiAgICAgICAgICAgdGhpcy5zcGVlZCxcbiAgICAgICAgICAgIGRpYWxvZ0hhbmRsZXI6ICAgSlNPTi5zdHJpbmdpZnkodGhpcy5hY3RpdmVEaWFsb2dIYW5kbGVyKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBIYW1tZXJoZWFkIGhhbmRsZXJzXG4gICAgZ2V0QXV0aENyZWRlbnRpYWxzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdC5hdXRoQ3JlZGVudGlhbHM7XG4gICAgfVxuXG4gICAgaGFuZGxlRmlsZURvd25sb2FkICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlKSB7XG4gICAgICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSh0cnVlKTtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZVdhaXRGb3JGaWxlRG93bmxvYWRpbmdQcm9taXNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGhhbmRsZVBhZ2VFcnJvciAoY3R4LCBlcnIpIHtcbiAgICAgICAgaWYgKGN0eC5yZXEuaGVhZGVyc1tVTlNUQUJMRV9ORVRXT1JLX01PREVfSEVBREVSXSkge1xuICAgICAgICAgICAgY3R4LmNsb3NlV2l0aEVycm9yKDUwMCwgZXJyLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbmV3IFBhZ2VMb2FkRXJyb3IoZXJyLCBjdHgucmVxT3B0cy51cmwpO1xuXG4gICAgICAgIGN0eC5yZWRpcmVjdChjdHgudG9Qcm94eVVybChTUEVDSUFMX0VSUk9SX1BBR0UpKTtcbiAgICB9XG5cbiAgICAvLyBUZXN0IGZ1bmN0aW9uIGV4ZWN1dGlvblxuICAgIGFzeW5jIF9leGVjdXRlVGVzdEZuIChwaGFzZSwgZm4pIHtcbiAgICAgICAgdGhpcy5waGFzZSA9IHBoYXNlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBmbih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBsZXQgc2NyZWVuc2hvdFBhdGggPSBudWxsO1xuXG4gICAgICAgICAgICBjb25zdCB7IHNjcmVlbnNob3RzIH0gPSB0aGlzLm9wdHM7XG5cbiAgICAgICAgICAgIGlmIChzY3JlZW5zaG90cyAmJiBzY3JlZW5zaG90cy50YWtlT25GYWlscylcbiAgICAgICAgICAgICAgICBzY3JlZW5zaG90UGF0aCA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQobmV3IGJyb3dzZXJNYW5pcHVsYXRpb25Db21tYW5kcy5UYWtlU2NyZWVuc2hvdE9uRmFpbENvbW1hbmQoKSk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkRXJyb3IoZXJyLCBzY3JlZW5zaG90UGF0aCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gIXRoaXMuX2FkZFBlbmRpbmdQYWdlRXJyb3JJZkFueSgpO1xuICAgIH1cblxuICAgIGFzeW5jIF9ydW5CZWZvcmVIb29rICgpIHtcbiAgICAgICAgaWYgKHRoaXMudGVzdC5iZWZvcmVGbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9leGVjdXRlVGVzdEZuKFBIQVNFLmluVGVzdEJlZm9yZUhvb2ssIHRoaXMudGVzdC5iZWZvcmVGbik7XG5cbiAgICAgICAgaWYgKHRoaXMudGVzdC5maXh0dXJlLmJlZm9yZUVhY2hGbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9leGVjdXRlVGVzdEZuKFBIQVNFLmluRml4dHVyZUJlZm9yZUVhY2hIb29rLCB0aGlzLnRlc3QuZml4dHVyZS5iZWZvcmVFYWNoRm4pO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGFzeW5jIF9ydW5BZnRlckhvb2sgKCkge1xuICAgICAgICBpZiAodGhpcy50ZXN0LmFmdGVyRm4pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZXhlY3V0ZVRlc3RGbihQSEFTRS5pblRlc3RBZnRlckhvb2ssIHRoaXMudGVzdC5hZnRlckZuKTtcblxuICAgICAgICBpZiAodGhpcy50ZXN0LmZpeHR1cmUuYWZ0ZXJFYWNoRm4pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZXhlY3V0ZVRlc3RGbihQSEFTRS5pbkZpeHR1cmVBZnRlckVhY2hIb29rLCB0aGlzLnRlc3QuZml4dHVyZS5hZnRlckVhY2hGbik7XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgYXN5bmMgc3RhcnQgKCkge1xuICAgICAgICB0ZXN0UnVuVHJhY2tlci5hY3RpdmVUZXN0UnVuc1t0aGlzLnNlc3Npb24uaWRdID0gdGhpcztcblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3N0YXJ0Jyk7XG5cbiAgICAgICAgY29uc3Qgb25EaXNjb25uZWN0ZWQgPSBlcnIgPT4gdGhpcy5fZGlzY29ubmVjdChlcnIpO1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb24ub25jZSgnZGlzY29ubmVjdGVkJywgb25EaXNjb25uZWN0ZWQpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMub25jZSgnY29ubmVjdGVkJyk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdyZWFkeScpO1xuXG4gICAgICAgIGlmIChhd2FpdCB0aGlzLl9ydW5CZWZvcmVIb29rKCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2V4ZWN1dGVUZXN0Rm4oUEhBU0UuaW5UZXN0LCB0aGlzLnRlc3QuZm4pO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fcnVuQWZ0ZXJIb29rKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kaXNjb25uZWN0ZWQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbi5yZW1vdmVMaXN0ZW5lcignZGlzY29ubmVjdGVkJywgb25EaXNjb25uZWN0ZWQpO1xuXG4gICAgICAgIGlmICh0aGlzLmVycnMubGVuZ3RoICYmIHRoaXMuZGVidWdPbkZhaWwpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbnF1ZXVlU2V0QnJlYWtwb2ludENvbW1hbmQobnVsbCwgdGhpcy5kZWJ1Z1JlcG9ydGVyUGx1Z2luSG9zdC5mb3JtYXRFcnJvcih0aGlzLmVycnNbMF0pKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ2JlZm9yZS1kb25lJyk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLlRlc3REb25lQ29tbWFuZCgpKTtcblxuICAgICAgICB0aGlzLl9hZGRQZW5kaW5nUGFnZUVycm9ySWZBbnkoKTtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmNsZWFyUmVxdWVzdEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgICAgIHRoaXMubm9ybWFsaXplUmVxdWVzdEhvb2tFcnJvcnMoKTtcblxuICAgICAgICBkZWxldGUgdGVzdFJ1blRyYWNrZXIuYWN0aXZlVGVzdFJ1bnNbdGhpcy5zZXNzaW9uLmlkXTtcblxuICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ2RvbmUnKTtcbiAgICB9XG5cbiAgICAvLyBFcnJvcnNcbiAgICBfYWRkUGVuZGluZ1BhZ2VFcnJvcklmQW55ICgpIHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ1BhZ2VFcnJvcikge1xuICAgICAgICAgICAgdGhpcy5hZGRFcnJvcih0aGlzLnBlbmRpbmdQYWdlRXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIF9jcmVhdGVFcnJvckFkYXB0ZXIgKGVyciwgc2NyZWVuc2hvdFBhdGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXN0UnVuRXJyb3JGb3JtYXR0YWJsZUFkYXB0ZXIoZXJyLCB7XG4gICAgICAgICAgICB1c2VyQWdlbnQ6ICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbi51c2VyQWdlbnQsXG4gICAgICAgICAgICBzY3JlZW5zaG90UGF0aDogc2NyZWVuc2hvdFBhdGggfHwgJycsXG4gICAgICAgICAgICB0ZXN0UnVuUGhhc2U6ICAgdGhpcy5waGFzZVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRFcnJvciAoZXJyLCBzY3JlZW5zaG90UGF0aCkge1xuICAgICAgICBjb25zdCBlcnJMaXN0ID0gZXJyIGluc3RhbmNlb2YgVGVzdENhZmVFcnJvckxpc3QgPyBlcnIuaXRlbXMgOiBbZXJyXTtcblxuICAgICAgICBlcnJMaXN0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5fY3JlYXRlRXJyb3JBZGFwdGVyKGl0ZW0sIHNjcmVlbnNob3RQYXRoKTtcblxuICAgICAgICAgICAgdGhpcy5lcnJzLnB1c2goYWRhcHRlcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5vcm1hbGl6ZVJlcXVlc3RIb29rRXJyb3JzICgpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdEhvb2tFcnJvcnMgPSByZW1vdmUodGhpcy5lcnJzLCBlID0+XG4gICAgICAgICAgICBlLmNvZGUgPT09IFRFU1RfUlVOX0VSUk9SUy5yZXF1ZXN0SG9va05vdEltcGxlbWVudGVkRXJyb3IgfHxcbiAgICAgICAgICAgIGUuY29kZSA9PT0gVEVTVF9SVU5fRVJST1JTLnJlcXVlc3RIb29rVW5oYW5kbGVkRXJyb3IpO1xuXG4gICAgICAgIGlmICghcmVxdWVzdEhvb2tFcnJvcnMubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHVuaXFSZXF1ZXN0SG9va0Vycm9ycyA9IGNoYWluKHJlcXVlc3RIb29rRXJyb3JzKVxuICAgICAgICAgICAgLnVuaXFCeShlID0+IGUuaG9va0NsYXNzTmFtZSArIGUubWV0aG9kTmFtZSlcbiAgICAgICAgICAgIC5zb3J0QnkoWydob29rQ2xhc3NOYW1lJywgJ21ldGhvZE5hbWUnXSlcbiAgICAgICAgICAgIC52YWx1ZSgpO1xuXG4gICAgICAgIHRoaXMuZXJycyA9IHRoaXMuZXJycy5jb25jYXQodW5pcVJlcXVlc3RIb29rRXJyb3JzKTtcbiAgICB9XG5cbiAgICAvLyBUYXNrIHF1ZXVlXG4gICAgX2VucXVldWVDb21tYW5kIChjb21tYW5kLCBjYWxsc2l0ZSkge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nUmVxdWVzdClcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVQZW5kaW5nUmVxdWVzdChjb21tYW5kKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50LS07XG4gICAgICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZS5wdXNoKHsgY29tbWFuZCwgcmVzb2x2ZSwgcmVqZWN0LCBjYWxsc2l0ZSB9KTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmFkZGluZ0RyaXZlclRhc2tzQ291bnQpXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KEFMTF9EUklWRVJfVEFTS1NfQURERURfVE9fUVVFVUVfRVZFTlQsIHRoaXMuZHJpdmVyVGFza1F1ZXVlLmxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldCBkcml2ZXJUYXNrUXVldWVMZW5ndGggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50ID8gcHJvbWlzaWZ5RXZlbnQodGhpcywgQUxMX0RSSVZFUl9UQVNLU19BRERFRF9UT19RVUVVRV9FVkVOVCkgOiBQcm9taXNlLnJlc29sdmUodGhpcy5kcml2ZXJUYXNrUXVldWUubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBhc3luYyBfZW5xdWV1ZUJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kIChjb21tYW5kLCBjYWxsc2l0ZSkge1xuICAgICAgICBhd2FpdCB0aGlzLl9lbnF1ZXVlQ29tbWFuZChjb21tYW5kLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgY29uc3QgY29uc29sZU1lc3NhZ2VDb3B5ID0gdGhpcy5jb25zb2xlTWVzc2FnZXMuZ2V0Q29weSgpO1xuXG4gICAgICAgIHJldHVybiBjb25zb2xlTWVzc2FnZUNvcHlbdGhpcy5icm93c2VyQ29ubmVjdGlvbi5hY3RpdmVXaW5kb3dJZF07XG4gICAgfVxuXG4gICAgYXN5bmMgX2VucXVldWVTZXRCcmVha3BvaW50Q29tbWFuZCAoY2FsbHNpdGUsIGVycm9yKSB7XG4gICAgICAgIGlmICh0aGlzLmJyb3dzZXJDb25uZWN0aW9uLmlzSGVhZGxlc3NCcm93c2VyKCkpIHtcbiAgICAgICAgICAgIHRoaXMud2FybmluZ0xvZy5hZGRXYXJuaW5nKFdBUk5JTkdfTUVTU0FHRS5kZWJ1Z0luSGVhZGxlc3NFcnJvcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kZWJ1Z0xvZ2dlcilcbiAgICAgICAgICAgIHRoaXMuZGVidWdMb2dnZXIuc2hvd0JyZWFrcG9pbnQodGhpcy5zZXNzaW9uLmlkLCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnVzZXJBZ2VudCwgY2FsbHNpdGUsIGVycm9yKTtcblxuICAgICAgICB0aGlzLmRlYnVnZ2luZyA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQobmV3IHNlcnZpY2VDb21tYW5kcy5TZXRCcmVha3BvaW50Q29tbWFuZCghIWVycm9yKSwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIF9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MgKCkge1xuICAgICAgICB0aGlzLmRyaXZlclRhc2tRdWV1ZSA9IHRoaXMuZHJpdmVyVGFza1F1ZXVlLmZpbHRlcihkcml2ZXJUYXNrID0+IGlzU2VydmljZUNvbW1hbmQoZHJpdmVyVGFzay5jb21tYW5kKSk7XG5cbiAgICAgICAgdGhpcy5icm93c2VyTWFuaXB1bGF0aW9uUXVldWUucmVtb3ZlQWxsTm9uU2VydmljZU1hbmlwdWxhdGlvbnMoKTtcbiAgICB9XG5cbiAgICAvLyBDdXJyZW50IGRyaXZlciB0YXNrXG4gICAgZ2V0IGN1cnJlbnREcml2ZXJUYXNrICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZHJpdmVyVGFza1F1ZXVlWzBdO1xuICAgIH1cblxuICAgIF9yZXNvbHZlQ3VycmVudERyaXZlclRhc2sgKHJlc3VsdCkge1xuICAgICAgICB0aGlzLmN1cnJlbnREcml2ZXJUYXNrLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgdGhpcy5kcml2ZXJUYXNrUXVldWUuc2hpZnQoKTtcblxuICAgICAgICBpZiAodGhpcy50ZXN0RG9uZUNvbW1hbmRRdWV1ZWQpXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MoKTtcbiAgICB9XG5cbiAgICBfcmVqZWN0Q3VycmVudERyaXZlclRhc2sgKGVycikge1xuICAgICAgICBlcnIuY2FsbHNpdGUgPSBlcnIuY2FsbHNpdGUgfHwgdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jYWxsc2l0ZTtcblxuICAgICAgICB0aGlzLmN1cnJlbnREcml2ZXJUYXNrLnJlamVjdChlcnIpO1xuICAgICAgICB0aGlzLl9yZW1vdmVBbGxOb25TZXJ2aWNlVGFza3MoKTtcbiAgICB9XG5cbiAgICAvLyBQZW5kaW5nIHJlcXVlc3RcbiAgICBfY2xlYXJQZW5kaW5nUmVxdWVzdCAoKSB7XG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdSZXF1ZXN0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZW5kaW5nUmVxdWVzdC5yZXNwb25zZVRpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcmVzb2x2ZVBlbmRpbmdSZXF1ZXN0IChjb21tYW5kKSB7XG4gICAgICAgIHRoaXMubGFzdERyaXZlclN0YXR1c1Jlc3BvbnNlID0gY29tbWFuZDtcbiAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdC5yZXNvbHZlKGNvbW1hbmQpO1xuICAgICAgICB0aGlzLl9jbGVhclBlbmRpbmdSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGRyaXZlciByZXF1ZXN0XG4gICAgX2Z1bGZpbGxDdXJyZW50RHJpdmVyVGFzayAoZHJpdmVyU3RhdHVzKSB7XG4gICAgICAgIGlmICghdGhpcy5jdXJyZW50RHJpdmVyVGFzaylcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBpZiAoZHJpdmVyU3RhdHVzLmV4ZWN1dGlvbkVycm9yKVxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0Q3VycmVudERyaXZlclRhc2soZHJpdmVyU3RhdHVzLmV4ZWN1dGlvbkVycm9yKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUN1cnJlbnREcml2ZXJUYXNrKGRyaXZlclN0YXR1cy5yZXN1bHQpO1xuICAgIH1cblxuICAgIF9oYW5kbGVQYWdlRXJyb3JTdGF0dXMgKHBhZ2VFcnJvcikge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RHJpdmVyVGFzayAmJiBpc0NvbW1hbmRSZWplY3RhYmxlQnlQYWdlRXJyb3IodGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kKSkge1xuICAgICAgICAgICAgdGhpcy5fcmVqZWN0Q3VycmVudERyaXZlclRhc2socGFnZUVycm9yKTtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1BhZ2VFcnJvciA9IG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUGFnZUVycm9yID0gdGhpcy5wZW5kaW5nUGFnZUVycm9yIHx8IHBhZ2VFcnJvcjtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgX2hhbmRsZURyaXZlclJlcXVlc3QgKGRyaXZlclN0YXR1cykge1xuICAgICAgICBjb25zdCBpc1Rlc3REb25lICAgICAgICAgICAgICAgICA9IHRoaXMuY3VycmVudERyaXZlclRhc2sgJiYgdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kLnR5cGUgPT09XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NTUFORF9UWVBFLnRlc3REb25lO1xuICAgICAgICBjb25zdCBwYWdlRXJyb3IgICAgICAgICAgICAgICAgICA9IHRoaXMucGVuZGluZ1BhZ2VFcnJvciB8fCBkcml2ZXJTdGF0dXMucGFnZUVycm9yO1xuICAgICAgICBjb25zdCBjdXJyZW50VGFza1JlamVjdGVkQnlFcnJvciA9IHBhZ2VFcnJvciAmJiB0aGlzLl9oYW5kbGVQYWdlRXJyb3JTdGF0dXMocGFnZUVycm9yKTtcblxuICAgICAgICBpZiAodGhpcy5kaXNjb25uZWN0ZWQpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKF8sIHJlamVjdCkgPT4gcmVqZWN0KCkpO1xuXG4gICAgICAgIHRoaXMuY29uc29sZU1lc3NhZ2VzLmNvbmNhdChkcml2ZXJTdGF0dXMuY29uc29sZU1lc3NhZ2VzKTtcblxuICAgICAgICBpZiAoIWN1cnJlbnRUYXNrUmVqZWN0ZWRCeUVycm9yICYmIGRyaXZlclN0YXR1cy5pc0NvbW1hbmRSZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChpc1Rlc3REb25lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZUN1cnJlbnREcml2ZXJUYXNrKCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gVEVTVF9ET05FX0NPTkZJUk1BVElPTl9SRVNQT05TRTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fZnVsZmlsbEN1cnJlbnREcml2ZXJUYXNrKGRyaXZlclN0YXR1cyk7XG5cbiAgICAgICAgICAgIGlmIChkcml2ZXJTdGF0dXMuaXNQZW5kaW5nV2luZG93U3dpdGNoaW5nKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnJlbnREcml2ZXJUYXNrQ29tbWFuZCgpO1xuICAgIH1cblxuICAgIF9nZXRDdXJyZW50RHJpdmVyVGFza0NvbW1hbmQgKCkge1xuICAgICAgICBpZiAoIXRoaXMuY3VycmVudERyaXZlclRhc2spXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBjb21tYW5kID0gdGhpcy5jdXJyZW50RHJpdmVyVGFzay5jb21tYW5kO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5uYXZpZ2F0ZVRvICYmIGNvbW1hbmQuc3RhdGVTbmFwc2hvdClcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi51c2VTdGF0ZVNuYXBzaG90KEpTT04ucGFyc2UoY29tbWFuZC5zdGF0ZVNuYXBzaG90KSk7XG5cbiAgICAgICAgcmV0dXJuIGNvbW1hbmQ7XG4gICAgfVxuXG4gICAgLy8gRXhlY3V0ZSBjb21tYW5kXG4gICAgX2V4ZWN1dGVKc0V4cHJlc3Npb24gKGNvbW1hbmQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0VmFyaWFibGVOYW1lID0gY29tbWFuZC5yZXN1bHRWYXJpYWJsZU5hbWU7XG4gICAgICAgIGxldCBleHByZXNzaW9uICAgICAgICAgICA9IGNvbW1hbmQuZXhwcmVzc2lvbjtcblxuICAgICAgICBpZiAocmVzdWx0VmFyaWFibGVOYW1lKVxuICAgICAgICAgICAgZXhwcmVzc2lvbiA9IGAke3Jlc3VsdFZhcmlhYmxlTmFtZX0gPSAke2V4cHJlc3Npb259LCAke3Jlc3VsdFZhcmlhYmxlTmFtZX1gO1xuXG4gICAgICAgIHJldHVybiBleGVjdXRlSnNFeHByZXNzaW9uKGV4cHJlc3Npb24sIHRoaXMsIHsgc2tpcFZpc2liaWxpdHlDaGVjazogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2V4ZWN1dGVBc3NlcnRpb24gKGNvbW1hbmQsIGNhbGxzaXRlKSB7XG4gICAgICAgIGNvbnN0IGFzc2VydGlvblRpbWVvdXQgPSBjb21tYW5kLm9wdGlvbnMudGltZW91dCA9PT1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgMCA/IHRoaXMub3B0cy5hc3NlcnRpb25UaW1lb3V0IDogY29tbWFuZC5vcHRpb25zLnRpbWVvdXQ7XG4gICAgICAgIGNvbnN0IGV4ZWN1dG9yICAgICAgICAgPSBuZXcgQXNzZXJ0aW9uRXhlY3V0b3IoY29tbWFuZCwgYXNzZXJ0aW9uVGltZW91dCwgY2FsbHNpdGUpO1xuXG4gICAgICAgIGV4ZWN1dG9yLm9uY2UoJ3N0YXJ0LWFzc2VydGlvbi1yZXRyaWVzJywgdGltZW91dCA9PiB0aGlzLmV4ZWN1dGVDb21tYW5kKG5ldyBzZXJ2aWNlQ29tbWFuZHMuU2hvd0Fzc2VydGlvblJldHJpZXNTdGF0dXNDb21tYW5kKHRpbWVvdXQpKSk7XG4gICAgICAgIGV4ZWN1dG9yLm9uY2UoJ2VuZC1hc3NlcnRpb24tcmV0cmllcycsIHN1Y2Nlc3MgPT4gdGhpcy5leGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLkhpZGVBc3NlcnRpb25SZXRyaWVzU3RhdHVzQ29tbWFuZChzdWNjZXNzKSkpO1xuXG4gICAgICAgIGNvbnN0IGV4ZWN1dGVGbiA9IHRoaXMuZGVjb3JhdGVQcmV2ZW50RW1pdEFjdGlvbkV2ZW50cygoKSA9PiBleGVjdXRvci5ydW4oKSwgeyBwcmV2ZW50OiB0cnVlIH0pO1xuXG4gICAgICAgIHJldHVybiBhd2FpdCBleGVjdXRlRm4oKTtcbiAgICB9XG5cbiAgICBfYWRqdXN0Q29uZmlndXJhdGlvbldpdGhDb21tYW5kIChjb21tYW5kKSB7XG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS50ZXN0RG9uZSkge1xuICAgICAgICAgICAgdGhpcy50ZXN0RG9uZUNvbW1hbmRRdWV1ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVidWdMb2dnZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlci5oaWRlQnJlYWtwb2ludCh0aGlzLnNlc3Npb24uaWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuc2V0TmF0aXZlRGlhbG9nSGFuZGxlcilcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlRGlhbG9nSGFuZGxlciA9IGNvbW1hbmQuZGlhbG9nSGFuZGxlcjtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5zd2l0Y2hUb0lmcmFtZSlcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlSWZyYW1lU2VsZWN0b3IgPSBjb21tYW5kLnNlbGVjdG9yO1xuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnN3aXRjaFRvTWFpbldpbmRvdylcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlSWZyYW1lU2VsZWN0b3IgPSBudWxsO1xuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldFRlc3RTcGVlZClcbiAgICAgICAgICAgIHRoaXMuc3BlZWQgPSBjb21tYW5kLnNwZWVkO1xuXG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldFBhZ2VMb2FkVGltZW91dClcbiAgICAgICAgICAgIHRoaXMucGFnZUxvYWRUaW1lb3V0ID0gY29tbWFuZC5kdXJhdGlvbjtcblxuICAgICAgICBlbHNlIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5kZWJ1ZylcbiAgICAgICAgICAgIHRoaXMuZGVidWdnaW5nID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBhc3luYyBfYWRqdXN0U2NyZWVuc2hvdENvbW1hbmQgKGNvbW1hbmQpIHtcbiAgICAgICAgY29uc3QgYnJvd3NlcklkICAgICAgICAgICAgICAgICAgICA9IHRoaXMuYnJvd3NlckNvbm5lY3Rpb24uaWQ7XG4gICAgICAgIGNvbnN0IHsgaGFzQ2hyb21lbGVzc1NjcmVlbnNob3RzIH0gPSBhd2FpdCB0aGlzLmJyb3dzZXJDb25uZWN0aW9uLnByb3ZpZGVyLmhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIoYnJvd3NlcklkKTtcblxuICAgICAgICBpZiAoIWhhc0Nocm9tZWxlc3NTY3JlZW5zaG90cylcbiAgICAgICAgICAgIGNvbW1hbmQuZ2VuZXJhdGVTY3JlZW5zaG90TWFyaygpO1xuICAgIH1cblxuICAgIGFzeW5jIF9zZXRCcmVha3BvaW50SWZOZWNlc3NhcnkgKGNvbW1hbmQsIGNhbGxzaXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5kaXNhYmxlRGVidWdCcmVha3BvaW50cyAmJiB0aGlzLmRlYnVnZ2luZyAmJiBjYW5TZXREZWJ1Z2dlckJyZWFrcG9pbnRCZWZvcmVDb21tYW5kKGNvbW1hbmQpKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5fZW5xdWV1ZVNldEJyZWFrcG9pbnRDb21tYW5kKGNhbGxzaXRlKTtcbiAgICB9XG5cbiAgICBhc3luYyBleGVjdXRlQWN0aW9uIChhY3Rpb25OYW1lLCBjb21tYW5kLCBjYWxsc2l0ZSkge1xuICAgICAgICBsZXQgZXJyb3IgID0gbnVsbDtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG51bGw7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0QWN0aW9uU3RhcnQoYWN0aW9uTmFtZSwgY29tbWFuZCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0QWN0aW9uRG9uZShhY3Rpb25OYW1lLCBjb21tYW5kLCBlcnJvcik7XG5cbiAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBhc3luYyBleGVjdXRlQ29tbWFuZCAoY29tbWFuZCwgY2FsbHNpdGUpIHtcbiAgICAgICAgdGhpcy5kZWJ1Z0xvZy5jb21tYW5kKGNvbW1hbmQpO1xuXG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdQYWdlRXJyb3IgJiYgaXNDb21tYW5kUmVqZWN0YWJsZUJ5UGFnZUVycm9yKGNvbW1hbmQpKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlamVjdENvbW1hbmRXaXRoUGFnZUVycm9yKGNhbGxzaXRlKTtcblxuICAgICAgICBpZiAoaXNFeGVjdXRhYmxlT25DbGllbnRDb21tYW5kKGNvbW1hbmQpKVxuICAgICAgICAgICAgdGhpcy5hZGRpbmdEcml2ZXJUYXNrc0NvdW50Kys7XG5cbiAgICAgICAgdGhpcy5fYWRqdXN0Q29uZmlndXJhdGlvbldpdGhDb21tYW5kKGNvbW1hbmQpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX3NldEJyZWFrcG9pbnRJZk5lY2Vzc2FyeShjb21tYW5kLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgaWYgKGlzU2NyZWVuc2hvdENvbW1hbmQoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZGlzYWJsZVNjcmVlbnNob3RzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoV0FSTklOR19NRVNTQUdFLnNjcmVlbnNob3RzRGlzYWJsZWQpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2FkanVzdFNjcmVlbnNob3RDb21tYW5kKGNvbW1hbmQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQnJvd3Nlck1hbmlwdWxhdGlvbkNvbW1hbmQoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIHRoaXMuYnJvd3Nlck1hbmlwdWxhdGlvblF1ZXVlLnB1c2goY29tbWFuZCk7XG5cbiAgICAgICAgICAgIGlmIChpc1Jlc2l6ZVdpbmRvd0NvbW1hbmQoY29tbWFuZCkgJiYgdGhpcy5vcHRzLnZpZGVvUGF0aClcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdMb2cuYWRkV2FybmluZyhXQVJOSU5HX01FU1NBR0UudmlkZW9Ccm93c2VyUmVzaXppbmcsIHRoaXMudGVzdC5uYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS53YWl0KVxuICAgICAgICAgICAgcmV0dXJuIGRlbGF5KGNvbW1hbmQudGltZW91dCk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLnNldFBhZ2VMb2FkVGltZW91dClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5kZWJ1ZylcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9lbnF1ZXVlU2V0QnJlYWtwb2ludENvbW1hbmQoY2FsbHNpdGUpO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS51c2VSb2xlKSB7XG4gICAgICAgICAgICBsZXQgZm4gPSAoKSA9PiB0aGlzLl91c2VSb2xlKGNvbW1hbmQucm9sZSwgY2FsbHNpdGUpO1xuXG4gICAgICAgICAgICBmbiA9IHRoaXMuZGVjb3JhdGVQcmV2ZW50RW1pdEFjdGlvbkV2ZW50cyhmbiwgeyBwcmV2ZW50OiB0cnVlIH0pO1xuICAgICAgICAgICAgZm4gPSB0aGlzLmRlY29yYXRlRGlzYWJsZURlYnVnQnJlYWtwb2ludHMoZm4sIHsgZGlzYWJsZTogdHJ1ZSB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuYXNzZXJ0aW9uKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4ZWN1dGVBc3NlcnRpb24oY29tbWFuZCwgY2FsbHNpdGUpO1xuXG4gICAgICAgIGlmIChjb21tYW5kLnR5cGUgPT09IENPTU1BTkRfVFlQRS5leGVjdXRlRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9leGVjdXRlSnNFeHByZXNzaW9uKGNvbW1hbmQsIGNhbGxzaXRlKTtcblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlID09PSBDT01NQU5EX1RZUEUuZXhlY3V0ZUFzeW5jRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBleGVjdXRlQXN5bmNKc0V4cHJlc3Npb24oY29tbWFuZC5leHByZXNzaW9uLCB0aGlzLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgaWYgKGNvbW1hbmQudHlwZSA9PT0gQ09NTUFORF9UWVBFLmdldEJyb3dzZXJDb25zb2xlTWVzc2FnZXMpXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZW5xdWV1ZUJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIF9yZWplY3RDb21tYW5kV2l0aFBhZ2VFcnJvciAoY2FsbHNpdGUpIHtcbiAgICAgICAgY29uc3QgZXJyID0gdGhpcy5wZW5kaW5nUGFnZUVycm9yO1xuXG4gICAgICAgIGVyci5jYWxsc2l0ZSAgICAgICAgICA9IGNhbGxzaXRlO1xuICAgICAgICB0aGlzLnBlbmRpbmdQYWdlRXJyb3IgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgIH1cblxuICAgIF9kZWNvcmF0ZVdpdGhGbGFnIChmbiwgZmxhZ05hbWUsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzW2ZsYWdOYW1lXSA9IHZhbHVlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBmbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXNbZmxhZ05hbWVdID0gIXZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGRlY29yYXRlUHJldmVudEVtaXRBY3Rpb25FdmVudHMgKGZuLCB7IHByZXZlbnQgfSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb3JhdGVXaXRoRmxhZyhmbiwgJ3ByZXZlbnRFbWl0QWN0aW9uRXZlbnRzJywgcHJldmVudCk7XG4gICAgfVxuXG4gICAgZGVjb3JhdGVEaXNhYmxlRGVidWdCcmVha3BvaW50cyAoZm4sIHsgZGlzYWJsZSB9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNvcmF0ZVdpdGhGbGFnKGZuLCAnZGlzYWJsZURlYnVnQnJlYWtwb2ludHMnLCBkaXNhYmxlKTtcbiAgICB9XG5cbiAgICAvLyBSb2xlIG1hbmFnZW1lbnRcbiAgICBhc3luYyBnZXRTdGF0ZVNuYXBzaG90ICgpIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLnNlc3Npb24uZ2V0U3RhdGVTbmFwc2hvdCgpO1xuXG4gICAgICAgIHN0YXRlLnN0b3JhZ2VzID0gYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChuZXcgc2VydmljZUNvbW1hbmRzLkJhY2t1cFN0b3JhZ2VzQ29tbWFuZCgpKTtcblxuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfVxuXG4gICAgYXN5bmMgc3dpdGNoVG9DbGVhblJ1biAodXJsKSB7XG4gICAgICAgIHRoaXMuY3R4ICAgICAgICAgICAgID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5maXh0dXJlQ3R4ICAgICAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmNvbnNvbGVNZXNzYWdlcyA9IG5ldyBCcm93c2VyQ29uc29sZU1lc3NhZ2VzKCk7XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uLnVzZVN0YXRlU25hcHNob3QoU3RhdGVTbmFwc2hvdC5lbXB0eSgpKTtcblxuICAgICAgICBpZiAodGhpcy5zcGVlZCAhPT0gdGhpcy5vcHRzLnNwZWVkKSB7XG4gICAgICAgICAgICBjb25zdCBzZXRTcGVlZENvbW1hbmQgPSBuZXcgYWN0aW9uQ29tbWFuZHMuU2V0VGVzdFNwZWVkQ29tbWFuZCh7IHNwZWVkOiB0aGlzLm9wdHMuc3BlZWQgfSk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQoc2V0U3BlZWRDb21tYW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnBhZ2VMb2FkVGltZW91dCAhPT0gdGhpcy5vcHRzLnBhZ2VMb2FkVGltZW91dCkge1xuICAgICAgICAgICAgY29uc3Qgc2V0UGFnZUxvYWRUaW1lb3V0Q29tbWFuZCA9IG5ldyBhY3Rpb25Db21tYW5kcy5TZXRQYWdlTG9hZFRpbWVvdXRDb21tYW5kKHsgZHVyYXRpb246IHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQgfSk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZUNvbW1hbmQoc2V0UGFnZUxvYWRUaW1lb3V0Q29tbWFuZCk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLm5hdmlnYXRlVG9VcmwodXJsLCB0cnVlKTtcblxuICAgICAgICBpZiAodGhpcy5hY3RpdmVEaWFsb2dIYW5kbGVyKSB7XG4gICAgICAgICAgICBjb25zdCByZW1vdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCA9IG5ldyBhY3Rpb25Db21tYW5kcy5TZXROYXRpdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCh7IGRpYWxvZ0hhbmRsZXI6IHsgZm46IG51bGwgfSB9KTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChyZW1vdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBuYXZpZ2F0ZVRvVXJsICh1cmwsIGZvcmNlUmVsb2FkLCBzdGF0ZVNuYXBzaG90KSB7XG4gICAgICAgIGNvbnN0IG5hdmlnYXRlQ29tbWFuZCA9IG5ldyBOYXZpZ2F0ZVRvQ29tbWFuZCh7IHVybCwgZm9yY2VSZWxvYWQsIHN0YXRlU25hcHNob3QgfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlQ29tbWFuZChuYXZpZ2F0ZUNvbW1hbmQpO1xuICAgIH1cblxuICAgIGFzeW5jIF9nZXRTdGF0ZVNuYXBzaG90RnJvbVJvbGUgKHJvbGUpIHtcbiAgICAgICAgY29uc3QgcHJldlBoYXNlID0gdGhpcy5waGFzZTtcblxuICAgICAgICB0aGlzLnBoYXNlID0gUEhBU0UuaW5Sb2xlSW5pdGlhbGl6ZXI7XG5cbiAgICAgICAgaWYgKHJvbGUucGhhc2UgPT09IFJPTEVfUEhBU0UudW5pbml0aWFsaXplZClcbiAgICAgICAgICAgIGF3YWl0IHJvbGUuaW5pdGlhbGl6ZSh0aGlzKTtcblxuICAgICAgICBlbHNlIGlmIChyb2xlLnBoYXNlID09PSBST0xFX1BIQVNFLnBlbmRpbmdJbml0aWFsaXphdGlvbilcbiAgICAgICAgICAgIGF3YWl0IHByb21pc2lmeUV2ZW50KHJvbGUsICdpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIGlmIChyb2xlLmluaXRFcnIpXG4gICAgICAgICAgICB0aHJvdyByb2xlLmluaXRFcnI7XG5cbiAgICAgICAgdGhpcy5waGFzZSA9IHByZXZQaGFzZTtcblxuICAgICAgICByZXR1cm4gcm9sZS5zdGF0ZVNuYXBzaG90O1xuICAgIH1cblxuICAgIGFzeW5jIF91c2VSb2xlIChyb2xlLCBjYWxsc2l0ZSkge1xuICAgICAgICBpZiAodGhpcy5waGFzZSA9PT0gUEhBU0UuaW5Sb2xlSW5pdGlhbGl6ZXIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUm9sZVN3aXRjaEluUm9sZUluaXRpYWxpemVyRXJyb3IoY2FsbHNpdGUpO1xuXG4gICAgICAgIGNvbnN0IGJvb2ttYXJrID0gbmV3IFRlc3RSdW5Cb29rbWFyayh0aGlzLCByb2xlKTtcblxuICAgICAgICBhd2FpdCBib29rbWFyay5pbml0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFJvbGVJZClcbiAgICAgICAgICAgIHRoaXMudXNlZFJvbGVTdGF0ZXNbdGhpcy5jdXJyZW50Um9sZUlkXSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGVTbmFwc2hvdCgpO1xuXG4gICAgICAgIGNvbnN0IHN0YXRlU25hcHNob3QgPSB0aGlzLnVzZWRSb2xlU3RhdGVzW3JvbGUuaWRdIHx8IGF3YWl0IHRoaXMuX2dldFN0YXRlU25hcHNob3RGcm9tUm9sZShyb2xlKTtcblxuICAgICAgICB0aGlzLnNlc3Npb24udXNlU3RhdGVTbmFwc2hvdChzdGF0ZVNuYXBzaG90KTtcblxuICAgICAgICB0aGlzLmN1cnJlbnRSb2xlSWQgPSByb2xlLmlkO1xuXG4gICAgICAgIGF3YWl0IGJvb2ttYXJrLnJlc3RvcmUoY2FsbHNpdGUsIHN0YXRlU25hcHNob3QpO1xuICAgIH1cblxuICAgIC8vIEdldCBjdXJyZW50IFVSTFxuICAgIGFzeW5jIGdldEN1cnJlbnRVcmwgKCkge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gbmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcigoKSA9PiB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICB9LCB7IGJvdW5kVGVzdFJ1bjogdGhpcyB9KTtcblxuICAgICAgICBjb25zdCBnZXRMb2NhdGlvbiA9IGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgZ2V0TG9jYXRpb24oKTtcbiAgICB9XG5cbiAgICBfZGlzY29ubmVjdCAoZXJyKSB7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50RHJpdmVyVGFzaylcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdEN1cnJlbnREcml2ZXJUYXNrKGVycik7XG5cbiAgICAgICAgdGhpcy5lbWl0KCdkaXNjb25uZWN0ZWQnLCBlcnIpO1xuXG4gICAgICAgIGRlbGV0ZSB0ZXN0UnVuVHJhY2tlci5hY3RpdmVUZXN0UnVuc1t0aGlzLnNlc3Npb24uaWRdO1xuICAgIH1cblxuICAgIGFzeW5jIGVtaXRBY3Rpb25TdGFydCAoYXBpQWN0aW9uTmFtZSwgY29tbWFuZCkge1xuICAgICAgICBpZiAoIXRoaXMucHJldmVudEVtaXRBY3Rpb25FdmVudHMpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ2FjdGlvbi1zdGFydCcsIHsgY29tbWFuZCwgYXBpQWN0aW9uTmFtZSB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBlbWl0QWN0aW9uRG9uZSAoYXBpQWN0aW9uTmFtZSwgY29tbWFuZCwgZXJyb3JzKSB7XG4gICAgICAgIGlmICghdGhpcy5wcmV2ZW50RW1pdEFjdGlvbkV2ZW50cylcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgnYWN0aW9uLWRvbmUnLCB7IGNvbW1hbmQsIGFwaUFjdGlvbk5hbWUsIGVycm9ycyB9KTtcbiAgICB9XG59XG5cbi8vIFNlcnZpY2UgbWVzc2FnZSBoYW5kbGVyc1xuY29uc3QgU2VydmljZU1lc3NhZ2VzID0gVGVzdFJ1bi5wcm90b3R5cGU7XG5cbi8vIE5PVEU6IHRoaXMgZnVuY3Rpb24gaXMgdGltZS1jcml0aWNhbCBhbmQgbXVzdCByZXR1cm4gQVNBUCB0byBhdm9pZCBjbGllbnQgZGlzY29ubmVjdGlvblxuU2VydmljZU1lc3NhZ2VzW0NMSUVOVF9NRVNTQUdFUy5yZWFkeV0gPSBmdW5jdGlvbiAobXNnKSB7XG4gICAgdGhpcy5kZWJ1Z0xvZy5kcml2ZXJNZXNzYWdlKG1zZyk7XG5cbiAgICB0aGlzLmVtaXQoJ2Nvbm5lY3RlZCcpO1xuXG4gICAgdGhpcy5fY2xlYXJQZW5kaW5nUmVxdWVzdCgpO1xuXG4gICAgLy8gTk9URTogdGhlIGRyaXZlciBzZW5kcyB0aGUgc3RhdHVzIGZvciB0aGUgc2Vjb25kIHRpbWUgaWYgaXQgZGlkbid0IGdldCBhIHJlc3BvbnNlIGF0IHRoZVxuICAgIC8vIGZpcnN0IHRyeS4gVGhpcyBpcyBwb3NzaWJsZSB3aGVuIHRoZSBwYWdlIHdhcyB1bmxvYWRlZCBhZnRlciB0aGUgZHJpdmVyIHNlbnQgdGhlIHN0YXR1cy5cbiAgICBpZiAobXNnLnN0YXR1cy5pZCA9PT0gdGhpcy5sYXN0RHJpdmVyU3RhdHVzSWQpXG4gICAgICAgIHJldHVybiB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZTtcblxuICAgIHRoaXMubGFzdERyaXZlclN0YXR1c0lkICAgICAgID0gbXNnLnN0YXR1cy5pZDtcbiAgICB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZSA9IHRoaXMuX2hhbmRsZURyaXZlclJlcXVlc3QobXNnLnN0YXR1cyk7XG5cbiAgICBpZiAodGhpcy5sYXN0RHJpdmVyU3RhdHVzUmVzcG9uc2UgfHwgbXNnLnN0YXR1cy5pc1BlbmRpbmdXaW5kb3dTd2l0Y2hpbmcpXG4gICAgICAgIHJldHVybiB0aGlzLmxhc3REcml2ZXJTdGF0dXNSZXNwb25zZTtcblxuICAgIC8vIE5PVEU6IHdlIHNlbmQgYW4gZW1wdHkgcmVzcG9uc2UgYWZ0ZXIgdGhlIE1BWF9SRVNQT05TRV9ERUxBWSB0aW1lb3V0IGlzIGV4Y2VlZGVkIHRvIGtlZXAgY29ubmVjdGlvblxuICAgIC8vIHdpdGggdGhlIGNsaWVudCBhbmQgcHJldmVudCB0aGUgcmVzcG9uc2UgdGltZW91dCBleGNlcHRpb24gb24gdGhlIGNsaWVudCBzaWRlXG4gICAgY29uc3QgcmVzcG9uc2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLl9yZXNvbHZlUGVuZGluZ1JlcXVlc3QobnVsbCksIE1BWF9SRVNQT05TRV9ERUxBWSk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLnBlbmRpbmdSZXF1ZXN0ID0geyByZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlVGltZW91dCB9O1xuICAgIH0pO1xufTtcblxuU2VydmljZU1lc3NhZ2VzW0NMSUVOVF9NRVNTQUdFUy5yZWFkeUZvckJyb3dzZXJNYW5pcHVsYXRpb25dID0gYXN5bmMgZnVuY3Rpb24gKG1zZykge1xuICAgIHRoaXMuZGVidWdMb2cuZHJpdmVyTWVzc2FnZShtc2cpO1xuXG4gICAgbGV0IHJlc3VsdCA9IG51bGw7XG4gICAgbGV0IGVycm9yICA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmJyb3dzZXJNYW5pcHVsYXRpb25RdWV1ZS5leGVjdXRlUGVuZGluZ01hbmlwdWxhdGlvbihtc2cpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGVycm9yID0gZXJyO1xuICAgIH1cblxuICAgIHJldHVybiB7IHJlc3VsdCwgZXJyb3IgfTtcbn07XG5cblNlcnZpY2VNZXNzYWdlc1tDTElFTlRfTUVTU0FHRVMud2FpdEZvckZpbGVEb3dubG9hZF0gPSBmdW5jdGlvbiAobXNnKSB7XG4gICAgdGhpcy5kZWJ1Z0xvZy5kcml2ZXJNZXNzYWdlKG1zZyk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmZpbGVEb3dubG9hZGluZ0hhbmRsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsZURvd25sb2FkaW5nSGFuZGxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVXYWl0Rm9yRmlsZURvd25sb2FkaW5nUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG59O1xuIl19
\No newline at end of file