cfc-ds
Version:
Design System do Conselho Federal de Contabilidade baseado no govbr-ds
148 lines • 24.4 kB
JavaScript
import { Component } from '@angular/core';
import { NavigationEnd } from '@angular/router';
import { filter } from 'rxjs';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@angular/common";
export class BreadcrumbComponent {
router;
activatedRoute;
/** Lista de breadcrumbs gerados */
links = [];
/** Limite de caracteres para truncamento */
maxLength = 25;
/** Inscrição para monitorar mudanças na rota */
routeSubscription;
constructor(router, activatedRoute) {
this.router = router;
this.activatedRoute = activatedRoute;
}
/** Inicializa o componente e observa mudanças de rota */
ngOnInit() {
this.updateBreadcrumbs();
this.routeSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
this.updateBreadcrumbs();
});
}
/** Atualiza os breadcrumbs com base na rota ativa */
updateBreadcrumbs() {
const breadcrumbs = this.buildBreadcrumbs(this.router.routerState.root);
this.removeLastBreadcrumbUrl(breadcrumbs);
this.links = breadcrumbs;
}
/**
* Constrói os breadcrumbs recursivamente com base nas rotas ativadas.
* @param route Rota ativa.
* @param breadcrumbs Lista de breadcrumbs acumulada.
* @returns Lista de BreadcrumbLink atualizada.
*/
buildBreadcrumbs(route, breadcrumbs = []) {
route.children.forEach((child) => {
const routeSegment = this.getRouteURL(child);
const label = this.getBreadcrumbLabel(child.snapshot.data);
const fullPath = this.buildFullPath(routeSegment, breadcrumbs);
if (label && !this.isDuplicateBreadcrumb(breadcrumbs, label)) {
const truncated = this.shouldTruncate(label) ? this.truncateText(label) : label;
const breadcrumb = {
label: truncated,
url: fullPath,
target: '_self',
};
// Adicionar tooltip apenas se o texto foi truncado
if (truncated !== label) {
breadcrumb.tooltipText = label;
breadcrumb.tooltipPlace = 'top';
breadcrumb.tooltipType = 'info';
}
breadcrumbs.push(breadcrumb);
}
this.buildBreadcrumbs(child, breadcrumbs);
});
return breadcrumbs;
}
/**
* Verifica se o texto deve ser truncado
* @param text Texto para verificar
* @returns true se o texto deve ser truncado
*/
shouldTruncate(text) {
return text.length > this.maxLength;
}
/**
* Trunca o texto para o tamanho máximo definido
* @param text Texto para truncar
* @returns Texto truncado
*/
truncateText(text) {
return text.substring(0, this.maxLength - 3) + '...';
}
/**
* Obtém o texto original para exibição no tooltip
* @param link Item do breadcrumb
* @returns Texto original ou undefined se não houver tooltip
*/
getOriginalText(link) {
return link.tooltipText;
}
/**
* Obtém o segmento da URL da rota atual.
* @param route Rota atual.
* @returns Segmento da URL ou string vazia.
*/
getRouteURL(route) {
return route.snapshot.url.length > 0
? route.snapshot.url.map(segment => segment.path).join('/')
: '';
}
/**
* Constrói o caminho completo concatenando segmentos anteriores.
* @param routeSegment Segmento atual da rota.
* @param breadcrumbs Lista de breadcrumbs acumulada.
* @returns Caminho completo da URL.
*/
buildFullPath(routeSegment, breadcrumbs) {
if (!routeSegment)
return '';
const previousPath = breadcrumbs.length > 0 ? breadcrumbs[breadcrumbs.length - 1].url : '';
return previousPath ? `${previousPath}/${routeSegment}` : `/${routeSegment}`;
}
/**
* Obtém o rótulo do breadcrumb a partir dos dados da rota.
* @param data Dados da rota.
* @returns Rótulo do breadcrumb ou null.
*/
getBreadcrumbLabel(data) {
const label = data['breadcrumb'];
return label && typeof label === 'string' && label.trim() ? label.trim() : null;
}
/**
* Remove a URL do último breadcrumb para evitar que seja clicável.
* @param breadcrumbs Lista de breadcrumbs.
*/
removeLastBreadcrumbUrl(breadcrumbs) {
if (breadcrumbs.length > 0) {
breadcrumbs[breadcrumbs.length - 1].url = undefined;
breadcrumbs[breadcrumbs.length - 1].active = true;
}
}
/**
* Verifica se um breadcrumb já existe na lista para evitar duplicatas.
* @param breadcrumbs Lista de breadcrumbs acumulada.
* @param label Nome do breadcrumb a verificar.
* @returns Verdadeiro se o breadcrumb já existir, falso caso contrário.
*/
isDuplicateBreadcrumb(breadcrumbs, label) {
return breadcrumbs.some(bc => bc.tooltipText === label || bc.label === label);
}
/** Cancela a inscrição ao destruir o componente */
ngOnDestroy() {
this.routeSubscription?.unsubscribe();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BreadcrumbComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BreadcrumbComponent, selector: "cfc-breadcrumb", ngImport: i0, template: "<nav\r\n class=\"br-breadcrumb\"\r\n aria-label=\"Breadcrumbs\">\r\n <ul\r\n class=\"crumb-list\"\r\n style=\"padding-left: 0;\"\r\n role=\"list\">\r\n <li\r\n class=\"crumb\">\r\n <a\r\n class=\"br-button circle\"\r\n href=\"/\"\r\n target=\"_self\">\r\n <i class=\"fas fa-home\"></i>\r\n </a>\r\n </li>\r\n\r\n <li\r\n class=\"crumb\"\r\n *ngFor=\"let link of links; let last = last\">\r\n <i\r\n class=\"icon fas fa-chevron-right\">\r\n </i>\r\n\r\n <a\r\n *ngIf=\"!last\"\r\n [href]=\"link.url\"\r\n [target]=\"link.target\"\r\n [title]=\"link.tooltipText || ''\"\r\n [attr.data-tooltip]=\"link.tooltipText || null\"\r\n [attr.data-tooltip-place]=\"link.tooltipPlace || null\"\r\n [attr.data-tooltip-type]=\"link.tooltipType || null\"\r\n [attr.data-tooltip-timer]=\"link.tooltipTimer || null\">\r\n <span>\r\n {{ link.label | titlecase }}\r\n </span>\r\n </a>\r\n\r\n <span\r\n *ngIf=\"last\"\r\n tabindex=\"0\"\r\n aria-current=\"page\"\r\n [title]=\"link.tooltipText || ''\"\r\n [attr.data-tooltip]=\"link.tooltipText || null\"\r\n [attr.data-tooltip-place]=\"link.tooltipPlace || null\"\r\n [attr.data-tooltip-type]=\"link.tooltipType || null\"\r\n [attr.data-tooltip-timer]=\"link.tooltipTimer || null\">\r\n {{ link.label | titlecase }}\r\n </span>\r\n\r\n </li>\r\n </ul>\r\n</nav>", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BreadcrumbComponent, decorators: [{
type: Component,
args: [{ selector: 'cfc-breadcrumb', template: "<nav\r\n class=\"br-breadcrumb\"\r\n aria-label=\"Breadcrumbs\">\r\n <ul\r\n class=\"crumb-list\"\r\n style=\"padding-left: 0;\"\r\n role=\"list\">\r\n <li\r\n class=\"crumb\">\r\n <a\r\n class=\"br-button circle\"\r\n href=\"/\"\r\n target=\"_self\">\r\n <i class=\"fas fa-home\"></i>\r\n </a>\r\n </li>\r\n\r\n <li\r\n class=\"crumb\"\r\n *ngFor=\"let link of links; let last = last\">\r\n <i\r\n class=\"icon fas fa-chevron-right\">\r\n </i>\r\n\r\n <a\r\n *ngIf=\"!last\"\r\n [href]=\"link.url\"\r\n [target]=\"link.target\"\r\n [title]=\"link.tooltipText || ''\"\r\n [attr.data-tooltip]=\"link.tooltipText || null\"\r\n [attr.data-tooltip-place]=\"link.tooltipPlace || null\"\r\n [attr.data-tooltip-type]=\"link.tooltipType || null\"\r\n [attr.data-tooltip-timer]=\"link.tooltipTimer || null\">\r\n <span>\r\n {{ link.label | titlecase }}\r\n </span>\r\n </a>\r\n\r\n <span\r\n *ngIf=\"last\"\r\n tabindex=\"0\"\r\n aria-current=\"page\"\r\n [title]=\"link.tooltipText || ''\"\r\n [attr.data-tooltip]=\"link.tooltipText || null\"\r\n [attr.data-tooltip-place]=\"link.tooltipPlace || null\"\r\n [attr.data-tooltip-type]=\"link.tooltipType || null\"\r\n [attr.data-tooltip-timer]=\"link.tooltipTimer || null\">\r\n {{ link.label | titlecase }}\r\n </span>\r\n\r\n </li>\r\n </ul>\r\n</nav>" }]
}], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJlYWRjcnVtYi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBQTBCLGFBQWEsRUFBUSxNQUFNLGlCQUFpQixDQUFDO0FBQzlFLE9BQU8sRUFBRSxNQUFNLEVBQWdCLE1BQU0sTUFBTSxDQUFDOzs7O0FBUTVDLE1BQU0sT0FBTyxtQkFBbUI7SUFXcEI7SUFDQTtJQVhWLG1DQUFtQztJQUNuQyxLQUFLLEdBQXFCLEVBQUUsQ0FBQztJQUU3Qiw0Q0FBNEM7SUFDbkMsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUV4QixnREFBZ0Q7SUFDeEMsaUJBQWlCLENBQWdCO0lBRXpDLFlBQ1UsTUFBYyxFQUNkLGNBQThCO1FBRDlCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7SUFDckMsQ0FBQztJQUVKLHlEQUF5RDtJQUN6RCxRQUFRO1FBQ04sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFekIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDOUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxZQUFZLGFBQWEsQ0FBQyxDQUNoRCxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDZixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FB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aUJBQWlCLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDeEMsQ0FBQzt3R0ExSlUsbUJBQW1COzRGQUFuQixtQkFBbUIsc0RDVmhDLCtnREFvRE07OzRGRDFDTyxtQkFBbUI7a0JBTC9CLFNBQVM7K0JBQ0UsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBSb3V0ZXIsIEFjdGl2YXRlZFJvdXRlLCBOYXZpZ2F0aW9uRW5kLCBEYXRhIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgZmlsdGVyLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgQnJlYWRjcnVtYkxpbmsgfSBmcm9tICcuLi8uLi9tb2RlbHMvYnJlYWRjcnVtYi5tb2RlbCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2NmYy1icmVhZGNydW1iJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vYnJlYWRjcnVtYi5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vYnJlYWRjcnVtYi5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBCcmVhZGNydW1iQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIC8qKiBMaXN0YSBkZSBicmVhZGNydW1icyBnZXJhZG9zICovXHJcbiAgbGlua3M6IEJyZWFkY3J1bWJMaW5rW10gPSBbXTtcclxuXHJcbiAgLyoqIExpbWl0ZSBkZSBjYXJhY3RlcmVzIHBhcmEgdHJ1bmNhbWVudG8gKi9cclxuICByZWFkb25seSBtYXhMZW5ndGggPSAyNTtcclxuXHJcbiAgLyoqIEluc2NyacOnw6NvIHBhcmEgbW9uaXRvcmFyIG11ZGFuw6dhcyBuYSByb3RhICovXHJcbiAgcHJpdmF0ZSByb3V0ZVN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxyXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGVcclxuICApIHt9XHJcblxyXG4gIC8qKiBJbmljaWFsaXphIG8gY29tcG9uZW50ZSBlIG9ic2VydmEgbXVkYW7Dp2FzIGRlIHJvdGEgKi9cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMudXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHJcbiAgICB0aGlzLnJvdXRlU3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZXIuZXZlbnRzLnBpcGUoXHJcbiAgICAgIGZpbHRlcihldmVudCA9PiBldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQpXHJcbiAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgIHRoaXMudXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqIEF0dWFsaXphIG9zIGJyZWFkY3J1bWJzIGNvbSBiYXNlIG5hIHJvdGEgYXRpdmEgKi9cclxuICBwcml2YXRlIHVwZGF0ZUJyZWFkY3J1bWJzKCk6IHZvaWQge1xyXG4gICAgY29uc3QgYnJlYWRjcnVtYnMgPSB0aGlzLmJ1aWxkQnJlYWRjcnVtYnModGhpcy5yb3V0ZXIucm91dGVyU3RhdGUucm9vdCk7XHJcbiAgICB0aGlzLnJlbW92ZUxhc3RCcmVhZGNydW1iVXJsKGJyZWFkY3J1bWJzKTtcclxuICAgIHRoaXMubGlua3MgPSBicmVhZGNydW1icztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnN0csOzaSBvcyBicmVhZGNydW1icyByZWN1cnNpdmFtZW50ZSBjb20gYmFzZSBuYXMgcm90YXMgYXRpdmFkYXMuXHJcbiAgICogQHBhcmFtIHJvdXRlIFJvdGEgYXRpdmEuXHJcbiAgICogQHBhcmFtIGJyZWFkY3J1bWJzIExpc3RhIGRlIGJyZWFkY3J1bWJzIGFjdW11bGFkYS5cclxuICAgKiBAcmV0dXJucyBMaXN0YSBkZSBCcmVhZGNydW1iTGluayBhdHVhbGl6YWRhLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgYnVpbGRCcmVhZGNydW1icyhyb3V0ZTogQWN0aXZhdGVkUm91dGUsIGJyZWFkY3J1bWJzOiBCcmVhZGNydW1iTGlua1tdID0gW10pOiBCcmVhZGNydW1iTGlua1tdIHtcclxuICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7XHJcbiAgICAgIGNvbnN0IHJvdXRlU2VnbWVudCA9IHRoaXMuZ2V0Um91dGVVUkwoY2hpbGQpO1xyXG4gICAgICBjb25zdCBsYWJlbCA9IHRoaXMuZ2V0QnJlYWRjcnVtYkxhYmVsKGNoaWxkLnNuYXBzaG90LmRhdGEpO1xyXG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHRoaXMuYnVpbGRGdWxsUGF0aChyb3V0ZVNlZ21lbnQsIGJyZWFkY3J1bWJzKTtcclxuXHJcbiAgICAgIGlmIChsYWJlbCAmJiAhdGhpcy5pc0R1cGxpY2F0ZUJyZWFkY3J1bWIoYnJlYWRjcnVtYnMsIGxhYmVsKSkge1xyXG4gICAgICAgIGNvbnN0IHRydW5jYXRlZCA9IHRoaXMuc2hvdWxkVHJ1bmNhdGUobGFiZWwpID8gdGhpcy50cnVuY2F0ZVRleHQobGFiZWwpIDogbGFiZWw7XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgYnJlYWRjcnVtYjogQnJlYWRjcnVtYkxpbmsgPSB7IFxyXG4gICAgICAgICAgbGFiZWw6IHRydW5jYXRlZCwgXHJcbiAgICAgICAgICB1cmw6IGZ1bGxQYXRoLCBcclxuICAgICAgICAgIHRhcmdldDogJ19zZWxmJyxcclxuICAgICAgICB9O1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIEFkaWNpb25hciB0b29sdGlwIGFwZW5hcyBzZSBvIHRleHRvIGZvaSB0cnVuY2Fkb1xyXG4gICAgICAgIGlmICh0cnVuY2F0ZWQgIT09IGxhYmVsKSB7XHJcbiAgICAgICAgICBicmVhZGNydW1iLnRvb2x0aXBUZXh0ID0gbGFiZWw7XHJcbiAgICAgICAgICBicmVhZGNydW1iLnRvb2x0aXBQbGFjZSA9ICd0b3AnO1xyXG4gICAgICAgICAgYnJlYWRjcnVtYi50b29sdGlwVHlwZSA9ICdpbmZvJztcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgYnJlYWRjcnVtYnMucHVzaChicmVhZGNydW1iKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5idWlsZEJyZWFkY3J1bWJzKGNoaWxkLCBicmVhZGNydW1icyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gYnJlYWRjcnVtYnM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWZXJpZmljYSBzZSBvIHRleHRvIGRldmUgc2VyIHRydW5jYWRvXHJcbiAgICogQHBhcmFtIHRleHQgVGV4dG8gcGFyYSB2ZXJpZmljYXJcclxuICAgKiBAcmV0dXJucyB0cnVlIHNlIG8gdGV4dG8gZGV2ZSBzZXIgdHJ1bmNhZG9cclxuICAgKi9cclxuICBzaG91bGRUcnVuY2F0ZSh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0ZXh0Lmxlbmd0aCA+IHRoaXMubWF4TGVuZ3RoO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJ1bmNhIG8gdGV4dG8gcGFyYSBvIHRhbWFuaG8gbcOheGltbyBkZWZpbmlkb1xyXG4gICAqIEBwYXJhbSB0ZXh0IFRleHRvIHBhcmEgdHJ1bmNhclxyXG4gICAqIEByZXR1cm5zIFRleHRvIHRydW5jYWRvXHJcbiAgICovXHJcbiAgdHJ1bmNhdGVUZXh0KHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGV4dC5zdWJzdHJpbmcoMCwgdGhpcy5tYXhMZW5ndGggLSAzKSArICcuLi4nO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT2J0w6ltIG8gdGV4dG8gb3JpZ2luYWwgcGFyYSBleGliacOnw6NvIG5vIHRvb2x0aXBcclxuICAgKiBAcGFyYW0gbGluayBJdGVtIGRvIGJyZWFkY3J1bWJcclxuICAgKiBAcmV0dXJucyBUZXh0byBvcmlnaW5hbCBvdSB1bmRlZmluZWQgc2UgbsOjbyBob3V2ZXIgdG9vbHRpcFxyXG4gICAqL1xyXG4gIGdldE9yaWdpbmFsVGV4dChsaW5rOiBCcmVhZGNydW1iTGluayk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gbGluay50b29sdGlwVGV4dDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE9idMOpbSBvIHNlZ21lbnRvIGRhIFVSTCBkYSByb3RhIGF0dWFsLlxyXG4gICAqIEBwYXJhbSByb3V0ZSBSb3RhIGF0dWFsLlxyXG4gICAqIEByZXR1cm5zIFNlZ21lbnRvIGRhIFVSTCBvdSBzdHJpbmcgdmF6aWEuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRSb3V0ZVVSTChyb3V0ZTogQWN0aXZhdGVkUm91dGUpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHJvdXRlLnNuYXBzaG90LnVybC5sZW5ndGggPiAwXHJcbiAgICAgID8gcm91dGUuc25hcHNob3QudXJsLm1hcChzZWdtZW50ID0+IHNlZ21lbnQucGF0aCkuam9pbignLycpXHJcbiAgICAgIDogJyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb25zdHLDs2kgbyBjYW1pbmhvIGNvbXBsZXRvIGNvbmNhdGVuYW5kbyBzZWdtZW50b3MgYW50ZXJpb3Jlcy5cclxuICAgKiBAcGFyYW0gcm91dGVTZWdtZW50IFNlZ21lbnRvIGF0dWFsIGRhIHJvdGEuXHJcbiAgICogQHBhcmFtIGJyZWFkY3J1bWJzIExpc3RhIGRlIGJyZWFkY3J1bWJzIGFjdW11bGFkYS5cclxuICAgKiBAcmV0dXJucyBDYW1pbmhvIGNvbXBsZXRvIGRhIFVSTC5cclxuICAgKi9cclxuICBwcml2YXRlIGJ1aWxkRnVsbFBhdGgocm91dGVTZWdtZW50OiBzdHJpbmcsIGJyZWFkY3J1bWJzOiBCcmVhZGNydW1iTGlua1tdKTogc3RyaW5nIHtcclxuICAgIGlmICghcm91dGVTZWdtZW50KSByZXR1cm4gJyc7XHJcbiAgICBjb25zdCBwcmV2aW91c1BhdGggPSBicmVhZGNydW1icy5sZW5ndGggPiAwID8gYnJlYWRjcnVtYnNbYnJlYWRjcnVtYnMubGVuZ3RoIC0gMV0udXJsIDogJyc7XHJcbiAgICByZXR1cm4gcHJldmlvdXNQYXRoID8gYCR7cHJldmlvdXNQYXRofS8ke3JvdXRlU2VnbWVudH1gIDogYC8ke3JvdXRlU2VnbWVudH1gO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT2J0w6ltIG8gcsOzdHVsbyBkbyBicmVhZGNydW1iIGEgcGFydGlyIGRvcyBkYWRvcyBkYSByb3RhLlxyXG4gICAqIEBwYXJhbSBkYXRhIERhZG9zIGRhIHJvdGEuXHJcbiAgICogQHJldHVybnMgUsOzdHVsbyBkbyBicmVhZGNydW1iIG91IG51bGwuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRCcmVhZGNydW1iTGFiZWwoZGF0YTogRGF0YSk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgbGFiZWwgPSBkYXRhWydicmVhZGNydW1iJ107XHJcbiAgICByZXR1cm4gbGFiZWwgJiYgdHlwZW9mIGxhYmVsID09PSAnc3RyaW5nJyAmJiBsYWJlbC50cmltKCkgPyBsYWJlbC50cmltKCkgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlIGEgVVJMIGRvIMO6bHRpbW8gYnJlYWRjcnVtYiBwYXJhIGV2aXRhciBxdWUgc2VqYSBjbGljw6F2ZWwuXHJcbiAgICogQHBhcmFtIGJyZWFkY3J1bWJzIExpc3RhIGRlIGJyZWFkY3J1bWJzLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVtb3ZlTGFzdEJyZWFkY3J1bWJVcmwoYnJlYWRjcnVtYnM6IEJyZWFkY3J1bWJMaW5rW10pOiB2b2lkIHtcclxuICAgIGlmIChicmVhZGNydW1icy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGJyZWFkY3J1bWJzW2JyZWFkY3J1bWJzLmxlbmd0aCAtIDFdLnVybCA9IHVuZGVmaW5lZDtcclxuICAgICAgYnJlYWRjcnVtYnNbYnJlYWRjcnVtYnMubGVuZ3RoIC0gMV0uYWN0aXZlID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFZlcmlmaWNhIHNlIHVtIGJyZWFkY3J1bWIgasOhIGV4aXN0ZSBuYSBsaXN0YSBwYXJhIGV2aXRhciBkdXBsaWNhdGFzLlxyXG4gICAqIEBwYXJhbSBicmVhZGNydW1icyBMaXN0YSBkZSBicmVhZGNydW1icyBhY3VtdWxhZGEuXHJcbiAgICogQHBhcmFtIGxhYmVsIE5vbWUgZG8gYnJlYWRjcnVtYiBhIHZlcmlmaWNhci5cclxuICAgKiBAcmV0dXJucyBWZXJkYWRlaXJvIHNlIG8gYnJlYWRjcnVtYiBqw6EgZXhpc3RpciwgZmFsc28gY2FzbyBjb250csOhcmlvLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgaXNEdXBsaWNhdGVCcmVhZGNydW1iKGJyZWFkY3J1bWJzOiBCcmVhZGNydW1iTGlua1tdLCBsYWJlbDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gYnJlYWRjcnVtYnMuc29tZShiYyA9PiBiYy50b29sdGlwVGV4dCA9PT0gbGFiZWwgfHwgYmMubGFiZWwgPT09IGxhYmVsKTtcclxuICB9XHJcblxyXG4gIC8qKiBDYW5jZWxhIGEgaW5zY3Jpw6fDo28gYW8gZGVzdHJ1aXIgbyBjb21wb25lbnRlICovXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLnJvdXRlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxufSIsIjxuYXZcclxuICBjbGFzcz1cImJyLWJyZWFkY3J1bWJcIlxyXG4gIGFyaWEtbGFiZWw9XCJCcmVhZGNydW1ic1wiPlxyXG4gIDx1bFxyXG4gICAgY2xhc3M9XCJjcnVtYi1saXN0XCJcclxuICAgIHN0eWxlPVwicGFkZGluZy1sZWZ0OiAwO1wiXHJcbiAgICByb2xlPVwibGlzdFwiPlxyXG4gICAgPGxpXHJcbiAgICAgIGNsYXNzPVwiY3J1bWJcIj5cclxuICAgICAgPGFcclxuICAgICAgICBjbGFzcz1cImJyLWJ1dHRvbiBjaXJjbGVcIlxyXG4gICAgICAgIGhyZWY9XCIvXCJcclxuICAgICAgICB0YXJnZXQ9XCJfc2VsZlwiPlxyXG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWhvbWVcIj48L2k+XHJcbiAgICAgIDwvYT5cclxuICAgIDwvbGk+XHJcblxyXG4gICAgPGxpXHJcbiAgICAgIGNsYXNzPVwiY3J1bWJcIlxyXG4gICAgICAqbmdGb3I9XCJsZXQgbGluayBvZiBsaW5rczsgbGV0IGxhc3QgPSBsYXN0XCI+XHJcbiAgICAgIDxpXHJcbiAgICAgICAgY2xhc3M9XCJpY29uIGZhcyBmYS1jaGV2cm9uLXJpZ2h0XCI+XHJcbiAgICAgIDwvaT5cclxuXHJcbiAgICAgIDxhXHJcbiAgICAgICAgKm5nSWY9XCIhbGFzdFwiXHJcbiAgICAgICAgW2hyZWZdPVwibGluay51cmxcIlxyXG4gICAgICAgIFt0YXJnZXRdPVwibGluay50YXJnZXRcIlxyXG4gICAgICAgIFt0aXRsZV09XCJsaW5rLnRvb2x0aXBUZXh0IHx8ICcnXCJcclxuICAgICAgICBbYXR0ci5kYXRhLXRvb2x0aXBdPVwibGluay50b29sdGlwVGV4dCB8fCBudWxsXCJcclxuICAgICAgICBbYXR0ci5kYXRhLXRvb2x0aXAtcGxhY2VdPVwibGluay50b29sdGlwUGxhY2UgfHwgbnVsbFwiXHJcbiAgICAgICAgW2F0dHIuZGF0YS10b29sdGlwLXR5cGVdPVwibGluay50b29sdGlwVHlwZSB8fCBudWxsXCJcclxuICAgICAgICBbYXR0ci5kYXRhLXRvb2x0aXAtdGltZXJdPVwibGluay50b29sdGlwVGltZXIgfHwgbnVsbFwiPlxyXG4gICAgICAgIDxzcGFuPlxyXG4gICAgICAgICAge3sgbGluay5sYWJlbCB8IHRpdGxlY2FzZSB9fVxyXG4gICAgICAgIDwvc3Bhbj5cclxuICAgICAgPC9hPlxyXG5cclxuICAgICAgPHNwYW5cclxuICAgICAgICAqbmdJZj1cImxhc3RcIlxyXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXHJcbiAgICAgICAgYXJpYS1jdXJyZW50PVwicGFnZVwiXHJcbiAgICAgICAgW3RpdGxlXT1cImxpbmsudG9vbHRpcFRleHQgfHwgJydcIlxyXG4gICAgICAgIFthdHRyLmRhdGEtdG9vbHRpcF09XCJsaW5rLnRvb2x0aXBUZXh0IHx8IG51bGxcIlxyXG4gICAgICAgIFthdHRyLmRhdGEtdG9vbHRpcC1wbGFjZV09XCJsaW5rLnRvb2x0aXBQbGFjZSB8fCBudWxsXCJcclxuICAgICAgICBbYXR0ci5kYXRhLXRvb2x0aXAtdHlwZV09XCJsaW5rLnRvb2x0aXBUeXBlIHx8IG51bGxcIlxyXG4gICAgICAgIFthdHRyLmRhdGEtdG9vbHRpcC10aW1lcl09XCJsaW5rLnRvb2x0aXBUaW1lciB8fCBudWxsXCI+XHJcbiAgICAgICAge3sgbGluay5sYWJlbCB8IHRpdGxlY2FzZSB9fVxyXG4gICAgICA8L3NwYW4+XHJcblxyXG4gICAgPC9saT5cclxuICA8L3VsPlxyXG48L25hdj4iXX0=