@ngneat/spectator
Version:
A powerful tool to simplify your Angular tests
288 lines • 44.9 kB
JavaScript
import { DebugElement, ElementRef, OutputEmitterRef } from '@angular/core';
import { tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent, dispatchTouchEvent } from '../dispatch-events';
import { DOMSelector } from '../dom-selectors';
import { createMouseEvent } from '../event-creators';
import { patchElementFocus } from '../internals/element-focus';
import { getChildren } from '../internals/query';
import { selectOption } from '../select-option';
import { typeInElement } from '../type-in-element';
import { isString } from '../types';
import { BaseSpectator } from './base-spectator';
const KEY_UP = 'keyup';
/**
* @internal
*/
export class DomSpectator extends BaseSpectator {
constructor(fixture, debugElement, instance, element) {
super();
this.fixture = fixture;
this.debugElement = debugElement;
this.instance = instance;
this.element = element;
}
inject(token) {
return super.inject(token);
}
detectChanges() {
this.fixture.detectChanges();
}
query(directiveOrSelector, options) {
if ((options || {}).root) {
if (isString(directiveOrSelector)) {
return document.querySelector(directiveOrSelector);
}
if (directiveOrSelector instanceof DOMSelector) {
return directiveOrSelector.execute(document)[0] || null;
}
return getChildren(this.getRootDebugElement())(directiveOrSelector, options)[0] || null;
}
if (options?.parentSelector) {
const debugElement = this.getDebugElement(options.parentSelector);
if (!debugElement) {
/* eslint-disable no-console */
console.error(`${directiveOrSelector} does not exists`);
return null;
}
return (getChildren(debugElement)(directiveOrSelector, {
root: options.root,
read: options.read,
})[0] || null);
}
return getChildren(this.debugElement)(directiveOrSelector, options)[0] || null;
}
queryAll(directiveOrSelector, options) {
if ((options || {}).root) {
if (isString(directiveOrSelector)) {
return Array.from(document.querySelectorAll(directiveOrSelector));
}
if (directiveOrSelector instanceof DOMSelector) {
return directiveOrSelector.execute(document);
}
return getChildren(this.getRootDebugElement())(directiveOrSelector, options);
}
if (options?.parentSelector) {
const debugElement = this.getDebugElement(options.parentSelector);
if (!debugElement) {
/* eslint-disable no-console */
console.error(`${directiveOrSelector} does not exists`);
return [];
}
return getChildren(debugElement)(directiveOrSelector, {
root: options.root,
read: options.read,
});
}
return getChildren(this.debugElement)(directiveOrSelector, options);
}
queryLast(directiveOrSelector, options) {
let result = [];
if ((options || {}).root) {
if (isString(directiveOrSelector)) {
result = Array.from(document.querySelectorAll(directiveOrSelector));
}
else if (directiveOrSelector instanceof DOMSelector) {
result = directiveOrSelector.execute(document);
}
else {
result = getChildren(this.getRootDebugElement())(directiveOrSelector, options);
}
}
else if (options?.parentSelector) {
const debugElement = this.getDebugElement(options.parentSelector);
if (!debugElement) {
/* eslint-disable no-console */
console.error(`${directiveOrSelector} does not exists`);
result = [];
}
else {
result = getChildren(debugElement)(directiveOrSelector, {
root: options.root,
read: options.read,
});
}
}
else {
result = getChildren(this.debugElement)(directiveOrSelector, options);
}
if (result && result.length) {
return result[result.length - 1];
}
return null;
}
output(output) {
const eventEmitter = this.instance[output];
if (!(eventEmitter instanceof Observable) && !(eventEmitter instanceof OutputEmitterRef)) {
throw new Error(`${String(output)} is not an or an output function`);
}
return eventEmitter;
}
tick(millis) {
tick(millis);
this.detectChanges();
}
click(selector = this.element) {
const element = this.getNativeElement(selector);
if (!(element instanceof HTMLElement)) {
throw new Error(`Cannot click: ${selector} is not a HTMLElement`);
}
element.click();
this.detectChanges();
}
blur(selector = this.element) {
const element = this.getNativeElement(selector);
if (!(element instanceof HTMLElement)) {
throw new Error(`Cannot blur: ${selector} is not a HTMLElement`);
}
patchElementFocus(element);
element.blur();
this.detectChanges();
}
focus(selector = this.element) {
const element = this.getNativeElement(selector);
if (!(element instanceof HTMLElement)) {
throw new Error(`Cannot focus: ${selector} is not a HTMLElement`);
}
patchElementFocus(element);
element.focus();
this.detectChanges();
}
dispatchMouseEvent(selector = this.element, type, x = 0, y = 0, event = createMouseEvent(type, x, y)) {
const element = this.getNativeElement(selector);
if (!(element instanceof Node)) {
throw new Error(`Cannot dispatch mouse event: ${selector} is not a node`);
}
const dispatchedEvent = dispatchMouseEvent(element, type, x, y, event);
this.detectChanges();
return dispatchedEvent;
}
dispatchKeyboardEvent(selector = this.element, type, keyOrKeyCode, target) {
const element = this.getNativeElement(selector);
if (!(element instanceof Node)) {
throw new Error(`Cannot dispatch keyboard event: ${selector} is not a node`);
}
const event = dispatchKeyboardEvent(element, type, keyOrKeyCode, target);
this.detectChanges();
return event;
}
dispatchFakeEvent(selector = this.element, type, canBubble) {
const event = dispatchFakeEvent(this.getNativeElement(selector), type, canBubble);
this.detectChanges();
return event;
}
triggerEventHandler(directiveOrSelector, eventName, eventObj, options) {
const triggerDebugElement = this.getDebugElement(directiveOrSelector, options);
if (!triggerDebugElement) {
/* eslint-disable no-console */
console.error(`${directiveOrSelector} does not exists`);
return;
}
triggerDebugElement.triggerEventHandler(eventName, eventObj);
this.detectChanges();
}
get keyboard() {
return {
pressKey: (key, selector = this.element, event = KEY_UP) => {
this.dispatchKeyboardEvent(selector, event, key);
},
pressEscape: (selector = this.element, event = KEY_UP) => {
this.dispatchKeyboardEvent(selector, event, { key: 'Escape', keyCode: 27 });
},
pressEnter: (selector = this.element, event = KEY_UP) => {
this.dispatchKeyboardEvent(selector, event, { key: 'Enter', keyCode: 13 });
},
pressTab: (selector = this.element, event = KEY_UP) => {
this.dispatchKeyboardEvent(selector, event, { key: 'Tab', keyCode: 9 });
},
pressBackspace: (selector = this.element, event = KEY_UP) => {
this.dispatchKeyboardEvent(selector, event, { key: 'Backspace', keyCode: 8 });
},
};
}
get mouse() {
return {
contextmenu: (selector = this.element) => {
this.dispatchMouseEvent(selector, 'contextmenu');
},
dblclick: (selector = this.element) => {
this.dispatchMouseEvent(selector, 'dblclick');
},
};
}
dispatchTouchEvent(selector = this.element, type, x = 0, y = 0) {
dispatchTouchEvent(this.getNativeElement(selector), type, x, y);
this.detectChanges();
}
typeInElement(value, selector = this.element) {
typeInElement(value, this.getNativeElement(selector));
this.detectChanges();
}
selectOption(selector = this.element, options, config = { emitEvents: true }) {
if (!selector) {
throw new Error(`Cannot find select: ${selector}`);
}
selectOption(options, this.getNativeElement(selector), config);
this.detectChanges();
}
getNativeElement(selector) {
let element;
// Support global objects window and document
if (selector === window || selector === document) {
return selector;
}
if (isString(selector)) {
const exists = this.debugElement.query(By.css(selector));
if (exists) {
element = exists.nativeElement;
}
else {
/* eslint-disable no-console */
console.error(`${selector} does not exists`);
}
}
else if (selector instanceof DOMSelector) {
element = selector.execute(document)[0] || null;
}
else {
if (selector instanceof DebugElement || selector instanceof ElementRef) {
element = selector.nativeElement;
}
else {
element = selector;
}
}
return element;
}
getDebugElement(directiveOrSelector, options) {
const debugElement = options?.root ? this.getRootDebugElement() : this.debugElement;
if (isString(directiveOrSelector)) {
return debugElement.query(By.css(directiveOrSelector));
}
else if (directiveOrSelector instanceof DebugElement) {
return directiveOrSelector;
}
else {
return debugElement.query(By.directive(directiveOrSelector));
}
}
getRootDebugElement() {
let element = this.debugElement;
/**
* This bounded loop call is required to access the debug element for
* root dom element
*/
while (true) {
if (!element) {
throw Error('Unable to find root element');
}
if (!element.parent) {
// Found the root element
return element;
}
element = element.parent;
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tLXNwZWN0YXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWN0YXRvci9zcmMvbGliL2Jhc2UvZG9tLXNwZWN0YXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBZ0IsZ0JBQWdCLEVBQVEsTUFBTSxlQUFlLENBQUM7QUFDL0YsT0FBTyxFQUFvQixJQUFJLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVsQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN0SCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWpELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUE2RixRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFL0gsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWpELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQztBQU92Qjs7R0FFRztBQUNILE1BQU0sT0FBZ0IsWUFBZ0IsU0FBUSxhQUFhO0lBQ3pELFlBQ1MsT0FBOEIsRUFDOUIsWUFBMEIsRUFDdkIsUUFBVyxFQUNkLE9BQWdC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bUJBQW1CO1FBQ3pCLElBQUksT0FBTyxHQUFvQyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBRWpFOzs7V0FHRztRQUNILE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztZQUM3QyxDQUFDO1lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDcEIseUJBQXlCO2dCQUN6QixPQUFPLE9BQU8sQ0FBQztZQUNqQixDQUFDO1lBRUQsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlYnVnRWxlbWVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBPdXRwdXRFbWl0dGVyUmVmLCBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21wb25lbnRGaXh0dXJlLCB0aWNrIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS90ZXN0aW5nJztcbmltcG9ydCB7IEJ5IH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IGRpc3BhdGNoRmFrZUV2ZW50LCBkaXNwYXRjaEtleWJvYXJkRXZlbnQsIGRpc3BhdGNoTW91c2VFdmVudCwgZGlzcGF0Y2hUb3VjaEV2ZW50IH0gZnJvbSAnLi4vZGlzcGF0Y2gtZXZlbnRzJztcbmltcG9ydCB7IERPTVNlbGVjdG9yIH0gZnJvbSAnLi4vZG9tLXNlbGVjdG9ycyc7XG5pbXBvcnQgeyBjcmVhdGVNb3VzZUV2ZW50IH0gZnJvbSAnLi4vZXZlbnQtY3JlYXRvcnMnO1xuaW1wb3J0IHsgcGF0Y2hFbGVtZW50Rm9jdXMgfSBmcm9tICcuLi9pbnRlcm5hbHMvZWxlbWVudC1mb2N1cyc7XG5pbXBvcnQgeyBnZXRDaGlsZHJlbiB9IGZyb20gJy4uL2ludGVybmFscy9xdWVyeSc7XG5pbXBvcnQgeyBTcHlPYmplY3QgfSBmcm9tICcuLi9tb2NrJztcbmltcG9ydCB7IHNlbGVjdE9wdGlvbiB9IGZyb20gJy4uL3NlbGVjdC1vcHRpb24nO1xuaW1wb3J0IHsgVG9rZW4gfSBmcm9tICcuLi90b2tlbic7XG5pbXBvcnQgeyB0eXBlSW5FbGVtZW50IH0gZnJvbSAnLi4vdHlwZS1pbi1lbGVtZW50JztcbmltcG9ydCB7IE91dHB1dFR5cGUsIEtleWJvYXJkRXZlbnRPcHRpb25zLCBLZXlzTWF0Y2hpbmcsIFF1ZXJ5T3B0aW9ucywgUXVlcnlUeXBlLCBTcGVjdGF0b3JFbGVtZW50LCBpc1N0cmluZyB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgQmFzZVNwZWN0YXRvciB9IGZyb20gJy4vYmFzZS1zcGVjdGF0b3InO1xuXG5jb25zdCBLRVlfVVAgPSAna2V5dXAnO1xuXG50eXBlIEtleXNNYXRjaGluZ1JldHVyblR5cGU8VCwgVj4gPSBrZXlvZiB7IFtQIGluIGtleW9mIFQgYXMgVFtQXSBleHRlbmRzIFYgPyBQIDogbmV2ZXJdOiBQIH0gJiBrZXlvZiBUO1xudHlwZSBLZXlzTWF0Y2hpbmdPdXRwdXRGdW5jdGlvbjxUPiA9IEtleXNNYXRjaGluZ1JldHVyblR5cGU8VCwgT3V0cHV0RW1pdHRlclJlZjxhbnk+PjtcbnR5cGUgS2V5c01hdGNoaW5nQ2xhc3NpY091dHB1dDxUPiA9IEtleXNNYXRjaGluZ1JldHVyblR5cGU8VCwgRXZlbnRFbWl0dGVyPGFueT4+O1xudHlwZSBLZXlzTWF0Y2hpbmdPdXRwdXQ8VD4gPSBLZXlzTWF0Y2hpbmdPdXRwdXRGdW5jdGlvbjxUPiB8IEtleXNNYXRjaGluZ0NsYXNzaWNPdXRwdXQ8VD47XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBEb21TcGVjdGF0b3I8ST4gZXh0ZW5kcyBCYXNlU3BlY3RhdG9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGZpeHR1cmU6IENvbXBvbmVudEZpeHR1cmU8YW55PixcbiAgICBwdWJsaWMgZGVidWdFbGVtZW50OiBEZWJ1Z0VsZW1lbnQsXG4gICAgcHJvdGVjdGVkIGluc3RhbmNlOiBJLFxuICAgIHB1YmxpYyBlbGVtZW50OiBFbGVtZW50LFxuICApIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVibGljIGluamVjdDxUPih0b2tlbjogVG9rZW48VD4pOiBTcHlPYmplY3Q8VD4ge1xuICAgIHJldHVybiBzdXBlci5pbmplY3QodG9rZW4pO1xuICB9XG5cbiAgcHVibGljIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5maXh0dXJlLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBxdWVyeTxSIGV4dGVuZHMgRWxlbWVudD4oc2VsZWN0b3I6IHN0cmluZyB8IERPTVNlbGVjdG9yLCBvcHRpb25zPzogeyByb290OiBib29sZWFuIH0pOiBSIHwgbnVsbDtcbiAgcHVibGljIHF1ZXJ5PFI+KGRpcmVjdGl2ZTogVHlwZTxSPiwgb3B0aW9ucz86IHsgcm9vdDogYm9vbGVhbiB9KTogUiB8IG51bGw7XG4gIHB1YmxpYyBxdWVyeTxSIGV4dGVuZHMgRWxlbWVudD4oc2VsZWN0b3I6IHN0cmluZyB8IERPTVNlbGVjdG9yLCBvcHRpb25zPzogeyBwYXJlbnRTZWxlY3RvcjogVHlwZTxhbnk+IHwgc3RyaW5nIH0pOiBSIHwgbnVsbDtcbiAgcHVibGljIHF1ZXJ5PFI+KGRpcmVjdGl2ZTogVHlwZTxSPiwgb3B0aW9ucz86IHsgcGFyZW50U2VsZWN0b3I/OiBUeXBlPGFueT4gfCBzdHJpbmcgfSk6IFIgfCBudWxsO1xuICBwdWJsaWMgcXVlcnk8Uj4oXG4gICAgZGlyZWN0aXZlT3JTZWxlY3RvcjogVHlwZTxhbnk+IHwgc3RyaW5nLFxuICAgIG9wdGlvbnM6IHsgcmVhZDogVG9rZW48Uj47IHJvb3Q/OiBib29sZWFuOyBwYXJlbnRTZWxlY3Rvcj86IFR5cGU8YW55PiB8IHN0cmluZyB9LFxuICApOiBSIHwgbnVsbDtcbiAgcHVibGljIHF1ZXJ5PFI+KGRpcmVjdGl2ZU9yU2VsZWN0b3I6IFF1ZXJ5VHlwZSwgb3B0aW9ucz86IFF1ZXJ5T3B0aW9uczxSPik6IFIgfCBFbGVtZW50IHwgbnVsbCB7XG4gICAgaWYgKChvcHRpb25zIHx8IHt9KS5yb290KSB7XG4gICAgICBpZiAoaXNTdHJpbmcoZGlyZWN0aXZlT3JTZWxlY3RvcikpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZGlyZWN0aXZlT3JTZWxlY3Rvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkaXJlY3RpdmVPclNlbGVjdG9yIGluc3RhbmNlb2YgRE9NU2VsZWN0b3IpIHtcbiAgICAgICAgcmV0dXJuIGRpcmVjdGl2ZU9yU2VsZWN0b3IuZXhlY3V0ZShkb2N1bWVudCBhcyBhbnkpWzBdIHx8IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBnZXRDaGlsZHJlbjxSPih0aGlzLmdldFJvb3REZWJ1Z0VsZW1lbnQoKSkoZGlyZWN0aXZlT3JTZWxlY3Rvciwgb3B0aW9ucylbMF0gfHwgbnVsbDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8ucGFyZW50U2VsZWN0b3IpIHtcbiAgICAgIGNvbnN0IGRlYnVnRWxlbWVudCA9IHRoaXMuZ2V0RGVidWdFbGVtZW50KG9wdGlvbnMucGFyZW50U2VsZWN0b3IpO1xuICAgICAgaWYgKCFkZWJ1Z0VsZW1lbnQpIHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICBjb25zb2xlLmVycm9yKGAke2RpcmVjdGl2ZU9yU2VsZWN0b3J9IGRvZXMgbm90IGV4aXN0c2ApO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIChcbiAgICAgICAgZ2V0Q2hpbGRyZW48Uj4oZGVidWdFbGVtZW50IGFzIERlYnVnRWxlbWVudCkoZGlyZWN0aXZlT3JTZWxlY3Rvciwge1xuICAgICAgICAgIHJvb3Q6IG9wdGlvbnMucm9vdCxcbiAgICAgICAgICByZWFkOiBvcHRpb25zLnJlYWQsXG4gICAgICAgIH0pWzBdIHx8IG51bGxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdldENoaWxkcmVuPFI+KHRoaXMuZGVidWdFbGVtZW50KShkaXJlY3RpdmVPclNlbGVjdG9yLCBvcHRpb25zKVswXSB8fCBudWxsO1xuICB9XG5cbiAgcHVibGljIHF1ZXJ5QWxsPFIgZXh0ZW5kcyBFbGVtZW50PihzZWxlY3Rvcjogc3RyaW5nIHwgRE9NU2VsZWN0b3IsIG9wdGlvbnM/OiB7IHJvb3Q6IGJvb2xlYW4gfSk6IFJbXTtcbiAgcHVibGljIHF1ZXJ5QWxsPFI+KGRpcmVjdGl2ZTogVHlwZTxSPiwgb3B0aW9ucz86IHsgcm9vdDogYm9vbGVhbiB9KTogUltdO1xuICBwdWJsaWMgcXVlcnlBbGw8UiBleHRlbmRzIEVsZW1lbnQ+KHNlbGVjdG9yOiBzdHJpbmcgfCBET01TZWxlY3Rvciwgb3B0aW9ucz86IHsgcGFyZW50U2VsZWN0b3I6IFR5cGU8YW55PiB8IHN0cmluZyB9KTogUltdO1xuICBwdWJsaWMgcXVlcnlBbGw8Uj4oZGlyZWN0aXZlOiBUeXBlPFI+LCBvcHRpb25zPzogeyBwYXJlbnRTZWxlY3RvcjogVHlwZTxhbnk+IHwgc3RyaW5nIH0pOiBSW107XG4gIHB1YmxpYyBxdWVyeUFsbDxSPihcbiAgICBkaXJlY3RpdmVPclNlbGVjdG9yOiBUeXBlPGFueT4gfCBzdHJpbmcsXG4gICAgb3B0aW9uczogeyByZWFkOiBUb2tlbjxSPjsgcm9vdD86IGJvb2xlYW47IHBhcmVudFNlbGVjdG9yPzogVHlwZTxhbnk+IHwgc3RyaW5nIH0sXG4gICk6IFJbXTtcbiAgcHVibGljIHF1ZXJ5QWxsPFI+KGRpcmVjdGl2ZU9yU2VsZWN0b3I6IFF1ZXJ5VHlwZSwgb3B0aW9ucz86IFF1ZXJ5T3B0aW9uczxSPik6IFJbXSB8IEVsZW1lbnRbXSB7XG4gICAgaWYgKChvcHRpb25zIHx8IHt9KS5yb290KSB7XG4gICAgICBpZiAoaXNTdHJpbmcoZGlyZWN0aXZlT3JTZWxlY3RvcikpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChkaXJlY3RpdmVPclNlbGVjdG9yKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkaXJlY3RpdmVPclNlbGVjdG9yIGluc3RhbmNlb2YgRE9NU2VsZWN0b3IpIHtcbiAgICAgICAgcmV0dXJuIGRpcmVjdGl2ZU9yU2VsZWN0b3IuZXhlY3V0ZShkb2N1bWVudCBhcyBhbnkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZ2V0Q2hpbGRyZW48Uj4odGhpcy5nZXRSb290RGVidWdFbGVtZW50KCkpKGRpcmVjdGl2ZU9yU2VsZWN0b3IsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zPy5wYXJlbnRTZWxlY3Rvcikge1xuICAgICAgY29uc3QgZGVidWdFbGVtZW50ID0gdGhpcy5nZXREZWJ1Z0VsZW1lbnQob3B0aW9ucy5wYXJlbnRTZWxlY3Rvcik7XG4gICAgICBpZiAoIWRlYnVnRWxlbWVudCkge1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7ZGlyZWN0aXZlT3JTZWxlY3Rvcn0gZG9lcyBub3QgZXhpc3RzYCk7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGdldENoaWxkcmVuPFI+KGRlYnVnRWxlbWVudCBhcyBEZWJ1Z0VsZW1lbnQpKGRpcmVjdGl2ZU9yU2VsZWN0b3IsIHtcbiAgICAgICAgcm9vdDogb3B0aW9ucy5yb290LFxuICAgICAgICByZWFkOiBvcHRpb25zLnJlYWQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0Q2hpbGRyZW48Uj4odGhpcy5kZWJ1Z0VsZW1lbnQpKGRpcmVjdGl2ZU9yU2VsZWN0b3IsIG9wdGlvbnMpO1xuICB9XG5cbiAgcHVibGljIHF1ZXJ5TGFzdDxSIGV4dGVuZHMgRWxlbWVudD4oc2VsZWN0b3I6IHN0cmluZyB8IERPTVNlbGVjdG9yLCBvcHRpb25zPzogeyByb290OiBib29sZWFuIH0pOiBSIHwgbnVsbDtcbiAgcHVibGljIHF1ZXJ5TGFzdDxSPihkaXJlY3RpdmU6IFR5cGU8Uj4sIG9wdGlvbnM/OiB7IHJvb3Q6IGJvb2xlYW4gfSk6IFIgfCBudWxsO1xuICBwdWJsaWMgcXVlcnlMYXN0PFIgZXh0ZW5kcyBFbGVtZW50PihzZWxlY3Rvcjogc3RyaW5nIHwgRE9NU2VsZWN0b3IsIG9wdGlvbnM/OiB7IHBhcmVudFNlbGVjdG9yOiBUeXBlPGFueT4gfCBzdHJpbmcgfSk6IFIgfCBudWxsO1xuICBwdWJsaWMgcXVlcnlMYXN0PFI+KGRpcmVjdGl2ZTogVHlwZTxSPiwgb3B0aW9ucz86IHsgcGFyZW50U2VsZWN0b3I6IFR5cGU8YW55PiB8IHN0cmluZyB9KTogUiB8IG51bGw7XG4gIHB1YmxpYyBxdWVyeUxhc3Q8Uj4oXG4gICAgZGlyZWN0aXZlT3JTZWxlY3RvcjogVHlwZTxhbnk+IHwgc3RyaW5nLFxuICAgIG9wdGlvbnM6IHsgcmVhZDogVG9rZW48Uj47IHJvb3Q/OiBib29sZWFuOyBwYXJlbnRTZWxlY3Rvcj86IFR5cGU8YW55PiB8IHN0cmluZyB9LFxuICApOiBSIHwgbnVsbDtcbiAgcHVibGljIHF1ZXJ5TGFzdDxSPihkaXJlY3RpdmVPclNlbGVjdG9yOiBRdWVyeVR5cGUsIG9wdGlvbnM/OiBRdWVyeU9wdGlvbnM8Uj4pOiBSIHwgRWxlbWVudCB8IG51bGwge1xuICAgIGxldCByZXN1bHQ6IChSIHwgRWxlbWVudClbXSA9IFtdO1xuXG4gICAgaWYgKChvcHRpb25zIHx8IHt9KS5yb290KSB7XG4gICAgICBpZiAoaXNTdHJpbmcoZGlyZWN0aXZlT3JTZWxlY3RvcikpIHtcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGRpcmVjdGl2ZU9yU2VsZWN0b3IpKTtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aXZlT3JTZWxlY3RvciBpbnN0YW5jZW9mIERPTVNlbGVjdG9yKSB7XG4gICAgICAgIHJlc3VsdCA9IGRpcmVjdGl2ZU9yU2VsZWN0b3IuZXhlY3V0ZShkb2N1bWVudCBhcyBhbnkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gZ2V0Q2hpbGRyZW48Uj4odGhpcy5nZXRSb290RGVidWdFbGVtZW50KCkpKGRpcmVjdGl2ZU9yU2VsZWN0b3IsIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3B0aW9ucz8ucGFyZW50U2VsZWN0b3IpIHtcbiAgICAgIGNvbnN0IGRlYnVnRWxlbWVudCA9IHRoaXMuZ2V0RGVidWdFbGVtZW50KG9wdGlvbnMucGFyZW50U2VsZWN0b3IpO1xuICAgICAgaWYgKCFkZWJ1Z0VsZW1lbnQpIHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICBjb25zb2xlLmVycm9yKGAke2RpcmVjdGl2ZU9yU2VsZWN0b3J9IGRvZXMgbm90IGV4aXN0c2ApO1xuICAgICAgICByZXN1bHQgPSBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGdldENoaWxkcmVuPFI+KGRlYnVnRWxlbWVudCBhcyBEZWJ1Z0VsZW1lbnQpKGRpcmVjdGl2ZU9yU2VsZWN0b3IsIHtcbiAgICAgICAgICByb290OiBvcHRpb25zLnJvb3QsXG4gICAgICAgICAgcmVhZDogb3B0aW9ucy5yZWFkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ID0gZ2V0Q2hpbGRyZW48Uj4odGhpcy5kZWJ1Z0VsZW1lbnQpKGRpcmVjdGl2ZU9yU2VsZWN0b3IsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwdWJsaWMgb3V0cHV0PEsgZXh0ZW5kcyBLZXlzTWF0Y2hpbmdPdXRwdXQ8ST4gPSBLZXlzTWF0Y2hpbmdPdXRwdXQ8ST4+KG91dHB1dDogSyk6IElbS107XG4gIHB1YmxpYyBvdXRwdXQ8VCwgSyBleHRlbmRzIEtleXNNYXRjaGluZ0NsYXNzaWNPdXRwdXQ8ST4gPSBLZXlzTWF0Y2hpbmdDbGFzc2ljT3V0cHV0PEk+PihvdXRwdXQ6IEspOiBPYnNlcnZhYmxlPFQ+O1xuICBwdWJsaWMgb3V0cHV0PFQsIEsgZXh0ZW5kcyBLZXlzTWF0Y2hpbmdPdXRwdXRGdW5jdGlvbjxJPiA9IEtleXNNYXRjaGluZ091dHB1dEZ1bmN0aW9uPEk+PihvdXRwdXQ6IEspOiBPdXRwdXRFbWl0dGVyUmVmPFQ+O1xuICBwdWJsaWMgb3V0cHV0PFQsIEsgZXh0ZW5kcyBLZXlzTWF0Y2hpbmdPdXRwdXQ8ST4+KG91dHB1dDogSyk6IElbS10gfCBPYnNlcnZhYmxlPFQ+IHwgT3V0cHV0RW1pdHRlclJlZjxUPiB7XG4gICAgY29uc3QgZXZlbnRFbWl0dGVyID0gdGhpcy5pbnN0YW5jZVtvdXRwdXRdO1xuXG4gICAgaWYgKCEoZXZlbnRFbWl0dGVyIGluc3RhbmNlb2YgT2JzZXJ2YWJsZSkgJiYgIShldmVudEVtaXR0ZXIgaW5zdGFuY2VvZiBPdXRwdXRFbWl0dGVyUmVmKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke1N0cmluZyhvdXRwdXQpfSBpcyBub3QgYW4gQE91dHB1dCBvciBhbiBvdXRwdXQgZnVuY3Rpb25gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXZlbnRFbWl0dGVyO1xuICB9XG5cbiAgcHVibGljIHRpY2sobWlsbGlzPzogbnVtYmVyKTogdm9pZCB7XG4gICAgdGljayhtaWxsaXMpO1xuICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIGNsaWNrKHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50ID0gdGhpcy5lbGVtZW50KTogdm9pZCB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0TmF0aXZlRWxlbWVudChzZWxlY3Rvcik7XG5cbiAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjbGljazogJHtzZWxlY3Rvcn0gaXMgbm90IGEgSFRNTEVsZW1lbnRgKTtcbiAgICB9XG5cbiAgICBlbGVtZW50LmNsaWNrKCk7XG4gICAgdGhpcy5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwdWJsaWMgYmx1cihzZWxlY3RvcjogU3BlY3RhdG9yRWxlbWVudCA9IHRoaXMuZWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldE5hdGl2ZUVsZW1lbnQoc2VsZWN0b3IpO1xuXG4gICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgYmx1cjogJHtzZWxlY3Rvcn0gaXMgbm90IGEgSFRNTEVsZW1lbnRgKTtcbiAgICB9XG5cbiAgICBwYXRjaEVsZW1lbnRGb2N1cyhlbGVtZW50KTtcbiAgICBlbGVtZW50LmJsdXIoKTtcbiAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBmb2N1cyhzZWxlY3RvcjogU3BlY3RhdG9yRWxlbWVudCA9IHRoaXMuZWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldE5hdGl2ZUVsZW1lbnQoc2VsZWN0b3IpO1xuXG4gICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZm9jdXM6ICR7c2VsZWN0b3J9IGlzIG5vdCBhIEhUTUxFbGVtZW50YCk7XG4gICAgfVxuXG4gICAgcGF0Y2hFbGVtZW50Rm9jdXMoZWxlbWVudCk7XG4gICAgZWxlbWVudC5mb2N1cygpO1xuICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIGRpc3BhdGNoTW91c2VFdmVudChcbiAgICBzZWxlY3RvcjogU3BlY3RhdG9yRWxlbWVudCA9IHRoaXMuZWxlbWVudCxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgeDogbnVtYmVyID0gMCxcbiAgICB5OiBudW1iZXIgPSAwLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50ID0gY3JlYXRlTW91c2VFdmVudCh0eXBlLCB4LCB5KSxcbiAgKTogTW91c2VFdmVudCB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0TmF0aXZlRWxlbWVudChzZWxlY3Rvcik7XG5cbiAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgTm9kZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGRpc3BhdGNoIG1vdXNlIGV2ZW50OiAke3NlbGVjdG9yfSBpcyBub3QgYSBub2RlYCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGlzcGF0Y2hlZEV2ZW50ID0gZGlzcGF0Y2hNb3VzZUV2ZW50KGVsZW1lbnQsIHR5cGUsIHgsIHksIGV2ZW50KTtcbiAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcblxuICAgIHJldHVybiBkaXNwYXRjaGVkRXZlbnQ7XG4gIH1cblxuICBwdWJsaWMgZGlzcGF0Y2hLZXlib2FyZEV2ZW50KHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50LCB0eXBlOiBzdHJpbmcsIGtleUNvZGU6IG51bWJlciwgdGFyZ2V0PzogRWxlbWVudCk6IEtleWJvYXJkRXZlbnQ7XG4gIHB1YmxpYyBkaXNwYXRjaEtleWJvYXJkRXZlbnQoc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQsIHR5cGU6IHN0cmluZywga2V5OiBzdHJpbmcsIHRhcmdldD86IEVsZW1lbnQpOiBLZXlib2FyZEV2ZW50O1xuICBwdWJsaWMgZGlzcGF0Y2hLZXlib2FyZEV2ZW50KHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50LCB0eXBlOiBzdHJpbmcsIGtleUFuZENvZGU6IEtleWJvYXJkRXZlbnRPcHRpb25zLCB0YXJnZXQ/OiBFbGVtZW50KTogS2V5Ym9hcmRFdmVudDtcbiAgcHVibGljIGRpc3BhdGNoS2V5Ym9hcmRFdmVudChcbiAgICBzZWxlY3RvcjogU3BlY3RhdG9yRWxlbWVudCA9IHRoaXMuZWxlbWVudCxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAga2V5T3JLZXlDb2RlOiBzdHJpbmcgfCBudW1iZXIgfCBLZXlib2FyZEV2ZW50T3B0aW9ucyxcbiAgICB0YXJnZXQ/OiBFbGVtZW50LFxuICApOiBLZXlib2FyZEV2ZW50IHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXROYXRpdmVFbGVtZW50KHNlbGVjdG9yKTtcblxuICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBOb2RlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZGlzcGF0Y2gga2V5Ym9hcmQgZXZlbnQ6ICR7c2VsZWN0b3J9IGlzIG5vdCBhIG5vZGVgKTtcbiAgICB9XG5cbiAgICBjb25zdCBldmVudCA9IGRpc3BhdGNoS2V5Ym9hcmRFdmVudChlbGVtZW50LCB0eXBlLCBrZXlPcktleUNvZGUsIHRhcmdldCk7XG5cbiAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcblxuICAgIHJldHVybiBldmVudDtcbiAgfVxuXG4gIHB1YmxpYyBkaXNwYXRjaEZha2VFdmVudChzZWxlY3RvcjogU3BlY3RhdG9yRWxlbWVudCA9IHRoaXMuZWxlbWVudCwgdHlwZTogc3RyaW5nLCBjYW5CdWJibGU/OiBib29sZWFuKTogRXZlbnQge1xuICAgIGNvbnN0IGV2ZW50ID0gZGlzcGF0Y2hGYWtlRXZlbnQodGhpcy5nZXROYXRpdmVFbGVtZW50KHNlbGVjdG9yKSwgdHlwZSwgY2FuQnViYmxlKTtcbiAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcblxuICAgIHJldHVybiBldmVudDtcbiAgfVxuXG4gIHB1YmxpYyB0cmlnZ2VyRXZlbnRIYW5kbGVyPEMgPSBhbnksIEsgZXh0ZW5kcyBLZXlzTWF0Y2hpbmc8QywgRXZlbnRFbWl0dGVyPGFueT4gfCBPdXRwdXRFbWl0dGVyUmVmPGFueT4+ID0gYW55PihcbiAgICBkaXJlY3RpdmVPclNlbGVjdG9yOiBUeXBlPEM+IHwgc3RyaW5nIHwgRGVidWdFbGVtZW50LFxuICAgIGV2ZW50TmFtZTogSyxcbiAgICBldmVudE9iajogT3V0cHV0VHlwZTxDW0tdPixcbiAgICBvcHRpb25zPzogeyByb290OiBib29sZWFuIH0sXG4gICkge1xuICAgIGNvbnN0IHRyaWdnZXJEZWJ1Z0VsZW1lbnQgPSB0aGlzLmdldERlYnVnRWxlbWVudChkaXJlY3RpdmVPclNlbGVjdG9yLCBvcHRpb25zKTtcbiAgICBpZiAoIXRyaWdnZXJEZWJ1Z0VsZW1lbnQpIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgIGNvbnNvbGUuZXJyb3IoYCR7ZGlyZWN0aXZlT3JTZWxlY3Rvcn0gZG9lcyBub3QgZXhpc3RzYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJpZ2dlckRlYnVnRWxlbWVudC50cmlnZ2VyRXZlbnRIYW5kbGVyKGV2ZW50TmFtZSBhcyBzdHJpbmcsIGV2ZW50T2JqKTtcblxuICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIGdldCBrZXlib2FyZCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcHJlc3NLZXk6IChrZXk6IHN0cmluZywgc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQgPSB0aGlzLmVsZW1lbnQsIGV2ZW50ID0gS0VZX1VQKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hLZXlib2FyZEV2ZW50KHNlbGVjdG9yLCBldmVudCwga2V5KTtcbiAgICAgIH0sXG4gICAgICBwcmVzc0VzY2FwZTogKHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50ID0gdGhpcy5lbGVtZW50LCBldmVudCA9IEtFWV9VUCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3BhdGNoS2V5Ym9hcmRFdmVudChzZWxlY3RvciwgZXZlbnQsIHsga2V5OiAnRXNjYXBlJywga2V5Q29kZTogMjcgfSk7XG4gICAgICB9LFxuICAgICAgcHJlc3NFbnRlcjogKHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50ID0gdGhpcy5lbGVtZW50LCBldmVudCA9IEtFWV9VUCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3BhdGNoS2V5Ym9hcmRFdmVudChzZWxlY3RvciwgZXZlbnQsIHsga2V5OiAnRW50ZXInLCBrZXlDb2RlOiAxMyB9KTtcbiAgICAgIH0sXG4gICAgICBwcmVzc1RhYjogKHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50ID0gdGhpcy5lbGVtZW50LCBldmVudCA9IEtFWV9VUCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3BhdGNoS2V5Ym9hcmRFdmVudChzZWxlY3RvciwgZXZlbnQsIHsga2V5OiAnVGFiJywga2V5Q29kZTogOSB9KTtcbiAgICAgIH0sXG4gICAgICBwcmVzc0JhY2tzcGFjZTogKHNlbGVjdG9yOiBTcGVjdGF0b3JFbGVtZW50ID0gdGhpcy5lbGVtZW50LCBldmVudCA9IEtFWV9VUCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3BhdGNoS2V5Ym9hcmRFdmVudChzZWxlY3RvciwgZXZlbnQsIHsga2V5OiAnQmFja3NwYWNlJywga2V5Q29kZTogOCB9KTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgbW91c2UoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRleHRtZW51OiAoc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQgPSB0aGlzLmVsZW1lbnQpID0+IHtcbiAgICAgICAgdGhpcy5kaXNwYXRjaE1vdXNlRXZlbnQoc2VsZWN0b3IsICdjb250ZXh0bWVudScpO1xuICAgICAgfSxcbiAgICAgIGRibGNsaWNrOiAoc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQgPSB0aGlzLmVsZW1lbnQpID0+IHtcbiAgICAgICAgdGhpcy5kaXNwYXRjaE1vdXNlRXZlbnQoc2VsZWN0b3IsICdkYmxjbGljaycpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGRpc3BhdGNoVG91Y2hFdmVudChzZWxlY3RvcjogU3BlY3RhdG9yRWxlbWVudCA9IHRoaXMuZWxlbWVudCwgdHlwZTogc3RyaW5nLCB4OiBudW1iZXIgPSAwLCB5OiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgZGlzcGF0Y2hUb3VjaEV2ZW50KHRoaXMuZ2V0TmF0aXZlRWxlbWVudChzZWxlY3RvciksIHR5cGUsIHgsIHkpO1xuICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIHR5cGVJbkVsZW1lbnQodmFsdWU6IHN0cmluZywgc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQgPSB0aGlzLmVsZW1lbnQpOiB2b2lkIHtcbiAgICB0eXBlSW5FbGVtZW50KHZhbHVlLCB0aGlzLmdldE5hdGl2ZUVsZW1lbnQoc2VsZWN0b3IpKTtcbiAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZWxlY3RPcHRpb24oXG4gICAgc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQgPSB0aGlzLmVsZW1lbnQsXG4gICAgb3B0aW9uczogc3RyaW5nIHwgc3RyaW5nW10gfCBIVE1MT3B0aW9uRWxlbWVudCB8IEhUTUxPcHRpb25FbGVtZW50W10sXG4gICAgY29uZmlnOiB7IGVtaXRFdmVudHM6IGJvb2xlYW4gfSA9IHsgZW1pdEV2ZW50czogdHJ1ZSB9LFxuICApOiB2b2lkIHtcbiAgICBpZiAoIXNlbGVjdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIHNlbGVjdDogJHtzZWxlY3Rvcn1gKTtcbiAgICB9XG4gICAgc2VsZWN0T3B0aW9uKG9wdGlvbnMsIHRoaXMuZ2V0TmF0aXZlRWxlbWVudChzZWxlY3RvciksIGNvbmZpZyk7XG4gICAgdGhpcy5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIGdldE5hdGl2ZUVsZW1lbnQoc2VsZWN0b3I6IFNwZWN0YXRvckVsZW1lbnQpOiBIVE1MRWxlbWVudCB8IFdpbmRvdyB8IERvY3VtZW50IHtcbiAgICBsZXQgZWxlbWVudDtcblxuICAgIC8vIFN1cHBvcnQgZ2xvYmFsIG9iamVjdHMgd2luZG93IGFuZCBkb2N1bWVudFxuICAgIGlmIChzZWxlY3RvciA9PT0gd2luZG93IHx8IHNlbGVjdG9yID09PSBkb2N1bWVudCkge1xuICAgICAgcmV0dXJuIHNlbGVjdG9yIGFzIGFueTtcbiAgICB9XG5cbiAgICBpZiAoaXNTdHJpbmcoc2VsZWN0b3IpKSB7XG4gICAgICBjb25zdCBleGlzdHMgPSB0aGlzLmRlYnVnRWxlbWVudC5xdWVyeShCeS5jc3Moc2VsZWN0b3IpKTtcbiAgICAgIGlmIChleGlzdHMpIHtcbiAgICAgICAgZWxlbWVudCA9IGV4aXN0cy5uYXRpdmVFbGVtZW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICBjb25zb2xlLmVycm9yKGAke3NlbGVjdG9yfSBkb2VzIG5vdCBleGlzdHNgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNlbGVjdG9yIGluc3RhbmNlb2YgRE9NU2VsZWN0b3IpIHtcbiAgICAgIGVsZW1lbnQgPSBzZWxlY3Rvci5leGVjdXRlKGRvY3VtZW50IGFzIGFueSlbMF0gfHwgbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHNlbGVjdG9yIGluc3RhbmNlb2YgRGVidWdFbGVtZW50IHx8IHNlbGVjdG9yIGluc3RhbmNlb2YgRWxlbWVudFJlZikge1xuICAgICAgICBlbGVtZW50ID0gc2VsZWN0b3IubmF0aXZlRWxlbWVudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBzZWxlY3RvcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGVidWdFbGVtZW50KFxuICAgIGRpcmVjdGl2ZU9yU2VsZWN0b3I6IHN0cmluZyB8IERlYnVnRWxlbWVudCB8IFR5cGU8dW5rbm93bj4sXG4gICAgb3B0aW9ucz86IHsgcm9vdDogYm9vbGVhbiB9LFxuICApOiBEZWJ1Z0VsZW1lbnQgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGRlYnVnRWxlbWVudCA9IG9wdGlvbnM/LnJvb3QgPyB0aGlzLmdldFJvb3REZWJ1Z0VsZW1lbnQoKSA6IHRoaXMuZGVidWdFbGVtZW50O1xuXG4gICAgaWYgKGlzU3RyaW5nKGRpcmVjdGl2ZU9yU2VsZWN0b3IpKSB7XG4gICAgICByZXR1cm4gZGVidWdFbGVtZW50LnF1ZXJ5KEJ5LmNzcyhkaXJlY3RpdmVPclNlbGVjdG9yKSk7XG4gICAgfSBlbHNlIGlmIChkaXJlY3RpdmVPclNlbGVjdG9yIGluc3RhbmNlb2YgRGVidWdFbGVtZW50KSB7XG4gICAgICByZXR1cm4gZGlyZWN0aXZlT3JTZWxlY3RvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRlYnVnRWxlbWVudC5xdWVyeShCeS5kaXJlY3RpdmUoZGlyZWN0aXZlT3JTZWxlY3RvcikpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Um9vdERlYnVnRWxlbWVudCgpOiBEZWJ1Z0VsZW1lbnQge1xuICAgIGxldCBlbGVtZW50OiBEZWJ1Z0VsZW1lbnQgfCBudWxsIHwgdW5kZWZpbmVkID0gdGhpcy5kZWJ1Z0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGJvdW5kZWQgbG9vcCBjYWxsIGlzIHJlcXVpcmVkIHRvIGFjY2VzcyB0aGUgZGVidWcgZWxlbWVudCBmb3JcbiAgICAgKiByb290IGRvbSBlbGVtZW50XG4gICAgICovXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICB0aHJvdyBFcnJvcignVW5hYmxlIHRvIGZpbmQgcm9vdCBlbGVtZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghZWxlbWVudC5wYXJlbnQpIHtcbiAgICAgICAgLy8gRm91bmQgdGhlIHJvb3QgZWxlbWVudFxuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgIH1cblxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50O1xuICAgIH1cbiAgfVxufVxuIl19