UNPKG

ngx-pinch-zoom

Version:
424 lines (423 loc) 48.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import { Component, HostBinding, ElementRef, HostListener, ViewChild, Input, EventEmitter, Output } from '@angular/core'; export class PinchZoomComponent { /** * @param {?} elementRef */ constructor(elementRef) { this.elementRef = elementRef; this.i = 0; this.scale = 1; this.initialScale = 1; this.moveX = 0; this.moveY = 0; this.initialMoveX = 0; this.initialMoveY = 0; this.draggingMode = false; this.lastTap = 0; this.transitionDuration = 200; this.autoZoomOut = false; this.events = new EventEmitter(); } /** * @param {?} value * @return {?} */ set id(value) { this._id = value; } /** * @return {?} */ get id() { return this._id; } /** * @return {?} */ get isMobile() { var /** @type {?} */ check = false; (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; })(navigator.userAgent || navigator.vendor); return check; } ; /** * @return {?} */ get isDragging() { let /** @type {?} */ imgHeight = this.getImageHeight(); let /** @type {?} */ imgWidth = this.getImageWidth(); if (this.scale > 1) { return imgHeight * this.scale > this.parentElement.offsetHeight || imgWidth * this.scale > this.parentElement.offsetWidth; } if (this.scale === 1) { return imgHeight > this.parentElement.offsetHeight || imgWidth > this.parentElement.offsetWidth; } } /** * @return {?} */ ngOnInit() { this.element = this.contentElement.nativeElement; this.parentElement = this.elementRef.nativeElement; this.setBasicStyles(); } /** * @param {?} event * @return {?} */ onResize(event) { this.setImageWidth(); this.transformElement(this.transitionDuration); } /** * @param {?} event * @return {?} */ touchstartHandler(event) { this.getElementPosition(); if (!this.eventType) { this.startX = event.touches[0].clientX - this.elementPosition.left; this.startY = event.touches[0].clientY - this.elementPosition.top; this.startClientX = event.touches[0].clientX - this.elementPosition.left; this.startClientY = event.touches[0].clientY - this.elementPosition.top; } this.events.emit({ type: 'touchstart' }); } /** * @param {?} event * @return {?} */ touchmoveHandler(event) { let /** @type {?} */ touches = event.touches; // Swipe if (this.detectSwipe(touches) || this.eventType == 'swipe') { this.handleSwipe(event); } // Pinch if (touches.length === 2 && !this.eventType || this.eventType == 'pinch') { this.handlePinch(event); } } /** * @param {?} event * @return {?} */ touchendHandler(event) { this.i = 0; this.draggingMode = false; let /** @type {?} */ touches = event.touches; if (this.scale < 1) { this.scale = 1; } // Auto Zoom Out if (this.autoZoomOut && this.eventType === 'pinch') { this.scale = 1; } this.events.emit({ type: 'touchend' }); if (this.eventType === 'pinch' || this.eventType === 'swipe') { this.alignImage(); } if (this.eventType === 'pinch' || this.eventType === 'swipe' || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') { this.updateInitialValues(); } this.eventType = 'touchend'; if (touches && touches.length == 0) { this.eventType = ''; } } /** * @param {?} event * @return {?} */ handleSwipe(event) { event.preventDefault(); if (!this.eventType) { this.startX = event.touches[0].clientX - this.elementPosition.left; this.startY = event.touches[0].clientY - this.elementPosition.top; } this.eventType = 'swipe'; this.events.emit({ type: 'swipe', moveX: this.moveX, moveY: this.moveY }); this.moveX = this.initialMoveX + ((event.touches[0].clientX - this.elementPosition.left) - this.startX); this.moveY = this.initialMoveY + ((event.touches[0].clientY - this.elementPosition.top) - this.startY); this.transformElement(0); } /** * @param {?} event * @return {?} */ handlePinch(event) { event.preventDefault(); let /** @type {?} */ touches = event.touches; if (!this.eventType) { this.initialDistance = this.getDistance(touches); this.moveXC = (((event.touches[0].clientX - this.elementPosition.left) + (event.touches[1].clientX - this.elementPosition.left)) / 2) - this.initialMoveX; this.moveYC = (((event.touches[0].clientY - this.elementPosition.top) + (event.touches[1].clientY - this.elementPosition.top)) / 2) - this.initialMoveY; } this.eventType = 'pinch'; this.events.emit({ type: 'pinch' }); this.distance = this.getDistance(touches); this.scale = this.initialScale * (this.distance / this.initialDistance); this.moveX = this.initialMoveX - (((this.distance / this.initialDistance) * this.moveXC) - this.moveXC); this.moveY = this.initialMoveY - (((this.distance / this.initialDistance) * this.moveYC) - this.moveYC); this.transformElement(0); } /** * @param {?} touches * @return {?} */ detectSwipe(touches) { return touches.length === 1 && this.scale > 1 && !this.eventType; } /** * @param {?} touches * @return {?} */ getDistance(touches) { return Math.sqrt(Math.pow(touches[0].pageX - touches[1].pageX, 2) + Math.pow(touches[0].pageY - touches[1].pageY, 2)); } /** * @return {?} */ getImageHeight() { return this.element.getElementsByTagName("img")[0].offsetHeight; } /** * @return {?} */ getImageWidth() { return this.element.getElementsByTagName("img")[0].offsetWidth; } /** * @return {?} */ setBasicStyles() { this.element.style.display = "flex"; this.element.style.height = "100%"; this.element.style.alignItems = "center"; this.element.style.justifyContent = "center"; this.element.style.transformOrigin = '0 0'; this.hostDisplay = "block"; this.hostOverflow = "hidden"; this.hostHeight = this.containerHeight; this.setImageWidth(); } /** * @return {?} */ setImageWidth() { let /** @type {?} */ imgElement = this.element.getElementsByTagName("img"); if (imgElement.length) { imgElement[0].style.maxWidth = '100%'; imgElement[0].style.maxHeight = '100%'; } } /** * @param {?=} duration * @return {?} */ transformElement(duration = 50) { this.element.style.transition = 'all ' + duration + 'ms'; this.element.style.transform = 'matrix(' + Number(this.scale) + ',' + 0 + ',' + 0 + ',' + Number(this.scale) + ',' + Number(this.moveX) + ',' + Number(this.moveY) + ')'; } /** * @return {?} */ resetScale() { this.scale = 1; this.moveX = 0; this.moveY = 0; this.updateInitialValues(); this.transformElement(this.transitionDuration); } /** * @return {?} */ updateInitialValues() { this.initialScale = this.scale; this.initialMoveX = this.moveX; this.initialMoveY = this.moveY; } /** * @return {?} */ centeringImage() { let /** @type {?} */ img = this.element.getElementsByTagName("img")[0]; const /** @type {?} */ initialMoveX = this.moveX; const /** @type {?} */ initialMoveY = this.moveY; if (this.moveY > 0) { this.moveY = 0; } if (this.moveX > 0) { this.moveX = 0; } if (img) { this.transitionYRestriction(); this.transitionXRestriction(); } if (img && this.scale < 1) { if (this.moveX < this.element.offsetWidth * (1 - this.scale)) { this.moveX = this.element.offsetWidth * (1 - this.scale); } } return initialMoveX != this.moveX || initialMoveY != this.moveY; } /** * @return {?} */ alignImage() { let /** @type {?} */ isMoveChanged = this.centeringImage(); if (isMoveChanged) { this.updateInitialValues(); this.transformElement(this.transitionDuration); } } /** * @return {?} */ transitionYRestriction() { let /** @type {?} */ imgHeight = this.getImageHeight(); if (imgHeight * this.scale < this.parentElement.offsetHeight) { this.moveY = (this.parentElement.offsetHeight - this.element.offsetHeight * this.scale) / 2; } else { let /** @type {?} */ imgOffsetTop = ((imgHeight - this.element.offsetHeight) * this.scale) / 2; if (this.moveY > imgOffsetTop) { this.moveY = imgOffsetTop; } else if ((imgHeight * this.scale + Math.abs(imgOffsetTop) - this.parentElement.offsetHeight) + this.moveY < 0) { this.moveY = -(imgHeight * this.scale + Math.abs(imgOffsetTop) - this.parentElement.offsetHeight); } } } /** * @return {?} */ transitionXRestriction() { let /** @type {?} */ imgWidth = this.getImageWidth(); if (imgWidth * this.scale < this.parentElement.offsetWidth) { this.moveX = (this.parentElement.offsetWidth - this.element.offsetWidth * this.scale) / 2; } else { let /** @type {?} */ imgOffsetLeft = ((imgWidth - this.element.offsetWidth) * this.scale) / 2; if (this.moveX > imgOffsetLeft) { this.moveX = imgOffsetLeft; } else if ((imgWidth * this.scale + Math.abs(imgOffsetLeft) - this.parentElement.offsetWidth) + this.moveX < 0) { this.moveX = -(imgWidth * this.scale + Math.abs(imgOffsetLeft) - this.parentElement.offsetWidth); } } } /** * @return {?} */ getElementPosition() { this.elementPosition = this.elementRef.nativeElement.getBoundingClientRect(); } } PinchZoomComponent.decorators = [ { type: Component, args: [{ selector: 'pinch-zoom, [pinch-zoom]', template: `<div #content> <ng-content></ng-content> </div>`, styles: [`:host{position:relative}`] },] }, ]; /** @nocollapse */ PinchZoomComponent.ctorParameters = () => [ { type: ElementRef } ]; PinchZoomComponent.propDecorators = { containerHeight: [{ type: Input, args: ['height',] }], transitionDuration: [{ type: Input, args: ['transition-duration',] }], autoZoomOut: [{ type: Input, args: ['auto-zoom-out',] }], id: [{ type: Input, args: ['id',] }], events: [{ type: Output }], hostDisplay: [{ type: HostBinding, args: ['style.display',] }], hostOverflow: [{ type: HostBinding, args: ['style.overflow',] }], hostHeight: [{ type: HostBinding, args: ['style.height',] }], contentElement: [{ type: ViewChild, args: ['content',] }], onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }], touchstartHandler: [{ type: HostListener, args: ['touchstart', ['$event'],] }], touchmoveHandler: [{ type: HostListener, args: ['touchmove', ['$event'],] }], touchendHandler: [{ type: HostListener, args: ['touchend', ['$event'],] }] }; function PinchZoomComponent_tsickle_Closure_declarations() { /** @type {?} */ PinchZoomComponent.prototype.i; /** @type {?} */ PinchZoomComponent.prototype._id; /** @type {?} */ PinchZoomComponent.prototype.element; /** @type {?} */ PinchZoomComponent.prototype.elementPosition; /** @type {?} */ PinchZoomComponent.prototype.parentElement; /** @type {?} */ PinchZoomComponent.prototype.eventType; /** @type {?} */ PinchZoomComponent.prototype.scale; /** @type {?} */ PinchZoomComponent.prototype.initialScale; /** @type {?} */ PinchZoomComponent.prototype.startX; /** @type {?} */ PinchZoomComponent.prototype.startY; /** @type {?} */ PinchZoomComponent.prototype.startClientX; /** @type {?} */ PinchZoomComponent.prototype.startClientY; /** @type {?} */ PinchZoomComponent.prototype.moveX; /** @type {?} */ PinchZoomComponent.prototype.moveY; /** @type {?} */ PinchZoomComponent.prototype.initialMoveX; /** @type {?} */ PinchZoomComponent.prototype.initialMoveY; /** @type {?} */ PinchZoomComponent.prototype.moveXC; /** @type {?} */ PinchZoomComponent.prototype.moveYC; /** @type {?} */ PinchZoomComponent.prototype.distance; /** @type {?} */ PinchZoomComponent.prototype.initialDistance; /** @type {?} */ PinchZoomComponent.prototype.draggingMode; /** @type {?} */ PinchZoomComponent.prototype.doubleTapTimeout; /** @type {?} */ PinchZoomComponent.prototype.lastTap; /** @type {?} */ PinchZoomComponent.prototype.containerHeight; /** @type {?} */ PinchZoomComponent.prototype.transitionDuration; /** @type {?} */ PinchZoomComponent.prototype.autoZoomOut; /** @type {?} */ PinchZoomComponent.prototype.events; /** @type {?} */ PinchZoomComponent.prototype.hostDisplay; /** @type {?} */ PinchZoomComponent.prototype.hostOverflow; /** @type {?} */ PinchZoomComponent.prototype.hostHeight; /** @type {?} */ PinchZoomComponent.prototype.contentElement; /** @type {?} */ PinchZoomComponent.prototype.elementRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGluY2gtem9vbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtcGluY2gtem9vbS8iLCJzb3VyY2VzIjpbImxpYi9waW5jaC16b29tLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBVSxTQUFTLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFVakksTUFBTTs7OztJQWtFRixZQUFvQixVQUFzQjtRQUF0QixlQUFVLEdBQVYsVUFBVSxDQUFZO2lCQWhFOUIsQ0FBQztxQkFPRyxDQUFDOzRCQUNNLENBQUM7cUJBT1gsQ0FBQztxQkFDRCxDQUFDOzRCQUNNLENBQUM7NEJBQ0QsQ0FBQzs0QkFNRyxLQUFLO3VCQUVYLENBQUM7a0NBR3dDLEdBQUc7MkJBQ2YsS0FBSztzQkFRZCxJQUFJLFlBQVksRUFBTztLQTJCNUQ7Ozs7O0lBbENELElBQWlCLEVBQUUsQ0FBQyxLQUFVO1FBQzFCLElBQUksQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDO0tBQ3BCOzs7O0lBQ0QsSUFBSSxFQUFFO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7S0FDbkI7Ozs7SUFVRCxJQUFJLFFBQVE7UUFDUixxQkFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLENBQUMsVUFBUyxDQUFDLElBQUUsRUFBRSxDQUFBLENBQUMsMFRBQTBULENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFFLHlrREFBeWtELENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLElBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzErRCxNQUFN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QU0sRUFBRSxDQUFDLDBCQUEwQixDQUFDO2FBQ3ZDOzs7O1lBUmdDLFVBQVU7Ozs4QkF3Q3RDLEtBQUssU0FBQyxRQUFRO2lDQUNkLEtBQUssU0FBQyxxQkFBcUI7MEJBQzNCLEtBQUssU0FBQyxlQUFlO2lCQUNyQixLQUFLLFNBQUMsSUFBSTtxQkFPVixNQUFNOzBCQUVOLFdBQVcsU0FBQyxlQUFlOzJCQUMzQixXQUFXLFNBQUMsZ0JBQWdCO3lCQUM1QixXQUFXLFNBQUMsY0FBYzs2QkFFMUIsU0FBUyxTQUFDLFNBQVM7dUJBa0NuQixZQUFZLFNBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDO2dDQU14QyxZQUFZLFNBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDOytCQWNyQyxZQUFZLFNBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDOzhCQWVwQyxZQUFZLFNBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0QmluZGluZywgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBPbkluaXQsIFZpZXdDaGlsZCwgSW5wdXQsIEV2ZW50RW1pdHRlciwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAncGluY2gtem9vbSwgW3BpbmNoLXpvb21dJyxcbiAgICB0ZW1wbGF0ZTogYDxkaXYgI2NvbnRlbnQ+XG5cdDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvZGl2PmAsXG4gICAgc3R5bGVzOiBbYDpob3N0e3Bvc2l0aW9uOnJlbGF0aXZlfWBdXG59KVxuXG5leHBvcnQgY2xhc3MgUGluY2hab29tQ29tcG9uZW50IHtcblxuICAgIGk6IG51bWJlciA9IDA7XG4gICAgX2lkOiBhbnk7XG4gICAgZWxlbWVudDogYW55O1xuICAgIGVsZW1lbnRQb3NpdGlvbjogYW55O1xuICAgIHBhcmVudEVsZW1lbnQ6IGFueTtcbiAgICBldmVudFR5cGU6IGFueTtcblxuICAgIHNjYWxlOiBudW1iZXIgPSAxO1xuICAgIGluaXRpYWxTY2FsZTogbnVtYmVyID0gMTtcblxuICAgIHN0YXJ0WDogbnVtYmVyO1xuICAgIHN0YXJ0WTogbnVtYmVyO1xuICAgIHN0YXJ0Q2xpZW50WDogbnVtYmVyO1xuICAgIHN0YXJ0Q2xpZW50WTogbnVtYmVyO1xuXG4gICAgbW92ZVg6IGFueSA9IDA7XG4gICAgbW92ZVk6IGFueSA9IDA7XG4gICAgaW5pdGlhbE1vdmVYOiBhbnkgPSAwO1xuICAgIGluaXRpYWxNb3ZlWTogYW55ID0gMDtcbiAgICBtb3ZlWEM6IG51bWJlcjtcbiAgICBtb3ZlWUM6IG51bWJlcjtcblxuICAgIGRpc3RhbmNlOiBudW1iZXI7XG4gICAgaW5pdGlhbERpc3RhbmNlOiBudW1iZXI7XG4gICAgZHJhZ2dpbmdNb2RlOiBib29sZWFuID0gZmFsc2U7XG4gICAgZG91YmxlVGFwVGltZW91dDogYW55O1xuICAgIGxhc3RUYXA6IG51bWJlciA9IDA7XG5cbiAgICBASW5wdXQoJ2hlaWdodCcpIGNvbnRhaW5lckhlaWdodDogc3RyaW5nO1xuICAgIEBJbnB1dCgndHJhbnNpdGlvbi1kdXJhdGlvbicpIHRyYW5zaXRpb25EdXJhdGlvbjogbnVtYmVyID0gMjAwO1xuICAgIEBJbnB1dCgnYXV0by16b29tLW91dCcpIGF1dG9ab29tT3V0OiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCdpZCcpIHNldCBpZCh2YWx1ZTogYW55KSB7XG4gICAgICAgIHRoaXMuX2lkID0gdmFsdWU7XG4gICAgfVxuICAgIGdldCBpZCgpe1xuICAgICAgICByZXR1cm4gdGhpcy5faWQ7XG4gICAgfVxuICAgIFxuICAgIEBPdXRwdXQoKSBldmVudHM6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLmRpc3BsYXknKSBob3N0RGlzcGxheTpzdHJpbmc7XG4gICAgQEhvc3RCaW5kaW5nKCdzdHlsZS5vdmVyZmxvdycpIGhvc3RPdmVyZmxvdzpzdHJpbmc7XG4gICAgQEhvc3RCaW5kaW5nKCdzdHlsZS5oZWlnaHQnKSBob3N0SGVpZ2h0OnN0cmluZztcblxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRlbnQnKSBjb250ZW50RWxlbWVudDogRWxlbWVudFJlZjtcblxuICAgIGdldCBpc01vYmlsZSgpIHtcbiAgICAgICAgdmFyIGNoZWNrID0gZmFsc2U7XG4gICAgICAgIChmdW5jdGlvbihhKXtpZigvKGFuZHJvaWR8YmJcXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVxcL3xibGFja2JlcnJ5fGJsYXplcnxjb21wYWx8ZWxhaW5lfGZlbm5lY3xoaXB0b3B8aWVtb2JpbGV8aXAoaG9uZXxvZCl8aXJpc3xraW5kbGV8bGdlIHxtYWVtb3xtaWRwfG1tcHxtb2JpbGUuK2ZpcmVmb3h8bmV0ZnJvbnR8b3BlcmEgbShvYnxpbilpfHBhbG0oIG9zKT98cGhvbmV8cChpeGl8cmUpXFwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vL2kudGVzdChhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XFwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3XFwtKG58dSl8YzU1XFwvfGNhcGl8Y2N3YXxjZG1cXC18Y2VsbHxjaHRtfGNsZGN8Y21kXFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXFwtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcXC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoXFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXFwtNXxnXFwtbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFxcLShtfHB8dCl8aGVpXFwtfGhpKHB0fHRhKXxocCggaXxpcCl8aHNcXC1jfGh0KGMoXFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVxcLSgyMHxnb3xtYSl8aTIzMHxpYWMoIHxcXC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Y1xcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHxcXC1bYS13XSl8bGlid3xseW54fG0xXFwtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cXC1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dChcXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVxcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XFwtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuXFwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XFwtZ3xxYVxcLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8XFwtWzItN118aVxcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGhcXC18b298cFxcLSl8c2RrXFwvfHNlKGMoXFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFxcLXxzaGFyfHNpZShcXC18bSl8c2tcXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcXC18dlxcLXx2ICl8c3koMDF8bWIpfHQyKDE4fDUwKXx0NigwMHwxMHwxOCl8dGEoZ3R8bGspfHRjbFxcLXx0ZGdcXC18dGVsKGl8bSl8dGltXFwtfHRcXC1tb3x0byhwbHxzaCl8dHMoNzB8bVxcLXxtM3xtNSl8dHhcXC05fHVwKFxcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcXC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFxcLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhc1xcLXx5b3VyfHpldG98enRlXFwtL2kudGVzdChhLnN1YnN0cigwLDQpKSkgY2hlY2sgPSB0cnVlO30pKG5hdmlnYXRvci51c2VyQWdlbnR8fG5hdmlnYXRvci52ZW5kb3IpO1xuICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgfTtcblxuICAgIGdldCBpc0RyYWdnaW5nKCl7XG4gICAgICAgIGxldCBpbWdIZWlnaHQgPSB0aGlzLmdldEltYWdlSGVpZ2h0KCk7XG4gICAgICAgIGxldCBpbWdXaWR0aCA9IHRoaXMuZ2V0SW1hZ2VXaWR0aCgpO1xuXG4gICAgICAgIGlmICh0aGlzLnNjYWxlID4gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGltZ0hlaWdodCAqIHRoaXMuc2NhbGUgPiB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IGltZ1dpZHRoICogdGhpcy5zY2FsZSA+IHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zY2FsZSA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGltZ0hlaWdodCA+IHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgaW1nV2lkdGggPiB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpe1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNvbnRlbnRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMucGFyZW50RWxlbWVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgICAgICB0aGlzLnNldEJhc2ljU3R5bGVzKCk7XG4gICAgfVxuXG5cbiAgICAvKlxuICAgICAqIE1vYmlsZSBsaXN0ZW5lcnNcbiAgICAgKi9cblxuICAgIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxuICAgIG9uUmVzaXplKGV2ZW50OkV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0SW1hZ2VXaWR0aCgpO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybUVsZW1lbnQodGhpcy50cmFuc2l0aW9uRHVyYXRpb24pOyBcbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgWyckZXZlbnQnXSlcbiAgICB0b3VjaHN0YXJ0SGFuZGxlcihldmVudDphbnkpIHtcbiAgICAgICAgdGhpcy5nZXRFbGVtZW50UG9zaXRpb24oKTtcblxuICAgICAgICBpZiAoIXRoaXMuZXZlbnRUeXBlKXtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRYID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdDtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wO1xuICAgICAgICAgICAgdGhpcy5zdGFydENsaWVudFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0O1xuICAgICAgICAgICAgdGhpcy5zdGFydENsaWVudFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3A7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHt0eXBlOiAndG91Y2hzdGFydCd9KTtcbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCd0b3VjaG1vdmUnLCBbJyRldmVudCddKVxuICAgIHRvdWNobW92ZUhhbmRsZXIoZXZlbnQ6YW55KSB7XG4gICAgICAgIGxldCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcblxuICAgICAgICAvLyBTd2lwZVxuICAgICAgICBpZiAodGhpcy5kZXRlY3RTd2lwZSh0b3VjaGVzKSB8fCB0aGlzLmV2ZW50VHlwZSA9PSAnc3dpcGUnKXtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlU3dpcGUoZXZlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGluY2hcbiAgICAgICAgaWYgKHRvdWNoZXMubGVuZ3RoID09PSAyICYmICF0aGlzLmV2ZW50VHlwZSB8fCB0aGlzLmV2ZW50VHlwZSA9PSAncGluY2gnKXtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUGluY2goZXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcigndG91Y2hlbmQnLCBbJyRldmVudCddKVxuICAgIHRvdWNoZW5kSGFuZGxlcihldmVudDphbnkpIHtcbiAgICAgICAgdGhpcy5pID0gMDtcbiAgICAgICAgdGhpcy5kcmFnZ2luZ01vZGUgPSBmYWxzZTtcbiAgICAgICAgbGV0IHRvdWNoZXMgPSBldmVudC50b3VjaGVzO1xuXG4gICAgICAgIGlmICh0aGlzLnNjYWxlIDwgMSl7XG4gICAgICAgICAgICB0aGlzLnNjYWxlID0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEF1dG8gWm9vbSBPdXRcbiAgICAgICAgaWYgKHRoaXMuYXV0b1pvb21PdXQgJiYgdGhpcy5ldmVudFR5cGUgPT09ICdwaW5jaCcpe1xuICAgICAgICAgICAgdGhpcy5zY2FsZSA9IDE7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHt0eXBlOiAndG91Y2hlbmQnfSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZXZlbnRUeXBlID09PSAncGluY2gnIHx8IHRoaXMuZXZlbnRUeXBlID09PSAnc3dpcGUnKXtcbiAgICAgICAgICAgIHRoaXMuYWxpZ25JbWFnZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZXZlbnRUeXBlID09PSAncGluY2gnIHx8IFxuICAgICAgICAgICAgdGhpcy5ldmVudFR5cGUgPT09ICdzd2lwZScgfHxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRUeXBlID09PSAnaG9yaXpvbnRhbC1zd2lwZScgfHxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRUeXBlID09PSAndmVydGljYWwtc3dpcGUnKXtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSW5pdGlhbFZhbHVlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ldmVudFR5cGUgPSAndG91Y2hlbmQnO1xuXG4gICAgICAgIGlmICh0b3VjaGVzICYmIHRvdWNoZXMubGVuZ3RoID09IDApe1xuICAgICAgICAgICAgdGhpcy5ldmVudFR5cGUgPSAnJztcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLypcbiAgICAgKiBIYW5kbGVyc1xuICAgICAqL1xuXG4gICAgaGFuZGxlU3dpcGUoZXZlbnQ6YW55KXtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBpZiAoIXRoaXMuZXZlbnRUeXBlKXtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRYID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdDtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ldmVudFR5cGUgPSAnc3dpcGUnO1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICdzd2lwZScsXG4gICAgICAgICAgICBtb3ZlWDogdGhpcy5tb3ZlWCxcbiAgICAgICAgICAgIG1vdmVZOiB0aGlzLm1vdmVZXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubW92ZVggPSB0aGlzLmluaXRpYWxNb3ZlWCArICgoZXZlbnQudG91Y2hlc1swXS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdCkgLSB0aGlzLnN0YXJ0WCk7XG4gICAgICAgIHRoaXMubW92ZVkgPSB0aGlzLmluaXRpYWxNb3ZlWSArICgoZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wKSAtIHRoaXMuc3RhcnRZKTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybUVsZW1lbnQoMCk7XG4gICAgfVxuXG4gICAgaGFuZGxlUGluY2goZXZlbnQ6YW55KXtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBsZXQgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XG5cbiAgICAgICAgaWYgKCF0aGlzLmV2ZW50VHlwZSl7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxEaXN0YW5jZSA9IHRoaXMuZ2V0RGlzdGFuY2UodG91Y2hlcyk7XG4gICAgICAgICAgICB0aGlzLm1vdmVYQyA9ICgoKGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQpICsgKGV2ZW50LnRvdWNoZXNbMV0uY2xpZW50WCAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQpKSAvIDIpIC0gdGhpcy5pbml0aWFsTW92ZVg7XG4gICAgICAgICAgICB0aGlzLm1vdmVZQyA9ICgoKGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcCkgKyAoZXZlbnQudG91Y2hlc1sxXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wKSkgLyAyKSAtIHRoaXMuaW5pdGlhbE1vdmVZO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ldmVudFR5cGUgPSAncGluY2gnO1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHt0eXBlOiAncGluY2gnfSk7XG4gICAgICAgIHRoaXMuZGlzdGFuY2UgPSB0aGlzLmdldERpc3RhbmNlKHRvdWNoZXMpO1xuICAgICAgICB0aGlzLnNjYWxlID0gdGhpcy5pbml0aWFsU2NhbGUgKiAodGhpcy5kaXN0YW5jZSAvIHRoaXMuaW5pdGlhbERpc3RhbmNlKTtcbiAgICAgICAgdGhpcy5tb3ZlWCA9IHRoaXMuaW5pdGlhbE1vdmVYIC0gKCgodGhpcy5kaXN0YW5jZSAvIHRoaXMuaW5pdGlhbERpc3RhbmNlKSAqIHRoaXMubW92ZVhDKSAtIHRoaXMubW92ZVhDKTtcbiAgICAgICAgdGhpcy5tb3ZlWSA9IHRoaXMuaW5pdGlhbE1vdmVZIC0gKCgodGhpcy5kaXN0YW5jZSAvIHRoaXMuaW5pdGlhbERpc3RhbmNlKSAqIHRoaXMubW92ZVlDKSAtIHRoaXMubW92ZVlDKTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybUVsZW1lbnQoMCk7XG4gICAgfVxuXG5cbiAgICBkZXRlY3RTd2lwZSh0b3VjaGVzOmFueSl7XG4gICAgICAgIHJldHVybiB0b3VjaGVzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLnNjYWxlID4gMSAmJiAhdGhpcy5ldmVudFR5cGU7XG4gICAgfVxuXG4gICAgZ2V0RGlzdGFuY2UodG91Y2hlczogYW55KXtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydCggTWF0aC5wb3codG91Y2hlc1swXS5wYWdlWCAtIHRvdWNoZXNbMV0ucGFnZVgsIDIpICsgTWF0aC5wb3codG91Y2hlc1swXS5wYWdlWSAtIHRvdWNoZXNbMV0ucGFnZVksIDIpKTtcbiAgICB9XG5cbiAgICBnZXRJbWFnZUhlaWdodCgpe1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaW1nXCIpWzBdLm9mZnNldEhlaWdodDtcbiAgICB9XG5cbiAgICBnZXRJbWFnZVdpZHRoKCl7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpbWdcIilbMF0ub2Zmc2V0V2lkdGg7XG4gICAgfVxuXG4gICAgc2V0QmFzaWNTdHlsZXMoKTp2b2lkIHtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSBcImZsZXhcIjtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYWxpZ25JdGVtcyA9IFwiY2VudGVyXCI7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5qdXN0aWZ5Q29udGVudCA9IFwiY2VudGVyXCI7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSAnMCAwJztcbiAgICAgICAgdGhpcy5ob3N0RGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgICAgdGhpcy5ob3N0T3ZlcmZsb3cgPSBcImhpZGRlblwiO1xuICAgICAgICB0aGlzLmhvc3RIZWlnaHQgPSB0aGlzLmNvbnRhaW5lckhlaWdodDtcblxuICAgICAgICB0aGlzLnNldEltYWdlV2lkdGgoKTtcbiAgICB9XG5cbiAgICBzZXRJbWFnZVdpZHRoKCk6dm9pZCB7XG4gICAgICAgIGxldCBpbWdFbGVtZW50ID0gdGhpcy5lbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaW1nXCIpO1xuXG4gICAgICAgIGlmIChpbWdFbGVtZW50Lmxlbmd0aCl7XG4gICAgICAgICAgICBpbWdFbGVtZW50WzBdLnN0eWxlLm1heFdpZHRoID0gJzEwMCUnO1xuICAgICAgICAgICAgaW1nRWxlbWVudFswXS5zdHlsZS5tYXhIZWlnaHQgPSAnMTAwJSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0cmFuc2Zvcm1FbGVtZW50KGR1cmF0aW9uOiBhbnkgPSA1MCl7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2l0aW9uID0gJ2FsbCAnKyBkdXJhdGlvbiArJ21zJztcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9ICdtYXRyaXgoJysgTnVtYmVyKHRoaXMuc2NhbGUpICsnLCcrIDAgKycsJysgMCArJywnKyBOdW1iZXIodGhpcy5zY2FsZSkgKycsJysgTnVtYmVyKHRoaXMubW92ZVgpICsnLCcrIE51bWJlcih0aGlzLm1vdmVZKSArJyknO1xuICAgIH1cblxuICAgIHJlc2V0U2NhbGUoKTp2b2lkIHtcbiAgICAgICAgdGhpcy5zY2FsZSA9IDE7XG4gICAgICAgIHRoaXMubW92ZVggPSAwO1xuICAgICAgICB0aGlzLm1vdmVZID0gMDtcbiAgICAgICAgdGhpcy51cGRhdGVJbml0aWFsVmFsdWVzKCk7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtRWxlbWVudCh0aGlzLnRyYW5zaXRpb25EdXJhdGlvbik7XG4gICAgfVxuXG4gICAgdXBkYXRlSW5pdGlhbFZhbHVlcygpOnZvaWQge1xuICAgICAgICB0aGlzLmluaXRpYWxTY2FsZSA9IHRoaXMuc2NhbGU7XG4gICAgICAgIHRoaXMuaW5pdGlhbE1vdmVYID0gdGhpcy5tb3ZlWDtcbiAgICAgICAgdGhpcy5pbml0aWFsTW92ZVkgPSB0aGlzLm1vdmVZO1xuICAgIH1cblxuICAgIGNlbnRlcmluZ0ltYWdlKCk6Ym9vbGVhbiB7XG4gICAgICAgIGxldCBpbWcgPSB0aGlzLmVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpbWdcIilbMF07XG4gICAgICAgIGNvbnN0IGluaXRpYWxNb3ZlWCA9IHRoaXMubW92ZVg7XG4gICAgICAgIGNvbnN0IGluaXRpYWxNb3ZlWSA9IHRoaXMubW92ZVk7XG5cbiAgICAgICAgaWYgKHRoaXMubW92ZVkgPiAwKXtcbiAgICAgICAgICAgIHRoaXMubW92ZVkgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1vdmVYID4gMCl7XG4gICAgICAgICAgICB0aGlzLm1vdmVYID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbWcpe1xuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uWVJlc3RyaWN0aW9uKCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25YUmVzdHJpY3Rpb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW1nICYmIHRoaXMuc2NhbGUgPCAxKXtcbiAgICAgICAgICAgIGlmICh0aGlzLm1vdmVYIDwgdGhpcy5lbGVtZW50Lm9mZnNldFdpZHRoICogKDEgLSB0aGlzLnNjYWxlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubW92ZVggPSB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGggKiAoMSAtIHRoaXMuc2NhbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGluaXRpYWxNb3ZlWCAhPSB0aGlzLm1vdmVYIHx8IGluaXRpYWxNb3ZlWSAhPSB0aGlzLm1vdmVZO1xuICAgIH1cblxuICAgIHB1YmxpYyBhbGlnbkltYWdlKCk6dm9pZCB7XG4gICAgICAgIGxldCBpc01vdmVDaGFuZ2VkID0gdGhpcy5jZW50ZXJpbmdJbWFnZSgpO1xuXG4gICAgICAgIGlmIChpc01vdmVDaGFuZ2VkKXtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSW5pdGlhbFZhbHVlcygpO1xuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm1FbGVtZW50KHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRyYW5zaXRpb25ZUmVzdHJpY3Rpb24oKTp2b2lkIHtcbiAgICAgICAgbGV0IGltZ0hlaWdodCA9IHRoaXMuZ2V0SW1hZ2VIZWlnaHQoKTtcblxuICAgICAgICBpZiAoaW1nSGVpZ2h0ICogdGhpcy5zY2FsZSA8IHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQpe1xuICAgICAgICAgICAgdGhpcy5tb3ZlWSA9ICh0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0IC0gdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodCAqIHRoaXMuc2NhbGUpIC8gMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBpbWdPZmZzZXRUb3AgPSAoKGltZ0hlaWdodCAtIHRoaXMuZWxlbWVudC5vZmZzZXRIZWlnaHQpICogdGhpcy5zY2FsZSkgLyAyO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5tb3ZlWSA+IGltZ09mZnNldFRvcCl7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3ZlWSA9IGltZ09mZnNldFRvcDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGltZ0hlaWdodCAqIHRoaXMuc2NhbGUgKyBNYXRoLmFicyhpbWdPZmZzZXRUb3ApIC0gdGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldEhlaWdodCkgKyB0aGlzLm1vdmVZIDwgMCl7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3ZlWSA9IC0gKGltZ0hlaWdodCAqIHRoaXMuc2NhbGUgKyBNYXRoLmFicyhpbWdPZmZzZXRUb3ApIC0gdGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldEhlaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0cmFuc2l0aW9uWFJlc3RyaWN0aW9uKCk6dm9pZCB7XG4gICAgICAgIGxldCBpbWdXaWR0aCA9IHRoaXMuZ2V0SW1hZ2VXaWR0aCgpO1xuXG4gICAgICAgIGlmIChpbWdXaWR0aCAqIHRoaXMuc2NhbGUgPCB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0V2lkdGgpIHtcbiAgICAgICAgICAgIHRoaXMubW92ZVggPSAodGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldFdpZHRoIC0gdGhpcy5lbGVtZW50Lm9mZnNldFdpZHRoICogdGhpcy5zY2FsZSkgLyAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGltZ09mZnNldExlZnQgPSAoKGltZ1dpZHRoIC0gdGhpcy5lbGVtZW50Lm9mZnNldFdpZHRoKSAqIHRoaXMuc2NhbGUpIC8gMjtcblxuICAgICAgICAgICAgaWYgKHRoaXMubW92ZVggPiBpbWdPZmZzZXRMZWZ0KXtcbiAgICAgICAgICAgICAgICB0aGlzLm1vdmVYID0gaW1nT2Zmc2V0TGVmdDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGltZ1dpZHRoICogdGhpcy5zY2FsZSArIE1hdGguYWJzKGltZ09mZnNldExlZnQpIC0gdGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldFdpZHRoKSArIHRoaXMubW92ZVggPCAwKXtcbiAgICAgICAgICAgICAgICB0aGlzLm1vdmVYID0gLSAoaW1nV2lkdGggKiB0aGlzLnNjYWxlICsgTWF0aC5hYnMoaW1nT2Zmc2V0TGVmdCkgLSB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0V2lkdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0RWxlbWVudFBvc2l0aW9uKCk6dm9pZCB7XG4gICAgICAgIHRoaXMuZWxlbWVudFBvc2l0aW9uID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxufSJdfQ==