angular-upcrop
Version:
Library with upload and crop feature for Angular 6+
921 lines (908 loc) • 102 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/material'), require('ng2-file-upload'), require('@angular/common'), require('angular-cropperjs'), require('@angular/flex-layout')) :
typeof define === 'function' && define.amd ? define('angular-upcrop', ['exports', '@angular/core', '@angular/material', 'ng2-file-upload', '@angular/common', 'angular-cropperjs', '@angular/flex-layout'], factory) :
(factory((global['angular-upcrop'] = {}),global.ng.core,global.ng.material,null,global.ng.common,null,global.ng['flex-layout']));
}(this, (function (exports,core,material,ng2FileUpload,common,angularCropperjs,flexLayout) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UpcropDialogComponent = (function () {
function UpcropDialogComponent(dialogRef, data) {
var _this = this;
this.dialogRef = dialogRef;
this.data = data;
this.cropData = {};
this.uploadedImages = [];
this.uploader = null;
this.steps = {
total: 2,
options: [{
label: 'Subir imagens',
number: 1,
next: 2,
nextDisabled: function () { return _this.step1NextDisabled(); },
nextAction: function () { _this.goToStep2(); }
}, {
label: 'Cortar imagens',
number: 2,
previus: 1,
previusAction: function () { _this.goToStep1(); }
}],
current: {}
};
}
/**
* @return {?}
*/
UpcropDialogComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
//
// Set first step
this.steps.current = this.steps.options[0];
};
/**
* Go to step 1
*/
/**
* Go to step 1
* @return {?}
*/
UpcropDialogComponent.prototype.goToStep1 = /**
* Go to step 1
* @return {?}
*/
function () {
//
// Reset crop
this.upcropCrop.unsetCropping();
//
// Change to step 1
this.steps.current = this.steps.options[0];
//
// Reset crop
this.upcropCrop.current = false;
this.upcropCrop.currentNumber = false;
};
/**
* Go to step 2
*/
/**
* Go to step 2
* @return {?}
*/
UpcropDialogComponent.prototype.goToStep2 = /**
* Go to step 2
* @return {?}
*/
function () {
//
// Change to step 2
this.steps.current = this.steps.options[1];
//
// Set crop
this.upcropCrop.setCropping(this.upcropUpload.uploader);
};
/**
* Finish
*/
/**
* Finish
* @return {?}
*/
UpcropDialogComponent.prototype.finish = /**
* Finish
* @return {?}
*/
function () {
var _this = this;
//
// On complete all files uplaod
this.upcropUpload.uploader.onCompleteAll = function () {
//
// Remove loading
//
// Remove loading
_this.upcropCrop.uploading = false;
//
// Close dialog with uploadedImages
//
// Close dialog with uploadedImages
_this.dialogRef.close(_this.uploadedImages);
};
//
// Emit on crop image
this.upcropCrop.emitOnCropImage();
//
// Set crop data in additionalParameter
this.upcropUpload.uploader.options.additionalParameter['cropData'] = this.cropData;
//
// Upload all
this.upcropCrop.uploading = true;
this.upcropUpload.uploader.uploadAll();
};
/**
* Step 1 next button disabled conditions
*/
/**
* Step 1 next button disabled conditions
* @return {?}
*/
UpcropDialogComponent.prototype.step1NextDisabled = /**
* Step 1 next button disabled conditions
* @return {?}
*/
function () {
return !this.upcropUpload.uploader.queue.length;
};
/**
* On crop image event
* @param event
*/
/**
* On crop image event
* @param {?} event
* @return {?}
*/
UpcropDialogComponent.prototype.onCropImage = /**
* On crop image event
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var cropData = this.createUrlParams(event.data);
//
// Add crop to uploader file crop data
this.upcropUpload.uploader.queue[event.file].url = this.data.uploadConfig.url + cropData;
};
/**
* On upload image event
* @param event
*/
/**
* On upload image event
* @param {?} event
* @return {?}
*/
UpcropDialogComponent.prototype.onUploadImage = /**
* On upload image event
* @param {?} event
* @return {?}
*/
function (event) {
this.uploadedImages.push(event);
};
/**
* Create url params
* @param obj
*/
/**
* Create url params
* @param {?} obj
* @return {?}
*/
UpcropDialogComponent.prototype.createUrlParams = /**
* Create url params
* @param {?} obj
* @return {?}
*/
function (obj) {
//
// Validate obj
if (!obj)
return '';
/** @type {?} */
var url = '?';
/** @type {?} */
var params = Object.keys(obj).map(function (key) {
return key + '=' + encodeURIComponent(obj[key]);
}).join('&');
return url + params;
};
UpcropDialogComponent.decorators = [
{ type: core.Component, args: [{
selector: 'upcrop-dialog',
template: "<h2 mat-dialog-title class=\"has-text-danger\">\n Upload de imagens\n <small>com corte</small>\n</h2>\n<mat-dialog-content>\n\n <!-- STEPS -->\n <div steps>\n <div steps-content fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <button mat-icon-button fxHide.xs [disabled]=\"!steps.current.previus || (steps.current.previusDisabled && steps.current.previusDisabled())\"\n (click)=\"steps.current.previusAction()\">\n <mat-icon>keyboard_arrow_left</mat-icon>\n </button>\n <span fxFlex></span>\n <h3>Passo\n <b>{{steps.current.number}}</b> de\n <b>{{steps.total}}</b> /\n <span class=\"has-text-primary\">{{steps.current.label}}</span>\n </h3>\n <span fxFlex></span>\n <button mat-icon-button fxHide.xs [disabled]=\"!steps.current.next || (steps.current.nextDisabled && steps.current.nextDisabled())\"\n (click)=\"steps.current.nextAction()\">\n <mat-icon>keyboard_arrow_right</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- STEP 1 / UPLOAD -->\n <div class=\"step-1\" [hidden]=\"steps.current.number != 1\">\n <upcrop-upload #upcropUpload [config]=\"data.uploadConfig\" (onUploadImage)=\"onUploadImage($event)\"></upcrop-upload>\n </div>\n\n <!-- STEP 2 / CROP -->\n <div class=\"step-2\" [hidden]=\"steps.current.number != 2\">\n <upcrop-crop #upcropCrop [config]=\"data.cropConfig\" (onCropImage)=\"onCropImage($event)\"></upcrop-crop>\n </div>\n</mat-dialog-content>\n<mat-dialog-actions *ngIf=\"steps.current.number == 1\">\n <button mat-button mat-dialog-close>Fechar</button>\n <button mat-button color=\"primary\" [disabled]=\"!upcropUpload.uploader.queue.length\" (click)=\"goToStep2()\">Continuar</button>\n</mat-dialog-actions>\n<mat-dialog-actions *ngIf=\"steps.current.number == 2\">\n <button mat-button (click)=\"goToStep1()\">Voltar</button>\n <button mat-button color=\"primary\" [fxHide]=\"upcropCrop.uploader?.queue?.length == (upcropCrop.currentNumber + 1)\" (click)=\"upcropCrop.goToNextCrop()\">Pr\u00F3xima imagem</button>\n <button mat-button color=\"primary\" [fxHide]=\"upcropCrop.uploader?.queue?.length > (upcropCrop.currentNumber + 1)\" [disabled]=\"upcropCrop.uploading\"\n (click)=\"finish()\">Concluir</button>\n</mat-dialog-actions>\n",
styles: ["[mat-dialog-title] small{color:#b5b5b5!important;font:400 16px/28px Roboto,\"Helvetica Neue\",sans-serif!important;margin:0 0 16px!important}[steps]{margin:0 -24px 16px;padding-top:16px;padding-bottom:16px;background-color:rgba(0,0,0,.04)}[steps] .has-text-primary{color:#3f51b5!important}[mat-dialog-title] .has-text-danger{color:#f44336!important}"]
},] },
];
/** @nocollapse */
UpcropDialogComponent.ctorParameters = function () {
return [
{ type: material.MatDialogRef },
{ type: undefined, decorators: [{ type: core.Inject, args: [material.MAT_DIALOG_DATA,] }] }
];
};
UpcropDialogComponent.propDecorators = {
upcropUpload: [{ type: core.ViewChild, args: ['upcropUpload',] }],
upcropCrop: [{ type: core.ViewChild, args: ['upcropCrop',] }]
};
return UpcropDialogComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UpcropService = (function () {
function UpcropService(dialog) {
this.dialog = dialog;
this.dialogConfig = {
width: '80%'
};
this.uploadConfig = {
url: null,
authToken: null,
autoUpload: false,
additionalParameter: {},
withCredentials: false
};
this.cropConfig = {
movable: true,
scalable: true,
zoomable: true,
viewMode: 1,
autoCrop: true,
autoCropArea: 1
};
}
/**
* @param {?=} dialogConfig
* @param {?=} uploadConfig
* @param {?=} cropConfig
* @return {?}
*/
UpcropService.prototype.open = /**
* @param {?=} dialogConfig
* @param {?=} uploadConfig
* @param {?=} cropConfig
* @return {?}
*/
function (dialogConfig, uploadConfig, cropConfig) {
var _this = this;
if (dialogConfig === void 0) {
dialogConfig = this.dialogConfig;
}
if (uploadConfig === void 0) {
uploadConfig = this.uploadConfig;
}
if (cropConfig === void 0) {
cropConfig = this.cropConfig;
}
//
// Merge config
this.uploadConfig = Object.assign(this.uploadConfig, uploadConfig);
this.cropConfig = Object.assign(this.cropConfig, cropConfig);
this.dialogConfig = Object.assign({}, this.dialogConfig, dialogConfig, {
data: {
uploadConfig: this.uploadConfig,
cropConfig: this.cropConfig
}
});
//
// Create promise to return the dialog result
return new Promise(function (resolve, reject) {
/** @type {?} */
var dialogRef = _this.dialog.open(UpcropDialogComponent, _this.dialogConfig);
//
// Subscribe to on close event
dialogRef.afterClosed().subscribe(function (result) {
//
// Validate result
if (result) {
resolve(result);
}
else {
reject();
}
});
});
};
UpcropService.decorators = [
{ type: core.Injectable },
];
/** @nocollapse */
UpcropService.ctorParameters = function () {
return [
{ type: material.MatDialog }
];
};
return UpcropService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UpcropComponent = (function () {
function UpcropComponent() {
}
/**
* @return {?}
*/
UpcropComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
};
UpcropComponent.decorators = [
{ type: core.Component, args: [{
selector: 'angular-upcrop',
template: "<p>\n upcrop works!\n</p>\n",
styles: [""]
},] },
];
/** @nocollapse */
UpcropComponent.ctorParameters = function () { return []; };
return UpcropComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UpcropCropComponent = (function () {
function UpcropCropComponent() {
this.config = {};
this.uploader = [];
this.onCropImage = new core.EventEmitter();
this.uploading = false;
this.current = false;
this.currentNumber = false;
}
/**
* @return {?}
*/
UpcropCropComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
};
/**
* Set cropping
* set cropping and everything to start crop
* @param uploader
*/
/**
* Set cropping
* set cropping and everything to start crop
* @param {?} uploader
* @return {?}
*/
UpcropCropComponent.prototype.setCropping = /**
* Set cropping
* set cropping and everything to start crop
* @param {?} uploader
* @return {?}
*/
function (uploader) {
//
// Disable cropping
this.current = false;
this.currentNumber = false;
//
// Set uploader
this.uploader = uploader;
//
// Set queue for crop
this.uploader.queue;
//
// Get next crop in the queue
this.goToNextCrop();
};
/**
* Unset cropping
*/
/**
* Unset cropping
* @return {?}
*/
UpcropCropComponent.prototype.unsetCropping = /**
* Unset cropping
* @return {?}
*/
function () {
this.angularCropper.cropper.destroy();
this.current = false;
};
/**
* Go to next crop
*/
/**
* Go to next crop
* @return {?}
*/
UpcropCropComponent.prototype.goToNextCrop = /**
* Go to next crop
* @return {?}
*/
function () {
var _this = this;
//
// Validate file
if (!this.uploader.queue.length)
return;
//
// Update counter and file
if (this.currentNumber === false) {
this.currentNumber = 0;
}
else {
this.emitOnCropImage();
//
// Unset cropping
this.unsetCropping();
//
// Update counter
this.currentNumber++;
}
//
// Get next crop in the queue
this.current = this.uploader.queue[this.currentNumber];
/** @type {?} */
var reader = new FileReader();
//
// Callback for reader.readAsDataUrl() below
reader.onloadend = function (e) {
//
// Set _dataUrl
//
// Set _dataUrl
_this.current._dataUrl = reader.result;
};
//
// Get data url
reader.readAsDataURL(this.current._file);
};
/**
* Emit on crop image
*/
/**
* Emit on crop image
* @return {?}
*/
UpcropCropComponent.prototype.emitOnCropImage = /**
* Emit on crop image
* @return {?}
*/
function () {
//
// Add image data to current file
this.onCropImage.emit({
data: this.angularCropper.cropper.getData(),
file: this.currentNumber
});
};
/**
* Zoom in
*/
/**
* Zoom in
* @return {?}
*/
UpcropCropComponent.prototype.zoomIn = /**
* Zoom in
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.zoom(0.1);
};
/**
* Zoom out
*/
/**
* Zoom out
* @return {?}
*/
UpcropCropComponent.prototype.zoomOut = /**
* Zoom out
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.zoom(-0.1);
};
/**
* Go left
*/
/**
* Go left
* @return {?}
*/
UpcropCropComponent.prototype.goLeft = /**
* Go left
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(-10, 0);
};
/**
* Go right
*/
/**
* Go right
* @return {?}
*/
UpcropCropComponent.prototype.goRight = /**
* Go right
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(10, 0);
};
/**
* Go up
*/
/**
* Go up
* @return {?}
*/
UpcropCropComponent.prototype.goUp = /**
* Go up
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(0, -10);
};
/**
* Go down
*/
/**
* Go down
* @return {?}
*/
UpcropCropComponent.prototype.goDown = /**
* Go down
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(0, 10);
};
/**
* Rotate left
*/
/**
* Rotate left
* @return {?}
*/
UpcropCropComponent.prototype.rotateLeft = /**
* Rotate left
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.rotate(-45);
};
/**
* Rotate right
*/
/**
* Rotate right
* @return {?}
*/
UpcropCropComponent.prototype.rotateRight = /**
* Rotate right
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.rotate(45);
};
/**
* Reset
*/
/**
* Reset
* @return {?}
*/
UpcropCropComponent.prototype.reset = /**
* Reset
* @return {?}
*/
function () {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.reset();
};
UpcropCropComponent.decorators = [
{ type: core.Component, args: [{
selector: 'upcrop-crop',
template: "<!-- MAIN LOAD -->\n<div class=\"crop-loading\" [fxHide]=\"!uploading\">\n <div class=\"spinner\"></div>\n</div>\n\n<div [hidden]=\"uploading\" class=\"upcrop-crop\">\n <h2 class=\"has-text-centered mat-subheading-2\">Imagem {{currentNumber + 1}} de {{uploader?.queue?.length}}</h2>\n\n <div class=\"crop-image-container\">\n <angular-cropper #angularCropper *ngIf=\"current && current._dataUrl\" [cropperOptions]=\"config\" [imageUrl]=\"current?._dataUrl\"></angular-cropper>\n </div>\n\n <!--CROPPER CONTROLS-->\n <div class=\"crop-controls\" fxLayout fxLayoutAlign=\"center center\" fxLayoutWrap *ngIf=\"current && current._dataUrl\">\n <button mat-button (click)=\"zoomIn()\" class=\"mat-icon-button\" aria-label=\"Aumentar zoom\" mdTooltip=\"Aumentar zoom\">\n <mat-icon>zoom_in</mat-icon>\n </button>\n\n <button mat-button (click)=\"zoomOut()\" class=\"mat-icon-button\" aria-label=\"Diminuir zoom\" mdTooltip=\"Diminuir zoom\">\n <mat-icon>zoom_out</mat-icon>\n </button>\n\n <button mat-button (click)=\"goLeft()\" class=\"mat-icon-button\" aria-label=\"Mover para esquerda\" mdTooltip=\"Mover para esquerda\">\n <mat-icon>keyboard_arrow_left</mat-icon>\n </button>\n\n <button mat-button (click)=\"goRight()\" class=\"mat-icon-button\" aria-label=\"Mover para direita\" mdTooltip=\"Mover para direita\">\n <mat-icon>keyboard_arrow_right</mat-icon>\n </button>\n\n <button mat-button (click)=\"goUp()\" class=\"mat-icon-button\" aria-label=\"Mover para cima\" mdTooltip=\"Mover para cima\">\n <mat-icon>keyboard_arrow_up</mat-icon>\n </button>\n\n <button mat-button (click)=\"goDown()\" class=\"mat-icon-button\" aria-label=\"Mover para baixo\" mdTooltip=\"Mover para baixo\">\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n\n <button mat-button (click)=\"reset()\" class=\"mat-icon-button mat-primary\" aria-label=\"Restaurar imagem original\" mdTooltip=\"Restaurar imagem original\">\n <mat-icon>cached</mat-icon>\n </button>\n </div>\n</div>\n",
styles: [".crop-image-container{max-height:500px;width:100%}.crop-image-container img{max-width:100%;max-height:100%}.crop-controls{padding-top:20px;padding-bottom:20px}.crop-loading{min-height:120px;padding-top:34px;margin:100px 24px;box-sizing:border-box;flex-direction:column;max-width:100%;place-content:center;align-items:center;display:flex}.crop-loading .spinner{margin-top:-20px;border:4px solid rgba(0,0,0,.06);border-top:4px solid #2196f3;border-radius:50%;width:50px;height:50px;-webkit-animation:1.1s linear infinite spin;animation:1.1s linear infinite spin}.upcrop-crop .has-text-centered{text-align:center!important}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}"]
},] },
];
/** @nocollapse */
UpcropCropComponent.ctorParameters = function () { return []; };
UpcropCropComponent.propDecorators = {
angularCropper: [{ type: core.ViewChild, args: ['angularCropper',] }],
config: [{ type: core.Input }],
uploader: [{ type: core.Input }],
onCropImage: [{ type: core.Output }]
};
return UpcropCropComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UpcropUploadComponent = (function () {
function UpcropUploadComponent() {
this.config = {};
this.uploadQueue = [];
this.onUploadQueue = new core.EventEmitter();
this.onUploadImage = new core.EventEmitter();
this.uploader = new ng2FileUpload.FileUploader({});
this.hasFileOver = false;
}
/**
* @return {?}
*/
UpcropUploadComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
//
// Set uploader
this.setUploader();
};
/**
* Set uploader
*/
/**
* Set uploader
* @return {?}
*/
UpcropUploadComponent.prototype.setUploader = /**
* Set uploader
* @return {?}
*/
function () {
var _this = this;
//
// Set uploader
this.uploader.setOptions({ url: this.config.url, authToken: this.config.authToken, autoUpload: this.config.autoUpload, additionalParameter: this.config.additionalParameter });
//
// After add file event
this.uploader.onAfterAddingFile = function (file) {
//
// Set with credentials
file.withCredentials = _this.config.withCredentials;
//
// Emit onUploadQueue
//
// Emit onUploadQueue
_this.onUploadQueue.emit({
file: file
});
};
//
// On success item event
this.uploader.onSuccessItem = function (item, response, status, headers) {
if (status == 200) {
/** @type {?} */
var data = JSON.parse(response);
//
// Emit onUploadQueue
//
// Emit onUploadQueue
_this.onUploadImage.emit({
data: data
});
}
};
};
/**
* On file over event
* @param {?} e
* @return {?}
*/
UpcropUploadComponent.prototype.onFileOver = /**
* On file over event
* @param {?} e
* @return {?}
*/
function (e) {
this.hasFileOver = e;
};
/**
* Truncate filename
* @param n
* @param len
*/
/**
* Truncate filename
* @param {?} n
* @param {?} len
* @return {?}
*/
UpcropUploadComponent.prototype.truncate = /**
* Truncate filename
* @param {?} n
* @param {?} len
* @return {?}
*/
function (n, len) {
//
// Validate
if (!n)
return n;
/** @type {?} */
var ext = n.substring(n.lastIndexOf(".") + 1, n.length).toLowerCase();
/** @type {?} */
var filename = n.replace('.' + ext, '');
if (filename.length <= len) {
return n;
}
filename = filename.substr(0, len) + (n.length > len ? '[...]' : '');
return filename + '.' + ext;
};
UpcropUploadComponent.decorators = [
{ type: core.Component, args: [{
selector: 'upcrop-upload',
template: "<label ng2FileDrop multiple class=\"my-drop-zone\" [ngClass]=\"{'nv-file-over': hasFileOver}\" (fileOver)=\"onFileOver($event)\"\n [uploader]=\"uploader\" fxLayout fxLayoutAlign=\"center center\">\n \u00C1rea de upload\n <input type=\"file\" ng2FileSelect multiple [uploader]=\"uploader\" style=\"display: none\" />\n</label>\n\n<!-- FILES -->\n<table class=\"table upcrop-upload-table\">\n <thead>\n <tr>\n <th>Preview</th>\n <th>Arquivo</th>\n <th style=\"width:30px; text-align: center\">\n <mat-icon class=\"is-pulled-right\">settings</mat-icon>\n </th>\n </tr>\n </thead>\n\n <tbody>\n <tr *ngFor=\"let item of uploader.queue\">\n <td class=\"image-preview\" style=\"width:100px\">\n <img upcropImagePreview [image]=\"item?._file\" class=\"media-object\" />\n </td>\n <td>{{ truncate(item?.file?.name, 16) }}</td>\n <td class=\"actions\" style=\"width:30px\">\n <button class=\"danger-btn\" mat-icon-button color=\"warn\" (click)=\"item.remove()\">\n <mat-icon>delete</mat-icon>\n </button>\n </td>\n </tr>\n <tr [hidden]=\"uploader.queue.length\">\n <td colspan=\"3\" class=\"has-text-danger\">\n Nenhum arquivo, adicione acima.\n </td>\n </tr>\n </tbody>\n</table>\n",
styles: [".my-drop-zone{border:2px dashed rgba(0,0,0,.04);width:100%;display:flex;padding:20px;background-color:rgba(0,0,0,.04);color:rgba(0,0,0,.7)}.nv-file-over{border:2px dashed rgba(244,67,54,.4)}[upcropImagePreview]{display:block}.upcrop-upload-table{background-color:#fff;color:#363636;border-collapse:collapse;border-spacing:0;width:100%;margin-bottom:0}.upcrop-upload-table td,.upcrop-upload-table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.upcrop-upload-table td.is-white,.upcrop-upload-table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.upcrop-upload-table td.is-black,.upcrop-upload-table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.upcrop-upload-table td.is-light,.upcrop-upload-table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.upcrop-upload-table td.is-dark,.upcrop-upload-table th.is-dark{background-color:#363636;border-color:#363636;color:#f5f5f5}.upcrop-upload-table td.is-primary,.upcrop-upload-table th.is-primary{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.upcrop-upload-table td.is-info,.upcrop-upload-table th.is-info{background-color:#3273dc;border-color:#3273dc;color:#fff}.upcrop-upload-table td.is-success,.upcrop-upload-table th.is-success{background-color:#23d160;border-color:#23d160;color:#fff}.upcrop-upload-table td.is-warning,.upcrop-upload-table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.upcrop-upload-table td.is-danger,.upcrop-upload-table th.is-danger{background-color:#ff3860;border-color:#ff3860;color:#fff}.upcrop-upload-table td.is-narrow,.upcrop-upload-table th.is-narrow{white-space:nowrap;width:1%}.upcrop-upload-table th{color:#363636;text-align:left}.upcrop-upload-table tr:hover{background-color:#fafafa}.upcrop-upload-table tr.is-selected{background-color:#00d1b2;color:#fff}.upcrop-upload-table tr.is-selected a,.upcrop-upload-table tr.is-selected strong{color:currentColor}.upcrop-upload-table tr.is-selected td,.upcrop-upload-table tr.is-selected th{border-color:#fff;color:currentColor}.upcrop-upload-table tfoot td,.upcrop-upload-table tfoot th{border-width:2px 0 0;color:#363636}.upcrop-upload-table tbody tr:last-child td,.upcrop-upload-table tbody tr:last-child th{border-bottom-width:0}.upcrop-upload-table.is-bordered td,.upcrop-upload-table.is-bordered th{border-width:1px}.upcrop-upload-table.is-bordered tr:last-child td,.upcrop-upload-table.is-bordered tr:last-child th{border-bottom-width:1px}.upcrop-upload-table.is-fullwidth{width:100%}.upcrop-upload-table.is-narrow td,.upcrop-upload-table.is-narrow th{padding:.25em .5em}.upcrop-upload-table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.upcrop-upload-table.is-striped tbody tr:not(.is-selected):nth-child(even):hover{background-color:#f5f5f5}td,th{padding:0;text-align:left}.upcrop-upload-table-search{display:flex;padding:1.3em 1.6em}.upcrop-upload-table-search input{font-size:14px;flex:1 1 100%;box-sizing:border-box;-webkit-box-flex:1;border:none;background-color:transparent;outline:-webkit-focus-ring-color auto 0!important}.upcrop-upload-table-search>mat-icon{margin-right:16px;margin-top:2px}[table-loading]{position:absolute;width:100%;margin-top:59px!important;background-color:rgba(255,255,255,.9);height:calc(100% - 59px);z-index:1}[table-no-entries]{padding:1.6em}.mat-card[has-table]{padding:0}.mat-card[has-table] .mat-card-actions{padding:8px!important;margin:0;border-top:1px solid #dbdbdb;border-color:rgba(0,0,0,.09)}.mat-card[has-table] .mat-card-actions .mat-icon-button{color:rgba(0,0,0,.54)}.mat-card[has-table] .mat-card-actions .mat-icon-button[disabled]{color:rgba(0,0,0,.18)}.mat-card[has-table] .mat-card-actions .mat-paginator-page-size-label{margin:0 15px;color:rgba(0,0,0,.54);font-size:12px;font-weight:400}.upcrop-upload-table .actions .mat-icon-button{height:30px!important;width:30px;line-height:30px;flex-direction:column;box-sizing:border-box;display:flex;max-width:100%;place-content:center;align-items:center}.upcrop-upload-table .actions .mat-icon-button .mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.upcrop-upload-table thead tr{background-color:rgba(0,0,0,.04)!important}.upcrop-upload-table thead td:first-of-type,.upcrop-upload-table thead th:first-of-type{padding-left:1.8em}.upcrop-upload-table thead td:last-of-type,.upcrop-upload-table thead th:last-of-type{padding-right:1.8em}.upcrop-upload-table thead td mat-icon,.upcrop-upload-table thead th mat-icon{height:16px;width:16px;line-height:16px;font-size:16px;vertical-align:bottom;margin-right:3px}.upcrop-upload-table tbody td,.upcrop-upload-table tbody th{border-color:rgba(0,0,0,.04)}.upcrop-upload-table tbody td:first-of-type,.upcrop-upload-table tbody th:first-of-type{padding-left:1.6em}.upcrop-upload-table tbody td:last-of-type,.upcrop-upload-table tbody th:last-of-type{padding-right:1.6em}.upcrop-upload-table thead td,.upcrop-upload-table thead th{color:rgba(0,0,0,.54);font-size:12px;font-weight:400;padding:1.3em .75em;border:0}.upcrop-upload-table tbody td{color:rgba(0,0,0,.87);padding:1em .75em;font-size:.9rem;font-weight:400}@media (max-width:800px){.upcrop-upload-table{display:inline-block;vertical-align:top;max-width:100%;overflow-x:auto;white-space:nowrap;border-collapse:collapse;border-spacing:0;display:flex;overflow:hidden;background:0 0}.upcrop-upload-table .actions a{margin-top:-.35em}.upcrop-upload-table .is-pulled-right{float:none!important}.upcrop-upload-table thead{display:flex;flex-shrink:0;min-width:-webkit-min-content;min-width:-moz-min-content;min-width:min-content}.upcrop-upload-table thead td,.upcrop-upload-table thead th{padding:1.3em 1.8em;text-align:right;width:100%!important}.upcrop-upload-table thead td mat-icon,.upcrop-upload-table thead th mat-icon{margin-right:0}.upcrop-upload-table tbody{flex:1 1 100%;box-sizing:border-box;-webkit-box-flex:1;-webkit-overflow-scrolling:touch;background:radial-gradient(left,ellipse,rgba(0,0,0,.2) 0,transparent 75%) 0 center,radial-gradient(right,ellipse,rgba(0,0,0,.2) 0,transparent 75%) 100% center;background-size:10px 100%,10px 100%;background-attachment:scroll,scroll;background-repeat:no-repeat;display:flex;position:relative;overflow-x:auto;overflow-y:hidden;margin-right:1.6em}.upcrop-upload-table tbody tr{flex:1 1 100%;box-sizing:border-box;-webkit-box-flex:1}.upcrop-upload-table tbody td,.upcrop-upload-table tbody th{padding:1.155em 1.6em;text-align:left!important}.upcrop-upload-table tbody td:first-of-type,.upcrop-upload-table tbody th:first-of-type{padding-left:1.6em}.upcrop-upload-table tbody td:last-of-type,.upcrop-upload-table tbody th:last-of-type{padding-right:1.6em}.upcrop-upload-table tr{display:flex;flex-direction:column;min-width:-webkit-min-content;min-width:-moz-min-content;min-width:min-content;flex-shrink:0}.upcrop-upload-table td,.upcrop-upload-table th{display:block;background-image:none!important;border-left:0}.upcrop-upload-table td:first-child,.upcrop-upload-table th:first-child{background-image:linear-gradient(to right,#fff 50%,rgba(255,255,255,0) 100%);background-repeat:no-repeat;background-size:20px 100%}.upcrop-upload-table td:last-child,.upcrop-upload-table th:last-child{background-image:linear-gradient(to left,#fff 50%,rgba(255,255,255,0) 100%);background-repeat:no-repeat;background-position:100% 0;background-size:20px 100%}.upcrop-upload-table td:not(:last-child),.upcrop-upload-table th:not(:last-child){border-bottom:0}}.upcrop-upload-table ::-webkit-scrollbar{height:8px;overflow:visible;width:16px}.upcrop-upload-table ::-webkit-scrollbar-button{height:0;width:0}.upcrop-upload-table ::-webkit-scrollbar-corner{background:0 0}.upcrop-upload-table ::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);background-clip:padding-box;border:solid transparent;border-width:1px 1px 1px 6px;min-height:28px;padding:100px 0 0;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07)}.upcrop-upload-table ::-webkit-scrollbar-track{background-clip:padding-box;border:solid transparent;border-width:0 0 0 4px}[enterlist] [has-table]{margin-right:-24px;margin-left:-24px}[enterlist] [has-table] .upcrop-upload-table{background-color:transparent}[enterlist] [has-table] .upcrop-upload-table thead tr{background-color:rgba(0,0,0,.02)!important}[enterlist] [has-table] .upcrop-upload-table tr:hover{background-color:inherit}.image-preview img{max-width:100%}"]
},] },
];
/** @nocollapse */
UpcropUploadComponent.ctorParameters = function () { return []; };
UpcropUploadComponent.propDecorators = {
config: [{ type: core.Input }],
uploadQueue: [{ type: core.Input }],
onUploadQueue: [{ type: core.Output }],
onUploadImage: [{ type: core.Output }]
};
return UpcropUploadComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UpcropImagePreviewDirective = (function () {
function UpcropImagePreviewDirective(el, renderer) {
this.el = el;
this.renderer = renderer;
}
/**
* Ng on changes
* Read file when image changes
* @param changes
*/
/**
* Ng on changes
* Read file when image changes
* @param {?} changes
* @return {?}
*/
UpcropImagePreviewDirective.prototype.ngOnChanges = /**
* Ng on changes
* Read file when image changes
* @param {?} changes
* @return {?}
*/
function (changes) {
/** @type {?} */
var reader = new FileReader();
/** @type {?} */
var el = this.el;
//
// On load
reader.onloadend = function (e) {
el.nativeElement.src = reader.result;
};
//
// Validate
if (this.image) {
return reader.readAsDataURL(this.image);
}
};
UpcropImagePreviewDirective.decorators = [
{ type: core.Directive, args: [{
selector: 'img[upcropImagePreview]'
},] },
];
/** @nocollapse */
UpcropImagePreviewDirective.ctorParameters = function () {
return [
{ type: core.ElementRef },
{ type: core.Renderer2 }
];
};
UpcropImagePreviewDirective.propDecorators = {
image: [{ type: core.Input }]
};
return UpcropImagePreviewDirective;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var AngularUpcropModule = (function () {
function AngularUpcropModule() {
}
AngularUpcropModule.decorators = [
{ type: core.NgModule, args: [{
imports: [
common.CommonModule,
ng2FileUpload.FileUploadModule,
flexLayout.FlexLayoutModule,
material.MatDialogModule,
material.MatIconModule,
material.MatButtonModule,
material.MatCardModule,
material.MatTooltipModule,
angularCropperjs.AngularCropperjsModule
],
declarations: [UpcropComponent, UpcropDialogComponent, UpcropCropComponent, UpcropUploadComponent, UpcropImagePreviewDirective],
exports: [UpcropComponent, UpcropDialogComponent, UpcropCropComponent, UpcropUploadComponent, UpcropImagePreviewDirective],
entryComponents: [UpcropDialogComponent]
},] },
];
return AngularUpcropModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
exports.UpcropService = UpcropService;
exports.UpcropComponent = UpcropComponent;
exports.UpcropDialogComponent = UpcropDialogComponent;
exports.UpcropCropComponent = UpcropCropComponent;
exports.UpcropUploadComponent = UpcropUploadComponent;
exports.UpcropImagePreviewDirective = UpcropImagePreviewDirective;
exports.AngularUpcropModule = AngularUpcropModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci11cGNyb3AudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9hbmd1bGFyLXVwY3JvcC9saWIvdXBjcm9wLWRpYWxvZy91cGNyb3AtZGlhbG9nLmNvbXBvbmVudC50cyIsIm5nOi8vYW5ndWxhci11cGNyb3AvbGliL3VwY3JvcC5zZXJ2aWNlLnRzIiwibmc6Ly9hbmd1bGFyLXVwY3JvcC9saWIvdXBjcm9wL3VwY3JvcC5jb21wb25lbnQudHMiLCJuZzovL2FuZ3VsYXItdXBjcm9wL2xpYi91cGNyb3AtY3JvcC91cGNyb3AtY3JvcC5jb21wb25lbnQudHMiLCJuZzovL2FuZ3VsYXItdXBjcm9wL2xpYi91cGNyb3AtdXBsb2FkL3VwY3JvcC11cGxvYWQuY29tcG9uZW50LnRzIiwibmc6Ly9hbmd1bGFyLXVwY3JvcC9saWIvdXBjcm9wLWltYWdlLXByZXZpZXcvdXBjcm9wLWltYWdlLXByZXZpZXcuZGlyZWN0aXZlLnRzIiwibmc6Ly9hbmd1bGFyLXVwY3JvcC9saWIvYW5ndWxhci11cGNyb3AubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVXBjcm9wVXBsb2FkQ29tcG9uZW50IH0gZnJvbSAnLi4vdXBjcm9wLXVwbG9hZC91cGNyb3AtdXBsb2FkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBVcGNyb3BDcm9wQ29tcG9uZW50IH0gZnJvbSAnLi4vdXBjcm9wLWNyb3AvdXBjcm9wLWNyb3AuY29tcG9uZW50JztcbmltcG9ydCB7IE1hdERpYWxvZ1JlZiwgTUFUX0RJQUxPR19EQVRBIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3VwY3JvcC1kaWFsb2cnLFxuICAgIHRlbXBsYXRlOiBgPGgyIG1hdC1kaWFsb2ctdGl0bGUgY2xhc3M9XCJoYXMtdGV4dC1kYW5nZXJcIj5cbiAgICBVcGxvYWQgZGUgaW1hZ2Vuc1xuICAgIDxzbWFsbD5jb20gY29ydGU8L3NtYWxsPlxuPC9oMj5cbjxtYXQtZGlhbG9nLWNvbnRlbnQ+XG5cbiAgICA8IS0tIFNURVBTIC0tPlxuICAgIDxkaXYgc3RlcHM+XG4gICAgICAgIDxkaXYgc3RlcHMtY29udGVudCBmeExheW91dD1cInJvd1wiIGZ4TGF5b3V0QWxpZ249XCJzdGFydCBjZW50ZXJcIj5cbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGZ4SGlkZS54cyBbZGlzYWJsZWRdPVwiIXN0ZXBzLmN1cnJlbnQucHJldml1cyB8fCAoc3RlcHMuY3VycmVudC5wcmV2aXVzRGlzYWJsZWQgJiYgc3RlcHMuY3VycmVudC5wcmV2aXVzRGlzYWJsZWQoKSlcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzdGVwcy5jdXJyZW50LnByZXZpdXNBY3Rpb24oKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd19sZWZ0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPHNwYW4gZnhGbGV4Pjwvc3Bhbj5cbiAgICAgICAgICAgIDxoMz5QYXNzb1xuICAgICAgICAgICAgICAgIDxiPnt7c3RlcHMuY3VycmVudC5udW1iZXJ9fTwvYj4gZGVcbiAgICAgICAgICAgICAgICA8Yj57e3N0ZXBzLnRvdGFsfX08L2I+IC9cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhhcy10ZXh0LXByaW1hcnlcIj57e3N0ZXBzLmN1cnJlbnQubGFiZWx9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvaDM+XG4gICAgICAgICAgICA8c3BhbiBmeEZsZXg+PC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gZnhIaWRlLnhzIFtkaXNhYmxlZF09XCIhc3RlcHMuY3VycmVudC5uZXh0IHx8IChzdGVwcy5jdXJyZW50Lm5leHREaXNhYmxlZCAmJiBzdGVwcy5jdXJyZW50Lm5leHREaXNhYmxlZCgpKVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInN0ZXBzLmN1cnJlbnQubmV4dEFjdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2Fycm93X3JpZ2h0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gU1RFUCAxIC8gVVBMT0FEIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzdGVwLTFcIiBbaGlkZGVuXT1cInN0ZXBzLmN1cnJlbnQubnVtYmVyICE9IDFcIj5cbiAgICAgICAgPHVwY3JvcC11cGxvYWQgI3VwY3JvcFVwbG9hZCBbY29uZmlnXT1cImRhdGEudXBsb2FkQ29uZmlnXCIgKG9uVXBsb2FkSW1hZ2UpPVwib25VcGxvYWRJbWFnZSgkZXZlbnQpXCI+PC91cGNyb3AtdXBsb2FkPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBTVEVQIDIgLyBDUk9QIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzdGVwLTJcIiBbaGlkZGVuXT1cInN0ZXBzLmN1cnJlbnQubnVtYmVyICE9IDJcIj5cbiAgICAgICAgPHVwY3JvcC1jcm9wICN1cGNyb3BDcm9wIFtjb25maWddPVwiZGF0YS5jcm9wQ29uZmlnXCIgKG9uQ3JvcEltYWdlKT1cIm9uQ3JvcEltYWdlKCRldmVudClcIj48L3VwY3JvcC1jcm9wPlxuICAgIDwvZGl2PlxuPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG48bWF0LWRpYWxvZy1hY3Rpb25zICpuZ0lmPVwic3RlcHMuY3VycmVudC5udW1iZXIgPT0gMVwiPlxuICAgIDxidXR0b24gbWF0LWJ1dHRvbiBtYXQtZGlhbG9nLWNsb3NlPkZlY2hhcjwvYnV0dG9uPlxuICAgIDxidXR0b24gbWF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBbZGlzYWJsZWRdPVwiIXVwY3JvcFVwbG9hZC51cGxvYWRlci5xdWV1ZS5sZW5ndGhcIiAoY2xpY2spPVwiZ29Ub1N0ZXAyKClcIj5Db250aW51YXI8L2J1dHRvbj5cbjwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuPG1hdC1kaWFsb2ctYWN0aW9ucyAqbmdJZj1cInN0ZXBzLmN1cnJlbnQubnVtYmVyID09IDJcIj5cbiAgICA8YnV0dG9uIG1hdC1idXR0b24gKGNsaWNrKT1cImdvVG9TdGVwMSgpXCI+Vm9sdGFyPC9idXR0b24+XG4gICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIFtmeEhpZGVdPVwidXBjcm9wQ3JvcC51cGxvYWRlcj8ucXVldWU/Lmxlbmd0aCA9PSAodXBjcm9wQ3JvcC5jdXJyZW50TnVtYmVyICsgMSlcIiAoY2xpY2spPVwidXBjcm9wQ3JvcC5nb1RvTmV4dENyb3AoKVwiPlByw4PCs3hpbWEgaW1hZ2VtPC9idXR0b24+XG4gICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIFtmeEhpZGVdPVwidXBjcm9wQ3JvcC51cGxvYWRlcj8ucXVldWU/Lmxlbmd0aCA+ICh1cGNyb3BDcm9wLmN1cnJlbnROdW1iZXIgKyAxKVwiIFtkaXNhYmxlZF09XCJ1cGNyb3BDcm9wLnVwbG9hZGluZ1wiXG4gICAgICAgIChjbGljayk9XCJmaW5pc2goKVwiPkNvbmNsdWlyPC9idXR0b24+XG48L21hdC1kaWFsb2ctYWN0aW9ucz5cbmAsXG4gICAgc3R5bGVzOiBbYFttYXQtZGlhbG9nLXRpdGxlXSBzbWFsbHtjb2xvcjojYjViNWI1IWltcG9ydGFudDtmb250OjQwMCAxNnB4LzI4cHggUm9ib3RvLFwiSGVsdmV0aWNhIE5ldWVcIixzYW5zLXNlcmlmIWltcG9ydGFudDttYXJnaW46MCAwIDE2cHghaW1wb3J0YW50fVtzdGVwc117bWFyZ2luOjAgLTI0cHggMTZweDtwYWRkaW5nLXRvcDoxNnB4O3BhZGRpbmctYm90dG9tOjE2cHg7YmFja2dyb3VuZC1jb2xvcjpyZ2JhKDAsMCwwLC4wNCl9W3N0ZXBzXSAuaGFzLXRleHQtcHJpbWFyeXtjb2xvcjojM2Y1MWI1IWltcG9ydGFudH1bbWF0LWRpYWxvZy10aXRsZV0gLmhhcy10ZXh0LWRhbmdlcntjb2xvcjojZjQ0MzM2IWltcG9ydGFudH1gXVxufSlcbmV4cG9ydCBjbGFzcyBVcGNyb3BEaWFsb2dDb21wb25