ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
414 lines • 38.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: upload-list.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @license
* Copyright Alibaba.com All Rights Reserved.
*
* 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, Inject, Input, NgZone, TemplateRef, ViewEncapsulation } from '@angular/core';
/** @type {?} */
const isImageFileType = (/**
* @param {?} type
* @return {?}
*/
(type) => !!type && type.indexOf('image/') === 0);
const ɵ0 = isImageFileType;
/** @type {?} */
const MEASURE_SIZE = 200;
/**
* @record
*/
function UploadListFile() { }
if (false) {
/** @type {?|undefined} */
UploadListFile.prototype.isImageUrl;
/** @type {?|undefined} */
UploadListFile.prototype.isUploading;
/** @type {?|undefined} */
UploadListFile.prototype.iconType;
/** @type {?|undefined} */
UploadListFile.prototype.listItemNameCls;
/** @type {?|undefined} */
UploadListFile.prototype.showDownload;
}
export class NzUploadListComponent {
// #endregion
/**
* @param {?} cdr
* @param {?} doc
* @param {?} ngZone
* @param {?} platform
*/
constructor(cdr, doc, ngZone, platform) {
this.cdr = cdr;
this.doc = doc;
this.ngZone = ngZone;
this.platform = platform;
this.locale = {};
}
/**
* @private
* @return {?}
*/
get showPic() {
return this.listType === 'picture' || this.listType === 'picture-card';
}
/**
* @param {?} list
* @return {?}
*/
set items(list) {
this.list = list;
}
/**
* @private
* @param {?} file
* @return {?}
*/
genErr(file) {
if (file.response && typeof file.response === 'string') {
return file.response;
}
return (file.error && file.error.statusText) || this.locale.uploadError;
}
/**
* @private
* @param {?} url
* @return {?}
*/
extname(url) {
/** @type {?} */
const temp = url.split('/');
/** @type {?} */
const filename = temp[temp.length - 1];
/** @type {?} */
const filenameWithoutSuffix = filename.split(/#|\?/)[0];
return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0];
}
/**
* @param {?} file
* @return {?}
*/
isImageUrl(file) {
if (isImageFileType((/** @type {?} */ (file.type)))) {
return true;
}
/** @type {?} */
const url = (/** @type {?} */ ((file.thumbUrl || file.url || '')));
if (!url) {
return false;
}
/** @type {?} */
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;
}
/**
* @private
* @param {?} file
* @return {?}
*/
getIconType(file) {
if (!this.showPic) {
return '';
}
if (file.isUploading || (!file.thumbUrl && !file.url)) {
return 'uploading';
}
else {
return 'thumbnail';
}
}
/**
* @private
* @param {?} file
* @return {?}
*/
previewImage(file) {
return new Promise((/**
* @param {?} resolve
* @return {?}
*/
resolve => {
if (!isImageFileType(file.type)) {
resolve('');
return;
}
this.ngZone.runOutsideAngular((/**
* @return {?}
*/
() => {
/** @type {?} */
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);
/** @type {?} */
const ctx = canvas.getContext('2d');
/** @type {?} */
const img = new Image();
img.onload = (/**
* @return {?}
*/
() => {
const { width, height } = img;
/** @type {?} */
let drawWidth = MEASURE_SIZE;
/** @type {?} */
let drawHeight = MEASURE_SIZE;
/** @type {?} */
let offsetX = 0;
/** @type {?} */
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 {
(/** @type {?} */ (ctx)).drawImage(img, offsetX, offsetY, drawWidth, drawHeight);
}
catch (_a) { }
/** @type {?} */
const dataURL = canvas.toDataURL();
this.doc.body.removeChild(canvas);
resolve(dataURL);
});
img.src = window.URL.createObjectURL(file);
}));
}));
}
/**
* @private
* @return {?}
*/
genThumb() {
if (!this.platform.isBrowser) {
return;
}
/** @type {?} */
const win = (/** @type {?} */ (window));
if (!this.showPic || typeof document === 'undefined' || typeof win === 'undefined' || !win.FileReader || !win.File) {
return;
}
this.list
.filter((/**
* @param {?} file
* @return {?}
*/
file => file.originFileObj instanceof File && file.thumbUrl === undefined))
.forEach((/**
* @param {?} file
* @return {?}
*/
file => {
file.thumbUrl = '';
(this.previewFile ? this.previewFile(file).toPromise() : this.previewImage((/** @type {?} */ (file.originFileObj)))).then((/**
* @param {?} dataUrl
* @return {?}
*/
dataUrl => {
file.thumbUrl = dataUrl;
this.detectChanges();
}));
}));
}
/**
* @private
* @param {?} file
* @return {?}
*/
listItemNameCls(file) {
/** @type {?} */
const count = [this.showDownload(file), this.icons.showRemoveIcon].filter((/**
* @param {?} x
* @return {?}
*/
x => x)).length;
return {
[`ant-upload-list-item-name`]: true,
[`ant-upload-list-item-name-icon-count-${count}`]: true
};
}
/**
* @private
* @param {?} file
* @return {?}
*/
showDownload(file) {
return !!(this.icons.showDownloadIcon && file.status === 'done');
}
/**
* @private
* @return {?}
*/
fixData() {
this.list.forEach((/**
* @param {?} file
* @return {?}
*/
file => {
file.message = this.genErr(file);
file.linkProps = typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps;
file.isImageUrl = this.isImageUrl(file);
file.iconType = this.getIconType(file);
file.isUploading = file.status === 'uploading';
file.listItemNameCls = this.listItemNameCls(file);
file.showDownload = this.showDownload(file);
}));
}
/**
* @param {?} file
* @param {?} e
* @return {?}
*/
handlePreview(file, e) {
if (!this.onPreview) {
return;
}
e.preventDefault();
return this.onPreview(file);
}
/**
* @param {?} file
* @param {?} e
* @return {?}
*/
handleRemove(file, e) {
e.preventDefault();
if (this.onRemove) {
this.onRemove(file);
}
return;
}
/**
* @param {?} file
* @return {?}
*/
handleDownload(file) {
if (typeof this.onDownload === 'function') {
this.onDownload(file);
}
else if (file.url) {
window.open(file.url);
}
}
/**
* @return {?}
*/
detectChanges() {
this.fixData();
this.cdr.detectChanges();
}
/**
* @return {?}
*/
ngOnChanges() {
this.fixData();
this.genThumb();
}
}
NzUploadListComponent.decorators = [
{ type: Component, args: [{
selector: 'nz-upload-list',
exportAs: 'nzUploadList',
template: "<div\n *ngFor=\"let file of list\"\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 <span *ngSwitchDefault class=\"ant-upload-text-icon\">\n <ng-template\n [ngTemplateOutlet]=\"iconNode\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n ></ng-template>\n </span>\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 #downloadOrDelete>\n <span\n *ngIf=\"listType !== 'picture-card'\"\n class=\"ant-upload-list-item-card-actions {{ listType === 'picture' ? 'picture' : '' }}\"\n >\n <a *ngIf=\"file.showDownload\" title=\"{{ locale.downloadFile }}\">\n <ng-template [ngTemplateOutlet]=\"downloadIcon\"></ng-template>\n </a>\n <a *ngIf=\"icons.showRemoveIcon\" title=\"{{ locale.removeFile }}\">\n <ng-template [ngTemplateOutlet]=\"removeIcon\"></ng-template>\n </a>\n </span>\n </ng-template>\n <ng-template #preview>\n <a\n *ngIf=\"file.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [ngClass]=\"file.listItemNameCls\"\n title=\"{{ file.name }}\"\n [href]=\"file.url\"\n [attr.download]=\"file.linkProps && file.linkProps.download\"\n (click)=\"handlePreview(file, $event)\"\n >{{ file.name }}</a\n >\n <span\n *ngIf=\"!file.url\"\n [ngClass]=\"file.listItemNameCls\"\n title=\"{{ file.name }}\"\n (click)=\"handlePreview(file, $event)\"\n >{{ file.name }}</span\n >\n <ng-template [ngTemplateOutlet]=\"downloadOrDelete\"></ng-template>\n </ng-template>\n <ng-template #removeIcon>\n <i\n *ngIf=\"icons.showRemoveIcon\"\n (click)=\"handleRemove(file, $event)\"\n nz-icon\n nzType=\"delete\"\n title=\"{{ locale.removeFile }}\"\n ></i>\n </ng-template>\n <ng-template #downloadIcon>\n <i\n *ngIf=\"file.showDownload\"\n (click)=\"handleDownload(file)\"\n nz-icon\n nzType=\"download\"\n title=\"{{ locale.downloadFile }}\"\n ></i>\n </ng-template>\n <div class=\"ant-upload-list-item-info\">\n <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 title=\"{{ locale.previewFile }}\"\n [ngStyle]=\"!(file.url || file.thumbUrl) && { opacity: 0.5, 'pointer-events': 'none' }\"\n (click)=\"handlePreview(file, $event)\"\n >\n <i nz-icon nzType=\"eye\"></i>\n </a>\n <ng-template [ngTemplateOutlet]=\"downloadIcon\"></ng-template>\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",
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]': `true`,
'[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
}] }
];
/** @nocollapse */
NzUploadListComponent.ctorParameters = () => [
{ type: ChangeDetectorRef },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: NgZone },
{ type: Platform }
];
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 }],
iconRender: [{ type: Input }]
};
if (false) {
/** @type {?} */
NzUploadListComponent.prototype.list;
/** @type {?} */
NzUploadListComponent.prototype.locale;
/** @type {?} */
NzUploadListComponent.prototype.listType;
/** @type {?} */
NzUploadListComponent.prototype.icons;
/** @type {?} */
NzUploadListComponent.prototype.onPreview;
/** @type {?} */
NzUploadListComponent.prototype.onRemove;
/** @type {?} */
NzUploadListComponent.prototype.onDownload;
/** @type {?} */
NzUploadListComponent.prototype.previewFile;
/** @type {?} */
NzUploadListComponent.prototype.iconRender;
/**
* @type {?}
* @private
*/
NzUploadListComponent.prototype.cdr;
/**
* @type {?}
* @private
*/
NzUploadListComponent.prototype.doc;
/**
* @type {?}
* @private
*/
NzUploadListComponent.prototype.ngZone;
/**
* @type {?}
* @private
*/
NzUploadListComponent.prototype.platform;
}
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC91cGxvYWQvIiwic291cmNlcyI6WyJ1cGxvYWQtbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUVOLFdBQVcsRUFDWCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7O01BTWpCLGVBQWU7Ozs7QUFBRyxDQUFDLElBQVksRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQTs7O01BRW5GLFlBQVksR0FBRyxHQUFHOzs7O0FBSXhCLDZCQU1DOzs7SUFMQyxvQ0FBcUI7O0lBQ3JCLHFDQUFzQjs7SUFDdEIsa0NBQThCOztJQUM5Qix5Q0FBOEI7O0lBQzlCLHNDQUF1Qjs7QUF1QnpCLE1BQU0sT0FBTyxxQkFBcUI7Ozs7Ozs7O0lBb0xoQyxZQUNVLEdBQXNCLEVBQ0osR0FBYyxFQUNoQyxNQUFjLEVBQ2QsUUFBa0I7UUFIbEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDSixRQUFHLEdBQUgsR0FBRyxDQUFXO1FBQ2hDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBakxuQixXQUFNLEdBQWMsRUFBRSxDQUFDO0lBa0w3QixDQUFDOzs7OztJQXRMSixJQUFZLE9B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QUNMLEtBQUs7eUJBQ0wsS0FBSzswQkFDTCxLQUFLO3lCQUNMLEtBQUs7Ozs7SUFqQk4scUNBQXVCOztJQU12Qix1Q0FBZ0M7O0lBQ2hDLHlDQUFrQzs7SUFLbEMsc0NBQXdDOztJQUN4QywwQ0FBK0M7O0lBQy9DLHlDQUE4Qzs7SUFDOUMsMkNBQWdEOztJQUNoRCw0Q0FBK0Q7O0lBQy9ELDJDQUF1Qzs7Ozs7SUFtS3JDLG9DQUE4Qjs7Ozs7SUFDOUIsb0NBQXdDOzs7OztJQUN4Qyx1Q0FBc0I7Ozs7O0lBQ3RCLHlDQUEwQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBbGliYWJhLmNvbSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBhbmltYXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ0NsYXNzVHlwZSwgTnpTYWZlQW55IH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgU2hvd1VwbG9hZExpc3RJbnRlcmZhY2UsIFVwbG9hZEZpbGUsIFVwbG9hZExpc3RUeXBlIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuXG5jb25zdCBpc0ltYWdlRmlsZVR5cGUgPSAodHlwZTogc3RyaW5nKTogYm9vbGVhbiA9PiAhIXR5cGUgJiYgdHlwZS5pbmRleE9mKCdpbWFnZS8nKSA9PT0gMDtcblxuY29uc3QgTUVBU1VSRV9TSVpFID0gMjAwO1xuXG50eXBlIFVwbG9hZExpc3RJY29uVHlwZSA9ICcnIHwgJ3VwbG9hZGluZycgfCAndGh1bWJuYWlsJztcblxuaW50ZXJmYWNlIFVwbG9hZExpc3RGaWxlIGV4dGVuZHMgVXBsb2FkRmlsZSB7XG4gIGlzSW1hZ2VVcmw/OiBib29sZWFuO1xuICBpc1VwbG9hZGluZz86IGJvb2xlYW47XG4gIGljb25UeXBlPzogVXBsb2FkTGlzdEljb25UeXBlO1xuICBsaXN0SXRlbU5hbWVDbHM/OiBOZ0NsYXNzVHlwZTtcbiAgc2hvd0Rvd25sb2FkPzogYm9vbGVhbjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnotdXBsb2FkLWxpc3QnLFxuICBleHBvcnRBczogJ256VXBsb2FkTGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi91cGxvYWQtbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIGFuaW1hdGlvbnM6IFtcbiAgICB0cmlnZ2VyKCdpdGVtU3RhdGUnLCBbXG4gICAgICB0cmFuc2l0aW9uKCc6ZW50ZXInLCBbc3R5bGUoeyBoZWlnaHQ6ICcwJywgd2lkdGg6ICcwJywgb3BhY2l0eTogMCB9KSwgYW5pbWF0ZSgxNTAsIHN0eWxlKHsgaGVpZ2h0OiAnKicsIHdpZHRoOiAnKicsIG9wYWNpdHk6IDEgfSkpXSksXG4gICAgICB0cmFuc2l0aW9uKCc6bGVhdmUnLCBbYW5pbWF0ZSgxNTAsIHN0eWxlKHsgaGVpZ2h0OiAnMCcsIHdpZHRoOiAnMCcsIG9wYWNpdHk6IDAgfSkpXSlcbiAgICBdKVxuICBdLFxuICBob3N0OiB7XG4gICAgJ1tjbGFzcy5hbnQtdXBsb2FkLWxpc3RdJzogYHRydWVgLFxuICAgICdbY2xhc3MuYW50LXVwbG9hZC1saXN0LXRleHRdJzogYGxpc3RUeXBlID09PSAndGV4dCdgLFxuICAgICdbY2xhc3MuYW50LXVwbG9hZC1saXN0LXBpY3R1cmVdJzogYGxpc3RUeXBlID09PSAncGljdHVyZSdgLFxuICAgICdbY2xhc3MuYW50LXVwbG9hZC1saXN0LXBpY3R1cmUtY2FyZF0nOiBgbGlzdFR5cGUgPT09ICdwaWN0dXJlLWNhcmQnYFxuICB9LFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgTnpVcGxvYWRMaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgbGlzdDogVXBsb2FkTGlzdEZpbGVbXTtcblxuICBwcml2YXRlIGdldCBzaG93UGljKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmxpc3RUeXBlID09PSAncGljdHVyZScgfHwgdGhpcy5saXN0VHlwZSA9PT0gJ3BpY3R1cmUtY2FyZCc7XG4gIH1cblxuICBASW5wdXQoKSBsb2NhbGU6IE56U2FmZUFueSA9IHt9O1xuICBASW5wdXQoKSBsaXN0VHlwZTogVXBsb2FkTGlzdFR5cGU7XG4gIEBJbnB1dCgpXG4gIHNldCBpdGVtcyhsaXN0OiBVcGxvYWRGaWxlW10pIHtcbiAgICB0aGlzLmxpc3QgPSBsaXN0O1xuICB9XG4gIEBJbnB1dCgpIGljb25zOiBTaG93VXBsb2FkTGlzdEludGVyZmFjZTtcbiAgQElucHV0KCkgb25QcmV2aWV3OiAoZmlsZTogVXBsb2FkRmlsZSkgPT4gdm9pZDtcbiAgQElucHV0KCkgb25SZW1vdmU6IChmaWxlOiBVcGxvYWRGaWxlKSA9PiB2b2lkO1xuICBASW5wdXQoKSBvbkRvd25sb2FkOiAoZmlsZTogVXBsb2FkRmlsZSkgPT4gdm9pZDtcbiAgQElucHV0KCkgcHJldmlld0ZpbGU6IChmaWxlOiBVcGxvYWRGaWxlKSA9PiBPYnNlcnZhYmxlPHN0cmluZz47XG4gIEBJbnB1dCgpIGljb25SZW5kZXI6IFRlbXBsYXRlUmVmPHZvaWQ+O1xuXG4gIHByaXZhdGUgZ2VuRXJyKGZpbGU6IFVwbG9hZEZpbGUpOiBzdHJpbmcge1xuICAgIGlmIChmaWxlLnJlc3BvbnNlICYmIHR5cGVvZiBmaWxlLnJlc3BvbnNlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGZpbGUucmVzcG9uc2U7XG4gICAgfVxuICAgIHJldHVybiAoZmlsZS5lcnJvciAmJiBmaWxlLmVycm9yLnN0YXR1c1RleHQpIHx8IHRoaXMubG9jYWxlLnVwbG9hZEVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRuYW1lKHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB0ZW1wID0gdXJsLnNwbGl0KCcvJyk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSB0ZW1wW3RlbXAubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgZmlsZW5hbWVXaXRob3V0U3VmZml4ID0gZmlsZW5hbWUuc3BsaXQoLyN8XFw/LylbMF07XG4gICAgcmV0dXJuICgvXFwuW14uL1xcXFxdKiQvLmV4ZWMoZmlsZW5hbWVXaXRob3V0U3VmZml4KSB8fCBbJyddKVswXTtcbiAgfVxuXG4gIGlzSW1hZ2VVcmwoZmlsZTogVXBsb2FkRmlsZSk6IGJvb2xlYW4ge1xuICAgIGlmIChpc0ltYWdlRmlsZVR5cGUoZmlsZS50eXBlISkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB1cmw6IHN0cmluZyA9IChmaWxlLnRodW1iVXJsIHx8IGZpbGUudXJsIHx8ICcnKSBhcyBzdHJpbmc7XG4gICAgaWYgKCF1cmwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgZXh0ZW5zaW9uID0gdGhpcy5leHRuYW1lKHVybCk7XG4gICAgaWYgKC9eZGF0YTppbWFnZVxcLy8udGVzdCh1cmwpIHx8IC8od2VicHxzdmd8cG5nfGdpZnxqcGd8anBlZ3xqZmlmfGJtcHxkcGcpJC9pLnRlc3QoZXh0ZW5zaW9uKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICgvXmRhdGE6Ly50ZXN0KHVybCkpIHtcbiAgICAgIC8vIG90aGVyIGZpbGUgdHlwZXMgb2YgYmFzZTY0XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChleHRlbnNpb24pIHtcbiAgICAgIC8vIG90aGVyIGZpbGUgdHlwZXMgd2hpY2ggaGF2ZSBleHRlbnNpb25cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGdldEljb25UeXBlKGZpbGU6IFVwbG9hZExpc3RGaWxlKTogVXBsb2FkTGlzdEljb25UeXBlIHtcbiAgICBpZiAoIXRoaXMuc2hvd1BpYykge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBpZiAoZmlsZS5pc1VwbG9hZGluZyB8fCAoIWZpbGUudGh1bWJVcmwgJiYgIWZpbGUudXJsKSkge1xuICAgICAgcmV0dXJuICd1cGxvYWRpbmcnO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gJ3RodW1ibmFpbCc7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwcmV2aWV3SW1hZ2UoZmlsZTogRmlsZSB8IEJsb2IpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGlmICghaXNJbWFnZUZpbGVUeXBlKGZpbGUudHlwZSkpIHtcbiAgICAgICAgcmVzb2x2ZSgnJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IE1FQVNVUkVfU0laRTtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IE1FQVNVUkVfU0laRTtcbiAgICAgICAgY2FudmFzLnN0eWxlLmNzc1RleHQgPSBgcG9zaXRpb246IGZpeGVkOyBsZWZ0OiAwOyB0b3A6IDA7IHdpZHRoOiAke01FQVNVUkVfU0laRX1weDsgaGVpZ2h0OiAke01FQVNVUkVfU0laRX1weDsgei1pbmRleDogOTk5OTsgZGlzcGxheTogbm9uZTtgO1xuICAgICAgICB0aGlzLmRvYy5ib2R5LmFwcGVuZENoaWxkKGNhbnZhcyk7XG4gICAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGltZztcblxuICAgICAgICAgIGxldCBkcmF3V2lkdGggPSBNRUFTVVJFX1NJWkU7XG4gICAgICAgICAgbGV0IGRyYXdIZWlnaHQgPSBNRUFTVVJFX1NJWkU7XG4gICAgICAgICAgbGV0IG9mZnNldFggPSAwO1xuICAgICAgICAgIGxldCBvZmZzZXRZID0gMDtcblxuICAgICAgICAgIGlmICh3aWR0aCA8IGhlaWdodCkge1xuICAgICAgICAgICAgZHJhd0hlaWdodCA9IGhlaWdodCAqIChNRUFTVVJFX1NJWkUgLyB3aWR0aCk7XG4gICAgICAgICAgICBvZmZzZXRZID0gLShkcmF3SGVpZ2h0IC0gZHJhd1dpZHRoKSAvIDI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRyYXdXaWR0aCA9IHdpZHRoICogKE1FQVNVUkVfU0laRSAvIGhlaWdodCk7XG4gICAgICAgICAgICBvZmZzZXRYID0gLShkcmF3V2lkdGggLSBkcmF3SGVpZ2h0KSAvIDI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGN0eCEuZHJhd0ltYWdlKGltZywgb2Zmc2V0WCwgb2Zmc2V0WSwgZHJhd1dpZHRoLCBkcmF3SGVpZ2h0KTtcbiAgICAgICAgICB9IGNhdGNoIHt9XG4gICAgICAgICAgY29uc3QgZGF0YVVSTCA9IGNhbnZhcy50b0RhdGFVUkwoKTtcbiAgICAgICAgICB0aGlzLmRvYy5ib2R5LnJlbW92ZUNoaWxkKGNhbnZhcyk7XG5cbiAgICAgICAgICByZXNvbHZlKGRhdGFVUkwpO1xuICAgICAgICB9O1xuICAgICAgICBpbWcuc3JjID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2VuVGh1bWIoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBsYXRmb3JtLmlzQnJvd3Nlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdpbiA9IHdpbmRvdyBhcyBOelNhZmVBbnk7XG4gICAgaWYgKCF0aGlzLnNob3dQaWMgfHwgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2Ygd2luID09PSAndW5kZWZpbmVkJyB8fCAhd2luLkZpbGVSZWFkZXIgfHwgIXdpbi5GaWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubGlzdFxuICAgICAgLmZpbHRlcihmaWxlID0+IGZpbGUub3JpZ2luRmlsZU9iaiBpbnN0YW5jZW9mIEZpbGUgJiYgZmlsZS50aHVtYlVybCA9PT0gdW5kZWZpbmVkKVxuICAgICAgLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgIGZpbGUudGh1bWJVcmwgPSAnJztcbiAgICAgICAgKHRoaXMucHJldmlld0ZpbGUgPyB0aGlzLnByZXZpZXdGaWxlKGZpbGUpLnRvUHJvbWlzZSgpIDogdGhpcy5wcmV2aWV3SW1hZ2UoZmlsZS5vcmlnaW5GaWxlT2JqISkpLnRoZW4oZGF0YVVybCA9PiB7XG4gICAgICAgICAgZmlsZS50aHVtYlVybCA9IGRhdGFVcmw7XG4gICAgICAgICAgdGhpcy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGxpc3RJdGVtTmFtZUNscyhmaWxlOiBVcGxvYWRGaWxlKTogTmdDbGFzc1R5cGUge1xuICAgIGNvbnN0IGNvdW50ID0gW3RoaXMuc2hvd0Rvd25sb2FkKGZpbGUpLCB0aGlzLmljb25zLnNob3dSZW1vdmVJY29uXS5maWx0ZXIoeCA9PiB4KS5sZW5ndGg7XG4gICAgcmV0dXJuIHtcbiAgICAgIFtgYW50LXVwbG9hZC1saXN0LWl0ZW0tbmFtZWBdOiB0cnVlLFxuICAgICAgW2BhbnQtdXBsb2FkLWxpc3QtaXRlbS1uYW1lLWljb24tY291bnQtJHtjb3VudH1gXTogdHJ1ZVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHNob3dEb3dubG9hZChmaWxlOiBVcGxvYWRGaWxlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhKHRoaXMuaWNvbnMuc2hvd0Rvd25sb2FkSWNvbiAmJiBmaWxlLnN0YXR1cyA9PT0gJ2RvbmUnKTtcbiAgfVxuXG4gIHByaXZhdGUgZml4RGF0YSgpOiB2b2lkIHtcbiAgICB0aGlzLmxpc3QuZm9yRWFjaChmaWxlID0+IHtcbiAgICAgIGZpbGUubWVzc2FnZSA9IHRoaXMuZ2VuRXJyKGZpbGUpO1xuICAgICAgZmlsZS5saW5rUHJvcHMgPSB0eXBlb2YgZmlsZS5saW5rUHJvcHMgPT09ICdzdHJpbmcnID8gSlNPTi5wYXJzZShmaWxlLmxpbmtQcm9wcykgOiBmaWxlLmxpbmtQcm9wcztcbiAgICAgIGZpbGUuaXNJbWFnZVVybCA9IHRoaXMuaXNJbWFnZVVybChmaWxlKTtcbiAgICAgIGZpbGUuaWNvblR5cGUgPSB0aGlzLmdldEljb25UeXBlKGZpbGUpO1xuICAgICAgZmlsZS5pc1VwbG9hZGluZyA9IGZpbGUuc3RhdHVzID09PSAndXBsb2FkaW5nJztcbiAgICAgIGZpbGUubGlzdEl0ZW1OYW1lQ2xzID0gdGhpcy5saXN0SXRlbU5hbWVDbHMoZmlsZSk7XG4gICAgICBmaWxlLnNob3dEb3dubG9hZCA9IHRoaXMuc2hvd0Rvd25sb2FkKGZpbGUpO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlUHJldmlldyhmaWxlOiBVcGxvYWRGaWxlLCBlOiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5vblByZXZpZXcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgcmV0dXJuIHRoaXMub25QcmV2aWV3KGZpbGUpO1xuICB9XG5cbiAgaGFuZGxlUmVtb3ZlKGZpbGU6IFVwbG9hZEZpbGUsIGU6IEV2ZW50KTogdm9pZCB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmICh0aGlzLm9uUmVtb3ZlKSB7XG4gICAgICB0aGlzLm9uUmVtb3ZlKGZpbGUpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBoYW5kbGVEb3dubG9hZChmaWxlOiBVcGxvYWRGaWxlKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm9uRG93bmxvYWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMub25Eb3dubG9hZChmaWxlKTtcbiAgICB9IGVsc2UgaWYgKGZpbGUudXJsKSB7XG4gICAgICB3aW5kb3cub3BlbihmaWxlLnVybCk7XG4gICAgfVxuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvYzogTnpTYWZlQW55LFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBwbGF0Zm9ybTogUGxhdGZvcm1cbiAgKSB7fVxuXG4gIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5maXhEYXRhKCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5maXhEYXRhKCk7XG4gICAgdGhpcy5nZW5UaHVtYigpO1xuICB9XG59XG4iXX0=