@rangertechnologies/ngnxt
Version:
This library was used for creating dymanic UI based on the input JSON/data
102 lines • 26 kB
JavaScript
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
export class NxtGroupInfo {
elementRef;
cardTitle = 'Title'; // card title
fields = []; // fields to display
isEditable = false; // is the card editable
allowAdd = false; // allow adding new fields
allowEditValues = false; // allow editing values
allowDelete = false; // allow deleting fields
cardWidth = '300px'; // card width
cardHeight = 'auto'; // card height
backgroundColor = 'white'; // card background color
borderRadius = '10px'; // card border radius
editConfig = null; // edit config
buttonClick = new EventEmitter();
editingIndex = -1;
isDropdownOpen = false;
constructor(elementRef) {
this.elementRef = elementRef;
}
getCardStyle() {
return {
width: this.cardWidth,
height: this.cardHeight,
backgroundColor: this.backgroundColor,
borderRadius: this.borderRadius || '8px'
};
}
startEditing(index) {
if (this.isEditable) {
this.editingIndex = index;
}
}
saveItem(index) {
this.editingIndex = -1;
}
deleteItem(index) {
if (this.isEditable && this.allowDelete) {
this.fields.splice(index, 1);
}
}
addNewItem() {
if (this.isEditable && this.allowAdd) {
this.fields.push({ icon: 'https://img.icons8.com/material-sharp/24/permanent-job.png', name: 'New Position', value: 0 });
this.editingIndex = this.fields.length - 1;
}
}
toggleDropdown() {
this.isDropdownOpen = !this.isDropdownOpen;
}
closeDropdown() {
this.isDropdownOpen = false;
}
onClickOutside(event) {
if (this.isDropdownOpen && !this.elementRef.nativeElement.contains(event.target)) {
this.isDropdownOpen = false;
}
}
onButtonClick(button) {
this.buttonClick.emit({ button, fields: this.fields });
this.closeDropdown();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NxtGroupInfo, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NxtGroupInfo, isStandalone: true, selector: "nxt-group-info", inputs: { cardTitle: "cardTitle", fields: "fields", isEditable: "isEditable", allowAdd: "allowAdd", allowEditValues: "allowEditValues", allowDelete: "allowDelete", cardWidth: "cardWidth", cardHeight: "cardHeight", backgroundColor: "backgroundColor", borderRadius: "borderRadius", editConfig: "editConfig" }, outputs: { buttonClick: "buttonClick" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, ngImport: i0, template: "<div class=\"position-card\" [ngStyle]=\"getCardStyle()\">\n <div class=\"title-card-header\">\n <h3 class=\"card-title\">{{ cardTitle }}</h3>\n <div class=\"card-actions\" *ngIf=\"isEditable\">\n <button class=\"edit-button\" (click)=\"toggleDropdown(); $event.stopPropagation()\">\n <i class=\"fa fa-ellipsis-v\"></i>\n </button>\n <!-- SKS4APR25 Dropdown menu -->\n <div *ngIf=\"isDropdownOpen\" class=\"edit-dropdown-menu show\">\n <div *ngFor=\"let button of editConfig.buttons\" class=\"edit-dropdown-item\" (click)=\"onButtonClick(button)\">\n <div class=\"dropdown-button-content\">\n <img *ngIf=\"button.isImageSvg && button.iconSrc\" [src]=\"button.iconSrc\" alt=\"icon\" class=\"button-icon\">\n <span class=\"button-name\">{{ button.name }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"card-content\">\n <div class=\"position-item\" *ngFor=\"let field of fields; let i = index\">\n <div *ngIf=\"editingIndex !== i\" class=\"position-display\">\n <div class=\"position-icon\">\n <img [src]=\"field.icon\" alt=\"icon\">\n </div>\n <div class=\"position-name\">{{ field.name }}</div>\n <div class=\"position-value\">{{ field.value }}</div>\n <div class=\"edit-actions\" *ngIf=\"isEditable\">\n <button class=\"edit-btn\" (click)=\"startEditing(i)\" *ngIf=\"allowEditValues\">\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button class=\"delete-btn\" (click)=\"deleteItem(i)\" *ngIf=\"allowDelete\">\n <i class=\"fa fa-trash\"></i>\n </button>\n </div>\n </div>\n\n <div *ngIf=\"editingIndex === i\" class=\"position-edit\">\n <div class=\"position-icon\">\n <img [src]=\"field.icon\" alt=\"icon\">\n </div>\n <input [(ngModel)]=\"field.name\" class=\"edit-name\" placeholder=\"Position name\">\n <input [(ngModel)]=\"field.value\" class=\"edit-value\" type=\"number\">\n <button class=\"save-btn\" (click)=\"saveItem(i)\">\n <i class=\"fa fa-check\"></i>\n </button>\n </div>\n </div>\n\n <div class=\"add-position\" *ngIf=\"isEditable && allowAdd\">\n <button class=\"add-btn\" (click)=\"addNewItem()\">\n <i class=\"fa fa-plus\"></i> Add\n </button>\n </div>\n </div>\n</div>", styles: [".position-card{box-shadow:0 2px 8px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.title-card-header{display:flex;justify-content:space-between;align-items:center;padding-left:15px!important;padding:5px}.card-title{margin:0;font-size:16px;font-weight:500;color:#555}.edit-button{right:0;cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;height:24px;background-color:#eee;border-radius:15px;padding:2px;border:none}.edit-button:hover{color:#000;background-color:#f4f4f4}.card-content{padding:8px 0}.position-item{display:flex;padding:8px 16px}.position-display,.position-edit{display:flex;align-items:center;width:100%}.position-icon{width:24px;height:24px;margin-right:12px;display:flex;align-items:center;justify-content:center}.position-icon img{max-width:100%;max-height:100%}.position-name{flex-grow:1;color:#333}.position-value{font-weight:700;color:#333;margin-left:8px;min-width:30px;text-align:right}.edit-actions{display:flex;opacity:0;transition:opacity .2s}.position-item:hover .edit-actions{opacity:1}.edit-btn,.delete-btn,.save-btn{background:none;border:none;cursor:pointer;padding:4px;color:#999}.edit-btn:hover,.save-btn:hover{color:#2196f3}.delete-btn:hover{color:#f44336}.position-edit{padding:4px 0}.edit-name,.edit-value{border:1px solid #ddd;padding:4px 8px;border-radius:4px}.edit-name{flex-grow:1;margin-right:8px}.edit-value{width:50px;text-align:right;margin-right:8px}.add-position{padding:8px 16px;text-align:center}.add-btn{background:none;border:1px dashed #ccc;border-radius:4px;padding:6px 12px;width:100%;cursor:pointer;color:#999;transition:all .2s}.add-btn:hover{border-color:#2196f3;color:#2196f3}.edit-dropdown-menu{position:absolute;z-index:1000;min-width:80px;max-height:75px;background-color:#fff;overflow-y:auto;border:1px solid rgba(0,0,0,.15);border-radius:4px;box-shadow:0 6px 12px #0000002d}.edit-dropdown-item{display:block;width:100%;padding:8px 16px;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0;cursor:pointer}.edit-dropdown-item:is(:hover,:focus){color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-button-content{display:flex;align-items:center;gap:8px}.button-icon{width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center}.button-icon ::ng-deep svg{width:20px;height:20px}.button-name{font-size:14px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NxtGroupInfo, decorators: [{
type: Component,
args: [{ selector: 'nxt-group-info', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"position-card\" [ngStyle]=\"getCardStyle()\">\n <div class=\"title-card-header\">\n <h3 class=\"card-title\">{{ cardTitle }}</h3>\n <div class=\"card-actions\" *ngIf=\"isEditable\">\n <button class=\"edit-button\" (click)=\"toggleDropdown(); $event.stopPropagation()\">\n <i class=\"fa fa-ellipsis-v\"></i>\n </button>\n <!-- SKS4APR25 Dropdown menu -->\n <div *ngIf=\"isDropdownOpen\" class=\"edit-dropdown-menu show\">\n <div *ngFor=\"let button of editConfig.buttons\" class=\"edit-dropdown-item\" (click)=\"onButtonClick(button)\">\n <div class=\"dropdown-button-content\">\n <img *ngIf=\"button.isImageSvg && button.iconSrc\" [src]=\"button.iconSrc\" alt=\"icon\" class=\"button-icon\">\n <span class=\"button-name\">{{ button.name }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"card-content\">\n <div class=\"position-item\" *ngFor=\"let field of fields; let i = index\">\n <div *ngIf=\"editingIndex !== i\" class=\"position-display\">\n <div class=\"position-icon\">\n <img [src]=\"field.icon\" alt=\"icon\">\n </div>\n <div class=\"position-name\">{{ field.name }}</div>\n <div class=\"position-value\">{{ field.value }}</div>\n <div class=\"edit-actions\" *ngIf=\"isEditable\">\n <button class=\"edit-btn\" (click)=\"startEditing(i)\" *ngIf=\"allowEditValues\">\n <i class=\"fa fa-pencil\"></i>\n </button>\n <button class=\"delete-btn\" (click)=\"deleteItem(i)\" *ngIf=\"allowDelete\">\n <i class=\"fa fa-trash\"></i>\n </button>\n </div>\n </div>\n\n <div *ngIf=\"editingIndex === i\" class=\"position-edit\">\n <div class=\"position-icon\">\n <img [src]=\"field.icon\" alt=\"icon\">\n </div>\n <input [(ngModel)]=\"field.name\" class=\"edit-name\" placeholder=\"Position name\">\n <input [(ngModel)]=\"field.value\" class=\"edit-value\" type=\"number\">\n <button class=\"save-btn\" (click)=\"saveItem(i)\">\n <i class=\"fa fa-check\"></i>\n </button>\n </div>\n </div>\n\n <div class=\"add-position\" *ngIf=\"isEditable && allowAdd\">\n <button class=\"add-btn\" (click)=\"addNewItem()\">\n <i class=\"fa fa-plus\"></i> Add\n </button>\n </div>\n </div>\n</div>", styles: [".position-card{box-shadow:0 2px 8px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.title-card-header{display:flex;justify-content:space-between;align-items:center;padding-left:15px!important;padding:5px}.card-title{margin:0;font-size:16px;font-weight:500;color:#555}.edit-button{right:0;cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;height:24px;background-color:#eee;border-radius:15px;padding:2px;border:none}.edit-button:hover{color:#000;background-color:#f4f4f4}.card-content{padding:8px 0}.position-item{display:flex;padding:8px 16px}.position-display,.position-edit{display:flex;align-items:center;width:100%}.position-icon{width:24px;height:24px;margin-right:12px;display:flex;align-items:center;justify-content:center}.position-icon img{max-width:100%;max-height:100%}.position-name{flex-grow:1;color:#333}.position-value{font-weight:700;color:#333;margin-left:8px;min-width:30px;text-align:right}.edit-actions{display:flex;opacity:0;transition:opacity .2s}.position-item:hover .edit-actions{opacity:1}.edit-btn,.delete-btn,.save-btn{background:none;border:none;cursor:pointer;padding:4px;color:#999}.edit-btn:hover,.save-btn:hover{color:#2196f3}.delete-btn:hover{color:#f44336}.position-edit{padding:4px 0}.edit-name,.edit-value{border:1px solid #ddd;padding:4px 8px;border-radius:4px}.edit-name{flex-grow:1;margin-right:8px}.edit-value{width:50px;text-align:right;margin-right:8px}.add-position{padding:8px 16px;text-align:center}.add-btn{background:none;border:1px dashed #ccc;border-radius:4px;padding:6px 12px;width:100%;cursor:pointer;color:#999;transition:all .2s}.add-btn:hover{border-color:#2196f3;color:#2196f3}.edit-dropdown-menu{position:absolute;z-index:1000;min-width:80px;max-height:75px;background-color:#fff;overflow-y:auto;border:1px solid rgba(0,0,0,.15);border-radius:4px;box-shadow:0 6px 12px #0000002d}.edit-dropdown-item{display:block;width:100%;padding:8px 16px;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0;cursor:pointer}.edit-dropdown-item:is(:hover,:focus){color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-button-content{display:flex;align-items:center;gap:8px}.button-icon{width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center}.button-icon ::ng-deep svg{width:20px;height:20px}.button-name{font-size:14px}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { cardTitle: [{
type: Input
}], fields: [{
type: Input
}], isEditable: [{
type: Input
}], allowAdd: [{
type: Input
}], allowEditValues: [{
type: Input
}], allowDelete: [{
type: Input
}], cardWidth: [{
type: Input
}], cardHeight: [{
type: Input
}], backgroundColor: [{
type: Input
}], borderRadius: [{
type: Input
}], editConfig: [{
type: Input
}], buttonClick: [{
type: Output
}], onClickOutside: [{
type: HostListener,
args: ['document:click', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtaW5mby5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvY29tcG9uZW50cy9jYXJkcy9ncm91cC1pbmZvL2dyb3VwLWluZm8uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvY2FyZHMvZ3JvdXAtaW5mby9ncm91cC1pbmZvLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7QUFxQjdDLE1BQU0sT0FBTyxZQUFZO0lBa0JIO0lBakJYLFNBQVMsR0FBVyxPQUFPLENBQUMsQ0FBQyxhQUFhO0lBQzFDLE1BQU0sR0FBWSxFQUFFLENBQUMsQ0FBQyxvQkFBb0I7SUFDMUMsVUFBVSxHQUFZLEtBQUssQ0FBQyxDQUFDLHVCQUF1QjtJQUNwRCxRQUFRLEdBQVksS0FBSyxDQUFDLENBQUMsMEJBQTBCO0lBQ3JELGVBQWUsR0FBWSxLQUFLLENBQUMsQ0FBQyx1QkFBdUI7SUFDekQsV0FBVyxHQUFZLEtBQUssQ0FBQyxDQUFDLHdCQUF3QjtJQUN0RCxTQUFTLEdBQVcsT0FBTyxDQUFDLENBQUMsYUFBYTtJQUMxQyxVQUFVLEdBQVcsTUFBTSxDQUFDLENBQUMsY0FBYztJQUMzQyxlQUFlLEdBQVcsT0FBTyxDQUFDLENBQUMsd0JBQXdCO0lBQzNELFlBQVksR0FBVyxNQUFNLENBQUMsQ0FBQyxxQkFBcUI7SUFDcEQsVUFBVSxHQUFRLElBQUksQ0FBQyxDQUFD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V0FBVztzQkFBcEIsTUFBTTtnQkE2Q1AsY0FBYztzQkFEYixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuZXhwb3J0IGludGVyZmFjZSBGaWVsZCB7XG4gIGljb246IHN0cmluZzsgICAgICAgLy8gVVJMIG9yIHBhdGggdG8gdGhlIGljb25cbiAgbmFtZTogc3RyaW5nOyAgICAgICAvLyBOYW1lL2xhYmVsIG9mIHRoZSBwb3NpdGlvblxuICB2YWx1ZTogbnVtYmVyIHwgc3RyaW5nOyAvLyBDb3VudC92YWx1ZSBmb3IgdGhpcyBwb3NpdGlvblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhcmRDb25maWcge1xuICB3aWR0aD86IHN0cmluZztcbiAgaGVpZ2h0Pzogc3RyaW5nO1xuICBiYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmc7XG4gIGJvcmRlclJhZGl1cz86IHN0cmluZztcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnh0LWdyb3VwLWluZm8nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9ncm91cC1pbmZvLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2dyb3VwLWluZm8uY29tcG9uZW50LmNzcydcbn0pXG5leHBvcnQgY2xhc3MgTnh0R3JvdXBJbmZvIHtcbiAgQElucHV0KCkgY2FyZFRpdGxlOiBzdHJpbmcgPSAnVGl0bGUnOyAvLyBjYXJkIHRpdGxlXG4gIEBJbnB1dCgpIGZpZWxkczogRmllbGRbXSA9IFtdOyAvLyBmaWVsZHMgdG8gZGlzcGxheVxuICBASW5wdXQoKSBpc0VkaXRhYmxlOiBib29sZWFuID0gZmFsc2U7IC8vIGlzIHRoZSBjYXJkIGVkaXRhYmxlXG4gIEBJbnB1dCgpIGFsbG93QWRkOiBib29sZWFuID0gZmFsc2U7IC8vIGFsbG93IGFkZGluZyBuZXcgZmllbGRzXG4gIEBJbnB1dCgpIGFsbG93RWRpdFZhbHVlczogYm9vbGVhbiA9IGZhbHNlOyAvLyBhbGxvdyBlZGl0aW5nIHZhbHVlc1xuICBASW5wdXQoKSBhbGxvd0RlbGV0ZTogYm9vbGVhbiA9IGZhbHNlOyAvLyBhbGxvdyBkZWxldGluZyBmaWVsZHNcbiAgQElucHV0KCkgY2FyZFdpZHRoOiBzdHJpbmcgPSAnMzAwcHgnOyAvLyBjYXJkIHdpZHRoXG4gIEBJbnB1dCgpIGNhcmRIZWlnaHQ6IHN0cmluZyA9ICdhdXRvJzsgLy8gY2FyZCBoZWlnaHRcbiAgQElucHV0KCkgYmFja2dyb3VuZENvbG9yOiBzdHJpbmcgPSAnd2hpdGUnOyAvLyBjYXJkIGJhY2tncm91bmQgY29sb3JcbiAgQElucHV0KCkgYm9yZGVyUmFkaXVzOiBzdHJpbmcgPSAnMTBweCc7IC8vIGNhcmQgYm9yZGVyIHJhZGl1c1xuICBASW5wdXQoKSBlZGl0Q29uZmlnOiBhbnkgPSBudWxsOyAvLyBlZGl0IGNvbmZpZ1xuXG4gIEBPdXRwdXQoKSBidXR0b25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8e30+KCk7XG5cbiAgZWRpdGluZ0luZGV4OiBudW1iZXIgPSAtMTtcbiAgaXNEcm9wZG93bk9wZW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHsgfVxuXG4gIGdldENhcmRTdHlsZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGg6IHRoaXMuY2FyZFdpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLmNhcmRIZWlnaHQsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuYmFja2dyb3VuZENvbG9yLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGlzLmJvcmRlclJhZGl1cyB8fCAnOHB4J1xuICAgIH07XG4gIH1cblxuICBzdGFydEVkaXRpbmcoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzRWRpdGFibGUpIHtcbiAgICAgIHRoaXMuZWRpdGluZ0luZGV4ID0gaW5kZXg7XG4gICAgfVxuICB9XG5cbiAgc2F2ZUl0ZW0oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdGluZ0luZGV4ID0gLTE7XG4gIH1cblxuICBkZWxldGVJdGVtKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0VkaXRhYmxlICYmIHRoaXMuYWxsb3dEZWxldGUpIHtcbiAgICAgIHRoaXMuZmllbGRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuICB9XG5cbiAgYWRkTmV3SXRlbSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0VkaXRhYmxlICYmIHRoaXMuYWxsb3dBZGQpIHtcbiAgICAgIHRoaXMuZmllbGRzLnB1c2goeyBpY29uOiAnaHR0cHM6Ly9pbWcuaWNvbnM4LmNvbS9tYXRlcmlhbC1zaGFycC8yNC9wZXJtYW5lbnQtam9iLnBuZycsIG5hbWU6ICdOZXcgUG9zaXRpb24nLCB2YWx1ZTogMCB9KTtcbiAgICAgIHRoaXMuZWRpdGluZ0luZGV4ID0gdGhpcy5maWVsZHMubGVuZ3RoIC0gMTtcbiAgICB9XG4gIH1cbiAgdG9nZ2xlRHJvcGRvd24oKSB7XG4gICAgdGhpcy5pc0Ryb3Bkb3duT3BlbiA9ICF0aGlzLmlzRHJvcGRvd25PcGVuO1xuICB9XG4gIGNsb3NlRHJvcGRvd24oKSB7XG4gICAgdGhpcy5pc0Ryb3Bkb3duT3BlbiA9IGZhbHNlO1xuICB9XG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcbiAgb25DbGlja091dHNpZGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc0Ryb3Bkb3duT3BlbiAmJiAhdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KVxuICAgICkge1xuICAgICAgdGhpcy5pc0Ryb3Bkb3duT3BlbiA9IGZhbHNlO1xuICAgIH1cbiAgfVxuICBvbkJ1dHRvbkNsaWNrKGJ1dHRvbjogYW55KSB7XG4gICAgdGhpcy5idXR0b25DbGljay5lbWl0KHsgYnV0dG9uLCBmaWVsZHM6IHRoaXMuZmllbGRzIH0pO1xuICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicG9zaXRpb24tY2FyZFwiIFtuZ1N0eWxlXT1cImdldENhcmRTdHlsZSgpXCI+XG4gIDxkaXYgY2xhc3M9XCJ0aXRsZS1jYXJkLWhlYWRlclwiPlxuICAgIDxoMyBjbGFzcz1cImNhcmQtdGl0bGVcIj57eyBjYXJkVGl0bGUgfX08L2gzPlxuICAgIDxkaXYgY2xhc3M9XCJjYXJkLWFjdGlvbnNcIiAqbmdJZj1cImlzRWRpdGFibGVcIj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJlZGl0LWJ1dHRvblwiIChjbGljayk9XCJ0b2dnbGVEcm9wZG93bigpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1lbGxpcHNpcy12XCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8IS0tIFNLUzRBUFIyNSBEcm9wZG93biBtZW51IC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImlzRHJvcGRvd25PcGVuXCIgY2xhc3M9XCJlZGl0LWRyb3Bkb3duLW1lbnUgc2hvd1wiPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBidXR0b24gb2YgZWRpdENvbmZpZy5idXR0b25zXCIgY2xhc3M9XCJlZGl0LWRyb3Bkb3duLWl0ZW1cIiAoY2xpY2spPVwib25CdXR0b25DbGljayhidXR0b24pXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWJ1dHRvbi1jb250ZW50XCI+XG4gICAgICAgICAgICA8aW1nICpuZ0lmPVwiYnV0dG9uLmlzSW1hZ2VTdmcgJiYgYnV0dG9uLmljb25TcmNcIiBbc3JjXT1cImJ1dHRvbi5pY29uU3JjXCIgYWx0PVwiaWNvblwiIGNsYXNzPVwiYnV0dG9uLWljb25cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnV0dG9uLW5hbWVcIj57eyBidXR0b24ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImNhcmQtY29udGVudFwiPlxuICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi1pdGVtXCIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGZpZWxkczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgPGRpdiAqbmdJZj1cImVkaXRpbmdJbmRleCAhPT0gaVwiIGNsYXNzPVwicG9zaXRpb24tZGlzcGxheVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24taWNvblwiPlxuICAgICAgICAgIDxpbWcgW3NyY109XCJmaWVsZC5pY29uXCIgYWx0PVwiaWNvblwiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBvc2l0aW9uLW5hbWVcIj57eyBmaWVsZC5uYW1lIH19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi12YWx1ZVwiPnt7IGZpZWxkLnZhbHVlIH19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJlZGl0LWFjdGlvbnNcIiAqbmdJZj1cImlzRWRpdGFibGVcIj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZWRpdC1idG5cIiAoY2xpY2spPVwic3RhcnRFZGl0aW5nKGkpXCIgKm5nSWY9XCJhbGxvd0VkaXRWYWx1ZXNcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtcGVuY2lsXCI+PC9pPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJkZWxldGUtYnRuXCIgKGNsaWNrKT1cImRlbGV0ZUl0ZW0oaSlcIiAqbmdJZj1cImFsbG93RGVsZXRlXCI+XG4gICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXRyYXNoXCI+PC9pPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2ICpuZ0lmPVwiZWRpdGluZ0luZGV4ID09PSBpXCIgY2xhc3M9XCJwb3NpdGlvbi1lZGl0XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi1pY29uXCI+XG4gICAgICAgICAgPGltZyBbc3JjXT1cImZpZWxkLmljb25cIiBhbHQ9XCJpY29uXCI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8aW5wdXQgWyhuZ01vZGVsKV09XCJmaWVsZC5uYW1lXCIgY2xhc3M9XCJlZGl0LW5hbWVcIiBwbGFjZWhvbGRlcj1cIlBvc2l0aW9uIG5hbWVcIj5cbiAgICAgICAgPGlucHV0IFsobmdNb2RlbCldPVwiZmllbGQudmFsdWVcIiBjbGFzcz1cImVkaXQtdmFsdWVcIiB0eXBlPVwibnVtYmVyXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJzYXZlLWJ0blwiIChjbGljayk9XCJzYXZlSXRlbShpKVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtY2hlY2tcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYWRkLXBvc2l0aW9uXCIgKm5nSWY9XCJpc0VkaXRhYmxlICYmIGFsbG93QWRkXCI+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYWRkLWJ0blwiIChjbGljayk9XCJhZGROZXdJdGVtKClcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1wbHVzXCI+PC9pPiBBZGRcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==