UNPKG

@bimeister/pupakit.forms

Version:
213 lines 31.8 kB
import { Directive, ElementRef, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core'; import { NgControl } from '@angular/forms'; import '@bimeister/pupakit.common'; import { distinctUntilSerializedChanged, filterNotNil, filterTruthy, isNil, shareReplayWithRefCount, } from '@bimeister/utilities'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { distinctUntilChanged, map, take } from 'rxjs/operators'; import '../../types/textarea-counter-visibility-mode.type'; import '../../types/textarea-size.type'; import { InputBaseControlValueAccessor } from './input-base-control-value-accessor.abstract'; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; const DEFAULT_MAX_ROWS = 5; const LARGE_TEXTAREA_VERTICAL_PADDINGS_PX = 24; const MEDIUM_TEXTAREA_VERTICAL_PADDINGS_PX = 16; export class TextareaBase extends InputBaseControlValueAccessor { constructor(ngControl) { super(ngControl); this.size = 'medium'; this.size$ = new BehaviorSubject('medium'); this.placeholder = ''; this.placeholder$ = new BehaviorSubject(''); this.autocomplete = false; this.autocomplete$ = new BehaviorSubject(false); this.isPatched = false; this.isPatched$ = new BehaviorSubject(false); this.minRows = 2; this.minRows$ = new BehaviorSubject(this.minRows); this.minHeightPx$ = combineLatest([this.minRows$, this.size$]).pipe(map(([minRows, size]) => TextareaBase.getHeightPxByRowsCount(this.lineHeightSourceRef, minRows, size))); this.maxRows = DEFAULT_MAX_ROWS; this.maxRows$ = new BehaviorSubject(this.maxRows); this.maxHeightPx$ = combineLatest([ this.minRows$, this.maxRows$, this.size$, ]).pipe(map(([minRows, maxRows, size]) => { if (isNil(maxRows)) { return null; } const rowsCount = minRows > maxRows ? minRows : maxRows; return TextareaBase.getHeightPxByRowsCount(this.lineHeightSourceRef, rowsCount, size); })); this.maxLength = null; this.maxLength$ = new BehaviorSubject(null); this.counterVisibility = 'always'; this.counterVisibility$ = new BehaviorSubject('always'); this.focus = new EventEmitter(); this.blur = new EventEmitter(); this.enterKeyPrevented = false; this.enterKeyPrevented$ = new BehaviorSubject(false); this.isInvalid$ = combineLatest([ this.isDisabled$, this.isPatched$, this.isValid$, this.isTouched$, ]).pipe(distinctUntilSerializedChanged(), map(([isDisabled, isPatched, isValid, isTouched]) => (isTouched || isPatched) && !isValid && !isDisabled)); this.valueLength$ = this.value$.pipe(filterNotNil(), map((currentValue) => currentValue?.length ?? 0)); this.counterValue$ = combineLatest([this.maxLength$, this.valueLength$]).pipe(map(([maxLength, valueLength]) => `${valueLength}/${maxLength}`)); this.isCounterVisible$ = combineLatest([ this.counterVisibility$, this.isFocused$, this.valueLength$, ]).pipe(map(([counterVisibilityMode, isFocused, valueLength]) => { if (counterVisibilityMode === 'onfocus') { return isFocused; } if (counterVisibilityMode === 'filled') { return valueLength > 0; } return true; }), distinctUntilChanged(), shareReplayWithRefCount()); } setValue(value) { const serializedValue = isNil(value) ? '' : value; this.value$.next(serializedValue); } ngOnChanges(changes) { this.processSizeChange(changes?.size); this.processPlaceholderChange(changes?.placeholder); this.processAutocompleteChange(changes?.autocomplete); this.processIsPatchedChange(changes?.isPatched); this.processMaxLengthChange(changes?.maxLength); this.processMaxRowsChange(changes?.maxRows); this.processMinRowsChange(changes?.minRows); this.processCounterVisibilityChange(changes?.counterVisibility); this.processEnterKeyDisabledChange(changes?.enterKeyPrevented); } emitFocusEvent(focusEvent) { this.isFocused$.next(true); this.focus.emit(focusEvent); } emitBlurEvent(blurEvent) { this.isFocused$.next(false); this.blur.emit(blurEvent); } preventEnterKeyEvent(event) { this.enterKeyPrevented$.pipe(take(1), filterTruthy()).subscribe(() => event.preventDefault()); } focusOnTextareaElement() { const textareaElement = this.textareaElementRef.nativeElement; textareaElement.focus(); } processMouseDown(event) { if (event.target === this.textareaElementRef.nativeElement) { return; } event.preventDefault(); } processSizeChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.size$.next(updatedValue); } processPlaceholderChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.placeholder$.next(updatedValue); } processAutocompleteChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.autocomplete$.next(updatedValue); } processIsPatchedChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.isPatched$.next(updatedValue); } processMaxLengthChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.maxLength$.next(updatedValue); } processMaxRowsChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue) || !Number.isInteger(updatedValue)) { return; } this.maxRows$.next(updatedValue); } processMinRowsChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue) || !Number.isInteger(updatedValue)) { return; } this.minRows$.next(updatedValue); } processCounterVisibilityChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.counterVisibility$.next(updatedValue); } processEnterKeyDisabledChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.enterKeyPrevented$.next(updatedValue); } static getHeightPxByRowsCount(lineHeightSourceRef, rowsCount, size) { const verticalPaddingsPx = size === 'large' ? LARGE_TEXTAREA_VERTICAL_PADDINGS_PX : MEDIUM_TEXTAREA_VERTICAL_PADDINGS_PX; const computedStyles = getComputedStyle(lineHeightSourceRef.nativeElement); const lineHeightPx = Number.parseFloat(computedStyles.lineHeight); return lineHeightPx * rowsCount + verticalPaddingsPx; } } TextareaBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TextareaBase, deps: [{ token: i1.NgControl, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); TextareaBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: TextareaBase, inputs: { size: "size", placeholder: "placeholder", autocomplete: "autocomplete", isPatched: "isPatched", minRows: "minRows", maxRows: "maxRows", maxLength: "maxLength", counterVisibility: "counterVisibility", enterKeyPrevented: "enterKeyPrevented" }, outputs: { focus: "focus", blur: "blur" }, viewQueries: [{ propertyName: "lineHeightSourceRef", first: true, predicate: ["lineHeightSource"], descendants: true, static: true }, { propertyName: "textareaElementRef", first: true, predicate: ["textarea"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TextareaBase, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: i1.NgControl, decorators: [{ type: Optional }] }]; }, propDecorators: { lineHeightSourceRef: [{ type: ViewChild, args: ['lineHeightSource', { static: true }] }], textareaElementRef: [{ type: ViewChild, args: ['textarea'] }], size: [{ type: Input }], placeholder: [{ type: Input }], autocomplete: [{ type: Input }], isPatched: [{ type: Input }], minRows: [{ type: Input }], maxRows: [{ type: Input }], maxLength: [{ type: Input }], counterVisibility: [{ type: Input }], focus: [{ type: Output }], blur: [{ type: Output }], enterKeyPrevented: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEtYmFzZS5hYnN0cmFjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9kZWNsYXJhdGlvbnMvY2xhc3Nlcy9hYnN0cmFjdC90ZXh0YXJlYS1iYXNlLmFic3RyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWEsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQWtELDJCQUEyQixDQUFDO0FBQzlFLE9BQU8sRUFDTCw4QkFBOEIsRUFDOUIsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBRUwsdUJBQXVCLEdBQ3hCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDbEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNqRSxPQUEwQyxtREFBbUQsQ0FBQztBQUM5RixPQUE2QixnQ0FBZ0MsQ0FBQztBQUM5RCxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQzs7O0FBRTdGLE1BQU0sZ0JBQWdCLEdBQVcsQ0FBQyxDQUFDO0FBQ25DLE1BQU0sbUNBQW1DLEdBQVcsRUFBRSxDQUFDO0FBQ3ZELE1BQU0sb0NBQW9DLEdBQVcsRUFBRSxDQUFDO0FBR3hELE1BQU0sT0FBZ0IsWUFBYSxTQUFRLDZCQUFxQztJQW1HOUUsWUFBd0IsU0FBb0I7UUFDMUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBN0ZILFNBQUksR0FBaUIsUUFBUSxDQUFDO1FBQzlCLFVBQUssR0FBa0MsSUFBSSxlQUFlLENBQWUsUUFBUSxDQUFDLENBQUM7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LENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFTyxNQUFNLENBQUMsc0JBQXNCLENBQ25DLG1CQUFvRCxFQUNwRCxTQUFpQixFQUNqQixJQUFrQjtRQUVsQixNQUFNLGtCQUFrQixHQUN0QixJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLENBQUMsb0NBQW9DLENBQUM7UUFFaEcsTUFBTSxjQUFjLEdBQXdCLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2hHLE1BQU0sWUFBWSxHQUFXLE1BQU0sQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTFFLE9BQU8sWUFBWSxHQUFHLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQztJQUN2RCxDQUFDOzswR0F4UG1CLFlBQVk7OEZBQVosWUFBWTs0RkFBWixZQUFZO2tCQURqQyxTQUFTOzswQkFvR0ssUUFBUTs0Q0FqR0YsbUJBQW1CO3NCQURyQyxTQUFTO3VCQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFJNUIsa0JBQWtCO3NCQURwQyxTQUFTO3VCQUFDLFVBQVU7Z0JBR0wsSUFBSTtzQkFBbkIsS0FBSztnQkFHbUIsV0FBVztzQkFBbkMsS0FBSztnQkFHbUIsWUFBWTtzQkFBcEMsS0FBSztnQkFHbUIsU0FBUztzQkFBakMsS0FBSztnQkFHVSxPQUFPO3NCQUF0QixLQUFLO2dCQVFVLE9BQU87c0JBQXRCLEtBQUs7Z0JBaUJVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBR1UsaUJBQWlCO3NCQUFoQyxLQUFLO2dCQUlxQixLQUFLO3NCQUEvQixNQUFNO2dCQUNvQixJQUFJO3NCQUE5QixNQUFNO2dCQUVTLGlCQUFpQjtzQkFBaEMsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPcHRpb25hbCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IENvbXBvbmVudENoYW5nZSwgQ29tcG9uZW50Q2hhbmdlcyB9IGZyb20gJ0BiaW1laXN0ZXIvcHVwYWtpdC5jb21tb24nO1xuaW1wb3J0IHtcbiAgZGlzdGluY3RVbnRpbFNlcmlhbGl6ZWRDaGFuZ2VkLFxuICBmaWx0ZXJOb3ROaWwsXG4gIGZpbHRlclRydXRoeSxcbiAgaXNOaWwsXG4gIE51bGxhYmxlLFxuICBzaGFyZVJlcGxheVdpdGhSZWZDb3VudCxcbn0gZnJvbSAnQGJpbWVpc3Rlci91dGlsaXRpZXMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGV4dGFyZWFDb3VudGVyVmlzaWJpbGl0eSB9IGZyb20gJy4uLy4uL3R5cGVzL3RleHRhcmVhLWNvdW50ZXItdmlzaWJpbGl0eS1tb2RlLnR5cGUnO1xuaW1wb3J0IHsgVGV4dGFyZWFTaXplIH0gZnJvbSAnLi4vLi4vdHlwZXMvdGV4dGFyZWEtc2l6ZS50eXBlJztcbmltcG9ydCB7IElucHV0QmFzZUNvbnRyb2xWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnLi9pbnB1dC1iYXNlLWNvbnRyb2wtdmFsdWUtYWNjZXNzb3IuYWJzdHJhY3QnO1xuXG5jb25zdCBERUZBVUxUX01BWF9ST1dTOiBudW1iZXIgPSA1O1xuY29uc3QgTEFSR0VfVEVYVEFSRUFfVkVSVElDQUxfUEFERElOR1NfUFg6IG51bWJlciA9IDI0O1xuY29uc3QgTUVESVVNX1RFWFRBUkVBX1ZFUlRJQ0FMX1BBRERJTkdTX1BYOiBudW1iZXIgPSAxNjtcblxuQERpcmVjdGl2ZSgpXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVGV4dGFyZWFCYXNlIGV4dGVuZHMgSW5wdXRCYXNlQ29udHJvbFZhbHVlQWNjZXNzb3I8c3RyaW5nPiBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBWaWV3Q2hpbGQoJ2xpbmVIZWlnaHRTb3VyY2UnLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGluZUhlaWdodFNvdXJjZVJlZjogRWxlbWVudFJlZjxIVE1MVGV4dEFyZWFFbGVtZW50PjtcblxuICBAVmlld0NoaWxkKCd0ZXh0YXJlYScpXG4gIHByb3RlY3RlZCByZWFkb25seSB0ZXh0YXJlYUVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTFRleHRBcmVhRWxlbWVudD47XG5cbiAgQElucHV0KCkgcHVibGljIHNpemU6IFRleHRhcmVhU2l6ZSA9ICdtZWRpdW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgc2l6ZSQ6IEJlaGF2aW9yU3ViamVjdDxUZXh0YXJlYVNpemU+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUZXh0YXJlYVNpemU+KCdtZWRpdW0nKTtcblxuICBASW5wdXQoKSBwdWJsaWMgcmVhZG9ubHkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICcnO1xuICBwdWJsaWMgcmVhZG9ubHkgcGxhY2Vob2xkZXIkOiBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XG5cbiAgQElucHV0KCkgcHVibGljIHJlYWRvbmx5IGF1dG9jb21wbGV0ZTogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgcmVhZG9ubHkgYXV0b2NvbXBsZXRlJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgQElucHV0KCkgcHVibGljIHJlYWRvbmx5IGlzUGF0Y2hlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgcmVhZG9ubHkgaXNQYXRjaGVkJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgQElucHV0KCkgcHVibGljIG1pblJvd3M6IG51bWJlciA9IDI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWluUm93cyQ6IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KHRoaXMubWluUm93cyk7XG4gIHB1YmxpYyByZWFkb25seSBtaW5IZWlnaHRQeCQ6IE9ic2VydmFibGU8bnVtYmVyPiA9IGNvbWJpbmVMYXRlc3QoW3RoaXMubWluUm93cyQsIHRoaXMuc2l6ZSRdKS5waXBlKFxuICAgIG1hcCgoW21pblJvd3MsIHNpemVdOiBbbnVtYmVyLCBUZXh0YXJlYVNpemVdKSA9PlxuICAgICAgVGV4dGFyZWFCYXNlLmdldEhlaWdodFB4QnlSb3dzQ291bnQodGhpcy5saW5lSGVpZ2h0U291cmNlUmVmLCBtaW5Sb3dzLCBzaXplKVxuICAgIClcbiAgKTtcblxuICBASW5wdXQoKSBwdWJsaWMgbWF4Um93czogbnVtYmVyID0gREVGQVVMVF9NQVhfUk9XUztcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhSb3dzJDogQmVoYXZpb3JTdWJqZWN0PE51bGxhYmxlPG51bWJlcj4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxOdWxsYWJsZTxudW1iZXI+Pih0aGlzLm1heFJvd3MpO1xuICBwdWJsaWMgcmVhZG9ubHkgbWF4SGVpZ2h0UHgkOiBPYnNlcnZhYmxlPE51bGxhYmxlPG51bWJlcj4+ID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5taW5Sb3dzJCxcbiAgICB0aGlzLm1heFJvd3MkLFxuICAgIHRoaXMuc2l6ZSQsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbbWluUm93cywgbWF4Um93cywgc2l6ZV06IFtudW1iZXIsIE51bGxhYmxlPG51bWJlcj4sIFRleHRhcmVhU2l6ZV0pID0+IHtcbiAgICAgIGlmIChpc05pbChtYXhSb3dzKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgcm93c0NvdW50OiBudW1iZXIgPSBtaW5Sb3dzID4gbWF4Um93cyA/IG1pblJvd3MgOiBtYXhSb3dzO1xuICAgICAgcmV0dXJuIFRleHRhcmVhQmFzZS5nZXRIZWlnaHRQeEJ5Um93c0NvdW50KHRoaXMubGluZUhlaWdodFNvdXJjZVJlZiwgcm93c0NvdW50LCBzaXplKTtcbiAgICB9KVxuICApO1xuXG4gIEBJbnB1dCgpIHB1YmxpYyBtYXhMZW5ndGg6IE51bGxhYmxlPG51bWJlcj4gPSBudWxsO1xuICBwdWJsaWMgcmVhZG9ubHkgbWF4TGVuZ3RoJDogQmVoYXZpb3JTdWJqZWN0PE51bGxhYmxlPG51bWJlcj4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxOdWxsYWJsZTxudW1iZXI+PihudWxsKTtcblxuICBASW5wdXQoKSBwdWJsaWMgY291bnRlclZpc2liaWxpdHk6IFRleHRhcmVhQ291bnRlclZpc2liaWxpdHkgPSAnYWx3YXlzJztcbiAgcHVibGljIHJlYWRvbmx5IGNvdW50ZXJWaXNpYmlsaXR5JDogQmVoYXZpb3JTdWJqZWN0PFRleHRhcmVhQ291bnRlclZpc2liaWxpdHk+ID1cbiAgICBuZXcgQmVoYXZpb3JTdWJqZWN0PFRleHRhcmVhQ291bnRlclZpc2liaWxpdHk+KCdhbHdheXMnKTtcblxuICBAT3V0cHV0KCkgcHJpdmF0ZSByZWFkb25seSBmb2N1czogRXZlbnRFbWl0dGVyPEZvY3VzRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuICBAT3V0cHV0KCkgcHJpdmF0ZSByZWFkb25seSBibHVyOiBFdmVudEVtaXR0ZXI8Rm9jdXNFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPEZvY3VzRXZlbnQ+KCk7XG5cbiAgQElucHV0KCkgcHVibGljIGVudGVyS2V5UHJldmVudGVkOiBib29sZWFuID0gZmFsc2U7XG4gIHB1YmxpYyByZWFkb25seSBlbnRlcktleVByZXZlbnRlZCQ6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIHB1YmxpYyByZWFkb25seSBpc0ludmFsaWQkOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5pc0Rpc2FibGVkJCxcbiAgICB0aGlzLmlzUGF0Y2hlZCQsXG4gICAgdGhpcy5pc1ZhbGlkJCxcbiAgICB0aGlzLmlzVG91Y2hlZCQsXG4gIF0pLnBpcGUoXG4gICAgZGlzdGluY3RVbnRpbFNlcmlhbGl6ZWRDaGFuZ2VkKCksXG4gICAgbWFwKFxuICAgICAgKFtpc0Rpc2FibGVkLCBpc1BhdGNoZWQsIGlzVmFsaWQsIGlzVG91Y2hlZF06IFtib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuXSkgPT5cbiAgICAgICAgKGlzVG91Y2hlZCB8fCBpc1BhdGNoZWQpICYmICFpc1ZhbGlkICYmICFpc0Rpc2FibGVkXG4gICAgKVxuICApO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdmFsdWVMZW5ndGgkOiBPYnNlcnZhYmxlPG51bWJlcj4gPSB0aGlzLnZhbHVlJC5waXBlKFxuICAgIGZpbHRlck5vdE5pbCgpLFxuICAgIG1hcCgoY3VycmVudFZhbHVlOiBzdHJpbmcpID0+IGN1cnJlbnRWYWx1ZT8ubGVuZ3RoID8/IDApXG4gICk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGNvdW50ZXJWYWx1ZSQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IGNvbWJpbmVMYXRlc3QoW3RoaXMubWF4TGVuZ3RoJCwgdGhpcy52YWx1ZUxlbmd0aCRdKS5waXBlKFxuICAgIG1hcCgoW21heExlbmd0aCwgdmFsdWVMZW5ndGhdOiBbbnVtYmVyLCBudW1iZXJdKSA9PiBgJHt2YWx1ZUxlbmd0aH0vJHttYXhMZW5ndGh9YClcbiAgKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgaXNDb3VudGVyVmlzaWJsZSQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLmNvdW50ZXJWaXNpYmlsaXR5JCxcbiAgICB0aGlzLmlzRm9jdXNlZCQsXG4gICAgdGhpcy52YWx1ZUxlbmd0aCQsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbY291bnRlclZpc2liaWxpdHlNb2RlLCBpc0ZvY3VzZWQsIHZhbHVlTGVuZ3RoXTogW1RleHRhcmVhQ291bnRlclZpc2liaWxpdHksIGJvb2xlYW4sIG51bWJlcl0pID0+IHtcbiAgICAgIGlmIChjb3VudGVyVmlzaWJpbGl0eU1vZGUgPT09ICdvbmZvY3VzJykge1xuICAgICAgICByZXR1cm4gaXNGb2N1c2VkO1xuICAgICAgfVxuXG4gICAgICBpZiAoY291bnRlclZpc2liaWxpdHlNb2RlID09PSAnZmlsbGVkJykge1xuICAgICAgICByZXR1cm4gdmFsdWVMZW5ndGggPiAwO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIHNoYXJlUmVwbGF5V2l0aFJlZkNvdW50KClcbiAgKTtcblxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBuZ0NvbnRyb2w6IE5nQ29udHJvbCkge1xuICAgIHN1cGVyKG5nQ29udHJvbCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmFsdWUodmFsdWU6IE51bGxhYmxlPHN0cmluZz4pOiB2b2lkIHtcbiAgICBjb25zdCBzZXJpYWxpemVkVmFsdWU6IHN0cmluZyA9IGlzTmlsKHZhbHVlKSA/ICcnIDogdmFsdWU7XG4gICAgdGhpcy52YWx1ZSQubmV4dChzZXJpYWxpemVkVmFsdWUpO1xuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IENvbXBvbmVudENoYW5nZXM8dGhpcz4pOiB2b2lkIHtcbiAgICB0aGlzLnByb2Nlc3NTaXplQ2hhbmdlKGNoYW5nZXM/LnNpemUpO1xuICAgIHRoaXMucHJvY2Vzc1BsYWNlaG9sZGVyQ2hhbmdlKGNoYW5nZXM/LnBsYWNlaG9sZGVyKTtcbiAgICB0aGlzLnByb2Nlc3NBdXRvY29tcGxldGVDaGFuZ2UoY2hhbmdlcz8uYXV0b2NvbXBsZXRlKTtcbiAgICB0aGlzLnByb2Nlc3NJc1BhdGNoZWRDaGFuZ2UoY2hhbmdlcz8uaXNQYXRjaGVkKTtcblxuICAgIHRoaXMucHJvY2Vzc01heExlbmd0aENoYW5nZShjaGFuZ2VzPy5tYXhMZW5ndGgpO1xuICAgIHRoaXMucHJvY2Vzc01heFJvd3NDaGFuZ2UoY2hhbmdlcz8ubWF4Um93cyk7XG4gICAgdGhpcy5wcm9jZXNzTWluUm93c0NoYW5nZShjaGFuZ2VzPy5taW5Sb3dzKTtcbiAgICB0aGlzLnByb2Nlc3NDb3VudGVyVmlzaWJpbGl0eUNoYW5nZShjaGFuZ2VzPy5jb3VudGVyVmlzaWJpbGl0eSk7XG4gICAgdGhpcy5wcm9jZXNzRW50ZXJLZXlEaXNhYmxlZENoYW5nZShjaGFuZ2VzPy5lbnRlcktleVByZXZlbnRlZCk7XG4gIH1cblxuICBwdWJsaWMgZW1pdEZvY3VzRXZlbnQoZm9jdXNFdmVudDogRm9jdXNFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuaXNGb2N1c2VkJC5uZXh0KHRydWUpO1xuICAgIHRoaXMuZm9jdXMuZW1pdChmb2N1c0V2ZW50KTtcbiAgfVxuXG4gIHB1YmxpYyBlbWl0Qmx1ckV2ZW50KGJsdXJFdmVudDogRm9jdXNFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuaXNGb2N1c2VkJC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLmJsdXIuZW1pdChibHVyRXZlbnQpO1xuICB9XG5cbiAgcHVibGljIHByZXZlbnRFbnRlcktleUV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5lbnRlcktleVByZXZlbnRlZCQucGlwZSh0YWtlKDEpLCBmaWx0ZXJUcnV0aHkoKSkuc3Vic2NyaWJlKCgpID0+IGV2ZW50LnByZXZlbnREZWZhdWx0KCkpO1xuICB9XG5cbiAgcHVibGljIGZvY3VzT25UZXh0YXJlYUVsZW1lbnQoKTogdm9pZCB7XG4gICAgY29uc3QgdGV4dGFyZWFFbGVtZW50OiBIVE1MVGV4dEFyZWFFbGVtZW50ID0gdGhpcy50ZXh0YXJlYUVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICB0ZXh0YXJlYUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBwcm9jZXNzTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gdGhpcy50ZXh0YXJlYUVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzU2l6ZUNoYW5nZShjaGFuZ2U6IENvbXBvbmVudENoYW5nZTx0aGlzLCBUZXh0YXJlYVNpemU+KTogdm9pZCB7XG4gICAgY29uc3QgdXBkYXRlZFZhbHVlOiBUZXh0YXJlYVNpemUgfCB1bmRlZmluZWQgPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zaXplJC5uZXh0KHVwZGF0ZWRWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NQbGFjZWhvbGRlckNoYW5nZShjaGFuZ2U6IENvbXBvbmVudENoYW5nZTx0aGlzLCBzdHJpbmc+KTogdm9pZCB7XG4gICAgY29uc3QgdXBkYXRlZFZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5wbGFjZWhvbGRlciQubmV4dCh1cGRhdGVkVmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzQXV0b2NvbXBsZXRlQ2hhbmdlKGNoYW5nZTogQ29tcG9uZW50Q2hhbmdlPHRoaXMsIGJvb2xlYW4+KTogdm9pZCB7XG4gICAgY29uc3QgdXBkYXRlZFZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkID0gY2hhbmdlPy5jdXJyZW50VmFsdWU7XG5cbiAgICBpZiAoaXNOaWwodXBkYXRlZFZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYXV0b2NvbXBsZXRlJC5uZXh0KHVwZGF0ZWRWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NJc1BhdGNoZWRDaGFuZ2UoY2hhbmdlOiBDb21wb25lbnRDaGFuZ2U8dGhpcywgYm9vbGVhbj4pOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWU6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pc1BhdGNoZWQkLm5leHQodXBkYXRlZFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc01heExlbmd0aENoYW5nZShjaGFuZ2U6IENvbXBvbmVudENoYW5nZTx0aGlzLCBOdWxsYWJsZTxudW1iZXI+Pik6IHZvaWQge1xuICAgIGNvbnN0IHVwZGF0ZWRWYWx1ZTogTnVsbGFibGU8bnVtYmVyPiA9IGNoYW5nZT8uY3VycmVudFZhbHVlO1xuXG4gICAgaWYgKGlzTmlsKHVwZGF0ZWRWYWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tYXhMZW5ndGgkLm5leHQodXBkYXRlZFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc01heFJvd3NDaGFuZ2UoY2hhbmdlOiBDb21wb25lbnRDaGFuZ2U8dGhpcywgTnVsbGFibGU8bnVtYmVyPj4pOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWU6IE51bGxhYmxlPG51bWJlcj4gPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHVwZGF0ZWRWYWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm1heFJvd3MkLm5leHQodXBkYXRlZFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc01pblJvd3NDaGFuZ2UoY2hhbmdlOiBDb21wb25lbnRDaGFuZ2U8dGhpcywgTnVsbGFibGU8bnVtYmVyPj4pOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWU6IE51bGxhYmxlPG51bWJlcj4gPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHVwZGF0ZWRWYWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm1pblJvd3MkLm5leHQodXBkYXRlZFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc0NvdW50ZXJWaXNpYmlsaXR5Q2hhbmdlKGNoYW5nZTogQ29tcG9uZW50Q2hhbmdlPHRoaXMsIFRleHRhcmVhQ291bnRlclZpc2liaWxpdHk+KTogdm9pZCB7XG4gICAgY29uc3QgdXBkYXRlZFZhbHVlOiBUZXh0YXJlYUNvdW50ZXJWaXNpYmlsaXR5ID0gY2hhbmdlPy5jdXJyZW50VmFsdWU7XG5cbiAgICBpZiAoaXNOaWwodXBkYXRlZFZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY291bnRlclZpc2liaWxpdHkkLm5leHQodXBkYXRlZFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc0VudGVyS2V5RGlzYWJsZWRDaGFuZ2UoY2hhbmdlOiBDb21wb25lbnRDaGFuZ2U8dGhpcywgYm9vbGVhbj4pOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWU6IGJvb2xlYW4gPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5lbnRlcktleVByZXZlbnRlZCQubmV4dCh1cGRhdGVkVmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0SGVpZ2h0UHhCeVJvd3NDb3VudChcbiAgICBsaW5lSGVpZ2h0U291cmNlUmVmOiBFbGVtZW50UmVmPEhUTUxUZXh0QXJlYUVsZW1lbnQ+LFxuICAgIHJvd3NDb3VudDogbnVtYmVyLFxuICAgIHNpemU6IFRleHRhcmVhU2l6ZVxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IHZlcnRpY2FsUGFkZGluZ3NQeDogbnVtYmVyID1cbiAgICAgIHNpemUgPT09ICdsYXJnZScgPyBMQVJHRV9URVhUQVJFQV9WRVJUSUNBTF9QQURESU5HU19QWCA6IE1FRElVTV9URVhUQVJFQV9WRVJUSUNBTF9QQURESU5HU19QWDtcblxuICAgIGNvbnN0IGNvbXB1dGVkU3R5bGVzOiBDU1NTdHlsZURlY2xhcmF0aW9uID0gZ2V0Q29tcHV0ZWRTdHlsZShsaW5lSGVpZ2h0U291cmNlUmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgIGNvbnN0IGxpbmVIZWlnaHRQeDogbnVtYmVyID0gTnVtYmVyLnBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZXMubGluZUhlaWdodCk7XG5cbiAgICByZXR1cm4gbGluZUhlaWdodFB4ICogcm93c0NvdW50ICsgdmVydGljYWxQYWRkaW5nc1B4O1xuICB9XG59XG4iXX0=