ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
220 lines • 34 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { animate, style, transition, trigger } from '@angular/animations';
import { Platform } from '@angular/cdk/platform';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, Input, NgZone, ViewEncapsulation } from '@angular/core';
const isImageFileType = (type) => !!type && type.indexOf('image/') === 0;
const ɵ0 = isImageFileType;
const MEASURE_SIZE = 200;
export class NzUploadListComponent {
// #endregion
constructor(cdr, doc, ngZone, platform, elementRef) {
this.cdr = cdr;
this.doc = doc;
this.ngZone = ngZone;
this.platform = platform;
this.elementRef = elementRef;
this.list = [];
this.locale = {};
this.iconRender = null;
// TODO: move to host after View Engine deprecation
this.elementRef.nativeElement.classList.add('ant-upload-list');
}
get showPic() {
return this.listType === 'picture' || this.listType === 'picture-card';
}
set items(list) {
this.list = list;
}
genErr(file) {
if (file.response && typeof file.response === 'string') {
return file.response;
}
return (file.error && file.error.statusText) || this.locale.uploadError;
}
extname(url) {
const temp = url.split('/');
const filename = temp[temp.length - 1];
const filenameWithoutSuffix = filename.split(/#|\?/)[0];
return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0];
}
isImageUrl(file) {
if (isImageFileType(file.type)) {
return true;
}
const url = (file.thumbUrl || file.url || '');
if (!url) {
return false;
}
const extension = this.extname(url);
if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg)$/i.test(extension)) {
return true;
}
else if (/^data:/.test(url)) {
// other file types of base64
return false;
}
else if (extension) {
// other file types which have extension
return false;
}
return true;
}
getIconType(file) {
if (!this.showPic) {
return '';
}
if (file.isUploading || (!file.thumbUrl && !file.url)) {
return 'uploading';
}
else {
return 'thumbnail';
}
}
previewImage(file) {
return new Promise(resolve => {
if (!isImageFileType(file.type)) {
resolve('');
return;
}
this.ngZone.runOutsideAngular(() => {
const canvas = this.doc.createElement('canvas');
canvas.width = MEASURE_SIZE;
canvas.height = MEASURE_SIZE;
canvas.style.cssText = `position: fixed; left: 0; top: 0; width: ${MEASURE_SIZE}px; height: ${MEASURE_SIZE}px; z-index: 9999; display: none;`;
this.doc.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
const { width, height } = img;
let drawWidth = MEASURE_SIZE;
let drawHeight = MEASURE_SIZE;
let offsetX = 0;
let offsetY = 0;
if (width < height) {
drawHeight = height * (MEASURE_SIZE / width);
offsetY = -(drawHeight - drawWidth) / 2;
}
else {
drawWidth = width * (MEASURE_SIZE / height);
offsetX = -(drawWidth - drawHeight) / 2;
}
try {
ctx.drawImage(img, offsetX, offsetY, drawWidth, drawHeight);
}
catch (_a) { }
const dataURL = canvas.toDataURL();
this.doc.body.removeChild(canvas);
resolve(dataURL);
};
img.src = window.URL.createObjectURL(file);
});
});
}
genThumb() {
if (!this.platform.isBrowser) {
return;
}
const win = window;
if (!this.showPic || typeof document === 'undefined' || typeof win === 'undefined' || !win.FileReader || !win.File) {
return;
}
this.list
.filter(file => file.originFileObj instanceof File && file.thumbUrl === undefined)
.forEach(file => {
file.thumbUrl = '';
(this.previewFile ? this.previewFile(file).toPromise() : this.previewImage(file.originFileObj)).then(dataUrl => {
file.thumbUrl = dataUrl;
this.detectChanges();
});
});
}
showDownload(file) {
return !!(this.icons.showDownloadIcon && file.status === 'done');
}
fixData() {
this.list.forEach(file => {
file.isUploading = file.status === 'uploading';
file.message = this.genErr(file);
file.linkProps = typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps;
file.isImageUrl = this.previewIsImage ? this.previewIsImage(file) : this.isImageUrl(file);
file.iconType = this.getIconType(file);
file.showDownload = this.showDownload(file);
});
}
handlePreview(file, e) {
if (!this.onPreview) {
return;
}
e.preventDefault();
return this.onPreview(file);
}
handleRemove(file, e) {
e.preventDefault();
if (this.onRemove) {
this.onRemove(file);
}
return;
}
handleDownload(file) {
if (typeof this.onDownload === 'function') {
this.onDownload(file);
}
else if (file.url) {
window.open(file.url);
}
}
detectChanges() {
this.fixData();
this.cdr.detectChanges();
}
ngOnChanges() {
this.fixData();
this.genThumb();
}
}
NzUploadListComponent.decorators = [
{ type: Component, args: [{
selector: 'nz-upload-list',
exportAs: 'nzUploadList',
template: "<div *ngFor=\"let file of list\" class=\"ant-upload-list-{{ listType }}-container\">\n <div\n class=\"ant-upload-list-item ant-upload-list-item-{{\n file.status\n }} ant-upload-list-item-list-type-{{ listType }}\"\n [attr.data-key]=\"file.key\"\n @itemState\n nz-tooltip\n [nzTooltipTitle]=\"file.status === 'error' ? file.message : null\"\n >\n <ng-template #icon>\n <ng-container [ngSwitch]=\"file.iconType\">\n <div\n *ngSwitchCase=\"'uploading'\"\n class=\"ant-upload-list-item-thumbnail\"\n [class.ant-upload-list-item-file]=\"!file.isUploading\"\n >\n <ng-template\n [ngTemplateOutlet]=\"iconNode\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n ></ng-template>\n </div>\n <a\n *ngSwitchCase=\"'thumbnail'\"\n class=\"ant-upload-list-item-thumbnail\"\n [class.ant-upload-list-item-file]=\"!file.isImageUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [href]=\"file.url || file.thumbUrl\"\n (click)=\"handlePreview(file, $event)\"\n >\n <img\n *ngIf=\"file.isImageUrl; else noImageThumbTpl\"\n class=\"ant-upload-list-item-image\"\n [src]=\"file.thumbUrl || file.url\"\n [attr.alt]=\"file.name\"\n />\n </a>\n <div *ngSwitchDefault class=\"ant-upload-text-icon\">\n <ng-template\n [ngTemplateOutlet]=\"iconNode\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n ></ng-template>\n </div>\n </ng-container>\n <ng-template #noImageThumbTpl>\n <ng-template\n [ngTemplateOutlet]=\"iconNode\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n ></ng-template>\n </ng-template>\n </ng-template>\n <ng-template #iconNode let-file>\n <ng-container *ngIf=\"!iconRender; else iconRender\">\n <ng-container [ngSwitch]=\"listType\">\n <ng-container *ngSwitchCase=\"'picture'\">\n <ng-container *ngIf=\"file.isUploading; else iconNodeFileIcon\">\n <i nz-icon nzType=\"loading\"></i>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'picture-card'\">\n <ng-container *ngIf=\"file.isUploading; else iconNodeFileIcon\">\n {{ locale.uploading }}\n </ng-container>\n </ng-container>\n <i *ngSwitchDefault nz-icon [nzType]=\"file.isUploading ? 'loading' : 'paper-clip'\"></i>\n </ng-container>\n </ng-container>\n <ng-template #iconNodeFileIcon>\n <i nz-icon [nzType]=\"file.isImageUrl ? 'picture' : 'file'\" nzTheme=\"twotone\"></i>\n </ng-template>\n </ng-template>\n <ng-template #removeIcon>\n <button\n *ngIf=\"icons.showRemoveIcon\"\n type=\"button\"\n nz-button\n nzType=\"text\"\n nzSize=\"small\"\n (click)=\"handleRemove(file, $event)\"\n [attr.title]=\"locale.removeFile\"\n class=\"ant-upload-list-item-card-actions-btn\"\n >\n <i nz-icon nzType=\"delete\"></i>\n </button>\n </ng-template>\n <ng-template #downloadIcon>\n <button\n *ngIf=\"file.showDownload\"\n type=\"button\"\n nz-button\n nzType=\"text\"\n nzSize=\"small\"\n (click)=\"handleDownload(file)\"\n [attr.title]=\"locale.downloadFile\"\n class=\"ant-upload-list-item-card-actions-btn\"\n >\n <i nz-icon nzType=\"download\"></i>\n </button>\n </ng-template>\n <ng-template #downloadOrDelete>\n <span\n *ngIf=\"listType !== 'picture-card'\"\n class=\"ant-upload-list-item-card-actions {{ listType === 'picture' ? 'picture' : '' }}\"\n >\n <ng-template [ngTemplateOutlet]=\"downloadIcon\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"removeIcon\"></ng-template>\n </span>\n </ng-template>\n <ng-template #preview>\n <a\n *ngIf=\"file.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"ant-upload-list-item-name\"\n [attr.title]=\"file.name\"\n [href]=\"file.url\"\n [attr.download]=\"file.linkProps && file.linkProps.download\"\n (click)=\"handlePreview(file, $event)\"\n >\n {{ file.name }}\n </a>\n <span\n *ngIf=\"!file.url\"\n class=\"ant-upload-list-item-name\"\n [attr.title]=\"file.name\"\n (click)=\"handlePreview(file, $event)\"\n >\n {{ file.name }}\n </span>\n <ng-template [ngTemplateOutlet]=\"downloadOrDelete\"></ng-template>\n </ng-template>\n <div class=\"ant-upload-list-item-info\">\n <span class=\"ant-upload-span\">\n <ng-template [ngTemplateOutlet]=\"icon\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"preview\"></ng-template>\n </span>\n </div>\n <span\n *ngIf=\"listType === 'picture-card' && !file.isUploading\"\n class=\"ant-upload-list-item-actions\"\n >\n <a\n *ngIf=\"icons.showPreviewIcon\"\n [href]=\"file.url || file.thumbUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [attr.title]=\"locale.previewFile\"\n [ngStyle]=\"!(file.url || file.thumbUrl) ? { opacity: 0.5, 'pointer-events': 'none' } : null\"\n (click)=\"handlePreview(file, $event)\"\n >\n <i nz-icon nzType=\"eye\"></i>\n </a>\n <ng-container *ngIf=\"file.status === 'done'\">\n <ng-template [ngTemplateOutlet]=\"downloadIcon\"></ng-template>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"removeIcon\"></ng-template>\n </span>\n <div *ngIf=\"file.isUploading\" class=\"ant-upload-list-item-progress\">\n <nz-progress\n [nzPercent]=\"file.percent!\"\n nzType=\"line\"\n [nzShowInfo]=\"false\"\n [nzStrokeWidth]=\"2\"\n ></nz-progress>\n </div>\n </div>\n</div>\n",
animations: [
trigger('itemState', [
transition(':enter', [style({ height: '0', width: '0', opacity: 0 }), animate(150, style({ height: '*', width: '*', opacity: 1 }))]),
transition(':leave', [animate(150, style({ height: '0', width: '0', opacity: 0 }))])
])
],
host: {
'[class.ant-upload-list-text]': `listType === 'text'`,
'[class.ant-upload-list-picture]': `listType === 'picture'`,
'[class.ant-upload-list-picture-card]': `listType === 'picture-card'`
},
preserveWhitespaces: false,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
},] }
];
NzUploadListComponent.ctorParameters = () => [
{ type: ChangeDetectorRef },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: NgZone },
{ type: Platform },
{ type: ElementRef }
];
NzUploadListComponent.propDecorators = {
locale: [{ type: Input }],
listType: [{ type: Input }],
items: [{ type: Input }],
icons: [{ type: Input }],
onPreview: [{ type: Input }],
onRemove: [{ type: Input }],
onDownload: [{ type: Input }],
previewFile: [{ type: Input }],
previewIsImage: [{ type: Input }],
iconRender: [{ type: Input }]
};
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3ZzdHMvd29yay8xL3MvY29tcG9uZW50cy91cGxvYWQvIiwic291cmNlcyI6WyJ1cGxvYWQtbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFHTixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFNdkIsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFZLEVBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7O0FBRTFGLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQztBQThCekIsTUFBTSxPQUFPLHFCQUFxQjtJQTBLaEMsYUFBYTtJQUViLFlBQ1UsR0FBc0IsRUFDSixHQUFjLEVBQ2hDLE1BQWMsRUFDZCxRQUFrQixFQUNsQixVQUFzQjtRQUp0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUNKLFFBQUcsR0FBSCxHQUFHLENBQVc7UUFDaEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQWhMaEMsU0FBSSxHQUFxQixFQUFFLENBQUM7UUFNbkIsV0FBTSxHQUFjLEVBQUUsQ0FBQztRQVl2QixlQUFVLEdBQWtDLElBQUksQ0FB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V0FBVyxFQUFFO3dCQUNuQixVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDcEksVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztxQkFDckYsQ0FBQztpQkFDSDtnQkFDRCxJQUFJLEVBQUU7b0JBQ0osOEJBQThCLEVBQUUscUJBQXFCO29CQUNyRCxpQ0FBaUMsRUFBRSx3QkFBd0I7b0JBQzNELHNDQUFzQyxFQUFFLDZCQUE2QjtpQkFDdEU7Z0JBQ0QsbUJBQW1CLEVBQUUsS0FBSztnQkFDMUIsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7Z0JBQ3JDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2FBQ2hEOzs7WUE5Q0MsaUJBQWlCOzRDQTZOZCxNQUFNLFNBQUMsUUFBUTtZQXhObEIsTUFBTTtZQVRDLFFBQVE7WUFNZixVQUFVOzs7cUJBb0RULEtBQUs7dUJBQ0wsS0FBSztvQkFDTCxLQUFLO29CQUlMLEtBQUs7d0JBQ0wsS0FBSzt1QkFDTCxLQUFLO3lCQUNMLEtBQUs7MEJBQ0wsS0FBSzs2QkFDTCxLQUFLO3lCQUNMLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBhbmltYXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBOelNob3dVcGxvYWRMaXN0LCBOelVwbG9hZEZpbGUsIE56VXBsb2FkTGlzdFR5cGUgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbmNvbnN0IGlzSW1hZ2VGaWxlVHlwZSA9ICh0eXBlOiBzdHJpbmcpOiBib29sZWFuID0+ICEhdHlwZSAmJiB0eXBlLmluZGV4T2YoJ2ltYWdlLycpID09PSAwO1xuXG5jb25zdCBNRUFTVVJFX1NJWkUgPSAyMDA7XG5cbnR5cGUgVXBsb2FkTGlzdEljb25UeXBlID0gJycgfCAndXBsb2FkaW5nJyB8ICd0aHVtYm5haWwnO1xuXG5pbnRlcmZhY2UgVXBsb2FkTGlzdEZpbGUgZXh0ZW5kcyBOelVwbG9hZEZpbGUge1xuICBpc0ltYWdlVXJsPzogYm9vbGVhbjtcbiAgaXNVcGxvYWRpbmc/OiBib29sZWFuO1xuICBpY29uVHlwZT86IFVwbG9hZExpc3RJY29uVHlwZTtcbiAgc2hvd0Rvd25sb2FkPzogYm9vbGVhbjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnotdXBsb2FkLWxpc3QnLFxuICBleHBvcnRBczogJ256VXBsb2FkTGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi91cGxvYWQtbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIGFuaW1hdGlvbnM6IFtcbiAgICB0cmlnZ2VyKCdpdGVtU3RhdGUnLCBbXG4gICAgICB0cmFuc2l0aW9uKCc6ZW50ZXInLCBbc3R5bGUoeyBoZWlnaHQ6ICcwJywgd2lkdGg6ICcwJywgb3BhY2l0eTogMCB9KSwgYW5pbWF0ZSgxNTAsIHN0eWxlKHsgaGVpZ2h0OiAnKicsIHdpZHRoOiAnKicsIG9wYWNpdHk6IDEgfSkpXSksXG4gICAgICB0cmFuc2l0aW9uKCc6bGVhdmUnLCBbYW5pbWF0ZSgxNTAsIHN0eWxlKHsgaGVpZ2h0OiAnMCcsIHdpZHRoOiAnMCcsIG9wYWNpdHk6IDAgfSkpXSlcbiAgICBdKVxuICBdLFxuICBob3N0OiB7XG4gICAgJ1tjbGFzcy5hbnQtdXBsb2FkLWxpc3QtdGV4dF0nOiBgbGlzdFR5cGUgPT09ICd0ZXh0J2AsXG4gICAgJ1tjbGFzcy5hbnQtdXBsb2FkLWxpc3QtcGljdHVyZV0nOiBgbGlzdFR5cGUgPT09ICdwaWN0dXJlJ2AsXG4gICAgJ1tjbGFzcy5hbnQtdXBsb2FkLWxpc3QtcGljdHVyZS1jYXJkXSc6IGBsaXN0VHlwZSA9PT0gJ3BpY3R1cmUtY2FyZCdgXG4gIH0sXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBOelVwbG9hZExpc3RDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBsaXN0OiBVcGxvYWRMaXN0RmlsZVtdID0gW107XG5cbiAgcHJpdmF0ZSBnZXQgc2hvd1BpYygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5saXN0VHlwZSA9PT0gJ3BpY3R1cmUnIHx8IHRoaXMubGlzdFR5cGUgPT09ICdwaWN0dXJlLWNhcmQnO1xuICB9XG5cbiAgQElucHV0KCkgbG9jYWxlOiBOelNhZmVBbnkgPSB7fTtcbiAgQElucHV0KCkgbGlzdFR5cGUhOiBOelVwbG9hZExpc3RUeXBlO1xuICBASW5wdXQoKVxuICBzZXQgaXRlbXMobGlzdDogTnpVcGxvYWRGaWxlW10pIHtcbiAgICB0aGlzLmxpc3QgPSBsaXN0O1xuICB9XG4gIEBJbnB1dCgpIGljb25zITogTnpTaG93VXBsb2FkTGlzdDtcbiAgQElucHV0KCkgb25QcmV2aWV3PzogKGZpbGU6IE56VXBsb2FkRmlsZSkgPT4gdm9pZDtcbiAgQElucHV0KCkgb25SZW1vdmUhOiAoZmlsZTogTnpVcGxvYWRGaWxlKSA9PiB2b2lkO1xuICBASW5wdXQoKSBvbkRvd25sb2FkPzogKGZpbGU6IE56VXBsb2FkRmlsZSkgPT4gdm9pZDtcbiAgQElucHV0KCkgcHJldmlld0ZpbGU/OiAoZmlsZTogTnpVcGxvYWRGaWxlKSA9PiBPYnNlcnZhYmxlPHN0cmluZz47XG4gIEBJbnB1dCgpIHByZXZpZXdJc0ltYWdlPzogKGZpbGU6IE56VXBsb2FkRmlsZSkgPT4gYm9vbGVhbjtcbiAgQElucHV0KCkgaWNvblJlbmRlcjogVGVtcGxhdGVSZWY8TnpTYWZlQW55PiB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgZ2VuRXJyKGZpbGU6IE56VXBsb2FkRmlsZSk6IHN0cmluZyB7XG4gICAgaWYgKGZpbGUucmVzcG9uc2UgJiYgdHlwZW9mIGZpbGUucmVzcG9uc2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmlsZS5yZXNwb25zZTtcbiAgICB9XG4gICAgcmV0dXJuIChmaWxlLmVycm9yICYmIGZpbGUuZXJyb3Iuc3RhdHVzVGV4dCkgfHwgdGhpcy5sb2NhbGUudXBsb2FkRXJyb3I7XG4gIH1cblxuICBwcml2YXRlIGV4dG5hbWUodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHRlbXAgPSB1cmwuc3BsaXQoJy8nKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IHRlbXBbdGVtcC5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBmaWxlbmFtZVdpdGhvdXRTdWZmaXggPSBmaWxlbmFtZS5zcGxpdCgvI3xcXD8vKVswXTtcbiAgICByZXR1cm4gKC9cXC5bXi4vXFxcXF0qJC8uZXhlYyhmaWxlbmFtZVdpdGhvdXRTdWZmaXgpIHx8IFsnJ10pWzBdO1xuICB9XG5cbiAgaXNJbWFnZVVybChmaWxlOiBOelVwbG9hZEZpbGUpOiBib29sZWFuIHtcbiAgICBpZiAoaXNJbWFnZUZpbGVUeXBlKGZpbGUudHlwZSEpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgdXJsOiBzdHJpbmcgPSAoZmlsZS50aHVtYlVybCB8fCBmaWxlLnVybCB8fCAnJykgYXMgc3RyaW5nO1xuICAgIGlmICghdXJsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGV4dGVuc2lvbiA9IHRoaXMuZXh0bmFtZSh1cmwpO1xuICAgIGlmICgvXmRhdGE6aW1hZ2VcXC8vLnRlc3QodXJsKSB8fCAvKHdlYnB8c3ZnfHBuZ3xnaWZ8anBnfGpwZWd8amZpZnxibXB8ZHBnKSQvaS50ZXN0KGV4dGVuc2lvbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoL15kYXRhOi8udGVzdCh1cmwpKSB7XG4gICAgICAvLyBvdGhlciBmaWxlIHR5cGVzIG9mIGJhc2U2NFxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoZXh0ZW5zaW9uKSB7XG4gICAgICAvLyBvdGhlciBmaWxlIHR5cGVzIHdoaWNoIGhhdmUgZXh0ZW5zaW9uXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJY29uVHlwZShmaWxlOiBVcGxvYWRMaXN0RmlsZSk6IFVwbG9hZExpc3RJY29uVHlwZSB7XG4gICAgaWYgKCF0aGlzLnNob3dQaWMpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgaWYgKGZpbGUuaXNVcGxvYWRpbmcgfHwgKCFmaWxlLnRodW1iVXJsICYmICFmaWxlLnVybCkpIHtcbiAgICAgIHJldHVybiAndXBsb2FkaW5nJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICd0aHVtYm5haWwnO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJldmlld0ltYWdlKGZpbGU6IEZpbGUgfCBCbG9iKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBpZiAoIWlzSW1hZ2VGaWxlVHlwZShmaWxlLnR5cGUpKSB7XG4gICAgICAgIHJlc29sdmUoJycpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICBjYW52YXMud2lkdGggPSBNRUFTVVJFX1NJWkU7XG4gICAgICAgIGNhbnZhcy5oZWlnaHQgPSBNRUFTVVJFX1NJWkU7XG4gICAgICAgIGNhbnZhcy5zdHlsZS5jc3NUZXh0ID0gYHBvc2l0aW9uOiBmaXhlZDsgbGVmdDogMDsgdG9wOiAwOyB3aWR0aDogJHtNRUFTVVJFX1NJWkV9cHg7IGhlaWdodDogJHtNRUFTVVJFX1NJWkV9cHg7IHotaW5kZXg6IDk5OTk7IGRpc3BsYXk6IG5vbmU7YDtcbiAgICAgICAgdGhpcy5kb2MuYm9keS5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBpbWc7XG5cbiAgICAgICAgICBsZXQgZHJhd1dpZHRoID0gTUVBU1VSRV9TSVpFO1xuICAgICAgICAgIGxldCBkcmF3SGVpZ2h0ID0gTUVBU1VSRV9TSVpFO1xuICAgICAgICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICAgICAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICAgICAgICBpZiAod2lkdGggPCBoZWlnaHQpIHtcbiAgICAgICAgICAgIGRyYXdIZWlnaHQgPSBoZWlnaHQgKiAoTUVBU1VSRV9TSVpFIC8gd2lkdGgpO1xuICAgICAgICAgICAgb2Zmc2V0WSA9IC0oZHJhd0hlaWdodCAtIGRyYXdXaWR0aCkgLyAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkcmF3V2lkdGggPSB3aWR0aCAqIChNRUFTVVJFX1NJWkUgLyBoZWlnaHQpO1xuICAgICAgICAgICAgb2Zmc2V0WCA9IC0oZHJhd1dpZHRoIC0gZHJhd0hlaWdodCkgLyAyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjdHghLmRyYXdJbWFnZShpbWcsIG9mZnNldFgsIG9mZnNldFksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgICAgIGNvbnN0IGRhdGFVUkwgPSBjYW52YXMudG9EYXRhVVJMKCk7XG4gICAgICAgICAgdGhpcy5kb2MuYm9keS5yZW1vdmVDaGlsZChjYW52YXMpO1xuXG4gICAgICAgICAgcmVzb2x2ZShkYXRhVVJMKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1nLnNyYyA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdlblRodW1iKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB3aW4gPSB3aW5kb3cgYXMgTnpTYWZlQW55O1xuICAgIGlmICghdGhpcy5zaG93UGljIHx8IHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHdpbiA9PT0gJ3VuZGVmaW5lZCcgfHwgIXdpbi5GaWxlUmVhZGVyIHx8ICF3aW4uRmlsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxpc3RcbiAgICAgIC5maWx0ZXIoZmlsZSA9PiBmaWxlLm9yaWdpbkZpbGVPYmogaW5zdGFuY2VvZiBGaWxlICYmIGZpbGUudGh1bWJVcmwgPT09IHVuZGVmaW5lZClcbiAgICAgIC5mb3JFYWNoKGZpbGUgPT4ge1xuICAgICAgICBmaWxlLnRodW1iVXJsID0gJyc7XG4gICAgICAgICh0aGlzLnByZXZpZXdGaWxlID8gdGhpcy5wcmV2aWV3RmlsZShmaWxlKS50b1Byb21pc2UoKSA6IHRoaXMucHJldmlld0ltYWdlKGZpbGUub3JpZ2luRmlsZU9iaiEpKS50aGVuKGRhdGFVcmwgPT4ge1xuICAgICAgICAgIGZpbGUudGh1bWJVcmwgPSBkYXRhVXJsO1xuICAgICAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG93RG93bmxvYWQoZmlsZTogTnpVcGxvYWRGaWxlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhKHRoaXMuaWNvbnMuc2hvd0Rvd25sb2FkSWNvbiAmJiBmaWxlLnN0YXR1cyA9PT0gJ2RvbmUnKTtcbiAgfVxuXG4gIHByaXZhdGUgZml4RGF0YSgpOiB2b2lkIHtcbiAgICB0aGlzLmxpc3QuZm9yRWFjaChmaWxlID0+IHtcbiAgICAgIGZpbGUuaXNVcGxvYWRpbmcgPSBmaWxlLnN0YXR1cyA9PT0gJ3VwbG9hZGluZyc7XG4gICAgICBmaWxlLm1lc3NhZ2UgPSB0aGlzLmdlbkVycihmaWxlKTtcbiAgICAgIGZpbGUubGlua1Byb3BzID0gdHlwZW9mIGZpbGUubGlua1Byb3BzID09PSAnc3RyaW5nJyA/IEpTT04ucGFyc2UoZmlsZS5saW5rUHJvcHMpIDogZmlsZS5saW5rUHJvcHM7XG4gICAgICBmaWxlLmlzSW1hZ2VVcmwgPSB0aGlzLnByZXZpZXdJc0ltYWdlID8gdGhpcy5wcmV2aWV3SXNJbWFnZShmaWxlKSA6IHRoaXMuaXNJbWFnZVVybChmaWxlKTtcbiAgICAgIGZpbGUuaWNvblR5cGUgPSB0aGlzLmdldEljb25UeXBlKGZpbGUpO1xuICAgICAgZmlsZS5zaG93RG93bmxvYWQgPSB0aGlzLnNob3dEb3dubG9hZChmaWxlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGhhbmRsZVByZXZpZXcoZmlsZTogTnpVcGxvYWRGaWxlLCBlOiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5vblByZXZpZXcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgcmV0dXJuIHRoaXMub25QcmV2aWV3KGZpbGUpO1xuICB9XG5cbiAgaGFuZGxlUmVtb3ZlKGZpbGU6IE56VXBsb2FkRmlsZSwgZTogRXZlbnQpOiB2b2lkIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKHRoaXMub25SZW1vdmUpIHtcbiAgICAgIHRoaXMub25SZW1vdmUoZmlsZSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGhhbmRsZURvd25sb2FkKGZpbGU6IE56VXBsb2FkRmlsZSk6IHZvaWQge1xuICAgIGlmICh0eXBlb2YgdGhpcy5vbkRvd25sb2FkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLm9uRG93bmxvYWQoZmlsZSk7XG4gICAgfSBlbHNlIGlmIChmaWxlLnVybCkge1xuICAgICAgd2luZG93Lm9wZW4oZmlsZS51cmwpO1xuICAgIH1cbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2M6IE56U2FmZUFueSxcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZlxuICApIHtcbiAgICAvLyBUT0RPOiBtb3ZlIHRvIGhvc3QgYWZ0ZXIgVmlldyBFbmdpbmUgZGVwcmVjYXRpb25cbiAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdhbnQtdXBsb2FkLWxpc3QnKTtcbiAgfVxuXG4gIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5maXhEYXRhKCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5maXhEYXRhKCk7XG4gICAgdGhpcy5nZW5UaHVtYigpO1xuICB9XG59XG4iXX0=