UNPKG

ngx-obelisco-example

Version:

Componentes funcionales y reutilizables para Angular.

158 lines 30.1 kB
import { Component, Input, ViewContainerRef, ViewChild, HostListener } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class OTabsComponent { constructor(viewContainerRef, renderer, cdr) { this.viewContainerRef = viewContainerRef; this.renderer = renderer; this.cdr = cdr; this.navTabsItems = []; this.isFixedWidth = false; this.isItemsRounded = false; this.isItemsRoundedLight = false; this.size = 'md'; this.isSlidered = false; this.customClasses = ''; this.activeTabComponentRef = null; this.activeTabIndex = null; this.isDragging = false; this.dragStartPositionX = 0; } ngAfterViewInit() { const initialActiveTabIndex = this.navTabsItems.findIndex((tab) => tab.isActive); if (initialActiveTabIndex !== -1) { this.activateTab(initialActiveTabIndex); } this.cdr.detectChanges(); // Agregar event listeners a los botones de flecha const arrowIcons = this.tabsListRef.nativeElement.parentElement.querySelectorAll('.icon'); if (arrowIcons.length >= 2) { arrowIcons[0].addEventListener('click', () => this.handleArrowClick('left')); arrowIcons[1].addEventListener('click', () => this.handleArrowClick('right')); } } handleArrowClick(direction) { const movementX = direction === 'left' ? -340 : 340; const newScrollLeft = this.tabsListRef.nativeElement.scrollLeft + movementX; this.tabsListRef.nativeElement.scrollTo({ left: newScrollLeft, behavior: 'smooth' }); this.handleIcons(newScrollLeft); } activateTab(tabIndex) { if (!this.navTabsItems[tabIndex].isDisabled) { if (this.activeTabIndex !== null) { this.navTabsItems[this.activeTabIndex].isActive = false; } this.activeTabIndex = tabIndex; this.navTabsItems[tabIndex].isActive = true; if (this.activeTabComponentRef) { this.activeTabComponentRef.destroy(); } if (this.navTabsItems[tabIndex].child) { this.activeTabComponentRef = this.viewContainerRef.createComponent(this.navTabsItems[tabIndex].child); } else { this.activeTabComponentRef = null; } } } handleTabClick(tabIndex, event) { this.activateTab(tabIndex); } handleTabKeyup(event, tabIndex) { if (event.key === 'Enter') { this.activateTab(tabIndex); } } // Función para el evento 'mousedown' onMouseDown(event) { const target = event.target; if (target.classList.contains('material-icons-round')) { return; } this.isDragging = true; this.dragStartPositionX = event.clientX; this.renderer.addClass(this.tabsListRef.nativeElement, 'dragging'); this.renderer.setStyle(this.tabsListRef.nativeElement, 'cursor', 'grabbing'); this.renderer.setStyle(document.body, 'user-select', 'none'); } onMouseLeave() { if (this.isDragging) { this.isDragging = false; this.renderer.removeClass(this.tabsListRef.nativeElement, 'dragging'); } } onMouseMove(event) { if (this.isDragging) { const movementX = event.clientX - this.dragStartPositionX; this.dragStartPositionX = event.clientX; this.renderer.setProperty(this.tabsListRef.nativeElement, 'scrollLeft', this.tabsListRef.nativeElement.scrollLeft - movementX); this.handleIcons(this.tabsListRef.nativeElement.scrollLeft); event.preventDefault(); } } // Función para el evento 'mouseup' onMouseUp() { this.isDragging = false; this.renderer.removeClass(this.tabsListRef.nativeElement, 'dragging'); this.renderer.removeStyle(this.tabsListRef.nativeElement, 'cursor'); this.renderer.removeStyle(document.body, 'user-select'); } // Función para mostrar u ocultar las flechas de navegación handleIcons(scrollVal) { const arrowIcons = this.tabsListRef.nativeElement.parentElement.querySelectorAll('.icon'); const maxScrollableWidth = this.tabsListRef.nativeElement.scrollWidth - this.tabsListRef.nativeElement.clientWidth; if (arrowIcons[0]) { arrowIcons[0].style.display = scrollVal <= 0 ? 'none' : 'flex'; } if (arrowIcons[1]) { arrowIcons[1].style.display = maxScrollableWidth - scrollVal <= 1 ? 'none' : 'flex'; } } ngOnDestroy() { if (this.activeTabComponentRef) { this.activeTabComponentRef.destroy(); } } } OTabsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OTabsComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); OTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: OTabsComponent, selector: "o-tabs", inputs: { navTabsItems: "navTabsItems", isFixedWidth: "isFixedWidth", isItemsRounded: "isItemsRounded", isItemsRoundedLight: "isItemsRoundedLight", size: "size", isSlidered: "isSlidered", customClasses: "customClasses" }, host: { listeners: { "mousedown": "onMouseDown($event)", "mouseleave": "onMouseLeave()", "mousemove": "onMouseMove($event)", "mouseup": "onMouseUp()" } }, viewQueries: [{ propertyName: "tabContentContainer", first: true, predicate: ["tabContentContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "tabsListRef", first: true, predicate: ["tabsList"], descendants: true }], ngImport: i0, template: "<nav\r\n [class.tabs-slider]=\"true\"\r\n [class.px-0]=\"!isSlidered\"\r\n [ngClass]=\"customClasses\"\r\n aria-label=\"Navegaci\u00F3n por pesta\u00F1as\"\r\n>\r\n <ul\r\n #tabsList\r\n class=\"nav nav-pills tabs\"\r\n [class.nav-box]=\"isItemsRounded\"\r\n [class.nav-box-bg]=\"isItemsRoundedLight\"\r\n [class.fixedWidth]=\"isFixedWidth\"\r\n >\r\n <li class=\"nav-item\" *ngFor=\"let tab of navTabsItems; let i = index\">\r\n <a\r\n class=\"nav-link\"\r\n [class.active]=\"i === activeTabIndex\"\r\n [class.disabled]=\"tab.isDisabled\"\r\n (click)=\"handleTabClick(i, $event)\"\r\n [ngClass]=\"{\r\n 'nav-link-lg': size === 'lg',\r\n 'nav-link-sm': size === 'sm'\r\n }\"\r\n tabindex=\"0\"\r\n (keyup)=\"handleTabKeyup($event, i)\"\r\n >\r\n <div class=\"nav-icon\">\r\n <ng-container *ngIf=\"tab.icon\">\r\n <ng-container *ngIf=\"tab.icon.includes('bx')\">\r\n <i [ngClass]=\"tab.icon\"></i>\r\n </ng-container>\r\n <ng-container *ngIf=\"!tab.icon.includes('bx')\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">{{ tab.icon }}</span>\r\n </ng-container>\r\n </ng-container>\r\n {{ tab.title }}\r\n <ng-container *ngIf=\"tab.iconRight\">\r\n <ng-container *ngIf=\"tab.icon && tab.icon.includes('bx')\">\r\n <i [ngClass]=\"tab.icon\"></i>\r\n </ng-container>\r\n <ng-container *ngIf=\"tab.icon && !tab.icon.includes('bx')\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">{{ tab.icon }}</span>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n <div class=\"icons-container\" *ngIf=\"isSlidered\">\r\n <button type=\"button\" class=\"right-left icon\" id=\"left\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">arrow_back_ios</span>\r\n </button>\r\n <button type=\"button\" class=\"right-left icon\" id=\"right\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">arrow_forward_ios</span>\r\n </button>\r\n </div>\r\n</nav>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OTabsComponent, decorators: [{ type: Component, args: [{ selector: 'o-tabs', template: "<nav\r\n [class.tabs-slider]=\"true\"\r\n [class.px-0]=\"!isSlidered\"\r\n [ngClass]=\"customClasses\"\r\n aria-label=\"Navegaci\u00F3n por pesta\u00F1as\"\r\n>\r\n <ul\r\n #tabsList\r\n class=\"nav nav-pills tabs\"\r\n [class.nav-box]=\"isItemsRounded\"\r\n [class.nav-box-bg]=\"isItemsRoundedLight\"\r\n [class.fixedWidth]=\"isFixedWidth\"\r\n >\r\n <li class=\"nav-item\" *ngFor=\"let tab of navTabsItems; let i = index\">\r\n <a\r\n class=\"nav-link\"\r\n [class.active]=\"i === activeTabIndex\"\r\n [class.disabled]=\"tab.isDisabled\"\r\n (click)=\"handleTabClick(i, $event)\"\r\n [ngClass]=\"{\r\n 'nav-link-lg': size === 'lg',\r\n 'nav-link-sm': size === 'sm'\r\n }\"\r\n tabindex=\"0\"\r\n (keyup)=\"handleTabKeyup($event, i)\"\r\n >\r\n <div class=\"nav-icon\">\r\n <ng-container *ngIf=\"tab.icon\">\r\n <ng-container *ngIf=\"tab.icon.includes('bx')\">\r\n <i [ngClass]=\"tab.icon\"></i>\r\n </ng-container>\r\n <ng-container *ngIf=\"!tab.icon.includes('bx')\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">{{ tab.icon }}</span>\r\n </ng-container>\r\n </ng-container>\r\n {{ tab.title }}\r\n <ng-container *ngIf=\"tab.iconRight\">\r\n <ng-container *ngIf=\"tab.icon && tab.icon.includes('bx')\">\r\n <i [ngClass]=\"tab.icon\"></i>\r\n </ng-container>\r\n <ng-container *ngIf=\"tab.icon && !tab.icon.includes('bx')\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">{{ tab.icon }}</span>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n <div class=\"icons-container\" *ngIf=\"isSlidered\">\r\n <button type=\"button\" class=\"right-left icon\" id=\"left\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">arrow_back_ios</span>\r\n </button>\r\n <button type=\"button\" class=\"right-left icon\" id=\"right\">\r\n <span class=\"material-icons-round\" aria-hidden=\"true\">arrow_forward_ios</span>\r\n </button>\r\n </div>\r\n</nav>\r\n" }] }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { navTabsItems: [{ type: Input }], isFixedWidth: [{ type: Input }], isItemsRounded: [{ type: Input }], isItemsRoundedLight: [{ type: Input }], size: [{ type: Input }], isSlidered: [{ type: Input }], customClasses: [{ type: Input }], tabContentContainer: [{ type: ViewChild, args: ['tabContentContainer', { read: ViewContainerRef }] }], tabsListRef: [{ type: ViewChild, args: ['tabsList'] }], onMouseDown: [{ type: HostListener, args: ['mousedown', ['$event']] }], onMouseLeave: [{ type: HostListener, args: ['mouseleave'] }], onMouseMove: [{ type: HostListener, args: ['mousemove', ['$event']] }], onMouseUp: [{ type: HostListener, args: ['mouseup'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby10YWJzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1vYmVsaXNjby9uYXYvby10YWJzL28tdGFicy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtb2JlbGlzY28vbmF2L28tdGFicy9vLXRhYnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBRUwsZ0JBQWdCLEVBSWhCLFNBQVMsRUFDVCxZQUFZLEVBR2IsTUFBTSxlQUFlLENBQUM7OztBQVF2QixNQUFNLE9BQU8sY0FBYztJQWlCekIsWUFDVSxnQkFBa0MsRUFDbEMsUUFBbUIsRUFDbkIsR0FBc0I7UUFGdEIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBbkJoQixpQkFBWSxHQUFnQixFQUFFLENBQUM7UUFDL0IsaUJBQVksR0FBWSxLQUFLLENBQUM7UUFDOUIsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFDaEMsd0JBQW1CLEdBQVksS0FBSyxDQUFDO1FBQ3JDLFNBQUksR0FBVSxJQUFJLENBQUM7UUFDbkIsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUM1QixrQkFBYSxHQUFXLEVBQUUsQ0FBQztRQUtwQywwQkFBcUIsR0FBNkIsSUFBSSxDQUFDO1FBQ3ZELG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQUNwQyxlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLHVCQUFrQixHQUFHLENBQUMsQ0FBQztJQU01QixDQUFDO0lBRUosZUFBZTtRQUNiLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRixJ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QztJQUVELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtZQUM5QixJQUFJLENBQUMscUJBQXFCLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDdEM7SUFDSCxDQUFDOzsyR0FwSlUsY0FBYzsrRkFBZCxjQUFjLDhnQkFTaUIsZ0JBQWdCLHVIQzdCNUQsNnRFQTBEQTsyRkR0Q2EsY0FBYztrQkFMMUIsU0FBUzsrQkFDRSxRQUFROytKQUtGLFlBQVk7c0JBQTNCLEtBQUs7Z0JBQ1UsWUFBWTtzQkFBM0IsS0FBSztnQkFDVSxjQUFjO3NCQUE3QixLQUFLO2dCQUNVLG1CQUFtQjtzQkFBbEMsS0FBSztnQkFDVSxJQUFJO3NCQUFuQixLQUFLO2dCQUNVLFVBQVU7c0JBQXpCLEtBQUs7Z0JBQ1UsYUFBYTtzQkFBNUIsS0FBSztnQkFFd0QsbUJBQW1CO3NCQUFoRixTQUFTO3VCQUFDLHFCQUFxQixFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQUNyQyxXQUFXO3NCQUFqQyxTQUFTO3VCQUFDLFVBQVU7Z0JBMEVyQixXQUFXO3NCQURWLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQWdCckMsWUFBWTtzQkFEWCxZQUFZO3VCQUFDLFlBQVk7Z0JBUzFCLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBaUJyQyxTQUFTO3NCQURSLFlBQVk7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIElucHV0LFxyXG4gIENvbXBvbmVudFJlZixcclxuICBWaWV3Q29udGFpbmVyUmVmLFxyXG4gIFJlbmRlcmVyMixcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgVmlld0NoaWxkLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBPbkRlc3Ryb3lcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU2l6ZXMsIFRhYnNQcm9wcyB9IGZyb20gJ25neC1vYmVsaXNjby1leGFtcGxlL2NvcmUvbW9kZWxzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnby10YWJzJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vby10YWJzLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9vLXRhYnMuY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgT1RhYnNDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBuYXZUYWJzSXRlbXM6IFRhYnNQcm9wc1tdID0gW107XHJcbiAgQElucHV0KCkgcHVibGljIGlzRml4ZWRXaWR0aDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBpc0l0ZW1zUm91bmRlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBpc0l0ZW1zUm91bmRlZExpZ2h0OiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcHVibGljIHNpemU6IFNpemVzID0gJ21kJztcclxuICBASW5wdXQoKSBwdWJsaWMgaXNTbGlkZXJlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBjdXN0b21DbGFzc2VzOiBzdHJpbmcgPSAnJztcclxuXHJcbiAgQFZpZXdDaGlsZCgndGFiQ29udGVudENvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KSB0YWJDb250ZW50Q29udGFpbmVyITogVmlld0NvbnRhaW5lclJlZjtcclxuICBAVmlld0NoaWxkKCd0YWJzTGlzdCcpIHRhYnNMaXN0UmVmITogRWxlbWVudFJlZjtcclxuXHJcbiAgcHVibGljIGFjdGl2ZVRhYkNvbXBvbmVudFJlZjogQ29tcG9uZW50UmVmPGFueT4gfCBudWxsID0gbnVsbDtcclxuICBwdWJsaWMgYWN0aXZlVGFiSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gIHByaXZhdGUgZHJhZ1N0YXJ0UG9zaXRpb25YID0gMDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcclxuICApIHt9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGNvbnN0IGluaXRpYWxBY3RpdmVUYWJJbmRleCA9IHRoaXMubmF2VGFic0l0ZW1zLmZpbmRJbmRleCgodGFiKSA9PiB0YWIuaXNBY3RpdmUpO1xyXG4gICAgaWYgKGluaXRpYWxBY3RpdmVUYWJJbmRleCAhPT0gLTEpIHtcclxuICAgICAgdGhpcy5hY3RpdmF0ZVRhYihpbml0aWFsQWN0aXZlVGFiSW5kZXgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuXHJcbiAgICAvLyBBZ3JlZ2FyIGV2ZW50IGxpc3RlbmVycyBhIGxvcyBib3RvbmVzIGRlIGZsZWNoYVxyXG4gICAgY29uc3QgYXJyb3dJY29ucyA9IHRoaXMudGFic0xpc3RSZWYubmF0aXZlRWxlbWVudC5wYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5pY29uJyk7XHJcbiAgICBpZiAoYXJyb3dJY29ucy5sZW5ndGggPj0gMikge1xyXG4gICAgICBhcnJvd0ljb25zWzBdLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGhpcy5oYW5kbGVBcnJvd0NsaWNrKCdsZWZ0JykpO1xyXG4gICAgICBhcnJvd0ljb25zWzFdLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGhpcy5oYW5kbGVBcnJvd0NsaWNrKCdyaWdodCcpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGhhbmRsZUFycm93Q2xpY2soZGlyZWN0aW9uOiAnbGVmdCcgfCAncmlnaHQnKSB7XHJcbiAgICBjb25zdCBtb3ZlbWVudFggPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/IC0zNDAgOiAzNDA7XHJcbiAgICBjb25zdCBuZXdTY3JvbGxMZWZ0ID0gdGhpcy50YWJzTGlzdFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQgKyBtb3ZlbWVudFg7XHJcblxyXG4gICAgdGhpcy50YWJzTGlzdFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbFRvKHtcclxuICAgICAgbGVmdDogbmV3U2Nyb2xsTGVmdCxcclxuICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmhhbmRsZUljb25zKG5ld1Njcm9sbExlZnQpO1xyXG4gIH1cclxuXHJcbiAgYWN0aXZhdGVUYWIodGFiSW5kZXg6IG51bWJlcikge1xyXG4gICAgaWYgKCF0aGlzLm5hdlRhYnNJdGVtc1t0YWJJbmRleF0uaXNEaXNhYmxlZCkge1xyXG4gICAgICBpZiAodGhpcy5hY3RpdmVUYWJJbmRleCAhPT0gbnVsbCkge1xyXG4gICAgICAgIHRoaXMubmF2VGFic0l0ZW1zW3RoaXMuYWN0aXZlVGFiSW5kZXhdLmlzQWN0aXZlID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuYWN0aXZlVGFiSW5kZXggPSB0YWJJbmRleDtcclxuICAgICAgdGhpcy5uYXZUYWJzSXRlbXNbdGFiSW5kZXhdLmlzQWN0aXZlID0gdHJ1ZTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmFjdGl2ZVRhYkNvbXBvbmVudFJlZikge1xyXG4gICAgICAgIHRoaXMuYWN0aXZlVGFiQ29tcG9uZW50UmVmLmRlc3Ryb3koKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHRoaXMubmF2VGFic0l0ZW1zW3RhYkluZGV4XS5jaGlsZCkge1xyXG4gICAgICAgIHRoaXMuYWN0aXZlVGFiQ29tcG9uZW50UmVmID0gdGhpcy52aWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudCh0aGlzLm5hdlRhYnNJdGVtc1t0YWJJbmRleF0uY2hpbGQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuYWN0aXZlVGFiQ29tcG9uZW50UmVmID0gbnVsbDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaGFuZGxlVGFiQ2xpY2sodGFiSW5kZXg6IG51bWJlciwgZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIHRoaXMuYWN0aXZhdGVUYWIodGFiSW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlVGFiS2V5dXAoZXZlbnQ6IEtleWJvYXJkRXZlbnQsIHRhYkluZGV4OiBudW1iZXIpIHtcclxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcclxuICAgICAgdGhpcy5hY3RpdmF0ZVRhYih0YWJJbmRleCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBGdW5jacOzbiBwYXJhIGVsIGV2ZW50byAnbW91c2Vkb3duJ1xyXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZG93bicsIFsnJGV2ZW50J10pXHJcbiAgb25Nb3VzZURvd24oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuICAgIGlmICh0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKCdtYXRlcmlhbC1pY29ucy1yb3VuZCcpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgdGhpcy5kcmFnU3RhcnRQb3NpdGlvblggPSBldmVudC5jbGllbnRYO1xyXG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLnRhYnNMaXN0UmVmLm5hdGl2ZUVsZW1lbnQsICdkcmFnZ2luZycpO1xyXG5cclxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy50YWJzTGlzdFJlZi5uYXRpdmVFbGVtZW50LCAnY3Vyc29yJywgJ2dyYWJiaW5nJyk7XHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKGRvY3VtZW50LmJvZHksICd1c2VyLXNlbGVjdCcsICdub25lJyk7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlJylcclxuICBvbk1vdXNlTGVhdmUoKSB7XHJcbiAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XHJcbiAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMudGFic0xpc3RSZWYubmF0aXZlRWxlbWVudCwgJ2RyYWdnaW5nJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdtb3VzZW1vdmUnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XHJcbiAgICAgIGNvbnN0IG1vdmVtZW50WCA9IGV2ZW50LmNsaWVudFggLSB0aGlzLmRyYWdTdGFydFBvc2l0aW9uWDtcclxuICAgICAgdGhpcy5kcmFnU3RhcnRQb3NpdGlvblggPSBldmVudC5jbGllbnRYO1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KFxyXG4gICAgICAgIHRoaXMudGFic0xpc3RSZWYubmF0aXZlRWxlbWVudCxcclxuICAgICAgICAnc2Nyb2xsTGVmdCcsXHJcbiAgICAgICAgdGhpcy50YWJzTGlzdFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQgLSBtb3ZlbWVudFhcclxuICAgICAgKTtcclxuICAgICAgdGhpcy5oYW5kbGVJY29ucyh0aGlzLnRhYnNMaXN0UmVmLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCk7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBGdW5jacOzbiBwYXJhIGVsIGV2ZW50byAnbW91c2V1cCdcclxuICBASG9zdExpc3RlbmVyKCdtb3VzZXVwJylcclxuICBvbk1vdXNlVXAoKSB7XHJcbiAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcclxuICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy50YWJzTGlzdFJlZi5uYXRpdmVFbGVtZW50LCAnZHJhZ2dpbmcnKTtcclxuXHJcbiAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKHRoaXMudGFic0xpc3RSZWYubmF0aXZlRWxlbWVudCwgJ2N1cnNvcicpO1xyXG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVTdHlsZShkb2N1bWVudC5ib2R5LCAndXNlci1zZWxlY3QnKTtcclxuICB9XHJcblxyXG4gIC8vIEZ1bmNpw7NuIHBhcmEgbW9zdHJhciB1IG9jdWx0YXIgbGFzIGZsZWNoYXMgZGUgbmF2ZWdhY2nDs25cclxuICBwcml2YXRlIGhhbmRsZUljb25zKHNjcm9sbFZhbDogbnVtYmVyKSB7XHJcbiAgICBjb25zdCBhcnJvd0ljb25zID0gdGhpcy50YWJzTGlzdFJlZi5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmljb24nKTtcclxuICAgIGNvbnN0IG1heFNjcm9sbGFibGVXaWR0aCA9IHRoaXMudGFic0xpc3RSZWYubmF0aXZlRWxlbWVudC5zY3JvbGxXaWR0aCAtIHRoaXMudGFic0xpc3RSZWYubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aDtcclxuXHJcbiAgICBpZiAoYXJyb3dJY29uc1swXSkge1xyXG4gICAgICBhcnJvd0ljb25zWzBdLnN0eWxlLmRpc3BsYXkgPSBzY3JvbGxWYWwgPD0gMCA/ICdub25lJyA6ICdmbGV4JztcclxuICAgIH1cclxuICAgIGlmIChhcnJvd0ljb25zWzFdKSB7XHJcbiAgICAgIGFycm93SWNvbnNbMV0uc3R5bGUuZGlzcGxheSA9IG1heFNjcm9sbGFibGVXaWR0aCAtIHNjcm9sbFZhbCA8PSAxID8gJ25vbmUnIDogJ2ZsZXgnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5hY3RpdmVUYWJDb21wb25lbnRSZWYpIHtcclxuICAgICAgdGhpcy5hY3RpdmVUYWJDb21wb25lbnRSZWYuZGVzdHJveSgpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8bmF2XHJcbiAgW2NsYXNzLnRhYnMtc2xpZGVyXT1cInRydWVcIlxyXG4gIFtjbGFzcy5weC0wXT1cIiFpc1NsaWRlcmVkXCJcclxuICBbbmdDbGFzc109XCJjdXN0b21DbGFzc2VzXCJcclxuICBhcmlhLWxhYmVsPVwiTmF2ZWdhY2nDs24gcG9yIHBlc3Rhw7Fhc1wiXHJcbj5cclxuICA8dWxcclxuICAgICN0YWJzTGlzdFxyXG4gICAgY2xhc3M9XCJuYXYgbmF2LXBpbGxzIHRhYnNcIlxyXG4gICAgW2NsYXNzLm5hdi1ib3hdPVwiaXNJdGVtc1JvdW5kZWRcIlxyXG4gICAgW2NsYXNzLm5hdi1ib3gtYmddPVwiaXNJdGVtc1JvdW5kZWRMaWdodFwiXHJcbiAgICBbY2xhc3MuZml4ZWRXaWR0aF09XCJpc0ZpeGVkV2lkdGhcIlxyXG4gID5cclxuICAgIDxsaSBjbGFzcz1cIm5hdi1pdGVtXCIgKm5nRm9yPVwibGV0IHRhYiBvZiBuYXZUYWJzSXRlbXM7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgPGFcclxuICAgICAgICBjbGFzcz1cIm5hdi1saW5rXCJcclxuICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImkgPT09IGFjdGl2ZVRhYkluZGV4XCJcclxuICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwidGFiLmlzRGlzYWJsZWRcIlxyXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVUYWJDbGljayhpLCAkZXZlbnQpXCJcclxuICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAnbmF2LWxpbmstbGcnOiBzaXplID09PSAnbGcnLFxyXG4gICAgICAgICAgJ25hdi1saW5rLXNtJzogc2l6ZSA9PT0gJ3NtJ1xyXG4gICAgICAgIH1cIlxyXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXHJcbiAgICAgICAgKGtleXVwKT1cImhhbmRsZVRhYktleXVwKCRldmVudCwgaSlcIlxyXG4gICAgICA+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm5hdi1pY29uXCI+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFiLmljb25cIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYi5pY29uLmluY2x1ZGVzKCdieCcpXCI+XHJcbiAgICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwidGFiLmljb25cIj48L2k+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXRhYi5pY29uLmluY2x1ZGVzKCdieCcpXCI+XHJcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1pY29ucy1yb3VuZFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPnt7IHRhYi5pY29uIH19PC9zcGFuPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAge3sgdGFiLnRpdGxlIH19XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFiLmljb25SaWdodFwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFiLmljb24gJiYgdGFiLmljb24uaW5jbHVkZXMoJ2J4JylcIj5cclxuICAgICAgICAgICAgICA8aSBbbmdDbGFzc109XCJ0YWIuaWNvblwiPjwvaT5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWIuaWNvbiAmJiAhdGFiLmljb24uaW5jbHVkZXMoJ2J4JylcIj5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLWljb25zLXJvdW5kXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+e3sgdGFiLmljb24gfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvYT5cclxuICAgIDwvbGk+XHJcbiAgPC91bD5cclxuXHJcbiAgPGRpdiBjbGFzcz1cImljb25zLWNvbnRhaW5lclwiICpuZ0lmPVwiaXNTbGlkZXJlZFwiPlxyXG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJyaWdodC1sZWZ0IGljb25cIiBpZD1cImxlZnRcIj5cclxuICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1pY29ucy1yb3VuZFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPmFycm93X2JhY2tfaW9zPC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInJpZ2h0LWxlZnQgaWNvblwiIGlkPVwicmlnaHRcIj5cclxuICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1pY29ucy1yb3VuZFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPmFycm93X2ZvcndhcmRfaW9zPC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvbmF2PlxyXG4iXX0=