UNPKG

@ngx-file-upload/ui

Version:

Angular 16 file upload components for @ngx-file-upload/core

1 lines 73.9 kB
{"version":3,"file":"ngx-file-upload-ui.mjs","sources":["../../../projects/ui/src/lib/i18n/src/i18n.ts","../../../projects/ui/src/lib/toolbar/src/toolbar.ts","../../../projects/ui/src/lib/toolbar/src/toolbar.html","../../../projects/ui/src/lib/upload-item/src/upload.control.ts","../../../projects/ui/src/lib/common/src/state-to-string.pipe.ts","../../../projects/ui/src/lib/common/src/file-size.pipe.ts","../../../projects/ui/src/lib/common/src/cancelable.pipe.ts","../../../projects/ui/src/lib/upload-item/src/upload-item.ts","../../../projects/ui/src/lib/upload-item/src/upload-item.html","../../../projects/ui/src/lib/file-browser/src/file-browser.ts","../../../projects/ui/src/lib/common/src/upload-view.ts","../../../projects/ui/src/lib/common/src/upload-view.html","../../../projects/ui/src/lib/toolbar/main.ts","../../../projects/ui/src/lib/progressbar/src/ui/progressbar.ts","../../../projects/ui/src/lib/progressbar/src/ui/progressbar.html","../../../projects/ui/src/lib/progressbar/src/ui/progressbar-circle.ts","../../../projects/ui/src/lib/progressbar/src/ui/progressbar-circle.html","../../../projects/ui/src/lib/progressbar/src/progressbar.module.ts","../../../projects/ui/src/lib/file-browser/main.ts","../../../projects/ui/src/lib/common/main.ts","../../../projects/ui/src/lib/upload-item/main.ts","../../../projects/ui/src/lib/ui.module.ts","../../../projects/ui/src/public-api.ts","../../../projects/ui/src/ngx-file-upload-ui.ts"],"sourcesContent":["import { InjectionToken, Inject, Optional, Injectable } from \"@angular/core\";\r\n\r\nexport enum NgxFileUploadUiI18nKey {\r\n Common = \"common\",\r\n UploadItem = \"item\",\r\n ToolBar = \"toolbar\"\r\n}\r\n\r\ninterface Labels {\r\n [key: string]: string;\r\n}\r\n\r\nexport interface NgxFileUploadUiI18nCommon extends Labels {\r\n SELECT_FILES: string;\r\n}\r\n\r\nexport interface NgxFileUploadUiI18nToolbar extends Labels {\r\n CLEAN_UP: string;\r\n REMOVE_ALL: string;\r\n UPLOAD_ALL: string;\r\n UPLOADS: string;\r\n}\r\n\r\nexport interface NgxFileUploadUiI18nItem extends Labels {\r\n UPLOADED: string;\r\n}\r\n\r\ndeclare type NgxFileuploadI18nValue = NgxFileUploadUiI18nCommon | NgxFileUploadUiI18nItem | NgxFileUploadUiI18nToolbar | undefined;\r\n\r\n/** all labels which exists */\r\nexport interface NgxFileUploadUiI18n {\r\n [key: string]: NgxFileUploadUiI18nCommon | NgxFileUploadUiI18nItem | NgxFileUploadUiI18nToolbar | undefined;\r\n common?: NgxFileUploadUiI18nCommon;\r\n item?: NgxFileUploadUiI18nItem;\r\n toolbar?: NgxFileUploadUiI18nToolbar;\r\n}\r\n\r\n/**\r\n * injection token\r\n */\r\nexport const NGX_FILE_UPLOAD_UI_I18N = new InjectionToken<NgxFileUploadUiI18n>(\"NgxFileUpload UI I18n labels\");\r\n\r\n@Injectable({providedIn: \"root\"})\r\nexport class NgxFileUploadUiI18nProvider {\r\n\r\n private labels: NgxFileUploadUiI18n;\r\n\r\n public constructor(\r\n @Optional() @Inject(NGX_FILE_UPLOAD_UI_I18N) labels: NgxFileUploadUiI18n\r\n ) {\r\n this.labels = labels || {};\r\n }\r\n\r\n public getI18n<T extends NgxFileuploadI18nValue>(k: NgxFileUploadUiI18nKey): T {\r\n return this.labels[k.toString()] as T;\r\n }\r\n}\r\n","import { Component, OnInit, Input, OnDestroy } from \"@angular/core\";\r\nimport { Subject } from \"rxjs\";\r\nimport { takeUntil, debounceTime } from \"rxjs/operators\";\r\nimport { INgxFileUploadRequest, NgxFileUploadStorage } from \"@ngx-file-upload/core\";\r\nimport { NgxFileUploadUiI18nProvider, NgxFileUploadUiI18nKey, NgxFileUploadUiI18nToolbar } from \"../../i18n\";\r\n\r\ninterface InfoData {\r\n error: number;\r\n idle: number;\r\n pending: number;\r\n progress: number;\r\n}\r\n\r\n@Component({\r\n selector: \"ngx-file-upload-ui--toolbar\",\r\n templateUrl: \"toolbar.html\",\r\n styleUrls: [\"./toolbar.scss\"]\r\n})\r\nexport class UploadToolbarComponent implements OnInit, OnDestroy {\r\n\r\n @Input()\r\n public storage: NgxFileUploadStorage | undefined;\r\n\r\n public uploadInfo: InfoData = { error: 0, pending: 0, idle: 0, progress: 0 };\r\n\r\n public hasUploadsInList = false;\r\n\r\n public i18n: NgxFileUploadUiI18nToolbar | undefined;\r\n\r\n /**\r\n * true if we have completed or invalid uploads\r\n * in list\r\n */\r\n public isCleanable = false;\r\n\r\n /**\r\n */\r\n private destroyed$: Subject<boolean> = new Subject();\r\n\r\n public constructor(\r\n private i18nProvider: NgxFileUploadUiI18nProvider\r\n ) {}\r\n\r\n ngOnInit() {\r\n this.i18n = this.i18nProvider.getI18n<NgxFileUploadUiI18nToolbar>(NgxFileUploadUiI18nKey.ToolBar);\r\n this.registerStoreChange();\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroyed$.next(true);\r\n }\r\n\r\n /** start upload for all files */\r\n public uploadAll() {\r\n if (this.storage) {\r\n this.storage.startAll();\r\n }\r\n }\r\n\r\n /** stop all uploads */\r\n public stopAll() {\r\n if (this.storage) {\r\n this.storage.stopAll();\r\n }\r\n }\r\n\r\n /** purge uploads, invalid, completed, canceled will be removed */\r\n public cleanAll() {\r\n if (this.storage) {\r\n this.storage.purge();\r\n }\r\n }\r\n\r\n private registerStoreChange() {\r\n if (this.storage) {\r\n this.storage.change()\r\n .pipe(\r\n debounceTime(10),\r\n takeUntil(this.destroyed$)\r\n )\r\n .subscribe((uploads: INgxFileUploadRequest[]) => {\r\n this.updateInfoBar(uploads);\r\n this.isCleanable = uploads.some(upload => upload.isCompleted(true) || upload.isInvalid());\r\n this.hasUploadsInList = uploads.length > 0;\r\n });\r\n }\r\n }\r\n\r\n private updateInfoBar(uploads: INgxFileUploadRequest[]) {\r\n this.uploadInfo = uploads.reduce<InfoData>((data, upload) => {\r\n return {\r\n error : data.error + (upload.hasError() || upload.isInvalid() ? 1 : 0),\r\n idle : data.idle + (upload.isIdle() ? 1 : 0),\r\n pending : data.pending + (upload.isPending() ? 1 : 0),\r\n progress: data.progress + (upload.isProgress() ? 1 : 0)\r\n };\r\n }, {idle: 0, pending: 0, error: 0, progress: 0});\r\n }\r\n}\r\n","<div class=\"actions\">\r\n <button class=\"upload-all\" [disabled]=\"uploadInfo.idle === 0\" (click)=\"uploadAll()\">\r\n <i class=\"ngx-fileupload-icon--upload\"></i>\r\n {{i18n?.UPLOAD_ALL || \"Upload all\"}}\r\n </button>\r\n <button class=\"clean\" [disabled]=\"!isCleanable\" (click)=\"cleanAll()\">\r\n {{i18n?.CLEAN_UP || \"Clear\"}}\r\n </button>\r\n <button class=\"remove-all\" [disabled]=\"!hasUploadsInList\" (click)=\"stopAll()\">\r\n {{i18n?.REMOVE_ALL || \"Remove\"}}\r\n </button>\r\n</div>\r\n\r\n<div class=\"info\">\r\n {{ i18n?.UPLOADS || \"Uploads\" }}:\r\n <ul>\r\n <li>\r\n <i class=\"ngx-fileupload-icon--upload\"></i>\r\n <span>{{uploadInfo.progress}}</span>\r\n </li>\r\n <li>\r\n <i class=\"ngx-fileupload-icon--pending\"></i>\r\n <span>{{uploadInfo.pending}}</span>\r\n </li>\r\n <li>\r\n <i class=\"ngx-fileupload-icon--idle\"></i>\r\n <span>{{uploadInfo.idle}}</span>\r\n </li>\r\n <li>\r\n <i class=\"ngx-fileupload-icon--error\"></i>\r\n <span>{{uploadInfo.error}}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n","import { INgxFileUploadRequest, NgxFileUploadControl } from \"@ngx-file-upload/core\";\r\n\r\n/**\r\n * remote control for a single upload, will passed\r\n * by [NgxFileUploadItem]{@link ../components/NgxFileUploadItem.html} as context.ctrl\r\n * to the item template.\r\n *\r\n * @example\r\n *\r\n * <ng-template let-uploadData=\"data\" let-uploadCtrl=\"ctrl\">\r\n * <button type=\"button\" *ngIf=\"!data.hasError\" (click)=\"uploadCtrl.start($event)\">start</button>\r\n * <button type=\"button\" *ngIf=\"data.hasError\" (click)=\"uploadCtrl.retry($event)\">retry</button>\r\n * <button type=\"button\" (click)=\"uploadCtrl.cancel($event)\">cancel</button>\r\n * </ng-template>\r\n *\r\n * <ngx-file-upload-item *ngFor=\"item of uploads\" [template]=\"myItemTemplate\" [upload]=\"item\"></ngx-fileUpload-item>\r\n */\r\nexport class Control implements NgxFileUploadControl {\r\n\r\n public constructor(private upload: INgxFileUploadRequest) {}\r\n\r\n /**\r\n * if upload has been failed (http error) it has not completed\r\n * since connection can be broken or something dont has started yet.\r\n *\r\n * Give them a chance for a retry\r\n */\r\n public retry(event?: MouseEvent) {\r\n this.handleEvent(event);\r\n this.upload.retry();\r\n }\r\n\r\n /**\r\n * start single upload\r\n */\r\n public start($event?: MouseEvent) {\r\n this.handleEvent($event);\r\n this.upload.start();\r\n }\r\n\r\n /**\r\n * cancel / stop single upload\r\n */\r\n public stop($event?: MouseEvent) {\r\n this.handleEvent($event);\r\n this.upload.cancel();\r\n }\r\n\r\n public remove($event?: MouseEvent) {\r\n this.handleEvent($event);\r\n this.upload.destroy();\r\n }\r\n\r\n public removeInvalidFiles($event?: MouseEvent) {\r\n this.handleEvent($event);\r\n this.upload.removeInvalidFiles();\r\n }\r\n\r\n private handleEvent(event?: MouseEvent) {\r\n if (event && event instanceof MouseEvent) {\r\n event.stopPropagation();\r\n }\r\n }\r\n}\r\n","import { Pipe, PipeTransform } from \"@angular/core\";\r\nimport { NgxFileUploadState } from \"@ngx-file-upload/core\";\r\n\r\n/**\r\n * converts upload state to string value\r\n *\r\n * @example\r\n * <span>{{upload.state | stateToString}}</span>\r\n * // prints one of these idle, pending, progress, completed, start, invalid, canceled\r\n */\r\n@Pipe({\r\n name: \"stateToString\"\r\n})\r\nexport class StateToStringPipe implements PipeTransform {\r\n\r\n transform(state: NgxFileUploadState): string {\r\n\r\n switch (state) {\r\n case NgxFileUploadState.CANCELED: return \"canceled\";\r\n case NgxFileUploadState.PENDING: return \"pending\";\r\n case NgxFileUploadState.PROGRESS: return \"progress\";\r\n case NgxFileUploadState.COMPLETED: return \"completed\";\r\n case NgxFileUploadState.START: return \"start\";\r\n case NgxFileUploadState.INVALID: return \"invalid\";\r\n default: return \"idle\";\r\n }\r\n }\r\n}\r\n","import { Pipe, PipeTransform } from \"@angular/core\";\r\n\r\n/**\r\n * format byte value into human readable value\r\n *\r\n * @example\r\n * <span>{{1024 | fileSize}}</span>\r\n * // prints out 1Kb\r\n *\r\n */\r\n@Pipe({\r\n name: \"fileSize\"\r\n})\r\nexport class FileSizePipe implements PipeTransform {\r\n\r\n private units = [\"Byte\", \"Kb\", \"Mb\", \"Gb\"];\r\n\r\n transform(size: number): string {\r\n let bytes = isNaN(size as number) ? parseFloat(size.toString()) : size;\r\n let unit = 0;\r\n\r\n while (bytes >= 1024 && this.units.length > unit) {\r\n bytes = bytes / 1024;\r\n unit++;\r\n }\r\n\r\n /**\r\n * sets a max precision to 2, remove trailing zeros, toFixed was not working\r\n * since this will fill up number with trailing zeros.\r\n *\r\n * steps:\r\n * 1. find all until this is not a .\r\n * 2. only match . if this is not followed by 2 zeros\r\n * 3. match any number\r\n * 4. match any char which is not a zero (0,1)\r\n *\r\n * will only works with numbers which will converted to string\r\n * and not with string\r\n *\r\n * @example\r\n * 123.001 becomes 123\r\n * 123.10 becomes 123.1\r\n * 123.01 becomes 123.01\r\n * 123.01231 becomes 123.01\r\n */\r\n const formatter = /^[^\\.]+(\\.(?!0{2})\\d[^0]?)?/g;\r\n const total = bytes.toString().match(formatter)?.[0] ?? bytes.toString();\r\n return `${total} ${this.units[unit]}`;\r\n }\r\n}\r\n","import { Pipe, PipeTransform } from \"@angular/core\";\r\nimport { NgxFileUploadState } from \"@ngx-file-upload/core\";\r\n\r\n/**\r\n * returns true if an upload could be canceled\r\n * an upload could canceled if state is one of these: PENDING, START or PROGRESS\r\n *\r\n * @example\r\n * <button [disabled]=\"!(upload.data.state | isCancelAble)\">cancel</button>\r\n */\r\n@Pipe({\r\n name: \"isCancelAble\"\r\n})\r\nexport class CancelAblePipe implements PipeTransform {\r\n\r\n transform(state: NgxFileUploadState): boolean {\r\n let isCancelAble = state === NgxFileUploadState.PENDING;\r\n isCancelAble = isCancelAble || state === NgxFileUploadState.START;\r\n isCancelAble = isCancelAble || state === NgxFileUploadState.PROGRESS;\r\n return isCancelAble;\r\n }\r\n}\r\n","\r\nimport { Component, Input, ViewChild, TemplateRef, HostListener, OnDestroy, AfterViewInit, OnInit } from \"@angular/core\";\r\nimport { NgxFileUploadState, NgxFileUploadControl, INgxFileUploadRequestData, INgxFileUploadRequest } from \"@ngx-file-upload/core\";\r\nimport { Subject } from \"rxjs\";\r\nimport { takeUntil } from \"rxjs/operators\";\r\nimport { Control } from \"./upload.control\";\r\nimport { NgxFileUploadUiI18nProvider, NgxFileUploadUiI18nItem, NgxFileUploadUiI18nKey } from \"../../i18n\";\r\n\r\nexport interface FileUploadItemContext {\r\n data: INgxFileUploadRequestData;\r\n ctrl: NgxFileUploadControl;\r\n}\r\n\r\n/**\r\n * view for upload\r\n */\r\n@Component({\r\n selector: \"ngx-file-upload-ui--item\",\r\n templateUrl: \"upload-item.html\",\r\n styleUrls: [\"./upload-item.scss\"],\r\n})\r\nexport class UploadItemComponent implements AfterViewInit, OnInit, OnDestroy {\r\n\r\n public uploadState = NgxFileUploadState;\r\n\r\n /**\r\n * template context which is bound to rendered template\r\n */\r\n public context: FileUploadItemContext | undefined;\r\n\r\n /**\r\n * file upload which should bound to this view\r\n */\r\n private fileUpload: INgxFileUploadRequest | undefined;\r\n\r\n /**\r\n * save subscription here, since we have only 1 sub\r\n * i think takeUntil and Subject will be to much so we could\r\n * unsubscribe directly\r\n */\r\n private destroyed: Subject<boolean> = new Subject();\r\n\r\n public i18n: NgxFileUploadUiI18nItem | undefined;\r\n\r\n /**\r\n * set template which should be used for upload items, if no TemplateRef is passed\r\n * it will fallback to [defaultUploadItem]{@link #template}\r\n */\r\n @ViewChild(\"defaultUploadItem\", { static: true })\r\n public itemTpl: TemplateRef<FileUploadItemContext> | undefined;\r\n\r\n @Input()\r\n public set template(tpl: TemplateRef<FileUploadItemContext>) {\r\n if (tpl instanceof TemplateRef) {\r\n this.itemTpl = tpl;\r\n }\r\n }\r\n\r\n /**\r\n * sets upload we want to bind with current view\r\n */\r\n @Input()\r\n public set upload(request: INgxFileUploadRequest) {\r\n this.fileUpload = request;\r\n this.context = {\r\n data: request.data,\r\n ctrl: new Control(request)\r\n };\r\n }\r\n\r\n public constructor(\r\n private i18nProvider: NgxFileUploadUiI18nProvider\r\n ) { }\r\n\r\n /**\r\n * ensure all click events will canceled\r\n * so we dont affect anything other\r\n */\r\n @HostListener(\"click\", [\"$event\"])\r\n public onItemClick(event: MouseEvent) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n event.stopImmediatePropagation();\r\n }\r\n\r\n /**\r\n * register on upload change event to get current informations from upload\r\n * and pass to template context to render them\r\n *\r\n * @inheritdoc\r\n */\r\n ngAfterViewInit(): void {\r\n if (!this.fileUpload) {\r\n return;\r\n }\r\n\r\n this.fileUpload.change\r\n .pipe(takeUntil(this.destroyed))\r\n .subscribe((fileUpload: INgxFileUploadRequestData) => (this.context as FileUploadItemContext).data = fileUpload);\r\n }\r\n\r\n ngOnInit() {\r\n this.i18n = this.i18nProvider.getI18n<NgxFileUploadUiI18nItem>(NgxFileUploadUiI18nKey.UploadItem);\r\n }\r\n\r\n /**\r\n * if component gets destroyed remove change subscription\r\n */\r\n ngOnDestroy() {\r\n this.destroyed.next(true);\r\n }\r\n\r\n /**\r\n * just to disable sort for keyvalue pipe\r\n */\r\n public returnZero() {\r\n return 0;\r\n }\r\n}\r\n","<ng-template #defaultUploadItem let-upload=\"data\" let-ctrl=\"ctrl\">\r\n\r\n <div class=\"upload-item\">\r\n <div class=\"upload-item--header\">\r\n <span class=\"title\">\r\n {{upload.name}}\r\n </span>\r\n\r\n <!-- remove upload completly -->\r\n <button type=\"button\" class=\"action-remove item-action--remove\" (click)=\"ctrl.remove($event);\">\r\n <i class=\"ngx-fileupload-icon--remove\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"upload-item--body\">\r\n <!-- upload state icon -->\r\n <div class=\"upload-item--state\">\r\n <i [ngClass]=\"[\r\n 'ngx-fileupload-icon--' + (upload.state | stateToString),\r\n upload.state === uploadState.COMPLETED ? upload.hasError ? 'error' : 'success' : ''\r\n ]\"></i>\r\n </div>\r\n\r\n <!-- file progress: current state | progressbar -->\r\n <div class=\"upload-item--progress\">\r\n <div class=\"progressbar\">\r\n <span class=\"label-size\">{{upload.size | fileSize}}</span>\r\n <div class=\"progressbar-inner\" [ngStyle]=\"{width: upload.progress + '%'}\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- upload actions: cancel | retry -->\r\n <div class=\"upload-item--actions\">\r\n <!-- start upload action -->\r\n <button type=\"button\" class=\"item-action--upload\" (click)=\"ctrl.start($event)\"\r\n *ngIf=\"!upload.hasError && upload.state !== uploadState.CANCELED\"\r\n [disabled]=\"upload.state !== uploadState.IDLE\">\r\n <i class=\"ngx-fileupload-icon--upload\"></i>\r\n </button>\r\n\r\n <!-- retry upload action -->\r\n <button type=\"button\" class=\"item-action--reload\" (click)=\"ctrl.retry($event)\"\r\n *ngIf=\"upload.hasError || upload.state === uploadState.CANCELED\">\r\n <i class=\"ngx-fileupload-icon--reload\"></i>\r\n </button>\r\n\r\n <!-- cancel active upload -->\r\n <button type=\"button\" [disabled]=\"!(upload.state | isCancelAble)\" class=\"item-action--cancel\"\r\n (click)=\"ctrl.stop($event);\">\r\n <i class=\"ngx-fileupload-icon--cancel\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- footer to display validation / upload errors or success notes -->\r\n <div class=\"upload-item--footer\">\r\n\r\n <!-- show validation errors -->\r\n <ul *ngIf=\"upload.validationErrors\" class=\"upload-item--validation\">\r\n <button (click)=\"ctrl.removeInvalidFiles($event)\">remove invalid</button>\r\n <li *ngFor=\"let invalidFile of upload.validationErrors | keyvalue : returnZero\" class=\"message\">\r\n {{invalidFile.key}}\r\n <ul>\r\n <li *ngFor=\"let suberror of invalidFile.value | keyvalue : returnZero\" class=\"message\">\r\n {{suberror.value}}\r\n </li>\r\n </ul>\r\n </li>\r\n </ul>\r\n\r\n <ng-container *ngIf=\"upload.state === uploadState.COMPLETED\">\r\n <ul *ngIf=\"upload.response.errors\" class=\"upload-item--response-errors\">\r\n <li *ngFor=\"let error of upload.response.errors\" class=\"message error\">\r\n {{error}}\r\n </li>\r\n </ul>\r\n\r\n <p class=\"message success\" *ngIf=\"!upload.response.errors\">\r\n <ng-container *ngIf=\"upload.response.body && upload.response.body.message; else uploadSuccess\">\r\n {{upload.response.body.message}}\r\n </ng-container>\r\n <ng-template #uploadSuccess>\r\n {{upload.name}} {{i18n?.UPLOADED || \"uploaded\"}}\r\n </ng-template>\r\n </p>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- display item template at this point -->\r\n<ng-container [ngTemplateOutlet]=\"itemTpl\" [ngTemplateOutletContext]=\"context\"></ng-container>","import { Directive, HostListener, Input, Output, EventEmitter, OnDestroy, Renderer2 } from \"@angular/core\";\r\nimport { Subject } from \"rxjs\";\r\n\r\n/**\r\n * FileBrowser directive\r\n *\r\n * @todo refactor this should only notifiy if files are dropped, not add them to store or create an upload\r\n *\r\n * directive to add uploads with drag / drop\r\n *\r\n * @example\r\n *\r\n * <div [ngxFileUpload]=\"'URL'\" (add)=\"onUploadAdd($event)\"></div>\r\n * <button (click)=\"ngxFileUploadRef.upload()\">Upload</button>\r\n */\r\n@Directive({\r\n selector: \"[ngxFileUpload]\"\r\n})\r\nexport class FileBrowserDirective implements OnDestroy {\r\n\r\n /**\r\n * upload has been added\r\n *\r\n * @example\r\n *\r\n * <div [ngxFileUpload]=\"\"localhost/upload\"\" (add)=\"onUploadAdd($event)\" ></div>\r\n */\r\n @Output()\r\n public add: EventEmitter<File[]>;\r\n\r\n @Input()\r\n public disabled = false;\r\n\r\n /**\r\n * remove from subscribtions if component gets destroyed\r\n */\r\n private destroyed$: Subject<boolean> = new Subject();\r\n\r\n /**\r\n * input file field to trigger file window\r\n */\r\n private fileSelect: HTMLInputElement;\r\n\r\n /**\r\n * Creates an instance of NgxFileUploadDirective.\r\n */\r\n constructor(\r\n private renderer: Renderer2\r\n ) {\r\n this.add = new EventEmitter();\r\n this.fileSelect = this.createFieldInputField();\r\n }\r\n\r\n /**\r\n * directive gets destroyed\r\n */\r\n public ngOnDestroy() {\r\n this.destroyed$.next(true);\r\n this.destroyed$.complete();\r\n }\r\n\r\n /**\r\n * handle drag over event\r\n */\r\n @HostListener(\"dragover\", [\"$event\"])\r\n public onFileDragOver(event: DragEvent) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n }\r\n\r\n /**\r\n * handle drop event\r\n */\r\n @HostListener(\"drop\", [\"$event\"])\r\n public onFileDrop(event: DragEvent) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n if (!this.disabled && event.dataTransfer) {\r\n const files = Array.from(event.dataTransfer.files);\r\n this.add.emit(files);\r\n }\r\n }\r\n\r\n /**\r\n * add click host listener\r\n * to get notified we have a click event\r\n */\r\n @HostListener(\"click\", [\"$event\"])\r\n public onClick(event: MouseEvent) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n if (!this.disabled) {\r\n this.fileSelect.click();\r\n }\r\n }\r\n\r\n /**\r\n * create dummy input field to select files\r\n * for security reasons, we cant trigger a file select window\r\n * without it\r\n */\r\n private createFieldInputField(): HTMLInputElement {\r\n const inputField = document.createElement(\"input\");\r\n this.renderer.setAttribute(inputField, \"type\", \"file\");\r\n this.renderer.setProperty(inputField, \"multiple\", true);\r\n this.renderer.setStyle(inputField, \"display\", \"none\");\r\n this.renderer.listen(inputField, \"change\", (e) => this.onFileSelect(e));\r\n return inputField;\r\n }\r\n\r\n /**\r\n * register on change event on input[type=\"file\"] field\r\n * and create the uploads\r\n */\r\n private onFileSelect(event: Event) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n const files = Array.from(this.fileSelect.files ?? []);\r\n this.add.emit(files);\r\n\r\n /**\r\n * clear value otherwise change will not trigger again\r\n */\r\n this.fileSelect.files = null;\r\n this.fileSelect.value = '';\r\n }\r\n}\r\n","import { Component, TemplateRef, Input, OnInit, OnDestroy, Inject } from \"@angular/core\";\r\nimport { takeUntil } from \"rxjs/operators\";\r\nimport { Subject } from \"rxjs\";\r\nimport {\r\n NgxFileUploadValidator,\r\n NgxFileUploadValidationFn,\r\n NgxFileUploadOptions,\r\n NgxFileUploadFactory,\r\n NgxFileUploadStorage,\r\n NgxFileUploadHeaders,\r\n INgxFileUploadRequest\r\n} from \"@ngx-file-upload/core\";\r\nimport { FileUploadItemContext } from \"../../upload-item/src/upload-item\";\r\nimport { NgxFileUploadUiI18nProvider, NgxFileUploadUiI18nCommon, NgxFileUploadUiI18nKey } from \"../../i18n\";\r\n\r\n@Component({\r\n selector: \"ngx-file-upload\",\r\n styleUrls: [\"./upload-view.scss\"],\r\n templateUrl: \"upload-view.html\",\r\n})\r\nexport class UploadViewComponent implements OnInit, OnDestroy {\r\n\r\n /**\r\n * set custom template, will pass through to [NgxFileUploadItem]{@link NgxFileUploadItemComponent.html#itemTpl}\r\n */\r\n @Input()\r\n public itemTemplate: TemplateRef<FileUploadItemContext> | undefined;\r\n\r\n @Input()\r\n public url: string | undefined;\r\n\r\n @Input()\r\n public useFormData = true;\r\n\r\n @Input()\r\n public formDataName = \"file\";\r\n\r\n @Input()\r\n public headers: NgxFileUploadHeaders | undefined;\r\n\r\n @Input()\r\n public validator: NgxFileUploadValidator | NgxFileUploadValidationFn | undefined;\r\n\r\n @Input()\r\n public set storage(storage: NgxFileUploadStorage) {\r\n this.uploadStorage = storage;\r\n this.uploadStorageSet = true;\r\n }\r\n\r\n public uploadStorage: NgxFileUploadStorage = new NgxFileUploadStorage();\r\n\r\n public uploads: INgxFileUploadRequest[] = [];\r\n\r\n public i18n: NgxFileUploadUiI18nCommon | undefined;\r\n\r\n private destroyed$: Subject<boolean> = new Subject();\r\n\r\n private uploadStorageSet = false;\r\n\r\n public constructor(\r\n @Inject(NgxFileUploadFactory) private uploadFactory: NgxFileUploadFactory,\r\n private i18nProvider: NgxFileUploadUiI18nProvider\r\n ) {}\r\n\r\n public ngOnInit() {\r\n\r\n if (!this.url) {\r\n return;\r\n }\r\n\r\n this.i18n = this.i18nProvider.getI18n<NgxFileUploadUiI18nCommon>(NgxFileUploadUiI18nKey.Common);\r\n this.registerStoreEvents();\r\n }\r\n\r\n public ngOnDestroy() {\r\n this.destroyed$.next(true);\r\n\r\n /** we handle our own storage so destroy this one */\r\n if (!this.uploadStorageSet && this.uploadStorage) {\r\n this.uploadStorage.destroy();\r\n }\r\n }\r\n\r\n /**\r\n * files get dropped\r\n */\r\n public dropFiles(files: File[]) {\r\n if (files.length && this.url) {\r\n const uploadOptions: NgxFileUploadOptions = {\r\n url: this.url,\r\n formData: {\r\n enabled: this.useFormData,\r\n name: this.formDataName\r\n },\r\n headers: this.headers\r\n };\r\n\r\n const uploads = this.uploadFactory.createUploadRequest(files, uploadOptions, this.validator);\r\n if (uploads) {\r\n this.uploadStorage?.add(uploads);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * register events for store changes\r\n */\r\n private registerStoreEvents() {\r\n this.uploadStorage.change()\r\n .pipe( takeUntil(this.destroyed$))\r\n .subscribe({\r\n next: (uploads) => {\r\n this.uploads = uploads;\r\n }\r\n });\r\n }\r\n}\r\n","<ngx-file-upload-ui--toolbar [storage]=\"uploadStorage\"></ngx-file-upload-ui--toolbar>\r\n\r\n<div class=\"upload--body fileupload\" ngxFileUpload (add)=\"dropFiles($event)\">\r\n\r\n <div *ngIf=\"!uploads.length\" class=\"file-browser\">\r\n <i class=\"ngx-fileupload-icon--add\"></i>\r\n <span>{{ i18n?.SELECT_FILES || \"Drag/Drop files here or click\"}}</span>\r\n </div>\r\n\r\n <div *ngIf=\"uploads.length\" class=\"file-upload--list\">\r\n <ngx-file-upload-ui--item *ngFor=\"let item of uploads\" [upload]=\"item\" [template]=\"itemTemplate\" >\r\n </ngx-file-upload-ui--item>\r\n </div>\r\n</div>\r\n","import { NgModule } from \"@angular/core\";\r\n\r\nimport { UploadToolbarComponent } from \"./src/toolbar\";\r\n\r\n@NgModule({\r\n exports: [ UploadToolbarComponent ],\r\n declarations: [UploadToolbarComponent],\r\n})\r\nexport class NgxFileUploadUiToolbarModule {\r\n}\r\n","import { Component, Input, OnInit, ViewChild, ElementRef, Renderer2, NgZone } from \"@angular/core\";\r\n\r\n@Component({\r\n selector: \"ngx-file-upload-ui--progressbar\",\r\n templateUrl: \"progressbar.html\",\r\n styleUrls: [\"./progressbar.scss\"]\r\n})\r\nexport class ProgressbarComponent implements OnInit {\r\n\r\n public dashArrayCSS = `1`;\r\n\r\n @Input()\r\n public animate = true;\r\n\r\n @Input()\r\n public set duration(duration: number) {\r\n this.animationDuration = Math.max(duration, 0);\r\n }\r\n\r\n @Input()\r\n public set gap(gap: number) {\r\n this.progressbarGap = Math.max(gap, 1);\r\n }\r\n\r\n @Input()\r\n public set parts(count: number) {\r\n this.progressbarParts = Math.max(count, 1);\r\n }\r\n\r\n @Input()\r\n public set progress(progress: number) {\r\n if (progress > 0) {\r\n this.updateProgress(progress);\r\n }\r\n }\r\n\r\n private animationDuration = 250;\r\n\r\n private progressbarGap = 1;\r\n\r\n private progressBuffer: number[] = [];\r\n\r\n private isAnimated = false;\r\n\r\n private progressbarParts = 1;\r\n\r\n @ViewChild(\"progressbar\", {read: ElementRef, static: true})\r\n private progressbar: ElementRef<SVGElement> | undefined;\r\n\r\n @ViewChild(\"progressLine\", {read: ElementRef, static: true})\r\n private progressLine: ElementRef<SVGLineElement> | undefined;\r\n\r\n public constructor(\r\n private renderer: Renderer2,\r\n private zone: NgZone\r\n ) {}\r\n\r\n public ngOnInit() {\r\n const {width} = this.progressbar?.nativeElement.getBoundingClientRect() ?? { width: 0 };\r\n\r\n /** calculate dasharray */\r\n const gap = this.progressbarParts === 1 ? 0 : this.progressbarGap;\r\n const widthWithoutGap = width - (this.progressbarParts * gap);\r\n const dashArrayWidth = Math.ceil(widthWithoutGap / this.progressbarParts);\r\n\r\n this.dashArrayCSS = `${dashArrayWidth} ${gap}`;\r\n }\r\n\r\n private updateProgress(progress: number) {\r\n\r\n if (this.animate) {\r\n this.isAnimated ? this.progressBuffer.push(progress) : this.animateProgress(progress);\r\n return;\r\n }\r\n\r\n if (this.progressLine) {\r\n const el = this.progressLine.nativeElement;\r\n this.renderer.setAttribute(el, \"x2\", `${progress}%`);\r\n }\r\n }\r\n\r\n /**\r\n * animate progress\r\n *\r\n * @see https://javascript.info/js-animation\r\n */\r\n private animateProgress(progress: number) {\r\n\r\n const start = performance.now();\r\n const self = this;\r\n const el = this.progressLine?.nativeElement;\r\n\r\n if (!el) {\r\n return;\r\n }\r\n\r\n const curProgress = progress; // new progress state\r\n const oldProgress = parseInt(el.getAttribute(\"x2\") ?? '0', 10); // old progress state\r\n\r\n this.isAnimated = true;\r\n\r\n this.zone.runOutsideAngular(() => {\r\n\r\n // should add to service so we dont have to get this multiple times\r\n requestAnimationFrame(function animate(time) {\r\n\r\n // timeFraction goes from 0 to 1\r\n const timeFraction = Math.min((time - start) / self.animationDuration, 1);\r\n\r\n // const progress = 1 - Math.sin(Math.acos(timeFraction));\r\n const progressed = timeFraction;\r\n\r\n // set progressed state\r\n const progressDelta = curProgress - oldProgress;\r\n const newProgress = oldProgress + (progressed * progressDelta);\r\n self.renderer.setAttribute(el, \"x2\", `${newProgress}%`);\r\n\r\n if (timeFraction < 1) {\r\n requestAnimationFrame(animate);\r\n return;\r\n }\r\n\r\n if (self.progressBuffer.length > 0) {\r\n self.animateProgress(self.progressBuffer.shift() as number);\r\n return;\r\n }\r\n\r\n self.isAnimated = false;\r\n });\r\n });\r\n }\r\n}\r\n","<!--\r\n<div class=\"progressbar\" role=\"progressbar\" [ngStyle]=\"{'flex-basis': progressed + '%'}\"></div>\r\n-->\r\n<svg xmlns=\"http://www.w3.org/2000/svg\" #progressbar class=\"progressbar\">\r\n\r\n <line class=\"background\"\r\n x1=\"0\"\r\n y1=\"50%\"\r\n x2=\"100%\"\r\n y2=\"50%\" \r\n shape-rendering=\"crispEdges\"\r\n style=\"stroke-dashoffset: 0;\"\r\n [ngStyle]=\"{'stroke-dasharray': dashArrayCSS}\">\r\n </line>\r\n \r\n <line \r\n class=\"progress\"\r\n #progressLine\r\n x1=\"0\" \r\n x2=\"0\"\r\n y1=\"50%\"\r\n y2=\"50%\" \r\n shape-rendering=\"crispEdges\"\r\n [ngStyle]=\" {'stroke-dasharray': dashArrayCSS}\">\r\n </line>\r\n</svg>\r\n","import { Component, Input, ViewChild, ElementRef, OnInit, NgZone } from \"@angular/core\";\r\n\r\nclass ProgressbarCircleData {\r\n radius = 0;\r\n circumferences = 0;\r\n offset = 0;\r\n progress = 0;\r\n}\r\n\r\n@Component({\r\n selector: \"ngx-file-upload-ui--progressbar-circle\",\r\n templateUrl: \"progressbar-circle.html\",\r\n styleUrls: [\"./progressbar-circle.scss\"]\r\n})\r\nexport class ProgressbarCircleComponent implements OnInit {\r\n\r\n public data: ProgressbarCircleData = new ProgressbarCircleData();\r\n\r\n public dashArray = `1`;\r\n\r\n public maskId = Math.random().toString(32);\r\n\r\n private circleParts = 1;\r\n\r\n private circleGap = 1;\r\n\r\n @ViewChild(\"progressbar\", {read: ElementRef, static: true})\r\n private progressbar: ElementRef<SVGElement> | undefined;\r\n\r\n @Input()\r\n public set radius(radius: number) {\r\n this.data.radius = radius;\r\n }\r\n\r\n @Input()\r\n public set parts(parts: number) {\r\n this.circleParts = Math.max(parts, 1);\r\n }\r\n\r\n @Input()\r\n public set gap(gap: number) {\r\n this.circleGap = Math.max(gap, 1);\r\n }\r\n\r\n @Input()\r\n set progress(progressed: number) {\r\n /** calculate new offset */\r\n this.data.progress = progressed;\r\n this.updateOffset();\r\n }\r\n\r\n public constructor(\r\n private zone: NgZone\r\n ) {}\r\n\r\n public ngOnInit() {\r\n this.initializeData(performance.now());\r\n }\r\n\r\n /**\r\n * initialize data, currently we running into a problem if data comes straight\r\n * from storage, then the css properties are not set correctly but element is allready\r\n * rendered. Seems it belongs to a document fragment but not the page / parent component.\r\n *\r\n * So we need to run into an loop to ensure we have all data we need, this loop will break\r\n * after 100ms to ensure we dont run into infinite loop and take what we have.\r\n *\r\n * Neither zone.onStable nor afterViewInit are working for me here. Maybe afterViewChecked but this\r\n * will trigger multiple times.\r\n *\r\n * @todo check for better ways to solve this without loop\r\n * @todo think about second option make size and radius mandatory could be bad for responsive design but will work without loop\r\n */\r\n private initializeData(start: number, time = 0) {\r\n\r\n if (!this.progressbar) {\r\n return;\r\n }\r\n\r\n const {width, height} = this.progressbar.nativeElement.getBoundingClientRect();\r\n const sideLength = Math.min(width, height);\r\n\r\n // start work arround here, will only triggered if data comes from storage / cache\r\n if (!this.data.radius && sideLength === 0 && (time - start) / 100 < 1) {\r\n this.zone.runOutsideAngular(() => {\r\n requestAnimationFrame((ellapsed) => this.initializeData(start, ellapsed));\r\n });\r\n } else {\r\n this.data.radius = this.data.radius || this.calcRadius(sideLength) || 0;\r\n this.data.circumferences = 2 * Math.PI * this.data.radius;\r\n\r\n this.updateOffset();\r\n this.calcDashArray();\r\n }\r\n }\r\n\r\n /** calculate dasharray offset for mask */\r\n private updateOffset() {\r\n this.data.offset = ((100 - this.data.progress) / 100) * this.data.circumferences;\r\n }\r\n\r\n /**\r\n * calculate circle radius if no one is passed\r\n */\r\n private calcRadius(sideLength: number): number {\r\n\r\n if (sideLength === 0 || !this.progressbar || !this.progressbar.nativeElement) {\r\n return 0;\r\n }\r\n\r\n const svgElement: SVGElement = this.progressbar.nativeElement;\r\n const strokeProgressEl = svgElement.querySelector(\"circle.progress\");\r\n const strokeBackgroundEl = svgElement.querySelector(\"circle.progress-bar\");\r\n\r\n console.log(strokeProgressEl);\r\n console.log(strokeBackgroundEl);\r\n\r\n if (!strokeProgressEl || !strokeBackgroundEl) {\r\n return 0;\r\n }\r\n\r\n const strokeProgress = getComputedStyle(strokeProgressEl).strokeWidth;\r\n const strokeBackground = getComputedStyle(strokeBackgroundEl).strokeWidth;\r\n const strokeWidth = Math.max(parseFloat(strokeProgress), parseFloat(strokeBackground));\r\n\r\n return sideLength / 2 - (strokeWidth / 2);\r\n }\r\n\r\n private calcDashArray() {\r\n const partWidth = (this.data.circumferences / this.circleParts);\r\n const gap = this.circleParts === 1 ? 0 : partWidth - Math.floor(partWidth) + this.circleGap;\r\n this.dashArray = `${partWidth - gap} ${gap}`;\r\n }\r\n}\r\n","<svg xmlns=\"http://www.w3.org/2000/svg\" #progressbar>\r\n\r\n <circle class=\"progress-bar\"\r\n cx=\"50%\"\r\n cy=\"50%\"\r\n fill=\"transparent\"\r\n shape-rendering=\"geometricPrecision\"\r\n [attr.r]=\"data.radius\"\r\n [attr.stroke-dasharray]=\"dashArray\"\r\n [attr.mask]=\"'url(#inverted-' + maskId +')'\"></circle>\r\n\r\n <!-- progresssbar circle -->\r\n <circle class=\"progress\" \r\n cx=\"50%\"\r\n cy=\"50%\"\r\n [attr.r]=\"data.radius\"\r\n [attr.stroke-dasharray]=\"dashArray\"\r\n [attr.mask]=\"'url(#' + maskId +')'\"\r\n shape-rendering=\"geometricPrecision\"\r\n fill=\"transparent\">\r\n </circle>\r\n\r\n <!--\r\n declare masks for circles\r\n\r\n first mask show progress, second mask remove progressbar background\r\n if both circles overlap, the edges looks a bit ugly so ensure we only see one\r\n of both progressbar circles\r\n -->\r\n <defs>\r\n <mask id=\"{{maskId}}\" maskUnits=\"userSpaceOnUse\">\r\n <circle class=\"progress mask\" [ngClass]=\"data.progress > 0 ? 'animate' : ''\"\r\n shape-rendering=\"geometricPrecision\"\r\n cx=\"50%\"\r\n cy=\"50%\"\r\n [attr.r]=\"data.radius\"\r\n [attr.stroke-dasharray]=\"data.circumferences\"\r\n [attr.stroke-dashoffset]=\"data.offset\"\r\n stroke=\"white\"\r\n fill=\"black\">\r\n </circle>\r\n </mask>\r\n <mask id=\"inverted-{{maskId}}\" maskUnits=\"userSpaceOnUse\">\r\n <circle class=\"progress-bar mask\" [ngClass]=\"data.progress > 0 ? 'animate' : ''\"\r\n shape-rendering=\"geometricPrecision\"\r\n cx=\"50%\"\r\n cy=\"50%\"\r\n [attr.r]=\"data.radius\"\r\n [attr.stroke-dasharray]=\"data.circumferences\"\r\n [attr.stroke-dashoffset]=\"data.offset - data.circumferences\"\r\n fill=\"black\">\r\n </circle>\r\n </mask>\r\n </defs>\r\n</svg>\r\n\r\n<span>{{data.progress}} %</span>\r\n","import { NgModule } from \"@angular/core\";\r\nimport { CommonModule } from \"@angular/common\";\r\nimport { ProgressbarComponent } from \"./ui/progressbar\";\r\nimport { ProgressbarCircleComponent } from \"./ui/progressbar-circle\";\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule\r\n ],\r\n exports: [\r\n ProgressbarComponent,\r\n ProgressbarCircleComponent\r\n ],\r\n declarations: [\r\n ProgressbarComponent,\r\n ProgressbarCircleComponent\r\n ],\r\n providers: [],\r\n})\r\nexport class NgxFileUploadUiProgressbarModule { }\r\n","import { NgModule } from \"@angular/core\";\r\nimport { FileBrowserDirective } from \"./src/file-browser\";\r\n\r\n@NgModule({\r\n imports: [],\r\n exports: [FileBrowserDirective],\r\n declarations: [FileBrowserDirective],\r\n providers: [],\r\n})\r\nexport class NgxFileUploadUiFileBrowserModule { }\r\n","export * from \"./src/upload-view\";\r\n\r\nimport { NgModule } from \"@angular/core\";\r\nimport { CancelAblePipe } from \"./src/cancelable.pipe\";\r\nimport { FileSizePipe } from \"./src/file-size.pipe\";\r\nimport { StateToStringPipe } from \"./src/state-to-string.pipe\";\r\n\r\n@NgModule({\r\n imports: [],\r\n exports: [\r\n StateToStringPipe,\r\n FileSizePipe,\r\n CancelAblePipe\r\n ],\r\n declarations: [\r\n StateToStringPipe,\r\n FileSizePipe,\r\n CancelAblePipe\r\n ],\r\n providers: [],\r\n})\r\nexport class NgxFileUploadUiCommonModule { }\r\n","import { NgModule } from \"@angular/core\";\r\nimport { CommonModule } from \"@angular/common\";\r\nimport { NgxFileUploadUiCommonModule } from \"../common/main\";\r\nimport { UploadItemComponent } from \"./src/upload-item\";\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n NgxFileUploadUiCommonModule\r\n ],\r\n exports: [UploadItemComponent],\r\n declarations: [UploadItemComponent],\r\n providers: [],\r\n})\r\nexport class NgxFileUploadUiItemModule { }\r\n","import { NgModule } from \"@angular/core\";\r\nimport { CommonModule } from \"@angular/common\";\r\n\r\nimport { UploadViewComponent } from \"./common/src/upload-view\";\r\n\r\nimport { NgxFileUploadUiToolbarModule } from \"./toolbar/main\";\r\nimport { NgxFileUploadUiProgressbarModule } from \"./progressbar/main\";\r\nimport { NgxFileUploadUiFileBrowserModule } from \"./file-browser/main\";\r\nimport { NgxFileUploadUiItemModule } from \"./upload-item/main\";\r\nimport { NgxFileUploadUiCommonModule } from \"./common/main\";\r\n\r\n@NgModule({\r\n declarations: [\r\n UploadViewComponent,\r\n ],\r\n imports: [\r\n CommonModule,\r\n NgxFileUploadUiProgressbarModule,\r\n NgxFileUploadUiCommonModule,\r\n NgxFileUploadUiToolbarModule,\r\n NgxFileUploadUiItemModule,\r\n NgxFileUploadUiFileBrowserModule\r\n ],\r\n exports: [\r\n NgxFileUploadUiCommonModule,\r\n NgxFileUploadUiProgressbarModule,\r\n NgxFileUploadUiCommonModule,\r\n NgxFileUploadUiToolbarModule,\r\n NgxFileUploadUiItemModule,\r\n NgxFileUploadUiFileBrowserModule,\r\n UploadViewComponent,\r\n ]\r\n})\r\nexport class NgxFileUploadUiModule {}\r\n","/*\r\n * Public API Surface of @ngx-file-upload/ui\r\n */\r\nexport * from \"./lib/ui.module\";\r\n\r\nexport * from \"./lib/common/main\";\r\nexport * from \"./lib/file-browser/main\";\r\nexport * from \"./lib/file-browser/src/file-browser\";\r\n\r\nexport * from \"./lib/progressbar/main\";\r\nexport * from \"./lib/progressbar/src/ui/progressbar\";\r\nexport * from \"./lib/progressbar/src/ui/progressbar-circle\";\r\n\r\nexport * from \"./lib/toolbar/main\";\r\nexport * from \"./lib/toolbar/src/toolbar\";\r\n\r\nexport * from \"./lib/upload-item/main\";\r\nexport * from \"./lib/upload-item/src/upload-item\";\r\nexport * from \"./lib/upload-item/src/upload.control\";\r\n\r\nexport * from \"./lib/common/src/cancelable.pipe\"\r\nexport * from \"./lib/common/src/file-size.pipe\"\r\nexport * from \"./lib/common/src/state-to-string.pipe\"\r\n\r\nexport { NgxFileUploadUiI18n, NGX_FILE_UPLOAD_UI_I18N } from \"./lib/i18n\";\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.NgxFileUploadUiI18nProvider","i3.StateToStringPipe","i4.FileSizePipe","i5.CancelAblePipe","i3.UploadToolbarComponent","i4.UploadItemComponent","i5.FileBrowserDirective","i1"],"mappings":"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