UNPKG

ng-prime-tools

Version:

An advanced PrimeNG table for Angular

206 lines 38.2 kB
import { Component, Input, } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../pt-menu/pt-menu.component"; export class PTCardComponent { // Default values as readonly variables static { this.DEFAULT_TITLE_COLOR = '#333'; } static { this.DEFAULT_TITLE_FONT_SIZE = '1.5em'; } static { this.DEFAULT_ICON_COLOR = '#333'; } static { this.DEFAULT_ICON_FONT_SIZE = '1em'; } static { this.DEFAULT_ICON_POSITION = 'left'; } static { this.DEFAULT_BACKGROUND_COLOR = '#fff'; } static { this.DEFAULT_WIDTH = '100%'; } static { this.DEFAULT_HEIGHT = 'auto'; } static { this.DEFAULT_TITLE_POSITION = 'left'; } static { this.DEFAULT_MENU_POSITION = 'right'; } static { this.DEFAULT_BORDER_COLOR = '#ddd'; } static { this.DEFAULT_BORDER_WIDTH = '1px'; } static { this.DEFAULT_TRANSPARENCY = '100'; } static { this.DEFAULT_PADDING = '16px'; } static { this.DEFAULT_MARGIN = '16px 0'; } ngAfterViewInit() { this.logPatternUrl(); } logPatternUrl() { if (this.config.pattern?.imageUrl) { console.log(`[PTCardComponent] Identifier: ${this.config.identifier}, Pattern URL: ${this.config.pattern.imageUrl}`); } } isTitleObject() { return typeof this.config.title === 'object'; } hasTitle() { return this.config.title !== undefined && this.config.title !== null; } getTitleText() { return this.isTitleObject() ? this.config.title.text : this.config.title; } getTitleStyles() { const title = this.config.title; const alignMap = { left: 'flex-start', center: 'center', right: 'flex-end', }; return { color: title?.color || PTCardComponent.DEFAULT_TITLE_COLOR, fontSize: title?.fontSize || PTCardComponent.DEFAULT_TITLE_FONT_SIZE, '--text-align': alignMap[title?.position || PTCardComponent.DEFAULT_TITLE_POSITION], }; } constructor(cd) { this.cd = cd; this.config = {}; } updateStyles() { // After data is fetched or updated this.getCardStyles(); this.cd.detectChanges(); // Force Angular to detect the changes } getIconClass() { const icon = this.config.title?.icon; return typeof icon === 'string' ? icon : icon?.code || null; } getIconStyles() { const icon = this.config.title?.icon; if (typeof icon !== 'string') { return { color: icon?.color || PTCardComponent.DEFAULT_ICON_COLOR, fontSize: icon?.fontSize || PTCardComponent.DEFAULT_ICON_FONT_SIZE, }; } return { color: PTCardComponent.DEFAULT_ICON_COLOR, fontSize: PTCardComponent.DEFAULT_ICON_FONT_SIZE, }; } getIconPosition() { const icon = this.config.title?.icon; if (typeof icon !== 'string' && icon?.position) { return icon.position; } return PTCardComponent.DEFAULT_ICON_POSITION; } getMenuPosition() { return this.config.menuPosition || PTCardComponent.DEFAULT_MENU_POSITION; } getCardStyles() { // Transparency for the background color const backgroundTransparency = this.config.transparencyPercentage ? parseFloat(this.config.transparencyPercentage) / 100 : 1; // Transparency for the pattern image const patternTransparency = this.config.pattern?.transparencyPercentage ? parseFloat(this.config.pattern.transparencyPercentage) / 100 : 1; // Background color with transparency const backgroundColor = this.config.backgroundColor && this.config.transparencyPercentage !== '0' ? this.hexToRgba(this.config.backgroundColor, backgroundTransparency) : 'transparent'; // Pattern image with transparency applied via linear-gradient const backgroundImage = this.config.pattern?.imageUrl && this.config.pattern.transparencyPercentage !== '0' ? `linear-gradient(rgba(255, 255, 255, ${1 - patternTransparency}), rgba(255, 255, 255, ${1 - patternTransparency})), url('${this.config.pattern.imageUrl}')` : ''; const patternWidth = this.config.pattern?.width || '100%'; const patternHeight = this.config.pattern?.height || 'auto'; // Determine background-repeat value const repeatX = this.config.pattern?.repeatX ? 'repeat' : 'no-repeat'; const repeatY = this.config.pattern?.repeatY ? 'repeat' : 'no-repeat'; const backgroundRepeat = `${repeatX} ${repeatY}`; // Adjust background-size based on repeatCount if provided const repeatCount = this.config.pattern?.repeatCount || 1; const backgroundSize = repeatCount > 1 ? `${patternWidth} ${patternHeight}` : `${patternWidth} ${patternHeight}`; // Determine background-position based on the position parameter const backgroundPosition = this.config.pattern?.position || 'center'; const justifyContent = this.config.alignContent === 'center' ? 'center' : 'flex-start'; const alignItems = this.config.alignContent === 'center' ? 'center' : 'stretch'; return { display: 'flex', flexDirection: 'column', justifyContent, // Apply conditional vertical alignment alignItems, // Apply conditional horizontal alignment backgroundColor, // Background color with transparency backgroundImage, // Pattern image with transparency backgroundSize, backgroundPosition, backgroundRepeat, width: this.config.width || PTCardComponent.DEFAULT_WIDTH, height: this.config.height || PTCardComponent.DEFAULT_HEIGHT, border: this.config.noBorder ? 'none' : `solid ${this.config.borderWidth || PTCardComponent.DEFAULT_BORDER_WIDTH} ${this.config.borderColor || PTCardComponent.DEFAULT_BORDER_COLOR}`, padding: this.config.padding || PTCardComponent.DEFAULT_PADDING, margin: this.config.margin || PTCardComponent.DEFAULT_MARGIN, borderRadius: this.config.borderRadius || '8px', boxShadow: this.config.boxShadow || '0 2px 4px rgba(0, 0, 0, 0.1)', position: 'relative', zIndex: this.config.zIndex !== undefined ? this.config.zIndex : 'auto', }; } // Utility function to convert hex color to rgba hexToRgba(hex, alpha) { const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, (_, r, g, b) => r + r + g + g + b + b); const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${alpha})` : hex; } getBodyStyles() { const justifyContent = this.config.alignBodyContent === 'center' ? 'center' : 'flex-start'; const alignItems = this.config.alignBodyContent === 'center' ? 'center' : 'stretch'; return { display: 'flex', flexDirection: 'column', justifyContent, alignItems, flexGrow: 1, maxWidth: '100%', padding: '16px', // Default padding for body boxSizing: 'border-box', overflowX: this.isScrollableHorizontal() ? 'auto' : 'hidden', overflowY: this.isScrollableVertical() ? 'auto' : 'hidden', }; } getHeaderStyles() { const justifyContent = this.config.alignHeaderContent === 'center' ? 'center' : 'flex-start'; const alignItems = this.config.alignHeaderContent === 'center' ? 'center' : 'stretch'; return { display: 'flex', justifyContent, alignItems, marginBottom: '16px', // Default margin for header position: 'relative', }; } isScrollableHorizontal() { return !!this.config.scrollableHorizontal; } isScrollableVertical() { return !!this.config.scrollableVertical; } getCardClass() { return this.config.alignContent === 'center' ? 'center-align' : ''; } getBodyClass() { return this.config.alignBodyContent === 'center' ? 'center-align' : ''; } getHeaderClass() { return this.config.alignHeaderContent === 'center' ? 'center-align' : ''; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTCardComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTCardComponent, selector: "pt-card", inputs: { config: "config" }, ngImport: i0, template: "<div\n class=\"pt-card card\"\n [ngClass]=\"getCardClass()\"\n [attr.id]=\"config.identifier\"\n [ngStyle]=\"getCardStyles()\"\n>\n <!-- Card Header -->\n <div\n *ngIf=\"hasTitle()\"\n class=\"card-header\"\n [ngClass]=\"getHeaderClass()\"\n [ngStyle]=\"getHeaderStyles()\"\n >\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'left'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-left\"\n ></i>\n <span>{{ getTitleText() }}</span>\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'right'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-right\"\n ></i>\n <pt-menu\n *ngIf=\"config.menu\"\n [config]=\"config.menu\"\n [ngClass]=\"{\n 'menu-left': getMenuPosition() === 'left',\n 'menu-right': getMenuPosition() === 'right'\n }\"\n ></pt-menu>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\" [ngClass]=\"getBodyClass()\" [ngStyle]=\"getBodyStyles()\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".pt-card .card{display:flex;flex-direction:column;padding:16px;margin:0 auto;max-height:100vh;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;justify-content:flex-start;align-items:stretch;background-color:transparent}.pt-card .card.center-align{justify-content:center;align-items:center}.pt-card .card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center;pointer-events:none;background-color:var( --background-color, rgba(255, 255, 255, 0) );background-image:var( --background-image-url, none );opacity:var(--image-opacity, 1);z-index:-1}.pt-card .card-body{display:flex;flex-direction:column;flex-grow:1;max-width:100%;z-index:1;padding:0;box-sizing:border-box;justify-content:flex-start;align-items:stretch}.pt-card .card-body.center-align{justify-content:center;align-items:center}.pt-card .card-header{margin-bottom:16px;display:flex;position:relative;justify-content:flex-start;align-items:stretch}.pt-card .card-header.center-align{justify-content:center;align-items:center}.pt-card .card-header-icon-left{margin-right:6px}.pt-card .card-header-icon-right{margin-left:6px}.pt-card .menu-left{position:absolute;left:0;top:0}.pt-card .menu-right{position:absolute;right:0;top:-2px}.pt-card .card-menu{margin-left:auto;cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.PTMenuComponent, selector: "pt-menu", inputs: ["config"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTCardComponent, decorators: [{ type: Component, args: [{ selector: 'pt-card', template: "<div\n class=\"pt-card card\"\n [ngClass]=\"getCardClass()\"\n [attr.id]=\"config.identifier\"\n [ngStyle]=\"getCardStyles()\"\n>\n <!-- Card Header -->\n <div\n *ngIf=\"hasTitle()\"\n class=\"card-header\"\n [ngClass]=\"getHeaderClass()\"\n [ngStyle]=\"getHeaderStyles()\"\n >\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'left'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-left\"\n ></i>\n <span>{{ getTitleText() }}</span>\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'right'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-right\"\n ></i>\n <pt-menu\n *ngIf=\"config.menu\"\n [config]=\"config.menu\"\n [ngClass]=\"{\n 'menu-left': getMenuPosition() === 'left',\n 'menu-right': getMenuPosition() === 'right'\n }\"\n ></pt-menu>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\" [ngClass]=\"getBodyClass()\" [ngStyle]=\"getBodyStyles()\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".pt-card .card{display:flex;flex-direction:column;padding:16px;margin:0 auto;max-height:100vh;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;justify-content:flex-start;align-items:stretch;background-color:transparent}.pt-card .card.center-align{justify-content:center;align-items:center}.pt-card .card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center;pointer-events:none;background-color:var( --background-color, rgba(255, 255, 255, 0) );background-image:var( --background-image-url, none );opacity:var(--image-opacity, 1);z-index:-1}.pt-card .card-body{display:flex;flex-direction:column;flex-grow:1;max-width:100%;z-index:1;padding:0;box-sizing:border-box;justify-content:flex-start;align-items:stretch}.pt-card .card-body.center-align{justify-content:center;align-items:center}.pt-card .card-header{margin-bottom:16px;display:flex;position:relative;justify-content:flex-start;align-items:stretch}.pt-card .card-header.center-align{justify-content:center;align-items:center}.pt-card .card-header-icon-left{margin-right:6px}.pt-card .card-header-icon-right{margin-left:6px}.pt-card .menu-left{position:absolute;left:0;top:0}.pt-card .menu-right{position:absolute;right:0;top:-2px}.pt-card .card-menu{margin-left:auto;cursor:pointer}\n"] }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { config: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWNhcmQvcHQtY2FyZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWNhcmQvcHQtY2FyZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsU0FBUyxFQUNULEtBQUssR0FHTixNQUFNLGVBQWUsQ0FBQzs7OztBQVF2QixNQUFNLE9BQU8sZUFBZTtJQUcxQix1Q0FBdUM7YUFDZix3QkFBbUIsR0FBRyxNQUFNLEFBQVQsQ0FBVTthQUM3Qiw0QkFBdUIsR0FBRyxPQUFPLEFBQVYsQ0FBVzthQUNsQyx1QkFBa0IsR0FBRyxNQUFNLEFBQVQsQ0FBVTthQUM1QiwyQkFBc0IsR0FBRyxLQUFLLEFBQVIsQ0FBUzthQUMvQiwwQkFBcUIsR0FBRyxNQUFNLEFBQVQsQ0FBVTthQUMvQiw2QkFBd0IsR0FBRyxNQUFNLEFBQVQsQ0FBVTthQUNsQyxrQkFBYSxHQUFHLE1BQU0sQUFBVCxDQUFVO2FBQ3ZCLG1CQUFjLEdBQUcsTUFBTSxBQUFULENBQVU7YUFDeEIsMkJBQXNCLEdBQUcsTUFBTSxBQUFULENBQVU7YUFDaEMsMEJBQXFCLEdBQUcsT0FBTyxBQUFWLENBQVc7YUFDaEMseUJBQW9CLEdBQUcsTUFBTSxBQUFULENBQVU7YUFDOUIseUJBQW9CLEdBQUcsS0FBSyxBQUFSLENBQVM7YUFDN0IseUJBQW9CLEdBQUcsS0FBSyxBQUFSLENBQVM7YUFDN0Isb0JBQWUsR0FBRyxNQUFNLEFBQVQsQ0FBVTthQUN6QixtQkFBYyxHQUFHLFFBQVEsQUFBWCxDQUFZO0lBRWxELGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVPLGFBQWE7UUFDbkIsSUFB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QWM7UUFDWixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUMzRSxDQUFDOytHQXBQVSxlQUFlO21HQUFmLGVBQWUsNkVDZjVCLDJtQ0F5Q0E7OzRGRDFCYSxlQUFlO2tCQUwzQixTQUFTOytCQUNFLFNBQVM7c0ZBS1YsTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENhcmRDb25maWcsIEljb25TdHlsZSwgVGl0bGVTdHlsZSB9IGZyb20gJy4uL21vZGVscyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3B0LWNhcmQnLFxuICB0ZW1wbGF0ZVVybDogJy4vcHQtY2FyZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3B0LWNhcmQuY29tcG9uZW50LmNzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBQVENhcmRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcbiAgQElucHV0KCkgY29uZmlnOiBDYXJkQ29uZmlnID0ge307XG5cbiAgLy8gRGVmYXVsdCB2YWx1ZXMgYXMgcmVhZG9ubHkgdmFyaWFibGVzXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfVElUTEVfQ09MT1IgPSAnIzMzMyc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfVElUTEVfRk9OVF9TSVpFID0gJzEuNWVtJztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9JQ09OX0NPTE9SID0gJyMzMzMnO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0lDT05fRk9OVF9TSVpFID0gJzFlbSc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfSUNPTl9QT1NJVElPTiA9ICdsZWZ0JztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SID0gJyNmZmYnO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBERUZBVUxUX1dJRFRIID0gJzEwMCUnO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0hFSUdIVCA9ICdhdXRvJztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9USVRMRV9QT1NJVElPTiA9ICdsZWZ0JztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9NRU5VX1BPU0lUSU9OID0gJ3JpZ2h0JztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9CT1JERVJfQ09MT1IgPSAnI2RkZCc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfQk9SREVSX1dJRFRIID0gJzFweCc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfVFJBTlNQQVJFTkNZID0gJzEwMCc7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfUEFERElORyA9ICcxNnB4JztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9NQVJHSU4gPSAnMTZweCAwJztcblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5sb2dQYXR0ZXJuVXJsKCk7XG4gIH1cblxuICBwcml2YXRlIGxvZ1BhdHRlcm5VcmwoKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLnBhdHRlcm4/LmltYWdlVXJsKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYFtQVENhcmRDb21wb25lbnRdIElkZW50aWZpZXI6ICR7dGhpcy5jb25maWcuaWRlbnRpZmllcn0sIFBhdHRlcm4gVVJMOiAke3RoaXMuY29uZmlnLnBhdHRlcm4uaW1hZ2VVcmx9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpc1RpdGxlT2JqZWN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eXBlb2YgdGhpcy5jb25maWcudGl0bGUgPT09ICdvYmplY3QnO1xuICB9XG5cbiAgaGFzVGl0bGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnRpdGxlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5jb25maWcudGl0bGUgIT09IG51bGw7XG4gIH1cblxuICBnZXRUaXRsZVRleHQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pc1RpdGxlT2JqZWN0KClcbiAgICAgID8gKHRoaXMuY29uZmlnLnRpdGxlIGFzIFRpdGxlU3R5bGUpLnRleHRcbiAgICAgIDogKHRoaXMuY29uZmlnLnRpdGxlIGFzIHN0cmluZyk7XG4gIH1cblxuICBnZXRUaXRsZVN0eWxlcygpIHtcbiAgICBjb25zdCB0aXRsZSA9IHRoaXMuY29uZmlnLnRpdGxlIGFzIFRpdGxlU3R5bGUgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgYWxpZ25NYXA6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICBsZWZ0OiAnZmxleC1zdGFydCcsXG4gICAgICBjZW50ZXI6ICdjZW50ZXInLFxuICAgICAgcmlnaHQ6ICdmbGV4LWVuZCcsXG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6IHRpdGxlPy5jb2xvciB8fCBQVENhcmRDb21wb25lbnQuREVGQVVMVF9USVRMRV9DT0xPUixcbiAgICAgIGZvbnRTaXplOiB0aXRsZT8uZm9udFNpemUgfHwgUFRDYXJkQ29tcG9uZW50LkRFRkFVTFRfVElUTEVfRk9OVF9TSVpFLFxuICAgICAgJy0tdGV4dC1hbGlnbic6XG4gICAgICAgIGFsaWduTWFwW3RpdGxlPy5wb3NpdGlvbiB8fCBQVENhcmRDb21wb25lbnQuREVGQVVMVF9USVRMRV9QT1NJVElPTl0sXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIHVwZGF0ZVN0eWxlcygpIHtcbiAgICAvLyBBZnRlciBkYXRhIGlzIGZldGNoZWQgb3IgdXBkYXRlZFxuICAgIHRoaXMuZ2V0Q2FyZFN0eWxlcygpO1xuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpOyAvLyBGb3JjZSBBbmd1bGFyIHRvIGRldGVjdCB0aGUgY2hhbmdlc1xuICB9XG5cbiAgZ2V0SWNvbkNsYXNzKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGljb24gPSAodGhpcy5jb25maWcudGl0bGUgYXMgVGl0bGVTdHlsZSk/Lmljb247XG4gICAgcmV0dXJuIHR5cGVvZiBpY29uID09PSAnc3RyaW5nJyA/IGljb24gOiAoaWNvbiBhcyBJY29uU3R5bGUpPy5jb2RlIHx8IG51bGw7XG4gIH1cblxuICBnZXRJY29uU3R5bGVzKCkge1xuICAgIGNvbnN0IGljb24gPSAodGhpcy5jb25maWcudGl0bGUgYXMgVGl0bGVTdHlsZSk/Lmljb247XG4gICAgaWYgKHR5cGVvZiBpY29uICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29sb3I6IGljb24/LmNvbG9yIHx8IFBUQ2FyZENvbXBvbmVudC5ERUZBVUxUX0lDT05fQ09MT1IsXG4gICAgICAgIGZvbnRTaXplOiBpY29uPy5mb250U2l6ZSB8fCBQVENhcmRDb21wb25lbnQuREVGQVVMVF9JQ09OX0ZPTlRfU0laRSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBjb2xvcjogUFRDYXJkQ29tcG9uZW50LkRFRkFVTFRfSUNPTl9DT0xPUixcbiAgICAgIGZvbnRTaXplOiBQVENhcmRDb21wb25lbnQuREVGQVVMVF9JQ09OX0ZPTlRfU0laRSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0SWNvblBvc2l0aW9uKCk6ICdsZWZ0JyB8ICdyaWdodCcgfCBudWxsIHtcbiAgICBjb25zdCBpY29uID0gKHRoaXMuY29uZmlnLnRpdGxlIGFzIFRpdGxlU3R5bGUpPy5pY29uO1xuICAgIGlmICh0eXBlb2YgaWNvbiAhPT0gJ3N0cmluZycgJiYgaWNvbj8ucG9zaXRpb24pIHtcbiAgICAgIHJldHVybiBpY29uLnBvc2l0aW9uO1xuICAgIH1cbiAgICByZXR1cm4gUFRDYXJkQ29tcG9uZW50LkRFRkFVTFRfSUNPTl9QT1NJVElPTjtcbiAgfVxuXG4gIGdldE1lbnVQb3NpdGlvbigpOiAnbGVmdCcgfCAncmlnaHQnIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcubWVudVBvc2l0aW9uIHx8IFBUQ2FyZENvbXBvbmVudC5ERUZBVUxUX01FTlVfUE9TSVRJT047XG4gIH1cblxuICBnZXRDYXJkU3R5bGVzKCkge1xuICAgIC8vIFRyYW5zcGFyZW5jeSBmb3IgdGhlIGJhY2tncm91bmQgY29sb3JcbiAgICBjb25zdCBiYWNrZ3JvdW5kVHJhbnNwYXJlbmN5ID0gdGhpcy5jb25maWcudHJhbnNwYXJlbmN5UGVyY2VudGFnZVxuICAgICAgPyBwYXJzZUZsb2F0KHRoaXMuY29uZmlnLnRyYW5zcGFyZW5jeVBlcmNlbnRhZ2UpIC8gMTAwXG4gICAgICA6IDE7XG5cbiAgICAvLyBUcmFuc3BhcmVuY3kgZm9yIHRoZSBwYXR0ZXJuIGltYWdlXG4gICAgY29uc3QgcGF0dGVyblRyYW5zcGFyZW5jeSA9IHRoaXMuY29uZmlnLnBhdHRlcm4/LnRyYW5zcGFyZW5jeVBlcmNlbnRhZ2VcbiAgICAgID8gcGFyc2VGbG9hdCh0aGlzLmNvbmZpZy5wYXR0ZXJuLnRyYW5zcGFyZW5jeVBlcmNlbnRhZ2UpIC8gMTAwXG4gICAgICA6IDE7XG5cbiAgICAvLyBCYWNrZ3JvdW5kIGNvbG9yIHdpdGggdHJhbnNwYXJlbmN5XG4gICAgY29uc3QgYmFja2dyb3VuZENvbG9yID1cbiAgICAgIHRoaXMuY29uZmlnLmJhY2tncm91bmRDb2xvciAmJiB0aGlzLmNvbmZpZy50cmFuc3BhcmVuY3lQZXJjZW50YWdlICE9PSAnMCdcbiAgICAgICAgPyB0aGlzLmhleFRvUmdiYSh0aGlzLmNvbmZpZy5iYWNrZ3JvdW5kQ29sb3IsIGJhY2tncm91bmRUcmFuc3BhcmVuY3kpXG4gICAgICAgIDogJ3RyYW5zcGFyZW50JztcblxuICAgIC8vIFBhdHRlcm4gaW1hZ2Ugd2l0aCB0cmFuc3BhcmVuY3kgYXBwbGllZCB2aWEgbGluZWFyLWdyYWRpZW50XG4gICAgY29uc3QgYmFja2dyb3VuZEltYWdlID1cbiAgICAgIHRoaXMuY29uZmlnLnBhdHRlcm4/LmltYWdlVXJsICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXR0ZXJuLnRyYW5zcGFyZW5jeVBlcmNlbnRhZ2UgIT09ICcwJ1xuICAgICAgICA/IGBsaW5lYXItZ3JhZGllbnQocmdiYSgyNTUsIDI1NSwgMjU1LCAke1xuICAgICAgICAgICAgMSAtIHBhdHRlcm5UcmFuc3BhcmVuY3lcbiAgICAgICAgICB9KSwgcmdiYSgyNTUsIDI1NSwgMjU1LCAkezEgLSBwYXR0ZXJuVHJhbnNwYXJlbmN5fSkpLCB1cmwoJyR7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5wYXR0ZXJuLmltYWdlVXJsXG4gICAgICAgICAgfScpYFxuICAgICAgICA6ICcnO1xuXG4gICAgY29uc3QgcGF0dGVybldpZHRoID0gdGhpcy5jb25maWcucGF0dGVybj8ud2lkdGggfHwgJzEwMCUnO1xuICAgIGNvbnN0IHBhdHRlcm5IZWlnaHQgPSB0aGlzLmNvbmZpZy5wYXR0ZXJuPy5oZWlnaHQgfHwgJ2F1dG8nO1xuXG4gICAgLy8gRGV0ZXJtaW5lIGJhY2tncm91bmQtcmVwZWF0IHZhbHVlXG4gICAgY29uc3QgcmVwZWF0WCA9IHRoaXMuY29uZmlnLnBhdHRlcm4/LnJlcGVhdFggPyAncmVwZWF0JyA6ICduby1yZXBlYXQnO1xuICAgIGNvbnN0IHJlcGVhdFkgPSB0aGlzLmNvbmZpZy5wYXR0ZXJuPy5yZXBlYXRZID8gJ3JlcGVhdCcgOiAnbm8tcmVwZWF0JztcbiAgICBjb25zdCBiYWNrZ3JvdW5kUmVwZWF0ID0gYCR7cmVwZWF0WH0gJHtyZXBlYXRZfWA7XG5cbiAgICAvLyBBZGp1c3QgYmFja2dyb3VuZC1zaXplIGJhc2VkIG9uIHJlcGVhdENvdW50IGlmIHByb3ZpZGVkXG4gICAgY29uc3QgcmVwZWF0Q291bnQgPSB0aGlzLmNvbmZpZy5wYXR0ZXJuPy5yZXBlYXRDb3VudCB8fCAxO1xuICAgIGNvbnN0IGJhY2tncm91bmRTaXplID1cbiAgICAgIHJlcGVhdENvdW50ID4gMVxuICAgICAgICA/IGAke3BhdHRlcm5XaWR0aH0gJHtwYXR0ZXJuSGVpZ2h0fWBcbiAgICAgICAgOiBgJHtwYXR0ZXJuV2lkdGh9ICR7cGF0dGVybkhlaWdodH1gO1xuXG4gICAgLy8gRGV0ZXJtaW5lIGJhY2tncm91bmQtcG9zaXRpb24gYmFzZWQgb24gdGhlIHBvc2l0aW9uIHBhcmFtZXRlclxuICAgIGNvbnN0IGJhY2tncm91bmRQb3NpdGlvbiA9IHRoaXMuY29uZmlnLnBhdHRlcm4/LnBvc2l0aW9uIHx8ICdjZW50ZXInO1xuXG4gICAgY29uc3QganVzdGlmeUNvbnRlbnQgPVxuICAgICAgdGhpcy5jb25maWcuYWxpZ25Db250ZW50ID09PSAnY2VudGVyJyA/ICdjZW50ZXInIDogJ2ZsZXgtc3RhcnQnO1xuXG4gICAgY29uc3QgYWxpZ25JdGVtcyA9XG4gICAgICB0aGlzLmNvbmZpZy5hbGlnbkNvbnRlbnQgPT09ICdjZW50ZXInID8gJ2NlbnRlcicgOiAnc3RyZXRjaCc7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICBqdXN0aWZ5Q29udGVudCwgLy8gQXBwbHkgY29uZGl0aW9uYWwgdmVydGljYWwgYWxpZ25tZW50XG4gICAgICBhbGlnbkl0ZW1zLCAvLyBBcHBseSBjb25kaXRpb25hbCBob3Jpem9udGFsIGFsaWdubWVudFxuICAgICAgYmFja2dyb3VuZENvbG9yLCAvLyBCYWNrZ3JvdW5kIGNvbG9yIHdpdGggdHJhbnNwYXJlbmN5XG4gICAgICBiYWNrZ3JvdW5kSW1hZ2UsIC8vIFBhdHRlcm4gaW1hZ2Ugd2l0aCB0cmFuc3BhcmVuY3lcbiAgICAgIGJhY2tncm91bmRTaXplLFxuICAgICAgYmFja2dyb3VuZFBvc2l0aW9uLFxuICAgICAgYmFja2dyb3VuZFJlcGVhdCxcbiAgICAgIHdpZHRoOiB0aGlzLmNvbmZpZy53aWR0aCB8fCBQVENhcmRDb21wb25lbnQuREVGQVVMVF9XSURUSCxcbiAgICAgIGhlaWdodDogdGhpcy5jb25maWcuaGVpZ2h0IHx8IFBUQ2FyZENvbXBvbmVudC5ERUZBVUxUX0hFSUdIVCxcbiAgICAgIGJvcmRlcjogdGhpcy5jb25maWcubm9Cb3JkZXJcbiAgICAgICAgPyAnbm9uZSdcbiAgICAgICAgOiBgc29saWQgJHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmJvcmRlcldpZHRoIHx8IFBUQ2FyZENvbXBvbmVudC5ERUZBVUxUX0JPUkRFUl9XSURUSFxuICAgICAgICAgIH0gJHt0aGlzLmNvbmZpZy5ib3JkZXJDb2xvciB8fCBQVENhcmRDb21wb25lbnQuREVGQVVMVF9CT1JERVJfQ09MT1J9YCxcbiAgICAgIHBhZGRpbmc6IHRoaXMuY29uZmlnLnBhZGRpbmcgfHwgUFRDYXJkQ29tcG9uZW50LkRFRkFVTFRfUEFERElORyxcbiAgICAgIG1hcmdpbjogdGhpcy5jb25maWcubWFyZ2luIHx8IFBUQ2FyZENvbXBvbmVudC5ERUZBVUxUX01BUkdJTixcbiAgICAgIGJvcmRlclJhZGl1czogdGhpcy5jb25maWcuYm9yZGVyUmFkaXVzIHx8ICc4cHgnLFxuICAgICAgYm94U2hhZG93OiB0aGlzLmNvbmZpZy5ib3hTaGFkb3cgfHwgJzAgMnB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMSknLFxuICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXG4gICAgICB6SW5kZXg6IHRoaXMuY29uZmlnLnpJbmRleCAhPT0gdW5kZWZpbmVkID8gdGhpcy5jb25maWcuekluZGV4IDogJ2F1dG8nLFxuICAgIH07XG4gIH1cblxuICAvLyBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNvbnZlcnQgaGV4IGNvbG9yIHRvIHJnYmFcbiAgcHJpdmF0ZSBoZXhUb1JnYmEoaGV4OiBzdHJpbmcsIGFscGhhOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNob3J0aGFuZFJlZ2V4ID0gL14jPyhbYS1mXFxkXSkoW2EtZlxcZF0pKFthLWZcXGRdKSQvaTtcbiAgICBoZXggPSBoZXgucmVwbGFjZShzaG9ydGhhbmRSZWdleCwgKF8sIHIsIGcsIGIpID0+IHIgKyByICsgZyArIGcgKyBiICsgYik7XG4gICAgY29uc3QgcmVzdWx0ID0gL14jPyhbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pKFthLWZcXGRdezJ9KSQvaS5leGVjKGhleCk7XG4gICAgcmV0dXJuIHJlc3VsdFxuICAgICAgPyBgcmdiYSgke3BhcnNlSW50KHJlc3VsdFsxXSwgMTYpfSwgJHtwYXJzZUludChcbiAgICAgICAgICByZXN1bHRbMl0sXG4gICAgICAgICAgMTZcbiAgICAgICAgKX0sICR7cGFyc2VJbnQocmVzdWx0WzNdLCAxNil9LCAke2FscGhhfSlgXG4gICAgICA6IGhleDtcbiAgfVxuXG4gIGdldEJvZHlTdHlsZXMoKSB7XG4gICAgY29uc3QganVzdGlmeUNvbnRlbnQgPVxuICAgICAgdGhpcy5jb25maWcuYWxpZ25Cb2R5Q29udGVudCA9PT0gJ2NlbnRlcicgPyAnY2VudGVyJyA6ICdmbGV4LXN0YXJ0JztcbiAgICBjb25zdCBhbGlnbkl0ZW1zID1cbiAgICAgIHRoaXMuY29uZmlnLmFsaWduQm9keUNvbnRlbnQgPT09ICdjZW50ZXInID8gJ2NlbnRlcicgOiAnc3RyZXRjaCc7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICBqdXN0aWZ5Q29udGVudCxcbiAgICAgIGFsaWduSXRlbXMsXG4gICAgICBmbGV4R3JvdzogMSxcbiAgICAgIG1heFdpZHRoOiAnMTAwJScsXG4gICAgICBwYWRkaW5nOiAnMTZweCcsIC8vIERlZmF1bHQgcGFkZGluZyBmb3IgYm9keVxuICAgICAgYm94U2l6aW5nOiAnYm9yZGVyLWJveCcsXG4gICAgICBvdmVyZmxvd1g6IHRoaXMuaXNTY3JvbGxhYmxlSG9yaXpvbnRhbCgpID8gJ2F1dG8nIDogJ2hpZGRlbicsXG4gICAgICBvdmVyZmxvd1k6IHRoaXMuaXNTY3JvbGxhYmxlVmVydGljYWwoKSA/ICdhdXRvJyA6ICdoaWRkZW4nLFxuICAgIH07XG4gIH1cblxuICBnZXRIZWFkZXJTdHlsZXMoKSB7XG4gICAgY29uc3QganVzdGlmeUNvbnRlbnQgPVxuICAgICAgdGhpcy5jb25maWcuYWxpZ25IZWFkZXJDb250ZW50ID09PSAnY2VudGVyJyA/ICdjZW50ZXInIDogJ2ZsZXgtc3RhcnQnO1xuICAgIGNvbnN0IGFsaWduSXRlbXMgPVxuICAgICAgdGhpcy5jb25maWcuYWxpZ25IZWFkZXJDb250ZW50ID09PSAnY2VudGVyJyA/ICdjZW50ZXInIDogJ3N0cmV0Y2gnO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgIGp1c3RpZnlDb250ZW50LFxuICAgICAgYWxpZ25JdGVtcyxcbiAgICAgIG1hcmdpbkJvdHRvbTogJzE2cHgnLCAvLyBEZWZhdWx0IG1hcmdpbiBmb3IgaGVhZGVyXG4gICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICB9O1xuICB9XG5cbiAgaXNTY3JvbGxhYmxlSG9yaXpvbnRhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbmZpZy5zY3JvbGxhYmxlSG9yaXpvbnRhbDtcbiAgfVxuXG4gIGlzU2Nyb2xsYWJsZVZlcnRpY2FsKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuY29uZmlnLnNjcm9sbGFibGVWZXJ0aWNhbDtcbiAgfVxuXG4gIGdldENhcmRDbGFzcygpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuYWxpZ25Db250ZW50ID09PSAnY2VudGVyJyA/ICdjZW50ZXItYWxpZ24nIDogJyc7XG4gIH1cblxuICBnZXRCb2R5Q2xhc3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmFsaWduQm9keUNvbnRlbnQgPT09ICdjZW50ZXInID8gJ2NlbnRlci1hbGlnbicgOiAnJztcbiAgfVxuXG4gIGdldEhlYWRlckNsYXNzKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5hbGlnbkhlYWRlckNvbnRlbnQgPT09ICdjZW50ZXInID8gJ2NlbnRlci1hbGlnbicgOiAnJztcbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cInB0LWNhcmQgY2FyZFwiXG4gIFtuZ0NsYXNzXT1cImdldENhcmRDbGFzcygpXCJcbiAgW2F0dHIuaWRdPVwiY29uZmlnLmlkZW50aWZpZXJcIlxuICBbbmdTdHlsZV09XCJnZXRDYXJkU3R5bGVzKClcIlxuPlxuICA8IS0tIENhcmQgSGVhZGVyIC0tPlxuICA8ZGl2XG4gICAgKm5nSWY9XCJoYXNUaXRsZSgpXCJcbiAgICBjbGFzcz1cImNhcmQtaGVhZGVyXCJcbiAgICBbbmdDbGFzc109XCJnZXRIZWFkZXJDbGFzcygpXCJcbiAgICBbbmdTdHlsZV09XCJnZXRIZWFkZXJTdHlsZXMoKVwiXG4gID5cbiAgICA8aVxuICAgICAgKm5nSWY9XCJnZXRJY29uQ2xhc3MoKSAmJiBnZXRJY29uUG9zaXRpb24oKSA9PT0gJ2xlZnQnXCJcbiAgICAgIFtuZ0NsYXNzXT1cImdldEljb25DbGFzcygpXCJcbiAgICAgIFtuZ1N0eWxlXT1cImdldEljb25TdHlsZXMoKVwiXG4gICAgICBjbGFzcz1cImNhcmQtaGVhZGVyLWljb24tbGVmdFwiXG4gICAgPjwvaT5cbiAgICA8c3Bhbj57eyBnZXRUaXRsZVRleHQoKSB9fTwvc3Bhbj5cbiAgICA8aVxuICAgICAgKm5nSWY9XCJnZXRJY29uQ2xhc3MoKSAmJiBnZXRJY29uUG9zaXRpb24oKSA9PT0gJ3JpZ2h0J1wiXG4gICAgICBbbmdDbGFzc109XCJnZXRJY29uQ2xhc3MoKVwiXG4gICAgICBbbmdTdHlsZV09XCJnZXRJY29uU3R5bGVzKClcIlxuICAgICAgY2xhc3M9XCJjYXJkLWhlYWRlci1pY29uLXJpZ2h0XCJcbiAgICA+PC9pPlxuICAgIDxwdC1tZW51XG4gICAgICAqbmdJZj1cImNvbmZpZy5tZW51XCJcbiAgICAgIFtjb25maWddPVwiY29uZmlnLm1lbnVcIlxuICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAnbWVudS1sZWZ0JzogZ2V0TWVudVBvc2l0aW9uKCkgPT09ICdsZWZ0JyxcbiAgICAgICAgJ21lbnUtcmlnaHQnOiBnZXRNZW51UG9zaXRpb24oKSA9PT0gJ3JpZ2h0J1xuICAgICAgfVwiXG4gICAgPjwvcHQtbWVudT5cbiAgPC9kaXY+XG5cbiAgPCEtLSBDYXJkIEJvZHkgLS0+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIiBbbmdDbGFzc109XCJnZXRCb2R5Q2xhc3MoKVwiIFtuZ1N0eWxlXT1cImdldEJvZHlTdHlsZXMoKVwiPlxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==