UNPKG

lamb-web-lib

Version:

LambWebLib. Es un proyecto angular de tipo Librería. que contiene una Suit de componentes reutilizables para el proyecto [Lamb Financial](https://lamb.upeu.edu.pe).

321 lines (320 loc) 28.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @license * Copyright Lamb Team. All Rights Reserved. * Licensed under the MIT License. See License.txt in the project root for license information. */ import { Component, Input, QueryList, Directive, ContentChild, ContentChildren, TemplateRef, Output, EventEmitter, } from '@angular/core'; import { LambTabConfig } from './tab-config'; export class LambTabGroupTitleDirective { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } LambTabGroupTitleDirective.decorators = [ { type: Directive, args: [{ selector: 'ng-template[lambTabGroupTitle]', },] }, ]; LambTabGroupTitleDirective.ctorParameters = () => [ { type: TemplateRef } ]; if (false) { /** @type {?} */ LambTabGroupTitleDirective.prototype.templateRef; } export class LambTabTitleDirective { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } LambTabTitleDirective.decorators = [ { type: Directive, args: [{ selector: 'ng-template[lambTabTitle]', },] }, ]; LambTabTitleDirective.ctorParameters = () => [ { type: TemplateRef } ]; if (false) { /** @type {?} */ LambTabTitleDirective.prototype.templateRef; } export class LambTabContentDirective { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } LambTabContentDirective.decorators = [ { type: Directive, args: [{ selector: 'ng-template[lambTabContent]', },] }, ]; LambTabContentDirective.ctorParameters = () => [ { type: TemplateRef } ]; if (false) { /** @type {?} */ LambTabContentDirective.prototype.templateRef; } /** @type {?} */ let nextId = 0; export class LambTabDirective { constructor() { this.id = `lamb-tab-${nextId++}`; this.disabled = false; } } LambTabDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: 'lamb-tab', },] }, ]; LambTabDirective.propDecorators = { id: [{ type: Input }], title: [{ type: Input }], icon: [{ type: Input }], disabled: [{ type: Input }], contentTemplate: [{ type: ContentChild, args: [LambTabContentDirective,] }], titleTemplate: [{ type: ContentChild, args: [LambTabTitleDirective,] }] }; if (false) { /** @type {?} */ LambTabDirective.prototype.id; /** @type {?} */ LambTabDirective.prototype.title; /** @type {?} */ LambTabDirective.prototype.icon; /** @type {?} */ LambTabDirective.prototype.disabled; /** @type {?} */ LambTabDirective.prototype.contentTemplate; /** @type {?} */ LambTabDirective.prototype.titleTemplate; } /** * @record */ export function LambTabChangeEvent() { } if (false) { /** * Id de la pestaña actualmente activa. * @type {?} */ LambTabChangeEvent.prototype.activeId; /** * Id de la pestaña recién seleccionada. * @type {?} */ LambTabChangeEvent.prototype.nextId; /** * Función que evitará el cambio de pertaña si se llama. * @type {?} */ LambTabChangeEvent.prototype.preventDefault; } export class LambTabGroupComponent { /** * @param {?} config */ constructor(config) { this.config = config; /** * Id del tab activo. */ // public currentActiveId: string; /** * Cuando cambia de tab se destruira el contenido anterior o solo se oculatará? */ this.destroyOnHide = true; /** * Emite cuando hay cambios de tabs. */ this.tabChange = new EventEmitter(); this.type = this.config.type; this.justify = this.config.justify; this.orientation = this.config.orientation; } /** * @param {?} className * @return {?} */ set justify(className) { if (className === 'fill' || className === 'justified') { this.justifyClass = `nav-${className}`; } else { this.justifyClass = `justify-content-${className}`; } } /** * @param {?} tabId * @return {?} */ onSelect(tabId) { /** @type {?} */ const selectedTab = this.getTabById(tabId); if (selectedTab && !selectedTab.disabled && this.activeId !== selectedTab.id) { /** @type {?} */ let defaultPrevented = false; this.tabChange.emit({ activeId: this.activeId, nextId: selectedTab.id, preventDefault: () => { defaultPrevented = true; }, }); if (!defaultPrevented) { this.activeId = selectedTab.id; // this.currentActiveId = this.activeId; } } } /** * @return {?} */ ngOnInit() { // this.currentActiveId = this.activeId; } /** * @return {?} */ ngAfterContentChecked() { /** @type {?} */ const activeTab = this.getTabById(this.activeId); this.activeId = activeTab ? activeTab.id : (this.tabs.length ? this.tabs.first.id : null); // this.currentActiveId = this.activeId; } /** * @param {?} id * @return {?} */ getTabById(id) { /** @type {?} */ const tabsWithId = this.tabs.filter(tab => tab.id === id); return tabsWithId.length ? tabsWithId[0] : null; } } LambTabGroupComponent.decorators = [ { type: Component, args: [{ selector: 'lamb-tab-group', exportAs: 'lambTabset', template: `<!-- <ul class="nav justify-content-center" id="myTab" role="tablist"> --> <div class="row"> <div [class]="'col-md-' + (orientation === 'horizontal' ? '12' : '2' ) "> <!-- <div class="card"> <div class="card-body"> --> <ul *ngIf="orientation === 'horizontal' && tabGroupTitle?.templateRef" class="nav flex-column lamb-nav-group-title"> <li class="nav-item-group-title"> <ng-template [ngTemplateOutlet]="tabGroupTitle?.templateRef"> </ng-template> </li> </ul> <ul [class]="'nav nav-' + type + (orientation === 'horizontal' ? ' ' + justifyClass + ' lamb-nav-horizontal' : ' flex-column lamb-ul-nav-vertical' )" id="myTab" role="tablist"> <li class="nav-item-group-title" *ngIf="orientation === 'vertical' && tabGroupTitle?.templateRef"> <ng-template [ngTemplateOutlet]="tabGroupTitle?.templateRef"> </ng-template> </li> <!-- <li> --> <!-- <ul>hola</ul> --> <!-- </li> --> <li *ngFor="let tab of tabs" class="nav-item"> <a [id]="tab.id" [class]="'nav-link' + (orientation === 'horizontal'? ' lamb-nav-horizontal': ' lamb-nav-vertical' )" [class.active]="tab.id === activeId" [class.disabled]="tab.disabled" (click)="!!onSelect(tab.id)" role="tab" [attr.tabindex]="(tab.disabled ? '-1': undefined)" [attr.aria-controls]="(!destroyOnHide || tab.id === activeId ? tab.id + '-panel': null)" [attr.aria-expanded]="tab.id === activeId" [attr.aria-disabled]="tab.disabled"> <!-- data-toggle="tab" aria-selected="true" --> <ng-template [ngIf]="tab.icon"> <span> <i class="{{ tab.icon }} lamb-icon"></i> </span> </ng-template> {{ tab.title }} <ng-template [ngTemplateOutlet]="tab.titleTemplate?.templateRef"></ng-template> </a> </li> <!-- <ng-content select="lamb-tab-head"></ng-content> --> </ul> <!-- </div> </div> --> </div> <div [class]="'col-md-' + (orientation === 'horizontal' ? '12' : '10' ) "> <div class="tab-content" id="myTabContent"> <!-- <ng-content select="lamb-tab-body"></ng-content> --> <ng-template ngFor let-tab [ngForOf]="tabs"> <!-- class="tab-pane fade {{ tab.id === activeId ? 'active': null }}" --> <div class="tab-pane {{ tab.id === activeId ? 'active': null }}" *ngIf="!destroyOnHide || tab.id === activeId" role="tabpanel" [attr.aria-labelledby]="tab.id" id="{{ tab.id }}-panel" [attr.aria-expanded]="tab.id === activeId"> <ng-template [ngTemplateOutlet]="tab.contentTemplate?.templateRef"></ng-template> </div> </ng-template> </div> </div> </div>`, styles: [`ul.nav{margin-bottom:.8rem;padding-left:0}ul.lamb-ul-nav-vertical{border-bottom:none}.nav-item-group-title{font-weight:400;text-transform:uppercase;padding:.5rem 1rem}.nav-item-group-title /deep/ i{width:50rem}.lamb-nav-group-title{margin-bottom:0!important;text-align:center}.nav-item{text-transform:uppercase;font-weight:400}.nav-item .nav-link{cursor:pointer;font-size:.7rem}.nav-item .nav-link.lamb-nav-vertical{border-right:.214rem solid transparent;display:flex;min-height:2.5rem}.nav-item .nav-link.lamb-nav-horizontal{border-bottom:.214rem solid transparent;display:flex}.nav-item .nav-link:not(.disabled).active,.nav-item .nav-link:not(.disabled).active:focus,.nav-item .nav-link:not(.disabled).active:hover{font-weight:500}.nav-item .nav-link ::ng-deep .lamb-icon{font-size:medium;margin-right:6px}.nav-item .nav-link.disabled{cursor:not-allowed}.nav-item .nav-link.disabled:focus,.nav-item .nav-link.disabled:hover{color:inherit}`], },] }, ]; LambTabGroupComponent.ctorParameters = () => [ { type: LambTabConfig } ]; LambTabGroupComponent.propDecorators = { tabs: [{ type: ContentChildren, args: [LambTabDirective,] }], tabGroupTitle: [{ type: ContentChild, args: [LambTabGroupTitleDirective,] }], activeId: [{ type: Input }], destroyOnHide: [{ type: Input }], tabChange: [{ type: Output }], justify: [{ type: Input }], orientation: [{ type: Input }], type: [{ type: Input }] }; if (false) { /** @type {?} */ LambTabGroupComponent.prototype.justifyClass; /** @type {?} */ LambTabGroupComponent.prototype.tabs; /** @type {?} */ LambTabGroupComponent.prototype.tabGroupTitle; /** * Id del tab que saldrá activado por defecto. * @type {?} */ LambTabGroupComponent.prototype.activeId; /** * Cuando cambia de tab se destruira el contenido anterior o solo se oculatará? * @type {?} */ LambTabGroupComponent.prototype.destroyOnHide; /** * Emite cuando hay cambios de tabs. * @type {?} */ LambTabGroupComponent.prototype.tabChange; /** @type {?} */ LambTabGroupComponent.prototype.orientation; /** @type {?} */ LambTabGroupComponent.prototype.type; /** @type {?} */ LambTabGroupComponent.prototype.config; } /** @type {?} */ export const LAMB_TABS_COMPONENTS = [ LambTabGroupComponent, LambTabDirective, LambTabTitleDirective, LambTabContentDirective, LambTabGroupTitleDirective, ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9sYW1iLXdlYi1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy90YWJzL3RhYnMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQU9BLE9BQU8sRUFDSCxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFDM0IsU0FBUyxFQUFFLFlBQVksRUFBRSxlQUFlLEVBQ3hDLFdBQVcsRUFBdUIsTUFBTSxFQUFFLFlBQVksR0FDekQsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUs3QyxNQUFNOzs7O0lBQ0YsWUFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUksQ0FBQzs7O1lBSnhELFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsZ0NBQWdDO2FBQzdDOzs7WUFORyxXQUFXOzs7O0lBUUMsaURBQW9DOztBQU1wRCxNQUFNOzs7O0lBQ0YsWUFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUksQ0FBQzs7O1lBSnhELFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsMkJBQTJCO2FBQ3hDOzs7WUFiRyxXQUFXOzs7O0lBZUMsNENBQW9DOztBQU1wRCxNQUFNOzs7O0lBQ0YsWUFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUksQ0FBQzs7O1lBSnhELFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsNkJBQTZCO2FBQzFDOzs7WUFwQkcsV0FBVzs7OztJQXNCQyw4Q0FBb0M7OztJQUdoRCxNQUFNLEdBQUcsQ0FBQztBQU1kLE1BQU07SUFKTjtRQU1hLE9BQUUsR0FBRyxZQUFZLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFNNUIsYUFBUSxHQUFHLEtBQUssQ0FBQztJQUk5QixDQUFDOzs7WUFoQkEsU0FBUyxTQUFDOztnQkFFUCxRQUFR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QUUsS0FBSyxFQUFFLENBQUM7UUFDN0UsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3BELENBQUM7OztZQXZJSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGdCQUFnQjtnQkFDMUIsUUFBUSxFQUFFLFlBQVk7Z0JBQ3RCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bc0RQO2dCQUNILE1BQU0sRUFBRSxDQUFDLDg2QkFBODZCLENBQUM7YUFDMzdCOzs7WUF4SFEsYUFBYTs7O21CQTRIakIsZUFBZSxTQUFDLGdCQUFnQjs0QkFDaEMsWUFBWSxTQUFDLDBCQUEwQjt1QkFLdkMsS0FBSzs0QkFVTCxLQUFLO3dCQUtMLE1BQU07c0JBRU4sS0FBSzswQkFvQ0wsS0FBSzttQkFFTCxLQUFLOzs7O0lBOUROLDZDQUFxQjs7SUFDckIscUNBQXFFOztJQUNyRSw4Q0FBb0Y7Ozs7O0lBS3BGLHlDQUEwQjs7Ozs7SUFVMUIsOENBQThCOzs7OztJQUs5QiwwQ0FBNkQ7O0lBc0M3RCw0Q0FBZ0Q7O0lBRWhELHFDQUFpQzs7SUFackIsdUNBQTZCOzs7QUEwQjdDLE1BQU0sT0FBTyxvQkFBb0IsR0FBRztJQUNoQyxxQkFBcUI7SUFDckIsZ0JBQWdCO0lBQ2hCLHFCQUFxQjtJQUNyQix1QkFBdUI7SUFDdkIsMEJBQTBCO0NBQzdCIiwic291cmNlc0NvbnRlbnQiOlsiXHJcbi8qKlxyXG4gKiBAbGljZW5zZVxyXG4gKiBDb3B5cmlnaHQgTGFtYiBUZWFtLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG4gKi9cclxuXHJcbmltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsIElucHV0LCBRdWVyeUxpc3QsXHJcbiAgICBEaXJlY3RpdmUsIENvbnRlbnRDaGlsZCwgQ29udGVudENoaWxkcmVuLFxyXG4gICAgVGVtcGxhdGVSZWYsIEFmdGVyQ29udGVudENoZWNrZWQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IExhbWJUYWJDb25maWcgfSBmcm9tICcuL3RhYi1jb25maWcnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgICBzZWxlY3RvcjogJ25nLXRlbXBsYXRlW2xhbWJUYWJHcm91cFRpdGxlXScsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMYW1iVGFiR3JvdXBUaXRsZURpcmVjdGl2ZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgdGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4pIHsgfVxyXG59XHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICAgIHNlbGVjdG9yOiAnbmctdGVtcGxhdGVbbGFtYlRhYlRpdGxlXScsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMYW1iVGFiVGl0bGVEaXJlY3RpdmUge1xyXG4gICAgY29uc3RydWN0b3IocHVibGljIHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+KSB7IH1cclxufVxyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgICBzZWxlY3RvcjogJ25nLXRlbXBsYXRlW2xhbWJUYWJDb250ZW50XScsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMYW1iVGFiQ29udGVudERpcmVjdGl2ZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgdGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4pIHsgfVxyXG59XHJcblxyXG5sZXQgbmV4dElkID0gMDtcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1zZWxlY3RvclxyXG4gICAgc2VsZWN0b3I6ICdsYW1iLXRhYicsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMYW1iVGFiRGlyZWN0aXZlIHtcclxuXHJcbiAgICBASW5wdXQoKSBpZCA9IGBsYW1iLXRhYi0ke25leHRJZCsrfWA7XHJcblxyXG4gICAgQElucHV0KCkgdGl0bGU6IHN0cmluZztcclxuXHJcbiAgICBASW5wdXQoKSBpY29uOiBzdHJpbmc7XHJcblxyXG4gICAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcclxuXHJcbiAgICBAQ29udGVudENoaWxkKExhbWJUYWJDb250ZW50RGlyZWN0aXZlKSBjb250ZW50VGVtcGxhdGU6IExhbWJUYWJDb250ZW50RGlyZWN0aXZlO1xyXG4gICAgQENvbnRlbnRDaGlsZChMYW1iVGFiVGl0bGVEaXJlY3RpdmUpIHRpdGxlVGVtcGxhdGU6IExhbWJUYWJUaXRsZURpcmVjdGl2ZTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBMYW1iVGFiQ2hhbmdlRXZlbnQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBJZCBkZSBsYSBwZXN0YcOxYSBhY3R1YWxtZW50ZSBhY3RpdmEuXHJcbiAgICAgKi9cclxuICAgIGFjdGl2ZUlkOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJZCBkZSBsYSBwZXN0YcOxYSByZWNpw6luIHNlbGVjY2lvbmFkYS5cclxuICAgICAqL1xyXG4gICAgbmV4dElkOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGdW5jacOzbiBxdWUgZXZpdGFyw6EgZWwgY2FtYmlvIGRlIHBlcnRhw7FhIHNpIHNlIGxsYW1hLlxyXG4gICAgICovXHJcbiAgICBwcmV2ZW50RGVmYXVsdDogKCkgPT4gdm9pZDtcclxuXHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdsYW1iLXRhYi1ncm91cCcsXHJcbiAgICBleHBvcnRBczogJ2xhbWJUYWJzZXQnLFxyXG4gICAgdGVtcGxhdGU6IGA8IS0tIDx1bCBjbGFzcz1cIm5hdiBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCIgaWQ9XCJteVRhYlwiIHJvbGU9XCJ0YWJsaXN0XCI+IC0tPlxyXG48ZGl2IGNsYXNzPVwicm93XCI+XHJcbiAgICA8ZGl2IFtjbGFzc109XCInY29sLW1kLScgKyAob3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/ICcxMicgOiAnMicgKSBcIj5cclxuICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJjYXJkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPiAtLT5cclxuICAgICAgICA8dWwgKm5nSWY9XCJvcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnICYmIHRhYkdyb3VwVGl0bGU/LnRlbXBsYXRlUmVmXCIgY2xhc3M9XCJuYXYgZmxleC1jb2x1bW4gbGFtYi1uYXYtZ3JvdXAtdGl0bGVcIj5cclxuICAgICAgICAgICAgPGxpIGNsYXNzPVwibmF2LWl0ZW0tZ3JvdXAtdGl0bGVcIj5cclxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0YWJHcm91cFRpdGxlPy50ZW1wbGF0ZVJlZlwiPlxyXG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgPC9saT5cclxuICAgICAgICA8L3VsPlxyXG4gICAgICAgIDx1bCBbY2xhc3NdPVwiJ25hdiBuYXYtJyArIHR5cGUgKyAob3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/ICcgJyArIGp1c3RpZnlDbGFzcyArICcgbGFtYi1uYXYtaG9yaXpvbnRhbCcgOiAnIGZsZXgtY29sdW1uIGxhbWItdWwtbmF2LXZlcnRpY2FsJyApXCJcclxuICAgICAgICAgICAgaWQ9XCJteVRhYlwiIHJvbGU9XCJ0YWJsaXN0XCI+XHJcbiAgICAgICAgICAgIDxsaSBjbGFzcz1cIm5hdi1pdGVtLWdyb3VwLXRpdGxlXCIgKm5nSWY9XCJvcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJyAmJiB0YWJHcm91cFRpdGxlPy50ZW1wbGF0ZVJlZlwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInRhYkdyb3VwVGl0bGU/LnRlbXBsYXRlUmVmXCI+XHJcbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICA8IS0tIDxsaT4gLS0+XHJcbiAgICAgICAgICAgIDwhLS0gPHVsPmhvbGE8L3VsPiAtLT5cclxuICAgICAgICAgICAgPCEtLSA8L2xpPiAtLT5cclxuICAgICAgICAgICAgPGxpICpuZ0Zvcj1cImxldCB0YWIgb2YgdGFic1wiIGNsYXNzPVwibmF2LWl0ZW1cIj5cclxuICAgICAgICAgICAgICAgIDxhIFtpZF09XCJ0YWIuaWRcIiBbY2xhc3NdPVwiJ25hdi1saW5rJyArIChvcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnPyAnIGxhbWItbmF2LWhvcml6b250YWwnOiAnIGxhbWItbmF2LXZlcnRpY2FsJyApXCIgW2NsYXNzLmFjdGl2ZV09XCJ0YWIuaWQgPT09IGFjdGl2ZUlkXCJcclxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwidGFiLmRpc2FibGVkXCIgKGNsaWNrKT1cIiEhb25TZWxlY3QodGFiLmlkKVwiIHJvbGU9XCJ0YWJcIiBbYXR0ci50YWJpbmRleF09XCIodGFiLmRpc2FibGVkID8gJy0xJzogdW5kZWZpbmVkKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCIoIWRlc3Ryb3lPbkhpZGUgfHwgdGFiLmlkID09PSBhY3RpdmVJZCA/IHRhYi5pZCArICctcGFuZWwnOiBudWxsKVwiIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwidGFiLmlkID09PSBhY3RpdmVJZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1kaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tIGRhdGEtdG9nZ2xlPVwidGFiXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9XCJ0cnVlXCIgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInRhYi5pY29uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJ7eyB0YWIuaWNvbiB9fSBsYW1iLWljb25cIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7IHRhYi50aXRsZSB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0YWIudGl0bGVUZW1wbGF0ZT8udGVtcGxhdGVSZWZcIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgPC9hPlxyXG4gICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICA8IS0tIDxuZy1jb250ZW50IHNlbGVjdD1cImxhbWItdGFiLWhlYWRcIj48L25nLWNvbnRlbnQ+IC0tPlxyXG4gICAgICAgIDwvdWw+XHJcbiAgICAgICAgPCEtLSA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PiAtLT5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBbY2xhc3NdPVwiJ2NvbC1tZC0nICsgKG9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgPyAnMTInIDogJzEwJyApIFwiPlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWNvbnRlbnRcIiBpZD1cIm15VGFiQ29udGVudFwiPlxyXG4gICAgICAgICAgICA8IS0tIDxuZy1jb250ZW50IHNlbGVjdD1cImxhbWItdGFiLWJvZHlcIj48L25nLWNvbnRlbnQ+IC0tPlxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LXRhYiBbbmdGb3JPZl09XCJ0YWJzXCI+XHJcbiAgICAgICAgICAgICAgICA8IS0tIGNsYXNzPVwidGFiLXBhbmUgZmFkZSB7eyB0YWIuaWQgPT09IGFjdGl2ZUlkID8gJ2FjdGl2ZSc6IG51bGwgfX1cIiAtLT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWItcGFuZSB7eyB0YWIuaWQgPT09IGFjdGl2ZUlkID8gJ2FjdGl2ZSc6IG51bGwgfX1cIiAqbmdJZj1cIiFkZXN0cm95T25IaWRlIHx8IHRhYi5pZCA9PT0gYWN0aXZlSWRcIiByb2xlPVwidGFicGFuZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxsZWRieV09XCJ0YWIuaWRcIiBpZD1cInt7IHRhYi5pZCB9fS1wYW5lbFwiIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwidGFiLmlkID09PSBhY3RpdmVJZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0YWIuY29udGVudFRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L2Rpdj5gLFxyXG4gICAgc3R5bGVzOiBbYHVsLm5hdnttYXJnaW4tYm90dG9tOi44cmVtO3BhZGRpbmctbGVmdDowfXVsLmxhbWItdWwtbmF2LXZlcnRpY2Fse2JvcmRlci1ib3R0b206bm9uZX0ubmF2LWl0ZW0tZ3JvdXAtdGl0bGV7Zm9udC13ZWlnaHQ6NDAwO3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTtwYWRkaW5nOi41cmVtIDFyZW19Lm5hdi1pdGVtLWdyb3VwLXRpdGxlIC9kZWVwLyBpe3dpZHRoOjUwcmVtfS5sYW1iLW5hdi1ncm91cC10aXRsZXttYXJnaW4tYm90dG9tOjAhaW1wb3J0YW50O3RleHQtYWxpZ246Y2VudGVyfS5uYXYtaXRlbXt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7Zm9udC13ZWlnaHQ6NDAwfS5uYXYtaXRlbSAubmF2LWxpbmt7Y3Vyc29yOnBvaW50ZXI7Zm9udC1zaXplOi43cmVtfS5uYXYtaXRlbSAubmF2LWxpbmsubGFtYi1uYXYtdmVydGljYWx7Ym9yZGVyLXJpZ2h0Oi4yMTRyZW0gc29saWQgdHJhbnNwYXJlbnQ7ZGlzcGxheTpmbGV4O21pbi1oZWlnaHQ6Mi41cmVtfS5uYXYtaXRlbSAubmF2LWxpbmsubGFtYi1uYXYtaG9yaXpvbnRhbHtib3JkZXItYm90dG9tOi4yMTRyZW0gc29saWQgdHJhbnNwYXJlbnQ7ZGlzcGxheTpmbGV4fS5uYXYtaXRlbSAubmF2LWxpbms6bm90KC5kaXNhYmxlZCkuYWN0aXZlLC5uYXYtaXRlbSAubmF2LWxpbms6bm90KC5kaXNhYmxlZCkuYWN0aXZlOmZvY3VzLC5uYXYtaXRlbSAubmF2LWxpbms6bm90KC5kaXNhYmxlZCkuYWN0aXZlOmhvdmVye2ZvbnQtd2VpZ2h0OjUwMH0ubmF2LWl0ZW0gLm5hdi1saW5rIDo6bmctZGVlcCAubGFtYi1pY29ue2ZvbnQtc2l6ZTptZWRpdW07bWFyZ2luLXJpZ2h0OjZweH0ubmF2LWl0ZW0gLm5hdi1saW5rLmRpc2FibGVke2N1cnNvcjpub3QtYWxsb3dlZH0ubmF2LWl0ZW0gLm5hdi1saW5rLmRpc2FibGVkOmZvY3VzLC5uYXYtaXRlbSAubmF2LWxpbmsuZGlzYWJsZWQ6aG92ZXJ7Y29sb3I6aW5oZXJpdH1gXSxcclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBMYW1iVGFiR3JvdXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudENoZWNrZWQge1xyXG4gICAganVzdGlmeUNsYXNzOiBzdHJpbmc7XHJcbiAgICBAQ29udGVudENoaWxkcmVuKExhbWJUYWJEaXJlY3RpdmUpIHRhYnM6IFF1ZXJ5TGlzdDxMYW1iVGFiRGlyZWN0aXZlPjtcclxuICAgIEBDb250ZW50Q2hpbGQoTGFtYlRhYkdyb3VwVGl0bGVEaXJlY3RpdmUpIHRhYkdyb3VwVGl0bGU6IExhbWJUYWJHcm91cFRpdGxlRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWQgZGVsIHRhYiBxdWUgc2FsZHLDoSBhY3RpdmFkbyBwb3IgZGVmZWN0by5cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgYWN0aXZlSWQ6IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIElkIGRlbCB0YWIgYWN0aXZvLlxyXG4gICAgICovXHJcbiAgICAvLyBwdWJsaWMgY3VycmVudEFjdGl2ZUlkOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdWFuZG8gY2FtYmlhIGRlIHRhYiBzZSBkZXN0cnVpcmEgZWwgY29udGVuaWRvIGFudGVyaW9yIG8gc29sbyBzZSBvY3VsYXRhcsOhP1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBkZXN0cm95T25IaWRlID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVtaXRlIGN1YW5kbyBoYXkgY2FtYmlvcyBkZSB0YWJzLlxyXG4gICAgICovXHJcbiAgICBAT3V0cHV0KCkgdGFiQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxMYW1iVGFiQ2hhbmdlRXZlbnQ+KCk7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHNldCBqdXN0aWZ5KGNsYXNzTmFtZTogJ3N0YXJ0JyB8ICdjZW50ZXInIHwgJ2VuZCcgfCAnZmlsbCcgfCAnanVzdGlmaWVkJykge1xyXG4gICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdmaWxsJyB8fCBjbGFzc05hbWUgPT09ICdqdXN0aWZpZWQnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuanVzdGlmeUNsYXNzID0gYG5hdi0ke2NsYXNzTmFtZX1gO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuanVzdGlmeUNsYXNzID0gYGp1c3RpZnktY29udGVudC0ke2NsYXNzTmFtZX1gO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBvblNlbGVjdCh0YWJJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRUYWIgPSB0aGlzLmdldFRhYkJ5SWQodGFiSWQpO1xyXG4gICAgICAgIGlmIChzZWxlY3RlZFRhYiAmJiAhc2VsZWN0ZWRUYWIuZGlzYWJsZWQgJiYgdGhpcy5hY3RpdmVJZCAhPT0gc2VsZWN0ZWRUYWIuaWQpIHtcclxuICAgICAgICAgICAgbGV0IGRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy50YWJDaGFuZ2UuZW1pdChcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVJZDogdGhpcy5hY3RpdmVJZCxcclxuICAgICAgICAgICAgICAgICAgICBuZXh0SWQ6IHNlbGVjdGVkVGFiLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7IGRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlOyB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgaWYgKCFkZWZhdWx0UHJldmVudGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZUlkID0gc2VsZWN0ZWRUYWIuaWQ7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzLmN1cnJlbnRBY3RpdmVJZCA9IHRoaXMuYWN0aXZlSWQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZzogTGFtYlRhYkNvbmZpZykge1xyXG4gICAgICAgIHRoaXMudHlwZSA9IHRoaXMuY29uZmlnLnR5cGU7XHJcbiAgICAgICAgdGhpcy5qdXN0aWZ5ID0gdGhpcy5jb25maWcuanVzdGlmeTtcclxuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID0gdGhpcy5jb25maWcub3JpZW50YXRpb247XHJcbiAgICB9XHJcbiAgICBuZ09uSW5pdCgpIHtcclxuICAgICAgICAvLyB0aGlzLmN1cnJlbnRBY3RpdmVJZCA9IHRoaXMuYWN0aXZlSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1lbWJlci1vcmRlcmluZ1xyXG4gICAgQElucHV0KCkgb3JpZW50YXRpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCc7XHJcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWVtYmVyLW9yZGVyaW5nXHJcbiAgICBASW5wdXQoKSB0eXBlOiAndGFic3MnIHwgJ3BpbGxzJztcclxuXHJcbiAgICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XHJcbiAgICAgICAgY29uc3QgYWN0aXZlVGFiID0gdGhpcy5nZXRUYWJCeUlkKHRoaXMuYWN0aXZlSWQpO1xyXG4gICAgICAgIHRoaXMuYWN0aXZlSWQgPSBhY3RpdmVUYWIgPyBhY3RpdmVUYWIuaWQgOiAodGhpcy50YWJzLmxlbmd0aCA/IHRoaXMudGFicy5maXJzdC5pZCA6IG51bGwpO1xyXG4gICAgICAgIC8vIHRoaXMuY3VycmVudEFjdGl2ZUlkID0gdGhpcy5hY3RpdmVJZDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFRhYkJ5SWQoaWQ6IHN0cmluZyk6IExhbWJUYWJEaXJlY3RpdmUge1xyXG4gICAgICAgIGNvbnN0IHRhYnNXaXRoSWQ6IExhbWJUYWJEaXJlY3RpdmVbXSA9IHRoaXMudGFicy5maWx0ZXIodGFiID0+IHRhYi5pZCA9PT0gaWQpO1xyXG4gICAgICAgIHJldHVybiB0YWJzV2l0aElkLmxlbmd0aCA/IHRhYnNXaXRoSWRbMF0gOiBudWxsO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTEFNQl9UQUJTX0NPTVBPTkVOVFMgPSBbXHJcbiAgICBMYW1iVGFiR3JvdXBDb21wb25lbnQsXHJcbiAgICBMYW1iVGFiRGlyZWN0aXZlLFxyXG4gICAgTGFtYlRhYlRpdGxlRGlyZWN0aXZlLFxyXG4gICAgTGFtYlRhYkNvbnRlbnREaXJlY3RpdmUsXHJcbiAgICBMYW1iVGFiR3JvdXBUaXRsZURpcmVjdGl2ZSxcclxuXTtcclxuXHJcblxyXG4iXX0=