UNPKG

cfc-ds

Version:

Design System do Conselho Federal de Contabilidade baseado no govbr-ds

159 lines 29.1 kB
import { Component, ContentChild, EventEmitter, Input, Output, ViewChild, } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class UploadComponent { config; files = []; showDownloadButton = true; showRemoveButton = true; filesChanged = new EventEmitter(); fileDownload = new EventEmitter(); fileRemove = new EventEmitter(); get showDefaultActions() { return this.showDownloadButton || this.showRemoveButton; } uploadRoot; fileInput; customActionsTemplate; brUploadInstance; loadInterval; loadTimeout; inputChangeTimeout; onInputChange = () => { this.emitFiles(); }; get acceptedFileTypesString() { return this.config?.acceptedFileTypes?.join(',') || ''; } ngOnInit() { if (!this.config) { console.error('A configuração do componente Upload é obrigatória'); } } ngOnChanges(changes) { // Arquivos salvos são exibidos pela lista customizada no template. } onDownload(file) { this.fileDownload.emit(file); } onRemove(file) { this.fileRemove.emit(file); } ngAfterViewInit() { this.ensureCoreLoaded(); } ngOnDestroy() { this.clearLoadTimer(); this.clearInputChangeTimeout(); this.destroyUpload(); } getCore() { return window.core; } ensureCoreLoaded() { if (typeof window === 'undefined') { return; } if (this.getCore()) { this.initializeUpload(); return; } this.loadInterval = window.setInterval(() => { if (this.getCore()) { this.clearLoadTimer(); this.initializeUpload(); } }, 100); this.loadTimeout = window.setTimeout(() => this.clearLoadTimer(), 10000); } clearLoadTimer() { if (this.loadInterval) { window.clearInterval(this.loadInterval); this.loadInterval = undefined; } if (this.loadTimeout) { window.clearTimeout(this.loadTimeout); this.loadTimeout = undefined; } } clearInputChangeTimeout() { if (this.inputChangeTimeout) { window.clearTimeout(this.inputChangeTimeout); this.inputChangeTimeout = undefined; } } initializeUpload() { const core = this.getCore(); if (!core || !core.BRUpload || !this.uploadRoot) { return; } this.destroyUpload(); const root = this.uploadRoot.nativeElement; try { this.brUploadInstance = new core.BRUpload('br-upload', root, this.uploadTimeout.bind(this)); } catch (error) { console.error('Erro ao inicializar BRUpload', error); return; } this.bindInputEvents(); } uploadTimeout() { this.emitFiles(); return Promise.resolve(); } bindInputEvents() { const input = this.fileInput?.nativeElement; if (!input) { return; } input.addEventListener('change', this.onInputChange); } emitFiles() { this.clearInputChangeTimeout(); const input = this.fileInput?.nativeElement; if (!input) { return; } this.filesChanged.emit(input.files ? Array.from(input.files) : []); } destroyUpload() { const input = this.fileInput?.nativeElement; if (input) { input.removeEventListener('change', this.onInputChange); } if (this.brUploadInstance) { this.brUploadInstance = null; } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: UploadComponent, selector: "cfc-upload", inputs: { config: "config", files: "files", showDownloadButton: "showDownloadButton", showRemoveButton: "showRemoveButton" }, outputs: { filesChanged: "filesChanged", fileDownload: "fileDownload", fileRemove: "fileRemove" }, queries: [{ propertyName: "customActionsTemplate", first: true, predicate: ["customActions"], descendants: true }], viewQueries: [{ propertyName: "uploadRoot", first: true, predicate: ["uploadRoot"], descendants: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"br-upload\" [attr.disabled]=\"config.disabled ? 'disabled' : null\" #uploadRoot>\r\n <label class=\"upload-label\" [for]=\"config.id\">\r\n <span>{{ config.label || 'Envio de arquivo' }}</span>\r\n </label>\r\n <input\r\n class=\"upload-input\"\r\n [id]=\"config.id\"\r\n type=\"file\"\r\n aria-hidden=\"null\"\r\n [attr.aria-label]=\"config.label || 'enviar arquivo'\"\r\n [attr.disabled]=\"config.disabled ? 'disabled' : null\"\r\n [multiple]=\"config.multiple\"\r\n [accept]=\"acceptedFileTypesString\"\r\n #fileInput\r\n />\r\n <div class=\"upload-list\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"files.length > 0\" class=\"upload-saved-list\">\r\n <div *ngFor=\"let file of files\" class=\"upload-saved-item\">\r\n <div class=\"upload-saved-info\">\r\n <a\r\n class=\"upload-saved-name\"\r\n [href]=\"file.url || null\"\r\n [attr.download]=\"file.name\"\r\n target=\"_blank\"\r\n >\r\n {{ file.name }}\r\n </a>\r\n <div *ngIf=\"file.text\" class=\"upload-saved-meta\">\r\n {{ file.text }}\r\n </div>\r\n </div>\r\n <div class=\"upload-saved-actions\">\r\n <span *ngIf=\"file.size\" class=\"upload-saved-size\">{{ file.size }}</span>\r\n <ng-container *ngIf=\"showDefaultActions\">\r\n <a\r\n *ngIf=\"showDownloadButton && file.url\"\r\n class=\"upload-saved-download\"\r\n [href]=\"file.url\"\r\n [attr.download]=\"file.name\"\r\n aria-label=\"Baixar arquivo\"\r\n (click)=\"onDownload(file); $event.stopPropagation()\"\r\n >\r\n <i class=\"fas fa-download\"></i>\r\n </a>\r\n <button\r\n *ngIf=\"showRemoveButton\"\r\n class=\"upload-saved-remove\"\r\n type=\"button\"\r\n aria-label=\"Remover arquivo\"\r\n (click)=\"onRemove(file); $event.stopPropagation()\"\r\n >\r\n <i class=\"fas fa-trash\"></i>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!showDefaultActions\">\r\n <ng-container *ngTemplateOutlet=\"customActionsTemplate; context: { $implicit: file }\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<p *ngIf=\"config.helperText\" class=\"text-base mt-1\">{{ config.helperText }}</p>\r\n", styles: [":host{display:block;width:100%}.br-upload{width:100%}.text-base{color:#555}.upload-saved-list{margin-top:16px;display:flex;flex-direction:column;gap:12px}.upload-saved-item{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff}.upload-saved-info{display:flex;flex-direction:column;gap:4px;min-width:0}.upload-saved-name{color:#06c;font-weight:500;text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.upload-saved-name:hover{text-decoration:underline}.upload-saved-meta{display:flex;flex-wrap:wrap;gap:8px;font-size:12px;color:#666}.upload-saved-profile{color:#333;font-weight:500}.upload-saved-actions{display:flex;align-items:center;gap:12px;flex-shrink:0}.upload-saved-size{font-size:12px;color:#666}.upload-saved-download{color:#06c;font-size:16px;text-decoration:none}.upload-saved-download:hover{color:#004999}.upload-saved-remove{background:none;border:none;color:#dc3545;cursor:pointer;font-size:16px;padding:4px}.upload-saved-remove:hover{color:#b02a37}\n"], dependencies: [{ 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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UploadComponent, decorators: [{ type: Component, args: [{ selector: 'cfc-upload', template: "<div class=\"br-upload\" [attr.disabled]=\"config.disabled ? 'disabled' : null\" #uploadRoot>\r\n <label class=\"upload-label\" [for]=\"config.id\">\r\n <span>{{ config.label || 'Envio de arquivo' }}</span>\r\n </label>\r\n <input\r\n class=\"upload-input\"\r\n [id]=\"config.id\"\r\n type=\"file\"\r\n aria-hidden=\"null\"\r\n [attr.aria-label]=\"config.label || 'enviar arquivo'\"\r\n [attr.disabled]=\"config.disabled ? 'disabled' : null\"\r\n [multiple]=\"config.multiple\"\r\n [accept]=\"acceptedFileTypesString\"\r\n #fileInput\r\n />\r\n <div class=\"upload-list\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"files.length > 0\" class=\"upload-saved-list\">\r\n <div *ngFor=\"let file of files\" class=\"upload-saved-item\">\r\n <div class=\"upload-saved-info\">\r\n <a\r\n class=\"upload-saved-name\"\r\n [href]=\"file.url || null\"\r\n [attr.download]=\"file.name\"\r\n target=\"_blank\"\r\n >\r\n {{ file.name }}\r\n </a>\r\n <div *ngIf=\"file.text\" class=\"upload-saved-meta\">\r\n {{ file.text }}\r\n </div>\r\n </div>\r\n <div class=\"upload-saved-actions\">\r\n <span *ngIf=\"file.size\" class=\"upload-saved-size\">{{ file.size }}</span>\r\n <ng-container *ngIf=\"showDefaultActions\">\r\n <a\r\n *ngIf=\"showDownloadButton && file.url\"\r\n class=\"upload-saved-download\"\r\n [href]=\"file.url\"\r\n [attr.download]=\"file.name\"\r\n aria-label=\"Baixar arquivo\"\r\n (click)=\"onDownload(file); $event.stopPropagation()\"\r\n >\r\n <i class=\"fas fa-download\"></i>\r\n </a>\r\n <button\r\n *ngIf=\"showRemoveButton\"\r\n class=\"upload-saved-remove\"\r\n type=\"button\"\r\n aria-label=\"Remover arquivo\"\r\n (click)=\"onRemove(file); $event.stopPropagation()\"\r\n >\r\n <i class=\"fas fa-trash\"></i>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!showDefaultActions\">\r\n <ng-container *ngTemplateOutlet=\"customActionsTemplate; context: { $implicit: file }\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<p *ngIf=\"config.helperText\" class=\"text-base mt-1\">{{ config.helperText }}</p>\r\n", styles: [":host{display:block;width:100%}.br-upload{width:100%}.text-base{color:#555}.upload-saved-list{margin-top:16px;display:flex;flex-direction:column;gap:12px}.upload-saved-item{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff}.upload-saved-info{display:flex;flex-direction:column;gap:4px;min-width:0}.upload-saved-name{color:#06c;font-weight:500;text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.upload-saved-name:hover{text-decoration:underline}.upload-saved-meta{display:flex;flex-wrap:wrap;gap:8px;font-size:12px;color:#666}.upload-saved-profile{color:#333;font-weight:500}.upload-saved-actions{display:flex;align-items:center;gap:12px;flex-shrink:0}.upload-saved-size{font-size:12px;color:#666}.upload-saved-download{color:#06c;font-size:16px;text-decoration:none}.upload-saved-download:hover{color:#004999}.upload-saved-remove{background:none;border:none;color:#dc3545;cursor:pointer;font-size:16px;padding:4px}.upload-saved-remove:hover{color:#b02a37}\n"] }] }], propDecorators: { config: [{ type: Input }], files: [{ type: Input }], showDownloadButton: [{ type: Input }], showRemoveButton: [{ type: Input }], filesChanged: [{ type: Output }], fileDownload: [{ type: Output }], fileRemove: [{ type: Output }], uploadRoot: [{ type: ViewChild, args: ['uploadRoot', { static: false }] }], fileInput: [{ type: ViewChild, args: ['fileInput', { static: false }] }], customActionsTemplate: [{ type: ContentChild, args: ['customActions', { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NmYy1kcy9zcmMvbGliL2NvbXBvbmVudHMvdXBsb2FkL3VwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL3VwbG9hZC91cGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBRVosWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBR04sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDOzs7QUFtQ3ZCLE1BQU0sT0FBTyxlQUFlO0lBQ2pCLE1BQU0sQ0FBZ0I7SUFDdEIsS0FBSyxHQUFnQixFQUFFLENBQUM7SUFDeEIsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0lBQzFCLGdCQUFnQixHQUFHLElBQUksQ0FBQztJQUN2QixZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztJQUMxQyxZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztJQUM3QyxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztJQUVyRCxJQUFJLGtCQUFrQjtRQUNwQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7SUFDMUQsQ0FBQztJQUUyQyxVQUFVLENBQTJCO0lBQ3RDLFNBQVMsQ0FBZ0M7SUFDbEMscUJBQXFCLENBQW9CO0lBRW5GLGdCQUFnQixDQUFNO0lBQ3RCLFlBQVksQ0FBcUI7SUFDakMsV0FBVyxDQUFxQjtJQUNoQyxrQkFBa0IsQ0FBcUI7SUFDdkMsYUFBYSxHQUFHLEdBQVMsRUFBRTtRQUNqQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbkIsQ0FBQyxDQUFDO0lBRUYsSUFBSSx1QkFBdUI7UUFDekIsT0FBTyxJQUFJLENBQUMs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LElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixLQUFLLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO3dHQXpKVSxlQUFlOzRGQUFmLGVBQWUsK2xCQ3BENUIsMHpFQWdFQTs7NEZEWmEsZUFBZTtrQkFMM0IsU0FBUzsrQkFDRSxZQUFZOzhCQUtiLE1BQU07c0JBQWQsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFNcUMsVUFBVTtzQkFBckQsU0FBUzt1QkFBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUNDLFNBQVM7c0JBQW5ELFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFDUyxxQkFBcUI7c0JBQXRFLFlBQVk7dUJBQUMsZUFBZSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIlxyXG5cclxuXHJcbmltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDb21wb25lbnQsXHJcbiAgQ29udGVudENoaWxkLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIFRlbXBsYXRlUmVmLFxyXG4gIFZpZXdDaGlsZCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVXBsb2FkQ29uZmlnIHtcclxuICBpZDogc3RyaW5nO1xyXG4gIGxhYmVsPzogc3RyaW5nO1xyXG4gIG11bHRpcGxlOiBib29sZWFuO1xyXG4gIGFjY2VwdGVkRmlsZVR5cGVzPzogc3RyaW5nW107XHJcbiAgbWF4RmlsZVNpemU/OiBudW1iZXI7IC8vIGVtIGJ5dGVzXHJcbiAgaGVscGVyVGV4dD86IHN0cmluZztcclxuICByZXF1aXJlZD86IGJvb2xlYW47XHJcbiAgbWF4RmlsZXM/OiBudW1iZXI7XHJcbiAgZGlzYWJsZWQ/OiBib29sZWFuO1xyXG4gIHNob3dGaWxlTGlzdD86IGJvb2xlYW47XHJcbiAgbWVzc2FnZXM/OiB7XHJcbiAgICBzdWNjZXNzPzogc3RyaW5nO1xyXG4gICAgZXJyb3I/OiBzdHJpbmc7XHJcbiAgICBmaWxlVHlwZUVycm9yPzogc3RyaW5nO1xyXG4gICAgZmlsZVNpemVFcnJvcj86IHN0cmluZztcclxuICAgIG1heEZpbGVzRXJyb3I/OiBzdHJpbmc7XHJcbiAgfTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTYXZlZEZpbGUge1xyXG4gIGlkOiBzdHJpbmcgfCBudW1iZXI7XHJcbiAgbmFtZTogc3RyaW5nO1xyXG4gIHNpemU/OiBzdHJpbmcgfCBudW1iZXI7XHJcbiAgdXJsPzogc3RyaW5nO1xyXG4gIHRleHQ/OiBzdHJpbmc7XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnY2ZjLXVwbG9hZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3VwbG9hZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL3VwbG9hZC5jb21wb25lbnQuc2NzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBVcGxvYWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICBASW5wdXQoKSBjb25maWchOiBVcGxvYWRDb25maWc7XHJcbiAgQElucHV0KCkgZmlsZXM6IFNhdmVkRmlsZVtdID0gW107XHJcbiAgQElucHV0KCkgc2hvd0Rvd25sb2FkQnV0dG9uID0gdHJ1ZTtcclxuICBASW5wdXQoKSBzaG93UmVtb3ZlQnV0dG9uID0gdHJ1ZTtcclxuICBAT3V0cHV0KCkgZmlsZXNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxGaWxlW10+KCk7XHJcbiAgQE91dHB1dCgpIGZpbGVEb3dubG9hZCA9IG5ldyBFdmVudEVtaXR0ZXI8U2F2ZWRGaWxlPigpO1xyXG4gIEBPdXRwdXQoKSBmaWxlUmVtb3ZlID0gbmV3IEV2ZW50RW1pdHRlcjxTYXZlZEZpbGU+KCk7XHJcblxyXG4gIGdldCBzaG93RGVmYXVsdEFjdGlvbnMoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5zaG93RG93bmxvYWRCdXR0b24gfHwgdGhpcy5zaG93UmVtb3ZlQnV0dG9uO1xyXG4gIH1cclxuXHJcbiAgQFZpZXdDaGlsZCgndXBsb2FkUm9vdCcsIHsgc3RhdGljOiBmYWxzZSB9KSB1cGxvYWRSb290ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XHJcbiAgQFZpZXdDaGlsZCgnZmlsZUlucHV0JywgeyBzdGF0aWM6IGZhbHNlIH0pIGZpbGVJbnB1dCE6IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XHJcbiAgQENvbnRlbnRDaGlsZCgnY3VzdG9tQWN0aW9ucycsIHsgc3RhdGljOiBmYWxzZSB9KSBjdXN0b21BY3Rpb25zVGVtcGxhdGUhOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG5cclxuICBwcml2YXRlIGJyVXBsb2FkSW5zdGFuY2U6IGFueTtcclxuICBwcml2YXRlIGxvYWRJbnRlcnZhbDogbnVtYmVyIHwgdW5kZWZpbmVkO1xyXG4gIHByaXZhdGUgbG9hZFRpbWVvdXQ6IG51bWJlciB8IHVuZGVmaW5lZDtcclxuICBwcml2YXRlIGlucHV0Q2hhbmdlVGltZW91dDogbnVtYmVyIHwgdW5kZWZpbmVkO1xyXG4gIHByaXZhdGUgb25JbnB1dENoYW5nZSA9ICgpOiB2b2lkID0+IHtcclxuICAgIHRoaXMuZW1pdEZpbGVzKCk7XHJcbiAgfTtcclxuXHJcbiAgZ2V0IGFjY2VwdGVkRmlsZVR5cGVzU3RyaW5nKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWc/LmFjY2VwdGVkRmlsZVR5cGVzPy5qb2luKCcsJykgfHwgJyc7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5jb25maWcpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignQSBjb25maWd1cmHDp8OjbyBkbyBjb21wb25lbnRlIFVwbG9hZCDDqSBvYnJpZ2F0w7NyaWEnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIC8vIEFycXVpdm9zIHNhbHZvcyBzw6NvIGV4aWJpZG9zIHBlbGEgbGlzdGEgY3VzdG9taXphZGEgbm8gdGVtcGxhdGUuXHJcbiAgfVxyXG5cclxuICBvbkRvd25sb2FkKGZpbGU6IFNhdmVkRmlsZSk6IHZvaWQge1xyXG4gICAgdGhpcy5maWxlRG93bmxvYWQuZW1pdChmaWxlKTtcclxuICB9XHJcblxyXG4gIG9uUmVtb3ZlKGZpbGU6IFNhdmVkRmlsZSk6IHZvaWQge1xyXG4gICAgdGhpcy5maWxlUmVtb3ZlLmVtaXQoZmlsZSk7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmVuc3VyZUNvcmVMb2FkZWQoKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5jbGVhckxvYWRUaW1lcigpO1xyXG4gICAgdGhpcy5jbGVhcklucHV0Q2hhbmdlVGltZW91dCgpO1xyXG4gICAgdGhpcy5kZXN0cm95VXBsb2FkKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldENvcmUoKTogYW55IHtcclxuICAgIHJldHVybiAod2luZG93IGFzIGFueSkuY29yZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZW5zdXJlQ29yZUxvYWRlZCgpOiB2b2lkIHtcclxuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuZ2V0Q29yZSgpKSB7XHJcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZVVwbG9hZCgpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5sb2FkSW50ZXJ2YWwgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5nZXRDb3JlKCkpIHtcclxuICAgICAgICB0aGlzLmNsZWFyTG9hZFRpbWVyKCk7XHJcbiAgICAgICAgdGhpcy5pbml0aWFsaXplVXBsb2FkKCk7XHJcbiAgICAgIH1cclxuICAgIH0sIDEwMCk7XHJcblxyXG4gICAgdGhpcy5sb2FkVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHRoaXMuY2xlYXJMb2FkVGltZXIoKSwgMTAwMDApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjbGVhckxvYWRUaW1lcigpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmxvYWRJbnRlcnZhbCkge1xyXG4gICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aGlzLmxvYWRJbnRlcnZhbCk7XHJcbiAgICAgIHRoaXMubG9hZEludGVydmFsID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMubG9hZFRpbWVvdXQpIHtcclxuICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLmxvYWRUaW1lb3V0KTtcclxuICAgICAgdGhpcy5sb2FkVGltZW91dCA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2xlYXJJbnB1dENoYW5nZVRpbWVvdXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5pbnB1dENoYW5nZVRpbWVvdXQpIHtcclxuICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLmlucHV0Q2hhbmdlVGltZW91dCk7XHJcbiAgICAgIHRoaXMuaW5wdXRDaGFuZ2VUaW1lb3V0ID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0aWFsaXplVXBsb2FkKCk6IHZvaWQge1xyXG4gICAgY29uc3QgY29yZSA9IHRoaXMuZ2V0Q29yZSgpO1xyXG4gICAgaWYgKCFjb3JlIHx8ICFjb3JlLkJSVXBsb2FkIHx8ICF0aGlzLnVwbG9hZFJvb3QpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZGVzdHJveVVwbG9hZCgpO1xyXG5cclxuICAgIGNvbnN0IHJvb3QgPSB0aGlzLnVwbG9hZFJvb3QubmF0aXZlRWxlbWVudDtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmJyVXBsb2FkSW5zdGFuY2UgPSBuZXcgY29yZS5CUlVwbG9hZChcclxuICAgICAgICAnYnItdXBsb2FkJyxcclxuICAgICAgICByb290LFxyXG4gICAgICAgIHRoaXMudXBsb2FkVGltZW91dC5iaW5kKHRoaXMpXHJcbiAgICAgICk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvIGFvIGluaWNpYWxpemFyIEJSVXBsb2FkJywgZXJyb3IpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5iaW5kSW5wdXRFdmVudHMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBsb2FkVGltZW91dCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuZW1pdEZpbGVzKCk7XHJcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGJpbmRJbnB1dEV2ZW50cygpOiB2b2lkIHtcclxuICAgIGNvbnN0IGlucHV0ID0gdGhpcy5maWxlSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoIWlucHV0KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMub25JbnB1dENoYW5nZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGVtaXRGaWxlcygpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xlYXJJbnB1dENoYW5nZVRpbWVvdXQoKTtcclxuICAgIGNvbnN0IGlucHV0ID0gdGhpcy5maWxlSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoIWlucHV0KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuZmlsZXNDaGFuZ2VkLmVtaXQoaW5wdXQuZmlsZXMgPyBBcnJheS5mcm9tKGlucHV0LmZpbGVzKSA6IFtdKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZGVzdHJveVVwbG9hZCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGlucHV0ID0gdGhpcy5maWxlSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoaW5wdXQpIHtcclxuICAgICAgaW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5vbklucHV0Q2hhbmdlKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmJyVXBsb2FkSW5zdGFuY2UpIHtcclxuICAgICAgdGhpcy5iclVwbG9hZEluc3RhbmNlID0gbnVsbDtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImJyLXVwbG9hZFwiIFthdHRyLmRpc2FibGVkXT1cImNvbmZpZy5kaXNhYmxlZCA/ICdkaXNhYmxlZCcgOiBudWxsXCIgI3VwbG9hZFJvb3Q+XHJcbiAgPGxhYmVsIGNsYXNzPVwidXBsb2FkLWxhYmVsXCIgW2Zvcl09XCJjb25maWcuaWRcIj5cclxuICAgIDxzcGFuPnt7IGNvbmZpZy5sYWJlbCB8fCAnRW52aW8gZGUgYXJxdWl2bycgfX08L3NwYW4+XHJcbiAgPC9sYWJlbD5cclxuICA8aW5wdXRcclxuICAgIGNsYXNzPVwidXBsb2FkLWlucHV0XCJcclxuICAgIFtpZF09XCJjb25maWcuaWRcIlxyXG4gICAgdHlwZT1cImZpbGVcIlxyXG4gICAgYXJpYS1oaWRkZW49XCJudWxsXCJcclxuICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiY29uZmlnLmxhYmVsIHx8ICdlbnZpYXIgYXJxdWl2bydcIlxyXG4gICAgW2F0dHIuZGlzYWJsZWRdPVwiY29uZmlnLmRpc2FibGVkID8gJ2Rpc2FibGVkJyA6IG51bGxcIlxyXG4gICAgW211bHRpcGxlXT1cImNvbmZpZy5tdWx0aXBsZVwiXHJcbiAgICBbYWNjZXB0XT1cImFjY2VwdGVkRmlsZVR5cGVzU3RyaW5nXCJcclxuICAgICNmaWxlSW5wdXRcclxuICAvPlxyXG4gIDxkaXYgY2xhc3M9XCJ1cGxvYWQtbGlzdFwiPjwvZGl2PlxyXG48L2Rpdj5cclxuXHJcbjxkaXYgKm5nSWY9XCJmaWxlcy5sZW5ndGggPiAwXCIgY2xhc3M9XCJ1cGxvYWQtc2F2ZWQtbGlzdFwiPlxyXG4gIDxkaXYgKm5nRm9yPVwibGV0IGZpbGUgb2YgZmlsZXNcIiBjbGFzcz1cInVwbG9hZC1zYXZlZC1pdGVtXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwidXBsb2FkLXNhdmVkLWluZm9cIj5cclxuICAgICAgPGFcclxuICAgICAgICBjbGFzcz1cInVwbG9hZC1zYXZlZC1uYW1lXCJcclxuICAgICAgICBbaHJlZl09XCJmaWxlLnVybCB8fCBudWxsXCJcclxuICAgICAgICBbYXR0ci5kb3dubG9hZF09XCJmaWxlLm5hbWVcIlxyXG4gICAgICAgIHRhcmdldD1cIl9ibGFua1wiXHJcbiAgICAgID5cclxuICAgICAgICB7eyBmaWxlLm5hbWUgfX1cclxuICAgICAgPC9hPlxyXG4gICAgICA8ZGl2ICpuZ0lmPVwiZmlsZS50ZXh0XCIgY2xhc3M9XCJ1cGxvYWQtc2F2ZWQtbWV0YVwiPlxyXG4gICAgICAgIHt7IGZpbGUudGV4dCB9fVxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cInVwbG9hZC1zYXZlZC1hY3Rpb25zXCI+XHJcbiAgICAgIDxzcGFuICpuZ0lmPVwiZmlsZS5zaXplXCIgY2xhc3M9XCJ1cGxvYWQtc2F2ZWQtc2l6ZVwiPnt7IGZpbGUuc2l6ZSB9fTwvc3Bhbj5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3dEZWZhdWx0QWN0aW9uc1wiPlxyXG4gICAgICAgIDxhXHJcbiAgICAgICAgICAqbmdJZj1cInNob3dEb3dubG9hZEJ1dHRvbiAmJiBmaWxlLnVybFwiXHJcbiAgICAgICAgICBjbGFzcz1cInVwbG9hZC1zYXZlZC1kb3dubG9hZFwiXHJcbiAgICAgICAgICBbaHJlZl09XCJmaWxlLnVybFwiXHJcbiAgICAgICAgICBbYXR0ci5kb3dubG9hZF09XCJmaWxlLm5hbWVcIlxyXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIkJhaXhhciBhcnF1aXZvXCJcclxuICAgICAgICAgIChjbGljayk9XCJvbkRvd25sb2FkKGZpbGUpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWRvd25sb2FkXCI+PC9pPlxyXG4gICAgICAgIDwvYT5cclxuICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAqbmdJZj1cInNob3dSZW1vdmVCdXR0b25cIlxyXG4gICAgICAgICAgY2xhc3M9XCJ1cGxvYWQtc2F2ZWQtcmVtb3ZlXCJcclxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlJlbW92ZXIgYXJxdWl2b1wiXHJcbiAgICAgICAgICAoY2xpY2spPVwib25SZW1vdmUoZmlsZSk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtdHJhc2hcIj48L2k+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXNob3dEZWZhdWx0QWN0aW9uc1wiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjdXN0b21BY3Rpb25zVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBmaWxlIH1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48cCAqbmdJZj1cImNvbmZpZy5oZWxwZXJUZXh0XCIgY2xhc3M9XCJ0ZXh0LWJhc2UgbXQtMVwiPnt7IGNvbmZpZy5oZWxwZXJUZXh0IH19PC9wPlxyXG4iXX0=