UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

121 lines 20.9 kB
import { Component, forwardRef, Input } from '@angular/core'; import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { StaticAssetsModalService } from '../static-assets-modal.service'; import { StaticAssetsService } from '@c8y/ngx-components/static-assets/data'; import { CoreModule } from '@c8y/ngx-components'; import * as i0 from "@angular/core"; import * as i1 from "../static-assets-modal.service"; import * as i2 from "@c8y/ngx-components/static-assets/data"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "@angular/common"; import * as i5 from "ngx-bootstrap/tooltip"; export class StaticAssetsFilePickerComponent { constructor(staticAssetsModal, staticAssets) { this.staticAssetsModal = staticAssetsModal; this.staticAssets = staticAssets; this.isCSSURL = false; this.staticAssetType = 'branding'; this.supportedFileExtensions = []; this.layout = 'grid'; this.size = 48; this.loading = false; this.currentFile = undefined; } writeValue(value) { if (/^url\('.*'\)$/.test(value)) { value = value.replace(/^url\('/, '').replace(/'\)$/, ''); } if (/^url\(.*\)$/.test(value)) { value = value.replace(/^url\(/, '').replace(/\)$/, ''); } this.currentValue = value; this.loadFileDetails(value); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } async loadFileDetails(currentUrl) { if (!currentUrl) { this.currentFile = undefined; return; } this.loading = true; try { const fileList = await this.staticAssets.listFilesCached(this.staticAssetType); const foundFile = fileList.find(file => currentUrl.includes(file.path)); this.currentFile = foundFile; if (!foundFile) { const filePresent = await this.ensureFileExists(currentUrl); if (filePresent) { this.currentFile = { path: currentUrl, fileName: currentUrl.split('/').pop(), originalFileName: currentUrl.split('/').pop() }; } } } catch (e) { } this.loading = false; } clear() { this.onChange(''); this.currentFile = undefined; this.currentValue = ''; this.onTouched(); } async openFilePicker() { try { const res = await this.staticAssetsModal.pickStaticAsset({ layout: this.layout, assetType: this.staticAssetType, supportedFileExtensions: this.supportedFileExtensions }); const value = this.isCSSURL ? `url(${res.path})` : res.path; this.onChange(value); this.currentFile = res; this.currentValue = value; this.onTouched(); } catch (e) { // modal closed } } async ensureFileExists(url) { const response = await fetch(url); return response.status === 200; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StaticAssetsFilePickerComponent, deps: [{ token: i1.StaticAssetsModalService }, { token: i2.StaticAssetsService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StaticAssetsFilePickerComponent, isStandalone: true, selector: "c8y-static-assets-file-picker", inputs: { isCSSURL: "isCSSURL", staticAssetType: "staticAssetType", supportedFileExtensions: "supportedFileExtensions", layout: "layout", size: "size" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StaticAssetsFilePickerComponent), multi: true } ], ngImport: i0, template: "\n<div class=\"d-flex a-i-center gap-8\">\n <div *ngIf=\"!currentValue else fileSelected\" class=\"d-contents\">\n <i c8yIcon=\"no-image\" class=\"icon-48 text-muted\"></i>\n <p class=\"m-r-auto text-muted\"><em translate>No file selected.</em></p>\n </div>\n\n <ng-template #fileSelected>\n <c8y-loading *ngIf=\"loading\"></c8y-loading>\n <div *ngIf=\"!loading && !currentFile\">\n <p translate>Unable to locate file: \"{{ currentValue }}\"</p>\n </div>\n\n <div *ngIf=\"!loading && currentFile\" style=\"min-height: 48px\" class=\"d-flex a-i-center\">\n <img *ngIf=\"currentFile\" [src]=\"currentFile.path\" class=\"img-responsive\" [ngStyle]=\"{'width.px': size}\" alt=\"{{currentFile?.fileName }}\">\n </div>\n <span class=\"text-truncate\" title=\"{{ currentFile?.fileName || currentValue }}\">{{ currentFile?.fileName || currentValue }}</span>\n <button class=\" m-l-auto btn btn-dot btn-dot--danger\"\n type=\"button\" (click)=\"clear()\"\n [delay]=\"500\"\n [attr.aria-label]=\"'Remove' | translate\"\n placement=\"top\"\n tooltip=\"{{'Remove' | translate}}\">\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </ng-template>\n\n <button (click)=\"openFilePicker()\" class=\"btn btn-default btn-sm\">\n <span *ngIf=\"!currentFile\">\n {{'Select' | translate}}\n </span>\n <span *ngIf=\"currentFile\">\n {{'Replace' | translate}}\n </span>\n </button>\n</div>\n\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StaticAssetsFilePickerComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-static-assets-file-picker', standalone: true, imports: [CoreModule, TooltipModule], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StaticAssetsFilePickerComponent), multi: true } ], template: "\n<div class=\"d-flex a-i-center gap-8\">\n <div *ngIf=\"!currentValue else fileSelected\" class=\"d-contents\">\n <i c8yIcon=\"no-image\" class=\"icon-48 text-muted\"></i>\n <p class=\"m-r-auto text-muted\"><em translate>No file selected.</em></p>\n </div>\n\n <ng-template #fileSelected>\n <c8y-loading *ngIf=\"loading\"></c8y-loading>\n <div *ngIf=\"!loading && !currentFile\">\n <p translate>Unable to locate file: \"{{ currentValue }}\"</p>\n </div>\n\n <div *ngIf=\"!loading && currentFile\" style=\"min-height: 48px\" class=\"d-flex a-i-center\">\n <img *ngIf=\"currentFile\" [src]=\"currentFile.path\" class=\"img-responsive\" [ngStyle]=\"{'width.px': size}\" alt=\"{{currentFile?.fileName }}\">\n </div>\n <span class=\"text-truncate\" title=\"{{ currentFile?.fileName || currentValue }}\">{{ currentFile?.fileName || currentValue }}</span>\n <button class=\" m-l-auto btn btn-dot btn-dot--danger\"\n type=\"button\" (click)=\"clear()\"\n [delay]=\"500\"\n [attr.aria-label]=\"'Remove' | translate\"\n placement=\"top\"\n tooltip=\"{{'Remove' | translate}}\">\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </ng-template>\n\n <button (click)=\"openFilePicker()\" class=\"btn btn-default btn-sm\">\n <span *ngIf=\"!currentFile\">\n {{'Select' | translate}}\n </span>\n <span *ngIf=\"currentFile\">\n {{'Replace' | translate}}\n </span>\n </button>\n</div>\n\n" }] }], ctorParameters: () => [{ type: i1.StaticAssetsModalService }, { type: i2.StaticAssetsService }], propDecorators: { isCSSURL: [{ type: Input }], staticAssetType: [{ type: Input }], supportedFileExtensions: [{ type: Input }], layout: [{ type: Input }], size: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLWFzc2V0cy1maWxlLXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zdGF0aWMtYXNzZXRzL3N0YXRpYy1hc3NldHMtZmlsZS1waWNrZXIvc3RhdGljLWFzc2V0cy1maWxlLXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zdGF0aWMtYXNzZXRzL3N0YXRpYy1hc3NldHMtZmlsZS1waWNrZXIvc3RhdGljLWFzc2V0cy1maWxlLXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RELE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMxRSxPQUFPLEVBQWUsbUJBQW1CLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMxRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7Ozs7Ozs7QUFnQmpELE1BQU0sT0FBTywrQkFBK0I7SUFhMUMsWUFDVSxpQkFBMkMsRUFDM0MsWUFBaUM7UUFEakMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUEwQjtRQUMzQyxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFkbEMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixvQkFBZSxHQUE0QyxVQUFVLENBQUM7UUFDdEUsNEJBQXVCLEdBQTBELEVBQUUsQ0FBQztRQUNwRixXQUFNLEdBQXlDLE1BQU0sQ0FBQztRQUN0RCxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ25CLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsZ0JBQVcsR0FBNEIsU0FBUyxDQUFDO0lBUzlDLENB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O3NCQUFaLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGZvcndhcmRSZWYsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC90b29sdGlwJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN0YXRpY0Fzc2V0c01vZGFsU2VydmljZSB9IGZyb20gJy4uL3N0YXRpYy1hc3NldHMtbW9kYWwuc2VydmljZSc7XG5pbXBvcnQgeyBTdGF0aWNBc3NldCwgU3RhdGljQXNzZXRzU2VydmljZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvc3RhdGljLWFzc2V0cy9kYXRhJztcbmltcG9ydCB7IENvcmVNb2R1bGUgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB0eXBlIHsgU3RhdGljQXNzZXRzTW9kYWxDb21wb25lbnQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL3N0YXRpYy1hc3NldHMvbW9kYWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktc3RhdGljLWFzc2V0cy1maWxlLXBpY2tlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdGF0aWMtYXNzZXRzLWZpbGUtcGlja2VyLmNvbXBvbmVudC5odG1sJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvcmVNb2R1bGUsIFRvb2x0aXBNb2R1bGVdLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFN0YXRpY0Fzc2V0c0ZpbGVQaWNrZXJDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgU3RhdGljQXNzZXRzRmlsZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgQElucHV0KCkgaXNDU1NVUkwgPSBmYWxzZTtcbiAgQElucHV0KCkgc3RhdGljQXNzZXRUeXBlOiBTdGF0aWNBc3NldHNNb2RhbENvbXBvbmVudFsnYXNzZXRUeXBlJ10gPSAnYnJhbmRpbmcnO1xuICBASW5wdXQoKSBzdXBwb3J0ZWRGaWxlRXh0ZW5zaW9uczogU3RhdGljQXNzZXRzTW9kYWxDb21wb25lbnRbJ3N1cHBvcnRlZEZpbGVFeHRlbnNpb25zJ10gPSBbXTtcbiAgQElucHV0KCkgbGF5b3V0OiBTdGF0aWNBc3NldHNNb2RhbENvbXBvbmVudFsnbGF5b3V0J10gPSAnZ3JpZCc7XG4gIEBJbnB1dCgpIHNpemUgPSA0ODtcbiAgbG9hZGluZyA9IGZhbHNlO1xuICBjdXJyZW50RmlsZTogU3RhdGljQXNzZXQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIGN1cnJlbnRWYWx1ZTogc3RyaW5nO1xuXG4gIHByaXZhdGUgb25DaGFuZ2U6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICBwcml2YXRlIG9uVG91Y2hlZDogKCkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHN0YXRpY0Fzc2V0c01vZGFsOiBTdGF0aWNBc3NldHNNb2RhbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzdGF0aWNBc3NldHM6IFN0YXRpY0Fzc2V0c1NlcnZpY2VcbiAgKSB7fVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICgvXnVybFxcKCcuKidcXCkkLy50ZXN0KHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9edXJsXFwoJy8sICcnKS5yZXBsYWNlKC8nXFwpJC8sICcnKTtcbiAgICB9XG4gICAgaWYgKC9edXJsXFwoLipcXCkkLy50ZXN0KHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9edXJsXFwoLywgJycpLnJlcGxhY2UoL1xcKSQvLCAnJyk7XG4gICAgfVxuICAgIHRoaXMuY3VycmVudFZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sb2FkRmlsZURldGFpbHModmFsdWUpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBhc3luYyBsb2FkRmlsZURldGFpbHMoY3VycmVudFVybDogc3RyaW5nKSB7XG4gICAgaWYgKCFjdXJyZW50VXJsKSB7XG4gICAgICB0aGlzLmN1cnJlbnRGaWxlID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBmaWxlTGlzdCA9IGF3YWl0IHRoaXMuc3RhdGljQXNzZXRzLmxpc3RGaWxlc0NhY2hlZCh0aGlzLnN0YXRpY0Fzc2V0VHlwZSk7XG4gICAgICBjb25zdCBmb3VuZEZpbGUgPSBmaWxlTGlzdC5maW5kKGZpbGUgPT4gY3VycmVudFVybC5pbmNsdWRlcyhmaWxlLnBhdGgpKTtcbiAgICAgIHRoaXMuY3VycmVudEZpbGUgPSBmb3VuZEZpbGU7XG4gICAgICBpZiAoIWZvdW5kRmlsZSkge1xuICAgICAgICBjb25zdCBmaWxlUHJlc2VudCA9IGF3YWl0IHRoaXMuZW5zdXJlRmlsZUV4aXN0cyhjdXJyZW50VXJsKTtcbiAgICAgICAgaWYgKGZpbGVQcmVzZW50KSB7XG4gICAgICAgICAgdGhpcy5jdXJyZW50RmlsZSA9IHtcbiAgICAgICAgICAgIHBhdGg6IGN1cnJlbnRVcmwsXG4gICAgICAgICAgICBmaWxlTmFtZTogY3VycmVudFVybC5zcGxpdCgnLycpLnBvcCgpLFxuICAgICAgICAgICAgb3JpZ2luYWxGaWxlTmFtZTogY3VycmVudFVybC5zcGxpdCgnLycpLnBvcCgpXG4gICAgICAgICAgfSBhcyBhbnk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICB0aGlzLm9uQ2hhbmdlKCcnKTtcbiAgICB0aGlzLmN1cnJlbnRGaWxlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY3VycmVudFZhbHVlID0gJyc7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgfVxuXG4gIGFzeW5jIG9wZW5GaWxlUGlja2VyKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnN0YXRpY0Fzc2V0c01vZGFsLnBpY2tTdGF0aWNBc3NldCh7XG4gICAgICAgIGxheW91dDogdGhpcy5sYXlvdXQsXG4gICAgICAgIGFzc2V0VHlwZTogdGhpcy5zdGF0aWNBc3NldFR5cGUsXG4gICAgICAgIHN1cHBvcnRlZEZpbGVFeHRlbnNpb25zOiB0aGlzLnN1cHBvcnRlZEZpbGVFeHRlbnNpb25zXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5pc0NTU1VSTCA/IGB1cmwoJHtyZXMucGF0aH0pYCA6IHJlcy5wYXRoO1xuICAgICAgdGhpcy5vbkNoYW5nZSh2YWx1ZSk7XG4gICAgICB0aGlzLmN1cnJlbnRGaWxlID0gcmVzO1xuICAgICAgdGhpcy5jdXJyZW50VmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gbW9kYWwgY2xvc2VkXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVGaWxlRXhpc3RzKHVybDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgIHJldHVybiByZXNwb25zZS5zdGF0dXMgPT09IDIwMDtcbiAgfVxufVxuIiwiXG48ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1jZW50ZXIgZ2FwLThcIj5cbiAgPGRpdiAqbmdJZj1cIiFjdXJyZW50VmFsdWUgZWxzZSBmaWxlU2VsZWN0ZWRcIiBjbGFzcz1cImQtY29udGVudHNcIj5cbiAgICA8aSBjOHlJY29uPVwibm8taW1hZ2VcIiBjbGFzcz1cImljb24tNDggdGV4dC1tdXRlZFwiPjwvaT5cbiAgICA8cCBjbGFzcz1cIm0tci1hdXRvIHRleHQtbXV0ZWRcIj48ZW0gdHJhbnNsYXRlPk5vIGZpbGUgc2VsZWN0ZWQuPC9lbT48L3A+XG4gIDwvZGl2PlxuXG4gIDxuZy10ZW1wbGF0ZSAjZmlsZVNlbGVjdGVkPlxuICAgIDxjOHktbG9hZGluZyAqbmdJZj1cImxvYWRpbmdcIj48L2M4eS1sb2FkaW5nPlxuICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiAhY3VycmVudEZpbGVcIj5cbiAgICAgIDxwIHRyYW5zbGF0ZT5VbmFibGUgdG8gbG9jYXRlIGZpbGU6IFwie3sgY3VycmVudFZhbHVlIH19XCI8L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2ICpuZ0lmPVwiIWxvYWRpbmcgJiYgY3VycmVudEZpbGVcIiBzdHlsZT1cIm1pbi1oZWlnaHQ6IDQ4cHhcIiBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyXCI+XG4gICAgICA8aW1nICpuZ0lmPVwiY3VycmVudEZpbGVcIiBbc3JjXT1cImN1cnJlbnRGaWxlLnBhdGhcIiBjbGFzcz1cImltZy1yZXNwb25zaXZlXCIgW25nU3R5bGVdPVwieyd3aWR0aC5weCc6IHNpemV9XCIgYWx0PVwie3tjdXJyZW50RmlsZT8uZmlsZU5hbWUgfX1cIj5cbiAgICA8L2Rpdj5cbiAgICA8c3BhbiBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIiB0aXRsZT1cInt7IGN1cnJlbnRGaWxlPy5maWxlTmFtZSB8fCBjdXJyZW50VmFsdWUgfX1cIj57eyBjdXJyZW50RmlsZT8uZmlsZU5hbWUgfHwgY3VycmVudFZhbHVlIH19PC9zcGFuPlxuICAgIDxidXR0b24gY2xhc3M9XCIgbS1sLWF1dG8gYnRuIGJ0bi1kb3QgYnRuLWRvdC0tZGFuZ2VyXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xlYXIoKVwiXG4gICAgICBbZGVsYXldPVwiNTAwXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1JlbW92ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgcGxhY2VtZW50PVwidG9wXCJcbiAgICAgIHRvb2x0aXA9XCJ7eydSZW1vdmUnIHwgdHJhbnNsYXRlfX1cIj5cbiAgICAgIDxpIGM4eUljb249XCJtaW51cy1jaXJjbGVcIj48L2k+XG4gICAgPC9idXR0b24+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPGJ1dHRvbiAoY2xpY2spPVwib3BlbkZpbGVQaWNrZXIoKVwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbVwiPlxuICAgIDxzcGFuICpuZ0lmPVwiIWN1cnJlbnRGaWxlXCI+XG4gICAgICB7eydTZWxlY3QnIHwgdHJhbnNsYXRlfX1cbiAgICA8L3NwYW4+XG4gICAgPHNwYW4gKm5nSWY9XCJjdXJyZW50RmlsZVwiPlxuICAgICAge3snUmVwbGFjZScgfCB0cmFuc2xhdGV9fVxuICAgIDwvc3Bhbj5cbiAgPC9idXR0b24+XG48L2Rpdj5cblxuIl19