UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

55 lines 14.2 kB
import { Component, Output } from '@angular/core'; import { EventEmitter } from '@angular/core'; import { AlertService, GainsightService, FilesService, gettext } from '@c8y/ngx-components'; import { PRODUCT_EXPERIENCE_FILE_REPOSITORY } from './files-repository-product-experience.constants'; import { combineLatest } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; export class FilesRepositoryUploadComponent { constructor(alertService, gainsightService, filesService) { this.alertService = alertService; this.gainsightService = gainsightService; this.filesService = filesService; /** Emits an event when modal is closed. `uploaded` indicates if any files were uploaded. */ this.onClose = new EventEmitter(); this.isLoading = false; this.dropFilesHereMessage = gettext('Drop files here'); } async upload() { this.isLoading = true; this.uploadProgress$ = combineLatest(this.filesToUpload.map(file => this.filesService.uploadFileWithProgress$(file))); this.uploadSubscription = this.uploadProgress$.subscribe(uploadProgress => { this.uploadProgress = uploadProgress; }, e => { if (e) { this.alertService.addServerFailure(e); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_FILE_REPOSITORY.EVENTS.FILE_REPOSITORY_UPLOAD, { component: PRODUCT_EXPERIENCE_FILE_REPOSITORY.COMPONENTS.FILE_REPOSITORY_UPLOAD_COMPONENT, action: PRODUCT_EXPERIENCE_FILE_REPOSITORY.RESULTS.UPLOAD_ITEM_FAILED }); } this.isLoading = false; }, () => { this.alertService.success(gettext('File(s) uploaded.')); this.onClose.emit({ uploaded: true }); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_FILE_REPOSITORY.EVENTS.FILE_REPOSITORY_UPLOAD, { component: PRODUCT_EXPERIENCE_FILE_REPOSITORY.COMPONENTS.FILE_REPOSITORY_UPLOAD_COMPONENT, action: PRODUCT_EXPERIENCE_FILE_REPOSITORY.RESULTS.UPLOAD_ITEM_SUCCESS }); }); } onFileDroppedEvent(event) { if (event && event.length > 0) { this.filesToUpload = event; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilesRepositoryUploadComponent, deps: [{ token: i1.AlertService }, { token: i1.GainsightService }, { token: i1.FilesService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FilesRepositoryUploadComponent, selector: "c8y-files-repository-upload", outputs: { onClose: "onClose" }, ngImport: i0, template: "<div class=\"c8y-viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"upload\"></i>\n <h4\n id=\"modal-title\"\n translate\n >\n Upload files\n </h4>\n </div>\n <div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n id=\"modal-body\"\n >\n <c8y-file-picker-form-control\n #filePicker\n [uploadInProgress]=\"isLoading\"\n (dropped)=\"onFileDroppedEvent($event)\"\n [uploadProgress]=\"uploadProgress\"\n ></c8y-file-picker-form-control>\n </div>\n </div>\n <div class=\"card-footer separator d-flex j-c-center\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"onClose.emit({ uploaded: false })\"\n [disabled]=\"isLoading\"\n translate\n >\n Cancel\n </button>\n <button\n class=\"btn btn-primary btn-form\"\n title=\"{{ 'Upload' | translate }}\"\n type=\"button\"\n (click)=\"upload()\"\n [disabled]=\"!filePicker.valid || isLoading\"\n translate\n data-cy=\"c8y-files-repository-upload--upload\"\n >\n Upload\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i1.FilePickerFormControlComponent, selector: "c8y-file-picker-form-control", inputs: ["accept", "maxAllowedFiles", "minRequiredFiles", "disableValidators", "uploadInProgress", "uploadProgress", "validateExtensionOnDrag"], outputs: ["dropped"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilesRepositoryUploadComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-files-repository-upload', template: "<div class=\"c8y-viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"upload\"></i>\n <h4\n id=\"modal-title\"\n translate\n >\n Upload files\n </h4>\n </div>\n <div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n id=\"modal-body\"\n >\n <c8y-file-picker-form-control\n #filePicker\n [uploadInProgress]=\"isLoading\"\n (dropped)=\"onFileDroppedEvent($event)\"\n [uploadProgress]=\"uploadProgress\"\n ></c8y-file-picker-form-control>\n </div>\n </div>\n <div class=\"card-footer separator d-flex j-c-center\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"onClose.emit({ uploaded: false })\"\n [disabled]=\"isLoading\"\n translate\n >\n Cancel\n </button>\n <button\n class=\"btn btn-primary btn-form\"\n title=\"{{ 'Upload' | translate }}\"\n type=\"button\"\n (click)=\"upload()\"\n [disabled]=\"!filePicker.valid || isLoading\"\n translate\n data-cy=\"c8y-files-repository-upload--upload\"\n >\n Upload\n </button>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.AlertService }, { type: i1.GainsightService }, { type: i1.FilesService }], propDecorators: { onClose: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXMtcmVwb3NpdG9yeS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZmlsZXMtcmVwb3NpdG9yeS9maWxlcy1yZXBvc2l0b3J5LXVwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9maWxlcy1yZXBvc2l0b3J5L2ZpbGVzLXJlcG9zaXRvcnktdXBsb2FkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0MsT0FBTyxFQUNMLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLE9BQU8sRUFFUixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxrQ0FBa0MsRUFBRSxNQUFNLGlEQUFpRCxDQUFDO0FBQ3JHLE9BQU8sRUFBNEIsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7QUFNL0QsTUFBTSxPQUFPLDhCQUE4QjtJQVV6QyxZQUNVLFlBQTBCLEVBQzFCLGdCQUFrQyxFQUNsQyxZQUEwQjtRQUYxQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBWnBDLDRGQUE0RjtRQUNsRixZQUFPLEdBQXdDLElBQUksWUFBWSxFQUFFLENBQUM7UUFDNUUsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQix5QkFBb0IsR0FBVyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQVV2RCxDQUFDO0lBRUosS0FBSyxDQUFDLE1BQU07UUFDVixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsZUFBZSxHQUFHLGFBQWEsQ0FDbEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFDLENBQ2hGLENBQUM7UUFFRixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQ3RELGNBQWMsQ0FBQyxFQUFFO1lBQ2YsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFDdkMsQ0FBQyxFQUNELENBQUMsQ0FBQyxFQUFFO1lBQ0YsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDTixJQUFJLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUNoQyxrQ0FBa0MsQ0FBQyxNQUFNLENBQUMsc0JBQXNCLEVBQ2hFO29CQUNFLFNBQVMsRUFDUCxrQ0FBa0MsQ0FBQyxVQUFVLENBQUMsZ0NBQWdDO29CQUNoRixNQUFNLEVBQUUsa0NBQWtDLENBQUMsT0FBTyxDQUFDLGtCQUFrQjtpQkFDdEUsQ0FDRixDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLENBQUMsRUFDRCxHQUFHLEVBQUU7WUFDSCxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDdEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FDaEMsa0NBQWtDLENBQUMsTUFBTSxDQUFDLHNCQUFzQixFQUNoRTtnQkFDRSxTQUFTLEVBQ1Asa0NBQWtDLENBQUMsVUFBVSxDQUFDLGdDQUFnQztnQkFDaEYsTUFBTSxFQUFFLGtDQUFrQyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUI7YUFDdkUsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsa0JBQWtCLENBQUMsS0FBYTtRQUM5QixJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7SUFDSCxDQUFDOytHQTNEVSw4QkFBOEI7bUdBQTlCLDhCQUE4QixvR0NoQjNDLG9zQ0ErQ0E7OzRGRC9CYSw4QkFBOEI7a0JBSjFDLFNBQVM7K0JBQ0UsNkJBQTZCOzJJQUs3QixPQUFPO3NCQUFoQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQWxlcnRTZXJ2aWNlLFxuICBHYWluc2lnaHRTZXJ2aWNlLFxuICBGaWxlc1NlcnZpY2UsXG4gIGdldHRleHQsXG4gIElGZXRjaFdpdGhQcm9ncmVzc1xufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IFBST0RVQ1RfRVhQRVJJRU5DRV9GSUxFX1JFUE9TSVRPUlkgfSBmcm9tICcuL2ZpbGVzLXJlcG9zaXRvcnktcHJvZHVjdC1leHBlcmllbmNlLmNvbnN0YW50cyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24sIGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWZpbGVzLXJlcG9zaXRvcnktdXBsb2FkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZpbGVzLXJlcG9zaXRvcnktdXBsb2FkLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBGaWxlc1JlcG9zaXRvcnlVcGxvYWRDb21wb25lbnQge1xuICAvKiogRW1pdHMgYW4gZXZlbnQgd2hlbiBtb2RhbCBpcyBjbG9zZWQuIGB1cGxvYWRlZGAgaW5kaWNhdGVzIGlmIGFueSBmaWxlcyB3ZXJlIHVwbG9hZGVkLiAqL1xuICBAT3V0cHV0KCkgb25DbG9zZTogRXZlbnRFbWl0dGVyPHsgdXBsb2FkZWQ6IGJvb2xlYW4gfT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIGlzTG9hZGluZyA9IGZhbHNlO1xuICBkcm9wRmlsZXNIZXJlTWVzc2FnZTogc3RyaW5nID0gZ2V0dGV4dCgnRHJvcCBmaWxlcyBoZXJlJyk7XG4gIGZpbGVzVG9VcGxvYWQ6IEZpbGVbXTtcbiAgdXBsb2FkUHJvZ3Jlc3M6IElGZXRjaFdpdGhQcm9ncmVzc1tdO1xuICB1cGxvYWRQcm9ncmVzcyQ6IE9ic2VydmFibGU8SUZldGNoV2l0aFByb2dyZXNzW10+O1xuICB1cGxvYWRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFsZXJ0U2VydmljZTogQWxlcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ2FpbnNpZ2h0U2VydmljZTogR2FpbnNpZ2h0U2VydmljZSxcbiAgICBwcml2YXRlIGZpbGVzU2VydmljZTogRmlsZXNTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyB1cGxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMudXBsb2FkUHJvZ3Jlc3MkID0gY29tYmluZUxhdGVzdChcbiAgICAgIHRoaXMuZmlsZXNUb1VwbG9hZC5tYXAoZmlsZSA9PiB0aGlzLmZpbGVzU2VydmljZS51cGxvYWRGaWxlV2l0aFByb2dyZXNzJChmaWxlKSlcbiAgICApO1xuXG4gICAgdGhpcy51cGxvYWRTdWJzY3JpcHRpb24gPSB0aGlzLnVwbG9hZFByb2dyZXNzJC5zdWJzY3JpYmUoXG4gICAgICB1cGxvYWRQcm9ncmVzcyA9PiB7XG4gICAgICAgIHRoaXMudXBsb2FkUHJvZ3Jlc3MgPSB1cGxvYWRQcm9ncmVzcztcbiAgICAgIH0sXG4gICAgICBlID0+IHtcbiAgICAgICAgaWYgKGUpIHtcbiAgICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGUpO1xuICAgICAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmlnZ2VyRXZlbnQoXG4gICAgICAgICAgICBQUk9EVUNUX0VYUEVSSUVOQ0VfRklMRV9SRVBPU0lUT1JZLkVWRU5UUy5GSUxFX1JFUE9TSVRPUllfVVBMT0FELFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb21wb25lbnQ6XG4gICAgICAgICAgICAgICAgUFJPRFVDVF9FWFBFUklFTkNFX0ZJTEVfUkVQT1NJVE9SWS5DT01QT05FTlRTLkZJTEVfUkVQT1NJVE9SWV9VUExPQURfQ09NUE9ORU5ULFxuICAgICAgICAgICAgICBhY3Rpb246IFBST0RVQ1RfRVhQRVJJRU5DRV9GSUxFX1JFUE9TSVRPUlkuUkVTVUxUUy5VUExPQURfSVRFTV9GQUlMRURcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5zdWNjZXNzKGdldHRleHQoJ0ZpbGUocykgdXBsb2FkZWQuJykpO1xuICAgICAgICB0aGlzLm9uQ2xvc2UuZW1pdCh7IHVwbG9hZGVkOiB0cnVlIH0pO1xuICAgICAgICB0aGlzLmdhaW5zaWdodFNlcnZpY2UudHJpZ2dlckV2ZW50KFxuICAgICAgICAgIFBST0RVQ1RfRVhQRVJJRU5DRV9GSUxFX1JFUE9TSVRPUlkuRVZFTlRTLkZJTEVfUkVQT1NJVE9SWV9VUExPQUQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgY29tcG9uZW50OlxuICAgICAgICAgICAgICBQUk9EVUNUX0VYUEVSSUVOQ0VfRklMRV9SRVBPU0lUT1JZLkNPTVBPTkVOVFMuRklMRV9SRVBPU0lUT1JZX1VQTE9BRF9DT01QT05FTlQsXG4gICAgICAgICAgICBhY3Rpb246IFBST0RVQ1RfRVhQRVJJRU5DRV9GSUxFX1JFUE9TSVRPUlkuUkVTVUxUUy5VUExPQURfSVRFTV9TVUNDRVNTXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBvbkZpbGVEcm9wcGVkRXZlbnQoZXZlbnQ6IEZpbGVbXSk6IHZvaWQge1xuICAgIGlmIChldmVudCAmJiBldmVudC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmZpbGVzVG9VcGxvYWQgPSBldmVudDtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjOHktdmlld3BvcnQtbW9kYWxcIj5cbiAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlciBkaWFsb2ctaGVhZGVyXCI+XG4gICAgPGkgYzh5SWNvbj1cInVwbG9hZFwiPjwvaT5cbiAgICA8aDRcbiAgICAgIGlkPVwibW9kYWwtdGl0bGVcIlxuICAgICAgdHJhbnNsYXRlXG4gICAgPlxuICAgICAgVXBsb2FkIGZpbGVzXG4gICAgPC9oND5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1pbm5lci1zY3JvbGxcIj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cIm1vZGFsLWJvZHlcIlxuICAgICAgaWQ9XCJtb2RhbC1ib2R5XCJcbiAgICA+XG4gICAgICA8Yzh5LWZpbGUtcGlja2VyLWZvcm0tY29udHJvbFxuICAgICAgICAjZmlsZVBpY2tlclxuICAgICAgICBbdXBsb2FkSW5Qcm9ncmVzc109XCJpc0xvYWRpbmdcIlxuICAgICAgICAoZHJvcHBlZCk9XCJvbkZpbGVEcm9wcGVkRXZlbnQoJGV2ZW50KVwiXG4gICAgICAgIFt1cGxvYWRQcm9ncmVzc109XCJ1cGxvYWRQcm9ncmVzc1wiXG4gICAgICA+PC9jOHktZmlsZS1waWNrZXItZm9ybS1jb250cm9sPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtZm9vdGVyIHNlcGFyYXRvciBkLWZsZXggai1jLWNlbnRlclwiPlxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICAgIHRpdGxlPVwie3sgJ0NhbmNlbCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAoY2xpY2spPVwib25DbG9zZS5lbWl0KHsgdXBsb2FkZWQ6IGZhbHNlIH0pXCJcbiAgICAgIFtkaXNhYmxlZF09XCJpc0xvYWRpbmdcIlxuICAgICAgdHJhbnNsYXRlXG4gICAgPlxuICAgICAgQ2FuY2VsXG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgYnRuLWZvcm1cIlxuICAgICAgdGl0bGU9XCJ7eyAnVXBsb2FkJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIChjbGljayk9XCJ1cGxvYWQoKVwiXG4gICAgICBbZGlzYWJsZWRdPVwiIWZpbGVQaWNrZXIudmFsaWQgfHwgaXNMb2FkaW5nXCJcbiAgICAgIHRyYW5zbGF0ZVxuICAgICAgZGF0YS1jeT1cImM4eS1maWxlcy1yZXBvc2l0b3J5LXVwbG9hZC0tdXBsb2FkXCJcbiAgICA+XG4gICAgICBVcGxvYWRcbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==