UNPKG

@asoftwareworld/form-builder-pro

Version:

ASW Form Builder Pro helps you with rapid development and designed web forms which includes several controls. The key feature of Form Builder is to make your content attractive and effective. We can customize our control at run time and preview the same b

206 lines 34.7 kB
/** * @license * Copyright ASW (A Software World) All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file */ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CSSFrameworkEnum } from '@asoftwareworld/form-builder-pro/api'; import { Constants, Icons } from '@asoftwareworld/form-builder-pro/common'; import { AswConfirmDialog } from '@asoftwareworld/form-builder-pro/form-control/confirm-dialog'; import { AswSingleSelectDialog } from '@asoftwareworld/form-builder-pro/form-control/shared'; import * as i0 from "@angular/core"; import * as i1 from "@angular/material/dialog"; import * as i2 from "@asoftwareworld/form-builder-pro/common"; import * as i3 from "@angular/common"; import * as i4 from "@angular/forms"; import * as i5 from "@angular/material/button"; import * as i6 from "@angular/material/radio"; import * as i7 from "@angular/material/tooltip"; import * as i8 from "@asoftwareworld/form-builder-pro/core"; export class AswRadioButton { dialog; aswApiService; constants = Constants; icons = Icons; /** * RadioButton control */ control; propertyPersonalization = []; isPreviewTemplate = false; CSSFramework = CSSFrameworkEnum.Material; formControls = []; radioButtonUpdateEvent = new EventEmitter(); radioButtonDeleteEvent = new EventEmitter(); selectionChange = new EventEmitter(); duplicateControl = new EventEmitter(); constructor(dialog, aswApiService) { this.dialog = dialog; this.aswApiService = aswApiService; } ngOnInit() { if (this.control?.apiUrl) { this.callApiToFetchData(this.control); } } callApiToFetchData(control) { switch (control.method) { case 'GET': { this.aswApiService.get(control.apiUrl, control.headers).subscribe({ next: (data) => { if (data?.value) { this.control.options = data.value; } else { this.control.options = data; } } }); break; } case 'POST': { this.aswApiService.post(control.apiUrl, control.body, control.headers).subscribe({ next: (data) => { if (data?.value) { this.control.options = data.value; } else { this.control.options = data; } } }); break; } case 'PUT': { this.aswApiService.put(control.apiUrl, control.body, control.headers).subscribe({ next: (data) => { if (data?.value) { this.control.options = data.value; } else { this.control.options = data; } } }); break; } case 'PATCH': { this.aswApiService.patch(control.apiUrl, control.body, control.headers).subscribe({ next: (data) => { if (data?.value) { this.control.options = data.value; } else { this.control.options = data; } } }); break; } case 'DELETE': { this.aswApiService.delete(control.apiUrl, control.headers).subscribe({ next: (data) => { if (data?.value) { this.control.options = data.value; } else { this.control.options = data; } } }); break; } } } deleteRadioButtonDialog(control) { const dialogRef = this.dialog.open(AswConfirmDialog, { width: '350px', data: { name: control.controlType, message: this.constants.messages.waringMessage } }); dialogRef.afterClosed().subscribe((result) => { if (result !== undefined) { this.radioButtonDeleteEvent.emit(control); } }); } editRadioButtonDialog(control, formControls) { let allControls = []; this.getAllExceptCurrentControl(formControls, allControls); allControls = [...new Set(allControls.map((numberControl) => numberControl))]; control.options.forEach((element) => { element.isChecked = control.value === element.key ? true : false; if (!element.hideControl) { element.hideControl = []; } }); const dialogRef = this.dialog.open(AswSingleSelectDialog, { width: '80%', minWidth: '70vw', disableClose: true, data: { control, CSSFramework: this.CSSFramework, propertyPersonalization: this.propertyPersonalization, allControls } }); dialogRef.afterClosed().subscribe((result) => { if (result !== undefined) { this.radioButtonUpdateEvent.emit(result); } }); } onSelectionChange(control) { control.options.forEach((element) => { element.isChecked = control.value === element.key ? true : false; }); this.selectionChange.emit(control); } duplicateRadioButtonControl(control) { this.duplicateControl.emit(control); } getAllExceptCurrentControl(formControls, allControls) { //allControls.push(...formControls.filter((x) => x.id !== this.control.id)); const columnsControls = formControls.filter((x) => x.controlType === 'columns'); if (columnsControls.length) { columnsControls.forEach((control) => { let isSelectedControl = false; control.columns.forEach((column) => { column.components.forEach((component) => { if (component.controlType === 'columns') { this.getAllExceptCurrentControl(column.components, allControls); } if (component.id === this.control.id) { isSelectedControl = true; } }); }); if (!isSelectedControl) { allControls.push(control); } }); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AswRadioButton, deps: [{ token: i1.MatDialog }, { token: i2.AswApiService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: AswRadioButton, selector: "asw-radio-button", inputs: { control: "control", propertyPersonalization: "propertyPersonalization", isPreviewTemplate: "isPreviewTemplate", CSSFramework: "CSSFramework", formControls: "formControls" }, outputs: { radioButtonUpdateEvent: "radioButtonUpdateEvent", radioButtonDeleteEvent: "radioButtonDeleteEvent", selectionChange: "selectionChange", duplicateControl: "duplicateControl" }, ngImport: i0, template: "<ng-container *ngIf=\"control as control\">\r\n <label id=\"example-radio-group-label\" [innerHTML]=\"(control.label | aswTranslate) | aswSafeHtml\"></label>\r\n <mat-radio-group class=\"asw-radio-group {{control.customClass}}\"\r\n color=\"primary\"\r\n [id]=\"control.id\"\r\n [matTooltip]=\"control.tooltip | aswTranslate\"\r\n [(ngModel)]=\"control.value\"\r\n (change)=\"onSelectionChange(control)\"\r\n [disabled]=\"control.isDisabled ? true : false\">\r\n <mat-radio-button\r\n *ngFor=\"let option of control.options\" \r\n [value]=\"option.key\">\r\n {{ option.value }}\r\n </mat-radio-button>\r\n </mat-radio-group>\r\n <div class=\"asw-row\" *ngIf=\"isPreviewTemplate\">\r\n <div class=\"asw-col-md-12\" align=\"right\">\r\n <button mat-icon-button \r\n type=\"button\" \r\n matTooltip=\"{{'FormControl.Duplicate' | aswTranslate}}\" \r\n [matTooltipPosition]=\"'below'\" \r\n (click)=\"duplicateRadioButtonControl(control)\">\r\n <div [innerHTML]=\"icons.contentCopy | aswSafeHtml\"></div>\r\n </button>\r\n <button mat-icon-button \r\n type=\"button\" \r\n matTooltip=\"{{'FormControl.Edit' | aswTranslate}}\" \r\n [matTooltipPosition]=\"'below'\" \r\n (click)=\"editRadioButtonDialog(control, formControls)\">\r\n <div [innerHTML]=\"icons.edit | aswSafeHtml\"></div>\r\n </button>\r\n <button mat-icon-button \r\n type=\"button\" \r\n matTooltip=\"{{'FormControl.Delete' | aswTranslate}}\" \r\n [matTooltipPosition]=\"'below'\" \r\n (click)=\"deleteRadioButtonDialog(control)\">\r\n <div [innerHTML]=\"icons.delete2 | aswSafeHtml\"></div>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i6.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i6.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i2.AswSafeHtmlPipe, name: "aswSafeHtml" }, { kind: "pipe", type: i8.AswTranslatePipe, name: "aswTranslate" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AswRadioButton, decorators: [{ type: Component, args: [{ selector: 'asw-radio-button', template: "<ng-container *ngIf=\"control as control\">\r\n <label id=\"example-radio-group-label\" [innerHTML]=\"(control.label | aswTranslate) | aswSafeHtml\"></label>\r\n <mat-radio-group class=\"asw-radio-group {{control.customClass}}\"\r\n color=\"primary\"\r\n [id]=\"control.id\"\r\n [matTooltip]=\"control.tooltip | aswTranslate\"\r\n [(ngModel)]=\"control.value\"\r\n (change)=\"onSelectionChange(control)\"\r\n [disabled]=\"control.isDisabled ? true : false\">\r\n <mat-radio-button\r\n *ngFor=\"let option of control.options\" \r\n [value]=\"option.key\">\r\n {{ option.value }}\r\n </mat-radio-button>\r\n </mat-radio-group>\r\n <div class=\"asw-row\" *ngIf=\"isPreviewTemplate\">\r\n <div class=\"asw-col-md-12\" align=\"right\">\r\n <button mat-icon-button \r\n type=\"button\" \r\n matTooltip=\"{{'FormControl.Duplicate' | aswTranslate}}\" \r\n [matTooltipPosition]=\"'below'\" \r\n (click)=\"duplicateRadioButtonControl(control)\">\r\n <div [innerHTML]=\"icons.contentCopy | aswSafeHtml\"></div>\r\n </button>\r\n <button mat-icon-button \r\n type=\"button\" \r\n matTooltip=\"{{'FormControl.Edit' | aswTranslate}}\" \r\n [matTooltipPosition]=\"'below'\" \r\n (click)=\"editRadioButtonDialog(control, formControls)\">\r\n <div [innerHTML]=\"icons.edit | aswSafeHtml\"></div>\r\n </button>\r\n <button mat-icon-button \r\n type=\"button\" \r\n matTooltip=\"{{'FormControl.Delete' | aswTranslate}}\" \r\n [matTooltipPosition]=\"'below'\" \r\n (click)=\"deleteRadioButtonDialog(control)\">\r\n <div [innerHTML]=\"icons.delete2 | aswSafeHtml\"></div>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-container>\r\n" }] }], ctorParameters: () => [{ type: i1.MatDialog }, { type: i2.AswApiService }], propDecorators: { control: [{ type: Input }], propertyPersonalization: [{ type: Input }], isPreviewTemplate: [{ type: Input }], CSSFramework: [{ type: Input }], formControls: [{ type: Input }], radioButtonUpdateEvent: [{ type: Output }], radioButtonDeleteEvent: [{ type: Output }], selectionChange: [{ type: Output }], duplicateControl: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaW8tYnV0dG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvZm9ybS1jb250cm9sL3JhZGlvLWJ1dHRvbi9yYWRpby1idXR0b24udHMiLCIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9mb3JtLWNvbnRyb2wvcmFkaW8tYnV0dG9uL3JhZGlvLWJ1dHRvbi5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDeEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWlCLE1BQU0seUNBQXlDLENBQUM7QUFDMUYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sOERBQThELENBQUM7QUFDaEcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0RBQXNELENBQUM7Ozs7Ozs7Ozs7QUFPN0YsTUFBTSxPQUFPLGNBQWM7SUFrQlo7SUFDQztJQWxCWixTQUFTLEdBQVEsU0FBUyxDQUFDO0lBQzNCLEtBQUssR0FBRyxLQUFLLENBQUM7SUFDZDs7T0FFRztJQUNNLE9BQU8sQ0FBTTtJQUNiLHVCQUF1QixHQUFhLEVBQUUsQ0FBQztJQUN2QyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7SUFDMUIsWUFBWSxHQUFxQixnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7SUFDM0QsWUFBWSxHQUFVLEVBQUUsQ0FBQztJQUV4QixzQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFBc0IsQ0FBQztJQUNoRSxzQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFBc0IsQ0FBQztJQUNoRSxlQUFlLEdBQUcsSUFBSSxZQUFZLEVBQXNCLENBQUM7SUFDekQsZ0JBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQXNCLENBQUM7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QyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUM7NEJBQ25DLGlCQUFpQixHQUFHLElBQUksQ0FBQzt3QkFDN0IsQ0FBQztvQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFDUCxDQUFDLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztvQkFDckIsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDOUIsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztJQUNMLENBQUM7dUdBaEtRLGNBQWM7MkZBQWQsY0FBYywyYUNwQjNCLG9oRUF5Q0E7OzJGRHJCYSxjQUFjO2tCQUoxQixTQUFTOytCQUNJLGtCQUFrQjswR0FTbkIsT0FBTztzQkFBZixLQUFLO2dCQUNHLHVCQUF1QjtzQkFBL0IsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUVJLHNCQUFzQjtzQkFBL0IsTUFBTTtnQkFDRyxzQkFBc0I7c0JBQS9CLE1BQU07Z0JBQ0csZUFBZTtzQkFBeEIsTUFBTTtnQkFDRyxnQkFBZ0I7c0JBQXpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQVNXIChBIFNvZnR3YXJlIFdvcmxkKSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlXG4gKi9cblxuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IENTU0ZyYW1ld29ya0VudW0gfSBmcm9tICdAYXNvZnR3YXJld29ybGQvZm9ybS1idWlsZGVyLXByby9hcGknO1xuaW1wb3J0IHsgQ29uc3RhbnRzLCBJY29ucywgQXN3QXBpU2VydmljZSB9IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9mb3JtLWJ1aWxkZXItcHJvL2NvbW1vbic7XG5pbXBvcnQgeyBBc3dDb25maXJtRGlhbG9nIH0gZnJvbSAnQGFzb2Z0d2FyZXdvcmxkL2Zvcm0tYnVpbGRlci1wcm8vZm9ybS1jb250cm9sL2NvbmZpcm0tZGlhbG9nJztcbmltcG9ydCB7IEFzd1NpbmdsZVNlbGVjdERpYWxvZyB9IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9mb3JtLWJ1aWxkZXItcHJvL2Zvcm0tY29udHJvbC9zaGFyZWQnO1xuaW1wb3J0IHsgUmFkaW9CdXR0b25Db250cm9sIH0gZnJvbSAnLi9yYWRpby1idXR0b24tY29udHJvbCc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYXN3LXJhZGlvLWJ1dHRvbicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3JhZGlvLWJ1dHRvbi5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBBc3dSYWRpb0J1dHRvbiBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgY29uc3RhbnRzOiBhbnkgPSBDb25zdGFudHM7XG4gICAgaWNvbnMgPSBJY29ucztcbiAgICAvKipcbiAgICAgKiBSYWRpb0J1dHRvbiBjb250cm9sXG4gICAgICovXG4gICAgQElucHV0KCkgY29udHJvbDogYW55O1xuICAgIEBJbnB1dCgpIHByb3BlcnR5UGVyc29uYWxpemF0aW9uOiBzdHJpbmdbXSA9IFtdO1xuICAgIEBJbnB1dCgpIGlzUHJldmlld1RlbXBsYXRlID0gZmFsc2U7XG4gICAgQElucHV0KCkgQ1NTRnJhbWV3b3JrOiBDU1NGcmFtZXdvcmtFbnVtID0gQ1NTRnJhbWV3b3JrRW51bS5NYXRlcmlhbDtcbiAgICBASW5wdXQoKSBmb3JtQ29udHJvbHM6IGFueVtdID0gW107XG5cbiAgICBAT3V0cHV0KCkgcmFkaW9CdXR0b25VcGRhdGVFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8UmFkaW9CdXR0b25Db250cm9sPigpO1xuICAgIEBPdXRwdXQoKSByYWRpb0J1dHRvbkRlbGV0ZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxSYWRpb0J1dHRvbkNvbnRyb2w+KCk7XG4gICAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8UmFkaW9CdXR0b25Db250cm9sPigpO1xuICAgIEBPdXRwdXQoKSBkdXBsaWNhdGVDb250cm9sID0gbmV3IEV2ZW50RW1pdHRlcjxSYWRpb0J1dHRvbkNvbnRyb2w+KCk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHVibGljIGRpYWxvZzogTWF0RGlhbG9nLFxuICAgICAgICBwcml2YXRlIGFzd0FwaVNlcnZpY2U6IEFzd0FwaVNlcnZpY2VcbiAgICApIHt9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY29udHJvbD8uYXBpVXJsKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxBcGlUb0ZldGNoRGF0YSh0aGlzLmNvbnRyb2wpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYWxsQXBpVG9GZXRjaERhdGEoY29udHJvbDogYW55KSB7XG4gICAgICAgIHN3aXRjaCAoY29udHJvbC5tZXRob2QpIHtcbiAgICAgICAgICAgIGNhc2UgJ0dFVCc6IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzd0FwaVNlcnZpY2UuZ2V0KGNvbnRyb2wuYXBpVXJsLCBjb250cm9sLmhlYWRlcnMpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YT8udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2wub3B0aW9ucyA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbC5vcHRpb25zID0gZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnUE9TVCc6IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzd0FwaVNlcnZpY2UucG9zdChjb250cm9sLmFwaVVybCwgY29udHJvbC5ib2R5LCBjb250cm9sLmhlYWRlcnMpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YT8udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2wub3B0aW9ucyA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbC5vcHRpb25zID0gZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnUFVUJzoge1xuICAgICAgICAgICAgICAgIHRoaXMuYXN3QXBpU2VydmljZS5wdXQoY29udHJvbC5hcGlVcmwsIGNvbnRyb2wuYm9keSwgY29udHJvbC5oZWFkZXJzKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGE/LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250cm9sLm9wdGlvbnMgPSBkYXRhLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2wub3B0aW9ucyA9IGRhdGE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgJ1BBVENIJzoge1xuICAgICAgICAgICAgICAgIHRoaXMuYXN3QXBpU2VydmljZS5wYXRjaChjb250cm9sLmFwaVVybCwgY29udHJvbC5ib2R5LCBjb250cm9sLmhlYWRlcnMpLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YT8udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2wub3B0aW9ucyA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbC5vcHRpb25zID0gZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnREVMRVRFJzoge1xuICAgICAgICAgICAgICAgIHRoaXMuYXN3QXBpU2VydmljZS5kZWxldGUoY29udHJvbC5hcGlVcmwsIGNvbnRyb2wuaGVhZGVycykuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dDogKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhPy52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbC5vcHRpb25zID0gZGF0YS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250cm9sLm9wdGlvbnMgPSBkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZWxldGVSYWRpb0J1dHRvbkRpYWxvZyhjb250cm9sOiBSYWRpb0J1dHRvbkNvbnRyb2wpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihBc3dDb25maXJtRGlhbG9nLCB7XG4gICAgICAgICAgICB3aWR0aDogJzM1MHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHsgbmFtZTogY29udHJvbC5jb250cm9sVHlwZSwgbWVzc2FnZTogdGhpcy5jb25zdGFudHMubWVzc2FnZXMud2FyaW5nTWVzc2FnZSB9XG4gICAgICAgIH0pO1xuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yYWRpb0J1dHRvbkRlbGV0ZUV2ZW50LmVtaXQoY29udHJvbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGVkaXRSYWRpb0J1dHRvbkRpYWxvZyhjb250cm9sOiBSYWRpb0J1dHRvbkNvbnRyb2wsIGZvcm1Db250cm9sczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgbGV0IGFsbENvbnRyb2xzOiBhbnlbXSA9IFtdO1xuICAgICAgICB0aGlzLmdldEFsbEV4Y2VwdEN1cnJlbnRDb250cm9sKGZvcm1Db250cm9scywgYWxsQ29udHJvbHMpO1xuICAgICAgICBhbGxDb250cm9scyA9IFsuLi5uZXcgU2V0KGFsbENvbnRyb2xzLm1hcCgobnVtYmVyQ29udHJvbCkgPT4gbnVtYmVyQ29udHJvbCkpXTtcbiAgICAgICAgY29udHJvbC5vcHRpb25zLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIGVsZW1lbnQuaXNDaGVja2VkID0gY29udHJvbC52YWx1ZSA9PT0gZWxlbWVudC5rZXkgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgICAgICBpZiAoIWVsZW1lbnQuaGlkZUNvbnRyb2wpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmhpZGVDb250cm9sID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEFzd1NpbmdsZVNlbGVjdERpYWxvZywge1xuICAgICAgICAgICAgd2lkdGg6ICc4MCUnLFxuICAgICAgICAgICAgbWluV2lkdGg6ICc3MHZ3JyxcbiAgICAgICAgICAgIGRpc2FibGVDbG9zZTogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IHsgY29udHJvbCwgQ1NTRnJhbWV3b3JrOiB0aGlzLkNTU0ZyYW1ld29yaywgcHJvcGVydHlQZXJzb25hbGl6YXRpb246IHRoaXMucHJvcGVydHlQZXJzb25hbGl6YXRpb24sIGFsbENvbnRyb2xzIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJhZGlvQnV0dG9uVXBkYXRlRXZlbnQuZW1pdChyZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvblNlbGVjdGlvbkNoYW5nZShjb250cm9sOiBSYWRpb0J1dHRvbkNvbnRyb2wpOiB2b2lkIHtcbiAgICAgICAgY29udHJvbC5vcHRpb25zLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIGVsZW1lbnQuaXNDaGVja2VkID0gY29udHJvbC52YWx1ZSA9PT0gZWxlbWVudC5rZXkgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KGNvbnRyb2wpO1xuICAgIH1cblxuICAgIGR1cGxpY2F0ZVJhZGlvQnV0dG9uQ29udHJvbChjb250cm9sOiBSYWRpb0J1dHRvbkNvbnRyb2wpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kdXBsaWNhdGVDb250cm9sLmVtaXQoY29udHJvbCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRBbGxFeGNlcHRDdXJyZW50Q29udHJvbChmb3JtQ29udHJvbHM6IGFueVtdLCBhbGxDb250cm9sczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgLy9hbGxDb250cm9scy5wdXNoKC4uLmZvcm1Db250cm9scy5maWx0ZXIoKHgpID0+IHguaWQgIT09IHRoaXMuY29udHJvbC5pZCkpO1xuICAgICAgICBjb25zdCBjb2x1bW5zQ29udHJvbHMgPSBmb3JtQ29udHJvbHMuZmlsdGVyKCh4KSA9PiB4LmNvbnRyb2xUeXBlID09PSAnY29sdW1ucycpO1xuICAgICAgICBpZiAoY29sdW1uc0NvbnRyb2xzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29sdW1uc0NvbnRyb2xzLmZvckVhY2goKGNvbnRyb2wpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgaXNTZWxlY3RlZENvbnRyb2wgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb250cm9sLmNvbHVtbnMuZm9yRWFjaCgoY29sdW1uOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uLmNvbXBvbmVudHMuZm9yRWFjaCgoY29tcG9uZW50OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQuY29udHJvbFR5cGUgPT09ICdjb2x1bW5zJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0QWxsRXhjZXB0Q3VycmVudENvbnRyb2woY29sdW1uLmNvbXBvbmVudHMsIGFsbENvbnRyb2xzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQuaWQgPT09IHRoaXMuY29udHJvbC5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2VsZWN0ZWRDb250cm9sID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc1NlbGVjdGVkQ29udHJvbCkge1xuICAgICAgICAgICAgICAgICAgICBhbGxDb250cm9scy5wdXNoKGNvbnRyb2wpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRyb2wgYXMgY29udHJvbFwiPlxyXG4gICAgPGxhYmVsIGlkPVwiZXhhbXBsZS1yYWRpby1ncm91cC1sYWJlbFwiIFtpbm5lckhUTUxdPVwiKGNvbnRyb2wubGFiZWwgfCBhc3dUcmFuc2xhdGUpIHwgYXN3U2FmZUh0bWxcIj48L2xhYmVsPlxyXG4gICAgPG1hdC1yYWRpby1ncm91cCBjbGFzcz1cImFzdy1yYWRpby1ncm91cCB7e2NvbnRyb2wuY3VzdG9tQ2xhc3N9fVwiXHJcbiAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICBbaWRdPVwiY29udHJvbC5pZFwiXHJcbiAgICAgICAgW21hdFRvb2x0aXBdPVwiY29udHJvbC50b29sdGlwIHwgYXN3VHJhbnNsYXRlXCJcclxuICAgICAgICBbKG5nTW9kZWwpXT1cImNvbnRyb2wudmFsdWVcIlxyXG4gICAgICAgIChjaGFuZ2UpPVwib25TZWxlY3Rpb25DaGFuZ2UoY29udHJvbClcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCJjb250cm9sLmlzRGlzYWJsZWQgPyB0cnVlIDogZmFsc2VcIj5cclxuICAgICAgICA8bWF0LXJhZGlvLWJ1dHRvblxyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGNvbnRyb2wub3B0aW9uc1wiIFxyXG4gICAgICAgICAgICBbdmFsdWVdPVwib3B0aW9uLmtleVwiPlxyXG4gICAgICAgICAgICB7eyBvcHRpb24udmFsdWUgfX1cclxuICAgICAgICA8L21hdC1yYWRpby1idXR0b24+XHJcbiAgICA8L21hdC1yYWRpby1ncm91cD5cclxuICAgIDxkaXYgY2xhc3M9XCJhc3ctcm93XCIgKm5nSWY9XCJpc1ByZXZpZXdUZW1wbGF0ZVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJhc3ctY29sLW1kLTEyXCIgYWxpZ249XCJyaWdodFwiPlxyXG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBcclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cInt7J0Zvcm1Db250cm9sLkR1cGxpY2F0ZScgfCBhc3dUcmFuc2xhdGV9fVwiIFxyXG4gICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwUG9zaXRpb25dPVwiJ2JlbG93J1wiIFxyXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkdXBsaWNhdGVSYWRpb0J1dHRvbkNvbnRyb2woY29udHJvbClcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgW2lubmVySFRNTF09XCJpY29ucy5jb250ZW50Q29weSB8IGFzd1NhZmVIdG1sXCI+PC9kaXY+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBcclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cInt7J0Zvcm1Db250cm9sLkVkaXQnIHwgYXN3VHJhbnNsYXRlfX1cIiBcclxuICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcFBvc2l0aW9uXT1cIidiZWxvdydcIiBcclxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZWRpdFJhZGlvQnV0dG9uRGlhbG9nKGNvbnRyb2wsIGZvcm1Db250cm9scylcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgW2lubmVySFRNTF09XCJpY29ucy5lZGl0IHwgYXN3U2FmZUh0bWxcIj48L2Rpdj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBcclxuICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwie3snRm9ybUNvbnRyb2wuRGVsZXRlJyB8IGFzd1RyYW5zbGF0ZX19XCIgXHJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBQb3NpdGlvbl09XCInYmVsb3cnXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZVJhZGlvQnV0dG9uRGlhbG9nKGNvbnRyb2wpXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IFtpbm5lckhUTUxdPVwiaWNvbnMuZGVsZXRlMiB8IGFzd1NhZmVIdG1sXCI+PC9kaXY+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvbmctY29udGFpbmVyPlxyXG4iXX0=