cfc-ds
Version:
Design System do Conselho Federal de Contabilidade baseado no govbr-ds
137 lines • 19.8 kB
JavaScript
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/extended";
export class TextareaComponent {
id = 'textarea-' + Math.random().toString(36).slice(2, 8);
label = '';
placeholder = '';
helperText = '';
maxLength = null;
required = false;
isDisabled = false;
resize = 'both';
state = 'default';
showCharCount = false;
rows = 3;
cols = 50;
textChange = new EventEmitter();
value = '';
focused = false;
touched = false;
// Identificadores únicos para acessibilidade
get textareaId() {
return this.id;
}
get countId() {
return this.id + '-count';
}
get helperId() {
return this.id + '-helper';
}
// Define qual rodapé é exibido:
// 'limit' -> com limite e contador (maxLength definido + contador)
// 'counter' -> sem limite e com contador
// 'none' -> padrão (apenas texto auxiliar)
get counterMode() {
if (this.showCharCount && this.maxLength)
return 'limit';
if (this.showCharCount)
return 'counter';
return 'none';
}
get charCount() {
return this.value ? this.value.length : 0;
}
get remainingChars() {
if (!this.maxLength)
return 0;
return this.maxLength - this.charCount;
}
// Configuração de acessibilidade
get ariaDescribedBy() {
const ids = [];
if (this.counterMode === 'none' && this.helperText)
ids.push(this.helperId);
if (this.counterMode === 'limit')
ids.push(this.countId);
return ids.length ? ids.join(' ') : null;
}
ngOnInit() { }
// Implementação de ControlValueAccessor
onChange = () => { };
onTouched = () => { };
writeValue(value) {
this.value = value || '';
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
setDisabledState(isDisabled) {
this.isDisabled = isDisabled;
}
onInput(event) {
this.value = event.target.value;
this.onChange(this.value);
this.textChange.emit(this.value);
}
onBlur() {
this.focused = false;
if (!this.touched) {
this.touched = true;
this.onTouched();
}
}
onFocus() {
this.focused = true;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TextareaComponent, selector: "cfc-textarea", inputs: { id: "id", label: "label", placeholder: "placeholder", helperText: "helperText", maxLength: "maxLength", required: "required", isDisabled: "isDisabled", resize: "resize", state: "state", showCharCount: "showCharCount", rows: "rows", cols: "cols" }, outputs: { textChange: "textChange" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TextareaComponent),
multi: true
}
], ngImport: i0, template: "<!-- textarea.component.html -->\r\n<div class=\"br-textarea\" [ngClass]=\"state\">\r\n <label *ngIf=\"label\" [for]=\"textareaId\">{{ label }}</label>\r\n\r\n <textarea\r\n [id]=\"textareaId\"\r\n [placeholder]=\"placeholder\"\r\n [attr.rows]=\"rows\"\r\n [attr.cols]=\"cols\"\r\n [disabled]=\"isDisabled\"\r\n [style.resize]=\"resize\"\r\n [attr.maxlength]=\"maxLength ? maxLength : null\"\r\n [attr.aria-controls]=\"counterMode === 'limit' ? countId : null\"\r\n [attr.aria-describedby]=\"ariaDescribedBy\"\r\n [attr.aria-required]=\"required\"\r\n [attr.aria-invalid]=\"state === 'error'\"\r\n (input)=\"onInput($event)\"\r\n (blur)=\"onBlur()\"\r\n (focus)=\"onFocus()\"\r\n [value]=\"value\">\r\n </textarea>\r\n\r\n <!-- Padr\u00E3o: texto auxiliar -->\r\n <p *ngIf=\"counterMode === 'none' && helperText\" class=\"text-base mt-1\" [id]=\"helperId\">\r\n {{ helperText }}\r\n </p>\r\n\r\n <!-- Com limite e contador -->\r\n <div *ngIf=\"counterMode === 'limit'\" class=\"text-base mt-1\">\r\n <span class=\"limit\" aria-live=\"polite\">Limite m\u00E1ximo de <strong>{{ maxLength }}</strong> caracteres</span>\r\n <span class=\"current\" aria-live=\"polite\" role=\"status\" [id]=\"countId\">{{ charCount }}/{{ maxLength }}</span>\r\n </div>\r\n\r\n <!-- Sem limite e com contador -->\r\n <div *ngIf=\"counterMode === 'counter'\" class=\"text-base mt-1\">\r\n <span class=\"characters\" aria-live=\"assertive\"><strong>{{ charCount }}</strong> caracteres digitados</span>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}.br-textarea .current{margin-left:8px}\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: i2.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextareaComponent, decorators: [{
type: Component,
args: [{ selector: 'cfc-textarea', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TextareaComponent),
multi: true
}
], template: "<!-- textarea.component.html -->\r\n<div class=\"br-textarea\" [ngClass]=\"state\">\r\n <label *ngIf=\"label\" [for]=\"textareaId\">{{ label }}</label>\r\n\r\n <textarea\r\n [id]=\"textareaId\"\r\n [placeholder]=\"placeholder\"\r\n [attr.rows]=\"rows\"\r\n [attr.cols]=\"cols\"\r\n [disabled]=\"isDisabled\"\r\n [style.resize]=\"resize\"\r\n [attr.maxlength]=\"maxLength ? maxLength : null\"\r\n [attr.aria-controls]=\"counterMode === 'limit' ? countId : null\"\r\n [attr.aria-describedby]=\"ariaDescribedBy\"\r\n [attr.aria-required]=\"required\"\r\n [attr.aria-invalid]=\"state === 'error'\"\r\n (input)=\"onInput($event)\"\r\n (blur)=\"onBlur()\"\r\n (focus)=\"onFocus()\"\r\n [value]=\"value\">\r\n </textarea>\r\n\r\n <!-- Padr\u00E3o: texto auxiliar -->\r\n <p *ngIf=\"counterMode === 'none' && helperText\" class=\"text-base mt-1\" [id]=\"helperId\">\r\n {{ helperText }}\r\n </p>\r\n\r\n <!-- Com limite e contador -->\r\n <div *ngIf=\"counterMode === 'limit'\" class=\"text-base mt-1\">\r\n <span class=\"limit\" aria-live=\"polite\">Limite m\u00E1ximo de <strong>{{ maxLength }}</strong> caracteres</span>\r\n <span class=\"current\" aria-live=\"polite\" role=\"status\" [id]=\"countId\">{{ charCount }}/{{ maxLength }}</span>\r\n </div>\r\n\r\n <!-- Sem limite e com contador -->\r\n <div *ngIf=\"counterMode === 'counter'\" class=\"text-base mt-1\">\r\n <span class=\"characters\" aria-live=\"assertive\"><strong>{{ charCount }}</strong> caracteres digitados</span>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}.br-textarea .current{margin-left:8px}\n"] }]
}], propDecorators: { id: [{
type: Input
}], label: [{
type: Input
}], placeholder: [{
type: Input
}], helperText: [{
type: Input
}], maxLength: [{
type: Input
}], required: [{
type: Input
}], isDisabled: [{
type: Input
}], resize: [{
type: Input
}], state: [{
type: Input
}], showCharCount: [{
type: Input
}], rows: [{
type: Input
}], cols: [{
type: Input
}], textChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2ZjLWRzL3NyYy9saWIvY29tcG9uZW50cy90ZXh0YXJlYS90ZXh0YXJlYS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL3RleHRhcmVhL3RleHRhcmVhLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pGLE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQWN2RSxNQUFNLE9BQU8saUJBQWlCO0lBQ25CLEVBQUUsR0FBRyxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFELEtBQUssR0FBRyxFQUFFLENBQUM7SUFDWCxXQUFXLEdBQUcsRUFBRSxDQUFDO0lBQ2pCLFVBQVUsR0FBRyxFQUFFLENBQUM7SUFDaEIsU0FBUyxHQUFrQixJQUFJLENBQUM7SUFDaEMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUNqQixVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQ25CLE1BQU0sR0FBZ0QsTUFBTSxDQUFDO0lBQzdELEtBQUssR0FBeUQsU0FBUyxDQUFDO0lBQ3hFLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDdEIsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNULElBQUksR0FBRyxFQUFFLENBQUM7SUFFVCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztJQUVsRCxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQ1gsT0FBTyxHQUFHLEtBQUss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Q25CLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7d0dBbEdVLGlCQUFpQjs0RkFBakIsaUJBQWlCLGdWQVJqQjtZQUNUO2dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsaUJBQWlCLENBQUM7Z0JBQ2hELEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRiwwQkNiSCxxaURBc0NBOzs0RkR2QmEsaUJBQWlCO2tCQVo3QixTQUFTOytCQUNFLGNBQWMsYUFHYjt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsQ0FBQzs0QkFDaEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7OEJBR1EsRUFBRTtzQkFBVixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUksVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIGZvcndhcmRSZWYsIElucHV0LCBPbkluaXQsIE91dHB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7Q29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2NmYy10ZXh0YXJlYScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3RleHRhcmVhLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vdGV4dGFyZWEuY29tcG9uZW50LnNjc3MnLFxyXG4gIHByb3ZpZGVyczogW1xyXG4gICAge1xyXG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gVGV4dGFyZWFDb21wb25lbnQpLFxyXG4gICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgfVxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFRleHRhcmVhQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCAge1xyXG4gIEBJbnB1dCgpIGlkID0gJ3RleHRhcmVhLScgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KTtcclxuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyID0gJyc7XHJcbiAgQElucHV0KCkgaGVscGVyVGV4dCA9ICcnO1xyXG4gIEBJbnB1dCgpIG1heExlbmd0aDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgQElucHV0KCkgcmVxdWlyZWQgPSBmYWxzZTtcclxuICBASW5wdXQoKSBpc0Rpc2FibGVkID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcmVzaXplOiAnYm90aCcgfCAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnIHwgJ25vbmUnID0gJ2JvdGgnO1xyXG4gIEBJbnB1dCgpIHN0YXRlOiAnZGVmYXVsdCcgfCAnZXJyb3InIHwgJ3N1Y2Nlc3MnIHwgJ3dhcm5pbmcnIHwgJ2luZm8nID0gJ2RlZmF1bHQnO1xyXG4gIEBJbnB1dCgpIHNob3dDaGFyQ291bnQgPSBmYWxzZTtcclxuICBASW5wdXQoKSByb3dzID0gMztcclxuICBASW5wdXQoKSBjb2xzID0gNTA7XHJcblxyXG4gIEBPdXRwdXQoKSB0ZXh0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gIHZhbHVlID0gJyc7XHJcbiAgZm9jdXNlZCA9IGZhbHNlO1xyXG4gIHRvdWNoZWQgPSBmYWxzZTtcclxuXHJcbiAgLy8gSWRlbnRpZmljYWRvcmVzIMO6bmljb3MgcGFyYSBhY2Vzc2liaWxpZGFkZVxyXG4gIGdldCB0ZXh0YXJlYUlkKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5pZDtcclxuICB9XHJcblxyXG4gIGdldCBjb3VudElkKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5pZCArICctY291bnQnO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGhlbHBlcklkKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5pZCArICctaGVscGVyJztcclxuICB9XHJcblxyXG4gIC8vIERlZmluZSBxdWFsIHJvZGFww6kgw6kgZXhpYmlkbzpcclxuICAvLyAnbGltaXQnICAgLT4gY29tIGxpbWl0ZSBlIGNvbnRhZG9yIChtYXhMZW5ndGggZGVmaW5pZG8gKyBjb250YWRvcilcclxuICAvLyAnY291bnRlcicgLT4gc2VtIGxpbWl0ZSBlIGNvbSBjb250YWRvclxyXG4gIC8vICdub25lJyAgICAtPiBwYWRyw6NvIChhcGVuYXMgdGV4dG8gYXV4aWxpYXIpXHJcbiAgZ2V0IGNvdW50ZXJNb2RlKCk6ICdsaW1pdCcgfCAnY291bnRlcicgfCAnbm9uZScge1xyXG4gICAgaWYgKHRoaXMuc2hvd0NoYXJDb3VudCAmJiB0aGlzLm1heExlbmd0aCkgcmV0dXJuICdsaW1pdCc7XHJcbiAgICBpZiAodGhpcy5zaG93Q2hhckNvdW50KSByZXR1cm4gJ2NvdW50ZXInO1xyXG4gICAgcmV0dXJuICdub25lJztcclxuICB9XHJcblxyXG4gIGdldCBjaGFyQ291bnQoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLnZhbHVlID8gdGhpcy52YWx1ZS5sZW5ndGggOiAwO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHJlbWFpbmluZ0NoYXJzKCk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRoaXMubWF4TGVuZ3RoKSByZXR1cm4gMDtcclxuICAgIHJldHVybiB0aGlzLm1heExlbmd0aCAtIHRoaXMuY2hhckNvdW50O1xyXG4gIH1cclxuXHJcbiAgLy8gQ29uZmlndXJhw6fDo28gZGUgYWNlc3NpYmlsaWRhZGVcclxuICBnZXQgYXJpYURlc2NyaWJlZEJ5KCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgaWRzOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgaWYgKHRoaXMuY291bnRlck1vZGUgPT09ICdub25lJyAmJiB0aGlzLmhlbHBlclRleHQpIGlkcy5wdXNoKHRoaXMuaGVscGVySWQpO1xyXG4gICAgaWYgKHRoaXMuY291bnRlck1vZGUgPT09ICdsaW1pdCcpIGlkcy5wdXNoKHRoaXMuY291bnRJZCk7XHJcbiAgICByZXR1cm4gaWRzLmxlbmd0aCA/IGlkcy5qb2luKCcgJykgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7fVxyXG5cclxuICAvLyBJbXBsZW1lbnRhw6fDo28gZGUgQ29udHJvbFZhbHVlQWNjZXNzb3JcclxuICBvbkNoYW5nZTogYW55ID0gKCkgPT4ge307XHJcbiAgb25Ub3VjaGVkOiBhbnkgPSAoKSA9PiB7fTtcclxuXHJcbiAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLnZhbHVlID0gdmFsdWUgfHwgJyc7XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XHJcbiAgfVxyXG5cclxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuaXNEaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XHJcbiAgfVxyXG5cclxuICBvbklucHV0KGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMudmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XHJcbiAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudmFsdWUpO1xyXG4gICAgdGhpcy50ZXh0Q2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBvbkJsdXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcclxuICAgIGlmICghdGhpcy50b3VjaGVkKSB7XHJcbiAgICAgIHRoaXMudG91Y2hlZCA9IHRydWU7XHJcbiAgICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbkZvY3VzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5mb2N1c2VkID0gdHJ1ZTtcclxuICB9XHJcbn1cclxuIiwiPCEtLSB0ZXh0YXJlYS5jb21wb25lbnQuaHRtbCAtLT5cclxuPGRpdiBjbGFzcz1cImJyLXRleHRhcmVhXCIgW25nQ2xhc3NdPVwic3RhdGVcIj5cclxuICA8bGFiZWwgKm5nSWY9XCJsYWJlbFwiIFtmb3JdPVwidGV4dGFyZWFJZFwiPnt7IGxhYmVsIH19PC9sYWJlbD5cclxuXHJcbiAgPHRleHRhcmVhXHJcbiAgICBbaWRdPVwidGV4dGFyZWFJZFwiXHJcbiAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxyXG4gICAgW2F0dHIucm93c109XCJyb3dzXCJcclxuICAgIFthdHRyLmNvbHNdPVwiY29sc1wiXHJcbiAgICBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiXHJcbiAgICBbc3R5bGUucmVzaXplXT1cInJlc2l6ZVwiXHJcbiAgICBbYXR0ci5tYXhsZW5ndGhdPVwibWF4TGVuZ3RoID8gbWF4TGVuZ3RoIDogbnVsbFwiXHJcbiAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImNvdW50ZXJNb2RlID09PSAnbGltaXQnID8gY291bnRJZCA6IG51bGxcIlxyXG4gICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJhcmlhRGVzY3JpYmVkQnlcIlxyXG4gICAgW2F0dHIuYXJpYS1yZXF1aXJlZF09XCJyZXF1aXJlZFwiXHJcbiAgICBbYXR0ci5hcmlhLWludmFsaWRdPVwic3RhdGUgPT09ICdlcnJvcidcIlxyXG4gICAgKGlucHV0KT1cIm9uSW5wdXQoJGV2ZW50KVwiXHJcbiAgICAoYmx1cik9XCJvbkJsdXIoKVwiXHJcbiAgICAoZm9jdXMpPVwib25Gb2N1cygpXCJcclxuICAgIFt2YWx1ZV09XCJ2YWx1ZVwiPlxyXG4gIDwvdGV4dGFyZWE+XHJcblxyXG4gIDwhLS0gUGFkcsOjbzogdGV4dG8gYXV4aWxpYXIgLS0+XHJcbiAgPHAgKm5nSWY9XCJjb3VudGVyTW9kZSA9PT0gJ25vbmUnICYmIGhlbHBlclRleHRcIiBjbGFzcz1cInRleHQtYmFzZSBtdC0xXCIgW2lkXT1cImhlbHBlcklkXCI+XHJcbiAgICB7eyBoZWxwZXJUZXh0IH19XHJcbiAgPC9wPlxyXG5cclxuICA8IS0tIENvbSBsaW1pdGUgZSBjb250YWRvciAtLT5cclxuICA8ZGl2ICpuZ0lmPVwiY291bnRlck1vZGUgPT09ICdsaW1pdCdcIiBjbGFzcz1cInRleHQtYmFzZSBtdC0xXCI+XHJcbiAgICA8c3BhbiBjbGFzcz1cImxpbWl0XCIgYXJpYS1saXZlPVwicG9saXRlXCI+TGltaXRlIG3DoXhpbW8gZGUgPHN0cm9uZz57eyBtYXhMZW5ndGggfX08L3N0cm9uZz4gY2FyYWN0ZXJlczwvc3Bhbj5cclxuICAgIDxzcGFuIGNsYXNzPVwiY3VycmVudFwiIGFyaWEtbGl2ZT1cInBvbGl0ZVwiIHJvbGU9XCJzdGF0dXNcIiBbaWRdPVwiY291bnRJZFwiPnt7IGNoYXJDb3VudCB9fS97eyBtYXhMZW5ndGggfX08L3NwYW4+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gU2VtIGxpbWl0ZSBlIGNvbSBjb250YWRvciAtLT5cclxuICA8ZGl2ICpuZ0lmPVwiY291bnRlck1vZGUgPT09ICdjb3VudGVyJ1wiIGNsYXNzPVwidGV4dC1iYXNlIG10LTFcIj5cclxuICAgIDxzcGFuIGNsYXNzPVwiY2hhcmFjdGVyc1wiIGFyaWEtbGl2ZT1cImFzc2VydGl2ZVwiPjxzdHJvbmc+e3sgY2hhckNvdW50IH19PC9zdHJvbmc+IGNhcmFjdGVyZXMgZGlnaXRhZG9zPC9zcGFuPlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxuIl19