cfc-ds
Version:
Design System do Conselho Federal de Contabilidade baseado no govbr-ds
179 lines • 31.3 kB
JavaScript
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/extended";
export class ModalComponent {
elementRef;
isOpen = false;
title;
primaryButtonLabel;
secondaryButtonLabel;
hasCloseButton = true;
closeOnOverlayClick = true;
isLoading = false;
autoCloseTimeout;
maxWidth = '480px';
alignButtons = 'right';
singleButtonCenter = true;
close = new EventEmitter();
primaryClick = new EventEmitter();
secondaryClick = new EventEmitter();
titleElement;
modalContainer;
isTitleOverflowing = false;
fullTitle = '';
autoCloseTimer;
constructor(elementRef) {
this.elementRef = elementRef;
}
ngOnInit() {
if (this.isOpen && this.autoCloseTimeout) {
this.startAutoCloseTimer();
}
}
ngOnChanges(changes) {
if (changes['isOpen'] && changes['isOpen'].currentValue) {
document.body.style.overflow = 'hidden';
if (this.autoCloseTimeout) {
this.startAutoCloseTimer();
}
// Adiciona listener para a tecla ESC
document.addEventListener('keydown', this.handleEscKey);
}
else if (changes['isOpen'] && !changes['isOpen'].currentValue) {
document.body.style.overflow = 'auto';
this.clearAutoCloseTimer();
document.removeEventListener('keydown', this.handleEscKey);
}
// Verifica o título quando ele mudar
if (changes['title'] && this.titleElement) {
this.checkTitleOverflow();
}
}
ngAfterViewInit() {
if (this.title && this.titleElement) {
this.checkTitleOverflow();
}
}
ngOnDestroy() {
document.body.style.overflow = 'auto';
this.clearAutoCloseTimer();
document.removeEventListener('keydown', this.handleEscKey);
}
handleEscKey = (event) => {
if (event.key === 'Escape' && this.isOpen) {
this.onClose();
}
};
onOverlayClick(event) {
if (this.closeOnOverlayClick &&
this.modalContainer &&
!this.modalContainer.nativeElement.contains(event.target)) {
this.onClose();
}
}
onClose() {
this.close.emit();
}
onPrimaryClick() {
this.primaryClick.emit();
}
onSecondaryClick() {
if (this.secondaryClick.observers.length) {
this.secondaryClick.emit();
}
else {
this.onClose();
}
}
getButtonsClass() {
if (this.secondaryButtonLabel && this.primaryButtonLabel) {
return this.alignButtons === 'right' ? 'modal-buttons-right' : 'modal-buttons-center';
}
return this.singleButtonCenter ? 'modal-buttons-center' : 'modal-buttons-right';
}
checkTitleOverflow() {
if (!this.titleElement)
return;
const element = this.titleElement.nativeElement;
this.fullTitle = this.title || '';
// Resetar o conteúdo para o título original para verificar o overflow
element.textContent = this.fullTitle;
if (element.scrollHeight > element.clientHeight ||
element.scrollWidth > element.clientWidth) {
this.isTitleOverflowing = true;
// Truncar o título e adicionar reticências
const words = this.fullTitle.split(' ');
let truncatedTitle = '';
let i = 0;
while (i < words.length) {
const testTitle = truncatedTitle + ' ' + words[i];
element.textContent = testTitle + '...';
if (element.scrollHeight > element.clientHeight ||
element.scrollWidth > element.clientWidth) {
break;
}
truncatedTitle = testTitle;
i++;
}
element.textContent = truncatedTitle.trim() + '...';
}
else {
this.isTitleOverflowing = false;
}
}
startAutoCloseTimer() {
if (this.autoCloseTimeout) {
this.clearAutoCloseTimer();
this.autoCloseTimer = setTimeout(() => {
this.onClose();
}, this.autoCloseTimeout);
}
}
clearAutoCloseTimer() {
if (this.autoCloseTimer) {
clearTimeout(this.autoCloseTimer);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ModalComponent, selector: "cfc-modal", inputs: { isOpen: "isOpen", title: "title", primaryButtonLabel: "primaryButtonLabel", secondaryButtonLabel: "secondaryButtonLabel", hasCloseButton: "hasCloseButton", closeOnOverlayClick: "closeOnOverlayClick", isLoading: "isLoading", autoCloseTimeout: "autoCloseTimeout", maxWidth: "maxWidth", alignButtons: "alignButtons", singleButtonCenter: "singleButtonCenter" }, outputs: { close: "close", primaryClick: "primaryClick", secondaryClick: "secondaryClick" }, viewQueries: [{ propertyName: "titleElement", first: true, predicate: ["modalTitle"], descendants: true }, { propertyName: "modalContainer", first: true, predicate: ["modalContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- modal.component.html -->\r\n<div class=\"modal-overlay\" *ngIf=\"isOpen\" (click)=\"onOverlayClick($event)\">\r\n <div class=\"modal-container\" #modalContainer [style.maxWidth]=\"maxWidth\">\r\n <div class=\"modal-header\" *ngIf=\"title\">\r\n <h3 class=\"modal-title\" \r\n #modalTitle \r\n [attr.title]=\"isTitleOverflowing ? fullTitle : null\">\r\n <!-- O conte\u00FAdo ser\u00E1 gerenciado pelo componente TypeScript -->\r\n </h3>\r\n <button *ngIf=\"hasCloseButton\"\r\n type=\"button\"\r\n class=\"modal-close\"\r\n (click)=\"onClose()\"\r\n aria-label=\"Fechar\">\r\n \u00D7\r\n </button>\r\n </div>\r\n \r\n <div class=\"modal-content\">\r\n <div *ngIf=\"isLoading\" class=\"modal-loading\">\r\n <div class=\"modal-spinner\"></div>\r\n <p>Carregando...</p>\r\n <button class=\"modal-button modal-button-secondary\" (click)=\"onClose()\">\r\n Cancelar\r\n </button>\r\n </div>\r\n <ng-container *ngIf=\"!isLoading\">\r\n <ng-content></ng-content>\r\n \r\n <div *ngIf=\"primaryButtonLabel || secondaryButtonLabel\" \r\n class=\"modal-buttons\" \r\n [ngClass]=\"getButtonsClass()\">\r\n <button *ngIf=\"secondaryButtonLabel\"\r\n type=\"button\"\r\n class=\"modal-button modal-button-secondary\"\r\n (click)=\"onSecondaryClick()\">\r\n {{secondaryButtonLabel}}\r\n </button>\r\n <button *ngIf=\"primaryButtonLabel\"\r\n type=\"button\"\r\n class=\"modal-button modal-button-primary\"\r\n (click)=\"onPrimaryClick()\">\r\n {{primaryButtonLabel}}\r\n </button>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:contents}.modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-container{background-color:#fff;border-radius:4px;box-shadow:0 5px 15px #0003;width:100%;max-width:480px;display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #f0f0f0}.modal-title{margin:0;font-size:18px;font-weight:600;color:#323232;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - 30px);line-height:1.4}.modal-close{background:none;border:none;cursor:pointer;font-size:24px;color:#757575;padding:0;margin:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center}.modal-close:hover{color:#323232}.modal-content{padding:24px;overflow-y:auto;flex-grow:1}.modal-buttons{display:flex;margin-top:24px;gap:12px}.modal-buttons.modal-buttons-right{justify-content:flex-end}.modal-buttons.modal-buttons-center{justify-content:center}.modal-button{padding:8px 24px;border-radius:4px;font-size:14px;font-weight:600;cursor:pointer;transition:all .2s}.modal-button.modal-button-primary{background-color:#0057d8;color:#fff;border:none}.modal-button.modal-button-primary:hover{background-color:#0046af}.modal-button.modal-button-secondary{background-color:transparent;color:#0057d8;border:1px solid #0057D8}.modal-button.modal-button-secondary:hover{background-color:#0057d81a}.modal-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px}.modal-spinner{border:3px solid rgba(0,87,216,.3);border-top:3px solid #0057D8;border-radius:50%;width:36px;height:36px;animation:spin 1s linear infinite;margin-bottom:16px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\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: ModalComponent, decorators: [{
type: Component,
args: [{ selector: 'cfc-modal', template: "<!-- modal.component.html -->\r\n<div class=\"modal-overlay\" *ngIf=\"isOpen\" (click)=\"onOverlayClick($event)\">\r\n <div class=\"modal-container\" #modalContainer [style.maxWidth]=\"maxWidth\">\r\n <div class=\"modal-header\" *ngIf=\"title\">\r\n <h3 class=\"modal-title\" \r\n #modalTitle \r\n [attr.title]=\"isTitleOverflowing ? fullTitle : null\">\r\n <!-- O conte\u00FAdo ser\u00E1 gerenciado pelo componente TypeScript -->\r\n </h3>\r\n <button *ngIf=\"hasCloseButton\"\r\n type=\"button\"\r\n class=\"modal-close\"\r\n (click)=\"onClose()\"\r\n aria-label=\"Fechar\">\r\n \u00D7\r\n </button>\r\n </div>\r\n \r\n <div class=\"modal-content\">\r\n <div *ngIf=\"isLoading\" class=\"modal-loading\">\r\n <div class=\"modal-spinner\"></div>\r\n <p>Carregando...</p>\r\n <button class=\"modal-button modal-button-secondary\" (click)=\"onClose()\">\r\n Cancelar\r\n </button>\r\n </div>\r\n <ng-container *ngIf=\"!isLoading\">\r\n <ng-content></ng-content>\r\n \r\n <div *ngIf=\"primaryButtonLabel || secondaryButtonLabel\" \r\n class=\"modal-buttons\" \r\n [ngClass]=\"getButtonsClass()\">\r\n <button *ngIf=\"secondaryButtonLabel\"\r\n type=\"button\"\r\n class=\"modal-button modal-button-secondary\"\r\n (click)=\"onSecondaryClick()\">\r\n {{secondaryButtonLabel}}\r\n </button>\r\n <button *ngIf=\"primaryButtonLabel\"\r\n type=\"button\"\r\n class=\"modal-button modal-button-primary\"\r\n (click)=\"onPrimaryClick()\">\r\n {{primaryButtonLabel}}\r\n </button>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:contents}.modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-container{background-color:#fff;border-radius:4px;box-shadow:0 5px 15px #0003;width:100%;max-width:480px;display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #f0f0f0}.modal-title{margin:0;font-size:18px;font-weight:600;color:#323232;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - 30px);line-height:1.4}.modal-close{background:none;border:none;cursor:pointer;font-size:24px;color:#757575;padding:0;margin:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center}.modal-close:hover{color:#323232}.modal-content{padding:24px;overflow-y:auto;flex-grow:1}.modal-buttons{display:flex;margin-top:24px;gap:12px}.modal-buttons.modal-buttons-right{justify-content:flex-end}.modal-buttons.modal-buttons-center{justify-content:center}.modal-button{padding:8px 24px;border-radius:4px;font-size:14px;font-weight:600;cursor:pointer;transition:all .2s}.modal-button.modal-button-primary{background-color:#0057d8;color:#fff;border:none}.modal-button.modal-button-primary:hover{background-color:#0046af}.modal-button.modal-button-secondary{background-color:transparent;color:#0057d8;border:1px solid #0057D8}.modal-button.modal-button-secondary:hover{background-color:#0057d81a}.modal-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px}.modal-spinner{border:3px solid rgba(0,87,216,.3);border-top:3px solid #0057D8;border-radius:50%;width:36px;height:36px;animation:spin 1s linear infinite;margin-bottom:16px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { isOpen: [{
type: Input
}], title: [{
type: Input
}], primaryButtonLabel: [{
type: Input
}], secondaryButtonLabel: [{
type: Input
}], hasCloseButton: [{
type: Input
}], closeOnOverlayClick: [{
type: Input
}], isLoading: [{
type: Input
}], autoCloseTimeout: [{
type: Input
}], maxWidth: [{
type: Input
}], alignButtons: [{
type: Input
}], singleButtonCenter: [{
type: Input
}], close: [{
type: Output
}], primaryClick: [{
type: Output
}], secondaryClick: [{
type: Output
}], titleElement: [{
type: ViewChild,
args: ['modalTitle']
}], modalContainer: [{
type: ViewChild,
args: ['modalContainer']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2ZjLWRzL3NyYy9saWIvY29tcG9uZW50cy9tb2RhbC9tb2RhbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL21vZGFsL21vZGFsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBaUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7O0FBVTFKLE1BQU0sT0FBTyxjQUFjO0lBd0JMO0lBdkJYLE1BQU0sR0FBWSxLQUFLLENBQUM7SUFDeEIsS0FBSyxDQUFVO0lBQ2Ysa0JBQWtCLENBQVU7SUFDNUIsb0JBQW9CLENBQVU7SUFDOUIsY0FBYyxHQUFZLElBQUksQ0FBQztJQUMvQixtQkFBbUIsR0FBWSxJQUFJLENBQUM7SUFDcEMsU0FBUyxHQUFZLEtBQUssQ0FBQztJQUMzQixnQkFBZ0IsQ0FBVTtJQUMxQixRQUFRLEdBQVcsT0FBTyxDQUFDO0lBQzNCLFlBQVksR0FBdUIsT0FBTyxDQUFDO0lBQzNDLGtCQUFrQixHQUFZLElBQUksQ0FBQztJQUVsQyxLQUFLLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztJQUNqQyxZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztJQUN4QyxjQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztJQUUzQixZQUFZLENBQWM7SUFDdEIsY0FBYyxDQUFjO0lBRXpELGtCQUFrQixHQUFZLEtBQUssQ0FBQztJQUNwQyxTQUFTLEdBQVcsRUFBRSxDQUFDO0lBQ3ZCLGNBQWMsQ0FBTztJQUVyQixZQUFvQixVQUFzQjtRQUF0QixlQUFVLEdBQVYsVUFBVSxDQUFZO0lBQUcsQ0FBQztJQUU5QyxRQUFRO1FB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QUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUVJLEtBQUs7c0JBQWQsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRWtCLFlBQVk7c0JBQXBDLFNBQVM7dUJBQUMsWUFBWTtnQkFDTSxjQUFjO3NCQUExQyxTQUFTO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTW9kYWxEZW5zaXR5IH0gZnJvbSAnLi4vLi4vZW51bXMvbW9kYWwtZGVuc2l0eS5lbnVtJztcclxuaW1wb3J0IHsgQnV0dG9uVHlwZSB9IGZyb20gJy4uLy4uL2VudW1zL2J1dHRvbi10eXBlLmVudW0nO1xyXG5pbXBvcnQgeyBNb2RhbFR5cGUgfSBmcm9tICcuLi8uLi9lbnVtcy9tb2RhbC10eXBlLmVudW0nO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdjZmMtbW9kYWwnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9tb2RhbC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL21vZGFsLmNvbXBvbmVudC5zY3NzJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgTW9kYWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICBASW5wdXQoKSBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSB0aXRsZT86IHN0cmluZztcclxuICBASW5wdXQoKSBwcmltYXJ5QnV0dG9uTGFiZWw/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgc2Vjb25kYXJ5QnV0dG9uTGFiZWw/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgaGFzQ2xvc2VCdXR0b246IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGNsb3NlT25PdmVybGF5Q2xpY2s6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGlzTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGF1dG9DbG9zZVRpbWVvdXQ/OiBudW1iZXI7XHJcbiAgQElucHV0KCkgbWF4V2lkdGg6IHN0cmluZyA9ICc0ODBweCc7XHJcbiAgQElucHV0KCkgYWxpZ25CdXR0b25zOiAncmlnaHQnIHwgJ2NlbnRlcicgPSAncmlnaHQnO1xyXG4gIEBJbnB1dCgpIHNpbmdsZUJ1dHRvbkNlbnRlcjogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIEBPdXRwdXQoKSBjbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuICBAT3V0cHV0KCkgcHJpbWFyeUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG4gIEBPdXRwdXQoKSBzZWNvbmRhcnlDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnbW9kYWxUaXRsZScpIHRpdGxlRWxlbWVudD86IEVsZW1lbnRSZWY7XHJcbiAgQFZpZXdDaGlsZCgnbW9kYWxDb250YWluZXInKSBtb2RhbENvbnRhaW5lcj86IEVsZW1lbnRSZWY7XHJcblxyXG4gIGlzVGl0bGVPdmVyZmxvd2luZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGZ1bGxUaXRsZTogc3RyaW5nID0gJyc7XHJcbiAgYXV0b0Nsb3NlVGltZXI/OiBhbnk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZikge31cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5pc09wZW4gJiYgdGhpcy5hdXRvQ2xvc2VUaW1lb3V0KSB7XHJcbiAgICAgIHRoaXMuc3RhcnRBdXRvQ2xvc2VUaW1lcigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXNbJ2lzT3BlbiddICYmIGNoYW5nZXNbJ2lzT3BlbiddLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XHJcbiAgICAgIFxyXG4gICAgICBpZiAodGhpcy5hdXRvQ2xvc2VUaW1lb3V0KSB7XHJcbiAgICAgICAgdGhpcy5zdGFydEF1dG9DbG9zZVRpbWVyKCk7XHJcbiAgICAgIH1cclxuICAgICAgXHJcbiAgICAgIC8vIEFkaWNpb25hIGxpc3RlbmVyIHBhcmEgYSB0ZWNsYSBFU0NcclxuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuaGFuZGxlRXNjS2V5KTtcclxuICAgIH0gZWxzZSBpZiAoY2hhbmdlc1snaXNPcGVuJ10gJiYgIWNoYW5nZXNbJ2lzT3BlbiddLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJ2F1dG8nO1xyXG4gICAgICB0aGlzLmNsZWFyQXV0b0Nsb3NlVGltZXIoKTtcclxuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuaGFuZGxlRXNjS2V5KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBWZXJpZmljYSBvIHTDrXR1bG8gcXVhbmRvIGVsZSBtdWRhclxyXG4gICAgaWYgKGNoYW5nZXNbJ3RpdGxlJ10gJiYgdGhpcy50aXRsZUVsZW1lbnQpIHtcclxuICAgICAgdGhpcy5jaGVja1RpdGxlT3ZlcmZsb3coKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnRpdGxlICYmIHRoaXMudGl0bGVFbGVtZW50KSB7XHJcbiAgICAgIHRoaXMuY2hlY2tUaXRsZU92ZXJmbG93KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnYXV0byc7XHJcbiAgICB0aGlzLmNsZWFyQXV0b0Nsb3NlVGltZXIoKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmhhbmRsZUVzY0tleSk7XHJcbiAgfVxyXG5cclxuICBoYW5kbGVFc2NLZXkgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcclxuICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnICYmIHRoaXMuaXNPcGVuKSB7XHJcbiAgICAgIHRoaXMub25DbG9zZSgpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIG9uT3ZlcmxheUNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5jbG9zZU9uT3ZlcmxheUNsaWNrICYmIFxyXG4gICAgICAgIHRoaXMubW9kYWxDb250YWluZXIgJiYgXHJcbiAgICAgICAgIXRoaXMubW9kYWxDb250YWluZXIubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XHJcbiAgICAgIHRoaXMub25DbG9zZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25DbG9zZSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xvc2UuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgb25QcmltYXJ5Q2xpY2soKTogdm9pZCB7XHJcbiAgICB0aGlzLnByaW1hcnlDbGljay5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBvblNlY29uZGFyeUNsaWNrKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuc2Vjb25kYXJ5Q2xpY2sub2JzZXJ2ZXJzLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLnNlY29uZGFyeUNsaWNrLmVtaXQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMub25DbG9zZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0QnV0dG9uc0NsYXNzKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5zZWNvbmRhcnlCdXR0b25MYWJlbCAmJiB0aGlzLnByaW1hcnlCdXR0b25MYWJlbCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5hbGlnbkJ1dHRvbnMgPT09ICdyaWdodCcgPyAnbW9kYWwtYnV0dG9ucy1yaWdodCcgOiAnbW9kYWwtYnV0dG9ucy1jZW50ZXInO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuc2luZ2xlQnV0dG9uQ2VudGVyID8gJ21vZGFsLWJ1dHRvbnMtY2VudGVyJyA6ICdtb2RhbC1idXR0b25zLXJpZ2h0JztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2hlY2tUaXRsZU92ZXJmbG93KCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnRpdGxlRWxlbWVudCkgcmV0dXJuO1xyXG4gICAgXHJcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy50aXRsZUVsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuZnVsbFRpdGxlID0gdGhpcy50aXRsZSB8fCAnJztcclxuICAgIFxyXG4gICAgLy8gUmVzZXRhciBvIGNvbnRlw7pkbyBwYXJhIG8gdMOtdHVsbyBvcmlnaW5hbCBwYXJhIHZlcmlmaWNhciBvIG92ZXJmbG93XHJcbiAgICBlbGVtZW50LnRleHRDb250ZW50ID0gdGhpcy5mdWxsVGl0bGU7XHJcbiAgICBcclxuICAgIGlmIChlbGVtZW50LnNjcm9sbEhlaWdodCA+IGVsZW1lbnQuY2xpZW50SGVpZ2h0IHx8IFxyXG4gICAgICAgIGVsZW1lbnQuc2Nyb2xsV2lkdGggPiBlbGVtZW50LmNsaWVudFdpZHRoKSB7XHJcbiAgICAgIHRoaXMuaXNUaXRsZU92ZXJmbG93aW5nID0gdHJ1ZTtcclxuICAgICAgXHJcbiAgICAgIC8vIFRydW5jYXIgbyB0w610dWxvIGUgYWRpY2lvbmFyIHJldGljw6puY2lhc1xyXG4gICAgICBjb25zdCB3b3JkcyA9IHRoaXMuZnVsbFRpdGxlLnNwbGl0KCcgJyk7XHJcbiAgICAgIGxldCB0cnVuY2F0ZWRUaXRsZSA9ICcnO1xyXG4gICAgICBsZXQgaSA9IDA7XHJcbiAgICAgIFxyXG4gICAgICB3aGlsZSAoaSA8IHdvcmRzLmxlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHRlc3RUaXRsZSA9IHRydW5jYXRlZFRpdGxlICsgJyAnICsgd29yZHNbaV07XHJcbiAgICAgICAgZWxlbWVudC50ZXh0Q29udGVudCA9IHRlc3RUaXRsZSArICcuLi4nO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChlbGVtZW50LnNjcm9sbEhlaWdodCA+IGVsZW1lbnQuY2xpZW50SGVpZ2h0IHx8IFxyXG4gICAgICAgICAgICBlbGVtZW50LnNjcm9sbFdpZHRoID4gZWxlbWVudC5jbGllbnRXaWR0aCkge1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHRydW5jYXRlZFRpdGxlID0gdGVzdFRpdGxlO1xyXG4gICAgICAgIGkrKztcclxuICAgICAgfVxyXG4gICAgICBcclxuICAgICAgZWxlbWVudC50ZXh0Q29udGVudCA9IHRydW5jYXRlZFRpdGxlLnRyaW0oKSArICcuLi4nO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5pc1RpdGxlT3ZlcmZsb3dpbmcgPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3RhcnRBdXRvQ2xvc2VUaW1lcigpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmF1dG9DbG9zZVRpbWVvdXQpIHtcclxuICAgICAgdGhpcy5jbGVhckF1dG9DbG9zZVRpbWVyKCk7XHJcbiAgICAgIHRoaXMuYXV0b0Nsb3NlVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLm9uQ2xvc2UoKTtcclxuICAgICAgfSwgdGhpcy5hdXRvQ2xvc2VUaW1lb3V0KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2xlYXJBdXRvQ2xvc2VUaW1lcigpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmF1dG9DbG9zZVRpbWVyKSB7XHJcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmF1dG9DbG9zZVRpbWVyKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPCEtLSBtb2RhbC5jb21wb25lbnQuaHRtbCAtLT5cclxuPGRpdiBjbGFzcz1cIm1vZGFsLW92ZXJsYXlcIiAqbmdJZj1cImlzT3BlblwiIChjbGljayk9XCJvbk92ZXJsYXlDbGljaygkZXZlbnQpXCI+XHJcbiAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRhaW5lclwiICNtb2RhbENvbnRhaW5lciBbc3R5bGUubWF4V2lkdGhdPVwibWF4V2lkdGhcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIiAqbmdJZj1cInRpdGxlXCI+XHJcbiAgICAgIDxoMyBjbGFzcz1cIm1vZGFsLXRpdGxlXCIgXHJcbiAgICAgICAgICAjbW9kYWxUaXRsZSBcclxuICAgICAgICAgIFthdHRyLnRpdGxlXT1cImlzVGl0bGVPdmVyZmxvd2luZyA/IGZ1bGxUaXRsZSA6IG51bGxcIj5cclxuICAgICAgICA8IS0tIE8gY29udGXDumRvIHNlcsOhIGdlcmVuY2lhZG8gcGVsbyBjb21wb25lbnRlIFR5cGVTY3JpcHQgLS0+XHJcbiAgICAgIDwvaDM+XHJcbiAgICAgIDxidXR0b24gKm5nSWY9XCJoYXNDbG9zZUJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJtb2RhbC1jbG9zZVwiXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xvc2UoKVwiXHJcbiAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIkZlY2hhclwiPlxyXG4gICAgICAgIMOXXHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcbiAgICBcclxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XHJcbiAgICAgIDxkaXYgKm5nSWY9XCJpc0xvYWRpbmdcIiBjbGFzcz1cIm1vZGFsLWxvYWRpbmdcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtc3Bpbm5lclwiPjwvZGl2PlxyXG4gICAgICAgIDxwPkNhcnJlZ2FuZG8uLi48L3A+XHJcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIm1vZGFsLWJ1dHRvbiBtb2RhbC1idXR0b24tc2Vjb25kYXJ5XCIgKGNsaWNrKT1cIm9uQ2xvc2UoKVwiPlxyXG4gICAgICAgICAgQ2FuY2VsYXJcclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkaW5nXCI+XHJcbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG4gICAgICAgIFxyXG4gICAgICAgIDxkaXYgKm5nSWY9XCJwcmltYXJ5QnV0dG9uTGFiZWwgfHwgc2Vjb25kYXJ5QnV0dG9uTGFiZWxcIiBcclxuICAgICAgICAgICAgIGNsYXNzPVwibW9kYWwtYnV0dG9uc1wiIFxyXG4gICAgICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0QnV0dG9uc0NsYXNzKClcIj5cclxuICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzZWNvbmRhcnlCdXR0b25MYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cIm1vZGFsLWJ1dHRvbiBtb2RhbC1idXR0b24tc2Vjb25kYXJ5XCJcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uU2Vjb25kYXJ5Q2xpY2soKVwiPlxyXG4gICAgICAgICAgICB7e3NlY29uZGFyeUJ1dHRvbkxhYmVsfX1cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInByaW1hcnlCdXR0b25MYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cIm1vZGFsLWJ1dHRvbiBtb2RhbC1idXR0b24tcHJpbWFyeVwiXHJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvblByaW1hcnlDbGljaygpXCI+XHJcbiAgICAgICAgICAgIHt7cHJpbWFyeUJ1dHRvbkxhYmVsfX1cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L2Rpdj4iXX0=