UNPKG

ngx-obelisco-example

Version:

Componentes funcionales y reutilizables para Angular.

118 lines 24.6 kB
import { Component, EventEmitter, Input, Output, ViewChildren } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; import * as i2 from "@angular/common"; export class OTableComponent { constructor(renderer, sanitizer) { this.renderer = renderer; this.sanitizer = sanitizer; this.isValidateComponent = false; this.id = 'o-table'; this.columns = []; this.dataSource = []; this.isBordered = false; this.isStriped = false; this.isScrollable = false; this.customClasses = ''; this.dataSelectedChange = new EventEmitter(); this.inputCheckArr = []; this.dataSelected = []; } ngOnInit() { this.componentValidations(); } ngAfterViewInit() { this.checkboxRef.map((e) => { this.inputCheckArr.push(e.nativeElement); }); } componentValidations() { this.isValidateComponent = this.columns.length > 0 && this.dataSource.length > 0; if (!this.isValidateComponent) { throw new Error('The columns and dataSource must not be empty'); } this.columns.map((e) => { if (e.key === '' || e.value === '') { this.isValidateComponent = false; throw new Error('The columns must not have null values'); } }); this.columns.map((e) => (e.value = e.value.trim())); this.columns = this.columns.map((e) => { e.value = e.value.charAt(0).toUpperCase() + e.value.slice(1).toLowerCase(); return e; }); this.columns.map((e) => { if (e.value.match(/^[a-zA-ZáéíóúÁÉÍÓÚñÑ ]*$/) && e.key.match(/^[a-zA-Z ]*$/)) { this.isValidateComponent = true; return e; } else { this.isValidateComponent = false; throw new Error('The columns value must not contain numbers or symbols and the key must not contain numbers, symbols or accents'); } }); } sanitizeHTML(html) { return this.sanitizer.bypassSecurityTrustHtml(html); } onHeaderCheckboxChange(event) { const target = event.target; if (target) { const isChecked = target.checked; this.checkboxRef.toArray().forEach((checkbox) => { checkbox.nativeElement.checked = isChecked; }); if (isChecked) { this.dataSelected = [...this.dataSource]; } else { this.dataSelected = []; } this.dataSelectedChange.emit(this.dataSelected); } } onCheckboxChange(data, event) { if (event && event.target && typeof event.target.checked === 'boolean') { const isChecked = event.target.checked; if (isChecked) { this.dataSelected.push(data); } else { const index = this.dataSelected.findIndex((item) => item === data); if (index !== -1) { this.dataSelected.splice(index, 1); } } this.dataSelectedChange.emit(this.dataSelected); } } } OTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OTableComponent, deps: [{ token: i0.Renderer2 }, { token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); OTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: OTableComponent, selector: "o-table", inputs: { id: "id", columns: "columns", dataSource: "dataSource", isBordered: "isBordered", isStriped: "isStriped", isScrollable: "isScrollable", customClasses: "customClasses", checkbox: "checkbox" }, outputs: { dataSelectedChange: "dataSelectedChange" }, viewQueries: [{ propertyName: "checkboxRef", predicate: ["checkbox"], descendants: true }], ngImport: i0, template: "<div [ngClass]=\"{ 'responsive-scroll': isScrollable }\" [class]=\"customClasses\" tabindex=\"0\">\r\n <table\r\n *ngIf=\"isValidateComponent\"\r\n class=\"table\"\r\n [ngClass]=\"{ 'table-borderless': !isBordered, 'table-striped': isStriped }\"\r\n >\r\n <thead>\r\n <tr>\r\n <th scope=\"col\" *ngIf=\"checkbox?.isAllSelectable == true\" [ngClass]=\"checkbox.customClassesTh\">\r\n <div class=\"custom-control custom-checkbox\">\r\n <input\r\n class=\"custom-control-input\"\r\n type=\"checkbox\"\r\n id=\"{{ id }}-selectAllCheckbox\"\r\n name=\"{{ id }}-selectAllCheckbox\"\r\n value=\"\"\r\n (change)=\"onHeaderCheckboxChange($event)\"\r\n />\r\n <label\r\n [ngClass]=\"checkbox.customClassesLabel\"\r\n class=\"custom-control-label\"\r\n for=\"{{ id }}-selectAllCheckbox\"\r\n aria-label=\"Descripci\u00F3n para usuarios de lectores de pantalla\"\r\n >{{ checkbox.title }}</label\r\n >\r\n </div>\r\n </th>\r\n <th scope=\"col\" *ngIf=\"checkbox?.isAllSelectable == false\" [ngClass]=\"checkbox.customClassesTh\">\r\n {{ checkbox.title }}\r\n </th>\r\n <ng-container *ngFor=\"let column of columns\">\r\n <th scope=\"col\" [ngClass]=\"column.customClasses\">{{ column.value }}</th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let data of dataSource; let i = index\">\r\n <td *ngIf=\"checkbox\">\r\n <div class=\"custom-control custom-checkbox\">\r\n <input\r\n #checkbox\r\n class=\"custom-control-input\"\r\n type=\"checkbox\"\r\n id=\"{{ id }}-checkbox_{{ i }}\"\r\n name=\"{{ id }}-checkbox_{{ i }}\"\r\n value=\"\"\r\n (change)=\"onCheckboxChange(data, $event)\"\r\n />\r\n <label\r\n class=\"custom-control-label no-text\"\r\n for=\"{{ id }}-checkbox_{{ i }}\"\r\n aria-label=\"Descripci\u00F3n para usuarios de lectores de pantalla\"\r\n ></label>\r\n </div>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns\">\r\n <td [ngClass]=\"data[column.key].customClasses\">\r\n <div *ngIf=\"data[column.key].data\" [innerHTML]=\"sanitizeHTML(data[column.key].data)\"></div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OTableComponent, decorators: [{ type: Component, args: [{ selector: 'o-table', template: "<div [ngClass]=\"{ 'responsive-scroll': isScrollable }\" [class]=\"customClasses\" tabindex=\"0\">\r\n <table\r\n *ngIf=\"isValidateComponent\"\r\n class=\"table\"\r\n [ngClass]=\"{ 'table-borderless': !isBordered, 'table-striped': isStriped }\"\r\n >\r\n <thead>\r\n <tr>\r\n <th scope=\"col\" *ngIf=\"checkbox?.isAllSelectable == true\" [ngClass]=\"checkbox.customClassesTh\">\r\n <div class=\"custom-control custom-checkbox\">\r\n <input\r\n class=\"custom-control-input\"\r\n type=\"checkbox\"\r\n id=\"{{ id }}-selectAllCheckbox\"\r\n name=\"{{ id }}-selectAllCheckbox\"\r\n value=\"\"\r\n (change)=\"onHeaderCheckboxChange($event)\"\r\n />\r\n <label\r\n [ngClass]=\"checkbox.customClassesLabel\"\r\n class=\"custom-control-label\"\r\n for=\"{{ id }}-selectAllCheckbox\"\r\n aria-label=\"Descripci\u00F3n para usuarios de lectores de pantalla\"\r\n >{{ checkbox.title }}</label\r\n >\r\n </div>\r\n </th>\r\n <th scope=\"col\" *ngIf=\"checkbox?.isAllSelectable == false\" [ngClass]=\"checkbox.customClassesTh\">\r\n {{ checkbox.title }}\r\n </th>\r\n <ng-container *ngFor=\"let column of columns\">\r\n <th scope=\"col\" [ngClass]=\"column.customClasses\">{{ column.value }}</th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let data of dataSource; let i = index\">\r\n <td *ngIf=\"checkbox\">\r\n <div class=\"custom-control custom-checkbox\">\r\n <input\r\n #checkbox\r\n class=\"custom-control-input\"\r\n type=\"checkbox\"\r\n id=\"{{ id }}-checkbox_{{ i }}\"\r\n name=\"{{ id }}-checkbox_{{ i }}\"\r\n value=\"\"\r\n (change)=\"onCheckboxChange(data, $event)\"\r\n />\r\n <label\r\n class=\"custom-control-label no-text\"\r\n for=\"{{ id }}-checkbox_{{ i }}\"\r\n aria-label=\"Descripci\u00F3n para usuarios de lectores de pantalla\"\r\n ></label>\r\n </div>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns\">\r\n <td [ngClass]=\"data[column.key].customClasses\">\r\n <div *ngIf=\"data[column.key].data\" [innerHTML]=\"sanitizeHTML(data[column.key].data)\"></div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n</div>\r\n" }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i1.DomSanitizer }]; }, propDecorators: { id: [{ type: Input }], columns: [{ type: Input }], dataSource: [{ type: Input }], isBordered: [{ type: Input }], isStriped: [{ type: Input }], isScrollable: [{ type: Input }], customClasses: [{ type: Input }], checkbox: [{ type: Input }], dataSelectedChange: [{ type: Output }], checkboxRef: [{ type: ViewChildren, args: ['checkbox'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtb2JlbGlzY28vdGFibGUvby10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtb2JlbGlzY28vdGFibGUvby10YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBR0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUVOLFlBQVksRUFFYixNQUFNLGVBQWUsQ0FBQzs7OztBQVN2QixNQUFNLE9BQU8sZUFBZTtJQW1CMUIsWUFBNkIsUUFBbUIsRUFBVSxTQUF1QjtRQUFwRCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBYztRQWxCMUUsd0JBQW1CLEdBQVksS0FBSyxDQUFDO1FBRTVCLE9BQUUsR0FBVyxTQUFTLENBQUM7UUFDdkIsWUFBTyxHQUFhLEVBQUUsQ0FBQztRQUN2QixlQUFVLEdBQWlCLEVBQUUsQ0FBQztRQUM5QixlQUFVLEdBQVksS0FBSyxDQUFDO1FBQzVCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IsaUJBQVksR0FBWSxLQUFLLENBQUM7UUFDOUIsa0JBQWEsR0FBVyxFQUFFLENBQUM7UUFHMUIsdUJBQWtCLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7UUFFL0Qsa0JBQWEsR0FBaUIsRUFBRSxDQUFDO1FBQ2pDLGlCQUFZLEdBQWlCLEVBQUUsQ0FBQztJQUk0QyxDQUFDO0lBRTlFLFFBQVE7UUFDYixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRU0sZUFBZTtRQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxhQUFhLENB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bSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBPbkluaXQsXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDb21wb25lbnQsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT3V0cHV0LFxyXG4gIFF1ZXJ5TGlzdCxcclxuICBWaWV3Q2hpbGRyZW4sXHJcbiAgUmVuZGVyZXIyXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZUh0bWwgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcclxuaW1wb3J0IHsgQ29sdW1uLCBEYXRhU291cmNlLCBUYWJsZUNoZWNrYm94IH0gZnJvbSAnbmd4LW9iZWxpc2NvLWV4YW1wbGUvY29yZS9tb2RlbHMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdvLXRhYmxlJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vby10YWJsZS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vby10YWJsZS5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBPVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xyXG4gIHB1YmxpYyBpc1ZhbGlkYXRlQ29tcG9uZW50OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIEBJbnB1dCgpIHB1YmxpYyBpZDogc3RyaW5nID0gJ28tdGFibGUnO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBjb2x1bW5zOiBDb2x1bW5bXSA9IFtdO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBkYXRhU291cmNlOiBEYXRhU291cmNlW10gPSBbXTtcclxuICBASW5wdXQoKSBwdWJsaWMgaXNCb3JkZXJlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBpc1N0cmlwZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBwdWJsaWMgaXNTY3JvbGxhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcHVibGljIGN1c3RvbUNsYXNzZXM6IHN0cmluZyA9ICcnO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBjaGVja2JveCE6IFRhYmxlQ2hlY2tib3g7XHJcblxyXG4gIEBPdXRwdXQoKSBwdWJsaWMgZGF0YVNlbGVjdGVkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRhU291cmNlW10+KCk7XHJcblxyXG4gIHByaXZhdGUgaW5wdXRDaGVja0FycjogRWxlbWVudFJlZltdID0gW107XHJcbiAgcHJpdmF0ZSBkYXRhU2VsZWN0ZWQ6IERhdGFTb3VyY2VbXSA9IFtdO1xyXG5cclxuICBAVmlld0NoaWxkcmVuKCdjaGVja2JveCcpIHB1YmxpYyBjaGVja2JveFJlZiE6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPjtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSByZW5kZXJlcjogUmVuZGVyZXIyLCBwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyKSB7fVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNvbXBvbmVudFZhbGlkYXRpb25zKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5jaGVja2JveFJlZi5tYXAoKGUpID0+IHtcclxuICAgICAgdGhpcy5pbnB1dENoZWNrQXJyLnB1c2goZS5uYXRpdmVFbGVtZW50KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wb25lbnRWYWxpZGF0aW9ucygpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNWYWxpZGF0ZUNvbXBvbmVudCA9IHRoaXMuY29sdW1ucy5sZW5ndGggPiAwICYmIHRoaXMuZGF0YVNvdXJjZS5sZW5ndGggPiAwO1xyXG5cclxuICAgIGlmICghdGhpcy5pc1ZhbGlkYXRlQ29tcG9uZW50KSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNvbHVtbnMgYW5kIGRhdGFTb3VyY2UgbXVzdCBub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmNvbHVtbnMubWFwKChlKSA9PiB7XHJcbiAgICAgIGlmIChlLmtleSA9PT0gJycgfHwgZS52YWx1ZSA9PT0gJycpIHtcclxuICAgICAgICB0aGlzLmlzVmFsaWRhdGVDb21wb25lbnQgPSBmYWxzZTtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb2x1bW5zIG11c3Qgbm90IGhhdmUgbnVsbCB2YWx1ZXMnKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5jb2x1bW5zLm1hcCgoZSkgPT4gKGUudmFsdWUgPSBlLnZhbHVlLnRyaW0oKSkpO1xyXG5cclxuICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuY29sdW1ucy5tYXAoKGUpID0+IHtcclxuICAgICAgZS52YWx1ZSA9IGUudmFsdWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBlLnZhbHVlLnNsaWNlKDEpLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgIHJldHVybiBlO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5jb2x1bW5zLm1hcCgoZSkgPT4ge1xyXG4gICAgICBpZiAoZS52YWx1ZS5tYXRjaCgvXlthLXpBLVrDocOpw63Ds8O6w4HDicONw5PDmsOxw5EgXSokLykgJiYgZS5rZXkubWF0Y2goL15bYS16QS1aIF0qJC8pKSB7XHJcbiAgICAgICAgdGhpcy5pc1ZhbGlkYXRlQ29tcG9uZW50ID0gdHJ1ZTtcclxuICAgICAgICByZXR1cm4gZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmlzVmFsaWRhdGVDb21wb25lbnQgPSBmYWxzZTtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICAnVGhlIGNvbHVtbnMgdmFsdWUgbXVzdCBub3QgY29udGFpbiBudW1iZXJzIG9yIHN5bWJvbHMgYW5kIHRoZSBrZXkgbXVzdCBub3QgY29udGFpbiBudW1iZXJzLCBzeW1ib2xzIG9yIGFjY2VudHMnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzYW5pdGl6ZUhUTUwoaHRtbDogc3RyaW5nKTogU2FmZUh0bWwge1xyXG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKGh0bWwpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uSGVhZGVyQ2hlY2tib3hDaGFuZ2UoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcclxuICAgIGlmICh0YXJnZXQpIHtcclxuICAgICAgY29uc3QgaXNDaGVja2VkID0gdGFyZ2V0LmNoZWNrZWQ7XHJcbiAgICAgIHRoaXMuY2hlY2tib3hSZWYudG9BcnJheSgpLmZvckVhY2goKGNoZWNrYm94OiBFbGVtZW50UmVmKSA9PiB7XHJcbiAgICAgICAgKGNoZWNrYm94Lm5hdGl2ZUVsZW1lbnQgYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZCA9IGlzQ2hlY2tlZDtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAoaXNDaGVja2VkKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhU2VsZWN0ZWQgPSBbLi4udGhpcy5kYXRhU291cmNlXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmRhdGFTZWxlY3RlZCA9IFtdO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmRhdGFTZWxlY3RlZENoYW5nZS5lbWl0KHRoaXMuZGF0YVNlbGVjdGVkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkNoZWNrYm94Q2hhbmdlKGRhdGE6IERhdGFTb3VyY2UsIGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIGlmIChldmVudCAmJiBldmVudC50YXJnZXQgJiYgdHlwZW9mIGV2ZW50LnRhcmdldC5jaGVja2VkID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgY29uc3QgaXNDaGVja2VkOiBib29sZWFuID0gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XHJcblxyXG4gICAgICBpZiAoaXNDaGVja2VkKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhU2VsZWN0ZWQucHVzaChkYXRhKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuZGF0YVNlbGVjdGVkLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbSA9PT0gZGF0YSk7XHJcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgdGhpcy5kYXRhU2VsZWN0ZWQuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuZGF0YVNlbGVjdGVkQ2hhbmdlLmVtaXQodGhpcy5kYXRhU2VsZWN0ZWQpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IFtuZ0NsYXNzXT1cInsgJ3Jlc3BvbnNpdmUtc2Nyb2xsJzogaXNTY3JvbGxhYmxlIH1cIiBbY2xhc3NdPVwiY3VzdG9tQ2xhc3Nlc1wiIHRhYmluZGV4PVwiMFwiPlxyXG4gIDx0YWJsZVxyXG4gICAgKm5nSWY9XCJpc1ZhbGlkYXRlQ29tcG9uZW50XCJcclxuICAgIGNsYXNzPVwidGFibGVcIlxyXG4gICAgW25nQ2xhc3NdPVwieyAndGFibGUtYm9yZGVybGVzcyc6ICFpc0JvcmRlcmVkLCAndGFibGUtc3RyaXBlZCc6IGlzU3RyaXBlZCB9XCJcclxuICA+XHJcbiAgICA8dGhlYWQ+XHJcbiAgICAgIDx0cj5cclxuICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiAqbmdJZj1cImNoZWNrYm94Py5pc0FsbFNlbGVjdGFibGUgPT0gdHJ1ZVwiIFtuZ0NsYXNzXT1cImNoZWNrYm94LmN1c3RvbUNsYXNzZXNUaFwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1jb250cm9sIGN1c3RvbS1jaGVja2JveFwiPlxyXG4gICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1jb250cm9sLWlucHV0XCJcclxuICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxyXG4gICAgICAgICAgICAgIGlkPVwie3sgaWQgfX0tc2VsZWN0QWxsQ2hlY2tib3hcIlxyXG4gICAgICAgICAgICAgIG5hbWU9XCJ7eyBpZCB9fS1zZWxlY3RBbGxDaGVja2JveFwiXHJcbiAgICAgICAgICAgICAgdmFsdWU9XCJcIlxyXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwib25IZWFkZXJDaGVja2JveENoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPGxhYmVsXHJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY2hlY2tib3guY3VzdG9tQ2xhc3Nlc0xhYmVsXCJcclxuICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1jb250cm9sLWxhYmVsXCJcclxuICAgICAgICAgICAgICBmb3I9XCJ7eyBpZCB9fS1zZWxlY3RBbGxDaGVja2JveFwiXHJcbiAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIkRlc2NyaXBjacOzbiBwYXJhIHVzdWFyaW9zIGRlIGxlY3RvcmVzIGRlIHBhbnRhbGxhXCJcclxuICAgICAgICAgICAgICA+e3sgY2hlY2tib3gudGl0bGUgfX08L2xhYmVsXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvdGg+XHJcbiAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgKm5nSWY9XCJjaGVja2JveD8uaXNBbGxTZWxlY3RhYmxlID09IGZhbHNlXCIgW25nQ2xhc3NdPVwiY2hlY2tib3guY3VzdG9tQ2xhc3Nlc1RoXCI+XHJcbiAgICAgICAgICB7eyBjaGVja2JveC50aXRsZSB9fVxyXG4gICAgICAgIDwvdGg+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnNcIj5cclxuICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiIFtuZ0NsYXNzXT1cImNvbHVtbi5jdXN0b21DbGFzc2VzXCI+e3sgY29sdW1uLnZhbHVlIH19PC90aD5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC90cj5cclxuICAgIDwvdGhlYWQ+XHJcbiAgICA8dGJvZHk+XHJcbiAgICAgIDx0ciAqbmdGb3I9XCJsZXQgZGF0YSBvZiBkYXRhU291cmNlOyBsZXQgaSA9IGluZGV4XCI+XHJcbiAgICAgICAgPHRkICpuZ0lmPVwiY2hlY2tib3hcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXN0b20tY29udHJvbCBjdXN0b20tY2hlY2tib3hcIj5cclxuICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgI2NoZWNrYm94XHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjdXN0b20tY29udHJvbC1pbnB1dFwiXHJcbiAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcclxuICAgICAgICAgICAgICBpZD1cInt7IGlkIH19LWNoZWNrYm94X3t7IGkgfX1cIlxyXG4gICAgICAgICAgICAgIG5hbWU9XCJ7eyBpZCB9fS1jaGVja2JveF97eyBpIH19XCJcclxuICAgICAgICAgICAgICB2YWx1ZT1cIlwiXHJcbiAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNoZWNrYm94Q2hhbmdlKGRhdGEsICRldmVudClcIlxyXG4gICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICA8bGFiZWxcclxuICAgICAgICAgICAgICBjbGFzcz1cImN1c3RvbS1jb250cm9sLWxhYmVsIG5vLXRleHRcIlxyXG4gICAgICAgICAgICAgIGZvcj1cInt7IGlkIH19LWNoZWNrYm94X3t7IGkgfX1cIlxyXG4gICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJEZXNjcmlwY2nDs24gcGFyYSB1c3VhcmlvcyBkZSBsZWN0b3JlcyBkZSBwYW50YWxsYVwiXHJcbiAgICAgICAgICAgID48L2xhYmVsPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZD5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgY29sdW1uc1wiPlxyXG4gICAgICAgICAgPHRkIFtuZ0NsYXNzXT1cImRhdGFbY29sdW1uLmtleV0uY3VzdG9tQ2xhc3Nlc1wiPlxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZGF0YVtjb2x1bW4ua2V5XS5kYXRhXCIgW2lubmVySFRNTF09XCJzYW5pdGl6ZUhUTUwoZGF0YVtjb2x1bW4ua2V5XS5kYXRhKVwiPjwvZGl2PlxyXG4gICAgICAgICAgPC90ZD5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC90cj5cclxuICAgIDwvdGJvZHk+XHJcbiAgPC90YWJsZT5cclxuPC9kaXY+XHJcbiJdfQ==