UNPKG

@ngspot/ngx-errors

Version:

<p align="center"> <img width="20%" height="20%" src="https://github.com/DmitryEfimenko/ngspot/blob/main/packages/ngx-errors/package/assets/logo.png?raw=true"> </p>

204 lines 28.1 kB
/* eslint-disable @angular-eslint/directive-selector */ import { ChangeDetectorRef, computed, Directive, effect, inject, input, TemplateRef, ViewContainerRef, } from '@angular/core'; import { toObservable } from '@angular/core/rxjs-interop'; import { combineLatest, Subscription } from 'rxjs'; import { map, switchMap, tap } from 'rxjs/operators'; import { getErrorStateMatcher } from './all-errors-state.service'; import { ErrorStateMatchers } from './error-state-matchers.service'; import { NgxErrorsBase } from './errors-base.directive'; import { ERROR_CONFIGURATION } from './errors-configuration'; import { filterOutNullish } from './misc'; import { ValueMustBeStringError } from './ngx-errors'; import * as i0 from "@angular/core"; let errorDirectiveId = 0; /** * Directive to provide a validation error for a specific error name. * Used as a child of ngxErrors directive. * * Example: * ```html * <div [ngxErrors]="control"> * <div ngxError="required">This input is required</div> * </div> * ``` */ export class ErrorDirective { constructor() { this.subs = new Subscription(); this.config = inject(ERROR_CONFIGURATION); this.errorStateMatchers = inject(ErrorStateMatchers); this.errorsDirective = inject(NgxErrorsBase); this.templateRef = inject(TemplateRef); this.viewContainerRef = inject(ViewContainerRef); this.cdr = inject(ChangeDetectorRef); this.errorDirectiveId = ++errorDirectiveId; this.errorName = input.required({ alias: 'ngxError' }); this.showWhen = input('', { alias: 'ngxErrorShowWhen' }); this.computedShowWhen = computed(() => { const errorDirectiveShowWhen = this.showWhen(); if (errorDirectiveShowWhen) { return errorDirectiveShowWhen; } const errorsDirectiveShowWhen = this.errorsDirective.showWhen(); if (errorsDirectiveShowWhen) { return errorsDirectiveShowWhen; } if (this.config.showErrorsWhenInput === 'formIsSubmitted' && !this.errorsDirective.parentControlContainer) { return 'touched'; } return this.config.showErrorsWhenInput; }); this.errorStateMatcher = computed(() => { const showWhen = this.computedShowWhen(); return getErrorStateMatcher(this.errorStateMatchers, showWhen); }); this.controlState$ = toObservable(this.errorsDirective.controlState).pipe(filterOutNullish()); /** * Calculates whether the error could be shown based on the result of * ErrorStateMatcher and whether there is an error for this particular errorName * The calculation does not take into account config.showMaxErrors * * In addition, it observable produces a side-effect of updating NgxErrorsStateService * with the information of whether this directive could be shown and a side-effect * of updating err object in case it was mutated */ this.couldBeShown$ = combineLatest([ this.controlState$, toObservable(this.errorName), toObservable(this.errorStateMatcher), ]).pipe(switchMap(([controlState, errorName, errorStateMatcher]) => controlState.watchedEvents$.pipe(map(() => ({ controlState, errorName, errorStateMatcher, })))), map(({ controlState, errorName, errorStateMatcher }) => { const isErrorState = errorStateMatcher.isErrorState(controlState.control, controlState.parentForm); const hasError = controlState.control.hasError(errorName); const couldBeShown = isErrorState && hasError; const prevCouldBeShown = controlState.errors()[this.errorDirectiveId]; return { prevCouldBeShown, couldBeShown, errorName, controlState, hasError, }; }), tap(({ controlState, errorName, prevCouldBeShown, couldBeShown, hasError, }) => { if (prevCouldBeShown !== couldBeShown) { controlState.errors.update((errors) => { return { ...errors, [this.errorDirectiveId]: couldBeShown }; }); } const err = controlState.control.getError(errorName); const errorUpdated = hasError && JSON.stringify(this.err) !== JSON.stringify(err); if (errorUpdated) { this.err = err; if (this.view) { this.view.context.$implicit = this.err; this.view.markForCheck(); } } })); this.subscribeToCouldBeShown = this.subs.add(this.couldBeShown$.subscribe()); /** * Determines whether the error is shown to the user based on * the value of couldBeShown and the config.showMaxErrors. * In addition, this reacts to the changes in visibility for all * errors associated with the control */ this.isShown = computed(() => { const controlState = this.errorsDirective.controlState(); if (!controlState) { return false; } const errors = controlState.errors(); const couldBeShown = errors[this.errorDirectiveId]; if (!couldBeShown) { return false; } const { showMaxErrors } = this.config; if (!showMaxErrors) { return true; } // get all errors for this control that are possibly visible, // take directive ids associated with them, sort them // and show only these with index <= to config.showMaxErrors return Object.entries(errors) .reduce((acc, curr) => { const [id, couldBeShown] = curr; if (couldBeShown) { acc.push(Number(id)); } return acc; }, []) .sort() .filter((_, ix) => ix < showMaxErrors) .includes(this.errorDirectiveId); }); this.isShownEffect = effect(() => { const isShown = this.isShown(); const control = this.errorsDirective.resolvedControl(); if (!control) { return; } const prevHidden = this.hidden; this.hidden = !isShown; if (isShown) { this.err = control.getError(this.errorName()); } else { this.err = {}; } if (prevHidden !== this.hidden) { this.toggleVisibility(); } this.cdr.detectChanges(); }); this.hidden = true; // eslint-disable-next-line @typescript-eslint/no-explicit-any this.err = {}; } ngAfterViewInit() { this.validateDirective(); } ngOnDestroy() { this.subs.unsubscribe(); } toggleVisibility() { if (this.hidden) { if (this.view) { this.view.destroy(); this.view = undefined; } } else { if (this.view) { this.view.context.$implicit = this.err; this.view.markForCheck(); } else { this.view = this.viewContainerRef.createEmbeddedView(this.templateRef, { $implicit: this.err, }); } } } validateDirective() { const errorName = this.errorName(); if (typeof errorName !== 'string' || errorName.trim() === '') { throw new ValueMustBeStringError(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: ErrorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.7", type: ErrorDirective, isStandalone: true, selector: "[ngxError]", inputs: { errorName: { classPropertyName: "errorName", publicName: "ngxError", isSignal: true, isRequired: true, transformFunction: null }, showWhen: { classPropertyName: "showWhen", publicName: "ngxErrorShowWhen", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["ngxError"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: ErrorDirective, decorators: [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: '[ngxError]', exportAs: 'ngxError', standalone: true, }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3IuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbmd4LWVycm9ycy9wYWNrYWdlL3NyYy9saWIvZXJyb3IuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFFBQVEsRUFDUixTQUFTLEVBQ1QsTUFBTSxFQUVOLE1BQU0sRUFDTixLQUFLLEVBRUwsV0FBVyxFQUNYLGdCQUFnQixHQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbkQsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxtQkFBbUIsRUFBaUIsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDMUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sY0FBYyxDQUFDOztBQUV0RCxJQUFJLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUV6Qjs7Ozs7Ozs7OztHQVVHO0FBT0gsTUFBTSxPQUFPLGNBQWM7SUFOM0I7UUFPVSxTQUFJLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUUxQixXQUFNLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFckMsdUJBQWtCLEdBQUcsTUFBTSxD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LE9BQU8sRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN4QixDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMzQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtvQkFDckUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHO2lCQUNwQixDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxpQkFBaUI7UUFDdkIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ25DLElBQUksT0FBTyxTQUFTLEtBQUssUUFBUSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUM3RCxNQUFNLElBQUksc0JBQXNCLEVBQUUsQ0FBQztRQUNyQyxDQUFDO0lBQ0gsQ0FBQzs4R0F0T1UsY0FBYztrR0FBZCxjQUFjOzsyRkFBZCxjQUFjO2tCQU4xQixTQUFTO21CQUFDO29CQUNULDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLFlBQVk7b0JBQ3RCLFFBQVEsRUFBRSxVQUFVO29CQUNwQixVQUFVLEVBQUUsSUFBSTtpQkFDakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yICovXHJcbmltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBjb21wdXRlZCxcclxuICBEaXJlY3RpdmUsXHJcbiAgZWZmZWN0LFxyXG4gIEVtYmVkZGVkVmlld1JlZixcclxuICBpbmplY3QsXHJcbiAgaW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIFRlbXBsYXRlUmVmLFxyXG4gIFZpZXdDb250YWluZXJSZWYsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IHRvT2JzZXJ2YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcclxuXHJcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuaW1wb3J0IHsgZ2V0RXJyb3JTdGF0ZU1hdGNoZXIgfSBmcm9tICcuL2FsbC1lcnJvcnMtc3RhdGUuc2VydmljZSc7XHJcbmltcG9ydCB7IEVycm9yU3RhdGVNYXRjaGVycyB9IGZyb20gJy4vZXJyb3Itc3RhdGUtbWF0Y2hlcnMuc2VydmljZSc7XHJcbmltcG9ydCB7IE5neEVycm9yc0Jhc2UgfSBmcm9tICcuL2Vycm9ycy1iYXNlLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEVSUk9SX0NPTkZJR1VSQVRJT04sIFNob3dFcnJvcldoZW4gfSBmcm9tICcuL2Vycm9ycy1jb25maWd1cmF0aW9uJztcclxuaW1wb3J0IHsgZmlsdGVyT3V0TnVsbGlzaCB9IGZyb20gJy4vbWlzYyc7XHJcbmltcG9ydCB7IFZhbHVlTXVzdEJlU3RyaW5nRXJyb3IgfSBmcm9tICcuL25neC1lcnJvcnMnO1xyXG5cclxubGV0IGVycm9yRGlyZWN0aXZlSWQgPSAwO1xyXG5cclxuLyoqXHJcbiAqIERpcmVjdGl2ZSB0byBwcm92aWRlIGEgdmFsaWRhdGlvbiBlcnJvciBmb3IgYSBzcGVjaWZpYyBlcnJvciBuYW1lLlxyXG4gKiBVc2VkIGFzIGEgY2hpbGQgb2Ygbmd4RXJyb3JzIGRpcmVjdGl2ZS5cclxuICpcclxuICogRXhhbXBsZTpcclxuICogYGBgaHRtbFxyXG4gKiA8ZGl2IFtuZ3hFcnJvcnNdPVwiY29udHJvbFwiPlxyXG4gKiAgIDxkaXYgbmd4RXJyb3I9XCJyZXF1aXJlZFwiPlRoaXMgaW5wdXQgaXMgcmVxdWlyZWQ8L2Rpdj5cclxuICogPC9kaXY+XHJcbiAqIGBgYFxyXG4gKi9cclxuQERpcmVjdGl2ZSh7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtc2VsZWN0b3JcclxuICBzZWxlY3RvcjogJ1tuZ3hFcnJvcl0nLFxyXG4gIGV4cG9ydEFzOiAnbmd4RXJyb3InLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBFcnJvckRpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XHJcbiAgcHJpdmF0ZSBzdWJzID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG5cclxuICBwcml2YXRlIGNvbmZpZyA9IGluamVjdChFUlJPUl9DT05GSUdVUkFUSU9OKTtcclxuXHJcbiAgcHJpdmF0ZSBlcnJvclN0YXRlTWF0Y2hlcnMgPSBpbmplY3QoRXJyb3JTdGF0ZU1hdGNoZXJzKTtcclxuXHJcbiAgcHJpdmF0ZSBlcnJvcnNEaXJlY3RpdmUgPSBpbmplY3QoTmd4RXJyb3JzQmFzZSk7XHJcblxyXG4gIHByaXZhdGUgdGVtcGxhdGVSZWYgPSBpbmplY3QoVGVtcGxhdGVSZWYpO1xyXG5cclxuICBwcml2YXRlIHZpZXdDb250YWluZXJSZWYgPSBpbmplY3QoVmlld0NvbnRhaW5lclJlZik7XHJcblxyXG4gIHByaXZhdGUgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcclxuXHJcbiAgcHJpdmF0ZSB2aWV3OiBFbWJlZGRlZFZpZXdSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuXHJcbiAgcHJpdmF0ZSBlcnJvckRpcmVjdGl2ZUlkID0gKytlcnJvckRpcmVjdGl2ZUlkO1xyXG5cclxuICBlcnJvck5hbWUgPSBpbnB1dC5yZXF1aXJlZDxzdHJpbmc+KHsgYWxpYXM6ICduZ3hFcnJvcicgfSk7XHJcblxyXG4gIHNob3dXaGVuID0gaW5wdXQ8U2hvd0Vycm9yV2hlbj4oJycsIHsgYWxpYXM6ICduZ3hFcnJvclNob3dXaGVuJyB9KTtcclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlZFNob3dXaGVuID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgZXJyb3JEaXJlY3RpdmVTaG93V2hlbiA9IHRoaXMuc2hvd1doZW4oKTtcclxuICAgIGlmIChlcnJvckRpcmVjdGl2ZVNob3dXaGVuKSB7XHJcbiAgICAgIHJldHVybiBlcnJvckRpcmVjdGl2ZVNob3dXaGVuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGVycm9yc0RpcmVjdGl2ZVNob3dXaGVuID0gdGhpcy5lcnJvcnNEaXJlY3RpdmUuc2hvd1doZW4oKTtcclxuICAgIGlmIChlcnJvcnNEaXJlY3RpdmVTaG93V2hlbikge1xyXG4gICAgICByZXR1cm4gZXJyb3JzRGlyZWN0aXZlU2hvd1doZW47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmNvbmZpZy5zaG93RXJyb3JzV2hlbklucHV0ID09PSAnZm9ybUlzU3VibWl0dGVkJyAmJlxyXG4gICAgICAhdGhpcy5lcnJvcnNEaXJlY3RpdmUucGFyZW50Q29udHJvbENvbnRhaW5lclxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiAndG91Y2hlZCc7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnNob3dFcnJvcnNXaGVuSW5wdXQ7XHJcbiAgfSk7XHJcblxyXG4gIHByaXZhdGUgZXJyb3JTdGF0ZU1hdGNoZXIgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICBjb25zdCBzaG93V2hlbiA9IHRoaXMuY29tcHV0ZWRTaG93V2hlbigpO1xyXG4gICAgcmV0dXJuIGdldEVycm9yU3RhdGVNYXRjaGVyKHRoaXMuZXJyb3JTdGF0ZU1hdGNoZXJzLCBzaG93V2hlbik7XHJcbiAgfSk7XHJcblxyXG4gIHByaXZhdGUgY29udHJvbFN0YXRlJCA9IHRvT2JzZXJ2YWJsZSh0aGlzLmVycm9yc0RpcmVjdGl2ZS5jb250cm9sU3RhdGUpLnBpcGUoXHJcbiAgICBmaWx0ZXJPdXROdWxsaXNoKCksXHJcbiAgKTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsY3VsYXRlcyB3aGV0aGVyIHRoZSBlcnJvciBjb3VsZCBiZSBzaG93biBiYXNlZCBvbiB0aGUgcmVzdWx0IG9mXHJcbiAgICogRXJyb3JTdGF0ZU1hdGNoZXIgYW5kIHdoZXRoZXIgdGhlcmUgaXMgYW4gZXJyb3IgZm9yIHRoaXMgcGFydGljdWxhciBlcnJvck5hbWVcclxuICAgKiBUaGUgY2FsY3VsYXRpb24gZG9lcyBub3QgdGFrZSBpbnRvIGFjY291bnQgY29uZmlnLnNob3dNYXhFcnJvcnNcclxuICAgKlxyXG4gICAqIEluIGFkZGl0aW9uLCBpdCBvYnNlcnZhYmxlIHByb2R1Y2VzIGEgc2lkZS1lZmZlY3Qgb2YgdXBkYXRpbmcgTmd4RXJyb3JzU3RhdGVTZXJ2aWNlXHJcbiAgICogd2l0aCB0aGUgaW5mb3JtYXRpb24gb2Ygd2hldGhlciB0aGlzIGRpcmVjdGl2ZSBjb3VsZCBiZSBzaG93biBhbmQgYSBzaWRlLWVmZmVjdFxyXG4gICAqIG9mIHVwZGF0aW5nIGVyciBvYmplY3QgaW4gY2FzZSBpdCB3YXMgbXV0YXRlZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgY291bGRCZVNob3duJCA9IGNvbWJpbmVMYXRlc3QoW1xyXG4gICAgdGhpcy5jb250cm9sU3RhdGUkLFxyXG4gICAgdG9PYnNlcnZhYmxlKHRoaXMuZXJyb3JOYW1lKSxcclxuICAgIHRvT2JzZXJ2YWJsZSh0aGlzLmVycm9yU3RhdGVNYXRjaGVyKSxcclxuICBdKS5waXBlKFxyXG4gICAgc3dpdGNoTWFwKChbY29udHJvbFN0YXRlLCBlcnJvck5hbWUsIGVycm9yU3RhdGVNYXRjaGVyXSkgPT5cclxuICAgICAgY29udHJvbFN0YXRlLndhdGNoZWRFdmVudHMkLnBpcGUoXHJcbiAgICAgICAgbWFwKCgpID0+ICh7XHJcbiAgICAgICAgICBjb250cm9sU3RhdGUsXHJcbiAgICAgICAgICBlcnJvck5hbWUsXHJcbiAgICAgICAgICBlcnJvclN0YXRlTWF0Y2hlcixcclxuICAgICAgICB9KSksXHJcbiAgICAgICksXHJcbiAgICApLFxyXG4gICAgbWFwKCh7IGNvbnRyb2xTdGF0ZSwgZXJyb3JOYW1lLCBlcnJvclN0YXRlTWF0Y2hlciB9KSA9PiB7XHJcbiAgICAgIGNvbnN0IGlzRXJyb3JTdGF0ZSA9IGVycm9yU3RhdGVNYXRjaGVyLmlzRXJyb3JTdGF0ZShcclxuICAgICAgICBjb250cm9sU3RhdGUuY29udHJvbCxcclxuICAgICAgICBjb250cm9sU3RhdGUucGFyZW50Rm9ybSxcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnN0IGhhc0Vycm9yID0gY29udHJvbFN0YXRlLmNvbnRyb2wuaGFzRXJyb3IoZXJyb3JOYW1lKTtcclxuICAgICAgY29uc3QgY291bGRCZVNob3duID0gaXNFcnJvclN0YXRlICYmIGhhc0Vycm9yO1xyXG5cclxuICAgICAgY29uc3QgcHJldkNvdWxkQmVTaG93biA9IGNvbnRyb2xTdGF0ZS5lcnJvcnMoKVt0aGlzLmVycm9yRGlyZWN0aXZlSWRdO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBwcmV2Q291bGRCZVNob3duLFxyXG4gICAgICAgIGNvdWxkQmVTaG93bixcclxuICAgICAgICBlcnJvck5hbWUsXHJcbiAgICAgICAgY29udHJvbFN0YXRlLFxyXG4gICAgICAgIGhhc0Vycm9yLFxyXG4gICAgICB9O1xyXG4gICAgfSksXHJcbiAgICB0YXAoXHJcbiAgICAgICh7XHJcbiAgICAgICAgY29udHJvbFN0YXRlLFxyXG4gICAgICAgIGVycm9yTmFtZSxcclxuICAgICAgICBwcmV2Q291bGRCZVNob3duLFxyXG4gICAgICAgIGNvdWxkQmVTaG93bixcclxuICAgICAgICBoYXNFcnJvcixcclxuICAgICAgfSkgPT4ge1xyXG4gICAgICAgIGlmIChwcmV2Q291bGRCZVNob3duICE9PSBjb3VsZEJlU2hvd24pIHtcclxuICAgICAgICAgIGNvbnRyb2xTdGF0ZS5lcnJvcnMudXBkYXRlKChlcnJvcnMpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHsgLi4uZXJyb3JzLCBbdGhpcy5lcnJvckRpcmVjdGl2ZUlkXTogY291bGRCZVNob3duIH07XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGVyciA9IGNvbnRyb2xTdGF0ZS5jb250cm9sLmdldEVycm9yKGVycm9yTmFtZSk7XHJcblxyXG4gICAgICAgIGNvbnN0IGVycm9yVXBkYXRlZCA9XHJcbiAgICAgICAgICBoYXNFcnJvciAmJiBKU09OLnN0cmluZ2lmeSh0aGlzLmVycikgIT09IEpTT04uc3RyaW5naWZ5KGVycik7XHJcblxyXG4gICAgICAgIGlmIChlcnJvclVwZGF0ZWQpIHtcclxuICAgICAgICAgIHRoaXMuZXJyID0gZXJyO1xyXG4gICAgICAgICAgaWYgKHRoaXMudmlldykge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXcuY29udGV4dC4kaW1wbGljaXQgPSB0aGlzLmVycjtcclxuICAgICAgICAgICAgdGhpcy52aWV3Lm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICksXHJcbiAgKTtcclxuXHJcbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb0NvdWxkQmVTaG93biA9IHRoaXMuc3Vicy5hZGQoXHJcbiAgICB0aGlzLmNvdWxkQmVTaG93biQuc3Vic2NyaWJlKCksXHJcbiAgKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBlcnJvciBpcyBzaG93biB0byB0aGUgdXNlciBiYXNlZCBvblxyXG4gICAqIHRoZSB2YWx1ZSBvZiBjb3VsZEJlU2hvd24gYW5kIHRoZSBjb25maWcuc2hvd01heEVycm9ycy5cclxuICAgKiBJbiBhZGRpdGlvbiwgdGhpcyByZWFjdHMgdG8gdGhlIGNoYW5nZXMgaW4gdmlzaWJpbGl0eSBmb3IgYWxsXHJcbiAgICogZXJyb3JzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29udHJvbFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaXNTaG93biA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIGNvbnN0IGNvbnRyb2xTdGF0ZSA9IHRoaXMuZXJyb3JzRGlyZWN0aXZlLmNvbnRyb2xTdGF0ZSgpO1xyXG4gICAgaWYgKCFjb250cm9sU3RhdGUpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGVycm9ycyA9IGNvbnRyb2xTdGF0ZS5lcnJvcnMoKTtcclxuXHJcbiAgICBjb25zdCBjb3VsZEJlU2hvd24gPSBlcnJvcnNbdGhpcy5lcnJvckRpcmVjdGl2ZUlkXTtcclxuXHJcbiAgICBpZiAoIWNvdWxkQmVTaG93bikge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgeyBzaG93TWF4RXJyb3JzIH0gPSB0aGlzLmNvbmZpZztcclxuICAgIGlmICghc2hvd01heEVycm9ycykge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBnZXQgYWxsIGVycm9ycyBmb3IgdGhpcyBjb250cm9sIHRoYXQgYXJlIHBvc3NpYmx5IHZpc2libGUsXHJcbiAgICAvLyB0YWtlIGRpcmVjdGl2ZSBpZHMgYXNzb2NpYXRlZCB3aXRoIHRoZW0sIHNvcnQgdGhlbVxyXG4gICAgLy8gYW5kIHNob3cgb25seSB0aGVzZSB3aXRoIGluZGV4IDw9IHRvIGNvbmZpZy5zaG93TWF4RXJyb3JzXHJcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoZXJyb3JzKVxyXG4gICAgICAucmVkdWNlKChhY2MsIGN1cnIpID0+IHtcclxuICAgICAgICBjb25zdCBbaWQsIGNvdWxkQmVTaG93bl0gPSBjdXJyO1xyXG4gICAgICAgIGlmIChjb3VsZEJlU2hvd24pIHtcclxuICAgICAgICAgIGFjYy5wdXNoKE51bWJlcihpZCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYWNjO1xyXG4gICAgICB9LCBbXSBhcyBudW1iZXJbXSlcclxuICAgICAgLnNvcnQoKVxyXG4gICAgICAuZmlsdGVyKChfLCBpeCkgPT4gaXggPCBzaG93TWF4RXJyb3JzKVxyXG4gICAgICAuaW5jbHVkZXModGhpcy5lcnJvckRpcmVjdGl2ZUlkKTtcclxuICB9KTtcclxuXHJcbiAgcHJpdmF0ZSBpc1Nob3duRWZmZWN0ID0gZWZmZWN0KCgpID0+IHtcclxuICAgIGNvbnN0IGlzU2hvd24gPSB0aGlzLmlzU2hvd24oKTtcclxuICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmVycm9yc0RpcmVjdGl2ZS5yZXNvbHZlZENvbnRyb2woKTtcclxuXHJcbiAgICBpZiAoIWNvbnRyb2wpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHByZXZIaWRkZW4gPSB0aGlzLmhpZGRlbjtcclxuICAgIHRoaXMuaGlkZGVuID0gIWlzU2hvd247XHJcblxyXG4gICAgaWYgKGlzU2hvd24pIHtcclxuICAgICAgdGhpcy5lcnIgPSBjb250cm9sLmdldEVycm9yKHRoaXMuZXJyb3JOYW1lKCkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5lcnIgPSB7fTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAocHJldkhpZGRlbiAhPT0gdGhpcy5oaWRkZW4pIHtcclxuICAgICAgdGhpcy50b2dnbGVWaXNpYmlsaXR5KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH0pO1xyXG5cclxuICBoaWRkZW4gPSB0cnVlO1xyXG5cclxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG4gIGVycjogYW55ID0ge307XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMudmFsaWRhdGVEaXJlY3RpdmUoKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5zdWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHRvZ2dsZVZpc2liaWxpdHkoKSB7XHJcbiAgICBpZiAodGhpcy5oaWRkZW4pIHtcclxuICAgICAgaWYgKHRoaXMudmlldykge1xyXG4gICAgICAgIHRoaXMudmlldy5kZXN0cm95KCk7XHJcbiAgICAgICAgdGhpcy52aWV3ID0gdW5kZWZpbmVkO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy52aWV3KSB7XHJcbiAgICAgICAgdGhpcy52aWV3LmNvbnRleHQuJGltcGxpY2l0ID0gdGhpcy5lcnI7XHJcbiAgICAgICAgdGhpcy52aWV3Lm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMudmlldyA9IHRoaXMudmlld0NvbnRhaW5lclJlZi5jcmVhdGVFbWJlZGRlZFZpZXcodGhpcy50ZW1wbGF0ZVJlZiwge1xyXG4gICAgICAgICAgJGltcGxpY2l0OiB0aGlzLmVycixcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB2YWxpZGF0ZURpcmVjdGl2ZSgpIHtcclxuICAgIGNvbnN0IGVycm9yTmFtZSA9IHRoaXMuZXJyb3JOYW1lKCk7XHJcbiAgICBpZiAodHlwZW9mIGVycm9yTmFtZSAhPT0gJ3N0cmluZycgfHwgZXJyb3JOYW1lLnRyaW0oKSA9PT0gJycpIHtcclxuICAgICAgdGhyb3cgbmV3IFZhbHVlTXVzdEJlU3RyaW5nRXJyb3IoKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19