ng-cw-v12
Version:
Angular UI Component Library
419 lines • 67.8 kB
JavaScript
import { __awaiter } from "tslib";
import { Component, EventEmitter, Input, Output } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
export class ImgClipComponent {
constructor(eleRef) {
this.eleRef = eleRef;
/** 图片地址 */
this.ncUrl = '';
/** 确认裁剪回调 */
this.ncConfirm = new EventEmitter();
/** 裁剪回调返回图片格式 */
this.ncImgType = 'base64';
/** 容器宽度 */
this.ncWidth = 300;
/** 默认裁剪框的尺寸占图片比例 */
this.ncClipSize = 0.7;
/** 裁剪框最小宽度 */
this.ncClipMinWidth = 50;
/** 裁剪框最小高度 */
this.ncClipMinHeight = 50;
/** 确认裁剪时是否下载图片 */
this._download = false;
/** 调整工具栏 */
this._tool = false;
/** 上传 */
this._upload = false;
this.hasImage = false;
// 图片当前宽高
this.clipImageWidth = 0;
this.clipImageHeight = 0;
// 图片原始宽高
this.clipImageOriginWidth = 0;
this.clipImageOriginHeight = 0;
this.scale = 0; //缩放比例
this.clipWidth = 0; //裁剪框宽度
this.clipHeight = 0; //裁剪框高度
this.clipX = 0; //裁剪框x
this.clipY = 0; //裁剪框y
}
set ncDownload(value) {
this._download = value !== null && value !== undefined && value !== false && value !== 'false';
}
get ncDownload() {
return this._download;
}
set ncTool(value) {
this._tool = value !== null && value !== undefined && value !== false && value !== 'false';
}
get ncTool() {
return this._tool;
}
set ncUpload(value) {
this._upload = value !== null && value !== undefined && value !== false && value !== 'false';
}
get ncUpload() {
return this._upload;
}
ngOnInit() {
this.clipImage = this.eleRef.nativeElement.querySelector('#clipImage');
this.clipPathImg = this.eleRef.nativeElement.querySelector('#clipPathImg');
this.clip = this.eleRef.nativeElement.querySelector('#clip');
if (this.ncUpload) {
setTimeout(() => {
this.file = this.eleRef.nativeElement.querySelector('#file');
// 监听上传状态 浏览图片
this.file.addEventListener('change', (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.readImage(reader.result);
};
});
});
}
//裁剪框缩放、拖拽
this.clipBoxZoom();
this.clipBpxDrag();
//读取图片
this.readImage(this.ncUrl);
}
ngOnChanges(changes) {
if (changes['ncUrl'] && !changes['ncUrl'].firstChange) {
this.readImage(this.ncUrl);
}
}
//读取图片
readImage(url) {
// 读取到的图片数据
this.clipImage.src = url;
// 裁剪使用的图片
this.clipPathImg.src = url;
//获取当前图片的宽高
this.getClipImageSize(url).then((res) => {
// 初始化
this.init();
this.hasImage = true;
});
}
// 获取上传图片的当前尺寸和原始尺寸
getClipImageSize(dataurl) {
return __awaiter(this, void 0, void 0, function* () {
const data = yield new Promise((resolve) => {
this.clipImage.onload = () => {
resolve(this.clipImage);
};
});
// 获取图片当前宽高
this.clipImageWidth = data.width;
this.clipImageHeight = data.height;
const data_1 = yield new Promise((resolve_1) => {
// 获取图片原始宽高
let img = document.createElement('img');
img.src = dataurl;
img.onload = () => {
resolve_1(img);
};
});
// 获取图片原始宽高
this.clipImageOriginWidth = data_1.width;
this.clipImageOriginHeight = data_1.height;
return yield Promise.resolve();
});
}
// 初始化
init() {
// 显示裁剪框
this.clip.style.display = 'block';
// 缩放比例
this.scale = this.clipImageOriginWidth / this.clipImageWidth;
// 设置裁剪框的宽高
let clipWidth = Math.floor(this.clipImageWidth * this.ncClipSize);
let clipHeight = Math.floor(this.clipImageHeight * this.ncClipSize);
this.setClipSize(clipWidth, clipHeight);
// 设置裁剪框的位置
let x = Math.floor((this.clipImageWidth - clipWidth) / 2);
let y = Math.floor((this.clipImageHeight - clipHeight) / 2);
this.setClipPosition(x, y);
}
// 设置裁剪框的尺寸
setClipSize(clipWidth, clipHeight) {
this.clip.style.setProperty('--clipWidth', clipWidth + 'px');
this.clip.style.setProperty('--clipHeight', clipHeight + 'px');
this.clipWidth = clipWidth;
this.clipHeight = clipHeight;
}
// 设置裁剪框的位置
setClipPosition(x, y) {
this.clip.style.setProperty('--clipX', x + 'px');
this.clip.style.setProperty('--clipY', y + 'px');
this.clipX = x;
this.clipY = y;
// 设置裁剪阴影
this.setClipPath();
}
// 设置裁剪阴影
setClipPath() {
let lt = this.clip.offsetLeft + 'px' + ' ' + this.clip.offsetTop + 'px';
let rt = (this.clip.offsetLeft + this.clip.offsetWidth) + 'px' + ' ' + this.clip.offsetTop + 'px';
let rb = (this.clip.offsetLeft + this.clip.offsetWidth) + 'px' + ' ' + (this.clip.offsetTop + this.clip.offsetHeight) + 'px';
let lb = this.clip.offsetLeft + 'px' + ' ' + (this.clip.offsetTop + this.clip.offsetHeight) + 'px';
this.clipPathImg.style.setProperty('--clipPath', `polygon(${lt}, ${rt}, ${rb}, ${lb})`);
}
// 裁剪
clipImg(x, y, cutWidth, cutHeight, width, height) {
return __awaiter(this, void 0, void 0, function* () {
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(this.clipImage, x, y, cutWidth, cutHeight, 0, 0, width, height);
//下载
if (this.ncDownload) {
const a = document.createElement('a');
a.download = '裁剪图片';
a.href = canvas.toDataURL('image/png');
a.click();
}
// 返回裁剪后的图片
return new Promise((resolve) => {
if (this.ncImgType == 'base64') {
resolve(canvas.toDataURL('image/png'));
}
else {
canvas.toBlob((blob) => {
resolve(new File([blob], 'clip.png', { type: 'image/png' }));
});
}
});
});
}
//确认裁剪
confirm() {
return __awaiter(this, void 0, void 0, function* () {
let res = yield this.clipImg(this.clip.offsetLeft * this.scale, this.clip.offsetTop * this.scale, this.clip.offsetWidth * this.scale, this.clip.offsetHeight * this.scale, this.clip.offsetWidth, this.clip.offsetHeight);
this.ncConfirm.emit(res);
});
}
//裁剪框的拖拽
clipBpxDrag() {
// 鼠标按下
this.clip.onmousedown = (e) => {
// 偏移量
let py = {
x: e.clientX - this.clip.offsetLeft,
y: e.clientY - this.clip.offsetTop
};
// 鼠标移动
window.onmousemove = (e) => {
// 鼠标移动的距离
let moveX = e.clientX - py.x;
let moveY = e.clientY - py.y;
// 裁剪框的位置
let left = moveX;
let top = moveY;
// 裁剪框的位置限制
if (left < 0) {
left = 0;
}
if (top < 0) {
top = 0;
}
if (left > this.clipImageWidth - this.clip.offsetWidth) {
left = this.clipImageWidth - this.clip.offsetWidth;
}
if (top > this.clipImageHeight - this.clip.offsetHeight) {
top = this.clipImageHeight - this.clip.offsetHeight;
}
// 设置裁剪框的位置
this.setClipPosition(left, top);
};
// 鼠标松开
window.onmouseup = () => {
window.onmouseup = null;
window.onmousemove = null;
};
};
}
//裁剪框缩放
clipBoxZoom() {
// 获取裁剪框的四个角
let zoomDom = {
lt: this.eleRef.nativeElement.querySelector('.lt'),
rt: this.eleRef.nativeElement.querySelector('.rt'),
rb: this.eleRef.nativeElement.querySelector('.rb'),
lb: this.eleRef.nativeElement.querySelector('.lb'),
};
// 鼠标按下时的位置
let zoomInfo = {
x: 0,
y: 0,
minWidth: this.ncClipMinWidth,
minHeight: this.ncClipMinHeight
};
// 鼠标按下时裁剪框的位置
for (let key in zoomDom) {
zoomDom[key].onmousedown = (e) => {
// 禁止冒泡
e.stopPropagation();
// 鼠标按下时的位置
zoomInfo.x = e.clientX;
zoomInfo.y = e.clientY;
// 鼠标移动
window.onmousemove = (e) => {
// 鼠标移动的距离
let moveX = e.clientX - zoomInfo.x;
let moveY = e.clientY - zoomInfo.y;
// 裁剪框的位置
let left = 0;
let top = 0;
// 裁剪框的尺寸
let width = 0;
let height = 0;
// 左上角
if (key === 'lt') {
// 裁剪框的位置
left = this.clip.offsetLeft + moveX;
top = this.clip.offsetTop + moveY;
// 裁剪框的尺寸
width = this.clip.offsetWidth - moveX;
height = this.clip.offsetHeight - moveY;
// 裁剪框的位置限制
if (left < 0) {
left = 0;
// 原来宽度+原来left
width = this.clip.offsetWidth + this.clip.offsetLeft;
}
if (top < 0) {
top = 0;
// 原来高度+原来top
height = this.clip.offsetHeight + this.clip.offsetTop;
}
}
// 右上角
if (key === 'rt') {
// 裁剪框的位置
top = this.clip.offsetTop + moveY;
left = this.clip.offsetLeft;
// 裁剪框的尺寸
width = this.clip.offsetWidth + moveX;
height = this.clip.offsetHeight - moveY;
// 裁剪框的位置限制
if (top < 0) {
top = 0;
// 原来高度+原来top
height = this.clip.offsetHeight + this.clip.offsetTop;
}
if (left + width > this.clipImageWidth) {
// 图片当前宽-原来left
width = this.clipImageWidth - left;
}
}
// 右下角
if (key === 'rb') {
// 裁剪框的尺寸
top = this.clip.offsetTop;
left = this.clip.offsetLeft;
width = this.clip.offsetWidth + moveX;
height = this.clip.offsetHeight + moveY;
// 裁剪框的位置限制
// 当前的left+当前的width>图片当前宽
if (this.clip.offsetLeft + width > this.clipImageWidth) {
width = this.clipImageWidth - left;
}
// 当前的top+当前的height>图片当前宽
if (this.clip.offsetTop + height > this.clipImageHeight) {
height = this.clipImageHeight - top;
}
}
// 左下角
if (key === 'lb') {
// 裁剪框的位置
left = this.clip.offsetLeft + moveX;
top = this.clip.offsetTop;
// 裁剪框的尺寸
width = this.clip.offsetWidth - moveX;
height = this.clip.offsetHeight + moveY;
// 裁剪框的位置限制
if (left < 0) {
left = 0;
width = this.clip.offsetWidth + this.clip.offsetLeft;
}
// 当前的top+当前的height>图片当前宽
if (this.clip.offsetTop + height > this.clipImageHeight) {
height = this.clipImageHeight - top;
}
}
// 裁剪框的限制
({ width, height, left, top } = this.ClipWidthPosition(zoomInfo, width, height, left, top));
// 设置裁剪框的位置
this.setClipPosition(left, top);
// 设置裁剪框的尺寸
this.setClipSize(width, height);
// 记录上一次的位置
zoomInfo.x = e.clientX;
zoomInfo.y = e.clientY;
};
// 鼠标松开
window.onmouseup = () => {
window.onmouseup = null;
window.onmousemove = null;
};
};
}
}
// 裁剪框的宽高限制以及位置限制
ClipWidthPosition(zoomInfo, w, h, l, t) {
let width = w; //裁剪框宽度
let height = h; //裁剪框的高度
let left = l; //裁剪框的left
let top = t; //裁剪框的top
if (w < zoomInfo.minWidth) {
width = zoomInfo.minWidth;
left = this.clip.offsetLeft;
}
if (h < zoomInfo.minHeight) {
height = zoomInfo.minHeight;
top = this.clip.offsetTop;
}
return { width, height, left, top };
}
//尺寸输入框变化
sizeInputChange() {
this.setClipSize(this.clipWidth, this.clipHeight);
this.setClipPosition(this.clipX, this.clipY);
}
}
ImgClipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ImgClipComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
ImgClipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: ImgClipComponent, selector: "nc-img-clip", inputs: { ncUrl: "ncUrl", ncImgType: "ncImgType", ncWidth: "ncWidth", ncClipSize: "ncClipSize", ncClipMinWidth: "ncClipMinWidth", ncClipMinHeight: "ncClipMinHeight", ncDownload: "ncDownload", ncTool: "ncTool", ncUpload: "ncUpload" }, outputs: { ncConfirm: "ncConfirm" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"clipContainer\" [ngStyle]=\"{'width': ncWidth + 'px'}\">\r\n <div class=\"clipBtnContainer\">\r\n <div *ngIf=\"ncUpload\" class=\"filebutton\">\r\n <div>\u4E0A\u4F20\u56FE\u7247</div>\r\n <input type=\"file\" id=\"file\" class=\"fileInput\" accept=\"image/*\">\r\n </div>\r\n <div *ngIf=\"hasImage\" class=\"confirmBtn\" (click)=\"confirm()\">\u786E\u5B9A</div>\r\n </div>\r\n <div class=\"clipImageCantainer\">\r\n <img id=\"clipImage\" src=\"\" crossorigin=\"anonymous\">\r\n <img id=\"clipPathImg\" src=\"\">\r\n <div id=\"clip\">\r\n <div class=\"corner lt\"></div>\r\n <div class=\"corner rt\"></div>\r\n <div class=\"corner rb\"></div>\r\n <div class=\"corner lb\"></div>\r\n </div>\r\n </div>\r\n <div class=\"bottomInputContainer\" *ngIf=\"hasImage && ncTool\">\r\n <div class=\"inputRow\">\r\n <div class=\"inputCol\">\r\n <div class=\"rowLabel\">\u5BBD\uFF1A</div>\r\n <input class=\"nc-input-number sizeInput\" type=\"number\" [(ngModel)]=\"clipWidth\" [min]=\"ncClipMinWidth\"\r\n [max]=\"clipImageWidth\" step=\"1\" (ngModelChange)=\"sizeInputChange()\">\r\n </div>\r\n <div class=\"inputCol\">\r\n <div class=\"rowLabel\">\u9AD8\uFF1A</div>\r\n <input class=\"nc-input-number sizeInput\" type=\"number\" [(ngModel)]=\"clipHeight\" [min]=\"ncClipMinHeight\"\r\n [max]=\"clipImageHeight\" step=\"1\" (ngModelChange)=\"sizeInputChange()\">\r\n </div>\r\n </div>\r\n <div class=\"inputRow\">\r\n <div class=\"inputCol\">\r\n <div class=\"rowLabel\">X\uFF1A</div>\r\n <input class=\"nc-input-number sizeInput\" type=\"number\" [(ngModel)]=\"clipX\" [min]=\"0\"\r\n [max]=\"clipImageWidth - clipWidth\" step=\"1\" (ngModelChange)=\"sizeInputChange()\">\r\n </div>\r\n <div class=\"inputCol\">\r\n <div class=\"rowLabel\">Y\uFF1A</div>\r\n <input class=\"nc-input-number sizeInput\" type=\"number\" [(ngModel)]=\"clipY\" [min]=\"0\"\r\n [max]=\"clipImageHeight - clipHeight\" step=\"1\" (ngModelChange)=\"sizeInputChange()\">\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".clipContainer{margin:5px}.clipContainer .clipBtnContainer{display:flex;align-items:center;justify-content:space-between;margin-bottom:5px}.clipContainer .clipBtnContainer .filebutton{position:relative;display:inline-block;overflow:hidden}.clipContainer .clipBtnContainer .filebutton input{position:absolute;top:0;opacity:0;font-size:0;width:100%;height:100%;cursor:pointer}.clipContainer .clipBtnContainer .filebutton div{font-size:13px;background:#00aeff;color:#fff;padding:4px 8px;border-radius:3px}.clipContainer .clipBtnContainer .confirmBtn{font-size:13px;background:#00aeff;color:#fff;padding:4px 8px;border-radius:3px;cursor:pointer}.clipContainer .clipImageCantainer{width:100%;position:relative}.clipContainer .clipImageCantainer:after{content:\"\";position:absolute;width:100%;height:100%;top:0;left:0;background:rgba(0,0,0,.5);z-index:1}.clipContainer .clipImageCantainer img{width:100%;top:0;left:0;display:block}.clipContainer .clipImageCantainer #clipPathImg{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;clip-path:var(--clipPath)}.clipContainer .clipImageCantainer #clip{position:absolute;top:0;left:0;width:var(--clipWidth);height:var(--clipHeight);left:var(--clipX);top:var(--clipY);z-index:3;cursor:move;border:1px dashed white;display:none}.clipContainer .clipImageCantainer #clip .corner{position:absolute;width:10px;height:10px;background:#fff;border:1px solid #000}.clipContainer .clipImageCantainer #clip .lt{cursor:nw-resize;left:-5px;top:-5px}.clipContainer .clipImageCantainer #clip .rt{cursor:ne-resize;right:-5px;top:-5px}.clipContainer .clipImageCantainer #clip .lb{cursor:sw-resize;left:-5px;bottom:-5px}.clipContainer .clipImageCantainer #clip .rb{cursor:se-resize;right:-5px;bottom:-5px}.clipContainer .bottomInputContainer .inputRow{display:flex;align-items:center;margin-top:5px}.clipContainer .bottomInputContainer .inputRow .inputCol{display:flex;align-items:center;margin-right:10px}.clipContainer .bottomInputContainer .inputRow .inputCol .rowLabel{width:30px;display:flex;justify-content:flex-end;color:#b9b9b9;mix-blend-mode:difference}.clipContainer .bottomInputContainer .inputRow .inputCol .sizeInput{width:70px}\n"], directives: [{ type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ImgClipComponent, decorators: [{
type: Component,
args: [{
selector: 'nc-img-clip',
templateUrl: './img-clip.component.html',
styleUrls: ['./img-clip.component.less']
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { ncUrl: [{
type: Input
}], ncConfirm: [{
type: Output
}], ncImgType: [{
type: Input
}], ncWidth: [{
type: Input
}], ncClipSize: [{
type: Input
}], ncClipMinWidth: [{
type: Input
}], ncClipMinHeight: [{
type: Input
}], ncDownload: [{
type: Input
}], ncTool: [{
type: Input
}], ncUpload: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1nLWNsaXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9pbWctY2xpcC9pbWctY2xpcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2ltZy1jbGlwL2ltZy1jbGlwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBaUIsTUFBTSxlQUFlLENBQUM7Ozs7QUFTckgsTUFBTSxPQUFPLGdCQUFnQjtJQXlEekIsWUFBb0IsTUFBa0I7UUFBbEIsV0FBTSxHQUFOLE1BQU0sQ0FBWTtRQXhEdEMsV0FBVztRQUNGLFVBQUssR0FBVyxFQUFFLENBQUM7UUFDNUIsYUFBYTtRQUNILGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3pDLGlCQUFpQjtRQUNSLGNBQVMsR0FBYyxRQUFRLENBQUM7UUFDekMsV0FBVztRQUNGLFlBQU8sR0FBVyxHQUFHLENBQUM7UUFDL0Isb0JBQW9CO1FBQ1gsZUFBVSxHQUFXLEdBQUcsQ0FBQztRQUNsQyxjQUFjO1FBQ0wsbUJBQWMsR0FBVyxFQUFFLENBQUM7UUFDckMsY0FBYztRQUNMLG9CQUFlLEdBQVcsRUFBRSxDQUFDO1FBQ3RDLGtCQUFrQjtRQUNWLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFPbkMsWUFBWTtRQUNKLFVBQUssR0FBWSxLQUFLLENBQUM7UUFPL0IsU0FBUztRQUNELFlBQU8sR0FBWSxLQUFLLENBQUM7UUFRakMsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUsxQixTQUFTO1FBQ1QsbUJBQWMsR0FBVyxDQUFDLENBQUM7UUFDM0Isb0JBQWUsR0FBVyxDQUFDLENBQUM7UUFDNUIsU0FBUztRQUNULHlCQUFvQixHQUFXLENBQUMsQ0FBQztRQUNqQywwQkFBcUIsR0FBVyxDQUFD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cEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuZXhwb3J0IHR5cGUgTmNJbWdUeXBlID0gJ2Jhc2U2NCcgfCAnZmlsZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnbmMtaW1nLWNsaXAnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2ltZy1jbGlwLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2ltZy1jbGlwLmNvbXBvbmVudC5sZXNzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIEltZ0NsaXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XHJcbiAgICAvKiog5Zu+54mH5Zyw5Z2AICovXHJcbiAgICBASW5wdXQoKSBuY1VybDogc3RyaW5nID0gJyc7XHJcbiAgICAvKiog56Gu6K6k6KOB5Ymq5Zue6LCDICovXHJcbiAgICBAT3V0cHV0KCkgbmNDb25maXJtID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgLyoqIOijgeWJquWbnuiwg+i/lOWbnuWbvueJh+agvOW8jyAqL1xyXG4gICAgQElucHV0KCkgbmNJbWdUeXBlOiBOY0ltZ1R5cGUgPSAnYmFzZTY0JztcclxuICAgIC8qKiDlrrnlmajlrr3luqYgKi9cclxuICAgIEBJbnB1dCgpIG5jV2lkdGg6IG51bWJlciA9IDMwMDtcclxuICAgIC8qKiDpu5jorqToo4HliarmoYbnmoTlsLrlr7jljaDlm77niYfmr5TkvosgKi9cclxuICAgIEBJbnB1dCgpIG5jQ2xpcFNpemU6IG51bWJlciA9IDAuNztcclxuICAgIC8qKiDoo4HliarmoYbmnIDlsI/lrr3luqYgKi9cclxuICAgIEBJbnB1dCgpIG5jQ2xpcE1pbldpZHRoOiBudW1iZXIgPSA1MDtcclxuICAgIC8qKiDoo4HliarmoYbmnIDlsI/pq5jluqYgKi9cclxuICAgIEBJbnB1dCgpIG5jQ2xpcE1pbkhlaWdodDogbnVtYmVyID0gNTA7XHJcbiAgICAvKiog56Gu6K6k6KOB5Ymq5pe25piv5ZCm5LiL6L295Zu+54mHICovXHJcbiAgICBwcml2YXRlIF9kb3dubG9hZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgc2V0IG5jRG93bmxvYWQodmFsdWU6IGJvb2xlYW4gfCBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9kb3dubG9hZCA9IHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IGZhbHNlICYmIHZhbHVlICE9PSAnZmFsc2UnO1xyXG4gICAgfVxyXG4gICAgZ2V0IG5jRG93bmxvYWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rvd25sb2FkO1xyXG4gICAgfVxyXG4gICAgLyoqIOiwg+aVtOW3peWFt+agjyAqL1xyXG4gICAgcHJpdmF0ZSBfdG9vbDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgc2V0IG5jVG9vbCh2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3Rvb2wgPSB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBmYWxzZSAmJiB2YWx1ZSAhPT0gJ2ZhbHNlJztcclxuICAgIH1cclxuICAgIGdldCBuY1Rvb2woKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rvb2w7XHJcbiAgICB9XHJcbiAgICAvKiog5LiK5LygICovXHJcbiAgICBwcml2YXRlIF91cGxvYWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIHNldCBuY1VwbG9hZCh2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3VwbG9hZCA9IHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IGZhbHNlICYmIHZhbHVlICE9PSAnZmFsc2UnO1xyXG4gICAgfVxyXG4gICAgZ2V0IG5jVXBsb2FkKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl91cGxvYWQ7XHJcbiAgICB9XHJcblxyXG4gICAgaGFzSW1hZ2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGZpbGU6IGFueTsvL2ZpbGXpgInmi6nmoYZcclxuICAgIGNsaXBJbWFnZTogYW55Oy8v6KOB5Ymq6IOM5pmv5Zu+54mHXHJcbiAgICBjbGlwUGF0aEltZzogYW55Oy8v6KOB5Ymq5L2/55So55qE5Zu+54mHXHJcbiAgICBjbGlwOiBhbnk7Ly/oo4HliarmoYZcclxuICAgIC8vIOWbvueJh+W9k+WJjeWuvemrmFxyXG4gICAgY2xpcEltYWdlV2lkdGg6IG51bWJlciA9IDA7XHJcbiAgICBjbGlwSW1hZ2VIZWlnaHQ6IG51bWJlciA9IDA7XHJcbiAgICAvLyDlm77niYfljp/lp4vlrr3pq5hcclxuICAgIGNsaXBJbWFnZU9yaWdpbldpZHRoOiBudW1iZXIgPSAwO1xyXG4gICAgY2xpcEltYWdlT3JpZ2luSGVpZ2h0OiBudW1iZXIgPSAwO1xyXG4gICAgc2NhbGU6IG51bWJlciA9IDA7Ly/nvKnmlL7mr5TkvotcclxuICAgIGNsaXBXaWR0aDogbnVtYmVyID0gMDsvL+ijgeWJquahhuWuveW6plxyXG4gICAgY2xpcEhlaWdodDogbnVtYmVyID0gMDsvL+ijgeWJquahhumrmOW6plxyXG4gICAgY2xpcFg6IG51bWJlciA9IDA7Ly/oo4HliarmoYZ4XHJcbiAgICBjbGlwWTogbnVtYmVyID0gMDsvL+ijgeWJquahhnlcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZVJlZjogRWxlbWVudFJlZikgeyB9XHJcblxyXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jbGlwSW1hZ2UgPSB0aGlzLmVsZVJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjbGlwSW1hZ2UnKTtcclxuICAgICAgICB0aGlzLmNsaXBQYXRoSW1nID0gdGhpcy5lbGVSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcjY2xpcFBhdGhJbWcnKTtcclxuICAgICAgICB0aGlzLmNsaXAgPSB0aGlzLmVsZVJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjbGlwJyk7XHJcbiAgICAgICAgaWYgKHRoaXMubmNVcGxvYWQpIHtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGUgPSB0aGlzLmVsZVJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyNmaWxlJyk7XHJcbiAgICAgICAgICAgICAgICAvLyDnm5HlkKzkuIrkvKDnirbmgIEg5rWP6KeI5Zu+54mHXHJcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGUuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGU6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBlLnRhcmdldC5maWxlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVhZEltYWdlKHJlYWRlci5yZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8v6KOB5Ymq5qGG57yp5pS+44CB5ouW5ou9XHJcbiAgICAgICAgdGhpcy5jbGlwQm94Wm9vbSgpO1xyXG4gICAgICAgIHRoaXMuY2xpcEJweERyYWcoKTtcclxuICAgICAgICAvL+ivu+WPluWbvueJh1xyXG4gICAgICAgIHRoaXMucmVhZEltYWdlKHRoaXMubmNVcmwpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgICAgICBpZiAoY2hhbmdlc1snbmNVcmwnXSAmJiAhY2hhbmdlc1snbmNVcmwnXS5maXJzdENoYW5nZSkge1xyXG4gICAgICAgICAgICB0aGlzLnJlYWRJbWFnZSh0aGlzLm5jVXJsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy/or7vlj5blm77niYdcclxuICAgIHJlYWRJbWFnZSh1cmw6IGFueSkge1xyXG4gICAgICAgIC8vIOivu+WPluWIsOeahOWbvueJh+aVsOaNrlxyXG4gICAgICAgIHRoaXMuY2xpcEltYWdlLnNyYyA9IHVybDtcclxuICAgICAgICAvLyDoo4Hliarkvb/nlKjnmoTlm77niYdcclxuICAgICAgICB0aGlzLmNsaXBQYXRoSW1nLnNyYyA9IHVybDtcclxuICAgICAgICAvL+iOt+WPluW9k+WJjeWbvueJh+eahOWuvemrmFxyXG4gICAgICAgIHRoaXMuZ2V0Q2xpcEltYWdlU2l6ZSh1cmwpLnRoZW4oKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIOWIneWni+WMllxyXG4gICAgICAgICAgICB0aGlzLmluaXQoKTtcclxuICAgICAgICAgICAgdGhpcy5oYXNJbWFnZSA9IHRydWU7XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICAvLyDojrflj5bkuIrkvKDlm77niYfnmoTlvZPliY3lsLrlr7jlkozljp/lp4vlsLrlr7hcclxuICAgIGFzeW5jIGdldENsaXBJbWFnZVNpemUoZGF0YXVybDogYW55KSB7XHJcbiAgICAgICAgY29uc3QgZGF0YTogYW55ID0gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5jbGlwSW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLmNsaXBJbWFnZSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8g6I635Y+W5Zu+54mH5b2T5YmN5a696auYXHJcbiAgICAgICAgdGhpcy5jbGlwSW1hZ2VXaWR0aCA9IGRhdGEud2lkdGg7XHJcbiAgICAgICAgdGhpcy5jbGlwSW1hZ2VIZWlnaHQgPSBkYXRhLmhlaWdodDtcclxuICAgICAgICBjb25zdCBkYXRhXzE6IGFueSA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlXzEpID0+IHtcclxuICAgICAgICAgICAgLy8g6I635Y+W5Zu+54mH5Y6f5aeL5a696auYXHJcbiAgICAgICAgICAgIGxldCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcclxuICAgICAgICAgICAgaW1nLnNyYyA9IGRhdGF1cmw7XHJcbiAgICAgICAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlXzEoaW1nKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyDojrflj5blm77niYfljp/lp4vlrr3pq5hcclxuICAgICAgICB0aGlzLmNsaXBJbWFnZU9yaWdpbldpZHRoID0gZGF0YV8xLndpZHRoO1xyXG4gICAgICAgIHRoaXMuY2xpcEltYWdlT3JpZ2luSGVpZ2h0ID0gZGF0YV8xLmhlaWdodDtcclxuICAgICAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5Yid5aeL5YyWXHJcbiAgICBpbml0KCkge1xyXG4gICAgICAgIC8vIOaYvuekuuijgeWJquahhlxyXG4gICAgICAgIHRoaXMuY2xpcC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICAvLyDnvKnmlL7mr5TkvotcclxuICAgICAgICB0aGlzLnNjYWxlID0gdGhpcy5jbGlwSW1hZ2VPcmlnaW5XaWR0aCAvIHRoaXMuY2xpcEltYWdlV2lkdGg7XHJcbiAgICAgICAgLy8g6K6+572u6KOB5Ymq5qGG55qE5a696auYXHJcbiAgICAgICAgbGV0IGNsaXBXaWR0aCA9IE1hdGguZmxvb3IodGhpcy5jbGlwSW1hZ2VXaWR0aCAqIHRoaXMubmNDbGlwU2l6ZSk7XHJcbiAgICAgICAgbGV0IGNsaXBIZWlnaHQgPSBNYXRoLmZsb29yKHRoaXMuY2xpcEltYWdlSGVpZ2h0ICogdGhpcy5uY0NsaXBTaXplKTtcclxuICAgICAgICB0aGlzLnNldENsaXBTaXplKGNsaXBXaWR0aCwgY2xpcEhlaWdodCk7XHJcblxyXG4gICAgICAgIC8vIOiuvue9ruijgeWJquahhueahOS9jee9rlxyXG4gICAgICAgIGxldCB4ID0gTWF0aC5mbG9vcigodGhpcy5jbGlwSW1hZ2VXaWR0aCAtIGNsaXBXaWR0aCkgLyAyKTtcclxuICAgICAgICBsZXQgeSA9IE1hdGguZmxvb3IoKHRoaXMuY2xpcEltYWdlSGVpZ2h0IC0gY2xpcEhlaWdodCkgLyAyKTtcclxuICAgICAgICB0aGlzLnNldENsaXBQb3NpdGlvbih4LCB5KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyDorr7nva7oo4HliarmoYbnmoTlsLrlr7hcclxuICAgIHNldENsaXBTaXplKGNsaXBXaWR0aDogbnVtYmVyLCBjbGlwSGVpZ2h0OiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLmNsaXAuc3R5bGUuc2V0UHJvcGVydHkoJy0tY2xpcFdpZHRoJywgY2xpcFdpZHRoICsgJ3B4Jyk7XHJcbiAgICAgICAgdGhpcy5jbGlwLnN0eWxlLnNldFByb3BlcnR5KCctLWNsaXBIZWlnaHQnLCBjbGlwSGVpZ2h0ICsgJ3B4Jyk7XHJcbiAgICAgICAgdGhpcy5jbGlwV2lkdGggPSBjbGlwV2lkdGg7XHJcbiAgICAgICAgdGhpcy5jbGlwSGVpZ2h0ID0gY2xpcEhlaWdodDtcclxuICAgIH1cclxuXHJcbiAgICAvLyDorr7nva7oo4HliarmoYbnmoTkvY3nva5cclxuICAgIHNldENsaXBQb3NpdGlvbih4OiBudW1iZXIsIHk6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuY2xpcC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1jbGlwWCcsIHggKyAncHgnKTtcclxuICAgICAgICB0aGlzLmNsaXAuc3R5bGUuc2V0UHJvcGVydHkoJy0tY2xpcFknLCB5ICsgJ3B4Jyk7XHJcbiAgICAgICAgdGhpcy5jbGlwWCA9IHg7XHJcbiAgICAgICAgdGhpcy5jbGlwWSA9IHk7XHJcbiAgICAgICAgLy8g6K6+572u6KOB5Ymq6Zi05b2xXHJcbiAgICAgICAgdGhpcy5zZXRDbGlwUGF0aCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOiuvue9ruijgeWJqumYtOW9sVxyXG4gICAgc2V0Q2xpcFBhdGgoKSB7XHJcbiAgICAgICAgbGV0IGx0ID0gdGhpcy5jbGlwLm9mZnNldExlZnQgKyAncHgnICsgJyAnICsgdGhpcy5jbGlwLm9mZnNldFRvcCArICdweCc7XHJcbiAgICAgICAgbGV0IHJ0ID0gKHRoaXMuY2xpcC5vZmZzZXRMZWZ0ICsgdGhpcy5jbGlwLm9mZnNldFdpZHRoKSArICdweCcgKyAnICcgKyB0aGlzLmNsaXAub2Zmc2V0VG9wICsgJ3B4JztcclxuICAgICAgICBsZXQgcmIgPSAodGhpcy5jbGlwLm9mZnNldExlZnQgKyB0aGlzLmNsaXAub2Zmc2V0V2lkdGgpICsgJ3B4JyArICcgJyArICh0aGlzLmNsaXAub2Zmc2V0VG9wICsgdGhpcy5jbGlwLm9mZnNldEhlaWdodCkgKyAncHgnO1xyXG4gICAgICAgIGxldCBsYiA9IHRoaXMuY2xpcC5vZmZzZXRMZWZ0ICsgJ3B4JyArICcgJyArICh0aGlzLmNsaXAub2Zmc2V0VG9wICsgdGhpcy5jbGlwLm9mZnNldEhlaWdodCkgKyAncHgnO1xyXG4gICAgICAgIHRoaXMuY2xpcFBhdGhJbWcuc3R5bGUuc2V0UHJvcGVydHkoJy0tY2xpcFBhdGgnLCBgcG9seWdvbig