UNPKG

@jsonforms/angular-material

Version:

Material Renderer Set for Angular module of JSON Forms

171 lines (167 loc) 19 kB
/* The MIT License Copyright (c) 2017-2019 EclipseSource Munich https://github.com/eclipsesource/jsonforms Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { ChangeDetectionStrategy, Component, Input, } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { Actions, composeWithUi, isEnumControl, rankWith, } from '@jsonforms/core'; import { map, startWith } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@jsonforms/angular"; import * as i2 from "@angular/common"; import * as i3 from "@angular/material/form-field"; import * as i4 from "@angular/material/input"; import * as i5 from "@angular/forms"; import * as i6 from "@angular/material/core"; import * as i7 from "@angular/material/autocomplete"; /** * To use this component you will need to add your own tester: * <pre><code> * ... * export const AutocompleteControlRendererTester: RankedTester = rankWith(2, isEnumControl); * ... * </code></pre> * Add the tester and renderer to JSONForms registry: * <pre><code> * ... * { tester: AutocompleteControlRendererTester, renderer: AutocompleteControlRenderer }, * ... * </code></pre> * Furthermore you need to update your module. * <pre><code> * ... * imports: [JsonFormsAngularMaterialModule, MatAutocompleteModule], * declarations: [AutocompleteControlRenderer] * ... * </code></pre> * */ export class AutocompleteControlRenderer extends JsonFormsControl { options; filteredOptions; shouldFilter; focused = false; constructor(jsonformsService) { super(jsonformsService); } getEventValue = (event) => event.target.value; ngOnInit() { super.ngOnInit(); this.shouldFilter = false; this.filteredOptions = this.form.valueChanges.pipe(startWith(''), map((val) => this.filter(val))); } updateFilter(event) { // ENTER if (event.keyCode === 13) { this.shouldFilter = false; } else { this.shouldFilter = true; } } onSelect(ev) { const path = composeWithUi(this.uischema, this.path); this.shouldFilter = false; this.jsonFormsService.updateCore(Actions.update(path, () => ev.option.value)); this.triggerValidation(); } filter(val) { return (this.options || this.scopedSchema.enum || []).filter((option) => !this.shouldFilter || !val || option.toLowerCase().indexOf(val.toLowerCase()) === 0); } getOwnProps() { return { ...super.getOwnProps(), options: this.options, }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AutocompleteControlRenderer, deps: [{ token: i1.JsonFormsAngularService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.10", type: AutocompleteControlRenderer, selector: "AutocompleteControlRenderer", inputs: { options: "options" }, usesInheritance: true, ngImport: i0, template: ` <mat-form-field [ngStyle]="{ display: hidden ? 'none' : '' }"> <mat-label>{{ label }}</mat-label> <input matInput type="text" (change)="onChange($event)" [id]="id" [formControl]="form" [matAutocomplete]="auto" (keydown)="updateFilter($event)" (focus)="focused = true" (focusout)="focused = false" /> <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="onSelect($event)" > <mat-option *ngFor="let option of filteredOptions | async" [value]="option" > {{ option }} </mat-option> </mat-autocomplete> <mat-hint *ngIf="shouldShowUnfocusedDescription() || focused">{{ description }}</mat-hint> <mat-error>{{ error }}</mat-error> </mat-form-field> `, isInline: true, styles: [":host{display:flex;flex-direction:row}mat-form-field{flex:1 1 auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i7.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i7.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AutocompleteControlRenderer, decorators: [{ type: Component, args: [{ selector: 'AutocompleteControlRenderer', template: ` <mat-form-field [ngStyle]="{ display: hidden ? 'none' : '' }"> <mat-label>{{ label }}</mat-label> <input matInput type="text" (change)="onChange($event)" [id]="id" [formControl]="form" [matAutocomplete]="auto" (keydown)="updateFilter($event)" (focus)="focused = true" (focusout)="focused = false" /> <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="onSelect($event)" > <mat-option *ngFor="let option of filteredOptions | async" [value]="option" > {{ option }} </mat-option> </mat-autocomplete> <mat-hint *ngIf="shouldShowUnfocusedDescription() || focused">{{ description }}</mat-hint> <mat-error>{{ error }}</mat-error> </mat-form-field> `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;flex-direction:row}mat-form-field{flex:1 1 auto}\n"] }] }], ctorParameters: () => [{ type: i1.JsonFormsAngularService }], propDecorators: { options: [{ type: Input }] } }); export const enumControlTester = rankWith(2, isEnumControl); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0b2NvbXBsZXRlLnJlbmRlcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYnJhcnkvY29udHJvbHMvYXV0b2NvbXBsZXRlLnJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQXVCRTtBQUNGLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULEtBQUssR0FFTixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvRSxPQUFPLEVBQ0wsT0FBTyxFQUNQLGFBQWEsRUFFYixhQUFhLEVBR2IsUUFBUSxHQUNULE1BQU0saUJBQWlCLENBQUM7QUFFekIsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7O0FBRWhEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFnREgsTUFBTSxPQUFPLDJCQUNYLFNBQVEsZ0JBQWdCO0lBR2YsT0FBTyxDQUFXO0lBQzNCLGVBQWUsQ0FBdUI7SUFDdEMsWUFBWSxDQUFVO0lBQ3RCLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsWUFBWSxnQkFBeUM7UUFDbkQsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUNELGFBQWEsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFFbkQsUUFBUTtRQUNOLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDaEQsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUNiLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUMvQixDQUFDO0lBQ0osQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFVO1FBQ3JCLFFBQVE7UUFDUixJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssRUFBRSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1NBQzNCO2FBQU07WUFDTCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztTQUMxQjtJQUNILENBQUM7SUFFRCxRQUFRLENBQUMsRUFBZ0M7UUFDdkMsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxRQUEwQixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUM5QixPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUM1QyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELE1BQU0sQ0FBQyxHQUFXO1FBQ2hCLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FDMUQsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUNULENBQUMsSUFBSSxDQUFDLFlBQVk7WUFDbEIsQ0FBQyxHQUFHO1lBQ0osTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQ3hELENBQUM7SUFDSixDQUFDO0lBQ1MsV0FBVztRQUNuQixPQUFPO1lBQ0wsR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFO1lBQ3RCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN0QixDQUFDO0lBQ0osQ0FBQzt3R0F0RFUsMkJBQTJCOzRGQUEzQiwyQkFBMkIsMEhBN0M1Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCVDs7NEZBY1UsMkJBQTJCO2tCQS9DdkMsU0FBUzsrQkFDRSw2QkFBNkIsWUFDN0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQlQsbUJBWWdCLHVCQUF1QixDQUFDLE1BQU07NEZBTXRDLE9BQU87c0JBQWYsS0FBSzs7QUFxRFIsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQWlCLFFBQVEsQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBUaGUgTUlUIExpY2Vuc2VcbiAgXG4gIENvcHlyaWdodCAoYykgMjAxNy0yMDE5IEVjbGlwc2VTb3VyY2UgTXVuaWNoXG4gIGh0dHBzOi8vZ2l0aHViLmNvbS9lY2xpcHNlc291cmNlL2pzb25mb3Jtc1xuICBcbiAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAgXG4gIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICBcbiAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICBUSEUgU09GVFdBUkUuXG4qL1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgdHlwZSB7IE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9hdXRvY29tcGxldGUnO1xuaW1wb3J0IHsgSnNvbkZvcm1zQW5ndWxhclNlcnZpY2UsIEpzb25Gb3Jtc0NvbnRyb2wgfSBmcm9tICdAanNvbmZvcm1zL2FuZ3VsYXInO1xuaW1wb3J0IHtcbiAgQWN0aW9ucyxcbiAgY29tcG9zZVdpdGhVaSxcbiAgQ29udHJvbEVsZW1lbnQsXG4gIGlzRW51bUNvbnRyb2wsXG4gIE93blByb3BzT2ZDb250cm9sLFxuICBSYW5rZWRUZXN0ZXIsXG4gIHJhbmtXaXRoLFxufSBmcm9tICdAanNvbmZvcm1zL2NvcmUnO1xuaW1wb3J0IHR5cGUgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIHN0YXJ0V2l0aCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuLyoqXG4gKiBUbyB1c2UgdGhpcyBjb21wb25lbnQgeW91IHdpbGwgbmVlZCB0byBhZGQgeW91ciBvd24gdGVzdGVyOlxuICogPHByZT48Y29kZT5cbiAqIC4uLlxuICogZXhwb3J0IGNvbnN0IEF1dG9jb21wbGV0ZUNvbnRyb2xSZW5kZXJlclRlc3RlcjogUmFua2VkVGVzdGVyID0gcmFua1dpdGgoMiwgaXNFbnVtQ29udHJvbCk7XG4gKiAuLi5cbiAqIDwvY29kZT48L3ByZT5cbiAqIEFkZCB0aGUgdGVzdGVyIGFuZCByZW5kZXJlciB0byBKU09ORm9ybXMgcmVnaXN0cnk6XG4gKiA8cHJlPjxjb2RlPlxuICogLi4uXG4gKiB7IHRlc3RlcjogQXV0b2NvbXBsZXRlQ29udHJvbFJlbmRlcmVyVGVzdGVyLCByZW5kZXJlcjogQXV0b2NvbXBsZXRlQ29udHJvbFJlbmRlcmVyIH0sXG4gKiAuLi5cbiAqIDwvY29kZT48L3ByZT5cbiAqIEZ1cnRoZXJtb3JlIHlvdSBuZWVkIHRvIHVwZGF0ZSB5b3VyIG1vZHVsZS5cbiAqIDxwcmU+PGNvZGU+XG4gKiAuLi5cbiAqIGltcG9ydHM6IFtKc29uRm9ybXNBbmd1bGFyTWF0ZXJpYWxNb2R1bGUsIE1hdEF1dG9jb21wbGV0ZU1vZHVsZV0sXG4gKiBkZWNsYXJhdGlvbnM6IFtBdXRvY29tcGxldGVDb250cm9sUmVuZGVyZXJdXG4gKiAuLi5cbiAqIDwvY29kZT48L3ByZT5cbiAqXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ0F1dG9jb21wbGV0ZUNvbnRyb2xSZW5kZXJlcicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPG1hdC1mb3JtLWZpZWxkIFtuZ1N0eWxlXT1cInsgZGlzcGxheTogaGlkZGVuID8gJ25vbmUnIDogJycgfVwiPlxuICAgICAgPG1hdC1sYWJlbD57eyBsYWJlbCB9fTwvbWF0LWxhYmVsPlxuICAgICAgPGlucHV0XG4gICAgICAgIG1hdElucHV0XG4gICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgW2lkXT1cImlkXCJcbiAgICAgICAgW2Zvcm1Db250cm9sXT1cImZvcm1cIlxuICAgICAgICBbbWF0QXV0b2NvbXBsZXRlXT1cImF1dG9cIlxuICAgICAgICAoa2V5ZG93bik9XCJ1cGRhdGVGaWx0ZXIoJGV2ZW50KVwiXG4gICAgICAgIChmb2N1cyk9XCJmb2N1c2VkID0gdHJ1ZVwiXG4gICAgICAgIChmb2N1c291dCk9XCJmb2N1c2VkID0gZmFsc2VcIlxuICAgICAgLz5cbiAgICAgIDxtYXQtYXV0b2NvbXBsZXRlXG4gICAgICAgIGF1dG9BY3RpdmVGaXJzdE9wdGlvblxuICAgICAgICAjYXV0bz1cIm1hdEF1dG9jb21wbGV0ZVwiXG4gICAgICAgIChvcHRpb25TZWxlY3RlZCk9XCJvblNlbGVjdCgkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgICAgPG1hdC1vcHRpb25cbiAgICAgICAgICAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpbHRlcmVkT3B0aW9ucyB8IGFzeW5jXCJcbiAgICAgICAgICBbdmFsdWVdPVwib3B0aW9uXCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7IG9wdGlvbiB9fVxuICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICA8L21hdC1hdXRvY29tcGxldGU+XG4gICAgICA8bWF0LWhpbnQgKm5nSWY9XCJzaG91bGRTaG93VW5mb2N1c2VkRGVzY3JpcHRpb24oKSB8fCBmb2N1c2VkXCI+e3tcbiAgICAgICAgZGVzY3JpcHRpb25cbiAgICAgIH19PC9tYXQtaGludD5cbiAgICAgIDxtYXQtZXJyb3I+e3sgZXJyb3IgfX08L21hdC1lcnJvcj5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuICBgLFxuICBzdHlsZXM6IFtcbiAgICBgXG4gICAgICA6aG9zdCB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICB9XG4gICAgICBtYXQtZm9ybS1maWVsZCB7XG4gICAgICAgIGZsZXg6IDEgMSBhdXRvO1xuICAgICAgfVxuICAgIGAsXG4gIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRvY29tcGxldGVDb250cm9sUmVuZGVyZXJcbiAgZXh0ZW5kcyBKc29uRm9ybXNDb250cm9sXG4gIGltcGxlbWVudHMgT25Jbml0XG57XG4gIEBJbnB1dCgpIG9wdGlvbnM6IHN0cmluZ1tdO1xuICBmaWx0ZXJlZE9wdGlvbnM6IE9ic2VydmFibGU8c3RyaW5nW10+O1xuICBzaG91bGRGaWx0ZXI6IGJvb2xlYW47XG4gIGZvY3VzZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihqc29uZm9ybXNTZXJ2aWNlOiBKc29uRm9ybXNBbmd1bGFyU2VydmljZSkge1xuICAgIHN1cGVyKGpzb25mb3Jtc1NlcnZpY2UpO1xuICB9XG4gIGdldEV2ZW50VmFsdWUgPSAoZXZlbnQ6IGFueSkgPT4gZXZlbnQudGFyZ2V0LnZhbHVlO1xuXG4gIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgdGhpcy5zaG91bGRGaWx0ZXIgPSBmYWxzZTtcbiAgICB0aGlzLmZpbHRlcmVkT3B0aW9ucyA9IHRoaXMuZm9ybS52YWx1ZUNoYW5nZXMucGlwZShcbiAgICAgIHN0YXJ0V2l0aCgnJyksXG4gICAgICBtYXAoKHZhbCkgPT4gdGhpcy5maWx0ZXIodmFsKSlcbiAgICApO1xuICB9XG5cbiAgdXBkYXRlRmlsdGVyKGV2ZW50OiBhbnkpIHtcbiAgICAvLyBFTlRFUlxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgICAgdGhpcy5zaG91bGRGaWx0ZXIgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zaG91bGRGaWx0ZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIG9uU2VsZWN0KGV2OiBNYXRBdXRvY29tcGxldGVTZWxlY3RlZEV2ZW50KSB7XG4gICAgY29uc3QgcGF0aCA9IGNvbXBvc2VXaXRoVWkodGhpcy51aXNjaGVtYSBhcyBDb250cm9sRWxlbWVudCwgdGhpcy5wYXRoKTtcbiAgICB0aGlzLnNob3VsZEZpbHRlciA9IGZhbHNlO1xuICAgIHRoaXMuanNvbkZvcm1zU2VydmljZS51cGRhdGVDb3JlKFxuICAgICAgQWN0aW9ucy51cGRhdGUocGF0aCwgKCkgPT4gZXYub3B0aW9uLnZhbHVlKVxuICAgICk7XG4gICAgdGhpcy50cmlnZ2VyVmFsaWRhdGlvbigpO1xuICB9XG5cbiAgZmlsdGVyKHZhbDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiAodGhpcy5vcHRpb25zIHx8IHRoaXMuc2NvcGVkU2NoZW1hLmVudW0gfHwgW10pLmZpbHRlcihcbiAgICAgIChvcHRpb24pID0+XG4gICAgICAgICF0aGlzLnNob3VsZEZpbHRlciB8fFxuICAgICAgICAhdmFsIHx8XG4gICAgICAgIG9wdGlvbi50b0xvd2VyQ2FzZSgpLmluZGV4T2YodmFsLnRvTG93ZXJDYXNlKCkpID09PSAwXG4gICAgKTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0T3duUHJvcHMoKTogT3duUHJvcHNPZkF1dG9Db21wbGV0ZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN1cGVyLmdldE93blByb3BzKCksXG4gICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZW51bUNvbnRyb2xUZXN0ZXI6IFJhbmtlZFRlc3RlciA9IHJhbmtXaXRoKDIsIGlzRW51bUNvbnRyb2wpO1xuXG5pbnRlcmZhY2UgT3duUHJvcHNPZkF1dG9Db21wbGV0ZSBleHRlbmRzIE93blByb3BzT2ZDb250cm9sIHtcbiAgb3B0aW9uczogc3RyaW5nW107XG59XG4iXX0=