You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
414 lines
54 KiB
414 lines
54 KiB
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
import { _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
|
|
import { DOCUMENT } from '@angular/common';
|
|
import { Directive, ElementRef, Inject, Injectable, Input, NgZone, } from '@angular/core';
|
|
import { take } from 'rxjs/operators';
|
|
import { InteractivityChecker } from '../interactivity-checker/interactivity-checker';
|
|
import * as i0 from "@angular/core";
|
|
import * as i1 from "../interactivity-checker/interactivity-checker";
|
|
import * as i2 from "@angular/common";
|
|
/**
|
|
* Class that allows for trapping focus within a DOM element.
|
|
*
|
|
* This class currently uses a relatively simple approach to focus trapping.
|
|
* It assumes that the tab order is the same as DOM order, which is not necessarily true.
|
|
* Things like `tabIndex > 0`, flex `order`, and shadow roots can cause the two to be misaligned.
|
|
*
|
|
* @deprecated Use `ConfigurableFocusTrap` instead.
|
|
* @breaking-change 11.0.0
|
|
*/
|
|
import * as ɵngcc0 from '@angular/core';
|
|
import * as ɵngcc1 from '../interactivity-checker/interactivity-checker';
|
|
export class FocusTrap {
|
|
constructor(_element, _checker, _ngZone, _document, deferAnchors = false) {
|
|
this._element = _element;
|
|
this._checker = _checker;
|
|
this._ngZone = _ngZone;
|
|
this._document = _document;
|
|
this._hasAttached = false;
|
|
// Event listeners for the anchors. Need to be regular functions so that we can unbind them later.
|
|
this.startAnchorListener = () => this.focusLastTabbableElement();
|
|
this.endAnchorListener = () => this.focusFirstTabbableElement();
|
|
this._enabled = true;
|
|
if (!deferAnchors) {
|
|
this.attachAnchors();
|
|
}
|
|
}
|
|
/** Whether the focus trap is active. */
|
|
get enabled() { return this._enabled; }
|
|
set enabled(value) {
|
|
this._enabled = value;
|
|
if (this._startAnchor && this._endAnchor) {
|
|
this._toggleAnchorTabIndex(value, this._startAnchor);
|
|
this._toggleAnchorTabIndex(value, this._endAnchor);
|
|
}
|
|
}
|
|
/** Destroys the focus trap by cleaning up the anchors. */
|
|
destroy() {
|
|
const startAnchor = this._startAnchor;
|
|
const endAnchor = this._endAnchor;
|
|
if (startAnchor) {
|
|
startAnchor.removeEventListener('focus', this.startAnchorListener);
|
|
if (startAnchor.parentNode) {
|
|
startAnchor.parentNode.removeChild(startAnchor);
|
|
}
|
|
}
|
|
if (endAnchor) {
|
|
endAnchor.removeEventListener('focus', this.endAnchorListener);
|
|
if (endAnchor.parentNode) {
|
|
endAnchor.parentNode.removeChild(endAnchor);
|
|
}
|
|
}
|
|
this._startAnchor = this._endAnchor = null;
|
|
this._hasAttached = false;
|
|
}
|
|
/**
|
|
* Inserts the anchors into the DOM. This is usually done automatically
|
|
* in the constructor, but can be deferred for cases like directives with `*ngIf`.
|
|
* @returns Whether the focus trap managed to attach successfully. This may not be the case
|
|
* if the target element isn't currently in the DOM.
|
|
*/
|
|
attachAnchors() {
|
|
// If we're not on the browser, there can be no focus to trap.
|
|
if (this._hasAttached) {
|
|
return true;
|
|
}
|
|
this._ngZone.runOutsideAngular(() => {
|
|
if (!this._startAnchor) {
|
|
this._startAnchor = this._createAnchor();
|
|
this._startAnchor.addEventListener('focus', this.startAnchorListener);
|
|
}
|
|
if (!this._endAnchor) {
|
|
this._endAnchor = this._createAnchor();
|
|
this._endAnchor.addEventListener('focus', this.endAnchorListener);
|
|
}
|
|
});
|
|
if (this._element.parentNode) {
|
|
this._element.parentNode.insertBefore(this._startAnchor, this._element);
|
|
this._element.parentNode.insertBefore(this._endAnchor, this._element.nextSibling);
|
|
this._hasAttached = true;
|
|
}
|
|
return this._hasAttached;
|
|
}
|
|
/**
|
|
* Waits for the zone to stabilize, then either focuses the first element that the
|
|
* user specified, or the first tabbable element.
|
|
* @returns Returns a promise that resolves with a boolean, depending
|
|
* on whether focus was moved successfully.
|
|
*/
|
|
focusInitialElementWhenReady(options) {
|
|
return new Promise(resolve => {
|
|
this._executeOnStable(() => resolve(this.focusInitialElement(options)));
|
|
});
|
|
}
|
|
/**
|
|
* Waits for the zone to stabilize, then focuses
|
|
* the first tabbable element within the focus trap region.
|
|
* @returns Returns a promise that resolves with a boolean, depending
|
|
* on whether focus was moved successfully.
|
|
*/
|
|
focusFirstTabbableElementWhenReady(options) {
|
|
return new Promise(resolve => {
|
|
this._executeOnStable(() => resolve(this.focusFirstTabbableElement(options)));
|
|
});
|
|
}
|
|
/**
|
|
* Waits for the zone to stabilize, then focuses
|
|
* the last tabbable element within the focus trap region.
|
|
* @returns Returns a promise that resolves with a boolean, depending
|
|
* on whether focus was moved successfully.
|
|
*/
|
|
focusLastTabbableElementWhenReady(options) {
|
|
return new Promise(resolve => {
|
|
this._executeOnStable(() => resolve(this.focusLastTabbableElement(options)));
|
|
});
|
|
}
|
|
/**
|
|
* Get the specified boundary element of the trapped region.
|
|
* @param bound The boundary to get (start or end of trapped region).
|
|
* @returns The boundary element.
|
|
*/
|
|
_getRegionBoundary(bound) {
|
|
// Contains the deprecated version of selector, for temporary backwards comparability.
|
|
let markers = this._element.querySelectorAll(`[cdk-focus-region-${bound}], ` +
|
|
`[cdkFocusRegion${bound}], ` +
|
|
`[cdk-focus-${bound}]`);
|
|
for (let i = 0; i < markers.length; i++) {
|
|
// @breaking-change 8.0.0
|
|
if (markers[i].hasAttribute(`cdk-focus-${bound}`)) {
|
|
console.warn(`Found use of deprecated attribute 'cdk-focus-${bound}', ` +
|
|
`use 'cdkFocusRegion${bound}' instead. The deprecated ` +
|
|
`attribute will be removed in 8.0.0.`, markers[i]);
|
|
}
|
|
else if (markers[i].hasAttribute(`cdk-focus-region-${bound}`)) {
|
|
console.warn(`Found use of deprecated attribute 'cdk-focus-region-${bound}', ` +
|
|
`use 'cdkFocusRegion${bound}' instead. The deprecated attribute ` +
|
|
`will be removed in 8.0.0.`, markers[i]);
|
|
}
|
|
}
|
|
if (bound == 'start') {
|
|
return markers.length ? markers[0] : this._getFirstTabbableElement(this._element);
|
|
}
|
|
return markers.length ?
|
|
markers[markers.length - 1] : this._getLastTabbableElement(this._element);
|
|
}
|
|
/**
|
|
* Focuses the element that should be focused when the focus trap is initialized.
|
|
* @returns Whether focus was moved successfully.
|
|
*/
|
|
focusInitialElement(options) {
|
|
// Contains the deprecated version of selector, for temporary backwards comparability.
|
|
const redirectToElement = this._element.querySelector(`[cdk-focus-initial], ` +
|
|
`[cdkFocusInitial]`);
|
|
if (redirectToElement) {
|
|
// @breaking-change 8.0.0
|
|
if (redirectToElement.hasAttribute(`cdk-focus-initial`)) {
|
|
console.warn(`Found use of deprecated attribute 'cdk-focus-initial', ` +
|
|
`use 'cdkFocusInitial' instead. The deprecated attribute ` +
|
|
`will be removed in 8.0.0`, redirectToElement);
|
|
}
|
|
// Warn the consumer if the element they've pointed to
|
|
// isn't focusable, when not in production mode.
|
|
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
!this._checker.isFocusable(redirectToElement)) {
|
|
console.warn(`Element matching '[cdkFocusInitial]' is not focusable.`, redirectToElement);
|
|
}
|
|
if (!this._checker.isFocusable(redirectToElement)) {
|
|
const focusableChild = this._getFirstTabbableElement(redirectToElement);
|
|
focusableChild === null || focusableChild === void 0 ? void 0 : focusableChild.focus(options);
|
|
return !!focusableChild;
|
|
}
|
|
redirectToElement.focus(options);
|
|
return true;
|
|
}
|
|
return this.focusFirstTabbableElement(options);
|
|
}
|
|
/**
|
|
* Focuses the first tabbable element within the focus trap region.
|
|
* @returns Whether focus was moved successfully.
|
|
*/
|
|
focusFirstTabbableElement(options) {
|
|
const redirectToElement = this._getRegionBoundary('start');
|
|
if (redirectToElement) {
|
|
redirectToElement.focus(options);
|
|
}
|
|
return !!redirectToElement;
|
|
}
|
|
/**
|
|
* Focuses the last tabbable element within the focus trap region.
|
|
* @returns Whether focus was moved successfully.
|
|
*/
|
|
focusLastTabbableElement(options) {
|
|
const redirectToElement = this._getRegionBoundary('end');
|
|
if (redirectToElement) {
|
|
redirectToElement.focus(options);
|
|
}
|
|
return !!redirectToElement;
|
|
}
|
|
/**
|
|
* Checks whether the focus trap has successfully been attached.
|
|
*/
|
|
hasAttached() {
|
|
return this._hasAttached;
|
|
}
|
|
/** Get the first tabbable element from a DOM subtree (inclusive). */
|
|
_getFirstTabbableElement(root) {
|
|
if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
|
|
return root;
|
|
}
|
|
// Iterate in DOM order. Note that IE doesn't have `children` for SVG so we fall
|
|
// back to `childNodes` which includes text nodes, comments etc.
|
|
let children = root.children || root.childNodes;
|
|
for (let i = 0; i < children.length; i++) {
|
|
let tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ?
|
|
this._getFirstTabbableElement(children[i]) :
|
|
null;
|
|
if (tabbableChild) {
|
|
return tabbableChild;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
/** Get the last tabbable element from a DOM subtree (inclusive). */
|
|
_getLastTabbableElement(root) {
|
|
if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
|
|
return root;
|
|
}
|
|
// Iterate in reverse DOM order.
|
|
let children = root.children || root.childNodes;
|
|
for (let i = children.length - 1; i >= 0; i--) {
|
|
let tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ?
|
|
this._getLastTabbableElement(children[i]) :
|
|
null;
|
|
if (tabbableChild) {
|
|
return tabbableChild;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
/** Creates an anchor element. */
|
|
_createAnchor() {
|
|
const anchor = this._document.createElement('div');
|
|
this._toggleAnchorTabIndex(this._enabled, anchor);
|
|
anchor.classList.add('cdk-visually-hidden');
|
|
anchor.classList.add('cdk-focus-trap-anchor');
|
|
anchor.setAttribute('aria-hidden', 'true');
|
|
return anchor;
|
|
}
|
|
/**
|
|
* Toggles the `tabindex` of an anchor, based on the enabled state of the focus trap.
|
|
* @param isEnabled Whether the focus trap is enabled.
|
|
* @param anchor Anchor on which to toggle the tabindex.
|
|
*/
|
|
_toggleAnchorTabIndex(isEnabled, anchor) {
|
|
// Remove the tabindex completely, rather than setting it to -1, because if the
|
|
// element has a tabindex, the user might still hit it when navigating with the arrow keys.
|
|
isEnabled ? anchor.setAttribute('tabindex', '0') : anchor.removeAttribute('tabindex');
|
|
}
|
|
/**
|
|
* Toggles the`tabindex` of both anchors to either trap Tab focus or allow it to escape.
|
|
* @param enabled: Whether the anchors should trap Tab.
|
|
*/
|
|
toggleAnchors(enabled) {
|
|
if (this._startAnchor && this._endAnchor) {
|
|
this._toggleAnchorTabIndex(enabled, this._startAnchor);
|
|
this._toggleAnchorTabIndex(enabled, this._endAnchor);
|
|
}
|
|
}
|
|
/** Executes a function when the zone is stable. */
|
|
_executeOnStable(fn) {
|
|
if (this._ngZone.isStable) {
|
|
fn();
|
|
}
|
|
else {
|
|
this._ngZone.onStable.pipe(take(1)).subscribe(fn);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Factory that allows easy instantiation of focus traps.
|
|
* @deprecated Use `ConfigurableFocusTrapFactory` instead.
|
|
* @breaking-change 11.0.0
|
|
*/
|
|
export class FocusTrapFactory {
|
|
constructor(_checker, _ngZone, _document) {
|
|
this._checker = _checker;
|
|
this._ngZone = _ngZone;
|
|
this._document = _document;
|
|
}
|
|
/**
|
|
* Creates a focus-trapped region around the given element.
|
|
* @param element The element around which focus will be trapped.
|
|
* @param deferCaptureElements Defers the creation of focus-capturing elements to be done
|
|
* manually by the user.
|
|
* @returns The created focus trap instance.
|
|
*/
|
|
create(element, deferCaptureElements = false) {
|
|
return new FocusTrap(element, this._checker, this._ngZone, this._document, deferCaptureElements);
|
|
}
|
|
}
|
|
FocusTrapFactory.ɵfac = function FocusTrapFactory_Factory(t) { return new (t || FocusTrapFactory)(ɵngcc0.ɵɵinject(ɵngcc1.InteractivityChecker), ɵngcc0.ɵɵinject(ɵngcc0.NgZone), ɵngcc0.ɵɵinject(DOCUMENT)); };
|
|
FocusTrapFactory.ɵprov = i0.ɵɵdefineInjectable({ factory: function FocusTrapFactory_Factory() { return new FocusTrapFactory(i0.ɵɵinject(i1.InteractivityChecker), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i2.DOCUMENT)); }, token: FocusTrapFactory, providedIn: "root" });
|
|
FocusTrapFactory.ctorParameters = () => [
|
|
{ type: InteractivityChecker },
|
|
{ type: NgZone },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(FocusTrapFactory, [{
|
|
type: Injectable,
|
|
args: [{ providedIn: 'root' }]
|
|
}], function () { return [{ type: ɵngcc1.InteractivityChecker }, { type: ɵngcc0.NgZone }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [DOCUMENT]
|
|
}] }]; }, null); })();
|
|
/** Directive for trapping focus within a region. */
|
|
export class CdkTrapFocus {
|
|
constructor(_elementRef, _focusTrapFactory,
|
|
/**
|
|
* @deprecated No longer being used. To be removed.
|
|
* @breaking-change 13.0.0
|
|
*/
|
|
_document) {
|
|
this._elementRef = _elementRef;
|
|
this._focusTrapFactory = _focusTrapFactory;
|
|
/** Previously focused element to restore focus to upon destroy when using autoCapture. */
|
|
this._previouslyFocusedElement = null;
|
|
this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true);
|
|
}
|
|
/** Whether the focus trap is active. */
|
|
get enabled() { return this.focusTrap.enabled; }
|
|
set enabled(value) { this.focusTrap.enabled = coerceBooleanProperty(value); }
|
|
/**
|
|
* Whether the directive should automatically move focus into the trapped region upon
|
|
* initialization and return focus to the previous activeElement upon destruction.
|
|
*/
|
|
get autoCapture() { return this._autoCapture; }
|
|
set autoCapture(value) { this._autoCapture = coerceBooleanProperty(value); }
|
|
ngOnDestroy() {
|
|
this.focusTrap.destroy();
|
|
// If we stored a previously focused element when using autoCapture, return focus to that
|
|
// element now that the trapped region is being destroyed.
|
|
if (this._previouslyFocusedElement) {
|
|
this._previouslyFocusedElement.focus();
|
|
this._previouslyFocusedElement = null;
|
|
}
|
|
}
|
|
ngAfterContentInit() {
|
|
this.focusTrap.attachAnchors();
|
|
if (this.autoCapture) {
|
|
this._captureFocus();
|
|
}
|
|
}
|
|
ngDoCheck() {
|
|
if (!this.focusTrap.hasAttached()) {
|
|
this.focusTrap.attachAnchors();
|
|
}
|
|
}
|
|
ngOnChanges(changes) {
|
|
const autoCaptureChange = changes['autoCapture'];
|
|
if (autoCaptureChange && !autoCaptureChange.firstChange && this.autoCapture &&
|
|
this.focusTrap.hasAttached()) {
|
|
this._captureFocus();
|
|
}
|
|
}
|
|
_captureFocus() {
|
|
this._previouslyFocusedElement = _getFocusedElementPierceShadowDom();
|
|
this.focusTrap.focusInitialElementWhenReady();
|
|
}
|
|
}
|
|
CdkTrapFocus.ɵfac = function CdkTrapFocus_Factory(t) { return new (t || CdkTrapFocus)(ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ElementRef), ɵngcc0.ɵɵdirectiveInject(FocusTrapFactory), ɵngcc0.ɵɵdirectiveInject(DOCUMENT)); };
|
|
CdkTrapFocus.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: CdkTrapFocus, selectors: [["", "cdkTrapFocus", ""]], inputs: { enabled: ["cdkTrapFocus", "enabled"], autoCapture: ["cdkTrapFocusAutoCapture", "autoCapture"] }, exportAs: ["cdkTrapFocus"], features: [ɵngcc0.ɵɵNgOnChangesFeature] });
|
|
CdkTrapFocus.ctorParameters = () => [
|
|
{ type: ElementRef },
|
|
{ type: FocusTrapFactory },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
|
|
];
|
|
CdkTrapFocus.propDecorators = {
|
|
enabled: [{ type: Input, args: ['cdkTrapFocus',] }],
|
|
autoCapture: [{ type: Input, args: ['cdkTrapFocusAutoCapture',] }]
|
|
};
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(CdkTrapFocus, [{
|
|
type: Directive,
|
|
args: [{
|
|
selector: '[cdkTrapFocus]',
|
|
exportAs: 'cdkTrapFocus'
|
|
}]
|
|
}], function () { return [{ type: ɵngcc0.ElementRef }, { type: FocusTrapFactory }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [DOCUMENT]
|
|
}] }]; }, { enabled: [{
|
|
type: Input,
|
|
args: ['cdkTrapFocus']
|
|
}], autoCapture: [{
|
|
type: Input,
|
|
args: ['cdkTrapFocusAutoCapture']
|
|
}] }); })();
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9jdXMtdHJhcC5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2Nkay9hMTF5L2ZvY3VzLXRyYXAvZm9jdXMtdHJhcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBRUgsT0FBTyxFQUFlLHFCQUFxQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDMUUsT0FBTyxFQUFDLGlDQUFpQyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFFTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLE1BQU0sRUFDTixVQUFVLEVBQ1YsS0FBSyxFQUNMLE1BQU0sR0FLUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEMsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sZ0RBQWdELENBQUM7QUFDcEY7QUFHK0I7QUFFSztBQUhwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOzs7QUFDSCxNQUFNLE9BQU8sU0FBUztBQUN0QixJQW9CRSxZQUNXLFFBQXFCLEVBQ3RCLFFBQThCLEVBQzdCLE9BQWUsRUFDZixTQUFtQixFQUM1QixZQUFZLEdBQUcsS0FBSztBQUN4QixRQUxhLGFBQVEsR0FBUixRQUFRLENBQWE7QUFBQyxRQUN2QixhQUFRLEdBQVIsUUFBUSxDQUFzQjtBQUFDLFFBQzlCLFlBQU8sR0FBUCxPQUFPLENBQVE7QUFBQyxRQUNoQixjQUFTLEdBQVQsU0FBUyxDQUFVO0FBQUMsUUF0QnZCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO0FBQy9CLFFBQ0Usa0dBQWtHO0FBQ3BHLFFBQVksd0JBQW1CLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7QUFD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b3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtCb29sZWFuSW5wdXQsIGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7X2dldEZvY3VzZWRFbGVtZW50UGllcmNlU2hhZG93RG9tfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIERvQ2hlY2ssXG4gIFNpbXBsZUNoYW5nZXMsXG4gIE9uQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge3Rha2V9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7SW50ZXJhY3Rpdml0eUNoZWNrZXJ9IGZyb20gJy4uL2ludGVyYWN0aXZpdHktY2hlY2tlci9pbnRlcmFjdGl2aXR5LWNoZWNrZXInO1xuXG5cbi8qKlxuICogQ2xhc3MgdGhhdCBhbGxvd3MgZm9yIHRyYXBwaW5nIGZvY3VzIHdpdGhpbiBhIERPTSBlbGVtZW50LlxuICpcbiAqIFRoaXMgY2xhc3MgY3VycmVudGx5IHVzZXMgYSByZWxhdGl2ZWx5IHNpbXBsZSBhcHByb2FjaCB0byBmb2N1cyB0cmFwcGluZy5cbiAqIEl0IGFzc3VtZXMgdGhhdCB0aGUgdGFiIG9yZGVyIGlzIHRoZSBzYW1lIGFzIERPTSBvcmRlciwgd2hpY2ggaXMgbm90IG5lY2Vzc2FyaWx5IHRydWUuXG4gKiBUaGluZ3MgbGlrZSBgdGFiSW5kZXggPiAwYCwgZmxleCBgb3JkZXJgLCBhbmQgc2hhZG93IHJvb3RzIGNhbiBjYXVzZSB0aGUgdHdvIHRvIGJlIG1pc2FsaWduZWQuXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIGBDb25maWd1cmFibGVGb2N1c1RyYXBgIGluc3RlYWQuXG4gKiBAYnJlYWtpbmctY2hhbmdlIDExLjAuMFxuICovXG5leHBvcnQgY2xhc3MgRm9jdXNUcmFwIHtcbiAgcHJpdmF0ZSBfc3RhcnRBbmNob3I6IEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgcHJpdmF0ZSBfZW5kQW5jaG9yOiBIVE1MRWxlbWVudCB8IG51bGw7XG4gIHByaXZhdGUgX2hhc0F0dGFjaGVkID0gZmFsc2U7XG5cbiAgLy8gRXZlbnQgbGlzdGVuZXJzIGZvciB0aGUgYW5jaG9ycy4gTmVlZCB0byBiZSByZWd1bGFyIGZ1bmN0aW9ucyBzbyB0aGF0IHdlIGNhbiB1bmJpbmQgdGhlbSBsYXRlci5cbiAgcHJvdGVjdGVkIHN0YXJ0QW5jaG9yTGlzdGVuZXIgPSAoKSA9PiB0aGlzLmZvY3VzTGFzdFRhYmJhYmxlRWxlbWVudCgpO1xuICBwcm90ZWN0ZWQgZW5kQW5jaG9yTGlzdGVuZXIgPSAoKSA9PiB0aGlzLmZvY3VzRmlyc3RUYWJiYWJsZUVsZW1lbnQoKTtcblxuICAvKiogV2hldGhlciB0aGUgZm9jdXMgdHJhcCBpcyBhY3RpdmUuICovXG4gIGdldCBlbmFibGVkKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fZW5hYmxlZDsgfVxuICBzZXQgZW5hYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2VuYWJsZWQgPSB2YWx1ZTtcblxuICAgIGlmICh0aGlzLl9zdGFydEFuY2hvciAmJiB0aGlzLl9lbmRBbmNob3IpIHtcbiAgICAgIHRoaXMuX3RvZ2dsZUFuY2hvclRhYkluZGV4KHZhbHVlLCB0aGlzLl9zdGFydEFuY2hvcik7XG4gICAgICB0aGlzLl90b2dnbGVBbmNob3JUYWJJbmRleCh2YWx1ZSwgdGhpcy5fZW5kQW5jaG9yKTtcbiAgICB9XG4gIH1cbiAgcHJvdGVjdGVkIF9lbmFibGVkOiBib29sZWFuID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICByZWFkb25seSBfZWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgcHJpdmF0ZSBfY2hlY2tlcjogSW50ZXJhY3Rpdml0eUNoZWNrZXIsXG4gICAgcmVhZG9ubHkgX25nWm9uZTogTmdab25lLFxuICAgIHJlYWRvbmx5IF9kb2N1bWVudDogRG9jdW1lbnQsXG4gICAgZGVmZXJBbmNob3JzID0gZmFsc2UpIHtcblxuICAgIGlmICghZGVmZXJBbmNob3JzKSB7XG4gICAgICB0aGlzLmF0dGFjaEFuY2hvcnMoKTtcbiAgICB9XG4gIH1cblxuICAvKiogRGVzdHJveXMgdGhlIGZvY3VzIHRyYXAgYnkgY2xlYW5pbmcgdXAgdGhlIGFuY2hvcnMuICovXG4gIGRlc3Ryb3koKSB7XG4gICAgY29uc3Qgc3RhcnRBbmNob3IgPSB0aGlzLl9zdGFydEFuY2hvcjtcbiAgICBjb25zdCBlbmRBbmNob3IgPSB0aGlzLl9lbmRBbmNob3I7XG5cbiAgICBpZiAoc3RhcnRBbmNob3IpIHtcbiAgICAgIHN0YXJ0QW5jaG9yLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgdGhpcy5zdGFydEFuY2hvckxpc3RlbmVyKTtcblxuICAgICAgaWYgKHN0YXJ0QW5jaG9yLnBhcmVudE5vZGUpIHtcbiAgICAgICAgc3RhcnRBbmNob3IucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzdGFydEFuY2hvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVuZEFuY2hvcikge1xuICAgICAgZW5kQW5jaG9yLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgdGhpcy5lbmRBbmNob3JMaXN0ZW5lcik7XG5cbiAgICAgIGlmIChlbmRBbmNob3IucGFyZW50Tm9kZSkge1xuICAgICAgICBlbmRBbmNob3IucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbmRBbmNob3IpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3N0YXJ0QW5jaG9yID0gdGhpcy5fZW5kQW5jaG9yID0gbnVsbDtcbiAgICB0aGlzLl9oYXNBdHRhY2hlZCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc2VydHMgdGhlIGFuY2hvcnMgaW50byB0aGUgRE9NLiBUaGlzIGlzIHVzdWFsbHkgZG9uZSBhdXRvbWF0aWNhbGx5XG4gICAqIGluIHRoZSBjb25zdHJ1Y3RvciwgYnV0IGNhbiBiZSBkZWZlcnJlZCBmb3IgY2FzZXMgbGlrZSBkaXJlY3RpdmVzIHdpdGggYCpuZ0lmYC5cbiAgICogQHJldHVybnMgV2hldGhlciB0aGUgZm9jdXMgdHJhcCBtYW5hZ2VkIHRvIGF0dGFjaCBzdWNjZXNzZnVsbHkuIFRoaXMgbWF5IG5vdCBiZSB0aGUgY2FzZVxuICAgKiBpZiB0aGUgdGFyZ2V0IGVsZW1lbnQgaXNuJ3QgY3VycmVudGx5IGluIHRoZSBET00uXG4gICAqL1xuICBhdHRhY2hBbmNob3JzKCk6IGJvb2xlYW4ge1xuICAgIC8vIElmIHdlJ3JlIG5vdCBvbiB0aGUgYnJvd3NlciwgdGhlcmUgY2FuIGJlIG5vIGZvY3VzIHRvIHRyYXAuXG4gICAgaWYgKHRoaXMuX2hhc0F0dGFjaGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLl9zdGFydEFuY2hvcikge1xuICAgICAgICB0aGlzLl9zdGFydEFuY2hvciA9IHRoaXMuX2NyZWF0ZUFuY2hvcigpO1xuICAgICAgICB0aGlzLl9zdGFydEFuY2hvciEuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLnN0YXJ0QW5jaG9yTGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuX2VuZEFuY2hvcikge1xuICAgICAgICB0aGlzLl9lbmRBbmNob3IgPSB0aGlzLl9jcmVhdGVBbmNob3IoKTtcbiAgICAgICAgdGhpcy5fZW5kQW5jaG9yIS5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuZW5kQW5jaG9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuX2VsZW1lbnQucGFyZW50Tm9kZSkge1xuICAgICAgdGhpcy5fZWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLl9zdGFydEFuY2hvciEsIHRoaXMuX2VsZW1lbnQpO1xuICAgICAgdGhpcy5fZWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLl9lbmRBbmNob3IhLCB0aGlzLl9lbGVtZW50Lm5leHRTaWJsaW5nKTtcbiAgICAgIHRoaXMuX2hhc0F0dGFjaGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5faGFzQXR0YWNoZWQ7XG4gIH1cblxuICAvKipcbiAgICogV2FpdHMgZm9yIHRoZSB6b25lIHRvIHN0YWJpbGl6ZSwgdGhlbiBlaXRoZXIgZm9jdXNlcyB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IHRoZVxuICAgKiB1c2VyIHNwZWNpZmllZCwgb3IgdGhlIGZpcnN0IHRhYmJhYmxlIGVsZW1lbnQuXG4gICAqIEByZXR1cm5zIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCBhIGJvb2xlYW4sIGRlcGVuZGluZ1xuICAgKiBvbiB3aGV0aGVyIGZvY3VzIHdhcyBtb3ZlZCBzdWNjZXNzZnVsbHkuXG4gICAqL1xuICBmb2N1c0luaXRpYWxFbGVtZW50V2hlblJlYWR5KG9wdGlvbnM/OiBGb2N1c09wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8Ym9vbGVhbj4ocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLl9leGVjdXRlT25TdGFibGUoKCkgPT4gcmVzb2x2ZSh0aGlzLmZvY3VzSW5pdGlhbEVsZW1lbnQob3B0aW9ucykpKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYWl0cyBmb3IgdGhlIHpvbmUgdG8gc3RhYmlsaXplLCB0aGVuIGZvY3VzZXNcbiAgICogdGhlIGZpcnN0IHRhYmJhYmxlIGVsZW1lbnQgd2l0aGluIHRoZSBmb2N1cyB0cmFwIHJlZ2lvbi5cbiAgICogQHJldHVybnMgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGEgYm9vbGVhbiwgZGVwZW5kaW5nXG4gICAqIG9uIHdoZXRoZXIgZm9jdXMgd2FzIG1vdmVkIHN1Y2Nlc3NmdWxseS5cbiAgICovXG4gIGZvY3VzRmlyc3RUYWJiYWJsZUVsZW1lbnRXaGVuUmVhZHkob3B0aW9ucz86IEZvY3VzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxib29sZWFuPihyZXNvbHZlID0+IHtcbiAgICAgIHRoaXMuX2V4ZWN1dGVPblN0YWJsZSgoKSA9PiByZXNvbHZlKHRoaXMuZm9jdXNGaXJzdFRhYmJhYmxlRWxlbWVudChvcHRpb25zKSkpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciB0aGUgem9uZSB0byBzdGFiaWxpemUsIHRoZW4gZm9jdXNlc1xuICAgKiB0aGUgbGFzdCB0YWJiYWJsZSBlbGVtZW50IHdpdGhpbiB0aGUgZm9jdXMgdHJhcCByZWdpb24uXG4gICAqIEByZXR1cm5zIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCBhIGJvb2xlYW4sIGRlcGVuZGluZ1xuICAgKiBvbiB3aGV0aGVyIGZvY3VzIHdhcyBtb3ZlZCBzdWNjZXNzZnVsbHkuXG4gICAqL1xuICBmb2N1c0xhc3RUYWJiYWJsZUVsZW1lbnRXaGVuUmVhZHkob3B0aW9ucz86IEZvY3VzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxib29sZWFuPihyZXNvbHZlID0+IHtcbiAgICAgIHRoaXMuX2V4ZWN1dGVPblN0YWJsZSgoKSA9PiByZXNvbHZlKHRoaXMuZm9jdXNMYXN0VGFiYmFibGVFbGVtZW50KG9wdGlvbnMpKSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzcGVjaWZpZWQgYm91bmRhcnkgZWxlbWVudCBvZiB0aGUgdHJhcHBlZCByZWdpb24uXG4gICAqIEBwYXJhbSBib3VuZCBUaGUgYm91bmRhcnkgdG8gZ2V0IChzdGFydCBvciBlbmQgb2YgdHJhcHBlZCByZWdpb24pLlxuICAgKiBAcmV0dXJucyBUaGUgYm91bmRhcnkgZWxlbWVudC5cbiAgICovXG4gIHByaXZhdGUgX2dldFJlZ2lvbkJvdW5kYXJ5KGJvdW5kOiAnc3RhcnQnIHwgJ2VuZCcpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuICAgIC8vIENvbnRhaW5zIHRoZSBkZXByZWNhdGVkIHZlcnNpb24gb2Ygc2VsZWN0b3IsIGZvciB0ZW1wb3JhcnkgYmFja3dhcmRzIGNvbXBhcmFiaWxpdHkuXG4gICAgbGV0IG1hcmtlcnMgPSB0aGlzLl9lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtjZGstZm9jdXMtcmVnaW9uLSR7Ym91bmR9XSwgYCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFtjZGtGb2N1c1JlZ2lvbiR7Ym91bmR9XSwgYCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFtjZGstZm9jdXMtJHtib3VuZH1dYCkgYXMgTm9kZUxpc3RPZjxIVE1MRWxlbWVudD47XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIEBicmVha2luZy1jaGFuZ2UgOC4wLjBcbiAgICAgIGlmIChtYXJrZXJzW2ldLmhhc0F0dHJpYnV0ZShgY2RrLWZvY3VzLSR7Ym91bmR9YCkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBGb3VuZCB1c2Ugb2YgZGVwcmVjYXRlZCBhdHRyaWJ1dGUgJ2Nkay1mb2N1cy0ke2JvdW5kfScsIGAgK1xuICAgICAgICAgICAgICAgICAgICAgYHVzZSAnY2RrRm9jdXNSZWdpb24ke2JvdW5kfScgaW5zdGVhZC4gVGhlIGRlcHJlY2F0ZWQgYCArXG4gICAgICAgICAgICAgICAgICAgICBgYXR0cmlidXRlIHdpbGwgYmUgcmVtb3ZlZCBpbiA4LjAuMC5gLCBtYXJrZXJzW2ldKTtcbiAgICAgIH0gZWxzZSBpZiAobWFya2Vyc1tpXS5oYXNBdHRyaWJ1dGUoYGNkay1mb2N1cy1yZWdpb24tJHtib3VuZH1gKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYEZvdW5kIHVzZSBvZiBkZXByZWNhdGVkIGF0dHJpYnV0ZSAnY2RrLWZvY3VzLXJlZ2lvbi0ke2JvdW5kfScsIGAgK1xuICAgICAgICAgICAgICAgICAgICAgYHVzZSAnY2RrRm9jdXNSZWdpb24ke2JvdW5kfScgaW5zdGVhZC4gVGhlIGRlcHJlY2F0ZWQgYXR0cmlidXRlIGAgK1xuICAgICAgICAgICAgICAgICAgICAgYHdpbGwgYmUgcmVtb3ZlZCBpbiA4LjAuMC5gLCBtYXJrZXJzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYm91bmQgPT0gJ3N0YXJ0Jykge1xuICAgICAgcmV0dXJuIG1hcmtlcnMubGVuZ3RoID8gbWFya2Vyc1swXSA6IHRoaXMuX2dldEZpcnN0VGFiYmFibGVFbGVtZW50KHRoaXMuX2VsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gbWFya2Vycy5sZW5ndGggP1xuICAgICAgICBtYXJrZXJzW21hcmtlcnMubGVuZ3RoIC0gMV0gOiB0aGlzLl9nZXRMYXN0VGFiYmFibGVFbGVtZW50KHRoaXMuX2VsZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvY3VzZXMgdGhlIGVsZW1lbnQgdGhhdCBzaG91bGQgYmUgZm9jdXNlZCB3aGVuIHRoZSBmb2N1cyB0cmFwIGlzIGluaXRpYWxpemVkLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIGZvY3VzIHdhcyBtb3ZlZCBzdWNjZXNzZnVsbHkuXG4gICAqL1xuICBmb2N1c0luaXRpYWxFbGVtZW50KG9wdGlvbnM/OiBGb2N1c09wdGlvbnMpOiBib29sZWFuIHtcbiAgICAvLyBDb250YWlucyB0aGUgZGVwcmVjYXRlZCB2ZXJzaW9uIG9mIHNlbGVjdG9yLCBmb3IgdGVtcG9yYXJ5IGJhY2t3YXJkcyBjb21wYXJhYmlsaXR5LlxuICAgIGNvbnN0IHJlZGlyZWN0VG9FbGVtZW50ID0gdGhpcy5fZWxlbWVudC5xdWVyeVNlbGVjdG9yKGBbY2RrLWZvY3VzLWluaXRpYWxdLCBgICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgW2Nka0ZvY3VzSW5pdGlhbF1gKSBhcyBIVE1MRWxlbWVudDtcblxuICAgIGlmIChyZWRpcmVjdFRvRWxlbWVudCkge1xuICAgICAgLy8gQGJyZWFraW5nLWNoYW5nZSA4LjAuMFxuICAgICAgaWYgKHJlZGlyZWN0VG9FbGVtZW50Lmhhc0F0dHJpYnV0ZShgY2RrLWZvY3VzLWluaXRpYWxgKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYEZvdW5kIHVzZSBvZiBkZXByZWNhdGVkIGF0dHJpYnV0ZSAnY2RrLWZvY3VzLWluaXRpYWwnLCBgICtcbiAgICAgICAgICAgICAgICAgICAgYHVzZSAnY2RrRm9jdXNJbml0aWFsJyBpbnN0ZWFkLiBUaGUgZGVwcmVjYXRlZCBhdHRyaWJ1dGUgYCArXG4gICAgICAgICAgICAgICAgICAgIGB3aWxsIGJlIHJlbW92ZWQgaW4gOC4wLjBgLCByZWRpcmVjdFRvRWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFdhcm4gdGhlIGNvbnN1bWVyIGlmIHRoZSBlbGVtZW50IHRoZXkndmUgcG9pbnRlZCB0b1xuICAgICAgLy8gaXNuJ3QgZm9jdXNhYmxlLCB3aGVuIG5vdCBpbiBwcm9kdWN0aW9uIG1vZGUuXG4gICAgICBpZiAoKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkgJiZcbiAgICAgICAgIXRoaXMuX2NoZWNrZXIuaXNGb2N1c2FibGUocmVkaXJlY3RUb0VsZW1lbnQpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBtYXRjaGluZyAnW2Nka0ZvY3VzSW5pdGlhbF0nIGlzIG5vdCBmb2N1c2FibGUuYCwgcmVkaXJlY3RUb0VsZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuX2NoZWNrZXIuaXNGb2N1c2FibGUocmVkaXJlY3RUb0VsZW1lbnQpKSB7XG4gICAgICAgIGNvbnN0IGZvY3VzYWJsZUNoaWxkID0gdGhpcy5fZ2V0Rmlyc3RUYWJiYWJsZUVsZW1lbnQocmVkaXJlY3RUb0VsZW1lbnQpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBmb2N1c2FibGVDaGlsZD8uZm9jdXMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiAhIWZvY3VzYWJsZUNoaWxkO1xuICAgICAgfVxuXG4gICAgICByZWRpcmVjdFRvRWxlbWVudC5mb2N1cyhvcHRpb25zKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZvY3VzRmlyc3RUYWJiYWJsZUVsZW1lbnQob3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogRm9jdXNlcyB0aGUgZmlyc3QgdGFiYmFibGUgZWxlbWVudCB3aXRoaW4gdGhlIGZvY3VzIHRyYXAgcmVnaW9uLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIGZvY3VzIHdhcyBtb3ZlZCBzdWNjZXNzZnVsbHkuXG4gICAqL1xuICBmb2N1c0ZpcnN0VGFiYmFibGVFbGVtZW50KG9wdGlvbnM/OiBGb2N1c09wdGlvbnMpOiBib29sZWFuIHtcbiAgICBjb25zdCByZWRpcmVjdFRvRWxlbWVudCA9IHRoaXMuX2dldFJlZ2lvbkJvdW5kYXJ5KCdzdGFydCcpO1xuXG4gICAgaWYgKHJlZGlyZWN0VG9FbGVtZW50KSB7XG4gICAgICByZWRpcmVjdFRvRWxlbWVudC5mb2N1cyhvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gISFyZWRpcmVjdFRvRWxlbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb2N1c2VzIHRoZSBsYXN0IHRhYmJhYmxlIGVsZW1lbnQgd2l0aGluIHRoZSBmb2N1cyB0cmFwIHJlZ2lvbi5cbiAgICogQHJldHVybnMgV2hldGhlciBmb2N1cyB3YXMgbW92ZWQgc3VjY2Vzc2Z1bGx5LlxuICAgKi9cbiAgZm9jdXNMYXN0VGFiYmFibGVFbGVtZW50KG9wdGlvbnM/OiBGb2N1c09wdGlvbnMpOiBib29sZWFuIHtcbiAgICBjb25zdCByZWRpcmVjdFRvRWxlbWVudCA9IHRoaXMuX2dldFJlZ2lvbkJvdW5kYXJ5KCdlbmQnKTtcblxuICAgIGlmIChyZWRpcmVjdFRvRWxlbWVudCkge1xuICAgICAgcmVkaXJlY3RUb0VsZW1lbnQuZm9jdXMob3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuICEhcmVkaXJlY3RUb0VsZW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGZvY3VzIHRyYXAgaGFzIHN1Y2Nlc3NmdWxseSBiZWVuIGF0dGFjaGVkLlxuICAgKi9cbiAgaGFzQXR0YWNoZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2hhc0F0dGFjaGVkO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgZmlyc3QgdGFiYmFibGUgZWxlbWVudCBmcm9tIGEgRE9NIHN1YnRyZWUgKGluY2x1c2l2ZSkuICovXG4gIHByaXZhdGUgX2dldEZpcnN0VGFiYmFibGVFbGVtZW50KHJvb3Q6IEhUTUxFbGVtZW50KTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBpZiAodGhpcy5fY2hlY2tlci5pc0ZvY3VzYWJsZShyb290KSAmJiB0aGlzLl9jaGVja2VyLmlzVGFiYmFibGUocm9vdCkpIHtcbiAgICAgIHJldHVybiByb290O1xuICAgIH1cblxuICAgIC8vIEl0ZXJhdGUgaW4gRE9NIG9yZGVyLiBOb3RlIHRoYXQgSUUgZG9lc24ndCBoYXZlIGBjaGlsZHJlbmAgZm9yIFNWRyBzbyB3ZSBmYWxsXG4gICAgLy8gYmFjayB0byBgY2hpbGROb2Rlc2Agd2hpY2ggaW5jbHVkZXMgdGV4dCBub2RlcywgY29tbWVudHMgZXRjLlxuICAgIGxldCBjaGlsZHJlbiA9IHJvb3QuY2hpbGRyZW4gfHwgcm9vdC5jaGlsZE5vZGVzO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IHRhYmJhYmxlQ2hpbGQgPSBjaGlsZHJlbltpXS5ub2RlVHlwZSA9PT0gdGhpcy5fZG9jdW1lbnQuRUxFTUVOVF9OT0RFID9cbiAgICAgICAgdGhpcy5fZ2V0Rmlyc3RUYWJiYWJsZUVsZW1lbnQoY2hpbGRyZW5baV0gYXMgSFRNTEVsZW1lbnQpIDpcbiAgICAgICAgbnVsbDtcblxuICAgICAgaWYgKHRhYmJhYmxlQ2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIHRhYmJhYmxlQ2hpbGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogR2V0IHRoZSBsYXN0IHRhYmJhYmxlIGVsZW1lbnQgZnJvbSBhIERPTSBzdWJ0cmVlIChpbmNsdXNpdmUpLiAqL1xuICBwcml2YXRlIF9nZXRMYXN0VGFiYmFibGVFbGVtZW50KHJvb3Q6IEhUTUxFbGVtZW50KTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBpZiAodGhpcy5fY2hlY2tlci5pc0ZvY3VzYWJsZShyb290KSAmJiB0aGlzLl9jaGVja2VyLmlzVGFiYmFibGUocm9vdCkpIHtcbiAgICAgIHJldHVybiByb290O1xuICAgIH1cblxuICAgIC8vIEl0ZXJhdGUgaW4gcmV2ZXJzZSBET00gb3JkZXIuXG4gICAgbGV0IGNoaWxkcmVuID0gcm9vdC5jaGlsZHJlbiB8fCByb290LmNoaWxkTm9kZXM7XG5cbiAgICBmb3IgKGxldCBpID0gY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGxldCB0YWJiYWJsZUNoaWxkID0gY2hpbGRyZW5baV0ubm9kZVR5cGUgPT09IHRoaXMuX2RvY3VtZW50LkVMRU1FTlRfTk9ERSA/XG4gICAgICAgIHRoaXMuX2dldExhc3RUYWJiYWJsZUVsZW1lbnQoY2hpbGRyZW5baV0gYXMgSFRNTEVsZW1lbnQpIDpcbiAgICAgICAgbnVsbDtcblxuICAgICAgaWYgKHRhYmJhYmxlQ2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIHRhYmJhYmxlQ2hpbGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogQ3JlYXRlcyBhbiBhbmNob3IgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfY3JlYXRlQW5jaG9yKCk6IEhUTUxFbGVtZW50IHtcbiAgICBjb25zdCBhbmNob3IgPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLl90b2dnbGVBbmNob3JUYWJJbmRleCh0aGlzLl9lbmFibGVkLCBhbmNob3IpO1xuICAgIGFuY2hvci5jbGFzc0xpc3QuYWRkKCdjZGstdmlzdWFsbHktaGlkZGVuJyk7XG4gICAgYW5jaG9yLmNsYXNzTGlzdC5hZGQoJ2Nkay1mb2N1cy10cmFwLWFuY2hvcicpO1xuICAgIGFuY2hvci5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICByZXR1cm4gYW5jaG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgdGhlIGB0YWJpbmRleGAgb2YgYW4gYW5jaG9yLCBiYXNlZCBvbiB0aGUgZW5hYmxlZCBzdGF0ZSBvZiB0aGUgZm9jdXMgdHJhcC5cbiAgICogQHBhcmFtIGlzRW5hYmxlZCBXaGV0aGVyIHRoZSBmb2N1cyB0cmFwIGlzIGVuYWJsZWQuXG4gICAqIEBwYXJhbSBhbmNob3IgQW5jaG9yIG9uIHdoaWNoIHRvIHRvZ2dsZSB0aGUgdGFiaW5kZXguXG4gICAqL1xuICBwcml2YXRlIF90b2dnbGVBbmNob3JUYWJJbmRleChpc0VuYWJsZWQ6IGJvb2xlYW4sIGFuY2hvcjogSFRNTEVsZW1lbnQpIHtcbiAgICAvLyBSZW1vdmUgdGhlIHRhYmluZGV4IGNvbXBsZXRlbHksIHJhdGhlciB0aGFuIHNldHRpbmcgaXQgdG8gLTEsIGJlY2F1c2UgaWYgdGhlXG4gICAgLy8gZWxlbWVudCBoYXMgYSB0YWJpbmRleCwgdGhlIHVzZXIgbWlnaHQgc3RpbGwgaGl0IGl0IHdoZW4gbmF2aWdhdGluZyB3aXRoIHRoZSBhcnJvdyBrZXlzLlxuICAgIGlzRW5hYmxlZCA/IGFuY2hvci5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJzAnKSA6IGFuY2hvci5yZW1vdmVBdHRyaWJ1dGUoJ3RhYmluZGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlcyB0aGVgdGFiaW5kZXhgIG9mIGJvdGggYW5jaG9ycyB0byBlaXRoZXIgdHJhcCBUYWIgZm9jdXMgb3IgYWxsb3cgaXQgdG8gZXNjYXBlLlxuICAgKiBAcGFyYW0gZW5hYmxlZDogV2hldGhlciB0aGUgYW5jaG9ycyBzaG91bGQgdHJhcCBUYWIuXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9nZ2xlQW5jaG9ycyhlbmFibGVkOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMuX3N0YXJ0QW5jaG9yICYmIHRoaXMuX2VuZEFuY2hvcikge1xuICAgICAgdGhpcy5fdG9nZ2xlQW5jaG9yVGFiSW5kZXgoZW5hYmxlZCwgdGhpcy5fc3RhcnRBbmNob3IpO1xuICAgICAgdGhpcy5fdG9nZ2xlQW5jaG9yVGFiSW5kZXgoZW5hYmxlZCwgdGhpcy5fZW5kQW5jaG9yKTtcbiAgICB9XG4gIH1cblxuICAvKiogRXhlY3V0ZXMgYSBmdW5jdGlvbiB3aGVuIHRoZSB6b25lIGlzIHN0YWJsZS4gKi9cbiAgcHJpdmF0ZSBfZXhlY3V0ZU9uU3RhYmxlKGZuOiAoKSA9PiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fbmdab25lLmlzU3RhYmxlKSB7XG4gICAgICBmbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9uZ1pvbmUub25TdGFibGUucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoZm4pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEZhY3RvcnkgdGhhdCBhbGxvd3MgZWFzeSBpbnN0YW50aWF0aW9uIG9mIGZvY3VzIHRyYXBzLlxuICogQGRlcHJlY2F0ZWQgVXNlIGBDb25maWd1cmFibGVGb2N1c1RyYXBGYWN0b3J5YCBpbnN0ZWFkLlxuICogQGJyZWFraW5nLWNoYW5nZSAxMS4wLjBcbiAqL1xuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXG5leHBvcnQgY2xhc3MgRm9jdXNUcmFwRmFjdG9yeSB7XG4gIHByaXZhdGUgX2RvY3VtZW50OiBEb2N1bWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgX2NoZWNrZXI6IEludGVyYWN0aXZpdHlDaGVja2VyLFxuICAgICAgcHJpdmF0ZSBfbmdab25lOiBOZ1pvbmUsXG4gICAgICBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ6IGFueSkge1xuXG4gICAgdGhpcy5fZG9jdW1lbnQgPSBfZG9jdW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGZvY3VzLXRyYXBwZWQgcmVnaW9uIGFyb3VuZCB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgYXJvdW5kIHdoaWNoIGZvY3VzIHdpbGwgYmUgdHJhcHBlZC5cbiAgICogQHBhcmFtIGRlZmVyQ2FwdHVyZUVsZW1lbnRzIERlZmVycyB0aGUgY3JlYXRpb24gb2YgZm9jdXMtY2FwdHVyaW5nIGVsZW1lbnRzIHRvIGJlIGRvbmVcbiAgICogICAgIG1hbnVhbGx5IGJ5IHRoZSB1c2VyLlxuICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBmb2N1cyB0cmFwIGluc3RhbmNlLlxuICAgKi9cbiAgY3JlYXRlKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBkZWZlckNhcHR1cmVFbGVtZW50czogYm9vbGVhbiA9IGZhbHNlKTogRm9jdXNUcmFwIHtcbiAgICByZXR1cm4gbmV3IEZvY3VzVHJhcChcbiAgICAgICAgZWxlbWVudCwgdGhpcy5fY2hlY2tlciwgdGhpcy5fbmdab25lLCB0aGlzLl9kb2N1bWVudCwgZGVmZXJDYXB0dXJlRWxlbWVudHMpO1xuICB9XG59XG5cbi8qKiBEaXJlY3RpdmUgZm9yIHRyYXBwaW5nIGZvY3VzIHdpdGhpbiBhIHJlZ2lvbi4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjZGtUcmFwRm9jdXNdJyxcbiAgZXhwb3J0QXM6ICdjZGtUcmFwRm9jdXMnLFxufSlcbmV4cG9ydCBjbGFzcyBDZGtUcmFwRm9jdXMgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyQ29udGVudEluaXQsIE9uQ2hhbmdlcywgRG9DaGVjayB7XG4gIC8qKiBVbmRlcmx5aW5nIEZvY3VzVHJhcCBpbnN0YW5jZS4gKi9cbiAgZm9jdXNUcmFwOiBGb2N1c1RyYXA7XG5cbiAgLyoqIFByZXZpb3VzbHkgZm9jdXNlZCBlbGVtZW50IHRvIHJlc3RvcmUgZm9jdXMgdG8gdXBvbiBkZXN0cm95IHdoZW4gdXNpbmcgYXV0b0NhcHR1cmUuICovXG4gIHByaXZhdGUgX3ByZXZpb3VzbHlGb2N1c2VkRWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICAvKiogV2hldGhlciB0aGUgZm9jdXMgdHJhcCBpcyBhY3RpdmUuICovXG4gIEBJbnB1dCgnY2RrVHJhcEZvY3VzJylcbiAgZ2V0IGVuYWJsZWQoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLmZvY3VzVHJhcC5lbmFibGVkOyB9XG4gIHNldCBlbmFibGVkKHZhbHVlOiBib29sZWFuKSB7IHRoaXMuZm9jdXNUcmFwLmVuYWJsZWQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpOyB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGRpcmVjdGl2ZSBzaG91bGQgYXV0b21hdGljYWxseSBtb3ZlIGZvY3VzIGludG8gdGhlIHRyYXBwZWQgcmVnaW9uIHVwb25cbiAgICogaW5pdGlhbGl6YXRpb24gYW5kIHJldHVybiBmb2N1cyB0byB0aGUgcHJldmlvdXMgYWN0aXZlRWxlbWVudCB1cG9uIGRlc3RydWN0aW9uLlxuICAgKi9cbiAgQElucHV0KCdjZGtUcmFwRm9jdXNBdXRvQ2FwdHVyZScpXG4gIGdldCBhdXRvQ2FwdHVyZSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX2F1dG9DYXB0dXJlOyB9XG4gIHNldCBhdXRvQ2FwdHVyZSh2YWx1ZTogYm9vbGVhbikgeyB0aGlzLl9hdXRvQ2FwdHVyZSA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7IH1cbiAgcHJpdmF0ZSBfYXV0b0NhcHR1cmU6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICAgIHByaXZhdGUgX2ZvY3VzVHJhcEZhY3Rvcnk6IEZvY3VzVHJhcEZhY3RvcnksXG4gICAgICAvKipcbiAgICAgICAqIEBkZXByZWNhdGVkIE5vIGxvbmdlciBiZWluZyB1c2VkLiBUbyBiZSByZW1vdmVkLlxuICAgICAgICogQGJyZWFraW5nLWNoYW5nZSAxMy4wLjBcbiAgICAgICAqL1xuICAgICAgQEluamVjdChET0NVTUVOVCkgX2RvY3VtZW50OiBhbnkpIHtcbiAgICB0aGlzLmZvY3VzVHJhcCA9IHRoaXMuX2ZvY3VzVHJhcEZhY3RvcnkuY3JlYXRlKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdHJ1ZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmZvY3VzVHJhcC5kZXN0cm95KCk7XG5cbiAgICAvLyBJZiB3ZSBzdG9yZWQgYSBwcmV2aW91c2x5IGZvY3VzZWQgZWxlbWVudCB3aGVuIHVzaW5nIGF1dG9DYXB0dXJlLCByZXR1cm4gZm9jdXMgdG8gdGhhdFxuICAgIC8vIGVsZW1lbnQgbm93IHRoYXQgdGhlIHRyYXBwZWQgcmVnaW9uIGlzIGJlaW5nIGRlc3Ryb3llZC5cbiAgICBpZiAodGhpcy5fcHJldmlvdXNseUZvY3VzZWRFbGVtZW50KSB7XG4gICAgICB0aGlzLl9wcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIHRoaXMuX3ByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMuZm9jdXNUcmFwLmF0dGFjaEFuY2hvcnMoKTtcblxuICAgIGlmICh0aGlzLmF1dG9DYXB0dXJlKSB7XG4gICAgICB0aGlzLl9jYXB0dXJlRm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBuZ0RvQ2hlY2soKSB7XG4gICAgaWYgKCF0aGlzLmZvY3VzVHJhcC5oYXNBdHRhY2hlZCgpKSB7XG4gICAgICB0aGlzLmZvY3VzVHJhcC5hdHRhY2hBbmNob3JzKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGNvbnN0IGF1dG9DYXB0dXJlQ2hhbmdlID0gY2hhbmdlc1snYXV0b0NhcHR1cmUnXTtcblxuICAgIGlmIChhdXRvQ2FwdHVyZUNoYW5nZSAmJiAhYXV0b0NhcHR1cmVDaGFuZ2UuZmlyc3RDaGFuZ2UgJiYgdGhpcy5hdXRvQ2FwdHVyZSAmJlxuICAgICAgICB0aGlzLmZvY3VzVHJhcC5oYXNBdHRhY2hlZCgpKSB7XG4gICAgICB0aGlzLl9jYXB0dXJlRm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9jYXB0dXJlRm9jdXMoKSB7XG4gICAgdGhpcy5fcHJldmlvdXNseUZvY3VzZWRFbGVtZW50ID0gX2dldEZvY3VzZWRFbGVtZW50UGllcmNlU2hhZG93RG9tKCk7XG4gICAgdGhpcy5mb2N1c1RyYXAuZm9jdXNJbml0aWFsRWxlbWVudFdoZW5SZWFkeSgpO1xuICB9XG5cbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2VuYWJsZWQ6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2F1dG9DYXB0dXJlOiBCb29sZWFuSW5wdXQ7XG59XG4iXX0=
|