UNPKG

@acrodata/gui

Version:

JSON powered GUI for configurable panels.

139 lines 25.3 kB
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, forwardRef, } from '@angular/core'; import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatIconButton } from '@angular/material/button'; import { MatFormField, MatHint, MatPrefix, MatSuffix } from '@angular/material/form-field'; import { MatIcon } from '@angular/material/icon'; import { MatInput } from '@angular/material/input'; import { finalize } from 'rxjs/operators'; import { GuiFieldLabel } from '../field-label/field-label'; import { GuiIconButtonWrapper } from '../icon-button-wrapper/icon-button-wrapper'; import * as i0 from "@angular/core"; import * as i1 from "./file-uploader-config"; import * as i2 from "../gui-icons"; import * as i3 from "@angular/forms"; export class GuiFileUploader { constructor(fileUploaderCfg, cdr, iconsRegistry) { this.fileUploaderCfg = fileUploaderCfg; this.cdr = cdr; this.config = {}; this.disabled = false; this.type = '*'; this.name = ''; this.accept = ''; this.fileChange = new EventEmitter(); // file url that returned from the server this.url = ''; this.onChange = () => { }; this.onTouched = () => { }; iconsRegistry.add('link', 'clear', 'file', 'upload'); } ngOnChanges(changes) { if (changes['config'] || changes['accept'] || changes['type']) { this.accept = this.config.accept || this.accept || this.type + '/*'; } } writeValue(value) { this.url = value; this.cdr.markForCheck(); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(isDisabled) { this.disabled = isDisabled; this.cdr.markForCheck(); } upload(fileUpload) { const formData = new FormData(); formData.append('file', fileUpload.data); fileUpload.inProgress = true; this.fileUploaderCfg .upload(formData, this.config) .pipe(finalize(() => { fileUpload.inProgress = false; })) .subscribe(result => { if (result) { this.url = result; this.cdr.detectChanges(); this.onChange(this.url); this.onTouched(); this.fileChange.emit(this.url); } }); } onUrlChange(e) { this.url = e.target.value; this.onChange(this.url); this.fileChange.emit(this.url); } onFileChange(e) { this.fileUpload = { data: e.target.files[0], inProgress: false, progress: 0, }; this.upload(this.fileUpload); // reset input value e.target.value = ''; } onBlur() { this.onTouched(); } onClear() { this.url = ''; this.onChange(this.url); this.onTouched(); this.fileChange.emit(this.url); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GuiFileUploader, deps: [{ token: i1.GuiFileUploaderConfig }, { token: i0.ChangeDetectorRef }, { token: i2.GuiIconsRegistry }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GuiFileUploader, isStandalone: true, selector: "gui-file-uploader", inputs: { config: "config", disabled: "disabled", type: "type", name: "name", accept: "accept" }, outputs: { fileChange: "fileChange" }, host: { classAttribute: "gui-field gui-file-uploader" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => GuiFileUploader), multi: true, }, ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mat-form-field>\n <gui-icon-button-wrapper matPrefix>\n <mat-icon svgIcon=\"link\" />\n </gui-icon-button-wrapper>\n\n <input\n matInput\n type=\"text\"\n [ngModel]=\"url\"\n [disabled]=\"disabled\"\n [placeholder]=\"config.placeholder || ''\"\n (change)=\"onUrlChange($event)\"\n (blur)=\"onBlur()\"\n />\n\n @if (url) {\n <gui-icon-button-wrapper matSuffix>\n <button mat-icon-button type=\"button\" color=\"warn\" [disabled]=\"disabled\" (click)=\"onClear()\">\n <mat-icon svgIcon=\"clear\" />\n </button>\n </gui-icon-button-wrapper>\n }\n</mat-form-field>\n\n<figure class=\"gui-file-content\">\n @if (url) {\n @switch (type) {\n @case ('image') {\n <img [src]=\"url\" alt=\"\" />\n }\n @case ('video') {\n <video [src]=\"url\"></video>\n }\n @case ('audio') {\n <audio [src]=\"url\" controls></audio>\n }\n @default {\n <mat-icon svgIcon=\"file\" />\n }\n }\n } @else {\n <div class=\"gui-file-placeholder\">\n <mat-icon svgIcon=\"upload\" />\n </div>\n }\n\n <input\n #fileInput\n type=\"file\"\n [accept]=\"accept\"\n [name]=\"name\"\n [disabled]=\"disabled\"\n (change)=\"onFileChange($event)\"\n />\n</figure>\n\n@if (config.parentType === 'inline') {\n <mat-hint>\n <gui-field-label [config]=\"config\" />\n </mat-hint>\n}\n", styles: [".gui-file-uploader{display:block;overflow:auto;line-height:1}.gui-file-uploader .mat-mdc-form-field{width:100%}.gui-file-uploader .gui-file-content{position:relative;display:flex;align-items:center;justify-content:center;height:7.5rem;margin:.25rem 0 0;padding:.25rem;background-color:var(--mdc-filled-text-field-container-color);border:1px solid transparent;border-radius:.25rem}.gui-file-uploader .gui-file-content:hover,.gui-file-uploader .gui-file-content:focus-within{border-color:currentColor}.gui-file-uploader .gui-file-content img,.gui-file-uploader .gui-file-content video{width:100%;height:100%;object-fit:contain}.gui-file-uploader .gui-file-content input[type=file]{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer}.gui-file-uploader .gui-file-content .mat-icon svg{width:1.5rem;height:1.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: GuiFieldLabel, selector: "gui-field-label", inputs: ["config", "index"] }, { kind: "component", type: GuiIconButtonWrapper, selector: "gui-icon-button-wrapper" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GuiFileUploader, decorators: [{ type: Component, args: [{ selector: 'gui-file-uploader', host: { class: 'gui-field gui-file-uploader', }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => GuiFileUploader), multi: true, }, ], standalone: true, imports: [ FormsModule, MatFormField, MatIcon, MatPrefix, MatInput, MatIconButton, MatSuffix, MatHint, GuiFieldLabel, GuiIconButtonWrapper, ], template: "<mat-form-field>\n <gui-icon-button-wrapper matPrefix>\n <mat-icon svgIcon=\"link\" />\n </gui-icon-button-wrapper>\n\n <input\n matInput\n type=\"text\"\n [ngModel]=\"url\"\n [disabled]=\"disabled\"\n [placeholder]=\"config.placeholder || ''\"\n (change)=\"onUrlChange($event)\"\n (blur)=\"onBlur()\"\n />\n\n @if (url) {\n <gui-icon-button-wrapper matSuffix>\n <button mat-icon-button type=\"button\" color=\"warn\" [disabled]=\"disabled\" (click)=\"onClear()\">\n <mat-icon svgIcon=\"clear\" />\n </button>\n </gui-icon-button-wrapper>\n }\n</mat-form-field>\n\n<figure class=\"gui-file-content\">\n @if (url) {\n @switch (type) {\n @case ('image') {\n <img [src]=\"url\" alt=\"\" />\n }\n @case ('video') {\n <video [src]=\"url\"></video>\n }\n @case ('audio') {\n <audio [src]=\"url\" controls></audio>\n }\n @default {\n <mat-icon svgIcon=\"file\" />\n }\n }\n } @else {\n <div class=\"gui-file-placeholder\">\n <mat-icon svgIcon=\"upload\" />\n </div>\n }\n\n <input\n #fileInput\n type=\"file\"\n [accept]=\"accept\"\n [name]=\"name\"\n [disabled]=\"disabled\"\n (change)=\"onFileChange($event)\"\n />\n</figure>\n\n@if (config.parentType === 'inline') {\n <mat-hint>\n <gui-field-label [config]=\"config\" />\n </mat-hint>\n}\n", styles: [".gui-file-uploader{display:block;overflow:auto;line-height:1}.gui-file-uploader .mat-mdc-form-field{width:100%}.gui-file-uploader .gui-file-content{position:relative;display:flex;align-items:center;justify-content:center;height:7.5rem;margin:.25rem 0 0;padding:.25rem;background-color:var(--mdc-filled-text-field-container-color);border:1px solid transparent;border-radius:.25rem}.gui-file-uploader .gui-file-content:hover,.gui-file-uploader .gui-file-content:focus-within{border-color:currentColor}.gui-file-uploader .gui-file-content img,.gui-file-uploader .gui-file-content video{width:100%;height:100%;object-fit:contain}.gui-file-uploader .gui-file-content input[type=file]{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer}.gui-file-uploader .gui-file-content .mat-icon svg{width:1.5rem;height:1.5rem}\n"] }] }], ctorParameters: () => [{ type: i1.GuiFileUploaderConfig }, { type: i0.ChangeDetectorRef }, { type: i2.GuiIconsRegistry }], propDecorators: { fileInput: [{ type: ViewChild, args: ['fileInput'] }], config: [{ type: Input }], disabled: [{ type: Input }], type: [{ type: Input }], name: [{ type: Input }], accept: [{ type: Input }], fileChange: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2d1aS9maWxlLXVwbG9hZGVyL2ZpbGUtdXBsb2FkZXIudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9ndWkvZmlsZS11cGxvYWRlci9maWxlLXVwbG9hZGVyLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixFQUNqQixVQUFVLEdBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTFDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUUzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQzs7Ozs7QUEwQ2xGLE1BQU0sT0FBTyxlQUFlO0lBb0IxQixZQUNVLGVBQXNDLEVBQ3RDLEdBQXNCLEVBQzlCLGFBQStCO1FBRnZCLG9CQUFlLEdBQWYsZUFBZSxDQUF1QjtRQUN0QyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQW5CdkIsV0FBTSxHQUF3QixFQUFFLENBQUM7UUFDakMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixTQUFJ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LFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLGdCQUFnQixDQUFDOzRCQUM5QyxLQUFLLEVBQUUsSUFBSTt5QkFDWjtxQkFDRixjQUNXLElBQUksV0FDUDt3QkFDUCxXQUFXO3dCQUNYLFlBQVk7d0JBQ1osT0FBTzt3QkFDUCxTQUFTO3dCQUNULFFBQVE7d0JBQ1IsYUFBYTt3QkFDYixTQUFTO3dCQUNULE9BQU87d0JBQ1AsYUFBYTt3QkFDYixvQkFBb0I7cUJBQ3JCO3lKQUd1QixTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVc7Z0JBRWIsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUksVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgZm9yd2FyZFJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybXNNb2R1bGUsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0SWNvbkJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGQsIE1hdEhpbnQsIE1hdFByZWZpeCwgTWF0U3VmZml4IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IGZpbmFsaXplIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBHdWlGaWVsZExhYmVsIH0gZnJvbSAnLi4vZmllbGQtbGFiZWwvZmllbGQtbGFiZWwnO1xuaW1wb3J0IHsgR3VpSWNvbnNSZWdpc3RyeSB9IGZyb20gJy4uL2d1aS1pY29ucyc7XG5pbXBvcnQgeyBHdWlJY29uQnV0dG9uV3JhcHBlciB9IGZyb20gJy4uL2ljb24tYnV0dG9uLXdyYXBwZXIvaWNvbi1idXR0b24td3JhcHBlcic7XG5pbXBvcnQgeyBHdWlDb250cm9sIH0gZnJvbSAnLi4vaW50ZXJmYWNlJztcbmltcG9ydCB7IEd1aUZpbGVVcGxvYWRlckNvbmZpZyB9IGZyb20gJy4vZmlsZS11cGxvYWRlci1jb25maWcnO1xuXG5leHBvcnQgdHlwZSBGaWxlVXBsb2FkVHlwZSA9ICdpbWFnZScgfCAndmlkZW8nIHwgJ2F1ZGlvJyB8ICcqJztcblxuZXhwb3J0IGludGVyZmFjZSBGaWxlVXBsb2FkQ29udGVudCB7XG4gIGRhdGE6IEZpbGU7XG4gIHByb2dyZXNzOiBudW1iZXI7XG4gIGluUHJvZ3Jlc3M6IGJvb2xlYW47XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2d1aS1maWxlLXVwbG9hZGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZpbGUtdXBsb2FkZXIuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9maWxlLXVwbG9hZGVyLnNjc3MnLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdndWktZmllbGQgZ3VpLWZpbGUtdXBsb2FkZXInLFxuICB9LFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBHdWlGaWxlVXBsb2FkZXIpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIE1hdEZvcm1GaWVsZCxcbiAgICBNYXRJY29uLFxuICAgIE1hdFByZWZpeCxcbiAgICBNYXRJbnB1dCxcbiAgICBNYXRJY29uQnV0dG9uLFxuICAgIE1hdFN1ZmZpeCxcbiAgICBNYXRIaW50LFxuICAgIEd1aUZpZWxkTGFiZWwsXG4gICAgR3VpSWNvbkJ1dHRvbldyYXBwZXIsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEd1aUZpbGVVcGxvYWRlciBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMge1xuICBAVmlld0NoaWxkKCdmaWxlSW5wdXQnKSBmaWxlSW5wdXQhOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuXG4gIEBJbnB1dCgpIGNvbmZpZzogUGFydGlhbDxHdWlDb250cm9sPiA9IHt9O1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICBASW5wdXQoKSB0eXBlOiBGaWxlVXBsb2FkVHlwZSA9ICcqJztcbiAgQElucHV0KCkgbmFtZSA9ICcnO1xuICBASW5wdXQoKSBhY2NlcHQgPSAnJztcblxuICBAT3V0cHV0KCkgZmlsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8vIGZpbGUgdXJsIHRoYXQgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyXG4gIHVybCA9ICcnO1xuXG4gIC8vIGZpbGUgdG8gdXBsb2FkXG4gIGZpbGVVcGxvYWQhOiBGaWxlVXBsb2FkQ29udGVudDtcblxuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBwcml2YXRlIG9uVG91Y2hlZDogKCkgPT4gdm9pZCA9ICgpID0+IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZmlsZVVwbG9hZGVyQ2ZnOiBHdWlGaWxlVXBsb2FkZXJDb25maWcsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIGljb25zUmVnaXN0cnk6IEd1aUljb25zUmVnaXN0cnlcbiAgKSB7XG4gICAgaWNvbnNSZWdpc3RyeS5hZGQoJ2xpbmsnLCAnY2xlYXInLCAnZmlsZScsICd1cGxvYWQnKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29uZmlnJ10gfHwgY2hhbmdlc1snYWNjZXB0J10gfHwgY2hhbmdlc1sndHlwZSddKSB7XG4gICAgICB0aGlzLmFjY2VwdCA9IHRoaXMuY29uZmlnLmFjY2VwdCB8fCB0aGlzLmFjY2VwdCB8fCB0aGlzLnR5cGUgKyAnLyonO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMudXJsID0gdmFsdWU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCkge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbikge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgdXBsb2FkKGZpbGVVcGxvYWQ6IEZpbGVVcGxvYWRDb250ZW50KSB7XG4gICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICBmb3JtRGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlVXBsb2FkLmRhdGEpO1xuXG4gICAgZmlsZVVwbG9hZC5pblByb2dyZXNzID0gdHJ1ZTtcblxuICAgIHRoaXMuZmlsZVVwbG9hZGVyQ2ZnXG4gICAgICAudXBsb2FkKGZvcm1EYXRhLCB0aGlzLmNvbmZpZylcbiAgICAgIC5waXBlKFxuICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgICAgZmlsZVVwbG9hZC5pblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICB0aGlzLnVybCA9IHJlc3VsdDtcbiAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG5cbiAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudXJsKTtcbiAgICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xuXG4gICAgICAgICAgdGhpcy5maWxlQ2hhbmdlLmVtaXQodGhpcy51cmwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIG9uVXJsQ2hhbmdlKGU6IEV2ZW50KSB7XG4gICAgdGhpcy51cmwgPSAoZS50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XG5cbiAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudXJsKTtcblxuICAgIHRoaXMuZmlsZUNoYW5nZS5lbWl0KHRoaXMudXJsKTtcbiAgfVxuXG4gIG9uRmlsZUNoYW5nZShlOiBFdmVudCkge1xuICAgIHRoaXMuZmlsZVVwbG9hZCA9IHtcbiAgICAgIGRhdGE6IChlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS5maWxlcyFbMF0sXG4gICAgICBpblByb2dyZXNzOiBmYWxzZSxcbiAgICAgIHByb2dyZXNzOiAwLFxuICAgIH07XG5cbiAgICB0aGlzLnVwbG9hZCh0aGlzLmZpbGVVcGxvYWQpO1xuXG4gICAgLy8gcmVzZXQgaW5wdXQgdmFsdWVcbiAgICAoZS50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWUgPSAnJztcbiAgfVxuXG4gIG9uQmx1cigpIHtcbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICB9XG5cbiAgb25DbGVhcigpIHtcbiAgICB0aGlzLnVybCA9ICcnO1xuXG4gICAgdGhpcy5vbkNoYW5nZSh0aGlzLnVybCk7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcblxuICAgIHRoaXMuZmlsZUNoYW5nZS5lbWl0KHRoaXMudXJsKTtcbiAgfVxufVxuIiwiPG1hdC1mb3JtLWZpZWxkPlxuICA8Z3VpLWljb24tYnV0dG9uLXdyYXBwZXIgbWF0UHJlZml4PlxuICAgIDxtYXQtaWNvbiBzdmdJY29uPVwibGlua1wiIC8+XG4gIDwvZ3VpLWljb24tYnV0dG9uLXdyYXBwZXI+XG5cbiAgPGlucHV0XG4gICAgbWF0SW5wdXRcbiAgICB0eXBlPVwidGV4dFwiXG4gICAgW25nTW9kZWxdPVwidXJsXCJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIFtwbGFjZWhvbGRlcl09XCJjb25maWcucGxhY2Vob2xkZXIgfHwgJydcIlxuICAgIChjaGFuZ2UpPVwib25VcmxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAvPlxuXG4gIEBpZiAodXJsKSB7XG4gICAgPGd1aS1pY29uLWJ1dHRvbi13cmFwcGVyIG1hdFN1ZmZpeD5cbiAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBjb2xvcj1cIndhcm5cIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAoY2xpY2spPVwib25DbGVhcigpXCI+XG4gICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwiY2xlYXJcIiAvPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9ndWktaWNvbi1idXR0b24td3JhcHBlcj5cbiAgfVxuPC9tYXQtZm9ybS1maWVsZD5cblxuPGZpZ3VyZSBjbGFzcz1cImd1aS1maWxlLWNvbnRlbnRcIj5cbiAgQGlmICh1cmwpIHtcbiAgICBAc3dpdGNoICh0eXBlKSB7XG4gICAgICBAY2FzZSAoJ2ltYWdlJykge1xuICAgICAgICA8aW1nIFtzcmNdPVwidXJsXCIgYWx0PVwiXCIgLz5cbiAgICAgIH1cbiAgICAgIEBjYXNlICgndmlkZW8nKSB7XG4gICAgICAgIDx2aWRlbyBbc3JjXT1cInVybFwiPjwvdmlkZW8+XG4gICAgICB9XG4gICAgICBAY2FzZSAoJ2F1ZGlvJykge1xuICAgICAgICA8YXVkaW8gW3NyY109XCJ1cmxcIiBjb250cm9scz48L2F1ZGlvPlxuICAgICAgfVxuICAgICAgQGRlZmF1bHQge1xuICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImZpbGVcIiAvPlxuICAgICAgfVxuICAgIH1cbiAgfSBAZWxzZSB7XG4gICAgPGRpdiBjbGFzcz1cImd1aS1maWxlLXBsYWNlaG9sZGVyXCI+XG4gICAgICA8bWF0LWljb24gc3ZnSWNvbj1cInVwbG9hZFwiIC8+XG4gICAgPC9kaXY+XG4gIH1cblxuICA8aW5wdXRcbiAgICAjZmlsZUlucHV0XG4gICAgdHlwZT1cImZpbGVcIlxuICAgIFthY2NlcHRdPVwiYWNjZXB0XCJcbiAgICBbbmFtZV09XCJuYW1lXCJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIChjaGFuZ2UpPVwib25GaWxlQ2hhbmdlKCRldmVudClcIlxuICAvPlxuPC9maWd1cmU+XG5cbkBpZiAoY29uZmlnLnBhcmVudFR5cGUgPT09ICdpbmxpbmUnKSB7XG4gIDxtYXQtaGludD5cbiAgICA8Z3VpLWZpZWxkLWxhYmVsIFtjb25maWddPVwiY29uZmlnXCIgLz5cbiAgPC9tYXQtaGludD5cbn1cbiJdfQ==