image-resizer-cropper
Version:
A simple image crop with resizing built for Angular 7, compatible with Angular Universal (SSR).
595 lines (594 loc) • 54.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, ElementRef, Renderer2, Inject, PLATFORM_ID, Output, EventEmitter } from "@angular/core";
import { isPlatformBrowser } from "@angular/common";
var ImageResizerCropperComponent = /** @class */ (function () {
function ImageResizerCropperComponent(_el, _renderer, platformId) {
this._el = _el;
this._renderer = _renderer;
this.platformId = platformId;
this.croppedImage = new EventEmitter(null);
this.error = new EventEmitter(null);
this.isDown = false;
this.offSet = [];
this.isBrowser = isPlatformBrowser(this.platformId);
if (this.isBrowser) {
this.canvasOne = this._renderer.createElement("canvas");
this.contextOne = this.canvasOne.getContext("2d");
this.canvasTwo = this._renderer.createElement("canvas");
this.contextTwo = this.canvasTwo.getContext("2d");
this.canvasThree = this._renderer.createElement("canvas");
this.contextThree = this.canvasThree.getContext("2d");
this.canvasFour = this._renderer.createElement("canvas");
this.contextFour = this.canvasFour.getContext("2d");
this.imgOne = this._renderer.createElement("img");
this.imgTwo = this._renderer.createElement("img");
}
}
Object.defineProperty(ImageResizerCropperComponent.prototype, "crContainer", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector(".cr-container");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "crRange", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#cr-range");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "crImage", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#cr-image");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "crLens", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#cr-lens");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "btn", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#crop");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "testImg", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#test-img");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "finalCrop", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#final-crop");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "fileUpload", {
get: /**
* @return {?}
*/
function () {
return this._el.nativeElement.querySelector("#file-upload");
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
if (this.sourceImage) {
if (this.sourceImage.target && this.sourceImage.target.files) {
this.parseFile(this.sourceImage);
}
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
if (this.sourceImage) {
if (this.imgOne) {
this._renderer.setProperty(this.imgOne, "src", this.crImage.getAttribute("src"));
}
this.setUpListeners();
this.setUpConfigurations();
}
};
/**
* @param {?} changes
* @return {?}
*/
ImageResizerCropperComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes["sourceImage"] &&
!changes["sourceImage"].firstChange &&
changes["sourceImage"].currentValue) {
this.clearImagePosition();
if (changes["sourceImage"].currentValue.target &&
changes["sourceImage"].currentValue.target.files) {
this.parseFile(this.sourceImage);
}
else {
if (this.imgOne) {
this._renderer.setProperty(this.imgOne, "src", this.crImage.getAttribute("src"));
this.setUpListeners();
this.setUpConfigurations();
}
}
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setUpListeners = /**
* @return {?}
*/
function () {
var _this = this;
if (this.isBrowser) {
this._renderer.listen(this.crRange, "input", function (event) {
_this.linkImageToRangeInput(event.target.value);
});
this._renderer.listen(this.crImage, "mousedown", function (event) {
_this.mouseDownOnImage(event);
});
this._renderer.listen(this.crImage, "mouseup", function (event) {
_this.mouseUpOnImage();
if (_this.autoCrop) {
_this.resizeAndCropImage();
}
});
this._renderer.listen(this.crImage, "mousemove", function (event) {
event.preventDefault();
_this.mouseMoveOnImage(event);
});
this._renderer.listen(this.crContainer, "mouseout", function (event) {
_this.keepMouseMoveInsideContainer();
});
this._renderer.listen(this.btn, "click", function (event) {
_this.resizeAndCropImage();
});
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setUpConfigurations = /**
* @return {?}
*/
function () {
this.setBorderColor();
this.setBackgroundOpacity();
this.setLensHeightAndWidth();
};
/**
* @param {?} value
* @return {?}
*/
ImageResizerCropperComponent.prototype.linkImageToRangeInput = /**
* @param {?} value
* @return {?}
*/
function (value) {
/** @type {?} */
var val = value / 100;
this.crImage.style.transform = "scale(" + val + ")";
};
/**
* @param {?} event
* @return {?}
*/
ImageResizerCropperComponent.prototype.mouseDownOnImage = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.isDown = true;
this.offSet = [
event.target.offsetLeft - event.clientX,
event.target.offsetTop - event.clientY
];
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.mouseUpOnImage = /**
* @return {?}
*/
function () {
this.isDown = false;
};
/**
* @param {?} event
* @return {?}
*/
ImageResizerCropperComponent.prototype.mouseMoveOnImage = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (this.isDown) {
/** @type {?} */
var mousePosition = {
x: event.clientX,
y: event.clientY
};
this.crImage.style.left = mousePosition.x + this.offSet[0] + "px";
this.crImage.style.top = mousePosition.y + this.offSet[1] + "px";
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.keepMouseMoveInsideContainer = /**
* @return {?}
*/
function () {
this.isDown = false;
};
/**
* @param {?} e1
* @param {?} e2
* @return {?}
*/
ImageResizerCropperComponent.prototype.checkForOverlap = /**
* @param {?} e1
* @param {?} e2
* @return {?}
*/
function (e1, e2) {
if (e1.length && e1.length > 1) {
e1 = e1[0];
}
if (e2.length && e2.length > 1) {
e2 = e2[0];
}
/** @type {?} */
var rect1 = e1 instanceof Element ? e1.getBoundingClientRect() : false;
/** @type {?} */
var rect2 = e2 instanceof Element ? e2.getBoundingClientRect() : false;
/** @type {?} */
var overlap = null;
if (rect1 && rect2) {
overlap = !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom);
return [overlap, rect1, rect2];
}
else {
return [overlap, rect1, rect2];
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.getResizeRatio = /**
* @return {?}
*/
function () {
/** @type {?} */
var transform = this.crImage.style.transform;
/** @type {?} */
var matrix = transform
.substring(transform.indexOf("(") + 1, transform.indexOf(")"))
.split(",");
return matrix.length > 0 ? matrix[0] : null;
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.drawImageResize = /**
* @return {?}
*/
function () {
/** @type {?} */
var ratio = this.getResizeRatio();
this.canvasTwo.width = this.imgOne.width;
this.canvasTwo.height = this.imgOne.height;
this.contextTwo.drawImage(this.imgOne, 0, 0);
this.canvasOne.width = this.imgOne.width * ratio;
this.canvasOne.height = this.imgOne.height * ratio;
this.contextOne.drawImage(this.canvasTwo, 0, 0, this.canvasTwo.width, this.canvasTwo.height, 0, 0, this.canvasOne.width, this.canvasOne.height);
/** @type {?} */
var i = this.canvasOne.toDataURL("image/png", 100);
if (this.testImg) {
this._renderer.setProperty(this.testImg, "src", i);
}
return i;
};
/**
* @param {?} src
* @return {?}
*/
ImageResizerCropperComponent.prototype.drawImageCrop = /**
* @param {?} src
* @return {?}
*/
function (src) {
var _this = this;
/** @type {?} */
var overlap = this.checkForOverlap(this.crLens, this.crImage);
if (this.imgTwo) {
this._renderer.setProperty(this.imgTwo, "src", src);
return new Promise(function (resolve, reject) {
_this._renderer.listen(_this.imgTwo, "load", function (event) {
_this.canvasThree.width = event.target.width;
_this.canvasThree.height = event.target.height;
_this.contextThree.drawImage(_this.imgTwo, 0, 0);
_this.canvasFour.width = _this.lensWidth;
_this.canvasFour.height = _this.lensHeight;
if (overlap) {
/** @type {?} */
var xCrop = overlap[1]["x"] - overlap[2]["x"];
/** @type {?} */
var yCrop = overlap[1]["y"] - overlap[2]["y"];
_this.contextFour.drawImage(_this.canvasThree, xCrop, yCrop, _this.lensWidth, _this.lensHeight, 0, 0, _this.lensWidth, _this.lensHeight);
if (_this.roundCrop) {
_this.contextFour.globalCompositeOperation = "destination-in";
_this.contextFour.beginPath();
_this.contextFour.arc(_this.lensWidth / 2, _this.lensHeight / 2, _this.lensHeight / 2, 0, Math.PI * 2);
_this.contextFour.closePath();
_this.contextFour.fill();
}
/** @type {?} */
var b_1 = _this.canvasFour.toDataURL("image/png", 100);
_this.cropAvailable = true;
setTimeout(function () {
if (_this.finalCrop) {
_this._renderer.setProperty(_this.finalCrop, "src", b_1);
}
});
resolve(b_1);
}
});
});
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.resizeAndCropImage = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var imgSrc = this.drawImageResize();
this.drawImageCrop(imgSrc).then(function (result) {
_this.croppedImage.emit(result);
console.log(result);
});
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setLensHeightAndWidth = /**
* @return {?}
*/
function () {
if (this.lensHeight && this.lensHeight !== 150) {
this._renderer.setStyle(this.crLens, "height", this.lensHeight + "px");
}
if (this.lensWidth && this.lensWidth !== 150) {
this._renderer.setStyle(this.crLens, "width", this.lensWidth + "px");
}
if (this.roundCrop) {
this._renderer.addClass(this.crLens, "rounded");
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setBorderColor = /**
* @return {?}
*/
function () {
var _this = this;
if (this.borderColor) {
this._renderer.setStyle(this.crContainer, "border-color", this.borderColor);
this._renderer.setStyle(this.crLens, "border-color", this.borderColor);
/** @type {?} */
var spans = this.crLens.querySelectorAll("span");
spans.forEach(function (element) {
_this._renderer.setStyle(element, "border-color", _this.borderColor);
});
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setBackgroundOpacity = /**
* @return {?}
*/
function () {
if (this.backgroundOpacity && this.crLens) {
this._renderer.setStyle(this.crLens, "box-shadow", "0 0 0 200000px rgba(0, 0, 0, " + this.backgroundOpacity + ")");
}
};
/**
* @param {?} event
* @return {?}
*/
ImageResizerCropperComponent.prototype.parseFile = /**
* @param {?} event
* @return {?}
*/
function (event) {
var _this = this;
/** @type {?} */
var file = event.target.files[0];
if (file.type === "image/png" ||
file.type === "image/jpeg" ||
file.type === "image/gif" ||
file.type === "image/tiff") {
/** @type {?} */
var reader_1 = new FileReader();
reader_1.readAsDataURL(file);
reader_1.addEventListener("load", function (e) {
/** @type {?} */
var val = reader_1.result.toString();
_this._renderer.setProperty(_this.crImage, "src", val);
_this.loadedSourceImage = _this.crImage.getAttribute("src");
_this._renderer.setProperty(_this.imgOne, "src", _this.crImage.getAttribute("src"));
_this.setUpListeners();
_this.setUpConfigurations();
});
reader_1.onerror = function () {
console.log("there are some problems");
};
}
else {
this.loadedSourceImage = null;
if (this.crContainer) {
this._renderer.addClass(this.crContainer, "error");
}
this.errorMessage = "Invalid file type.";
this.error.emit(this.errorMessage);
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.clearImagePosition = /**
* @return {?}
*/
function () {
if (this.crImage) {
this.crImage.style.left = "auto";
this.crImage.style.top = "auto";
}
};
ImageResizerCropperComponent.decorators = [
{ type: Component, args: [{
selector: "irc-image-resizer-cropper",
template: "<ng-container *ngIf=\"sourceImage\">\n <div class=\"cr-container\">\n <div id=\"cr-lens\">\n <span></span>\n <span></span>\n <span></span>\n <span></span>\n </div>\n <img\n src=\"{{ loadedSourceImage }}\"\n style=\"transform: scale(1);\"\n draggable=\"false\"\n id=\"cr-image\"\n />\n <div *ngIf=\"errorMessage\" id=\"error-message\">{{ errorMessage }}</div>\n </div>\n <div class=\"cr-range-selector\">\n <input type=\"range\" id=\"cr-range\" min=\"10\" max=\"200\" />\n </div>\n <div class=\"text-center\">\n <button id=\"crop\" type=\"button\">Crop</button>\n </div>\n <div>\n <img src=\"#\" id=\"test-img\" style=\"display:none;\" />\n <img src=\"#\" *ngIf=\"previewCrop && cropAvailable\" id=\"final-crop\" />\n </div>\n</ng-container>\n",
styles: [".text-center{text-align:center}.cr-container{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;position:relative;min-height:300px;margin:0 auto;overflow:hidden;border:2px dashed #333}.cr-range-selector{margin:1rem 0;text-align:center}#cr-lens{height:150px;width:150px;border:2px solid #333;z-index:999999;box-shadow:0 0 0 200000px rgba(0,0,0,.2);position:relative}#cr-lens.rounded{border-radius:50%}#cr-lens span{position:absolute;width:15px;height:15px}#cr-lens span:nth-child(1){top:-17px;left:-17px;border-right:2px dashed #333;border-bottom:2px dashed #333}#cr-lens span:nth-child(2){top:-17px;right:-17px;border-left:2px dashed #333;border-bottom:2px dashed #333}#cr-lens span:nth-child(3){bottom:-17px;right:-17px;border-left:2px dashed #333;border-top:2px dashed #333}#cr-lens span:nth-child(4){bottom:-17px;left:-17px;border-right:2px dashed #333;border-top:2px dashed #333}#cr-image{display:block;position:absolute;-webkit-transform-origin:center center;transform-origin:center center;cursor:move}"]
}] }
];
/** @nocollapse */
ImageResizerCropperComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Renderer2 },
{ type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
]; };
ImageResizerCropperComponent.propDecorators = {
sourceImage: [{ type: Input }],
lensHeight: [{ type: Input }],
lensWidth: [{ type: Input }],
autoCrop: [{ type: Input }],
previewCrop: [{ type: Input }],
roundCrop: [{ type: Input }],
borderColor: [{ type: Input }],
backgroundOpacity: [{ type: Input }],
croppedImage: [{ type: Output }],
error: [{ type: Output }]
};
return ImageResizerCropperComponent;
}());
export { ImageResizerCropperComponent };
if (false) {
/** @type {?} */
ImageResizerCropperComponent.prototype.isBrowser;
/** @type {?} */
ImageResizerCropperComponent.prototype.sourceImage;
/** @type {?} */
ImageResizerCropperComponent.prototype.lensHeight;
/** @type {?} */
ImageResizerCropperComponent.prototype.lensWidth;
/** @type {?} */
ImageResizerCropperComponent.prototype.autoCrop;
/** @type {?} */
ImageResizerCropperComponent.prototype.previewCrop;
/** @type {?} */
ImageResizerCropperComponent.prototype.roundCrop;
/** @type {?} */
ImageResizerCropperComponent.prototype.borderColor;
/** @type {?} */
ImageResizerCropperComponent.prototype.backgroundOpacity;
/** @type {?} */
ImageResizerCropperComponent.prototype.croppedImage;
/** @type {?} */
ImageResizerCropperComponent.prototype.error;
/** @type {?} */
ImageResizerCropperComponent.prototype.cropAvailable;
/** @type {?} */
ImageResizerCropperComponent.prototype.loadedSourceImage;
/** @type {?} */
ImageResizerCropperComponent.prototype.errorMessage;
/** @type {?} */
ImageResizerCropperComponent.prototype.isDown;
/** @type {?} */
ImageResizerCropperComponent.prototype.offSet;
/** @type {?} */
ImageResizerCropperComponent.prototype.imgOne;
/** @type {?} */
ImageResizerCropperComponent.prototype.imgTwo;
/** @type {?} */
ImageResizerCropperComponent.prototype.canvasOne;
/** @type {?} */
ImageResizerCropperComponent.prototype.contextOne;
/** @type {?} */
ImageResizerCropperComponent.prototype.canvasTwo;
/** @type {?} */
ImageResizerCropperComponent.prototype.contextTwo;
/** @type {?} */
ImageResizerCropperComponent.prototype.canvasThree;
/** @type {?} */
ImageResizerCropperComponent.prototype.contextThree;
/** @type {?} */
ImageResizerCropperComponent.prototype.canvasFour;
/** @type {?} */
ImageResizerCropperComponent.prototype.contextFour;
/** @type {?} */
ImageResizerCropperComponent.prototype._el;
/** @type {?} */
ImageResizerCropperComponent.prototype._renderer;
/** @type {?} */
ImageResizerCropperComponent.prototype.platformId;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtcmVzaXplci1jcm9wcGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2ltYWdlLXJlc2l6ZXItY3JvcHBlci8iLCJzb3VyY2VzIjpbImxpYi9pbWFnZS1yZXNpemVyLWNyb3BwZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULEtBQUssRUFDTCxVQUFVLEVBQ1YsU0FBUyxFQUVULE1BQU0sRUFDTixXQUFXLEVBQ1gsTUFBTSxFQUNOLFlBQVksRUFHYixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7SUE0Q2xELHNDQUNVLEtBQ0EsV0FDcUIsVUFBa0I7UUFGdkMsUUFBRyxHQUFILEdBQUc7UUFDSCxjQUFTLEdBQVQsU0FBUztRQUNZLGVBQVUsR0FBVixVQUFVLENBQVE7NEJBM0JMLElBQUksWUFBWSxDQUFNLElBQUksQ0FBQztxQkFDL0IsSUFBSSxZQUFZLENBQVMsSUFBSSxDQUFDO3NCQUs3RCxLQUFLO3NCQUNVLEVBQUU7UUFzQnhCLElBQUksQ0FBQyxTQUFTLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRXBELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lB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QUFLLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztTQUNqQztLQUNGOztnQkEvYUYsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSwyQkFBMkI7b0JBQ3JDLDZ6QkFBcUQ7O2lCQUV0RDs7OztnQkFoQkMsVUFBVTtnQkFDVixTQUFTO2dCQXdEa0MsTUFBTSx1QkFBOUMsTUFBTSxTQUFDLFdBQVc7Ozs4QkFwQ3BCLEtBQUs7NkJBQ0wsS0FBSzs0QkFDTCxLQUFLOzJCQUNMLEtBQUs7OEJBQ0wsS0FBSzs0QkFDTCxLQUFLOzhCQUNMLEtBQUs7b0NBQ0wsS0FBSzsrQkFFTCxNQUFNO3dCQUNOLE1BQU07O3VDQW5DVDs7U0FxQmEsNEJBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIElucHV0LFxuICBFbGVtZW50UmVmLFxuICBSZW5kZXJlcjIsXG4gIEFmdGVyVmlld0luaXQsXG4gIEluamVjdCxcbiAgUExBVEZPUk1fSUQsXG4gIE91dHB1dCxcbiAgRXZlbnRFbWl0dGVyLFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiaXJjLWltYWdlLXJlc2l6ZXItY3JvcHBlclwiLFxuICB0ZW1wbGF0ZVVybDogXCIuL2ltYWdlLXJlc2l6ZXItY3JvcHBlci5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vaW1hZ2UtcmVzaXplci1jcm9wcGVyLmNvbXBvbmVudC5jc3NcIl1cbn0pXG5leHBvcnQgY2xhc3MgSW1hZ2VSZXNpemVyQ3JvcHBlckNvbXBvbmVudFxuICBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzIHtcbiAgaXNCcm93c2VyOiBib29sZWFuO1xuXG4gIEBJbnB1dCgpIHNvdXJjZUltYWdlOiBhbnk7XG4gIEBJbnB1dCgpIGxlbnNIZWlnaHQ6IG51bWJlcjtcbiAgQElucHV0KCkgbGVuc1dpZHRoOiBudW1iZXI7XG4gIEBJbnB1dCgpIGF1dG9Dcm9wOiBib29sZWFuO1xuICBASW5wdXQoKSBwcmV2aWV3Q3JvcDogYm9vbGVhbjtcbiAgQElucHV0KCkgcm91bmRDcm9wOiBib29sZWFuO1xuICBASW5wdXQoKSBib3JkZXJDb2xvcjogc3RyaW5nO1xuICBASW5wdXQoKSBiYWNrZ3JvdW5kT3BhY2l0eTogc3RyaW5nO1xuXG4gIEBPdXRwdXQoKSBjcm9wcGVkSW1hZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KG51bGwpO1xuICBAT3V0cHV0KCkgZXJyb3I6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KG51bGwpO1xuICBjcm9wQXZhaWxhYmxlOiBib29sZWFuO1xuICBsb2FkZWRTb3VyY2VJbWFnZTogYW55O1xuXG4gIGVycm9yTWVzc2FnZTogc3RyaW5nO1xuICBpc0Rvd24gPSBmYWxzZTtcbiAgb2ZmU2V0OiBBcnJheTxudW1iZXI+ID0gW107XG5cbiAgaW1nT25lOiBIVE1MSW1hZ2VFbGVtZW50O1xuICBpbWdUd286IEhUTUxJbWFnZUVsZW1lbnQ7XG5cbiAgY2FudmFzT25lOiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgY29udGV4dE9uZTogYW55O1xuXG4gIGNhbnZhc1R3bzogSFRNTENhbnZhc0VsZW1lbnQ7XG4gIGNvbnRleHRUd286IGFueTtcblxuICBjYW52YXNUaHJlZTogSFRNTENhbnZhc0VsZW1lbnQ7XG4gIGNvbnRleHRUaHJlZTogYW55O1xuXG4gIGNhbnZhc0ZvdXI6IEhUTUxDYW52YXNFbGVtZW50O1xuICBjb250ZXh0Rm91cjogYW55O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2VsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBPYmplY3RcbiAgKSB7XG4gICAgdGhpcy5pc0Jyb3dzZXIgPSBpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpO1xuXG4gICAgaWYgKHRoaXMuaXNCcm93c2VyKSB7XG4gICAgICB0aGlzLmNhbnZhc09uZSA9IHRoaXMuX3JlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICB0aGlzLmNvbnRleHRPbmUgPSB0aGlzLmNhbnZhc09uZS5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgICAgIHRoaXMuY2FudmFzVHdvID0gdGhpcy5fcmVuZGVyZXIuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgIHRoaXMuY29udGV4dFR3byA9IHRoaXMuY2FudmFzVHdvLmdldENvbnRleHQoXCIyZFwiKTtcblxuICAgICAgdGhpcy5jYW52YXNUaHJlZSA9IHRoaXMuX3JlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICB0aGlzLmNvbnRleHRUaHJlZSA9IHRoaXMuY2FudmFzVGhyZWUuZ2V0Q29udGV4dChcIjJkXCIpO1xuXG4gICAgICB0aGlzLmNhbnZhc0ZvdXIgPSB0aGlzLl9yZW5kZXJlci5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgdGhpcy5jb250ZXh0Rm91ciA9IHRoaXMuY2FudmFzRm91ci5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgICAgIHRoaXMuaW1nT25lID0gdGhpcy5fcmVuZGVyZXIuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcbiAgICAgIHRoaXMuaW1nVHdvID0gdGhpcy5fcmVuZGVyZXIuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcbiAgICB9XG4gIH1cblxuICBnZXQgY3JDb250YWluZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcIi5jci1jb250YWluZXJcIik7XG4gIH1cblxuICBnZXQgY3JSYW5nZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiI2NyLXJhbmdlXCIpO1xuICB9XG5cbiAgZ2V0IGNySW1hZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcIiNjci1pbWFnZVwiKTtcbiAgfVxuXG4gIGdldCBjckxlbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcIiNjci1sZW5zXCIpO1xuICB9XG5cbiAgZ2V0IGJ0bigpIHtcbiAgICByZXR1cm4gdGhpcy5fZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiI2Nyb3BcIik7XG4gIH1cblxuICBnZXQgdGVzdEltZygpIHtcbiAgICByZXR1cm4gdGhpcy5fZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiI3Rlc3QtaW1nXCIpO1xuICB9XG5cbiAgZ2V0IGZpbmFsQ3JvcCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiI2ZpbmFsLWNyb3BcIik7XG4gIH1cblxuICBnZXQgZmlsZVVwbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiI2ZpbGUtdXBsb2FkXCIpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMuc291cmNlSW1hZ2UpIHtcbiAgICAgIGlmICh0aGlzLnNvdXJjZUltYWdlLnRhcmdldCAmJiB0aGlzLnNvdXJjZUltYWdlLnRhcmdldC5maWxlcykge1xuICAgICAgICB0aGlzLnBhcnNlRmlsZSh0aGlzLnNvdXJjZUltYWdlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgaWYgKHRoaXMuc291cmNlSW1hZ2UpIHtcbiAgICAgIGlmICh0aGlzLmltZ09uZSkge1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eShcbiAgICAgICAgICB0aGlzLmltZ09uZSxcbiAgICAgICAgICBcInNyY1wiLFxuICAgICAgICAgIHRoaXMuY3JJbWFnZS5nZXRBdHRyaWJ1dGUoXCJzcmNcIilcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0VXBMaXN0ZW5lcnMoKTtcbiAgICAgIHRoaXMuc2V0VXBDb25maWd1cmF0aW9ucygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoXG4gICAgICBjaGFuZ2VzLnNvdXJjZUltYWdlICYmXG4gICAgICAhY2hhbmdlcy5zb3VyY2VJbWFnZS5maXJzdENoYW5nZSAmJlxuICAgICAgY2hhbmdlcy5zb3VyY2VJbWFnZS5jdXJyZW50VmFsdWVcbiAgICApIHtcbiAgICAgIHRoaXMuY2xlYXJJbWFnZVBvc2l0aW9uKCk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgY2hhbmdlcy5zb3VyY2VJbWFnZS5jdXJyZW50VmFsdWUudGFyZ2V0ICYmXG4gICAgICAgIGNoYW5nZXMuc291cmNlSW1hZ2UuY3VycmVudFZhbHVlLnRhcmdldC5maWxlc1xuICAgICAgKSB7XG4gICAgICAgIHRoaXMucGFyc2VGaWxlKHRoaXMuc291cmNlSW1hZ2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuaW1nT25lKSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0UHJvcGVydHkoXG4gICAgICAgICAgICB0aGlzLmltZ09uZSxcbiAgICAgICAgICAgIFwic3JjXCIsXG4gICAgICAgICAgICB0aGlzLmNySW1hZ2UuZ2V0QXR0cmlidXRlKFwic3JjXCIpXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHRoaXMuc2V0VXBMaXN0ZW5lcnMoKTtcbiAgICAgICAgICB0aGlzLnNldFVwQ29uZmlndXJhdGlvbnMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldFVwTGlzdGVuZXJzKCkge1xuICAgIGlmICh0aGlzLmlzQnJvd3Nlcikge1xuICAgICAgdGhpcy5fcmVuZGVyZXIubGlzdGVuKHRoaXMuY3JSYW5nZSwgXCJpbnB1dFwiLCBldmVudCA9PiB7XG4gICAgICAgIHRoaXMubGlua0ltYWdlVG9SYW5nZUlucHV0KGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5fcmVuZGVyZXIubGlzdGVuKHRoaXMuY3JJbWFnZSwgXCJtb3VzZWRvd25cIiwgZXZlbnQgPT4ge1xuICAgICAgICB0aGlzLm1vdXNlRG93bk9uSW1hZ2UoZXZlbnQpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3JlbmRlcmVyLmxpc3Rlbih0aGlzLmNySW1hZ2UsIFwibW91c2V1cFwiLCBldmVudCA9PiB7XG4gICAgICAgIHRoaXMubW91c2VVcE9uSW1hZ2UoKTtcblxuICAgICAgICBpZiAodGhpcy5hdXRvQ3JvcCkge1xuICAgICAgICAgIHRoaXMucmVzaXplQW5kQ3JvcEltYWdlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9yZW5kZXJlci5saXN0ZW4odGhpcy5jckltYWdlLCBcIm1vdXNlbW92ZVwiLCBldmVudCA9PiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMubW91c2VNb3ZlT25JbWFnZShldmVudCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5fcmVuZGVyZXIubGlzdGVuKHRoaXMuY3JDb250YWluZXIsIFwibW91c2VvdXRcIiwgZXZlbnQgPT4ge1xuICAgICAgICB0aGlzLmtlZXBNb3VzZU1vdmVJbnNpZGVDb250YWluZXIoKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9yZW5kZXJlci5saXN0ZW4odGhpcy5idG4sIFwiY2xpY2tcIiwgZXZlbnQgPT4ge1xuICAgICAgICB0aGlzLnJlc2l6ZUFuZENyb3BJbWFnZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0VXBDb25maWd1cmF0aW9ucygpIHtcbiAgICB0aGlzLnNldEJvcmRlckNvbG9yKCk7XG4gICAgdGhpcy5zZXRCYWNrZ3JvdW5kT3BhY2l0eSgpO1xuICAgIHRoaXMuc2V0TGVuc0hlaWdodEFuZFdpZHRoKCk7XG4gIH1cblxuICBsaW5rSW1hZ2VUb1JhbmdlSW5wdXQodmFsdWU6IGFueSkge1xuICAgIGNvbnN0IHZhbCA9IHZhbHVlIC8gMTAwO1xuICAgIHRoaXMuY3JJbWFnZS5zdHlsZS50cmFuc2Zvcm0gPSBgc2NhbGUoJHt2YWx9KWA7XG4gIH1cblxuICBtb3VzZURvd25PbkltYWdlKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLmlzRG93biA9IHRydWU7XG4gICAgdGhpcy5vZmZTZXQgPSBbXG4gICAgICBldmVudC50YXJnZXQub2Zmc2V0TGVmdCAtIGV2ZW50LmNsaWVudFgsXG4gICAgICBldmVudC50YXJnZXQub2Zmc2V0VG9wIC0gZXZlbnQuY2xpZW50WVxuICAgIF07XG4gIH1cblxuICBtb3VzZVVwT25JbWFnZSgpIHtcbiAgICB0aGlzLmlzRG93biA9IGZhbHNlO1xuICB9XG5cbiAgbW91c2VNb3ZlT25JbWFnZShldmVudDogYW55KSB7XG4gICAgaWYgKHRoaXMuaXNEb3duKSB7XG4gICAgICBjb25zdCBtb3VzZVBvc2l0aW9uID0ge1xuICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICB5OiBldmVudC5jbGllbnRZXG4gICAgICB9O1xuICAgICAgdGhpcy5jckltYWdlLnN0eWxlLmxlZnQgPSBtb3VzZVBvc2l0aW9uLnggKyB0aGlzLm9mZlNldFswXSArIFwicHhcIjtcbiAgICAgIHRoaXMuY3JJbWFnZS5zdHlsZS50b3AgPSBtb3VzZVBvc2l0aW9uLnkgKyB0aGlzLm9mZlNldFsxXSArIFwicHhcIjtcbiAgICB9XG4gIH1cblxuICBrZWVwTW91c2VNb3ZlSW5zaWRlQ29udGFpbmVyKCkge1xuICAgIHRoaXMuaXNEb3duID0gZmFsc2U7XG4gIH1cblxuICBjaGVja0Zvck92ZXJsYXAoZTEsIGUyKSB7XG4gICAgaWYgKGUxLmxlbmd0aCAmJiBlMS5sZW5ndGggPiAxKSB7XG4gICAgICBlMSA9IGUxWzBdO1xuICAgIH1cbiAgICBpZiAoZTIubGVuZ3RoICYmIGUyLmxlbmd0aCA+IDEpIHtcbiAgICAgIGUyID0gZTJbMF07XG4gICAgfVxuICAgIGNvbnN0IHJlY3QxID0gZTEgaW5zdGFuY2VvZiBFbGVtZW50ID8gZTEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgOiBmYWxzZTtcbiAgICBjb25zdCByZWN0MiA9IGUyIGluc3RhbmNlb2YgRWxlbWVudCA/IGUyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIDogZmFsc2U7XG5cbiAgICBsZXQgb3ZlcmxhcCA9IG51bGw7XG4gICAgaWYgKHJlY3QxICYmIHJlY3QyKSB7XG4gICAgICBvdmVybGFwID0gIShcbiAgICAgICAgcmVjdDEucmlnaHQgPCByZWN0Mi5sZWZ0IHx8XG4gICAgICAgIHJlY3QxLmxlZnQgPiByZWN0Mi5yaWdodCB8fFxuICAgICAgICByZWN0MS5ib3R0b20gPCByZWN0Mi50b3AgfHxcbiAgICAgICAgcmVjdDEudG9wID4gcmVjdDIuYm90dG9tXG4gICAgICApO1xuICAgICAgcmV0dXJuIFtvdmVybGFwLCByZWN0MSwgcmVjdDJdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gW292ZXJsYXAsIHJlY3QxLCByZWN0Ml07XG4gICAgfVxuICB9XG5cbiAgZ2V0UmVzaXplUmF0aW8oKSB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5jckltYWdlLnN0eWxlLnRyYW5zZm9ybTtcbiAgICBjb25zdCBtYXRyaXggPSB0cmFuc2Zvcm1cbiAgICAgIC5zdWJzdHJpbmcodHJhbnNmb3JtLmluZGV4T2YoXCIoXCIpICsgMSwgdHJhbnNmb3JtLmluZGV4T2YoXCIpXCIpKVxuICAgICAgLnNwbGl0KFwiLFwiKTtcbiAgICByZXR1cm4gbWF0cml4Lmxlbmd0aCA+IDAgPyBtYXRyaXhbMF0gOiBudWxsO1xuICB9XG5cbiAgZHJhd0ltYWdlUmVzaXplKCkge1xuICAgIGNvbnN0IHJhdGlvID0gdGhpcy5nZXRSZXNpemVSYXRpbygpO1xuICAgIHRoaXMuY2FudmFzVHdvLndpZHRoID0gdGhpcy5pbWdPbmUud2lkdGg7XG4gICAgdGhpcy5jYW52YXNUd28uaGVpZ2h0ID0gdGhpcy5pbWdPbmUuaGVpZ2h0O1xuICAgIHRoaXMuY29udGV4dFR3by5kcmF3SW1hZ2UodGhpcy5pbWdPbmUsIDAsIDApO1xuICAgIHRoaXMuY2FudmFzT25lLndpZHRoID0gdGhpcy5pbWdPbmUud2lkdGggKiByYXRpbztcbiAgICB0aGlzLmNhbnZhc09uZS5oZWlnaHQgPSB0aGlzLmltZ09uZS5oZWlnaHQgKiByYXRpbztcbiAgICB0aGlzLmNvbnRleHRPbmUuZHJhd0ltYWdlKFxuICAgICAgdGhpcy5jYW52YXNUd28sXG4gICAgICAwLFxuICAgICAgMCxcbiAgICAgIHRoaXMuY2FudmFzVHdvLndpZHRoLFxuICAgICAgdGhpcy5jYW52YXNUd28uaGVpZ2h0LFxuICAgICAgMCxcbiAgICAgIDAsXG4gICAgICB0aGlzLmNhbnZhc09uZS53aWR0aCxcbiAgICAgIHRoaXMuY2FudmFzT25lLmhlaWdodFxuICAgICk7XG5cbiAgICBjb25zdCBpID0gdGhpcy5jYW52YXNPbmUudG9EYXRhVVJMKFwiaW1hZ2UvcG5nXCIsIDEwMCk7XG5cbiAgICBpZiAodGhpcy50ZXN0SW1nKSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLnRlc3RJbWcsIFwic3JjXCIsIGkpO1xuICAgIH1cbiAgICByZXR1cm4gaTtcbiAgfVxuXG4gIGRyYXdJbWFnZUNyb3Aoc3JjOiBzdHJpbmcpIHtcbiAgICBjb25zdCBvdmVybGFwID0gdGhpcy5jaGVja0Zvck92ZXJsYXAodGhpcy5jckxlbnMsIHRoaXMuY3JJbWFnZSk7XG5cbiAgICBpZiAodGhpcy5pbWdUd28pIHtcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuaW1nVHdvLCBcInNyY1wiLCBzcmMpO1xuXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5saXN0ZW4odGhpcy5pbWdUd28sIFwibG9hZFwiLCBldmVudCA9PiB7XG4gICAgICAgICAgdGhpcy5jYW52YXNUaHJlZS53aWR0aCA9IGV2ZW50LnRhcmdldC53aWR0aDtcbiAgICAgICAgICB0aGlzLmNhbnZhc1RocmVlLmhlaWdodCA9IGV2ZW50LnRhcmdldC5oZWlnaHQ7XG4gICAgICAgICAgdGhpcy5jb250ZXh0VGhyZWUuZHJhd0ltYWdlKHRoaXMuaW1nVHdvLCAwLCAwKTtcbiAgICAgICAgICB0aGlzLmNhbnZhc0ZvdXIud2lkdGggPSB0aGlzLmxlbnNXaWR0aDtcbiAgICAgICAgICB0aGlzLmNhbnZhc0ZvdXIuaGVpZ2h0ID0gdGhpcy5sZW5zSGVpZ2h0O1xuXG4gICAgICAgICAgaWYgKG92ZXJsYXApIHtcbiAgICAgICAgICAgIGNvbnN0IHhDcm9wID0gb3ZlcmxhcFsxXVtcInhcIl0gLSBvdmVybGFwWzJdW1wieFwiXTtcbiAgICAgICAgICAgIGNvbnN0IHlDcm9wID0gb3ZlcmxhcFsxXVtcInlcIl0gLSBvdmVybGFwWzJdW1wieVwiXTtcblxuICAgICAgICAgICAgdGhpcy5jb250ZXh0Rm91ci5kcmF3SW1hZ2UoXG4gICAgICAgICAgICAgIHRoaXMuY2FudmFzVGhyZWUsXG4gICAgICAgICAgICAgIHhDcm9wLFxuICAgICAgICAgICAgICB5Q3JvcCxcbiAgICAgICAgICAgICAgdGhpcy5sZW5zV2lkdGgsXG4gICAgICAgICAgICAgIHRoaXMubGVuc0hlaWdodCxcbiAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgdGhpcy5sZW5zV2lkdGgsXG4gICAgICAgICAgICAgIHRoaXMubGVuc0hlaWdodFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucm91bmRDcm9wKSB7XG4gICAgICAgICAgICAgIHRoaXMuY29udGV4dEZvdXIuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gXCJkZXN0aW5hdGlvbi1pblwiO1xuICAgICAgICAgICAgICB0aGlzLmNvbnRleHRGb3VyLmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgICB0aGlzLmNvbnRleHRGb3VyLmFyYyhcbiAgICAgICAgICAgICAgICB0aGlzLmxlbnNXaWR0aCAvIDIsXG4gICAgICAgICAgICAgICAgdGhpcy5sZW5zSGVpZ2h0IC8gMixcbiAgICAgICAgICAgICAgICB0aGlzLmxlbnNIZWlnaHQgLyAyLFxuICAgICAgICAgICAgICAgIDAsXG4gICAg