@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
94 lines • 21.1 kB
JavaScript
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { AlertService, C8yJSONSchema, gettext, FilesService } from '@c8y/ngx-components';
import { clone, sortBy } from 'lodash-es';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components";
import * as i2 from "@angular/common";
import * as i3 from "@ngx-formly/core";
export class AssetPropertiesItemComponent {
constructor(alert, c8yJsonSchemaService, filesService) {
this.alert = alert;
this.c8yJsonSchemaService = c8yJsonSchemaService;
this.filesService = filesService;
}
async ngOnChanges(changes) {
if (changes.isEdit) {
this.resolveJsonSchema();
await this.resolveFile();
}
}
async resolveFile() {
if (this.file) {
try {
if (this.filesService.fileNamesHaveValidExtension(this.file.name, 'image')) {
const imageFile = await this.filesService.getFile(this.file);
this.previewImage = await this.getPreviewIfImage(imageFile);
}
}
catch (ex) {
this.alert.danger(gettext('File could not be loaded.'));
}
}
}
formComplexPropsValue() {
const complexProps = {};
this.complex.forEach(complexObj => {
if (complexObj.file) {
complexProps[complexObj.key] = complexObj.value;
}
else {
complexProps[complexObj.key] = this.value[complexObj.key];
}
});
return complexProps;
}
getModel() {
if (this.complex && this.complex.length > 0) {
return {
[this.key]: this.formComplexPropsValue()
};
}
return {
[this.key]: clone(this.value)
};
}
resolveJsonSchema() {
if (this.jsonSchema) {
const fieldConfig = this.c8yJsonSchemaService.toFieldConfig(this.jsonSchema, this.jsonSchema);
if (this.complex && this.complex.length > 0) {
const orderedFieldConfig = sortBy(fieldConfig.fieldGroup[0].fieldGroup, 'order');
fieldConfig.fieldGroup[0].fieldGroup = orderedFieldConfig;
}
this.form = new FormGroup({});
this.fields = [fieldConfig];
this.model = this.getModel();
}
}
async getPreviewIfImage(imageFile) {
return this.filesService.toBase64(imageFile);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssetPropertiesItemComponent, deps: [{ token: i1.AlertService }, { token: i1.C8yJSONSchema }, { token: i1.FilesService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AssetPropertiesItemComponent, selector: "c8y-asset-properties-item", inputs: { key: "key", value: "value", label: "label", type: "type", file: "file", complex: "complex", isEdit: "isEdit", jsonSchema: "jsonSchema" }, usesOnChanges: true, ngImport: i0, template: "<ng-container [ngSwitch]=\"type\" *ngIf=\"!isEdit\">\n <ng-container *ngSwitchCase=\"'date'\">\n {{ (value | c8yDate: 'fullDate') || ('Undefined' | translate) }}\n </ng-container>\n <ng-container *ngSwitchCase=\"'file'\">\n <ng-container *ngIf=\"file\">\n <img *ngIf=\"previewImage\" [src]=\"previewImage\" class=\"img-responsive\" />\n <button\n *ngIf=\"!previewImage\"\n (click)=\"filesService.download(file)\"\n type=\"button\"\n title=\"{{ 'Download' | translate }} {{ file.name }}\"\n class=\"btn btn-clean text-truncate p-0\"\n >\n {{ file.name }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"!file\">\n {{ 'No file attached.' | translate }}\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'object'\">\n <ul class=\"list-unstyled c8y-custom-properties\">\n <li\n *ngFor=\"let prop of complex; let i = index\"\n [ngClass]=\"{ 'separator-top-bottom': i === 0, 'separator-bottom': i > 0 }\"\n class=\"p-t-4 p-b-4 d-flex text-nowrap\"\n >\n <label\n class=\"small m-b-0 m-r-8 text-truncate\"\n title=\"{{ prop.label | translate }}\"\n [ngClass]=\"{ 'a-s-start': prop.file }\"\n >\n {{ prop.label | translate }}\n </label>\n <span class=\"m-l-auto\" style=\"max-width: {{ prop.file ? '50%' : '100%' }}; min-width:0;\">\n <c8y-asset-properties-item\n [file]=\"prop.file\"\n [key]=\"prop.key\"\n [type]=\"prop.type\"\n [value]=\"prop.value\"\n ></c8y-asset-properties-item>\n </span>\n </li>\n </ul>\n </ng-container>\n <!--\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input type=\"checkbox\" [checked]=\"value\" [disabled]=\"true\" />\n </ng-container>\n -->\n <ng-container *ngSwitchCase=\"type === 'number' || type === 'boolean' ? type : ''\">\n <p class=\"text-truncate\" title=\"{{ value != null ? value : ('Undefined' | translate) }}\">\n {{ value != null ? value : ('Undefined' | translate) }}\n </p>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <p class=\"text-truncate\" title=\"{{ (value | translate) || ('Undefined' | translate) }}\">\n {{ (value | translate) || ('Undefined' | translate) }}\n </p>\n </ng-container>\n</ng-container>\n<formly-form *ngIf=\"isEdit\" [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "component", type: AssetPropertiesItemComponent, selector: "c8y-asset-properties-item", inputs: ["key", "value", "label", "type", "file", "complex", "isEdit", "jsonSchema"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssetPropertiesItemComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-asset-properties-item', template: "<ng-container [ngSwitch]=\"type\" *ngIf=\"!isEdit\">\n <ng-container *ngSwitchCase=\"'date'\">\n {{ (value | c8yDate: 'fullDate') || ('Undefined' | translate) }}\n </ng-container>\n <ng-container *ngSwitchCase=\"'file'\">\n <ng-container *ngIf=\"file\">\n <img *ngIf=\"previewImage\" [src]=\"previewImage\" class=\"img-responsive\" />\n <button\n *ngIf=\"!previewImage\"\n (click)=\"filesService.download(file)\"\n type=\"button\"\n title=\"{{ 'Download' | translate }} {{ file.name }}\"\n class=\"btn btn-clean text-truncate p-0\"\n >\n {{ file.name }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"!file\">\n {{ 'No file attached.' | translate }}\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'object'\">\n <ul class=\"list-unstyled c8y-custom-properties\">\n <li\n *ngFor=\"let prop of complex; let i = index\"\n [ngClass]=\"{ 'separator-top-bottom': i === 0, 'separator-bottom': i > 0 }\"\n class=\"p-t-4 p-b-4 d-flex text-nowrap\"\n >\n <label\n class=\"small m-b-0 m-r-8 text-truncate\"\n title=\"{{ prop.label | translate }}\"\n [ngClass]=\"{ 'a-s-start': prop.file }\"\n >\n {{ prop.label | translate }}\n </label>\n <span class=\"m-l-auto\" style=\"max-width: {{ prop.file ? '50%' : '100%' }}; min-width:0;\">\n <c8y-asset-properties-item\n [file]=\"prop.file\"\n [key]=\"prop.key\"\n [type]=\"prop.type\"\n [value]=\"prop.value\"\n ></c8y-asset-properties-item>\n </span>\n </li>\n </ul>\n </ng-container>\n <!--\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input type=\"checkbox\" [checked]=\"value\" [disabled]=\"true\" />\n </ng-container>\n -->\n <ng-container *ngSwitchCase=\"type === 'number' || type === 'boolean' ? type : ''\">\n <p class=\"text-truncate\" title=\"{{ value != null ? value : ('Undefined' | translate) }}\">\n {{ value != null ? value : ('Undefined' | translate) }}\n </p>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <p class=\"text-truncate\" title=\"{{ (value | translate) || ('Undefined' | translate) }}\">\n {{ (value | translate) || ('Undefined' | translate) }}\n </p>\n </ng-container>\n</ng-container>\n<formly-form *ngIf=\"isEdit\" [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n" }]
}], ctorParameters: () => [{ type: i1.AlertService }, { type: i1.C8yJSONSchema }, { type: i1.FilesService }], propDecorators: { key: [{
type: Input
}], value: [{
type: Input
}], label: [{
type: Input
}], type: [{
type: Input
}], file: [{
type: Input
}], complex: [{
type: Input
}], isEdit: [{
type: Input
}], jsonSchema: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXQtcHJvcGVydGllcy1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3N1Yi1hc3NldHMvYXNzZXQtcHJvcGVydGllcy1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3N1Yi1hc3NldHMvYXNzZXQtcHJvcGVydGllcy1pdGVtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUMzRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBSXpGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sV0FBVyxDQUFDOzs7OztBQU0xQyxNQUFNLE9BQU8sNEJBQTRCO0lBdUJ2QyxZQUNVLEtBQW1CLEVBQ25CLG9CQUFtQyxFQUNwQyxZQUEwQjtRQUZ6QixVQUFLLEdBQUwsS0FBSyxDQUFjO1FBQ25CLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBZTtRQUNwQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztJQUNoQyxDQUFDO0lBRUosS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFzQjtRQUN0QyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXO1FBQ3ZCLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDO2dCQUNILElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElB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REgsS0FBSztnQkFHTixJQUFJO3NCQURILEtBQUs7Z0JBR04sT0FBTztzQkFETixLQUFLO2dCQUdOLE1BQU07c0JBREwsS0FBSztnQkFHTixVQUFVO3NCQURULEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkNoYW5nZXMsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IElNYW5hZ2VkT2JqZWN0QmluYXJ5IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQWxlcnRTZXJ2aWNlLCBDOHlKU09OU2NoZW1hLCBnZXR0ZXh0LCBGaWxlc1NlcnZpY2UgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IEZvcm1seUZpZWxkQ29uZmlnIH0gZnJvbSAnQG5neC1mb3JtbHkvY29yZSc7XG5pbXBvcnQgeyBBc3NldFByb3BlcnRpZXNJdGVtIH0gZnJvbSAnLi9hc3NldC1wcm9wZXJ0aWVzLm1vZGVsJztcbmltcG9ydCB7IEpTT05TY2hlbWE3IH0gZnJvbSAnanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgY2xvbmUsIHNvcnRCeSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1hc3NldC1wcm9wZXJ0aWVzLWl0ZW0nLFxuICB0ZW1wbGF0ZVVybDogJy4vYXNzZXQtcHJvcGVydGllcy1pdGVtLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBBc3NldFByb3BlcnRpZXNJdGVtQ29tcG9uZW50IGltcGxlbWVudHMgQXNzZXRQcm9wZXJ0aWVzSXRlbSwgT25DaGFuZ2VzIHtcbiAgQElucHV0KClcbiAga2V5OiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHZhbHVlOiBhbnk7XG4gIEBJbnB1dCgpXG4gIGxhYmVsOiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHR5cGU6IHN0cmluZztcbiAgQElucHV0KClcbiAgZmlsZTogSU1hbmFnZWRPYmplY3RCaW5hcnk7XG4gIEBJbnB1dCgpXG4gIGNvbXBsZXg6IEFzc2V0UHJvcGVydGllc0l0ZW1bXTtcbiAgQElucHV0KClcbiAgaXNFZGl0OiBib29sZWFuO1xuICBASW5wdXQoKVxuICBqc29uU2NoZW1hOiBKU09OU2NoZW1hNztcblxuICBmb3JtOiBGb3JtR3JvdXA7XG4gIGZpZWxkczogRm9ybWx5RmllbGRDb25maWdbXTtcbiAgbW9kZWw6IGFueTtcbiAgcHJldmlld0ltYWdlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYWxlcnQ6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIGM4eUpzb25TY2hlbWFTZXJ2aWNlOiBDOHlKU09OU2NoZW1hLFxuICAgIHB1YmxpYyBmaWxlc1NlcnZpY2U6IEZpbGVzU2VydmljZVxuICApIHt9XG5cbiAgYXN5bmMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChjaGFuZ2VzLmlzRWRpdCkge1xuICAgICAgdGhpcy5yZXNvbHZlSnNvblNjaGVtYSgpO1xuICAgICAgYXdhaXQgdGhpcy5yZXNvbHZlRmlsZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUZpbGUoKSB7XG4gICAgaWYgKHRoaXMuZmlsZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHRoaXMuZmlsZXNTZXJ2aWNlLmZpbGVOYW1lc0hhdmVWYWxpZEV4dGVuc2lvbih0aGlzLmZpbGUubmFtZSwgJ2ltYWdlJykpIHtcbiAgICAgICAgICBjb25zdCBpbWFnZUZpbGUgPSBhd2FpdCB0aGlzLmZpbGVzU2VydmljZS5nZXRGaWxlKHRoaXMuZmlsZSk7XG4gICAgICAgICAgdGhpcy5wcmV2aWV3SW1hZ2UgPSBhd2FpdCB0aGlzLmdldFByZXZpZXdJZkltYWdlKGltYWdlRmlsZSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgIHRoaXMuYWxlcnQuZGFuZ2VyKGdldHRleHQoJ0ZpbGUgY291bGQgbm90IGJlIGxvYWRlZC4nKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmb3JtQ29tcGxleFByb3BzVmFsdWUoKSB7XG4gICAgY29uc3QgY29tcGxleFByb3BzID0ge307XG4gICAgdGhpcy5jb21wbGV4LmZvckVhY2goY29tcGxleE9iaiA9PiB7XG4gICAgICBpZiAoY29tcGxleE9iai5maWxlKSB7XG4gICAgICAgIGNvbXBsZXhQcm9wc1tjb21wbGV4T2JqLmtleV0gPSBjb21wbGV4T2JqLnZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tcGxleFByb3BzW2NvbXBsZXhPYmoua2V5XSA9IHRoaXMudmFsdWVbY29tcGxleE9iai5rZXldO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBjb21wbGV4UHJvcHM7XG4gIH1cblxuICBwcml2YXRlIGdldE1vZGVsKCkge1xuICAgIGlmICh0aGlzLmNvbXBsZXggJiYgdGhpcy5jb21wbGV4Lmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFt0aGlzLmtleV06IHRoaXMuZm9ybUNvbXBsZXhQcm9wc1ZhbHVlKClcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBbdGhpcy5rZXldOiBjbG9uZSh0aGlzLnZhbHVlKVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVKc29uU2NoZW1hKCkge1xuICAgIGlmICh0aGlzLmpzb25TY2hlbWEpIHtcbiAgICAgIGNvbnN0IGZpZWxkQ29uZmlnID0gdGhpcy5jOHlKc29uU2NoZW1hU2VydmljZS50b0ZpZWxkQ29uZmlnKHRoaXMuanNvblNjaGVtYSwgdGhpcy5qc29uU2NoZW1hKTtcbiAgICAgIGlmICh0aGlzLmNvbXBsZXggJiYgdGhpcy5jb21wbGV4Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3Qgb3JkZXJlZEZpZWxkQ29uZmlnID0gc29ydEJ5KGZpZWxkQ29uZmlnLmZpZWxkR3JvdXBbMF0uZmllbGRHcm91cCwgJ29yZGVyJyk7XG4gICAgICAgIGZpZWxkQ29uZmlnLmZpZWxkR3JvdXBbMF0uZmllbGRHcm91cCA9IG9yZGVyZWRGaWVsZENvbmZpZztcbiAgICAgIH1cbiAgICAgIHRoaXMuZm9ybSA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICAgICAgdGhpcy5maWVsZHMgPSBbZmllbGRDb25maWddO1xuICAgICAgdGhpcy5tb2RlbCA9IHRoaXMuZ2V0TW9kZWwoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldFByZXZpZXdJZkltYWdlKGltYWdlRmlsZTogRmlsZSkge1xuICAgIHJldHVybiB0aGlzLmZpbGVzU2VydmljZS50b0Jhc2U2NChpbWFnZUZpbGUpO1xuICB9XG59XG4iLCI8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJ0eXBlXCIgKm5nSWY9XCIhaXNFZGl0XCI+XG4gIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidkYXRlJ1wiPlxuICAgIHt7ICh2YWx1ZSB8IGM4eURhdGU6ICdmdWxsRGF0ZScpIHx8ICgnVW5kZWZpbmVkJyB8IHRyYW5zbGF0ZSkgfX1cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidmaWxlJ1wiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWxlXCI+XG4gICAgICA8aW1nICpuZ0lmPVwicHJldmlld0ltYWdlXCIgW3NyY109XCJwcmV2aWV3SW1hZ2VcIiBjbGFzcz1cImltZy1yZXNwb25zaXZlXCIgLz5cbiAgICAgIDxidXR0b25cbiAgICAgICAgKm5nSWY9XCIhcHJldmlld0ltYWdlXCJcbiAgICAgICAgKGNsaWNrKT1cImZpbGVzU2VydmljZS5kb3dubG9hZChmaWxlKVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICB0aXRsZT1cInt7ICdEb3dubG9hZCcgfCB0cmFuc2xhdGUgfX0ge3sgZmlsZS5uYW1lIH19XCJcbiAgICAgICAgY2xhc3M9XCJidG4gYnRuLWNsZWFuIHRleHQtdHJ1bmNhdGUgcC0wXCJcbiAgICAgID5cbiAgICAgICAge3sgZmlsZS5uYW1lIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWZpbGVcIj5cbiAgICAgIHt7ICdObyBmaWxlIGF0dGFjaGVkLicgfCB0cmFuc2xhdGUgfX1cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidvYmplY3QnXCI+XG4gICAgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZCBjOHktY3VzdG9tLXByb3BlcnRpZXNcIj5cbiAgICAgIDxsaVxuICAgICAgICAqbmdGb3I9XCJsZXQgcHJvcCBvZiBjb21wbGV4OyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnc2VwYXJhdG9yLXRvcC1ib3R0b20nOiBpID09PSAwLCAnc2VwYXJhdG9yLWJvdHRvbSc6IGkgPiAwIH1cIlxuICAgICAgICBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCB0ZXh0LW5vd3JhcFwiXG4gICAgICA+XG4gICAgICAgIDxsYWJlbFxuICAgICAgICAgIGNsYXNzPVwic21hbGwgbS1iLTAgbS1yLTggdGV4dC10cnVuY2F0ZVwiXG4gICAgICAgICAgdGl0bGU9XCJ7eyBwcm9wLmxhYmVsIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdhLXMtc3RhcnQnOiBwcm9wLmZpbGUgfVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBwcm9wLmxhYmVsIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibS1sLWF1dG9cIiBzdHlsZT1cIm1heC13aWR0aDoge3sgcHJvcC5maWxlID8gJzUwJScgOiAnMTAwJScgfX07IG1pbi13aWR0aDowO1wiPlxuICAgICAgICAgIDxjOHktYXNzZXQtcHJvcGVydGllcy1pdGVtXG4gICAgICAgICAgICBbZmlsZV09XCJwcm9wLmZpbGVcIlxuICAgICAgICAgICAgW2tleV09XCJwcm9wLmtleVwiXG4gICAgICAgICAgICBbdHlwZV09XCJwcm9wLnR5cGVcIlxuICAgICAgICAgICAgW3ZhbHVlXT1cInByb3AudmFsdWVcIlxuICAgICAgICAgID48L2M4eS1hc3NldC1wcm9wZXJ0aWVzLWl0ZW0+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbGk+XG4gICAgPC91bD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDwhLS1cbiAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Jvb2xlYW4nXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwidmFsdWVcIiBbZGlzYWJsZWRdPVwidHJ1ZVwiIC8+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIC0tPlxuICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJ0eXBlID09PSAnbnVtYmVyJyB8fCB0eXBlID09PSAnYm9vbGVhbicgPyB0eXBlIDogJydcIj5cbiAgICA8cCBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIiB0aXRsZT1cInt7IHZhbHVlICE9IG51bGwgPyB2YWx1ZSA6ICgnVW5kZWZpbmVkJyB8IHRyYW5zbGF0ZSkgfX1cIj5cbiAgICAgIHt7IHZhbHVlICE9IG51bGwgPyB2YWx1ZSA6ICgnVW5kZWZpbmVkJyB8IHRyYW5zbGF0ZSkgfX1cbiAgICA8L3A+XG4gIDwvbmctY29udGFpbmVyPlxuICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+XG4gICAgPHAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgdGl0bGU9XCJ7eyAodmFsdWUgfCB0cmFuc2xhdGUpIHx8ICgnVW5kZWZpbmVkJyB8IHRyYW5zbGF0ZSkgfX1cIj5cbiAgICAgIHt7ICh2YWx1ZSB8IHRyYW5zbGF0ZSkgfHwgKCdVbmRlZmluZWQnIHwgdHJhbnNsYXRlKSB9fVxuICAgIDwvcD5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cbjxmb3JtbHktZm9ybSAqbmdJZj1cImlzRWRpdFwiIFtmb3JtXT1cImZvcm1cIiBbZmllbGRzXT1cImZpZWxkc1wiIFttb2RlbF09XCJtb2RlbFwiPjwvZm9ybWx5LWZvcm0+XG4iXX0=