UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

567 lines 66.7 kB
import { __decorate } from "tslib"; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** get some code from https://github.com/angular/material2 */ import { A11yModule } from '@angular/cdk/a11y'; import { coerceNumberProperty } from '@angular/cdk/coercion'; import { NgForOf, NgIf, NgStyle } from '@angular/common'; import { booleanAttribute, ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Optional, Output, QueryList, ViewChild, ViewEncapsulation } from '@angular/core'; import { NavigationEnd } from '@angular/router'; import { merge, of, Subject, Subscription } from 'rxjs'; import { delay, filter, first, startWith, takeUntil } from 'rxjs/operators'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { PREFIX } from 'ng-zorro-antd/core/logger'; import { NzOutletModule } from 'ng-zorro-antd/core/outlet'; import { wrapIntoObservable } from 'ng-zorro-antd/core/util'; import { NzTabChangeEvent } from './interfaces'; import { NzTabBodyComponent } from './tab-body.component'; import { NzTabCloseButtonComponent } from './tab-close-button.component'; import { NzTabNavBarComponent } from './tab-nav-bar.component'; import { NzTabNavItemDirective } from './tab-nav-item.directive'; import { NZ_TAB_SET, NzTabComponent } from './tab.component'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "@angular/cdk/bidi"; import * as i3 from "@angular/router"; import * as i4 from "@angular/cdk/a11y"; import * as i5 from "ng-zorro-antd/core/outlet"; const NZ_CONFIG_MODULE_NAME = 'tabs'; let nextId = 0; export class NzTabSetComponent { get nzSelectedIndex() { return this.selectedIndex; } set nzSelectedIndex(value) { this.indexToSelect = coerceNumberProperty(value, null); } get position() { return ['top', 'bottom'].indexOf(this.nzTabPosition) === -1 ? 'vertical' : 'horizontal'; } get addable() { return this.nzType === 'editable-card' && !this.nzHideAdd; } get closable() { return this.nzType === 'editable-card'; } get line() { return this.nzType === 'line'; } get inkBarAnimated() { return this.line && (typeof this.nzAnimated === 'boolean' ? this.nzAnimated : this.nzAnimated.inkBar); } get tabPaneAnimated() { return typeof this.nzAnimated === 'boolean' ? this.nzAnimated : this.nzAnimated.tabPane; } constructor(nzConfigService, ngZone, cdr, directionality, router) { this.nzConfigService = nzConfigService; this.ngZone = ngZone; this.cdr = cdr; this.directionality = directionality; this.router = router; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzTabPosition = 'top'; this.nzCanDeactivate = null; this.nzAddIcon = 'plus'; this.nzTabBarStyle = null; this.nzType = 'line'; this.nzSize = 'default'; this.nzAnimated = true; this.nzTabBarGutter = undefined; this.nzHideAdd = false; this.nzCentered = false; this.nzHideAll = false; this.nzLinkRouter = false; this.nzLinkExact = true; this.nzSelectChange = new EventEmitter(true); this.nzSelectedIndexChange = new EventEmitter(); this.nzTabListScroll = new EventEmitter(); this.nzClose = new EventEmitter(); this.nzAdd = new EventEmitter(); // Pick up only direct descendants under ivy rendering engine // We filter out only the tabs that belong to this tab set in `tabs`. this.allTabs = new QueryList(); // All the direct tabs for this tab set this.tabs = new QueryList(); this.dir = 'ltr'; this.destroy$ = new Subject(); this.indexToSelect = 0; this.selectedIndex = null; this.tabLabelSubscription = Subscription.EMPTY; this.tabsSubscription = Subscription.EMPTY; this.canDeactivateSubscription = Subscription.EMPTY; this.tabSetId = nextId++; } ngOnInit() { this.dir = this.directionality.value; this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => { this.dir = direction; this.cdr.detectChanges(); }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); this.tabs.destroy(); this.tabLabelSubscription.unsubscribe(); this.tabsSubscription.unsubscribe(); this.canDeactivateSubscription.unsubscribe(); } ngAfterContentInit() { this.ngZone.runOutsideAngular(() => { Promise.resolve().then(() => this.setUpRouter()); }); this.subscribeToTabLabels(); this.subscribeToAllTabChanges(); // Subscribe to changes in the amount of tabs, in order to be // able to re-render the content as new tabs are added or removed. this.tabsSubscription = this.tabs.changes.subscribe(() => { const indexToSelect = this.clampTabIndex(this.indexToSelect); // Maintain the previously-selected tab if a new tab is added or removed and there is no // explicit change that selects a different tab. if (indexToSelect === this.selectedIndex) { const tabs = this.tabs.toArray(); for (let i = 0; i < tabs.length; i++) { if (tabs[i].isActive) { // Assign both to the `indexToSelect` and `selectedIndex` so we don't fire a changed // event, otherwise the consumer may end up in an infinite loop in some edge cases like // adding a tab within the `nzSelectedIndexChange` event. this.indexToSelect = this.selectedIndex = i; break; } } } this.subscribeToTabLabels(); this.cdr.markForCheck(); }); } ngAfterContentChecked() { // Don't clamp the `indexToSelect` immediately in the setter because it can happen that // the amount of tabs changes before the actual change detection runs. const indexToSelect = (this.indexToSelect = this.clampTabIndex(this.indexToSelect)); // If there is a change in selected index, emit a change event. Should not trigger if // the selected index has not yet been initialized. if (this.selectedIndex !== indexToSelect) { const isFirstRun = this.selectedIndex == null; if (!isFirstRun) { this.nzSelectChange.emit(this.createChangeEvent(indexToSelect)); } // Changing these values after change detection has run // since the checked content may contain references to them. Promise.resolve().then(() => { this.tabs.forEach((tab, index) => (tab.isActive = index === indexToSelect)); if (!isFirstRun) { this.nzSelectedIndexChange.emit(indexToSelect); } }); } // Setup the position for each tab and optionally setup an origin on the next selected tab. this.tabs.forEach((tab, index) => { tab.position = index - indexToSelect; // If there is already a selected tab, then set up an origin for the next selected tab // if it doesn't have one already. if (this.selectedIndex != null && tab.position === 0 && !tab.origin) { tab.origin = indexToSelect - this.selectedIndex; } }); if (this.selectedIndex !== indexToSelect) { this.selectedIndex = indexToSelect; this.cdr.markForCheck(); } } onClose(index, e) { e.preventDefault(); e.stopPropagation(); this.nzClose.emit({ index }); } onAdd() { this.nzAdd.emit(); } clampTabIndex(index) { return Math.min(this.tabs.length - 1, Math.max(index || 0, 0)); } createChangeEvent(index) { const event = new NzTabChangeEvent(); event.index = index; if (this.tabs && this.tabs.length) { event.tab = this.tabs.toArray()[index]; this.tabs.forEach((tab, i) => { if (i !== index) { tab.nzDeselect.emit(); } }); event.tab.nzSelect.emit(); } return event; } subscribeToTabLabels() { if (this.tabLabelSubscription) { this.tabLabelSubscription.unsubscribe(); } this.tabLabelSubscription = merge(...this.tabs.map(tab => tab.stateChanges)).subscribe(() => this.cdr.markForCheck()); } subscribeToAllTabChanges() { this.allTabs.changes.pipe(startWith(this.allTabs)).subscribe((tabs) => { this.tabs.reset(tabs.filter(tab => tab.closestTabSet === this)); this.tabs.notifyOnChanges(); }); } canDeactivateFun(pre, next) { if (typeof this.nzCanDeactivate === 'function') { const observable = wrapIntoObservable(this.nzCanDeactivate(pre, next)); return observable.pipe(first(), takeUntil(this.destroy$)); } else { return of(true); } } clickNavItem(tab, index, e) { if (!tab.nzDisabled) { // ignore nzCanDeactivate tab.nzClick.emit(); if (!this.isRouterLinkClickEvent(index, e)) { this.setSelectedIndex(index); } } } isRouterLinkClickEvent(index, event) { const target = event.target; if (this.nzLinkRouter) { return !!this.tabs.toArray()[index]?.linkDirective?.elementRef.nativeElement.contains(target); } else { return false; } } contextmenuNavItem(tab, e) { if (!tab.nzDisabled) { // ignore nzCanDeactivate tab.nzContextmenu.emit(e); } } setSelectedIndex(index) { this.canDeactivateSubscription.unsubscribe(); this.canDeactivateSubscription = this.canDeactivateFun(this.selectedIndex, index).subscribe(can => { if (can) { this.nzSelectedIndex = index; this.tabNavBarRef.focusIndex = index; this.cdr.markForCheck(); } }); } getTabIndex(tab, index) { if (tab.nzDisabled) { return null; } return this.selectedIndex === index ? 0 : -1; } getTabContentId(i) { return `nz-tabs-${this.tabSetId}-tab-${i}`; } setUpRouter() { if (this.nzLinkRouter) { if (!this.router) { throw new Error(`${PREFIX} you should import 'RouterModule' if you want to use 'nzLinkRouter'!`); } this.router.events .pipe(takeUntil(this.destroy$), filter(e => e instanceof NavigationEnd), startWith(true), delay(0)) .subscribe(() => { this.updateRouterActive(); this.cdr.markForCheck(); }); } } updateRouterActive() { if (this.router.navigated) { const index = this.findShouldActiveTabIndex(); if (index !== this.selectedIndex) { this.setSelectedIndex(index); } this.nzHideAll = index === -1; } } findShouldActiveTabIndex() { const tabs = this.tabs.toArray(); const isActive = this.isLinkActive(this.router); return tabs.findIndex(tab => { const c = tab.linkDirective; return c ? isActive(c.routerLink) : false; }); } isLinkActive(router) { return (link) => link ? router.isActive(link.urlTree || '', { paths: this.nzLinkExact ? 'exact' : 'subset', queryParams: this.nzLinkExact ? 'exact' : 'subset', fragment: 'ignored', matrixParams: 'ignored' }) : false; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzTabSetComponent, deps: [{ token: i1.NzConfigService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i2.Directionality, optional: true }, { token: i3.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.0.1", type: NzTabSetComponent, isStandalone: true, selector: "nz-tabset", inputs: { nzSelectedIndex: "nzSelectedIndex", nzTabPosition: "nzTabPosition", nzTabBarExtraContent: "nzTabBarExtraContent", nzCanDeactivate: "nzCanDeactivate", nzAddIcon: "nzAddIcon", nzTabBarStyle: "nzTabBarStyle", nzType: "nzType", nzSize: "nzSize", nzAnimated: "nzAnimated", nzTabBarGutter: "nzTabBarGutter", nzHideAdd: ["nzHideAdd", "nzHideAdd", booleanAttribute], nzCentered: ["nzCentered", "nzCentered", booleanAttribute], nzHideAll: ["nzHideAll", "nzHideAll", booleanAttribute], nzLinkRouter: ["nzLinkRouter", "nzLinkRouter", booleanAttribute], nzLinkExact: ["nzLinkExact", "nzLinkExact", booleanAttribute] }, outputs: { nzSelectChange: "nzSelectChange", nzSelectedIndexChange: "nzSelectedIndexChange", nzTabListScroll: "nzTabListScroll", nzClose: "nzClose", nzAdd: "nzAdd" }, host: { properties: { "class.ant-tabs-card": "nzType === 'card' || nzType === 'editable-card'", "class.ant-tabs-editable": "nzType === 'editable-card'", "class.ant-tabs-editable-card": "nzType === 'editable-card'", "class.ant-tabs-centered": "nzCentered", "class.ant-tabs-rtl": "dir === 'rtl'", "class.ant-tabs-top": "nzTabPosition === 'top'", "class.ant-tabs-bottom": "nzTabPosition === 'bottom'", "class.ant-tabs-left": "nzTabPosition === 'left'", "class.ant-tabs-right": "nzTabPosition === 'right'", "class.ant-tabs-default": "nzSize === 'default'", "class.ant-tabs-small": "nzSize === 'small'", "class.ant-tabs-large": "nzSize === 'large'" }, classAttribute: "ant-tabs" }, providers: [ { provide: NZ_TAB_SET, useExisting: NzTabSetComponent } ], queries: [{ propertyName: "allTabs", predicate: NzTabComponent, descendants: true }], viewQueries: [{ propertyName: "tabNavBarRef", first: true, predicate: NzTabNavBarComponent, descendants: true }], exportAs: ["nzTabset"], ngImport: i0, template: ` <nz-tabs-nav *ngIf="tabs.length || addable" [ngStyle]="nzTabBarStyle" [selectedIndex]="nzSelectedIndex || 0" [inkBarAnimated]="inkBarAnimated" [addable]="addable" [addIcon]="nzAddIcon" [hideBar]="nzHideAll" [position]="position" [extraTemplate]="nzTabBarExtraContent" (tabScroll)="nzTabListScroll.emit($event)" (selectFocusedIndex)="setSelectedIndex($event)" (addClicked)="onAdd()" > <div class="ant-tabs-tab" [style.margin-right.px]="position === 'horizontal' ? nzTabBarGutter : null" [style.margin-bottom.px]="position === 'vertical' ? nzTabBarGutter : null" [class.ant-tabs-tab-active]="nzSelectedIndex === i" [class.ant-tabs-tab-disabled]="tab.nzDisabled" (click)="clickNavItem(tab, i, $event)" (contextmenu)="contextmenuNavItem(tab, $event)" *ngFor="let tab of tabs; let i = index" > <button type="button" role="tab" [id]="getTabContentId(i)" [attr.tabIndex]="getTabIndex(tab, i)" [attr.aria-disabled]="tab.nzDisabled" [attr.aria-selected]="nzSelectedIndex === i && !nzHideAll" [attr.aria-controls]="getTabContentId(i)" [disabled]="tab.nzDisabled" [tab]="tab" [active]="nzSelectedIndex === i" class="ant-tabs-tab-btn" nzTabNavItem cdkMonitorElementFocus > <ng-container *nzStringTemplateOutlet="tab.label; context: { visible: true }">{{ tab.label }}</ng-container> <button type="button" nz-tab-close-button *ngIf="tab.nzClosable && closable && !tab.nzDisabled" [closeIcon]="tab.nzCloseIcon" (click)="onClose(i, $event)" ></button> </button> </div> </nz-tabs-nav> <div class="ant-tabs-content-holder"> <div class="ant-tabs-content" [class.ant-tabs-content-top]="nzTabPosition === 'top'" [class.ant-tabs-content-bottom]="nzTabPosition === 'bottom'" [class.ant-tabs-content-left]="nzTabPosition === 'left'" [class.ant-tabs-content-right]="nzTabPosition === 'right'" [class.ant-tabs-content-animated]="tabPaneAnimated" > <div role="tabpanel" [id]="getTabContentId(i)" [attr.aria-labelledby]="getTabContentId(i)" nz-tab-body *ngFor="let tab of tabs; let i = index" [active]="nzSelectedIndex === i && !nzHideAll" [content]="tab.content" [forceRender]="tab.nzForceRender" [animated]="tabPaneAnimated" ></div> </div> </div> `, isInline: true, dependencies: [{ kind: "component", type: NzTabNavBarComponent, selector: "nz-tabs-nav", inputs: ["position", "addable", "hideBar", "addIcon", "inkBarAnimated", "extraTemplate", "selectedIndex"], outputs: ["indexFocused", "selectFocusedIndex", "addClicked", "tabScroll"], exportAs: ["nzTabsNav"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NzTabNavItemDirective, selector: "[nzTabNavItem]", inputs: ["disabled", "tab", "active"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i4.CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"], exportAs: ["cdkMonitorFocus"] }, { kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i5.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }, { kind: "component", type: NzTabCloseButtonComponent, selector: "nz-tab-close-button, button[nz-tab-close-button]", inputs: ["closeIcon"] }, { kind: "component", type: NzTabBodyComponent, selector: "[nz-tab-body]", inputs: ["content", "active", "animated", "forceRender"], exportAs: ["nzTabBody"] }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzType", void 0); __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzSize", void 0); __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzAnimated", void 0); __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzTabBarGutter", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzTabSetComponent, decorators: [{ type: Component, args: [{ selector: 'nz-tabset', exportAs: 'nzTabset', preserveWhitespaces: false, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [ { provide: NZ_TAB_SET, useExisting: NzTabSetComponent } ], template: ` <nz-tabs-nav *ngIf="tabs.length || addable" [ngStyle]="nzTabBarStyle" [selectedIndex]="nzSelectedIndex || 0" [inkBarAnimated]="inkBarAnimated" [addable]="addable" [addIcon]="nzAddIcon" [hideBar]="nzHideAll" [position]="position" [extraTemplate]="nzTabBarExtraContent" (tabScroll)="nzTabListScroll.emit($event)" (selectFocusedIndex)="setSelectedIndex($event)" (addClicked)="onAdd()" > <div class="ant-tabs-tab" [style.margin-right.px]="position === 'horizontal' ? nzTabBarGutter : null" [style.margin-bottom.px]="position === 'vertical' ? nzTabBarGutter : null" [class.ant-tabs-tab-active]="nzSelectedIndex === i" [class.ant-tabs-tab-disabled]="tab.nzDisabled" (click)="clickNavItem(tab, i, $event)" (contextmenu)="contextmenuNavItem(tab, $event)" *ngFor="let tab of tabs; let i = index" > <button type="button" role="tab" [id]="getTabContentId(i)" [attr.tabIndex]="getTabIndex(tab, i)" [attr.aria-disabled]="tab.nzDisabled" [attr.aria-selected]="nzSelectedIndex === i && !nzHideAll" [attr.aria-controls]="getTabContentId(i)" [disabled]="tab.nzDisabled" [tab]="tab" [active]="nzSelectedIndex === i" class="ant-tabs-tab-btn" nzTabNavItem cdkMonitorElementFocus > <ng-container *nzStringTemplateOutlet="tab.label; context: { visible: true }">{{ tab.label }}</ng-container> <button type="button" nz-tab-close-button *ngIf="tab.nzClosable && closable && !tab.nzDisabled" [closeIcon]="tab.nzCloseIcon" (click)="onClose(i, $event)" ></button> </button> </div> </nz-tabs-nav> <div class="ant-tabs-content-holder"> <div class="ant-tabs-content" [class.ant-tabs-content-top]="nzTabPosition === 'top'" [class.ant-tabs-content-bottom]="nzTabPosition === 'bottom'" [class.ant-tabs-content-left]="nzTabPosition === 'left'" [class.ant-tabs-content-right]="nzTabPosition === 'right'" [class.ant-tabs-content-animated]="tabPaneAnimated" > <div role="tabpanel" [id]="getTabContentId(i)" [attr.aria-labelledby]="getTabContentId(i)" nz-tab-body *ngFor="let tab of tabs; let i = index" [active]="nzSelectedIndex === i && !nzHideAll" [content]="tab.content" [forceRender]="tab.nzForceRender" [animated]="tabPaneAnimated" ></div> </div> </div> `, host: { class: 'ant-tabs', '[class.ant-tabs-card]': `nzType === 'card' || nzType === 'editable-card'`, '[class.ant-tabs-editable]': `nzType === 'editable-card'`, '[class.ant-tabs-editable-card]': `nzType === 'editable-card'`, '[class.ant-tabs-centered]': `nzCentered`, '[class.ant-tabs-rtl]': `dir === 'rtl'`, '[class.ant-tabs-top]': `nzTabPosition === 'top'`, '[class.ant-tabs-bottom]': `nzTabPosition === 'bottom'`, '[class.ant-tabs-left]': `nzTabPosition === 'left'`, '[class.ant-tabs-right]': `nzTabPosition === 'right'`, '[class.ant-tabs-default]': `nzSize === 'default'`, '[class.ant-tabs-small]': `nzSize === 'small'`, '[class.ant-tabs-large]': `nzSize === 'large'` }, imports: [ NzTabNavBarComponent, NgIf, NgStyle, NgForOf, NzTabNavItemDirective, A11yModule, NzOutletModule, NzTabCloseButtonComponent, NzTabBodyComponent ], standalone: true }] }], ctorParameters: () => [{ type: i1.NzConfigService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i2.Directionality, decorators: [{ type: Optional }] }, { type: i3.Router, decorators: [{ type: Optional }] }], propDecorators: { nzSelectedIndex: [{ type: Input }], nzTabPosition: [{ type: Input }], nzTabBarExtraContent: [{ type: Input }], nzCanDeactivate: [{ type: Input }], nzAddIcon: [{ type: Input }], nzTabBarStyle: [{ type: Input }], nzType: [{ type: Input }], nzSize: [{ type: Input }], nzAnimated: [{ type: Input }], nzTabBarGutter: [{ type: Input }], nzHideAdd: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzCentered: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzHideAll: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzLinkRouter: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzLinkExact: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzSelectChange: [{ type: Output }], nzSelectedIndexChange: [{ type: Output }], nzTabListScroll: [{ type: Output }], nzClose: [{ type: Output }], nzAdd: [{ type: Output }], allTabs: [{ type: ContentChildren, args: [NzTabComponent, { descendants: true }] }], tabNavBarRef: [{ type: ViewChild, args: [NzTabNavBarComponent, { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvdGFicy90YWJzZXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7QUFFSCw4REFBOEQ7QUFFOUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRS9DLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFHTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxlQUFlLEVBQ2YsWUFBWSxFQUNaLEtBQUssRUFJTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFFVCxTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQXNCLE1BQU0saUJBQWlCLENBQUM7QUFDcEUsT0FBTyxFQUFFLEtBQUssRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckYsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUUzRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUU3RCxPQUFPLEVBRUwsZ0JBQWdCLEVBTWpCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxr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QkFBdkIsTUFBTTtnQkE2QlAsT0FBTztzQkFETixlQUFlO3VCQUFDLGNBQWMsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7Z0JBRUYsWUFBWTtzQkFBL0QsU0FBUzt1QkFBQyxvQkFBb0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vKiogZ2V0IHNvbWUgY29kZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL21hdGVyaWFsMiAqL1xuXG5pbXBvcnQgeyBBMTF5TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2ExMXknO1xuaW1wb3J0IHsgRGlyZWN0aW9uLCBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IGNvZXJjZU51bWJlclByb3BlcnR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7IE5nRm9yT2YsIE5nSWYsIE5nU3R5bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50Q2hlY2tlZCxcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5hdmlnYXRpb25FbmQsIFJvdXRlciwgUm91dGVyTGluayB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVsYXksIGZpbHRlciwgZmlyc3QsIHN0YXJ0V2l0aCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOekNvbmZpZ0tleSwgTnpDb25maWdTZXJ2aWNlLCBXaXRoQ29uZmlnIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyBQUkVGSVggfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvbG9nZ2VyJztcbmltcG9ydCB7IE56T3V0bGV0TW9kdWxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL291dGxldCc7XG5pbXBvcnQgeyBOelNhZmVBbnksIE56U2l6ZUxEU1R5cGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgd3JhcEludG9PYnNlcnZhYmxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuXG5pbXBvcnQge1xuICBOekFuaW1hdGVkSW50ZXJmYWNlLFxuICBOelRhYkNoYW5nZUV2ZW50LFxuICBOelRhYlBvc2l0aW9uLFxuICBOelRhYlBvc2l0aW9uTW9kZSxcbiAgTnpUYWJzQ2FuRGVhY3RpdmF0ZUZuLFxuICBOelRhYlNjcm9sbEV2ZW50LFxuICBOelRhYlR5cGVcbn0gZnJvbSAnLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IE56VGFiQm9keUNvbXBvbmVudCB9IGZyb20gJy4vdGFiLWJvZHkuY29tcG9uZW50JztcbmltcG9ydCB7IE56VGFiQ2xvc2VCdXR0b25Db21wb25lbnQgfSBmcm9tICcuL3RhYi1jbG9zZS1idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7IE56VGFiTmF2QmFyQ29tcG9uZW50IH0gZnJvbSAnLi90YWItbmF2LWJhci5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnpUYWJOYXZJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi90YWItbmF2LWl0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IE5aX1RBQl9TRVQsIE56VGFiQ29tcG9uZW50IH0gZnJvbSAnLi90YWIuY29tcG9uZW50JztcblxuY29uc3QgTlpfQ09ORklHX01PRFVMRV9OQU1FOiBOekNvbmZpZ0tleSA9ICd0YWJzJztcblxubGV0IG5leHRJZCA9IDA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LXRhYnNldCcsXG4gIGV4cG9ydEFzOiAnbnpUYWJzZXQnLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5EZWZhdWx0LFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOWl9UQUJfU0VULFxuICAgICAgdXNlRXhpc3Rpbmc6IE56VGFiU2V0Q29tcG9uZW50XG4gICAgfVxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuei10YWJzLW5hdlxuICAgICAgKm5nSWY9XCJ0YWJzLmxlbmd0aCB8fCBhZGRhYmxlXCJcbiAgICAgIFtuZ1N0eWxlXT1cIm56VGFiQmFyU3R5bGVcIlxuICAgICAgW3NlbGVjdGVkSW5kZXhdPVwibnpTZWxlY3RlZEluZGV4IHx8IDBcIlxuICAgICAgW2lua0JhckFuaW1hdGVkXT1cImlua0JhckFuaW1hdGVkXCJcbiAgICAgIFthZGRhYmxlXT1cImFkZGFibGVcIlxuICAgICAgW2FkZEljb25dPVwibnpBZGRJY29uXCJcbiAgICAgIFtoaWRlQmFyXT1cIm56SGlkZUFsbFwiXG4gICAgICBbcG9zaXRpb25dPVwicG9zaXRpb25cIlxuICAgICAgW2V4dHJhVGVtcGxhdGVdPVwibnpUYWJCYXJFeHRyYUNvbnRlbnRcIlxuICAgICAgKHRhYlNjcm9sbCk9XCJuelRhYkxpc3RTY3JvbGwuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChzZWxlY3RGb2N1c2VkSW5kZXgpPVwic2V0U2VsZWN0ZWRJbmRleCgkZXZlbnQpXCJcbiAgICAgIChhZGRDbGlja2VkKT1cIm9uQWRkKClcIlxuICAgID5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJhbnQtdGFicy10YWJcIlxuICAgICAgICBbc3R5bGUubWFyZ2luLXJpZ2h0LnB4XT1cInBvc2l0aW9uID09PSAnaG9yaXpvbnRhbCcgPyBuelRhYkJhckd1dHRlciA6IG51bGxcIlxuICAgICAgICBbc3R5bGUubWFyZ2luLWJvdHRvbS5weF09XCJwb3NpdGlvbiA9PT0gJ3ZlcnRpY2FsJyA/IG56VGFiQmFyR3V0dGVyIDogbnVsbFwiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy10YWItYWN0aXZlXT1cIm56U2VsZWN0ZWRJbmRleCA9PT0gaVwiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy10YWItZGlzYWJsZWRdPVwidGFiLm56RGlzYWJsZWRcIlxuICAgICAgICAoY2xpY2spPVwiY2xpY2tOYXZJdGVtKHRhYiwgaSwgJGV2ZW50KVwiXG4gICAgICAgIChjb250ZXh0bWVudSk9XCJjb250ZXh0bWVudU5hdkl0ZW0odGFiLCAkZXZlbnQpXCJcbiAgICAgICAgKm5nRm9yPVwibGV0IHRhYiBvZiB0YWJzOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgID5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIHJvbGU9XCJ0YWJcIlxuICAgICAgICAgIFtpZF09XCJnZXRUYWJDb250ZW50SWQoaSlcIlxuICAgICAgICAgIFthdHRyLnRhYkluZGV4XT1cImdldFRhYkluZGV4KHRhYiwgaSlcIlxuICAgICAgICAgIFthdHRyLmFyaWEtZGlzYWJsZWRdPVwidGFiLm56RGlzYWJsZWRcIlxuICAgICAgICAgIFthdHRyLmFyaWEtc2VsZWN0ZWRdPVwibnpTZWxlY3RlZEluZGV4ID09PSBpICYmICFuekhpZGVBbGxcIlxuICAgICAgICAgIFthdHRyLmFyaWEtY29udHJvbHNdPVwiZ2V0VGFiQ29udGVudElkKGkpXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwidGFiLm56RGlzYWJsZWRcIlxuICAgICAgICAgIFt0YWJdPVwidGFiXCJcbiAgICAgICAgICBbYWN0aXZlXT1cIm56U2VsZWN0ZWRJbmRleCA9PT0gaVwiXG4gICAgICAgICAgY2xhc3M9XCJhbnQtdGFicy10YWItYnRuXCJcbiAgICAgICAgICBuelRhYk5hdkl0ZW1cbiAgICAgICAgICBjZGtNb25pdG9yRWxlbWVudEZvY3VzXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwidGFiLmxhYmVsOyBjb250ZXh0OiB7IHZpc2libGU6IHRydWUgfVwiPnt7IHRhYi5sYWJlbCB9fTwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgbnotdGFiLWNsb3NlLWJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJ0YWIubnpDbG9zYWJsZSAmJiBjbG9zYWJsZSAmJiAhdGFiLm56RGlzYWJsZWRcIlxuICAgICAgICAgICAgW2Nsb3NlSWNvbl09XCJ0YWIubnpDbG9zZUljb25cIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xvc2UoaSwgJGV2ZW50KVwiXG4gICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbnotdGFicy1uYXY+XG4gICAgPGRpdiBjbGFzcz1cImFudC10YWJzLWNvbnRlbnQtaG9sZGVyXCI+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYW50LXRhYnMtY29udGVudFwiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LXRvcF09XCJuelRhYlBvc2l0aW9uID09PSAndG9wJ1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LWJvdHRvbV09XCJuelRhYlBvc2l0aW9uID09PSAnYm90dG9tJ1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LWxlZnRdPVwibnpUYWJQb3NpdGlvbiA9PT0gJ2xlZnQnXCJcbiAgICAgICAgW2NsYXNzLmFudC10YWJzLWNvbnRlbnQtcmlnaHRdPVwibnpUYWJQb3NpdGlvbiA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LWFuaW1hdGVkXT1cInRhYlBhbmVBbmltYXRlZFwiXG4gICAgICA+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICByb2xlPVwidGFicGFuZWxcIlxuICAgICAgICAgIFtpZF09XCJnZXRUYWJDb250ZW50SWQoaSlcIlxuICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxsZWRieV09XCJnZXRUYWJDb250ZW50SWQoaSlcIlxuICAgICAgICAgIG56LXRhYi1ib2R5XG4gICAgICAgICAgKm5nRm9yPVwibGV0IHRhYiBvZiB0YWJzOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbYWN0aXZlXT1cIm56U2VsZWN0ZWRJbmRleCA9PT0gaSAmJiAhbnpIaWRlQWxsXCJcbiAgICAgICAgICBbY29udGVudF09XCJ0YWIuY29udGVudFwiXG4gICAgICAgICAg