UNPKG

ng-zorro-antd

Version:

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

434 lines (432 loc) 50.3 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 { Directionality } from '@angular/cdk/bidi'; import { LEFT_ARROW, RIGHT_ARROW } from '@angular/cdk/keycodes'; import { NgTemplateOutlet } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, booleanAttribute, inject, numberAttribute } from '@angular/core'; import { Subject, fromEvent } from 'rxjs'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { NzCarouselContentDirective } from './carousel-content.directive'; import { NzCarouselOpacityStrategy } from './strategies/opacity-strategy'; import { NzCarouselTransformStrategy } from './strategies/transform-strategy'; import { NZ_CAROUSEL_CUSTOM_STRATEGIES } from './typings'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "@angular/cdk/platform"; import * as i3 from "ng-zorro-antd/core/services"; import * as i4 from "ng-zorro-antd/cdk/resize-observer"; const NZ_CONFIG_MODULE_NAME = 'carousel'; export class NzCarouselComponent { set nzDotPosition(value) { this._dotPosition = value; if (value === 'left' || value === 'right') { this.vertical = true; } else { this.vertical = false; } } get nzDotPosition() { return this._dotPosition; } constructor(elementRef, nzConfigService, ngZone, renderer, cdr, platform, resizeService, nzDragService, nzResizeObserver) { this.nzConfigService = nzConfigService; this.ngZone = ngZone; this.renderer = renderer; this.cdr = cdr; this.platform = platform; this.resizeService = resizeService; this.nzDragService = nzDragService; this.nzResizeObserver = nzResizeObserver; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzEffect = 'scrollx'; this.nzEnableSwipe = true; this.nzDots = true; this.nzAutoPlay = false; this.nzAutoPlaySpeed = 3000; this.nzTransitionSpeed = 500; this.nzLoop = true; /** * this property is passed directly to an NzCarouselBaseStrategy */ this.nzStrategyOptions = undefined; this._dotPosition = 'bottom'; this.nzBeforeChange = new EventEmitter(); this.nzAfterChange = new EventEmitter(); this.activeIndex = 0; this.vertical = false; this.dir = 'ltr'; this.destroy$ = new Subject(); this.gestureRect = null; this.pointerDelta = null; this.isTransiting = false; this.isDragging = false; this.directionality = inject(Directionality); this.customStrategies = inject(NZ_CAROUSEL_CUSTOM_STRATEGIES, { optional: true }); this.onLiClick = (index) => { if (this.dir === 'rtl') { this.goTo(this.carouselContents.length - 1 - index); } else { this.goTo(index); } }; /** * Drag carousel. */ this.pointerDown = (event) => { if (!this.isDragging && !this.isTransiting && this.nzEnableSwipe) { this.clearScheduledTransition(); this.gestureRect = this.slickListEl.getBoundingClientRect(); this.nzDragService.requestDraggingSequence(event).subscribe(delta => { this.pointerDelta = delta; this.isDragging = true; this.strategy?.dragging(this.pointerDelta); }, () => { }, () => { if (this.nzEnableSwipe && this.isDragging) { const xDelta = this.pointerDelta ? this.pointerDelta.x : 0; // Switch to another slide if delta is bigger than third of the width. if (Math.abs(xDelta) > this.gestureRect.width / 3 && (this.nzLoop || (xDelta <= 0 && this.activeIndex + 1 < this.carouselContents.length) || (xDelta > 0 && this.activeIndex > 0))) { this.goTo(xDelta > 0 ? this.activeIndex - 1 : this.activeIndex + 1); } else { this.goTo(this.activeIndex); } this.gestureRect = null; this.pointerDelta = null; } this.isDragging = false; }); } }; this.nzDotPosition = 'bottom'; this.el = elementRef.nativeElement; } ngOnInit() { this.slickListEl = this.slickList.nativeElement; this.slickTrackEl = this.slickTrack.nativeElement; this.dir = this.directionality.value; this.directionality.change.pipe(takeUntil(this.destroy$)).subscribe((direction) => { this.dir = direction; this.markContentActive(this.activeIndex); this.cdr.detectChanges(); }); this.ngZone.runOutsideAngular(() => { fromEvent(this.slickListEl, 'keydown') .pipe(takeUntil(this.destroy$)) .subscribe(event => { const { keyCode } = event; if (keyCode !== LEFT_ARROW && keyCode !== RIGHT_ARROW) { return; } event.preventDefault(); this.ngZone.run(() => { if (keyCode === LEFT_ARROW) { this.pre(); } else { this.next(); } this.cdr.markForCheck(); }); }); }); this.nzResizeObserver .observe(this.el) .pipe(debounceTime(100), distinctUntilChanged(), takeUntil(this.destroy$)) .subscribe(() => { this.layout(); }); } ngAfterContentInit() { this.markContentActive(0); } ngAfterViewInit() { this.carouselContents.changes.subscribe(() => { this.markContentActive(0); this.layout(); }); this.resizeService .subscribe() .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.layout(); }); this.switchStrategy(); this.markContentActive(0); this.layout(); // If embedded in an entry component, it may do initial render at an inappropriate time. // ngZone.onStable won't do this trick // TODO: need to change this. Promise.resolve().then(() => { this.layout(); }); } ngOnChanges(changes) { const { nzEffect, nzDotPosition } = changes; if (nzEffect && !nzEffect.isFirstChange()) { this.switchStrategy(); this.markContentActive(0); this.layout(); } if (nzDotPosition && !nzDotPosition.isFirstChange()) { this.switchStrategy(); this.markContentActive(0); this.layout(); } if (!this.nzAutoPlay || !this.nzAutoPlaySpeed) { this.clearScheduledTransition(); } else { this.scheduleNextTransition(); } } ngOnDestroy() { this.clearScheduledTransition(); if (this.strategy) { this.strategy.dispose(); } this.destroy$.next(); this.destroy$.complete(); } next() { this.goTo(this.activeIndex + 1); } pre() { this.goTo(this.activeIndex - 1); } goTo(index) { if (this.carouselContents && this.carouselContents.length && !this.isTransiting && (this.nzLoop || (index >= 0 && index < this.carouselContents.length))) { const length = this.carouselContents.length; const from = this.activeIndex; const to = (index + length) % length; this.isTransiting = true; this.nzBeforeChange.emit({ from, to }); this.strategy.switch(this.activeIndex, index).subscribe(() => { this.scheduleNextTransition(); this.nzAfterChange.emit(to); this.isTransiting = false; }); this.markContentActive(to); this.cdr.markForCheck(); } } switchStrategy() { if (this.strategy) { this.strategy.dispose(); } // Load custom strategies first. const customStrategy = this.customStrategies ? this.customStrategies.find(s => s.name === this.nzEffect) : null; if (customStrategy) { this.strategy = new customStrategy.strategy(this, this.cdr, this.renderer, this.platform); return; } this.strategy = this.nzEffect === 'scrollx' ? new NzCarouselTransformStrategy(this, this.cdr, this.renderer, this.platform) : new NzCarouselOpacityStrategy(this, this.cdr, this.renderer, this.platform); } scheduleNextTransition() { this.clearScheduledTransition(); if (this.nzAutoPlay && this.nzAutoPlaySpeed > 0 && this.platform.isBrowser) { this.transitionInProgress = setTimeout(() => { this.goTo(this.activeIndex + 1); }, this.nzAutoPlaySpeed); } } clearScheduledTransition() { if (this.transitionInProgress) { clearTimeout(this.transitionInProgress); this.transitionInProgress = undefined; } } markContentActive(index) { this.activeIndex = index; if (this.carouselContents) { this.carouselContents.forEach((slide, i) => { if (this.dir === 'rtl') { slide.isActive = index === this.carouselContents.length - 1 - i; } else { slide.isActive = index === i; } }); } this.cdr.markForCheck(); } layout() { if (this.strategy) { this.strategy.withCarouselContents(this.carouselContents); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzCarouselComponent, deps: [{ token: i0.ElementRef }, { token: i1.NzConfigService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i2.Platform }, { token: i3.NzResizeService }, { token: i3.NzDragService }, { token: i4.NzResizeObserver }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: NzCarouselComponent, isStandalone: true, selector: "nz-carousel", inputs: { nzDotRender: "nzDotRender", nzEffect: "nzEffect", nzEnableSwipe: ["nzEnableSwipe", "nzEnableSwipe", booleanAttribute], nzDots: ["nzDots", "nzDots", booleanAttribute], nzAutoPlay: ["nzAutoPlay", "nzAutoPlay", booleanAttribute], nzAutoPlaySpeed: ["nzAutoPlaySpeed", "nzAutoPlaySpeed", numberAttribute], nzTransitionSpeed: ["nzTransitionSpeed", "nzTransitionSpeed", numberAttribute], nzLoop: "nzLoop", nzStrategyOptions: "nzStrategyOptions", nzDotPosition: "nzDotPosition" }, outputs: { nzBeforeChange: "nzBeforeChange", nzAfterChange: "nzAfterChange" }, host: { properties: { "class.ant-carousel-vertical": "vertical", "class.ant-carousel-rtl": "dir === 'rtl'" }, classAttribute: "ant-carousel" }, queries: [{ propertyName: "carouselContents", predicate: NzCarouselContentDirective }], viewQueries: [{ propertyName: "slickList", first: true, predicate: ["slickList"], descendants: true, static: true }, { propertyName: "slickTrack", first: true, predicate: ["slickTrack"], descendants: true, static: true }], exportAs: ["nzCarousel"], usesOnChanges: true, ngImport: i0, template: ` <div class="slick-initialized slick-slider" [class.slick-vertical]="nzDotPosition === 'left' || nzDotPosition === 'right'" > <div #slickList class="slick-list" tabindex="-1" (mousedown)="pointerDown($event)" (touchstart)="pointerDown($event)" > <!-- Render carousel items. --> <div class="slick-track" #slickTrack> <ng-content></ng-content> </div> </div> <!-- Render dots. --> @if (nzDots) { <ul class="slick-dots" [class.slick-dots-top]="nzDotPosition === 'top'" [class.slick-dots-bottom]="nzDotPosition === 'bottom'" [class.slick-dots-left]="nzDotPosition === 'left'" [class.slick-dots-right]="nzDotPosition === 'right'" > @for (content of carouselContents; track content) { <li [class.slick-active]="$index === activeIndex" (click)="onLiClick($index)"> <ng-template [ngTemplateOutlet]="nzDotRender || renderDotTemplate" [ngTemplateOutletContext]="{ $implicit: $index }" ></ng-template> </li> } </ul> } </div> <ng-template #renderDotTemplate let-index> <button>{{ index + 1 }}</button> </ng-template> `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzEffect", void 0); __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzEnableSwipe", void 0); __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzDots", void 0); __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzAutoPlay", void 0); __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzAutoPlaySpeed", void 0); __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzLoop", void 0); __decorate([ WithConfig() ], NzCarouselComponent.prototype, "nzDotPosition", null); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzCarouselComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, selector: 'nz-carousel', exportAs: 'nzCarousel', preserveWhitespaces: false, template: ` <div class="slick-initialized slick-slider" [class.slick-vertical]="nzDotPosition === 'left' || nzDotPosition === 'right'" > <div #slickList class="slick-list" tabindex="-1" (mousedown)="pointerDown($event)" (touchstart)="pointerDown($event)" > <!-- Render carousel items. --> <div class="slick-track" #slickTrack> <ng-content></ng-content> </div> </div> <!-- Render dots. --> @if (nzDots) { <ul class="slick-dots" [class.slick-dots-top]="nzDotPosition === 'top'" [class.slick-dots-bottom]="nzDotPosition === 'bottom'" [class.slick-dots-left]="nzDotPosition === 'left'" [class.slick-dots-right]="nzDotPosition === 'right'" > @for (content of carouselContents; track content) { <li [class.slick-active]="$index === activeIndex" (click)="onLiClick($index)"> <ng-template [ngTemplateOutlet]="nzDotRender || renderDotTemplate" [ngTemplateOutletContext]="{ $implicit: $index }" ></ng-template> </li> } </ul> } </div> <ng-template #renderDotTemplate let-index> <button>{{ index + 1 }}</button> </ng-template> `, host: { class: 'ant-carousel', '[class.ant-carousel-vertical]': 'vertical', '[class.ant-carousel-rtl]': `dir === 'rtl'` }, imports: [NgTemplateOutlet], standalone: true }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NzConfigService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i2.Platform }, { type: i3.NzResizeService }, { type: i3.NzDragService }, { type: i4.NzResizeObserver }], propDecorators: { carouselContents: [{ type: ContentChildren, args: [NzCarouselContentDirective] }], slickList: [{ type: ViewChild, args: ['slickList', { static: true }] }], slickTrack: [{ type: ViewChild, args: ['slickTrack', { static: true }] }], nzDotRender: [{ type: Input }], nzEffect: [{ type: Input }], nzEnableSwipe: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzDots: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzAutoPlay: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzAutoPlaySpeed: [{ type: Input, args: [{ transform: numberAttribute }] }], nzTransitionSpeed: [{ type: Input, args: [{ transform: numberAttribute }] }], nzLoop: [{ type: Input }], nzStrategyOptions: [{ type: Input }], nzDotPosition: [{ type: Input }], nzBeforeChange: [{ type: Output }], nzAfterChange: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9jYXJvdXNlbC9jYXJvdXNlbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBYSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRWhFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFHTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULGVBQWUsRUFFZixZQUFZLEVBQ1osS0FBSyxFQUtMLE1BQU0sRUFLTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixNQUFNLEVBQ04sZUFBZSxFQUNoQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRy9FLE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFJckYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFMUUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDMUUsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUUsT0FBTyxFQUVMLDZCQUE2QixFQUk5QixNQUFNLFdBQVcsQ0FBQzs7Ozs7O0FBRW5CLE1BQU0scUJBQXFCLEdBQWdCLFVBQVUsQ0FBQztBQTBEdEQsTUFBTSxPQUFPLG1CQUFtQjtJQXlCOUIsSUFBSSxhQUFhLENBQUMsS0FBNEI7UUFDNUMsSUFBSSxDQUFDLFlB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IGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBEaXJlY3Rpb24sIERpcmVjdGlvbmFsaXR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHsgTEVGVF9BUlJPVywgUklHSFRfQVJST1cgfSBmcm9tICdAYW5ndWxhci9jZGsva2V5Y29kZXMnO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBib29sZWFuQXR0cmlidXRlLFxuICBpbmplY3QsXG4gIG51bWJlckF0dHJpYnV0ZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QsIGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOelJlc2l6ZU9ic2VydmVyIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jZGsvcmVzaXplLW9ic2VydmVyJztcbmltcG9ydCB7IE56Q29uZmlnS2V5LCBOekNvbmZpZ1NlcnZpY2UsIFdpdGhDb25maWcgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IE56RHJhZ1NlcnZpY2UsIE56UmVzaXplU2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuXG5pbXBvcnQgeyBOekNhcm91c2VsQ29udGVudERpcmVjdGl2ZSB9IGZyb20gJy4vY2Fyb3VzZWwtY29udGVudC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnpDYXJvdXNlbEJhc2VTdHJhdGVneSB9IGZyb20gJy4vc3RyYXRlZ2llcy9iYXNlLXN0cmF0ZWd5JztcbmltcG9ydCB7IE56Q2Fyb3VzZWxPcGFjaXR5U3RyYXRlZ3kgfSBmcm9tICcuL3N0cmF0ZWdpZXMvb3BhY2l0eS1zdHJhdGVneSc7XG5pbXBvcnQgeyBOekNhcm91c2VsVHJhbnNmb3JtU3RyYXRlZ3kgfSBmcm9tICcuL3N0cmF0ZWdpZXMvdHJhbnNmb3JtLXN0cmF0ZWd5JztcbmltcG9ydCB7XG4gIEZyb21Ub0ludGVyZmFjZSxcbiAgTlpfQ0FST1VTRUxfQ1VTVE9NX1NUUkFURUdJRVMsXG4gIE56Q2Fyb3VzZWxEb3RQb3NpdGlvbixcbiAgTnpDYXJvdXNlbEVmZmVjdHMsXG4gIFBvaW50ZXJWZWN0b3Jcbn0gZnJvbSAnLi90eXBpbmdzJztcblxuY29uc3QgTlpfQ09ORklHX01PRFVMRV9OQU1FOiBOekNvbmZpZ0tleSA9ICdjYXJvdXNlbCc7XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICduei1jYXJvdXNlbCcsXG4gIGV4cG9ydEFzOiAnbnpDYXJvdXNlbCcsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwic2xpY2staW5pdGlhbGl6ZWQgc2xpY2stc2xpZGVyXCJcbiAgICAgIFtjbGFzcy5zbGljay12ZXJ0aWNhbF09XCJuekRvdFBvc2l0aW9uID09PSAnbGVmdCcgfHwgbnpEb3RQb3NpdGlvbiA9PT0gJ3JpZ2h0J1wiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICAjc2xpY2tMaXN0XG4gICAgICAgIGNsYXNzPVwic2xpY2stbGlzdFwiXG4gICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgICAobW91c2Vkb3duKT1cInBvaW50ZXJEb3duKCRldmVudClcIlxuICAgICAgICAodG91Y2hzdGFydCk9XCJwb2ludGVyRG93bigkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgICAgPCEtLSBSZW5kZXIgY2Fyb3VzZWwgaXRlbXMuIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2xpY2stdHJhY2tcIiAjc2xpY2tUcmFjaz5cbiAgICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8IS0tIFJlbmRlciBkb3RzLiAtLT5cbiAgICAgIEBpZiAobnpEb3RzKSB7XG4gICAgICAgIDx1bFxuICAgICAgICAgIGNsYXNzPVwic2xpY2stZG90c1wiXG4gICAgICAgICAgW2NsYXNzLnNsaWNrLWRvdHMtdG9wXT1cIm56RG90UG9zaXRpb24gPT09ICd0b3AnXCJcbiAgICAgICAgICBbY2xhc3Muc2xpY2stZG90cy1ib3R0b21dPVwibnpEb3RQb3NpdGlvbiA9PT0gJ2JvdHRvbSdcIlxuICAgICAgICAgIFtjbGFzcy5zbGljay1kb3RzLWxlZnRdPVwibnpEb3RQb3NpdGlvbiA9PT0gJ2xlZnQnXCJcbiAgICAgICAgICBbY2xhc3Muc2xpY2stZG90cy1yaWdodF09XCJuekRvdFBvc2l0aW9uID09PSAncmlnaHQnXCJcbiAgICAgICAgPlxuICAgICAgICAgIEBmb3IgKGNvbnRlbnQgb2YgY2Fyb3VzZWxDb250ZW50czsgdHJhY2sgY29udGVudCkge1xuICAgICAgICAgICAgPGxpIFtjbGFzcy5zbGljay1hY3RpdmVdPVwiJGluZGV4ID09PSBhY3RpdmVJbmRleFwiIChjbGljayk9XCJvbkxpQ2xpY2soJGluZGV4KVwiPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJuekRvdFJlbmRlciB8fCByZW5kZXJEb3RUZW1wbGF0ZVwiXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiAkaW5kZXggfVwiXG4gICAgICAgICAgICAgID48L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICB9XG4gICAgICAgIDwvdWw+XG4gICAgICB9XG4gICAgPC9kaXY+XG5cbiAgICA8bmctdGVtcGxhdGUgI3JlbmRlckRvdFRlbXBsYXRlIGxldC1pbmRleD5cbiAgICAgIDxidXR0b24+e3sgaW5kZXggKyAxIH19PC9idXR0b24+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgYCxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnYW50LWNhcm91c2VsJyxcbiAgICAnW2NsYXNzLmFudC1jYXJvdXNlbC12ZXJ0aWNhbF0nOiAndmVydGljYWwnLFxuICAgICdbY2xhc3MuYW50LWNhcm91c2VsLXJ0bF0nOiBgZGlyID09PSAncnRsJ2BcbiAgfSxcbiAgaW1wb3J0czogW05nVGVtcGxhdGVPdXRsZXRdLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIE56Q2Fyb3VzZWxDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcywgT25Jbml0IHtcbiAgcmVhZG9ubHkgX256TW9kdWxlTmFtZTogTnpDb25maWdLZXkgPSBOWl9DT05GSUdfTU9EVUxFX05BTUU7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihOekNhcm91c2VsQ29udGVudERpcmVjdGl2ZSkgY2Fyb3VzZWxDb250ZW50cyE6IFF1ZXJ5TGlzdDxOekNhcm91c2VsQ29udGVudERpcmVjdGl2ZT47XG5cbiAgQFZpZXdDaGlsZCgnc2xpY2tMaXN0JywgeyBzdGF0aWM6IHRydWUgfSkgc2xpY2tMaXN0ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3NsaWNrVHJhY2snLCB7IHN0YXRpYzogdHJ1ZSB9KSBzbGlja1RyYWNrITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgQElucHV0KCkgbnpEb3RSZW5kZXI/OiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogbnVtYmVyIH0+O1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56RWZmZWN0OiBOekNhcm91c2VsRWZmZWN0cyA9ICdzY3JvbGx4JztcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIEBXaXRoQ29uZmlnKCkgbnpFbmFibGVTd2lwZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBAV2l0aENvbmZpZygpIG56RG90czogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBAV2l0aENvbmZpZygpIG56QXV0b1BsYXk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSkgQFdpdGhDb25maWcoKSBuekF1dG9QbGF5U3BlZWQ6IG51bWJlciA9IDMwMDA7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlIH0pIG56VHJhbnNpdGlvblNwZWVkID0gNTAwO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56TG9vcDogYm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIHRoaXMgcHJvcGVydHkgaXMgcGFzc2VkIGRpcmVjdGx5IHRvIGFuIE56Q2Fyb3VzZWxCYXNlU3RyYXRlZ3lcbiAgICovXG4gIEBJbnB1dCgpIG56U3RyYXRlZ3lPcHRpb25zOiBOelNhZmVBbnkgPSB1bmRlZmluZWQ7XG5cbiAgQElucHV0KClcbiAgLy8gQHRzLWlnbm9yZVxuICBAV2l0aENvbmZpZygpXG4gIHNldCBuekRvdFBvc2l0aW9uKHZhbHVlOiBOekNhcm91c2VsRG90UG9zaXRpb24pIHtcbiAgICB0aGlzLl9kb3RQb3NpdGlvbiA9IHZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2xlZnQnIHx8IHZhbHVlID09PSAncmlnaHQnKSB7XG4gICAgICB0aGlzLnZlcnRpY2FsID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52ZXJ0aWNhbCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGdldCBuekRvdFBvc2l0aW9uKCk6IE56Q2Fyb3VzZWxEb3RQb3NpdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuX2RvdFBvc2l0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBfZG90UG9zaXRpb246IE56Q2Fyb3VzZWxEb3RQb3NpdGlvbiA9ICdib3R0b20nO1xuXG4gIEBPdXRwdXQoKSByZWFkb25seSBuekJlZm9yZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RnJvbVRvSW50ZXJmYWNlPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpBZnRlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gIGFjdGl2ZUluZGV4ID0gMDtcbiAgZWw6IEhUTUxFbGVtZW50O1xuICBzbGlja0xpc3RFbCE6IEhUTUxFbGVtZW50O1xuICBzbGlja1RyYWNrRWwhOiBIVE1MRWxlbWVudDtcbiAgc3RyYXRlZ3k/OiBOekNhcm91c2VsQmFzZVN0cmF0ZWd5O1xuICB2ZXJ0aWNhbCA9IGZhbHNlO1xuICB0cmFuc2l0aW9uSW5Qcm9ncmVzcz86IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+O1xuICBkaXI6IERpcmVjdGlvbiA9ICdsdHInO1xuXG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIGdlc3R1cmVSZWN0OiBDbGllbnRSZWN0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcG9pbnRlckRlbHRhOiBQb2ludGVyVmVjdG9yIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNUcmFuc2l0aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgaXNEcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIGRpcmVjdGlvbmFsaXR5ID0gaW5qZWN0KERpcmVjdGlvbmFsaXR5KTtcbiAgcHJpdmF0ZSBjdXN0b21TdHJhdGVnaWVzID0gaW5qZWN0KE5aX0NBUk9VU0VMX0NVU1RPTV9TVFJBVEVHSUVTLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHVibGljIHJlYWRvbmx5IG56Q29uZmlnU2VydmljZTogTnpDb25maWdTZXJ2aWNlLFxuICAgIHB1YmxpYyByZWFkb25seSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzaXplU2VydmljZTogTnpSZXNpemVTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbnpEcmFnU2VydmljZTogTnpEcmFnU2VydmljZSxcbiAgICBwcml2YXRlIG56UmVzaXplT2JzZXJ2ZXI6IE56UmVzaXplT2JzZXJ2ZXJcbiAgKSB7XG4gICAgdGhpcy5uekRvdFBvc2l0aW9uID0gJ2JvdHRvbSc7XG4gICAgdGhpcy5lbCA9IGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgfVxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWNrTGlzdEVsID0gdGhpcy5zbGlja0xpc3QhLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5zbGlja1RyYWNrRWwgPSB0aGlzLnNsaWNrVHJhY2shLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICB0aGlzLmRpciA9IHRoaXMuZGlyZWN0aW9uYWxpdHkudmFsdWU7XG5cbiAgICB0aGlzLmRpcmVjdGlvbmFsaXR5LmNoYW5nZS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChkaXJlY3Rpb246IERpcmVjdGlvbikgPT4ge1xuICAgICAgdGhpcy5kaXIgPSBkaXJlY3Rpb247XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKHRoaXMuYWN0aXZlSW5kZXgpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuc2xpY2tMaXN0RWwsICdrZXlkb3duJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgICBjb25zdCB7IGtleUNvZGUgfSA9IGV2ZW50O1xuXG4gICAgICAgICAgaWYgKGtleUNvZGUgIT09IExFRlRfQVJST1cgJiYga2V5Q29kZSAhPT0gUklHSFRfQVJST1cpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSBMRUZUX0FSUk9XKSB7XG4gICAgICAgICAgICAgIHRoaXMucHJlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLm5leHQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMubnpSZXNpemVPYnNlcnZlclxuICAgICAgLm9ic2VydmUodGhpcy5lbClcbiAgICAgIC5waXBlKGRlYm91bmNlVGltZSgxMDApLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUoMCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5jYXJvdXNlbENvbnRlbnRzLmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUoMCk7XG4gICAgICB0aGlzLmxheW91dCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5yZXNpemVTZXJ2aWNlXG4gICAgICAuc3Vic2NyaWJlKClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLmxheW91dCgpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnN3aXRjaFN0cmF0ZWd5KCk7XG4gICAgdGhpcy5tYXJrQ29udGVudEFjdGl2ZSgwKTtcbiAgICB0aGlzLmxheW91dCgpO1xuXG4gICAgLy8gSWYgZW1iZWRkZWQgaW4gYW4gZW50cnkgY29tcG9uZW50LCBpdCBtYXkgZG8gaW5pdGlhbCByZW5kZXIgYXQgYW4gaW5hcHByb3ByaWF0ZSB0aW1lLlxuICAgIC8vIG5nWm9uZS5vblN0YWJsZSB3b24ndCBkbyB0aGlzIHRyaWNrXG4gICAgLy8gVE9ETzogbmVlZCB0byBjaGFuZ2UgdGhpcy5cbiAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMubGF5b3V0KCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgeyBuekVmZmVjdCwgbnpEb3RQb3NpdGlvbiB9ID0gY2hhbmdlcztcblxuICAgIGlmIChuekVmZmVjdCAmJiAhbnpFZmZlY3QuaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLnN3aXRjaFN0cmF0ZWd5KCk7XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKDApO1xuICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICB9XG5cbiAgICBpZiAobnpEb3RQb3NpdGlvbiAmJiAhbnpEb3RQb3NpdGlvbi5pc0ZpcnN0Q2hhbmdlKCkpIHtcbiAgICAgIHRoaXMuc3dpdGNoU3RyYXRlZ3koKTtcbiAgICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUoMCk7XG4gICAgICB0aGlzLmxheW91dCgpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5uekF1dG9QbGF5IHx8ICF0aGlzLm56QXV0b1BsYXlTcGVlZCkge1xuICAgICAgdGhpcy5jbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY2hlZHVsZU5leHRUcmFuc2l0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKTtcbiAgICBpZiAodGhpcy5zdHJhdGVneSkge1xuICAgICAgdGhpcy5zdHJhdGVneS5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgb25MaUNsaWNrID0gKGluZGV4OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5kaXIgPT09ICdydGwnKSB7XG4gICAgICB0aGlzLmdvVG8odGhpcy5jYXJvdXNlbENvbnRlbnRzLmxlbmd0aCAtIDEgLSBpbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ29UbyhpbmRleCk7XG4gICAgfVxuICB9O1xuXG4gIG5leHQoKTogdm9pZCB7XG4gICAgdGhpcy5nb1RvKHRoaXMuYWN0aXZlSW5kZXggKyAxKTtcbiAgfVxuXG4gIHByZSgpOiB2b2lkIHtcbiAgICB0aGlzLmdvVG8odGhpcy5hY3RpdmVJbmRleCAtIDEpO1xuICB9XG5cbiAgZ29UbyhpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5jYXJvdXNlbENvbnRlbnRzICYmXG4gICAgICB0aGlzLmNhcm91c2VsQ29udGVudHMubGVuZ3RoICYmXG4gICAgICAhdGhpcy5pc1RyYW5zaXRpbmcgJiZcbiAgICAgICh0aGlzLm56TG9vcCB8fCAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMuY2Fyb3VzZWxDb250ZW50cy5sZW5ndGgpKVxuICAgICkge1xuICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy5jYXJvdXNlbENvbnRlbnRzLmxlbmd0aDtcbiAgICAgIGNvbnN0IGZyb20gPSB0aGlzLmFjdGl2ZUluZGV4O1xuICAgICAgY29uc3QgdG8gPSAoaW5kZXggKyBsZW5ndGgpICUgbGVuZ3RoO1xuICAgICAgdGhpcy5pc1RyYW5zaXRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5uekJlZm9yZUNoYW5nZS5lbWl0KHsgZnJvbSwgdG8gfSk7XG4gICAgICB0aGlzLnN0cmF0ZWd5IS5zd2l0Y2godGhpcy5hY3RpdmVJbmRleCwgaW5kZXgpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVOZXh0VHJhbnNpdGlvbigpO1xuICAgICAgICB0aGlzLm56QWZ0ZXJDaGFuZ2UuZW1pdCh0byk7XG4gICAgICAgIHRoaXMuaXNUcmFuc2l0aW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUodG8pO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzd2l0Y2hTdHJhdGVneSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdHJhdGVneSkge1xuICAgICAgdGhpcy5zdHJhdGVneS5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gTG9hZCBjdXN0b20gc3RyYXRlZ2llcyBmaXJzdC5cbiAgICBjb25zdCBjdXN0b21TdHJhdGVneSA9IHRoaXMuY3VzdG9tU3RyYXRlZ2llcyA/IHRoaXMuY3VzdG9tU3RyYXRlZ2llcy5maW5kKHMgPT4gcy5uYW1lID09PSB0aGlzLm56RWZmZWN0KSA6IG51bGw7XG4gICAgaWYgKGN1c3RvbVN0cmF0ZWd5KSB7XG4gICAgICB0aGlzLnN0cmF0ZWd5ID0gbmV3IChjdXN0b21TdHJhdGVneS5zdHJhdGVneSBhcyBOelNhZmVBbnkpKHRoaXMsIHRoaXMuY2RyLCB0aGlzLnJlbmRlcmVyLCB0aGlzLnBsYXRmb3JtKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnN0cmF0ZWd5ID1cbiAgICAgIHRoaXMubnpFZmZlY3QgPT09ICdzY3JvbGx4J1xuICAgICAgICA/IG5ldyBOekNhcm91c2VsVHJhbnNmb3JtU3RyYXRlZ3kodGhpcywgdGhpcy5jZHIsIHRoaXMucmVuZGVyZXIsIHRoaXMucGxhdGZvcm0pXG4gICAgICAgIDogbmV3IE56Q2Fyb3VzZWxPcGFjaXR5U3RyYXRlZ3kodGhpcywgdGhpcy5jZHIsIHRoaXMucmVuZGVyZXIsIHRoaXMucGxhdGZvcm0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzY2hlZHVsZU5leHRUcmFuc2l0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XG4gICAgaWYgKHRoaXMubnpBdXRvUGxheSAmJiB0aGlzLm56QXV0b1BsYXlTcGVlZCA+IDAgJiYgdGhpcy5wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgIHRoaXMudHJhbnNpdGlvbkluUHJvZ3Jlc3MgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5nb1RvKHRoaXMuYWN0aXZlSW5kZXggKyAxKTtcbiAgICAgIH0sIHRoaXMubnpBdXRvUGxheVNwZWVkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2NoZWR1bGVkVHJhbnNpdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50cmFuc2l0aW9uSW5Qcm9ncmVzcykge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudHJhbnNpdGlvbkluUHJvZ3Jlc3MpO1xuICAgICAgdGhpcy50cmFuc2l0aW9uSW5Qcm9ncmVzcyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1hcmtDb250ZW50QWN0aXZlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUluZGV4ID0gaW5kZXg7XG5cbiAgICBpZiAodGhpcy5jYXJvdXNlbENvbnRlbnRzKSB7XG4gICAgICB0aGlzLmNhcm91c2VsQ29udGVudHMuZm9yRWFjaCgoc2xpZGUsIGkpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZGlyID09PSAncnRsJykge1xuICAgICAgICAgIHNsaWRlLmlzQWN0aXZlID0gaW5kZXggPT09IHRoaXMuY2Fyb3VzZWxDb250ZW50cy5sZW5ndGggLSAxIC0gaTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzbGlkZS5pc0FjdGl2ZSA9IGluZGV4ID09PSBpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmFnIGNhcm91c2VsLlxuICAgKi9cbiAgcG9pbnRlckRvd24gPSAoZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcgJiYgIXRoaXMuaXNUcmFuc2l0aW5nICYmIHRoaXMubnpFbmFibGVTd2lwZSkge1xuICAgICAgdGhpcy5jbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKTtcbiAgICAgIHRoaXMuZ2VzdHVyZVJlY3QgPSB0aGlzLnNsaWNrTGlzdEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICB0aGlzLm56RHJhZ1NlcnZpY2UucmVxdWVzdERyYWdnaW5nU2VxdWVuY2UoZXZlbnQpLnN1YnNjcmliZShcbiAgICAgICAgZGVsdGEgPT4ge1xuICAgICAgICAgIHRoaXMucG9pbnRlckRlbHRhID0gZGVsdGE7XG4gICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnN0cmF0ZWd5Py5kcmFnZ2luZyh0aGlzLnBvaW50ZXJEZWx0YSk7XG4gICAgICAgIH0sXG4gICAgICAgICgpID0+IHt9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMubnpFbmFibGVTd2lwZSAmJiB0aGlzLmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IHhEZWx0YSA9IHRoaXMucG9pbnRlckRlbHRhID8gdGhpcy5wb2ludGVyRGVsdGEueCA6IDA7XG5cbiAgICAgICAgICAgIC8vIFN3aXRjaCB0byBhbm90aGVyIHNsaWRlIGlmIGRlbHRhIGlzIGJpZ2dlciB0aGFuIHRoaXJkIG9mIHRoZSB3aWR0aC5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgTWF0aC5hYnMoeERlbHRhKSA+IHRoaXMuZ2VzdHVyZVJlY3QhLndpZHRoIC8gMyAmJlxuICAgICAgICAgICAgICAodGhpcy5uekxvb3AgfHxcbiAgICAgICAgICAgICAgICAoeERlbHRhIDw9IDAgJiYgdGhpcy5hY3RpdmVJbmRleCArIDEgPCB0aGlzLmNhcm91c2VsQ29udGVudHMubGVuZ3RoKSB8fFxuICAgICAgICAgICAgICAgICh4RGVsdGEgPiAwICYmIHRoaXMuYWN0aXZlSW5kZXggPiAwKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLmdvVG8oeERlbHRhID4gMCA/IHRoaXMuYWN0aXZlSW5kZXggLSAxIDogdGhpcy5hY3RpdmVJbmRleCArIDEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5nb1RvKHRoaXMuYWN0aXZlSW5kZXgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmdlc3R1cmVSZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMucG9pbnRlckRlbHRhID0gbnVsbDtcbiAgICAgIC