UNPKG

ng-zorro-antd

Version:

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

420 lines 49.4 kB
import { CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop'; import { NgForOf, NgIf } from '@angular/common'; import { ChangeDetectionStrategy, Component, EventEmitter, ViewChild, ViewEncapsulation } from '@angular/core'; import { fromEvent } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { fadeMotion } from 'ng-zorro-antd/core/animation'; import { NzDestroyService } from 'ng-zorro-antd/core/services'; import { isNotNil } from 'ng-zorro-antd/core/util'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { FADE_CLASS_NAME_MAP, NZ_CONFIG_MODULE_NAME } from './image-config'; import { getClientSize, getFitContentPosition, getOffset } from './utils'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "./image-preview-options"; import * as i3 from "@angular/cdk/overlay"; import * as i4 from "ng-zorro-antd/core/services"; import * as i5 from "@angular/platform-browser"; import * as i6 from "ng-zorro-antd/icon"; const initialPosition = { x: 0, y: 0 }; export const NZ_DEFAULT_SCALE_STEP = 0.5; const NZ_DEFAULT_ZOOM = 1; const NZ_DEFAULT_ROTATE = 0; export class NzImagePreviewComponent { get animationDisabled() { return this.config.nzNoAnimation ?? false; } get maskClosable() { const defaultConfig = this.nzConfigService.getConfigForComponent(NZ_CONFIG_MODULE_NAME) || {}; return this.config.nzMaskClosable ?? defaultConfig.nzMaskClosable ?? true; } constructor(ngZone, host, cdr, nzConfigService, config, overlayRef, destroy$, sanitizer) { this.ngZone = ngZone; this.host = host; this.cdr = cdr; this.nzConfigService = nzConfigService; this.config = config; this.overlayRef = overlayRef; this.destroy$ = destroy$; this.sanitizer = sanitizer; this._defaultNzZoom = NZ_DEFAULT_ZOOM; this._defaultNzScaleStep = NZ_DEFAULT_SCALE_STEP; this._defaultNzRotate = NZ_DEFAULT_ROTATE; this.images = []; this.index = 0; this.isDragging = false; this.visible = true; this.animationState = 'enter'; this.animationStateChanged = new EventEmitter(); this.scaleStepMap = new Map(); this.previewImageTransform = ''; this.previewImageWrapperTransform = ''; this.operations = [ { icon: 'close', onClick: () => { this.onClose(); }, type: 'close' }, { icon: 'zoom-in', onClick: () => { this.onZoomIn(); }, type: 'zoomIn' }, { icon: 'zoom-out', onClick: () => { this.onZoomOut(); }, type: 'zoomOut' }, { icon: 'rotate-right', onClick: () => { this.onRotateRight(); }, type: 'rotateRight' }, { icon: 'rotate-left', onClick: () => { this.onRotateLeft(); }, type: 'rotateLeft' } ]; this.zoomOutDisabled = false; this.position = { ...initialPosition }; this.containerClick = new EventEmitter(); this.closeClick = new EventEmitter(); this.zoom = this.config.nzZoom ?? this._defaultNzZoom; this.scaleStep = this.config.nzScaleStep ?? this._defaultNzScaleStep; this.rotate = this.config.nzRotate ?? this._defaultNzRotate; this.updateZoomOutDisabled(); this.updatePreviewImageTransform(); this.updatePreviewImageWrapperTransform(); } ngOnInit() { this.ngZone.runOutsideAngular(() => { fromEvent(this.host.nativeElement, 'click') .pipe(takeUntil(this.destroy$)) .subscribe(event => { if (event.target === event.currentTarget && this.maskClosable && this.containerClick.observers.length) { this.ngZone.run(() => this.containerClick.emit()); } }); fromEvent(this.imagePreviewWrapper.nativeElement, 'mousedown') .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.isDragging = true; }); }); } setImages(images, scaleStepMap) { if (scaleStepMap) this.scaleStepMap = scaleStepMap; this.images = images; this.cdr.markForCheck(); } switchTo(index) { this.index = index; this.cdr.markForCheck(); } next() { if (this.index < this.images.length - 1) { this.reset(); this.index++; this.updatePreviewImageTransform(); this.updatePreviewImageWrapperTransform(); this.updateZoomOutDisabled(); this.cdr.markForCheck(); } } prev() { if (this.index > 0) { this.reset(); this.index--; this.updatePreviewImageTransform(); this.updatePreviewImageWrapperTransform(); this.updateZoomOutDisabled(); this.cdr.markForCheck(); } } markForCheck() { this.cdr.markForCheck(); } onClose() { this.closeClick.emit(); } onZoomIn() { const zoomStep = this.scaleStepMap.get(this.images[this.index].src ?? this.images[this.index].srcset) ?? this.scaleStep; this.zoom += zoomStep; this.updatePreviewImageTransform(); this.updateZoomOutDisabled(); this.position = { ...initialPosition }; } onZoomOut() { if (this.zoom > 1) { const zoomStep = this.scaleStepMap.get(this.images[this.index].src ?? this.images[this.index].srcset) ?? this.scaleStep; this.zoom -= zoomStep; this.updatePreviewImageTransform(); this.updateZoomOutDisabled(); this.position = { ...initialPosition }; } } onRotateRight() { this.rotate += 90; this.updatePreviewImageTransform(); } onRotateLeft() { this.rotate -= 90; this.updatePreviewImageTransform(); } onSwitchLeft(event) { event.preventDefault(); event.stopPropagation(); this.prev(); } onSwitchRight(event) { event.preventDefault(); event.stopPropagation(); this.next(); } onAnimationStart(event) { if (event.toState === 'enter') { this.setEnterAnimationClass(); } else if (event.toState === 'leave') { this.setLeaveAnimationClass(); } this.animationStateChanged.emit(event); } onAnimationDone(event) { if (event.toState === 'enter') { this.setEnterAnimationClass(); } else if (event.toState === 'leave') { this.setLeaveAnimationClass(); } this.animationStateChanged.emit(event); } startLeaveAnimation() { this.animationState = 'leave'; this.cdr.markForCheck(); } onDragReleased() { this.isDragging = false; const width = this.imageRef.nativeElement.offsetWidth * this.zoom; const height = this.imageRef.nativeElement.offsetHeight * this.zoom; const { left, top } = getOffset(this.imageRef.nativeElement); const { width: clientWidth, height: clientHeight } = getClientSize(); const isRotate = this.rotate % 180 !== 0; const fitContentParams = { width: isRotate ? height : width, height: isRotate ? width : height, left, top, clientWidth, clientHeight }; const fitContentPos = getFitContentPosition(fitContentParams); if (isNotNil(fitContentPos.x) || isNotNil(fitContentPos.y)) { this.position = { ...this.position, ...fitContentPos }; } } sanitizerResourceUrl(url) { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } updatePreviewImageTransform() { this.previewImageTransform = `scale3d(${this.zoom}, ${this.zoom}, 1) rotate(${this.rotate}deg)`; } updatePreviewImageWrapperTransform() { this.previewImageWrapperTransform = `translate3d(${this.position.x}px, ${this.position.y}px, 0)`; } updateZoomOutDisabled() { this.zoomOutDisabled = this.zoom <= 1; } setEnterAnimationClass() { if (this.animationDisabled) { return; } const backdropElement = this.overlayRef.backdropElement; if (backdropElement) { backdropElement.classList.add(FADE_CLASS_NAME_MAP.enter); backdropElement.classList.add(FADE_CLASS_NAME_MAP.enterActive); } } setLeaveAnimationClass() { if (this.animationDisabled) { return; } const backdropElement = this.overlayRef.backdropElement; if (backdropElement) { backdropElement.classList.add(FADE_CLASS_NAME_MAP.leave); backdropElement.classList.add(FADE_CLASS_NAME_MAP.leaveActive); } } reset() { this.zoom = this.config.nzZoom ?? this._defaultNzZoom; this.scaleStep = this.config.nzScaleStep ?? this._defaultNzScaleStep; this.rotate = this.config.nzRotate ?? this._defaultNzRotate; this.position = { ...initialPosition }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: NzImagePreviewComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.NzConfigService }, { token: i2.NzImagePreviewOptions }, { token: i3.OverlayRef }, { token: i4.NzDestroyService }, { token: i5.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.7", type: NzImagePreviewComponent, isStandalone: true, selector: "nz-image-preview", host: { attributes: { "tabindex": "-1", "role": "document" }, listeners: { "@fadeMotion.start": "onAnimationStart($event)", "@fadeMotion.done": "onAnimationDone($event)" }, properties: { "class.ant-image-preview-moving": "isDragging", "style.zIndex": "config.nzZIndex", "@.disabled": "config.nzNoAnimation", "@fadeMotion": "animationState" }, classAttribute: "ant-image-preview-wrap" }, providers: [NzDestroyService], viewQueries: [{ propertyName: "imageRef", first: true, predicate: ["imgRef"], descendants: true }, { propertyName: "imagePreviewWrapper", first: true, predicate: ["imagePreviewWrapper"], descendants: true, static: true }], exportAs: ["nzImagePreview"], ngImport: i0, template: ` <div class="ant-image-preview"> <div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div> <div class="ant-image-preview-content"> <div class="ant-image-preview-body"> <ul class="ant-image-preview-operations"> <li class="ant-image-preview-operations-operation" [class.ant-image-preview-operations-operation-disabled]="zoomOutDisabled && option.type === 'zoomOut'" (click)="option.onClick()" *ngFor="let option of operations" > <span class="ant-image-preview-operations-icon" nz-icon [nzType]="option.icon" nzTheme="outline"></span> </li> </ul> <div class="ant-image-preview-img-wrapper" #imagePreviewWrapper cdkDrag [style.transform]="previewImageWrapperTransform" [cdkDragFreeDragPosition]="position" (cdkDragReleased)="onDragReleased()" > <ng-container *ngFor="let image of images; index as imageIndex"> <img cdkDragHandle class="ant-image-preview-img" #imgRef *ngIf="index === imageIndex" [attr.src]="sanitizerResourceUrl(image.src)" [attr.srcset]="image.srcset" [attr.alt]="image.alt" [style.width]="image.width" [style.height]="image.height" [style.transform]="previewImageTransform" /> </ng-container> </div> <ng-container *ngIf="images.length > 1"> <div class="ant-image-preview-switch-left" [class.ant-image-preview-switch-left-disabled]="index <= 0" (click)="onSwitchLeft($event)" > <span nz-icon nzType="left" nzTheme="outline"></span> </div> <div class="ant-image-preview-switch-right" [class.ant-image-preview-switch-right-disabled]="index >= images.length - 1" (click)="onSwitchRight($event)" > <span nz-icon nzType="right" nzTheme="outline"></span> </div> </ng-container> </div> </div> <div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div> </div> `, isInline: true, dependencies: [{ kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i6.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [fadeMotion], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: NzImagePreviewComponent, decorators: [{ type: Component, args: [{ selector: 'nz-image-preview', exportAs: 'nzImagePreview', animations: [fadeMotion], standalone: true, template: ` <div class="ant-image-preview"> <div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div> <div class="ant-image-preview-content"> <div class="ant-image-preview-body"> <ul class="ant-image-preview-operations"> <li class="ant-image-preview-operations-operation" [class.ant-image-preview-operations-operation-disabled]="zoomOutDisabled && option.type === 'zoomOut'" (click)="option.onClick()" *ngFor="let option of operations" > <span class="ant-image-preview-operations-icon" nz-icon [nzType]="option.icon" nzTheme="outline"></span> </li> </ul> <div class="ant-image-preview-img-wrapper" #imagePreviewWrapper cdkDrag [style.transform]="previewImageWrapperTransform" [cdkDragFreeDragPosition]="position" (cdkDragReleased)="onDragReleased()" > <ng-container *ngFor="let image of images; index as imageIndex"> <img cdkDragHandle class="ant-image-preview-img" #imgRef *ngIf="index === imageIndex" [attr.src]="sanitizerResourceUrl(image.src)" [attr.srcset]="image.srcset" [attr.alt]="image.alt" [style.width]="image.width" [style.height]="image.height" [style.transform]="previewImageTransform" /> </ng-container> </div> <ng-container *ngIf="images.length > 1"> <div class="ant-image-preview-switch-left" [class.ant-image-preview-switch-left-disabled]="index <= 0" (click)="onSwitchLeft($event)" > <span nz-icon nzType="left" nzTheme="outline"></span> </div> <div class="ant-image-preview-switch-right" [class.ant-image-preview-switch-right-disabled]="index >= images.length - 1" (click)="onSwitchRight($event)" > <span nz-icon nzType="right" nzTheme="outline"></span> </div> </ng-container> </div> </div> <div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div> </div> `, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'ant-image-preview-wrap', '[class.ant-image-preview-moving]': 'isDragging', '[style.zIndex]': 'config.nzZIndex', '[@.disabled]': 'config.nzNoAnimation', '[@fadeMotion]': 'animationState', '(@fadeMotion.start)': 'onAnimationStart($event)', '(@fadeMotion.done)': 'onAnimationDone($event)', tabindex: '-1', role: 'document' }, imports: [NgForOf, NzIconModule, CdkDragHandle, CdkDrag, NgIf], providers: [NzDestroyService] }] }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.NzConfigService }, { type: i2.NzImagePreviewOptions }, { type: i3.OverlayRef }, { type: i4.NzDestroyService }, { type: i5.DomSanitizer }], propDecorators: { imageRef: [{ type: ViewChild, args: ['imgRef'] }], imagePreviewWrapper: [{ type: ViewChild, args: ['imagePreviewWrapper', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtcHJldmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL2ltYWdlL2ltYWdlLXByZXZpZXcuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFaEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBR1osU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFMUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFL0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUk1RSxPQUFPLEVBQUUsYUFBYSxFQUFFLHFCQUFxQixFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7Ozs7Ozs7QUFTMUUsTUFBTSxlQUFlLEdBQUc7SUFDdEIsQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztDQUNMLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFDekMsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLE1BQU0saUJBQWlCLEdBQUcs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QUU7d0JBQ0osS0FBSyxFQUFFLHdCQUF3Qjt3QkFDL0Isa0NBQWtDLEVBQUUsWUFBWTt3QkFDaEQsZ0JBQWdCLEVBQUUsaUJBQWlCO3dCQUNuQyxjQUFjLEVBQUUsc0JBQXNCO3dCQUN0QyxlQUFlLEVBQUUsZ0JBQWdCO3dCQUNqQyxxQkFBcUIsRUFBRSwwQkFBMEI7d0JBQ2pELG9CQUFvQixFQUFFLHlCQUF5Qjt3QkFDL0MsUUFBUSxFQUFFLElBQUk7d0JBQ2QsSUFBSSxFQUFFLFVBQVU7cUJBQ2pCO29CQUNELE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUM7b0JBQzlELFNBQVMsRUFBRSxDQUFDLGdCQUFnQixDQUFDO2lCQUM5Qjt5UkE0RHNCLFFBQVE7c0JBQTVCLFNBQVM7dUJBQUMsUUFBUTtnQkFDaUMsbUJBQW1CO3NCQUF0RSxTQUFTO3VCQUFDLHFCQUFxQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IEFuaW1hdGlvbkV2ZW50IH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBDZGtEcmFnLCBDZGtEcmFnSGFuZGxlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBPdmVybGF5UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHsgTmdGb3JPZiwgTmdJZiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBOZ1pvbmUsXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZVJlc291cmNlVXJsIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBmcm9tRXZlbnQgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgZmFkZU1vdGlvbiB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9hbmltYXRpb24nO1xuaW1wb3J0IHsgTnpDb25maWdTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyBOekRlc3Ryb3lTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3NlcnZpY2VzJztcbmltcG9ydCB7IE56U2FmZUFueSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBpc05vdE5pbCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcbmltcG9ydCB7IE56SWNvbk1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvaWNvbic7XG5cbmltcG9ydCB7IEZBREVfQ0xBU1NfTkFNRV9NQVAsIE5aX0NPTkZJR19NT0RVTEVfTkFNRSB9IGZyb20gJy4vaW1hZ2UtY29uZmlnJztcbmltcG9ydCB7IE56SW1hZ2UsIE56SW1hZ2VQcmV2aWV3T3B0aW9ucyB9IGZyb20gJy4vaW1hZ2UtcHJldmlldy1vcHRpb25zJztcbmltcG9ydCB7IE56SW1hZ2VQcmV2aWV3UmVmIH0gZnJvbSAnLi9pbWFnZS1wcmV2aWV3LXJlZic7XG5pbXBvcnQgeyBOekltYWdlU2NhbGVTdGVwLCBOekltYWdlVXJsIH0gZnJvbSAnLi9pbWFnZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgZ2V0Q2xpZW50U2l6ZSwgZ2V0Rml0Q29udGVudFBvc2l0aW9uLCBnZXRPZmZzZXQgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBOekltYWdlQ29udGFpbmVyT3BlcmF0aW9uIHtcbiAgaWNvbjogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG5cbiAgb25DbGljaygpOiB2b2lkO1xufVxuXG5jb25zdCBpbml0aWFsUG9zaXRpb24gPSB7XG4gIHg6IDAsXG4gIHk6IDBcbn07XG5cbmV4cG9ydCBjb25zdCBOWl9ERUZBVUxUX1NDQUxFX1NURVAgPSAwLjU7XG5jb25zdCBOWl9ERUZBVUxUX1pPT00gPSAxO1xuY29uc3QgTlpfREVGQVVMVF9ST1RBVEUgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei1pbWFnZS1wcmV2aWV3JyxcbiAgZXhwb3J0QXM6ICduekltYWdlUHJldmlldycsXG4gIGFuaW1hdGlvbnM6IFtmYWRlTW90aW9uXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwiYW50LWltYWdlLXByZXZpZXdcIj5cbiAgICAgIDxkaXYgdGFiaW5kZXg9XCIwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCIgc3R5bGU9XCJ3aWR0aDogMDsgaGVpZ2h0OiAwOyBvdmVyZmxvdzogaGlkZGVuOyBvdXRsaW5lOiBub25lO1wiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LWNvbnRlbnRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LWJvZHlcIj5cbiAgICAgICAgICA8dWwgY2xhc3M9XCJhbnQtaW1hZ2UtcHJldmlldy1vcGVyYXRpb25zXCI+XG4gICAgICAgICAgICA8bGlcbiAgICAgICAgICAgICAgY2xhc3M9XCJhbnQtaW1hZ2UtcHJldmlldy1vcGVyYXRpb25zLW9wZXJhdGlvblwiXG4gICAgICAgICAgICAgIFtjbGFzcy5hbnQtaW1hZ2UtcHJldmlldy1vcGVyYXRpb25zLW9wZXJhdGlvbi1kaXNhYmxlZF09XCJ6b29tT3V0RGlzYWJsZWQgJiYgb3B0aW9uLnR5cGUgPT09ICd6b29tT3V0J1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvcHRpb24ub25DbGljaygpXCJcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBvcGVyYXRpb25zXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbnQtaW1hZ2UtcHJldmlldy1vcGVyYXRpb25zLWljb25cIiBuei1pY29uIFtuelR5cGVdPVwib3B0aW9uLmljb25cIiBuelRoZW1lPVwib3V0bGluZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC91bD5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LWltZy13cmFwcGVyXCJcbiAgICAgICAgICAgICNpbWFnZVByZXZpZXdXcmFwcGVyXG4gICAgICAgICAgICBjZGtEcmFnXG4gICAgICAgICAgICBbc3R5bGUudHJhbnNmb3JtXT1cInByZXZpZXdJbWFnZVdyYXBwZXJUcmFuc2Zvcm1cIlxuICAgICAgICAgICAgW2Nka0RyYWdGcmVlRHJhZ1Bvc2l0aW9uXT1cInBvc2l0aW9uXCJcbiAgICAgICAgICAgIChjZGtEcmFnUmVsZWFzZWQpPVwib25EcmFnUmVsZWFzZWQoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaW1hZ2Ugb2YgaW1hZ2VzOyBpbmRleCBhcyBpbWFnZUluZGV4XCI+XG4gICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICBjZGtEcmFnSGFuZGxlXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJhbnQtaW1hZ2UtcHJldmlldy1pbWdcIlxuICAgICAgICAgICAgICAgICNpbWdSZWZcbiAgICAgICAgICAgICAgICAqbmdJZj1cImluZGV4ID09PSBpbWFnZUluZGV4XCJcbiAgICAgICAgICAgICAgICBbYXR0ci5zcmNdPVwic2FuaXRpemVyUmVzb3VyY2VVcmwoaW1hZ2Uuc3JjKVwiXG4gICAgICAgICAgICAgICAgW2F0dHIuc3Jjc2V0XT1cImltYWdlLnNyY3NldFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYWx0XT1cImltYWdlLmFsdFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImltYWdlLndpZHRoXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cImltYWdlLmhlaWdodFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLnRyYW5zZm9ybV09XCJwcmV2aWV3SW1hZ2VUcmFuc2Zvcm1cIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImltYWdlcy5sZW5ndGggPiAxXCI+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzPVwiYW50LWltYWdlLXByZXZpZXctc3dpdGNoLWxlZnRcIlxuICAgICAgICAgICAgICBbY2xhc3MuYW50LWltYWdlLXByZXZpZXctc3dpdGNoLWxlZnQtZGlzYWJsZWRdPVwiaW5kZXggPD0gMFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvblN3aXRjaExlZnQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxzcGFuIG56LWljb24gbnpUeXBlPVwibGVmdFwiIG56VGhlbWU9XCJvdXRsaW5lXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzPVwiYW50LWltYWdlLXByZXZpZXctc3dpdGNoLXJpZ2h0XCJcbiAgICAgICAgICAgICAgW2NsYXNzLmFudC1pbWFnZS1wcmV2aWV3LXN3aXRjaC1yaWdodC1kaXNhYmxlZF09XCJpbmRleCA+PSBpbWFnZXMubGVuZ3RoIC0gMVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvblN3aXRjaFJpZ2h0KCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3BhbiBuei1pY29uIG56VHlwZT1cInJpZ2h0XCIgbnpUaGVtZT1cIm91dGxpbmVcIj48L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgdGFiaW5kZXg9XCIwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCIgc3R5bGU9XCJ3aWR0aDogMDsgaGVpZ2h0OiAwOyBvdmVyZmxvdzogaGlkZGVuOyBvdXRsaW5lOiBub25lO1wiPjwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC1pbWFnZS1wcmV2aWV3LXdyYXAnLFxuICAgICdbY2xhc3MuYW50LWltYWdlLXByZXZpZXctbW92aW5nXSc6ICdpc0RyYWdnaW5nJyxcbiAgICAnW3N0eWxlLnpJbmRleF0nOiAnY29uZmlnLm56WkluZGV4JyxcbiAgICAnW0AuZGlzYWJsZWRdJzogJ2NvbmZpZy5uek5vQW5pbWF0aW9uJyxcbiAgICAnW0BmYWRlTW90aW9uXSc6ICdhbmltYXRpb25TdGF0ZScsXG4gICAgJyhAZmFkZU1vdGlvbi5zdGFydCknOiAnb25BbmltYXRpb25TdGFydCgkZXZlbnQpJyxcbiAgICAnKEBmYWRlTW90aW9uLmRvbmUpJzogJ29uQW5pbWF0aW9uRG9uZSgkZXZlbnQpJyxcbiAgICB0YWJpbmRleDogJy0xJyxcbiAgICByb2xlOiAnZG9jdW1lbnQnXG4gIH0sXG4gIGltcG9ydHM6IFtOZ0Zvck9mLCBOekljb25Nb2R1bGUsIENka0RyYWdIYW5kbGUsIENka0RyYWcsIE5nSWZdLFxuICBwcm92aWRlcnM6IFtOekRlc3Ryb3lTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBOekltYWdlUHJldmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHJlYWRvbmx5IF9kZWZhdWx0Tnpab29tID0gTlpfREVGQVVMVF9aT09NO1xuICByZWFkb25seSBfZGVmYXVsdE56U2NhbGVTdGVwID0gTlpfREVGQVVMVF9TQ0FMRV9TVEVQO1xuICByZWFkb25seSBfZGVmYXVsdE56Um90YXRlID0gTlpfREVGQVVMVF9ST1RBVEU7XG5cbiAgaW1hZ2VzOiBOekltYWdlW10gPSBbXTtcbiAgaW5kZXggPSAwO1xuICBpc0RyYWdnaW5nID0gZmFsc2U7XG4gIHZpc2libGUgPSB0cnVlO1xuICBhbmltYXRpb25TdGF0ZTogJ3ZvaWQnIHwgJ2VudGVyJyB8ICdsZWF2ZScgPSAnZW50ZXInO1xuICBhbmltYXRpb25TdGF0ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEFuaW1hdGlvbkV2ZW50PigpO1xuICBzY2FsZVN0ZXBNYXA6IE1hcDxOekltYWdlVXJsLCBOekltYWdlU2NhbGVTdGVwPiA9IG5ldyBNYXA8TnpJbWFnZVVybCwgTnpJbWFnZVNjYWxlU3RlcD4oKTtcblxuICBwcmV2aWV3SW1hZ2VUcmFuc2Zvcm0gPSAnJztcbiAgcHJldmlld0ltYWdlV3JhcHBlclRyYW5zZm9ybSA9ICcnO1xuICBvcGVyYXRpb25zOiBOekltYWdlQ29udGFpbmVyT3BlcmF0aW9uW10gPSBbXG4gICAge1xuICAgICAgaWNvbjogJ2Nsb3NlJyxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5vbkNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ2Nsb3NlJ1xuICAgIH0sXG4gICAge1xuICAgICAgaWNvbjogJ3pvb20taW4nLFxuICAgICAgb25DbGljazogKCkgPT4ge1xuICAgICAgICB0aGlzLm9uWm9vbUluKCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ3pvb21JbidcbiAgICB9LFxuICAgIHtcbiAgICAgIGljb246ICd6b29tLW91dCcsXG4gICAgICBvbkNsaWNrOiAoKSA9PiB7XG4gICAgICAgIHRoaXMub25ab29tT3V0KCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ3pvb21PdXQnXG4gICAgfSxcbiAgICB7XG4gICAgICBpY29uOiAncm90YXRlLXJpZ2h0JyxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5vblJvdGF0ZVJpZ2h0KCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ3JvdGF0ZVJpZ2h0J1xuICAgIH0sXG4gICAge1xuICAgICAgaWNvbjogJ3JvdGF0ZS1sZWZ0JyxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5vblJvdGF0ZUxlZnQoKTtcbiAgICAgIH0sXG4gICAgICB0eXBlOiAncm90YXRlTGVmdCdcbiAgICB9XG4gIF07XG5cbiAgem9vbU91dERpc2FibGVkID0gZmFsc2U7XG4gIHBvc2l0aW9uID0geyAuLi5pbml0aWFsUG9zaXRpb24gfTtcbiAgcHJldmlld1JlZiE6IE56SW1hZ2VQcmV2aWV3UmVmO1xuICBjb250YWluZXJDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgY2xvc2VDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBAVmlld0NoaWxkKCdpbWdSZWYnKSBpbWFnZVJlZiE6IEVsZW1lbnRSZWY8SFRNTEltYWdlRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ2ltYWdlUHJldmlld1dyYXBwZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBpbWFnZVByZXZpZXdXcmFwcGVyITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgcHJpdmF0ZSB6b29tOiBudW1iZXI7XG4gIHByaXZhdGUgcm90YXRlOiBudW1iZXI7XG4gIHByaXZhdGUgc2NhbGVTdGVwOiBudW1iZXI7XG5cbiAgZ2V0IGFuaW1hdGlvbkRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5uek5vQW5pbWF0aW9uID8/IGZhbHNlO1xuICB9XG5cbiAgZ2V0IG1hc2tDbG9zYWJsZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBkZWZhdWx0Q29uZmlnOiBOelNhZmVBbnkgPSB0aGlzLm56Q29uZmlnU2VydmljZS5nZXRDb25maWdGb3JDb21wb25lbnQoTlpfQ09ORklHX01PRFVMRV9OQU1FKSB8fCB7fTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcubnpNYXNrQ2xvc2FibGUgPz8gZGVmYXVsdENvbmZpZy5uek1hc2tDbG9zYWJsZSA/PyB0cnVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGhvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UsXG4gICAgcHVibGljIGNvbmZpZzogTnpJbWFnZVByZXZpZXdPcHRpb25zLFxuICAgIHByaXZhdGUgb3ZlcmxheVJlZjogT3ZlcmxheVJlZixcbiAgICBwcml2YXRlIGRlc3Ryb3kkOiBOekRlc3Ryb3lTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXJcbiAgKSB7XG4gICAgdGhpcy56b29tID0gdGhpcy5jb25maWcubnpab29tID8/IHRoaXMuX2RlZmF1bHROelpvb207XG4gICAgdGhpcy5zY2FsZVN0ZXAgPSB0aGlzLmNvbmZpZy5uelNjYWxlU3RlcCA/PyB0aGlzLl9kZWZhdWx0TnpTY2FsZVN0ZXA7XG4gICAgdGhpcy5yb3RhdGUgPSB0aGlzLmNvbmZpZy5uelJvdGF0ZSA/PyB0aGlzLl9kZWZhdWx0TnpSb3RhdGU7XG4gICAgdGhpcy51cGRhdGVab29tT3V0RGlzYWJsZWQoKTtcbiAgICB0aGlzLnVwZGF0ZVByZXZpZXdJbWFnZVRyYW5zZm9ybSgpO1xuICAgIHRoaXMudXBkYXRlUHJldmlld0ltYWdlV3JhcHBlclRyYW5zZm9ybSgpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50KHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50LCAnY2xpY2snKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICAgIGlmIChldmVudC50YXJnZXQgPT09IGV2ZW50LmN1cnJlbnRUYXJnZXQgJiYgdGhpcy5tYXNrQ2xvc2FibGUgJiYgdGhpcy5jb250YWluZXJDbGljay5vYnNlcnZlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5jb250YWluZXJDbGljay5lbWl0KCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgIGZyb21FdmVudCh0aGlzLmltYWdlUHJldmlld1dyYXBwZXIubmF0aXZlRWxlbWVudCwgJ21vdXNlZG93bicpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRJbWFnZXMoaW1hZ2VzOiBOekltYWdlW10sIHNjYWxlU3RlcE1hcD86IE1hcDxzdHJpbmcsIG51bWJlcj4pOiB2b2lkIHtcbiAgICBpZiAoc2NhbGVTdGVwTWFwKSB0aGlzLnNjYWxlU3RlcE1hcCA9IHNjYWxlU3RlcE1hcDtcbiAgICB0aGlzLmltYWdlcyA9IGltYWdlcztcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHN3aXRjaFRvKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBuZXh0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmluZGV4IDwgdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkge1xuICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgdGhpcy5pbmRleCsrO1xuICAgICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VUcmFuc2Zvcm0oKTtcbiAgICAgIHRoaXMudXBkYXRlUHJldmlld0ltYWdlV3JhcHBlclRyYW5zZm9ybSgpO1xuICAgICAgdGhpcy51cGRhdGVab29tT3V0RGlzYWJsZWQoKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByZXYoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW5kZXggPiAwKSB7XG4gICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICB0aGlzLmluZGV4LS07XG4gICAgICB0aGlzLnVwZGF0ZVByZXZpZXdJbWFnZVRyYW5zZm9ybSgpO1xuICAgICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VXcmFwcGVyVHJhbnNmb3JtKCk7XG4gICAgICB0aGlzLnVwZGF0ZVpvb21PdXREaXNhYmxlZCgpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbWFya0ZvckNoZWNrKCk6IHZvaWQge1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25DbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ2xpY2suZW1pdCgpO1xuICB9XG5cbiAgb25ab29tSW4oKTogdm9pZCB7XG4gICAgY29uc3Qgem9vbVN0ZXAgPVxuICAgICAgdGhpcy5zY2FsZVN0ZXBNYXAuZ2V0KHRoaXMuaW1hZ2VzW3RoaXMuaW5kZXhdLnNyYyA/PyB0aGlzLmltYWdlc1t0aGlzLmluZGV4XS5zcmNzZXQpID8/IHRoaXMuc2NhbGVTdGVwO1xuICAgIHRoaXMuem9vbSArPSB6b29tU3RlcDtcbiAgICB0aGlzLnVwZGF0ZVByZXZpZXdJbWFnZVRyYW5zZm9ybSgpO1xuICAgIHRoaXMudXBkYXRlWm9vbU91dERpc2FibGVkKCk7XG4gICAgdGhpcy5wb3NpdGlvbiA9IHsgLi4uaW5pdGlhbFBvc2l0aW9uIH07XG4gIH1cblxuICBvblpvb21PdXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuem9vbSA+IDEpIHtcbiAgICAgIGNvbnN0IHpvb21TdGVwID1cbiAgICAgICAgdGhpcy5zY2FsZVN0ZXBNYXAuZ2V0KHRoaXMuaW1hZ2VzW3RoaXMuaW5kZXhdLnNyYyA/PyB0aGlzLmltYWdlc1t0aGlzLmluZGV4XS5zcmNzZXQpID8/IHRoaXMuc2NhbGVTdGVwO1xuICAgICAgdGhpcy56b29tIC09IHpvb21TdGVwO1xuICAgICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VUcmFuc2Zvcm0oKTtcbiAgICAgIHRoaXMudXBkYXRlWm9vbU91dERpc2FibGVkKCk7XG4gICAgICB0aGlzLnBvc2l0aW9uID0geyAuLi5pbml0aWFsUG9zaXRpb24gfTtcbiAgICB9XG4gIH1cblxuICBvblJvdGF0ZVJpZ2h0KCk6IHZvaWQge1xuICAgIHRoaXMucm90YXRlICs9IDkwO1xuICAgIHRoaXMudXBkYXRlUHJldmlld0ltYWdlVHJhbnNmb3JtKCk7XG4gIH1cblxuICBvblJvdGF0ZUxlZnQoKTogdm9pZCB7XG4gICAgdGhpcy5yb3RhdGUgLT0gOTA7XG4gICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VUcmFuc2Zvcm0oKTtcbiAgfVxuXG4gIG9uU3dpdGNoTGVmdChldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5wcmV2KCk7XG4gIH1cblxuICBvblN3aXRjaFJpZ2h0KGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm5leHQoKTtcbiAgfVxuXG4gIG9uQW5pbWF0aW9uU3RhcnQoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LnRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuc2V0RW50ZXJBbmltYXRpb25DbGFzcygpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQudG9TdGF0ZSA9PT0gJ2xlYXZlJykge1xuICAgICAgdGhpcy5zZXRMZWF2ZUFuaW1hdGlvbkNsYXNzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRpb25TdGF0ZUNoYW5nZWQuZW1pdChldmVudCk7XG4gIH1cblxuICBvbkFuaW1hdGlvbkRvbmUoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LnRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuc2V0RW50ZXJBbmltYXRpb25DbGFzcygpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQudG9TdGF0ZSA9PT0gJ2xlYXZlJykge1xuICAgICAgdGhpcy5zZXRMZWF2ZUFuaW1hdGlvbkNsYXNzKCk7XG4gICAgfVxuICAgIHRoaXMuYW5pbWF0aW9uU3RhdGVDaGFuZ2VkLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgc3RhcnRMZWF2ZUFuaW1hdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmFuaW1hdGlvblN0YXRlID0gJ2xlYXZlJztcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uRHJhZ1JlbGVhc2VkKCk6IHZvaWQge1xuICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgIGNvbnN0IHdpZHRoID0gdGhpcy5pbWFnZVJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoICogdGhpcy56b29tO1xuICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuaW1hZ2VSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgKiB0aGlzLnpvb207XG4gICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGdldE9mZnNldCh0aGlzLmltYWdlUmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgIGNvbnN0IHsgd2lkdGg6IGNsaWVudFdpZHRoLCBoZWlnaHQ6IGNsaWVudEhlaWdodCB9ID0gZ2V0Q2xpZW50U2l6ZSgpO1xuICAgIGNvbnN0IGlzUm90YXRlID0gdGhpcy5yb3RhdGUgJSAxODAgIT09IDA7XG4gICAgY29uc3QgZml0Q29udGVudFBhcmFtcyA9IHtcbiAgICAgIHdpZHRoOiBpc1JvdGF0ZSA/IGhlaWdodCA6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBpc1JvdGF0ZSA/IHdpZHRoIDogaGVpZ2h0LFxuICAgICAgbGVmdCxcbiAgICAgIHRvcCxcbiAgICAgIGNsaWVudFdpZHRoLFxuICAgICAgY2xpZW50SGVpZ2h0XG4gICAgfTtcbiAgICBjb25zdCBmaXRDb250ZW50UG9zID0gZ2V0Rml0Q29udGVudFBvc2l0aW9uKGZpdENvbnRlbnRQYXJhbXMpO1xuICAgIGlmIChpc05vdE5pbChmaXRDb250ZW50UG9zLngpIHx8IGlzTm90TmlsKGZpdENvbnRlbnRQb3MueSkpIHtcbiAgICAgIHRoaXMucG9zaXRpb24gPSB7IC4uLnRoaXMucG9zaXRpb24sIC4uLmZpdENvbnRlbnRQb3MgfTtcbiAgICB9XG4gIH1cblxuICBzYW5pdGl6ZXJSZXNvdXJjZVVybCh1cmw6IHN0cmluZyk6IFNhZmVSZXNvdXJjZVVybCB7XG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybCh1cmwpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVQcmV2aWV3SW1hZ2VUcmFuc2Zvcm0oKTogdm9pZCB7XG4gICAgdGhpcy5wcmV2aWV3SW1hZ2VUcmFuc2Zvcm0gPSBgc2NhbGUzZCgke3RoaXMuem9vbX0sICR7dGhpcy56b29tfSwgMSkgcm90YXRlKCR7dGhpcy5yb3RhdGV9ZGVnKWA7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVByZXZpZXdJbWFnZVdyYXBwZXJUcmFuc2Zvcm0oKTogdm9pZCB7XG4gICAgdGhpcy5wcmV2aWV3SW1hZ2VXcmFwcGVyVHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7dGhpcy5wb3NpdGlvbi54fXB4LCAke3RoaXMucG9zaXRpb24ueX1weCwgMClgO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVab29tT3V0RGlzYWJsZWQoKTogdm9pZCB7XG4gICAgdGhpcy56b29tT3V0RGlzYWJsZWQgPSB0aGlzLnpvb20gPD0gMTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0RW50ZXJBbmltYXRpb25DbGFzcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hbmltYXRpb25EaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBiYWNrZHJvcEVsZW1lbnQgPSB0aGlzLm92ZXJsYXlSZWYuYmFja2Ryb3BFbGVtZW50O1xuICAgIGlmIChiYWNrZHJvcEVsZW1lbnQpIHtcbiAgICAgIGJhY2tkcm9wRWxlbWVudC5jbGFzc0xpc3QuYWRkKEZBREVfQ0xBU1NfTkFNRV9NQVAuZW50ZXIpO1xuICAgICAgYmFja2Ryb3BFbGVtZW50LmNsYXNzTGlzdC5hZGQoRkFERV9DTEFTU19OQU1FX01BUC5lbnRlckFjdGl2ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRMZWF2ZUFuaW1hdGlvbkNsYXNzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFuaW1hdGlvbkRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGJhY2tkcm9wRWxlbWVudCA9IHRoaXMub3ZlcmxheVJlZi5iYWNrZHJvcEVsZW1lbnQ7XG4gICAgaWYgKGJhY2tkcm9wRWxlbWVudCkge1xuICAgICAgYmFja2Ryb3BFbGVtZW50LmNsYXNzTGlzdC5hZGQoRkFERV9DTEFTU19OQU1FX01BUC5sZWF2ZSk7XG4gICAgICBiYWNrZHJvcEVsZW1lbnQuY2xhc3NMaXN0LmFkZChGQURFX0NMQVNTX05BTUVfTUFQLmxlYXZlQWN0aXZlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuem9vbSA9IHRoaXMuY29uZmlnLm56Wm9vbSA/PyB0aGlzLl9kZWZhdWx0Tnpab29tO1xuICAgIHRoaXMuc2NhbGVTdGVwID0gdGhpcy5jb25maWcubnpTY2FsZVN0ZXAgPz8gdGhpcy5fZGVmYXVsdE56U2NhbGVTdGVwO1xuICAgIHRoaXMucm90YXRlID0gdGhpcy5jb25maWcubnpSb3RhdGUgPz8gdGhpcy5fZGVmYXVsdE56Um90YXRlO1xuICAgIHRoaXMucG9zaXRpb24gPSB7IC4uLmluaXRpYWxQb3NpdGlvbiB9O1xuICB9XG59XG4iXX0=