@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
141 lines • 23.2 kB
JavaScript
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Directive, ElementRef, EventEmitter, inject, Input, NgZone, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { AccessibilityOptionsService } from '../options/accessibility-options.service';
import { LocalFocusIndicatorOptions } from './focus-indicator-options/focus-indicator-options';
import { FocusIndicatorService } from './focus-indicator.service';
import * as i0 from "@angular/core";
export class FocusIndicatorDirective {
/** Specify whether or not we should mark this element as having focus if a child is focused */
set checkChildren(checkChildren) {
// allow a string to be used so we can skip checking a binding for performance benefits
checkChildren = coerceBooleanProperty(checkChildren);
if (checkChildren !== null && checkChildren !== undefined) {
this._checkChildren = checkChildren;
this.setOptions();
}
}
/** Indicate whether or not mouse events should cause the focus indicator to appear - will override any global setting */
set mouseFocusIndicator(mouseFocusIndicator) {
// allow a string to be used so we can skip checking a binding for performance benefits
mouseFocusIndicator = coerceBooleanProperty(mouseFocusIndicator);
if (mouseFocusIndicator !== null && mouseFocusIndicator !== undefined) {
this._options.set('mouseFocusIndicator', mouseFocusIndicator);
this.setOptions();
}
}
/** Indicate whether or not touch events should cause the focus indicator to appear - will override any global setting */
set touchFocusIndicator(touchFocusIndicator) {
// allow a string to be used so we can skip checking a binding for performance benefits
touchFocusIndicator = coerceBooleanProperty(touchFocusIndicator);
if (touchFocusIndicator !== null && touchFocusIndicator !== undefined) {
this._options.set('touchFocusIndicator', touchFocusIndicator);
this.setOptions();
}
}
/** Indicate whether or not keyboard events should cause the focus indicator to appear - will override any global setting */
set keyboardFocusIndicator(keyboardFocusIndicator) {
// allow a string to be used so we can skip checking a binding for performance benefits
keyboardFocusIndicator = coerceBooleanProperty(keyboardFocusIndicator);
if (keyboardFocusIndicator !== null && keyboardFocusIndicator !== undefined) {
this._options.set('keyboardFocusIndicator', keyboardFocusIndicator);
this.setOptions();
}
}
/** Indicate whether or not programmatic events should cause the focus indicator to appear - will override any global setting */
set programmaticFocusIndicator(programmaticFocusIndicator) {
// allow a string to be used so we can skip checking a binding for performance benefits
programmaticFocusIndicator = coerceBooleanProperty(programmaticFocusIndicator);
if (programmaticFocusIndicator !== null && programmaticFocusIndicator !== undefined) {
this._options.set('programmaticFocusIndicator', programmaticFocusIndicator);
this.setOptions();
}
}
constructor() {
this.optionsService = inject(AccessibilityOptionsService);
this._elementRef = inject(ElementRef);
this._focusIndicatorService = inject(FocusIndicatorService);
this._ngZone = inject(NgZone);
this.localOptions = inject(LocalFocusIndicatorOptions, { optional: true });
/** Emit the latest focus state */
this.indicator = new EventEmitter();
/** Store a private reference for the checkChildren option */
this._checkChildren = false;
/** Store all configuation options*/
this._options = new Map();
/** Unsubscribe on component destroy */
this._onDestroy = new Subject();
// set the inital option values based on global options
for (const option in (this.optionsService.options || {})) {
this._options.set(option, this.optionsService.options[option]);
}
// set the inital option values based on local options (if there are any)
for (const option in (this.localOptions || {})) {
this._options.set(option, this.localOptions[option]);
}
}
/** Setup the focus monitoring */
ngOnInit() {
// start the focus monitoring
this._focusIndicator = this._focusIndicatorService.monitor(this._elementRef.nativeElement, {
checkChildren: this._checkChildren,
mouseFocusIndicator: this._options.get('mouseFocusIndicator'),
touchFocusIndicator: this._options.get('touchFocusIndicator'),
keyboardFocusIndicator: this._options.get('keyboardFocusIndicator'),
programmaticFocusIndicator: this._options.get('programmaticFocusIndicator')
});
// subscribe to the focus state to emit an event on change
this._focusIndicator.isFocused$.pipe(takeUntil(this._onDestroy)).subscribe(isFocused => {
// emit the latest value
this._ngZone.run(() => this.indicator.emit(isFocused));
});
}
/** Tear down the directive */
ngOnDestroy() {
if (this._focusIndicator) {
this._focusIndicator.destroy();
}
// unsubscribe from all observables
this._onDestroy.next();
this._onDestroy.complete();
}
/** Focus this element with a specific origin */
focus(origin, options) {
this._focusIndicator.focus(origin, options);
}
/** Update the focus indicator with the latest options */
setOptions() {
if (this._focusIndicator) {
this._focusIndicator.setOptions({
checkChildren: this._checkChildren,
mouseFocusIndicator: this._options.get('mouseFocusIndicator'),
touchFocusIndicator: this._options.get('touchFocusIndicator'),
keyboardFocusIndicator: this._options.get('keyboardFocusIndicator'),
programmaticFocusIndicator: this._options.get('programmaticFocusIndicator')
});
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FocusIndicatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.12", type: FocusIndicatorDirective, selector: "[uxFocusIndicator]", inputs: { checkChildren: "checkChildren", mouseFocusIndicator: "mouseFocusIndicator", touchFocusIndicator: "touchFocusIndicator", keyboardFocusIndicator: "keyboardFocusIndicator", programmaticFocusIndicator: "programmaticFocusIndicator" }, outputs: { indicator: "indicator" }, exportAs: ["ux-focus-indicator"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FocusIndicatorDirective, decorators: [{
type: Directive,
args: [{
selector: '[uxFocusIndicator]',
exportAs: 'ux-focus-indicator',
}]
}], ctorParameters: () => [], propDecorators: { checkChildren: [{
type: Input
}], mouseFocusIndicator: [{
type: Input
}], touchFocusIndicator: [{
type: Input
}], keyboardFocusIndicator: [{
type: Input
}], programmaticFocusIndicator: [{
type: Input
}], indicator: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9jdXMtaW5kaWNhdG9yLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9kaXJlY3RpdmVzL2FjY2Vzc2liaWxpdHkvZm9jdXMtaW5kaWNhdG9yL2ZvY3VzLWluZGljYXRvci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEgsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFFdkYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDL0YsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7O0FBTWxFLE1BQU0sT0FBTyx1QkFBdUI7SUFXaEMsK0ZBQStGO0lBQy9GLElBQWEsYUFBYSxDQUFDLGFBQStCO1FBRXRELHVGQUF1RjtRQUN2RixhQUFhLEdBQUcscUJBQXFCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFckQsSUFBSSxhQUFhLEtBQUssSUFBSSxJQUFJLGFBQWEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN4RCxJQUFJLENBQUMsY0FBYyxHQUFHLGFBQWEsQ0FBQztZQUNwQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDdEIsQ0FBQztJQUNMLENBQUM7SUFFRCx5SEFBeUg7SUFDekgsSUFBYSxtQkFBbUIsQ0FBQyxtQkFBcUM7UUFFbEUsdUZBQXVGO1FBQ3ZGLG1CQUFtQixHQUFHLHFC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QGFuZ3VsYXIvY2RrL2ExMXknO1xuaW1wb3J0IHsgY29lcmNlQm9vbGVhblByb3BlcnR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFjY2Vzc2liaWxpdHlPcHRpb25zU2VydmljZSB9IGZyb20gJy4uL29wdGlvbnMvYWNjZXNzaWJpbGl0eS1vcHRpb25zLnNlcnZpY2UnO1xuaW1wb3J0IHsgRm9jdXNJbmRpY2F0b3IgfSBmcm9tICcuL2ZvY3VzLWluZGljYXRvcic7XG5pbXBvcnQgeyBMb2NhbEZvY3VzSW5kaWNhdG9yT3B0aW9ucyB9IGZyb20gJy4vZm9jdXMtaW5kaWNhdG9yLW9wdGlvbnMvZm9jdXMtaW5kaWNhdG9yLW9wdGlvbnMnO1xuaW1wb3J0IHsgRm9jdXNJbmRpY2F0b3JTZXJ2aWNlIH0gZnJvbSAnLi9mb2N1cy1pbmRpY2F0b3Iuc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW3V4Rm9jdXNJbmRpY2F0b3JdJyxcbiAgICBleHBvcnRBczogJ3V4LWZvY3VzLWluZGljYXRvcicsXG59KVxuZXhwb3J0IGNsYXNzIEZvY3VzSW5kaWNhdG9yRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAgIHJlYWRvbmx5IG9wdGlvbnNTZXJ2aWNlID0gaW5qZWN0KEFjY2Vzc2liaWxpdHlPcHRpb25zU2VydmljZSk7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZm9jdXNJbmRpY2F0b3JTZXJ2aWNlID0gaW5qZWN0KEZvY3VzSW5kaWNhdG9yU2VydmljZSk7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9uZ1pvbmUgPSBpbmplY3QoTmdab25lKTtcblxuICAgIHJlYWRvbmx5IGxvY2FsT3B0aW9ucyA9IGluamVjdChMb2NhbEZvY3VzSW5kaWNhdG9yT3B0aW9ucywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICAgIC8qKiBTcGVjaWZ5IHdoZXRoZXIgb3Igbm90IHdlIHNob3VsZCBtYXJrIHRoaXMgZWxlbWVudCBhcyBoYXZpbmcgZm9jdXMgaWYgYSBjaGlsZCBpcyBmb2N1c2VkICovXG4gICAgQElucHV0KCkgc2V0IGNoZWNrQ2hpbGRyZW4oY2hlY2tDaGlsZHJlbjogYm9vbGVhbiB8IHN0cmluZykge1xuXG4gICAgICAgIC8vIGFsbG93IGEgc3RyaW5nIHRvIGJlIHVzZWQgc28gd2UgY2FuIHNraXAgY2hlY2tpbmcgYSBiaW5kaW5nIGZvciBwZXJmb3JtYW5jZSBiZW5lZml0c1xuICAgICAgICBjaGVja0NoaWxkcmVuID0gY29lcmNlQm9vbGVhblByb3BlcnR5KGNoZWNrQ2hpbGRyZW4pO1xuXG4gICAgICAgIGlmIChjaGVja0NoaWxkcmVuICE9PSBudWxsICYmIGNoZWNrQ2hpbGRyZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fY2hlY2tDaGlsZHJlbiA9IGNoZWNrQ2hpbGRyZW47XG4gICAgICAgICAgICB0aGlzLnNldE9wdGlvbnMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBJbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCBtb3VzZSBldmVudHMgc2hvdWxkIGNhdXNlIHRoZSBmb2N1cyBpbmRpY2F0b3IgdG8gYXBwZWFyIC0gd2lsbCBvdmVycmlkZSBhbnkgZ2xvYmFsIHNldHRpbmcgKi9cbiAgICBASW5wdXQoKSBzZXQgbW91c2VGb2N1c0luZGljYXRvcihtb3VzZUZvY3VzSW5kaWNhdG9yOiBib29sZWFuIHwgc3RyaW5nKSB7XG5cbiAgICAgICAgLy8gYWxsb3cgYSBzdHJpbmcgdG8gYmUgdXNlZCBzbyB3ZSBjYW4gc2tpcCBjaGVja2luZyBhIGJpbmRpbmcgZm9yIHBlcmZvcm1hbmNlIGJlbmVmaXRzXG4gICAgICAgIG1vdXNlRm9jdXNJbmRpY2F0b3IgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkobW91c2VGb2N1c0luZGljYXRvcik7XG5cbiAgICAgICAgaWYgKG1vdXNlRm9jdXNJbmRpY2F0b3IgIT09IG51bGwgJiYgbW91c2VGb2N1c0luZGljYXRvciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnNldCgnbW91c2VGb2N1c0luZGljYXRvcicsIG1vdXNlRm9jdXNJbmRpY2F0b3IpO1xuICAgICAgICAgICAgdGhpcy5zZXRPcHRpb25zKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogSW5kaWNhdGUgd2hldGhlciBvciBub3QgdG91Y2ggZXZlbnRzIHNob3VsZCBjYXVzZSB0aGUgZm9jdXMgaW5kaWNhdG9yIHRvIGFwcGVhciAtIHdpbGwgb3ZlcnJpZGUgYW55IGdsb2JhbCBzZXR0aW5nICovXG4gICAgQElucHV0KCkgc2V0IHRvdWNoRm9jdXNJbmRpY2F0b3IodG91Y2hGb2N1c0luZGljYXRvcjogYm9vbGVhbiB8IHN0cmluZykge1xuXG4gICAgICAgIC8vIGFsbG93IGEgc3RyaW5nIHRvIGJlIHVzZWQgc28gd2UgY2FuIHNraXAgY2hlY2tpbmcgYSBiaW5kaW5nIGZvciBwZXJmb3JtYW5jZSBiZW5lZml0c1xuICAgICAgICB0b3VjaEZvY3VzSW5kaWNhdG9yID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHRvdWNoRm9jdXNJbmRpY2F0b3IpO1xuXG4gICAgICAgIGlmICh0b3VjaEZvY3VzSW5kaWNhdG9yICE9PSBudWxsICYmIHRvdWNoRm9jdXNJbmRpY2F0b3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zZXQoJ3RvdWNoRm9jdXNJbmRpY2F0b3InLCB0b3VjaEZvY3VzSW5kaWNhdG9yKTtcbiAgICAgICAgICAgIHRoaXMuc2V0T3B0aW9ucygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEluZGljYXRlIHdoZXRoZXIgb3Igbm90IGtleWJvYXJkIGV2ZW50cyBzaG91bGQgY2F1c2UgdGhlIGZvY3VzIGluZGljYXRvciB0byBhcHBlYXIgLSB3aWxsIG92ZXJyaWRlIGFueSBnbG9iYWwgc2V0dGluZyAqL1xuICAgIEBJbnB1dCgpIHNldCBrZXlib2FyZEZvY3VzSW5kaWNhdG9yKGtleWJvYXJkRm9jdXNJbmRpY2F0b3I6IGJvb2xlYW4gfCBzdHJpbmcpIHtcblxuICAgICAgICAvLyBhbGxvdyBhIHN0cmluZyB0byBiZSB1c2VkIHNvIHdlIGNhbiBza2lwIGNoZWNraW5nIGEgYmluZGluZyBmb3IgcGVyZm9ybWFuY2UgYmVuZWZpdHNcbiAgICAgICAga2V5Ym9hcmRGb2N1c0luZGljYXRvciA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eShrZXlib2FyZEZvY3VzSW5kaWNhdG9yKTtcblxuICAgICAgICBpZiAoa2V5Ym9hcmRGb2N1c0luZGljYXRvciAhPT0gbnVsbCAmJiBrZXlib2FyZEZvY3VzSW5kaWNhdG9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuc2V0KCdrZXlib2FyZEZvY3VzSW5kaWNhdG9yJywga2V5Ym9hcmRGb2N1c0luZGljYXRvcik7XG4gICAgICAgICAgICB0aGlzLnNldE9wdGlvbnMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBJbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCBwcm9ncmFtbWF0aWMgZXZlbnRzIHNob3VsZCBjYXVzZSB0aGUgZm9jdXMgaW5kaWNhdG9yIHRvIGFwcGVhciAtIHdpbGwgb3ZlcnJpZGUgYW55IGdsb2JhbCBzZXR0aW5nICovXG4gICAgQElucHV0KCkgc2V0IHByb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yKHByb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yOiBib29sZWFuIHwgc3RyaW5nKSB7XG5cbiAgICAgICAgLy8gYWxsb3cgYSBzdHJpbmcgdG8gYmUgdXNlZCBzbyB3ZSBjYW4gc2tpcCBjaGVja2luZyBhIGJpbmRpbmcgZm9yIHBlcmZvcm1hbmNlIGJlbmVmaXRzXG4gICAgICAgIHByb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHByb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yKTtcblxuICAgICAgICBpZiAocHJvZ3JhbW1hdGljRm9jdXNJbmRpY2F0b3IgIT09IG51bGwgJiYgcHJvZ3JhbW1hdGljRm9jdXNJbmRpY2F0b3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zZXQoJ3Byb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yJywgcHJvZ3JhbW1hdGljRm9jdXNJbmRpY2F0b3IpO1xuICAgICAgICAgICAgdGhpcy5zZXRPcHRpb25zKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogRW1pdCB0aGUgbGF0ZXN0IGZvY3VzIHN0YXRlICovXG4gICAgQE91dHB1dCgpIGluZGljYXRvciA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAgIC8qKiBTdG9yZSBhIHByaXZhdGUgcmVmZXJlbmNlIGZvciB0aGUgY2hlY2tDaGlsZHJlbiBvcHRpb24gKi9cbiAgICBwcml2YXRlIF9jaGVja0NoaWxkcmVuOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKiogU3RvcmUgYWxsIGNvbmZpZ3VhdGlvbiBvcHRpb25zKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vcHRpb25zID0gbmV3IE1hcDxzdHJpbmcsIGJvb2xlYW4+KCk7XG5cbiAgICAvKiogU3RvcmUgYSByZWZlcmVuY2UgdG8gdGhlIGZvY3VzIGhhbmRsZXIgKi9cbiAgICBwcml2YXRlIF9mb2N1c0luZGljYXRvcjogRm9jdXNJbmRpY2F0b3I7XG5cbiAgICAvKiogVW5zdWJzY3JpYmUgb24gY29tcG9uZW50IGRlc3Ryb3kgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG5cbiAgICAgICAgLy8gc2V0IHRoZSBpbml0YWwgb3B0aW9uIHZhbHVlcyBiYXNlZCBvbiBnbG9iYWwgb3B0aW9uc1xuICAgICAgICBmb3IgKGNvbnN0IG9wdGlvbiBpbiAodGhpcy5vcHRpb25zU2VydmljZS5vcHRpb25zIHx8IHt9KSkge1xuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zZXQob3B0aW9uLCB0aGlzLm9wdGlvbnNTZXJ2aWNlLm9wdGlvbnNbb3B0aW9uXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgdGhlIGluaXRhbCBvcHRpb24gdmFsdWVzIGJhc2VkIG9uIGxvY2FsIG9wdGlvbnMgKGlmIHRoZXJlIGFyZSBhbnkpXG4gICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIGluICh0aGlzLmxvY2FsT3B0aW9ucyB8fCB7fSkpIHtcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuc2V0KG9wdGlvbiwgdGhpcy5sb2NhbE9wdGlvbnNbb3B0aW9uXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogU2V0dXAgdGhlIGZvY3VzIG1vbml0b3JpbmcgKi9cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcblxuICAgICAgICAvLyBzdGFydCB0aGUgZm9jdXMgbW9uaXRvcmluZ1xuICAgICAgICB0aGlzLl9mb2N1c0luZGljYXRvciA9IHRoaXMuX2ZvY3VzSW5kaWNhdG9yU2VydmljZS5tb25pdG9yKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwge1xuICAgICAgICAgICAgY2hlY2tDaGlsZHJlbjogdGhpcy5fY2hlY2tDaGlsZHJlbixcbiAgICAgICAgICAgIG1vdXNlRm9jdXNJbmRpY2F0b3I6IHRoaXMuX29wdGlvbnMuZ2V0KCdtb3VzZUZvY3VzSW5kaWNhdG9yJyksXG4gICAgICAgICAgICB0b3VjaEZvY3VzSW5kaWNhdG9yOiB0aGlzLl9vcHRpb25zLmdldCgndG91Y2hGb2N1c0luZGljYXRvcicpLFxuICAgICAgICAgICAga2V5Ym9hcmRGb2N1c0luZGljYXRvcjogdGhpcy5fb3B0aW9ucy5nZXQoJ2tleWJvYXJkRm9jdXNJbmRpY2F0b3InKSxcbiAgICAgICAgICAgIHByb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yOiB0aGlzLl9vcHRpb25zLmdldCgncHJvZ3JhbW1hdGljRm9jdXNJbmRpY2F0b3InKVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBzdWJzY3JpYmUgdG8gdGhlIGZvY3VzIHN0YXRlIHRvIGVtaXQgYW4gZXZlbnQgb24gY2hhbmdlXG4gICAgICAgIHRoaXMuX2ZvY3VzSW5kaWNhdG9yLmlzRm9jdXNlZCQucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSkuc3Vic2NyaWJlKGlzRm9jdXNlZCA9PiB7XG4gICAgICAgICAgICAvLyBlbWl0IHRoZSBsYXRlc3QgdmFsdWVcbiAgICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy5pbmRpY2F0b3IuZW1pdChpc0ZvY3VzZWQpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqIFRlYXIgZG93biB0aGUgZGlyZWN0aXZlICovXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9mb2N1c0luZGljYXRvcikge1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNJbmRpY2F0b3IuZGVzdHJveSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdW5zdWJzY3JpYmUgZnJvbSBhbGwgb2JzZXJ2YWJsZXNcbiAgICAgICAgdGhpcy5fb25EZXN0cm95Lm5leHQoKTtcbiAgICAgICAgdGhpcy5fb25EZXN0cm95LmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgLyoqIEZvY3VzIHRoaXMgZWxlbWVudCB3aXRoIGEgc3BlY2lmaWMgb3JpZ2luICovXG4gICAgZm9jdXMob3JpZ2luPzogRm9jdXNPcmlnaW4sIG9wdGlvbnM/OiB7IHByZXZlbnRTY3JvbGw6IGJvb2xlYW4gfSk6IHZvaWQge1xuICAgICAgICB0aGlzLl9mb2N1c0luZGljYXRvci5mb2N1cyhvcmlnaW4sIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKiBVcGRhdGUgdGhlIGZvY3VzIGluZGljYXRvciB3aXRoIHRoZSBsYXRlc3Qgb3B0aW9ucyAqL1xuICAgIHByaXZhdGUgc2V0T3B0aW9ucygpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2ZvY3VzSW5kaWNhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9mb2N1c0luZGljYXRvci5zZXRPcHRpb25zKHtcbiAgICAgICAgICAgICAgICBjaGVja0NoaWxkcmVuOiB0aGlzLl9jaGVja0NoaWxkcmVuLFxuICAgICAgICAgICAgICAgIG1vdXNlRm9jdXNJbmRpY2F0b3I6IHRoaXMuX29wdGlvbnMuZ2V0KCdtb3VzZUZvY3VzSW5kaWNhdG9yJyksXG4gICAgICAgICAgICAgICAgdG91Y2hGb2N1c0luZGljYXRvcjogdGhpcy5fb3B0aW9ucy5nZXQoJ3RvdWNoRm9jdXNJbmRpY2F0b3InKSxcbiAgICAgICAgICAgICAgICBrZXlib2FyZEZvY3VzSW5kaWNhdG9yOiB0aGlzLl9vcHRpb25zLmdldCgna2V5Ym9hcmRGb2N1c0luZGljYXRvcicpLFxuICAgICAgICAgICAgICAgIHByb2dyYW1tYXRpY0ZvY3VzSW5kaWNhdG9yOiB0aGlzLl9vcHRpb25zLmdldCgncHJvZ3JhbW1hdGljRm9jdXNJbmRpY2F0b3InKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59Il19