UNPKG

ng-zorro-antd

Version:

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

293 lines (291 loc) 35.6 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 */ import { normalizePassiveListenerOptions } from '@angular/cdk/platform'; import { DOCUMENT, NgClass, NgIf, NgStyle, NgTemplateOutlet } from '@angular/common'; import { booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, inject, Input, numberAttribute, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { takeUntil, throttleTime } from 'rxjs/operators'; import { NzAffixModule } from 'ng-zorro-antd/affix'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { numberAttributeWithZeroFallback } from 'ng-zorro-antd/core/util'; import { getOffsetTop } from './util'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "ng-zorro-antd/core/services"; import * as i3 from "@angular/cdk/platform"; import * as i4 from "ng-zorro-antd/affix"; const VISIBLE_CLASSNAME = 'ant-anchor-ink-ball-visible'; const NZ_CONFIG_MODULE_NAME = 'anchor'; const sharpMatcherRegx = /#([^#]+)$/; const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true }); export class NzAnchorComponent { constructor(nzConfigService, scrollSrv, cdr, platform, zone, renderer) { this.nzConfigService = nzConfigService; this.scrollSrv = scrollSrv; this.cdr = cdr; this.platform = platform; this.zone = zone; this.renderer = renderer; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzAffix = true; this.nzShowInkInFixed = false; this.nzBounds = 5; this.nzOffsetTop = undefined; this.nzTargetOffset = undefined; this.nzDirection = 'vertical'; this.nzClick = new EventEmitter(); this.nzChange = new EventEmitter(); this.nzScroll = new EventEmitter(); this.visible = false; this.wrapperStyle = { 'max-height': '100vh' }; this.links = []; this.animating = false; this.destroy$ = new Subject(); this.doc = inject(DOCUMENT); } registerLink(link) { this.links.push(link); } unregisterLink(link) { this.links.splice(this.links.indexOf(link), 1); } getContainer() { return this.container || window; } ngAfterViewInit() { this.registerScrollEvent(); } ngOnDestroy() { clearTimeout(this.handleScrollTimeoutID); this.destroy$.next(true); this.destroy$.complete(); } registerScrollEvent() { if (!this.platform.isBrowser) { return; } this.destroy$.next(true); this.zone.runOutsideAngular(() => { fromEvent(this.getContainer(), 'scroll', passiveEventListenerOptions) .pipe(throttleTime(50), takeUntil(this.destroy$)) .subscribe(() => this.handleScroll()); }); // Browser would maintain the scrolling position when refreshing. // So we have to delay calculation in avoid of getting a incorrect result. this.handleScrollTimeoutID = setTimeout(() => this.handleScroll()); } handleScroll() { if (typeof document === 'undefined' || this.animating) { return; } const sections = []; const offsetTop = this.nzTargetOffset ? this.nzTargetOffset : this.nzOffsetTop || 0; const scope = offsetTop + this.nzBounds; this.links.forEach(comp => { const sharpLinkMatch = sharpMatcherRegx.exec(comp.nzHref.toString()); if (!sharpLinkMatch) { return; } const target = this.doc.getElementById(sharpLinkMatch[1]); if (target) { const top = getOffsetTop(target, this.getContainer()); if (top < scope) { sections.push({ top, comp }); } } }); this.visible = !!sections.length; if (!this.visible) { this.clearActive(); this.cdr.detectChanges(); } else { const maxSection = sections.reduce((prev, curr) => (curr.top > prev.top ? curr : prev)); this.handleActive(maxSection.comp); } this.setVisible(); } clearActive() { this.links.forEach(i => { i.unsetActive(); }); } setActive(comp) { const originalActiveLink = this.activeLink; const targetComp = (this.nzCurrentAnchor && this.links.find(n => n.nzHref === this.nzCurrentAnchor)) || comp; if (!targetComp) return; targetComp.setActive(); const linkNode = targetComp.getLinkTitleElement(); if (this.nzDirection === 'vertical') { this.ink.nativeElement.style.top = `${linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5}px`; } else { this.ink.nativeElement.style.left = `${linkNode.offsetLeft + linkNode.clientWidth / 2}px`; } this.activeLink = (comp || targetComp).nzHref; if (originalActiveLink !== this.activeLink) { this.nzChange.emit(this.activeLink); } } handleActive(comp) { this.clearActive(); this.setActive(comp); this.visible = true; this.setVisible(); this.nzScroll.emit(comp); } setVisible() { if (this.ink) { const visible = this.visible; if (visible) { this.renderer.addClass(this.ink.nativeElement, VISIBLE_CLASSNAME); } else { this.renderer.removeClass(this.ink.nativeElement, VISIBLE_CLASSNAME); } } } handleScrollTo(linkComp) { const el = this.doc.querySelector(linkComp.nzHref); if (!el) { return; } this.animating = true; const containerScrollTop = this.scrollSrv.getScroll(this.getContainer()); const elOffsetTop = getOffsetTop(el, this.getContainer()); let targetScrollTop = containerScrollTop + elOffsetTop; targetScrollTop -= this.nzTargetOffset !== undefined ? this.nzTargetOffset : this.nzOffsetTop || 0; this.scrollSrv.scrollTo(this.getContainer(), targetScrollTop, { callback: () => { this.animating = false; this.handleActive(linkComp); } }); this.nzClick.emit(linkComp.nzHref); } ngOnChanges(changes) { const { nzOffsetTop, nzContainer, nzCurrentAnchor } = changes; if (nzOffsetTop) { this.wrapperStyle = { 'max-height': `calc(100vh - ${this.nzOffsetTop}px)` }; } if (nzContainer) { const container = this.nzContainer; this.container = typeof container === 'string' ? this.doc.querySelector(container) : container; this.registerScrollEvent(); } if (nzCurrentAnchor) { this.setActive(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzAnchorComponent, deps: [{ token: i1.NzConfigService }, { token: i2.NzScrollService }, { token: i0.ChangeDetectorRef }, { token: i3.Platform }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: NzAnchorComponent, isStandalone: true, selector: "nz-anchor", inputs: { nzAffix: ["nzAffix", "nzAffix", booleanAttribute], nzShowInkInFixed: ["nzShowInkInFixed", "nzShowInkInFixed", booleanAttribute], nzBounds: ["nzBounds", "nzBounds", numberAttribute], nzOffsetTop: ["nzOffsetTop", "nzOffsetTop", numberAttributeWithZeroFallback], nzTargetOffset: ["nzTargetOffset", "nzTargetOffset", numberAttributeWithZeroFallback], nzContainer: "nzContainer", nzCurrentAnchor: "nzCurrentAnchor", nzDirection: "nzDirection" }, outputs: { nzClick: "nzClick", nzChange: "nzChange", nzScroll: "nzScroll" }, viewQueries: [{ propertyName: "ink", first: true, predicate: ["ink"], descendants: true }], exportAs: ["nzAnchor"], usesOnChanges: true, ngImport: i0, template: ` @if (nzAffix) { <nz-affix [nzOffsetTop]="nzOffsetTop" [nzTarget]="container"> <ng-template [ngTemplateOutlet]="content"></ng-template> </nz-affix> } @else { <ng-template [ngTemplateOutlet]="content"></ng-template> } <ng-template #content> <div class="ant-anchor-wrapper" [ngClass]="{ 'ant-anchor-wrapper-horizontal': nzDirection === 'horizontal' }" [ngStyle]="wrapperStyle" > <div class="ant-anchor" [ngClass]="{ 'ant-anchor-fixed': !nzAffix && !nzShowInkInFixed }"> <div class="ant-anchor-ink"> <div class="ant-anchor-ink-ball" #ink></div> </div> <ng-content></ng-content> </div> </div> </ng-template> `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NzAffixModule }, { kind: "component", type: i4.NzAffixComponent, selector: "nz-affix", inputs: ["nzTarget", "nzOffsetTop", "nzOffsetBottom"], outputs: ["nzChange"], exportAs: ["nzAffix"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzShowInkInFixed", void 0); __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzBounds", void 0); __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzOffsetTop", void 0); __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzTargetOffset", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzAnchorComponent, decorators: [{ type: Component, args: [{ selector: 'nz-anchor', exportAs: 'nzAnchor', preserveWhitespaces: false, standalone: true, imports: [NgClass, NgIf, NgStyle, NgTemplateOutlet, NzAffixModule], template: ` @if (nzAffix) { <nz-affix [nzOffsetTop]="nzOffsetTop" [nzTarget]="container"> <ng-template [ngTemplateOutlet]="content"></ng-template> </nz-affix> } @else { <ng-template [ngTemplateOutlet]="content"></ng-template> } <ng-template #content> <div class="ant-anchor-wrapper" [ngClass]="{ 'ant-anchor-wrapper-horizontal': nzDirection === 'horizontal' }" [ngStyle]="wrapperStyle" > <div class="ant-anchor" [ngClass]="{ 'ant-anchor-fixed': !nzAffix && !nzShowInkInFixed }"> <div class="ant-anchor-ink"> <div class="ant-anchor-ink-ball" #ink></div> </div> <ng-content></ng-content> </div> </div> </ng-template> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush }] }], ctorParameters: () => [{ type: i1.NzConfigService }, { type: i2.NzScrollService }, { type: i0.ChangeDetectorRef }, { type: i3.Platform }, { type: i0.NgZone }, { type: i0.Renderer2 }], propDecorators: { ink: [{ type: ViewChild, args: ['ink', { static: false }] }], nzAffix: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzShowInkInFixed: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzBounds: [{ type: Input, args: [{ transform: numberAttribute }] }], nzOffsetTop: [{ type: Input, args: [{ transform: numberAttributeWithZeroFallback }] }], nzTargetOffset: [{ type: Input, args: [{ transform: numberAttributeWithZeroFallback }] }], nzContainer: [{ type: Input }], nzCurrentAnchor: [{ type: Input }], nzDirection: [{ type: Input }], nzClick: [{ type: Output }], nzChange: [{ type: Output }], nzScroll: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5jaG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvYW5jaG9yL2FuY2hvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSwrQkFBK0IsRUFBWSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRixPQUFPLEVBRUwsZ0JBQWdCLEVBQ2hCLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBRUwsZUFBZSxFQUdmLE1BQU0sRUFHTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHckYsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHMUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQzs7Ozs7O0FBT3RDLE1BQU0saUJBQWlCLEdBQUcsNkJBQTZCLENBQUM7QUFDeEQsTUFBTSxxQkFBcUIsR0FBZ0IsUUFBUSxDQUFDO0FBQ3BELE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDO0FBRXJDLE1BQU0sMkJBQTJCLEdBQUcsK0JBQStCLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQW1DdkYsTUFBTSxPQUFPLGlCQUFp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Q2xFLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1QlQ7b0JBQ0QsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2lCQUNoRDtzTkFJOEMsR0FBRztzQkFBL0MsU0FBUzt1QkFBQyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUVLLE9BQU87c0JBQTlDLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBSXRDLGdCQUFnQjtzQkFGZixLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQU10QyxRQUFRO3NCQUZQLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFO2dCQU1yQyxXQUFXO3NCQUZWLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsK0JBQStCLEVBQUU7Z0JBTXJELGNBQWM7c0JBRmIsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSwrQkFBK0IsRUFBRTtnQkFJNUMsV0FBVztzQkFBbkIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRWEsT0FBTztzQkFBekIsTUFBTTtnQkFDWSxRQUFRO3NCQUExQixNQUFNO2dCQUNZLFFBQVE7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zLCBQbGF0Zm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5pbXBvcnQgeyBET0NVTUVOVCwgTmdDbGFzcywgTmdJZiwgTmdTdHlsZSwgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBib29sZWFuQXR0cmlidXRlLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBpbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIG51bWJlckF0dHJpYnV0ZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwsIHRocm90dGxlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpBZmZpeE1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvYWZmaXgnO1xuaW1wb3J0IHsgTnpDb25maWdLZXksIE56Q29uZmlnU2VydmljZSwgV2l0aENvbmZpZyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9jb25maWcnO1xuaW1wb3J0IHsgTnpTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3NlcnZpY2VzJztcbmltcG9ydCB7IE5nU3R5bGVJbnRlcmZhY2UsIE56RGlyZWN0aW9uVkhUeXBlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IG51bWJlckF0dHJpYnV0ZVdpdGhaZXJvRmFsbGJhY2sgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5cbmltcG9ydCB7IE56QW5jaG9yTGlua0NvbXBvbmVudCB9IGZyb20gJy4vYW5jaG9yLWxpbmsuY29tcG9uZW50JztcbmltcG9ydCB7IGdldE9mZnNldFRvcCB9IGZyb20gJy4vdXRpbCc7XG5cbmludGVyZmFjZSBTZWN0aW9uIHtcbiAgY29tcDogTnpBbmNob3JMaW5rQ29tcG9uZW50O1xuICB0b3A6IG51bWJlcjtcbn1cblxuY29uc3QgVklTSUJMRV9DTEFTU05BTUUgPSAnYW50LWFuY2hvci1pbmstYmFsbC12aXNpYmxlJztcbmNvbnN0IE5aX0NPTkZJR19NT0RVTEVfTkFNRTogTnpDb25maWdLZXkgPSAnYW5jaG9yJztcbmNvbnN0IHNoYXJwTWF0Y2hlclJlZ3ggPSAvIyhbXiNdKykkLztcblxuY29uc3QgcGFzc2l2ZUV2ZW50TGlzdGVuZXJPcHRpb25zID0gbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyh7IHBhc3NpdmU6IHRydWUgfSk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LWFuY2hvcicsXG4gIGV4cG9ydEFzOiAnbnpBbmNob3InLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nQ2xhc3MsIE5nSWYsIE5nU3R5bGUsIE5nVGVtcGxhdGVPdXRsZXQsIE56QWZmaXhNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIEBpZiAobnpBZmZpeCkge1xuICAgICAgPG56LWFmZml4IFtuek9mZnNldFRvcF09XCJuek9mZnNldFRvcFwiIFtuelRhcmdldF09XCJjb250YWluZXJcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRlbnRcIj48L25nLXRlbXBsYXRlPlxuICAgICAgPC9uei1hZmZpeD5cbiAgICB9IEBlbHNlIHtcbiAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICB9XG5cbiAgICA8bmctdGVtcGxhdGUgI2NvbnRlbnQ+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYW50LWFuY2hvci13cmFwcGVyXCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnYW50LWFuY2hvci13cmFwcGVyLWhvcml6b250YWwnOiBuekRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnIH1cIlxuICAgICAgICBbbmdTdHlsZV09XCJ3cmFwcGVyU3R5bGVcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWFuY2hvclwiIFtuZ0NsYXNzXT1cInsgJ2FudC1hbmNob3ItZml4ZWQnOiAhbnpBZmZpeCAmJiAhbnpTaG93SW5rSW5GaXhlZCB9XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1hbmNob3ItaW5rXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWFuY2hvci1pbmstYmFsbFwiICNpbms+PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIGAsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE56QW5jaG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMge1xuICByZWFkb25seSBfbnpNb2R1bGVOYW1lOiBOekNvbmZpZ0tleSA9IE5aX0NPTkZJR19NT0RVTEVfTkFNRTtcblxuICBAVmlld0NoaWxkKCdpbmsnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBpbmshOiBFbGVtZW50UmVmO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBuekFmZml4ID0gdHJ1ZTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSlcbiAgQFdpdGhDb25maWcoKVxuICBuelNob3dJbmtJbkZpeGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSlcbiAgQFdpdGhDb25maWcoKVxuICBuekJvdW5kczogbnVtYmVyID0gNTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZVdpdGhaZXJvRmFsbGJhY2sgfSlcbiAgQFdpdGhDb25maWc8bnVtYmVyPigpXG4gIG56T2Zmc2V0VG9wPzogbnVtYmVyID0gdW5kZWZpbmVkO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlV2l0aFplcm9GYWxsYmFjayB9KVxuICBAV2l0aENvbmZpZzxudW1iZXI+KClcbiAgbnpUYXJnZXRPZmZzZXQ/OiBudW1iZXIgPSB1bmRlZmluZWQ7XG5cbiAgQElucHV0KCkgbnpDb250YWluZXI/OiBzdHJpbmcgfCBIVE1MRWxlbWVudDtcbiAgQElucHV0KCkgbnpDdXJyZW50QW5jaG9yPzogc3RyaW5nO1xuICBASW5wdXQoKSBuekRpcmVjdGlvbjogTnpEaXJlY3Rpb25WSFR5cGUgPSAndmVydGljYWwnO1xuXG4gIEBPdXRwdXQoKSByZWFkb25seSBuekNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuekNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpTY3JvbGwgPSBuZXcgRXZlbnRFbWl0dGVyPE56QW5jaG9yTGlua0NvbXBvbmVudD4oKTtcblxuICB2aXNpYmxlID0gZmFsc2U7XG4gIHdyYXBwZXJTdHlsZTogTmdTdHlsZUludGVyZmFjZSA9IHsgJ21heC1oZWlnaHQnOiAnMTAwdmgnIH07XG5cbiAgY29udGFpbmVyPzogSFRNTEVsZW1lbnQgfCBXaW5kb3c7XG4gIGFjdGl2ZUxpbms/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBsaW5rczogTnpBbmNob3JMaW5rQ29tcG9uZW50W10gPSBbXTtcbiAgcHJpdmF0ZSBhbmltYXRpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG4gIHByaXZhdGUgaGFuZGxlU2Nyb2xsVGltZW91dElEPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG4gIHByaXZhdGUgZG9jOiBEb2N1bWVudCA9IGluamVjdChET0NVTUVOVCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG56Q29uZmlnU2VydmljZTogTnpDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2Nyb2xsU3J2OiBOelNjcm9sbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgIHByaXZhdGUgem9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMlxuICApIHt9XG5cbiAgcmVnaXN0ZXJMaW5rKGxpbms6IE56QW5jaG9yTGlua0NvbXBvbmVudCk6IHZvaWQge1xuICAgIHRoaXMubGlua3MucHVzaChsaW5rKTtcbiAgfVxuXG4gIHVucmVnaXN0ZXJMaW5rKGxpbms6IE56QW5jaG9yTGlua0NvbXBvbmVudCk6IHZvaWQge1xuICAgIHRoaXMubGlua3Muc3BsaWNlKHRoaXMubGlua3MuaW5kZXhPZihsaW5rKSwgMSk7XG4gIH1cblxuICBwcml2YXRlIGdldENvbnRhaW5lcigpOiBIVE1MRWxlbWVudCB8IFdpbmRvdyB7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyIHx8IHdpbmRvdztcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lzdGVyU2Nyb2xsRXZlbnQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmhhbmRsZVNjcm9sbFRpbWVvdXRJRCk7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJTY3JvbGxFdmVudCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucGxhdGZvcm0uaXNCcm93c2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50KHRoaXMuZ2V0Q29udGFpbmVyKCksICdzY3JvbGwnLCA8QWRkRXZlbnRMaXN0ZW5lck9wdGlvbnM+cGFzc2l2ZUV2ZW50TGlzdGVuZXJPcHRpb25zKVxuICAgICAgICAucGlwZSh0aHJvdHRsZVRpbWUoNTApLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5oYW5kbGVTY3JvbGwoKSk7XG4gICAgfSk7XG4gICAgLy8gQnJvd3NlciB3b3VsZCBtYWludGFpbiB0aGUgc2Nyb2xsaW5nIHBvc2l0aW9uIHdoZW4gcmVmcmVzaGluZy5cbiAgICAvLyBTbyB3ZSBoYXZlIHRvIGRlbGF5IGNhbGN1bGF0aW9uIGluIGF2b2lkIG9mIGdldHRpbmcgYSBpbmNvcnJlY3QgcmVzdWx0LlxuICAgIHRoaXMuaGFuZGxlU2Nyb2xsVGltZW91dElEID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLmhhbmRsZVNjcm9sbCgpKTtcbiAgfVxuXG4gIGhhbmRsZVNjcm9sbCgpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLmFuaW1hdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNlY3Rpb25zOiBTZWN0aW9uW10gPSBbXTtcbiAgICBjb25zdCBvZmZzZXRUb3AgPSB0aGlzLm56VGFyZ2V0T2Zmc2V0ID8gdGhpcy5uelRhcmdldE9mZnNldCA6IHRoaXMubnpPZmZzZXRUb3AgfHwgMDtcbiAgICBjb25zdCBzY29wZSA9IG9mZnNldFRvcCArIHRoaXMubnpCb3VuZHM7XG4gICAgdGhpcy5saW5rcy5mb3JFYWNoKGNvbXAgPT4ge1xuICAgICAgY29uc3Qgc2hhcnBMaW5rTWF0Y2ggPSBzaGFycE1hdGNoZXJSZWd4LmV4ZWMoY29tcC5uekhyZWYudG9TdHJpbmcoKSk7XG4gICAgICBpZiAoIXNoYXJwTGlua01hdGNoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZG9jLmdldEVsZW1lbnRCeUlkKHNoYXJwTGlua01hdGNoWzFdKTtcbiAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgY29uc3QgdG9wID0gZ2V0T2Zmc2V0VG9wKHRhcmdldCwgdGhpcy5nZXRDb250YWluZXIoKSk7XG4gICAgICAgIGlmICh0b3AgPCBzY29wZSkge1xuICAgICAgICAgIHNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgdG9wLFxuICAgICAgICAgICAgY29tcFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnZpc2libGUgPSAhIXNlY3Rpb25zLmxlbmd0aDtcbiAgICBpZiAoIXRoaXMudmlzaWJsZSkge1xuICAgICAgdGhpcy5jbGVhckFjdGl2ZSgpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBtYXhTZWN0aW9uID0gc2VjdGlvbnMucmVkdWNlKChwcmV2LCBjdXJyKSA9PiAoY3Vyci50b3AgPiBwcmV2LnRvcCA/IGN1cnIgOiBwcmV2KSk7XG4gICAgICB0aGlzLmhhbmRsZUFjdGl2ZShtYXhTZWN0aW9uLmNvbXApO1xuICAgIH1cbiAgICB0aGlzLnNldFZpc2libGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJBY3RpdmUoKTogdm9pZCB7XG4gICAgdGhpcy5saW5rcy5mb3JFYWNoKGkgPT4ge1xuICAgICAgaS51bnNldEFjdGl2ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRBY3RpdmUoY29tcD86IE56QW5jaG9yTGlua0NvbXBvbmVudCk6IHZvaWQge1xuICAgIGNvbnN0IG9yaWdpbmFsQWN0aXZlTGluayA9IHRoaXMuYWN0aXZlTGluaztcbiAgICBjb25zdCB0YXJnZXRDb21wID0gKHRoaXMubnpDdXJyZW50QW5jaG9yICYmIHRoaXMubGlua3MuZmluZChuID0+IG4ubnpIcmVmID09PSB0aGlzLm56Q3VycmVudEFuY2hvcikpIHx8IGNvbXA7XG4gICAgaWYgKCF0YXJnZXRDb21wKSByZXR1cm47XG5cbiAgICB0YXJnZXRDb21wLnNldEFjdGl2ZSgpO1xuICAgIGNvbnN0IGxpbmtOb2RlID0gdGFyZ2V0Q29tcC5nZXRMaW5rVGl0bGVFbGVtZW50KCk7XG4gICAgaWYgKHRoaXMubnpEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgIHRoaXMuaW5rLm5hdGl2ZUVsZW1lbnQuc3R5bGUudG9wID0gYCR7bGlua05vZGUub2Zmc2V0VG9wICsgbGlua05vZGUuY2xpZW50SGVpZ2h0IC8gMiAtIDQuNX1weGA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW5rLm5hdGl2ZUVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xpbmtOb2RlLm9mZnNldExlZnQgKyBsaW5rTm9kZS5jbGllbnRXaWR0aCAvIDJ9cHhgO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZUxpbmsgPSAoY29tcCB8fCB0YXJnZXRDb21wKS5uekhyZWY7XG4gICAgaWYgKG9yaWdpbmFsQWN0aXZlTGluayAhPT0gdGhpcy5hY3RpdmVMaW5rKSB7XG4gICAgICB0aGlzLm56Q2hhbmdlLmVtaXQodGhpcy5hY3RpdmVMaW5rKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUFjdGl2ZShjb21wOiBOekFuY2hvckxpbmtDb21wb25lbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyQWN0aXZlKCk7XG4gICAgdGhpcy5zZXRBY3RpdmUoY29tcCk7XG4gICAgdGhpcy52aXNpYmxlID0gdHJ1ZTtcbiAgICB0aGlzLnNldFZpc2libGUoKTtcbiAgICB0aGlzLm56U2Nyb2xsLmVtaXQoY29tcCk7XG4gIH1cblxuICBwcml2YXRlIHNldFZpc2libGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW5rKSB7XG4gICAgICBjb25zdCB2aXNpYmxlID0gdGhpcy52aXNpYmxlO1xuICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmluay5uYXRpdmVFbGVtZW50LCBWSVNJQkxFX0NMQVNTTkFNRSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuaW5rLm5hdGl2ZUVsZW1lbnQsIFZJU0lCTEVfQ0xBU1NOQU1FKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVTY3JvbGxUbyhsaW5rQ29tcDogTnpBbmNob3JMaW5rQ29tcG9uZW50KTogdm9pZCB7XG4gICAgY29uc3QgZWwgPSB0aGlzLmRvYy5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihsaW5rQ29tcC5uekhyZWYpO1xuICAgIGlmICghZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmFuaW1hdGluZyA9IHRydWU7XG4gICAgY29uc3QgY29udGFpbmVyU2Nyb2xsVG9wID0gdGhpcy5zY3JvbGxTcnYuZ2V0U2Nyb2xsKHRoaXMuZ2V0Q29udGFpbmVyKCkpO1xuICAgIGNvbnN0IGVsT2Zmc2V0VG9wID0gZ2V0T2Zmc2V0VG9wKGVsLCB0aGlzLmdldENvbnRhaW5lcigpKTtcbiAgICBsZXQgdGFyZ2V0U2Nyb2xsVG9wID0gY29udGFpbmVyU2Nyb2xsVG9wICsgZWxPZmZzZXRUb3A7XG4gICAgdGFyZ2V0U2Nyb2xsVG9wIC09IHRoaXMubnpUYXJnZXRPZmZzZXQgIT09IHVuZGVmaW5lZCA/IHRoaXMubnpUYXJnZXRPZmZzZXQgOiB0aGlzLm56T2Zmc2V0VG9wIHx8IDA7XG4gICAgdGhpcy5zY3JvbGxTcnYuc2Nyb2xsVG8odGhpcy5nZXRDb250YWluZXIoKSwgdGFyZ2V0U2Nyb2xsVG9wLCB7XG4gICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICB0aGlzLmFuaW1hdGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmhhbmRsZUFjdGl2ZShsaW5rQ29tcCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5uekNsaWNrLmVtaXQobGlua0NvbXAubnpIcmVmKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IG56T2Zmc2V0VG9wLCBuekNvbnRhaW5lciwgbnpDdXJyZW50QW5jaG9yIH0gPSBjaGFuZ2VzO1xuICAgIGlmIChuek9mZnNldFRvcCkge1xuICAgICAgdGhpcy53cmFwcGVyU3R5bGUgPSB7XG4gICAgICAgICdtYXgtaGVpZ2h0JzogYGNhbGMoMTAwdmggLSAke3RoaXMubnpPZmZzZXRUb3B9cHgpYFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG56Q29udGFpbmVyKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLm56Q29udGFpbmVyO1xuICAgICAgdGhpcy5jb250YWluZXIgPSB0eXBlb2YgY29udGFpbmVyID09PSAnc3RyaW5nJyA/IHRoaXMuZG9jLnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KGNvbnRhaW5lcikhIDogY29udGFpbmVyO1xuICAgICAgdGhpcy5yZWdpc3RlclNjcm9sbEV2ZW50KCk7XG4gICAgfVxuICAgIGlmIChuekN1cnJlbnRBbmNob3IpIHtcbiAgICAgIHRoaXMuc2V0QWN0aXZlKCk7XG4gICAgfVxuICB9XG59XG4iXX0=