valtech-components 4.0.87 → 4.0.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/organisms/attachment-uploader/attachment-uploader.component.mjs +63 -6
- package/esm2022/lib/services/i18n/default-content.mjs +7 -1
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +68 -5
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/attachment-uploader/attachment-uploader.component.d.ts +9 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
package/esm2022/lib/components/organisms/attachment-uploader/attachment-uploader.component.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Compressor from 'compressorjs';
|
|
2
|
-
import { Component, computed, inject, input, output, signal } from '@angular/core';
|
|
2
|
+
import { Component, ViewChild, ViewEncapsulation, computed, inject, input, output, signal, } from '@angular/core';
|
|
3
3
|
import { IonButton, IonIcon, IonNote, IonSpinner } from '@ionic/angular/standalone';
|
|
4
4
|
import { addIcons } from 'ionicons';
|
|
5
5
|
import { attachOutline, cameraOutline, checkmarkCircleOutline, closeCircleOutline, closeOutline, documentOutline, imageOutline, } from 'ionicons/icons';
|
|
@@ -19,6 +19,8 @@ export class AttachmentUploaderComponent {
|
|
|
19
19
|
this.i18n = inject(I18nService);
|
|
20
20
|
this.feedbackService = inject(FeedbackService, { optional: true });
|
|
21
21
|
this.attachments = signal([]);
|
|
22
|
+
this.showCameraOverlay = signal(false);
|
|
23
|
+
this.cameraStream = null;
|
|
22
24
|
this.maxFiles = computed(() => this.props().maxFiles ?? 5);
|
|
23
25
|
this.accept = computed(() => this.props().accept ?? 'image/jpeg,image/png,image/webp,application/pdf');
|
|
24
26
|
this.maxReached = computed(() => this.attachments().length >= this.maxFiles());
|
|
@@ -34,10 +36,59 @@ export class AttachmentUploaderComponent {
|
|
|
34
36
|
imageOutline,
|
|
35
37
|
});
|
|
36
38
|
}
|
|
39
|
+
async openCamera() {
|
|
40
|
+
if (!navigator.mediaDevices?.getUserMedia) {
|
|
41
|
+
this.cameraPicker.nativeElement.click();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
this.cameraStream = await navigator.mediaDevices.getUserMedia({
|
|
46
|
+
video: { facingMode: { ideal: 'environment' }, width: { ideal: 1920 }, height: { ideal: 1080 } },
|
|
47
|
+
});
|
|
48
|
+
this.showCameraOverlay.set(true);
|
|
49
|
+
// El video element se renderiza después del signal → esperar un tick
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
if (this.cameraVideo?.nativeElement) {
|
|
52
|
+
this.cameraVideo.nativeElement.srcObject = this.cameraStream;
|
|
53
|
+
}
|
|
54
|
+
}, 50);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Permiso denegado o dispositivo sin cámara → fallback file picker
|
|
58
|
+
this.cameraPicker.nativeElement.click();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
capturePhoto() {
|
|
62
|
+
const video = this.cameraVideo?.nativeElement;
|
|
63
|
+
if (!video)
|
|
64
|
+
return;
|
|
65
|
+
const canvas = document.createElement('canvas');
|
|
66
|
+
canvas.width = video.videoWidth;
|
|
67
|
+
canvas.height = video.videoHeight;
|
|
68
|
+
canvas.getContext('2d').drawImage(video, 0, 0);
|
|
69
|
+
canvas.toBlob(blob => {
|
|
70
|
+
if (!blob)
|
|
71
|
+
return;
|
|
72
|
+
const file = new File([blob], `foto_${Date.now()}.jpg`, { type: 'image/jpeg' });
|
|
73
|
+
this.closeCamera();
|
|
74
|
+
this.processFiles([file]);
|
|
75
|
+
}, 'image/jpeg', 0.9);
|
|
76
|
+
}
|
|
77
|
+
closeCamera() {
|
|
78
|
+
this.cameraStream?.getTracks().forEach(t => t.stop());
|
|
79
|
+
this.cameraStream = null;
|
|
80
|
+
if (this.cameraVideo?.nativeElement) {
|
|
81
|
+
this.cameraVideo.nativeElement.srcObject = null;
|
|
82
|
+
}
|
|
83
|
+
this.showCameraOverlay.set(false);
|
|
84
|
+
}
|
|
37
85
|
async onFilesSelected(event) {
|
|
38
86
|
const input = event.target;
|
|
39
87
|
const files = Array.from(input.files ?? []);
|
|
40
88
|
input.value = '';
|
|
89
|
+
this.processFiles(files);
|
|
90
|
+
}
|
|
91
|
+
processFiles(files) {
|
|
41
92
|
const available = this.maxFiles() - this.attachments().length;
|
|
42
93
|
const toProcess = files.slice(0, available);
|
|
43
94
|
for (const file of toProcess) {
|
|
@@ -53,7 +104,7 @@ export class AttachmentUploaderComponent {
|
|
|
53
104
|
quality: 0.8,
|
|
54
105
|
maxWidth: 1920,
|
|
55
106
|
maxHeight: 1920,
|
|
56
|
-
convertSize: 2 * 1024 * 1024,
|
|
107
|
+
convertSize: 2 * 1024 * 1024,
|
|
57
108
|
success(result) {
|
|
58
109
|
resolve(new File([result], file.name, { type: result.type }));
|
|
59
110
|
},
|
|
@@ -89,10 +140,16 @@ export class AttachmentUploaderComponent {
|
|
|
89
140
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
90
141
|
}
|
|
91
142
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AttachmentUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
92
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AttachmentUploaderComponent, isStandalone: true, selector: "val-attachment-uploader", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { attachmentsChange: "attachmentsChange" }, ngImport: i0, template: "<div class=\"attachment-uploader\">\n @if (props().title) {\n <val-title class=\"attachment-title\" [props]=\"{ content: props().title, size: 'small', color: 'dark', bold: false }\" />\n }\n\n <input #filePicker type=\"file\" [accept]=\"accept()\" multiple class=\"hidden-input\" (change)=\"onFilesSelected($event)\" />\n\n <div class=\"attachment-actions\">\n <ion-button fill=\"outline\" color=\"dark\" size=\"small\" [disabled]=\"isDisabled()\" (click)=\"filePicker.click()\">\n <ion-icon slot=\"start\" name=\"attach-outline\"></ion-icon>\n {{ i18n.t('attachAdd') }}\n </ion-button>\n
|
|
143
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AttachmentUploaderComponent, isStandalone: true, selector: "val-attachment-uploader", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { attachmentsChange: "attachmentsChange" }, viewQueries: [{ propertyName: "cameraPicker", first: true, predicate: ["cameraPicker"], descendants: true }, { propertyName: "cameraVideo", first: true, predicate: ["cameraVideo"], descendants: true }], ngImport: i0, template: "<div class=\"attachment-uploader\">\n @if (props().title) {\n <val-title class=\"attachment-title\" [props]=\"{ content: props().title, size: 'small', color: 'dark', bold: false }\" />\n }\n\n <!-- file picker est\u00E1ndar -->\n <input #filePicker type=\"file\" [accept]=\"accept()\" multiple class=\"hidden-input\" (change)=\"onFilesSelected($event)\" />\n <!-- fallback c\u00E1mara: solo se dispara si getUserMedia falla/denegado -->\n <input\n #cameraPicker\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n class=\"hidden-input\"\n (change)=\"onFilesSelected($event)\"\n />\n\n <div class=\"attachment-actions\">\n <ion-button fill=\"outline\" color=\"dark\" size=\"small\" [disabled]=\"isDisabled()\" (click)=\"filePicker.click()\">\n <ion-icon slot=\"start\" name=\"attach-outline\"></ion-icon>\n {{ i18n.t('attachAdd') }}\n </ion-button>\n <ion-button fill=\"outline\" color=\"dark\" size=\"small\" [disabled]=\"isDisabled()\" (click)=\"openCamera()\">\n <ion-icon slot=\"start\" name=\"camera-outline\"></ion-icon>\n {{ i18n.t('attachCamera') }}\n </ion-button>\n </div>\n\n @if (maxReached()) {\n <ion-note color=\"warning\" class=\"max-note\">\n {{ i18n.t('attachMaxCount', '_global', { count: maxFiles().toString() }) }}\n </ion-note>\n } @if (attachments().length > 0) {\n <div class=\"attachment-list\">\n @for (item of attachments(); track item.id) {\n <div class=\"attachment-item\" [class]=\"'status-' + item.status\">\n <ion-icon\n class=\"file-icon\"\n [name]=\"item.file.type.startsWith('image/') ? 'image-outline' : 'document-outline'\"\n ></ion-icon>\n <div class=\"file-info\">\n <span class=\"file-name\">{{ item.file.name }}</span>\n <span class=\"file-size\">{{ formatSize(item.file.size) }}</span>\n </div>\n\n @if (item.status === 'uploading') {\n <ion-spinner class=\"status-icon\" name=\"circular\"></ion-spinner>\n } @else if (item.status === 'ready') {\n <ion-icon class=\"status-icon\" name=\"checkmark-circle-outline\" color=\"success\"></ion-icon>\n } @else if (item.status === 'error') {\n <ion-icon class=\"status-icon\" name=\"close-circle-outline\" color=\"danger\"></ion-icon>\n } @if (item.status !== 'uploading') {\n <ion-button fill=\"clear\" size=\"small\" color=\"dark\" (click)=\"remove(item.id)\">\n <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>\n </ion-button>\n } @if (item.status === 'error' && item.error) {\n <ion-note color=\"danger\" class=\"error-note\">{{ item.error }}</ion-note>\n }\n </div>\n }\n </div>\n } @if (props().hint) {\n <p class=\"attachment-hint\">{{ props().hint }}</p>\n }\n</div>\n\n<!-- Overlay de c\u00E1mara (getUserMedia) -->\n@if (showCameraOverlay()) {\n<div class=\"camera-overlay\" (click)=\"closeCamera()\">\n <div class=\"camera-modal\" (click)=\"$event.stopPropagation()\">\n <video #cameraVideo autoplay playsinline class=\"camera-preview\"></video>\n <div class=\"camera-controls\">\n <ion-button fill=\"outline\" color=\"dark\" (click)=\"closeCamera()\"> {{ i18n.t('attachCancel') }} </ion-button>\n <ion-button color=\"dark\" shape=\"round\" (click)=\"capturePhoto()\">\n <ion-icon slot=\"start\" name=\"camera-outline\"></ion-icon>\n {{ i18n.t('attachCapture') }}\n </ion-button>\n </div>\n </div>\n</div>\n}\n", styles: [".hidden-input{display:none}.camera-overlay{position:fixed;inset:0;z-index:9999;background:#000000d9;display:flex;align-items:center;justify-content:center}.camera-modal{display:flex;flex-direction:column;gap:16px;padding:16px;max-width:min(640px,95vw);width:100%}.camera-preview{width:100%;border-radius:12px;background:#000;aspect-ratio:16/9;object-fit:cover}.camera-controls{display:flex;justify-content:center;gap:12px}.camera-controls ion-button{margin:0;--color: #fff;--border-color: rgba(255, 255, 255, .5)}.attachment-uploader{display:flex;flex-direction:column;gap:8px}.attachment-title{display:block;margin-bottom:2px}.attachment-hint{margin:2px 0 0;text-align:right;font-size:.75rem;line-height:1.4;color:var(--ion-color-dark)}.attachment-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.attachment-actions ion-button{margin:0;height:32px}.attachment-list{display:flex;flex-direction:column;gap:4px}.attachment-item{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:8px;background:var(--ion-background-color, #fff);border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .08));flex-wrap:wrap}.attachment-item.status-error{border-color:var(--ion-color-danger)}.file-icon{font-size:1.375rem;color:var(--ion-text-color);flex-shrink:0}.file-info{flex:1;min-width:0;display:flex;flex-direction:column}.file-name{font-size:.8125rem;color:var(--ion-text-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-size{font-size:.6875rem;color:var(--ion-color-medium)}:host-context(.dark) .attachment-item,:host-context(.ion-palette-dark) .attachment-item,:host-context(html.ion-palette-dark) .attachment-item,:host-context(body.dark) .attachment-item,:host-context([data-theme=dark]) .attachment-item{background:#ffffff0a;border-color:#ffffff1f}:host-context(.dark) .attachment-item.status-error,:host-context(.ion-palette-dark) .attachment-item.status-error,:host-context(html.ion-palette-dark) .attachment-item.status-error,:host-context(body.dark) .attachment-item.status-error,:host-context([data-theme=dark]) .attachment-item.status-error{border-color:var(--ion-color-danger)}.status-icon{font-size:1.25rem;flex-shrink:0}.error-note{font-size:.6875rem;width:100%}.max-note{font-size:.75rem}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
93
144
|
}
|
|
94
145
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AttachmentUploaderComponent, decorators: [{
|
|
95
146
|
type: Component,
|
|
96
|
-
args: [{ selector: 'val-attachment-uploader', standalone: true, imports: [IonButton, IonIcon, IonNote, IonSpinner, TitleComponent], template: "<div class=\"attachment-uploader\">\n @if (props().title) {\n <val-title class=\"attachment-title\" [props]=\"{ content: props().title, size: 'small', color: 'dark', bold: false }\" />\n }\n\n <input #filePicker type=\"file\" [accept]=\"accept()\" multiple class=\"hidden-input\" (change)=\"onFilesSelected($event)\" />\n\n <div class=\"attachment-actions\">\n <ion-button fill=\"outline\" color=\"dark\" size=\"small\" [disabled]=\"isDisabled()\" (click)=\"filePicker.click()\">\n <ion-icon slot=\"start\" name=\"attach-outline\"></ion-icon>\n {{ i18n.t('attachAdd') }}\n </ion-button>\n
|
|
97
|
-
}], ctorParameters: () => []
|
|
98
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL2F0dGFjaG1lbnQtdXBsb2FkZXIvYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL2F0dGFjaG1lbnQtdXBsb2FkZXIvYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFVBQVUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25GLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNwRixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3BDLE9BQU8sRUFDTCxhQUFhLEVBQ2IsYUFBYSxFQUNiLHNCQUFzQixFQUN0QixrQkFBa0IsRUFDbEIsWUFBWSxFQUNaLGVBQWUsRUFDZixZQUFZLEdBQ2IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7QUFVbkUsTUFBTSxPQUFPLDJCQUEyQjtJQWdCdEMsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFO2FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENB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LElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxJQUFJO1lBQUUsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDakUsT0FBTyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDcEQsQ0FBQzsrR0F2RlUsMkJBQTJCO21HQUEzQiwyQkFBMkIsNFFDekJ4Qyx1c0ZBZ0VBLDZ6RUQzQ1ksU0FBUyxvUEFBRSxPQUFPLDJKQUFFLE9BQU8sZ0ZBQUUsVUFBVSx5R0FBRSxjQUFjOzs0RkFJdEQsMkJBQTJCO2tCQVB2QyxTQUFTOytCQUNFLHlCQUF5QixjQUN2QixJQUFJLFdBQ1AsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsY0FBYyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvbXByZXNzb3IgZnJvbSAnY29tcHJlc3NvcmpzJztcbmltcG9ydCB7IENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgaW5wdXQsIG91dHB1dCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJb25CdXR0b24sIElvbkljb24sIElvbk5vdGUsIElvblNwaW5uZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhci9zdGFuZGFsb25lJztcbmltcG9ydCB7IGFkZEljb25zIH0gZnJvbSAnaW9uaWNvbnMnO1xuaW1wb3J0IHtcbiAgYXR0YWNoT3V0bGluZSxcbiAgY2FtZXJhT3V0bGluZSxcbiAgY2hlY2ttYXJrQ2lyY2xlT3V0bGluZSxcbiAgY2xvc2VDaXJjbGVPdXRsaW5lLFxuICBjbG9zZU91dGxpbmUsXG4gIGRvY3VtZW50T3V0bGluZSxcbiAgaW1hZ2VPdXRsaW5lLFxufSBmcm9tICdpb25pY29ucy9pY29ucyc7XG5pbXBvcnQgeyBGZWVkYmFja1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9mZWVkYmFjayc7XG5pbXBvcnQgeyBJMThuU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2kxOG4nO1xuaW1wb3J0IHsgVGl0bGVDb21wb25lbnQgfSBmcm9tICcuLi8uLi9hdG9tcy90aXRsZS90aXRsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQXR0YWNobWVudEl0ZW0sIEF0dGFjaG1lbnRVcGxvYWRlck1ldGFkYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbC1hdHRhY2htZW50LXVwbG9hZGVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0lvbkJ1dHRvbiwgSW9uSWNvbiwgSW9uTm90ZSwgSW9uU3Bpbm5lciwgVGl0bGVDb21wb25lbnRdLFxuICB0ZW1wbGF0ZVVybDogJy4vYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9hdHRhY2htZW50LXVwbG9hZGVyLmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgQXR0YWNobWVudFVwbG9hZGVyQ29tcG9uZW50IHtcbiAgcHJvcHMgPSBpbnB1dDxBdHRhY2htZW50VXBsb2FkZXJNZXRhZGF0YT4oe30pO1xuXG4gIGF0dGFjaG1lbnRzQ2hhbmdlID0gb3V0cHV0PEF0dGFjaG1lbnRJdGVtW10+KCk7XG5cbiAgcHJvdGVjdGVkIGkxOG4gPSBpbmplY3QoSTE4blNlcnZpY2UpO1xuICBwcml2YXRlIGZlZWRiYWNrU2VydmljZSA9IGluamVjdChGZWVkYmFja1NlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgYXR0YWNobWVudHMgPSBzaWduYWw8QXR0YWNobWVudEl0ZW1bXT4oW10pO1xuXG4gIG1heEZpbGVzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5wcm9wcygpLm1heEZpbGVzID8/IDUpO1xuICBhY2NlcHQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnByb3BzKCkuYWNjZXB0ID8/ICdpbWFnZS9qcGVnLGltYWdlL3BuZyxpbWFnZS93ZWJwLGFwcGxpY2F0aW9uL3BkZicpO1xuICBtYXhSZWFjaGVkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5hdHRhY2htZW50cygpLmxlbmd0aCA+PSB0aGlzLm1heEZpbGVzKCkpO1xuICBpc0Rpc2FibGVkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5wcm9wcygpLmRpc2FibGVkID09PSB0cnVlIHx8IHRoaXMubWF4UmVhY2hlZCgpKTtcbiAgaXNVcGxvYWRpbmcgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmF0dGFjaG1lbnRzKCkuc29tZShhID0+IGEuc3RhdHVzID09PSAndXBsb2FkaW5nJykpO1xuXG4gIGdldCByZWFkeVVybHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmF0dGFjaG1lbnRzKClcbiAgICAgIC5maWx0ZXIoYSA9PiBhLnN0YXR1cyA9PT0gJ3JlYWR5JylcbiAgICAgIC5tYXAoYSA9PiBhLnVybCEpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgYWRkSWNvbnMoe1xuICAgICAgYXR0YWNoT3V0bGluZSxcbiAgICAgIGNhbWVyYU91dGxpbmUsXG4gICAgICBjaGVja21hcmtDaXJjbGVPdXRsaW5lLFxuICAgICAgY2xvc2VDaXJjbGVPdXRsaW5lLFxuICAgICAgY2xvc2VPdXRsaW5lLFxuICAgICAgZG9jdW1lbnRPdXRsaW5lLFxuICAgICAgaW1hZ2VPdXRsaW5lLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgb25GaWxlc1NlbGVjdGVkKGV2ZW50OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgY29uc3QgZmlsZXMgPSBBcnJheS5mcm9tKGlucHV0LmZpbGVzID8/IFtdKTtcbiAgICBpbnB1dC52YWx1ZSA9ICcnO1xuICAgIGNvbnN0IGF2YWlsYWJsZSA9IHRoaXMubWF4RmlsZXMoKSAtIHRoaXMuYXR0YWNobWVudHMoKS5sZW5ndGg7XG4gICAgY29uc3QgdG9Qcm9jZXNzID0gZmlsZXMuc2xpY2UoMCwgYXZhaWxhYmxlKTtcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgdG9Qcm9jZXNzKSB7XG4gICAgICBjb25zdCBpZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgICB0aGlzLmF0dGFjaG1lbnRzLnVwZGF0ZShsaXN0ID0+IFsuLi5saXN0LCB7IGlkLCBmaWxlLCBzdGF0dXM6ICd1cGxvYWRpbmcnIH1dKTtcbiAgICAgIHRoaXMuYXR0YWNobWVudHNDaGFuZ2UuZW1pdCh0aGlzLmF0dGFjaG1lbnRzKCkpO1xuICAgICAgdGhpcy51cGxvYWRGaWxlKGlkLCBmaWxlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbXByZXNzSW1hZ2UoZmlsZTogRmlsZSk6IFByb21pc2U8RmlsZT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuZXcgQ29tcHJlc3NvcihmaWxlLCB7XG4gICAgICAgIHF1YWxpdHk6IDAuOCxcbiAgICAgICAgbWF4V2lkdGg6IDE5MjAsXG4gICAgICAgIG1heEhlaWdodDogMTkyMCxcbiAgICAgICAgY29udmVydFNpemU6IDIgKiAxMDI0ICogMTAyNCwgLy8gUE5HID4gMiBNQiDihpIgSlBFR1xuICAgICAgICBzdWNjZXNzKHJlc3VsdCkge1xuICAgICAgICAgIHJlc29sdmUobmV3IEZpbGUoW3Jlc3VsdF0sIGZpbGUubmFtZSwgeyB0eXBlOiByZXN1bHQudHlwZSB9KSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiByZWplY3QsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBsb2FkRmlsZShpZDogc3RyaW5nLCBmaWxlOiBGaWxlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNob3VsZENvbXByZXNzID0gdGhpcy5wcm9wcygpLmNvbXByZXNzSW1hZ2VzICE9PSBmYWxzZSAmJiBmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJyk7XG4gICAgICBjb25zdCBmaWxlVG9VcGxvYWQgPSBzaG91bGRDb21wcmVzcyA/IGF3YWl0IHRoaXMuY29tcHJlc3NJbWFnZShmaWxlKSA6IGZpbGU7XG4gICAgICBjb25zdCB1cGxvYWRGbiA9IHRoaXMucHJvcHMoKS51cGxvYWRGbiA/PyB0aGlzLmZlZWRiYWNrU2VydmljZT8udXBsb2FkQXR0YWNobWVudC5iaW5kKHRoaXMuZmVlZGJhY2tTZXJ2aWNlKTtcbiAgICAgIGlmICghdXBsb2FkRm4pIHRocm93IG5ldyBFcnJvcignTm8gdXBsb2FkIGZ1bmN0aW9uIGNvbmZpZ3VyZWQnKTtcbiAgICAgIGNvbnN0IHVybCA9IGF3YWl0IHVwbG9hZEZuKGZpbGVUb1VwbG9hZCk7XG4gICAgICB0aGlzLmF0dGFjaG1lbnRzLnVwZGF0ZShsaXN0ID0+IGxpc3QubWFwKGEgPT4gKGEuaWQgPT09IGlkID8geyAuLi5hLCBzdGF0dXM6ICdyZWFkeScsIHVybCB9IDogYSkpKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnN0IGVycm9yID0gdGhpcy5pMThuLnQoJ2F0dGFjaFVwbG9hZEZhaWxlZCcpO1xuICAgICAgdGhpcy5hdHRhY2htZW50cy51cGRhdGUobGlzdCA9PiBsaXN0Lm1hcChhID0+IChhLmlkID09PSBpZCA/IHsgLi4uYSwgc3RhdHVzOiAnZXJyb3InLCBlcnJvciB9IDogYSkpKTtcbiAgICB9XG4gICAgdGhpcy5hdHRhY2htZW50c0NoYW5nZS5lbWl0KHRoaXMuYXR0YWNobWVudHMoKSk7XG4gIH1cblxuICByZW1vdmUoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuYXR0YWNobWVudHMudXBkYXRlKGxpc3QgPT4gbGlzdC5maWx0ZXIoYSA9PiBhLmlkICE9PSBpZCkpO1xuICAgIHRoaXMuYXR0YWNobWVudHNDaGFuZ2UuZW1pdCh0aGlzLmF0dGFjaG1lbnRzKCkpO1xuICB9XG5cbiAgZm9ybWF0U2l6ZShieXRlczogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoYnl0ZXMgPCAxMDI0KSByZXR1cm4gYCR7Ynl0ZXN9IEJgO1xuICAgIGlmIChieXRlcyA8IDEwMjQgKiAxMDI0KSByZXR1cm4gYCR7TWF0aC5yb3VuZChieXRlcyAvIDEwMjQpfSBLQmA7XG4gICAgcmV0dXJuIGAkeyhieXRlcyAvICgxMDI0ICogMTAyNCkpLnRvRml4ZWQoMSl9IE1CYDtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImF0dGFjaG1lbnQtdXBsb2FkZXJcIj5cbiAgQGlmIChwcm9wcygpLnRpdGxlKSB7XG4gIDx2YWwtdGl0bGUgY2xhc3M9XCJhdHRhY2htZW50LXRpdGxlXCIgW3Byb3BzXT1cInsgY29udGVudDogcHJvcHMoKS50aXRsZSwgc2l6ZTogJ3NtYWxsJywgY29sb3I6ICdkYXJrJywgYm9sZDogZmFsc2UgfVwiIC8+XG4gIH1cblxuICA8aW5wdXQgI2ZpbGVQaWNrZXIgdHlwZT1cImZpbGVcIiBbYWNjZXB0XT1cImFjY2VwdCgpXCIgbXVsdGlwbGUgY2xhc3M9XCJoaWRkZW4taW5wdXRcIiAoY2hhbmdlKT1cIm9uRmlsZXNTZWxlY3RlZCgkZXZlbnQpXCIgLz5cblxuICA8ZGl2IGNsYXNzPVwiYXR0YWNobWVudC1hY3Rpb25zXCI+XG4gICAgPGlvbi1idXR0b24gZmlsbD1cIm91dGxpbmVcIiBjb2xvcj1cImRhcmtcIiBzaXplPVwic21hbGxcIiBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZCgpXCIgKGNsaWNrKT1cImZpbGVQaWNrZXIuY2xpY2soKVwiPlxuICAgICAgPGlvbi1pY29uIHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJhdHRhY2gtb3V0bGluZVwiPjwvaW9uLWljb24+XG4gICAgICB7eyBpMThuLnQoJ2F0dGFjaEFkZCcpIH19XG4gICAgPC9pb24tYnV0dG9uPlxuICAgIDwhLS0gbGFiZWwgdHJpY2s6IG5hdGl2ZSBicm93c2VyIGdlc3R1cmUgZm9yd2FyZGluZyDihpIgaU9TL1BXQSBubyBibG9xdWVhIGVsIHBpY2tlciAtLT5cbiAgICA8bGFiZWwgY2xhc3M9XCJjYW1lcmEtbGFiZWxcIiBbY2xhc3MuY2FtZXJhLWxhYmVsLS1kaXNhYmxlZF09XCJpc0Rpc2FibGVkKClcIj5cbiAgICAgIDxpbnB1dFxuICAgICAgICB0eXBlPVwiZmlsZVwiXG4gICAgICAgIGFjY2VwdD1cImltYWdlLypcIlxuICAgICAgICBjYXB0dXJlPVwiZW52aXJvbm1lbnRcIlxuICAgICAgICBjbGFzcz1cImhpZGRlbi1pbnB1dFwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkKClcIlxuICAgICAgICAoY2hhbmdlKT1cIm9uRmlsZXNTZWxlY3RlZCgkZXZlbnQpXCJcbiAgICAgIC8+XG4gICAgICA8aW9uLWljb24gbmFtZT1cImNhbWVyYS1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgIHt7IGkxOG4udCgnYXR0YWNoQ2FtZXJhJykgfX1cbiAgICA8L2xhYmVsPlxuICA8L2Rpdj5cblxuICBAaWYgKG1heFJlYWNoZWQoKSkge1xuICA8aW9uLW5vdGUgY29sb3I9XCJ3YXJuaW5nXCIgY2xhc3M9XCJtYXgtbm90ZVwiPlxuICAgIHt7IGkxOG4udCgnYXR0YWNoTWF4Q291bnQnLCAnX2dsb2JhbCcsIHsgY291bnQ6IG1heEZpbGVzKCkudG9TdHJpbmcoKSB9KSB9fVxuICA8L2lvbi1ub3RlPlxuICB9IEBpZiAoYXR0YWNobWVudHMoKS5sZW5ndGggPiAwKSB7XG4gIDxkaXYgY2xhc3M9XCJhdHRhY2htZW50LWxpc3RcIj5cbiAgICBAZm9yIChpdGVtIG9mIGF0dGFjaG1lbnRzKCk7IHRyYWNrIGl0ZW0uaWQpIHtcbiAgICA8ZGl2IGNsYXNzPVwiYXR0YWNobWVudC1pdGVtXCIgW2NsYXNzXT1cIidzdGF0dXMtJyArIGl0ZW0uc3RhdHVzXCI+XG4gICAgICA8aW9uLWljb25cbiAgICAgICAgY2xhc3M9XCJmaWxlLWljb25cIlxuICAgICAgICBbbmFtZV09XCJpdGVtLmZpbGUudHlwZS5zdGFydHNXaXRoKCdpbWFnZS8nKSA/ICdpbWFnZS1vdXRsaW5lJyA6ICdkb2N1bWVudC1vdXRsaW5lJ1wiXG4gICAgICA+PC9pb24taWNvbj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmaWxlLWluZm9cIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLW5hbWVcIj57eyBpdGVtLmZpbGUubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLXNpemVcIj57eyBmb3JtYXRTaXplKGl0ZW0uZmlsZS5zaXplKSB9fTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICBAaWYgKGl0ZW0uc3RhdHVzID09PSAndXBsb2FkaW5nJykge1xuICAgICAgPGlvbi1zcGlubmVyIGNsYXNzPVwic3RhdHVzLWljb25cIiBuYW1lPVwiY2lyY3VsYXJcIj48L2lvbi1zcGlubmVyPlxuICAgICAgfSBAZWxzZSBpZiAoaXRlbS5zdGF0dXMgPT09ICdyZWFkeScpIHtcbiAgICAgIDxpb24taWNvbiBjbGFzcz1cInN0YXR1cy1pY29uXCIgbmFtZT1cImNoZWNrbWFyay1jaXJjbGUtb3V0bGluZVwiIGNvbG9yPVwic3VjY2Vzc1wiPjwvaW9uLWljb24+XG4gICAgICB9IEBlbHNlIGlmIChpdGVtLnN0YXR1cyA9PT0gJ2Vycm9yJykge1xuICAgICAgPGlvbi1pY29uIGNsYXNzPVwic3RhdHVzLWljb25cIiBuYW1lPVwiY2xvc2UtY2lyY2xlLW91dGxpbmVcIiBjb2xvcj1cImRhbmdlclwiPjwvaW9uLWljb24+XG4gICAgICB9IEBpZiAoaXRlbS5zdGF0dXMgIT09ICd1cGxvYWRpbmcnKSB7XG4gICAgICA8aW9uLWJ1dHRvbiBmaWxsPVwiY2xlYXJcIiBzaXplPVwic21hbGxcIiBjb2xvcj1cImRhcmtcIiAoY2xpY2spPVwicmVtb3ZlKGl0ZW0uaWQpXCI+XG4gICAgICAgIDxpb24taWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgbmFtZT1cImNsb3NlLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgfSBAaWYgKGl0ZW0uc3RhdHVzID09PSAnZXJyb3InICYmIGl0ZW0uZXJyb3IpIHtcbiAgICAgIDxpb24tbm90ZSBjb2xvcj1cImRhbmdlclwiIGNsYXNzPVwiZXJyb3Itbm90ZVwiPnt7IGl0ZW0uZXJyb3IgfX08L2lvbi1ub3RlPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG4gIH0gQGlmIChwcm9wcygpLmhpbnQpIHtcbiAgPHAgY2xhc3M9XCJhdHRhY2htZW50LWhpbnRcIj57eyBwcm9wcygpLmhpbnQgfX08L3A+XG4gIH1cbjwvZGl2PlxuIl19
|
|
147
|
+
args: [{ selector: 'val-attachment-uploader', standalone: true, imports: [IonButton, IonIcon, IonNote, IonSpinner, TitleComponent], encapsulation: ViewEncapsulation.None, template: "<div class=\"attachment-uploader\">\n @if (props().title) {\n <val-title class=\"attachment-title\" [props]=\"{ content: props().title, size: 'small', color: 'dark', bold: false }\" />\n }\n\n <!-- file picker est\u00E1ndar -->\n <input #filePicker type=\"file\" [accept]=\"accept()\" multiple class=\"hidden-input\" (change)=\"onFilesSelected($event)\" />\n <!-- fallback c\u00E1mara: solo se dispara si getUserMedia falla/denegado -->\n <input\n #cameraPicker\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n class=\"hidden-input\"\n (change)=\"onFilesSelected($event)\"\n />\n\n <div class=\"attachment-actions\">\n <ion-button fill=\"outline\" color=\"dark\" size=\"small\" [disabled]=\"isDisabled()\" (click)=\"filePicker.click()\">\n <ion-icon slot=\"start\" name=\"attach-outline\"></ion-icon>\n {{ i18n.t('attachAdd') }}\n </ion-button>\n <ion-button fill=\"outline\" color=\"dark\" size=\"small\" [disabled]=\"isDisabled()\" (click)=\"openCamera()\">\n <ion-icon slot=\"start\" name=\"camera-outline\"></ion-icon>\n {{ i18n.t('attachCamera') }}\n </ion-button>\n </div>\n\n @if (maxReached()) {\n <ion-note color=\"warning\" class=\"max-note\">\n {{ i18n.t('attachMaxCount', '_global', { count: maxFiles().toString() }) }}\n </ion-note>\n } @if (attachments().length > 0) {\n <div class=\"attachment-list\">\n @for (item of attachments(); track item.id) {\n <div class=\"attachment-item\" [class]=\"'status-' + item.status\">\n <ion-icon\n class=\"file-icon\"\n [name]=\"item.file.type.startsWith('image/') ? 'image-outline' : 'document-outline'\"\n ></ion-icon>\n <div class=\"file-info\">\n <span class=\"file-name\">{{ item.file.name }}</span>\n <span class=\"file-size\">{{ formatSize(item.file.size) }}</span>\n </div>\n\n @if (item.status === 'uploading') {\n <ion-spinner class=\"status-icon\" name=\"circular\"></ion-spinner>\n } @else if (item.status === 'ready') {\n <ion-icon class=\"status-icon\" name=\"checkmark-circle-outline\" color=\"success\"></ion-icon>\n } @else if (item.status === 'error') {\n <ion-icon class=\"status-icon\" name=\"close-circle-outline\" color=\"danger\"></ion-icon>\n } @if (item.status !== 'uploading') {\n <ion-button fill=\"clear\" size=\"small\" color=\"dark\" (click)=\"remove(item.id)\">\n <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>\n </ion-button>\n } @if (item.status === 'error' && item.error) {\n <ion-note color=\"danger\" class=\"error-note\">{{ item.error }}</ion-note>\n }\n </div>\n }\n </div>\n } @if (props().hint) {\n <p class=\"attachment-hint\">{{ props().hint }}</p>\n }\n</div>\n\n<!-- Overlay de c\u00E1mara (getUserMedia) -->\n@if (showCameraOverlay()) {\n<div class=\"camera-overlay\" (click)=\"closeCamera()\">\n <div class=\"camera-modal\" (click)=\"$event.stopPropagation()\">\n <video #cameraVideo autoplay playsinline class=\"camera-preview\"></video>\n <div class=\"camera-controls\">\n <ion-button fill=\"outline\" color=\"dark\" (click)=\"closeCamera()\"> {{ i18n.t('attachCancel') }} </ion-button>\n <ion-button color=\"dark\" shape=\"round\" (click)=\"capturePhoto()\">\n <ion-icon slot=\"start\" name=\"camera-outline\"></ion-icon>\n {{ i18n.t('attachCapture') }}\n </ion-button>\n </div>\n </div>\n</div>\n}\n", styles: [".hidden-input{display:none}.camera-overlay{position:fixed;inset:0;z-index:9999;background:#000000d9;display:flex;align-items:center;justify-content:center}.camera-modal{display:flex;flex-direction:column;gap:16px;padding:16px;max-width:min(640px,95vw);width:100%}.camera-preview{width:100%;border-radius:12px;background:#000;aspect-ratio:16/9;object-fit:cover}.camera-controls{display:flex;justify-content:center;gap:12px}.camera-controls ion-button{margin:0;--color: #fff;--border-color: rgba(255, 255, 255, .5)}.attachment-uploader{display:flex;flex-direction:column;gap:8px}.attachment-title{display:block;margin-bottom:2px}.attachment-hint{margin:2px 0 0;text-align:right;font-size:.75rem;line-height:1.4;color:var(--ion-color-dark)}.attachment-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.attachment-actions ion-button{margin:0;height:32px}.attachment-list{display:flex;flex-direction:column;gap:4px}.attachment-item{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:8px;background:var(--ion-background-color, #fff);border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .08));flex-wrap:wrap}.attachment-item.status-error{border-color:var(--ion-color-danger)}.file-icon{font-size:1.375rem;color:var(--ion-text-color);flex-shrink:0}.file-info{flex:1;min-width:0;display:flex;flex-direction:column}.file-name{font-size:.8125rem;color:var(--ion-text-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-size{font-size:.6875rem;color:var(--ion-color-medium)}:host-context(.dark) .attachment-item,:host-context(.ion-palette-dark) .attachment-item,:host-context(html.ion-palette-dark) .attachment-item,:host-context(body.dark) .attachment-item,:host-context([data-theme=dark]) .attachment-item{background:#ffffff0a;border-color:#ffffff1f}:host-context(.dark) .attachment-item.status-error,:host-context(.ion-palette-dark) .attachment-item.status-error,:host-context(html.ion-palette-dark) .attachment-item.status-error,:host-context(body.dark) .attachment-item.status-error,:host-context([data-theme=dark]) .attachment-item.status-error{border-color:var(--ion-color-danger)}.status-icon{font-size:1.25rem;flex-shrink:0}.error-note{font-size:.6875rem;width:100%}.max-note{font-size:.75rem}\n"] }]
|
|
148
|
+
}], ctorParameters: () => [], propDecorators: { cameraPicker: [{
|
|
149
|
+
type: ViewChild,
|
|
150
|
+
args: ['cameraPicker']
|
|
151
|
+
}], cameraVideo: [{
|
|
152
|
+
type: ViewChild,
|
|
153
|
+
args: ['cameraVideo']
|
|
154
|
+
}] } });
|
|
155
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL2F0dGFjaG1lbnQtdXBsb2FkZXIvYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL2F0dGFjaG1lbnQtdXBsb2FkZXIvYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFVBQVUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUNMLFNBQVMsRUFFVCxTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLFFBQVEsRUFDUixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDcEMsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2Isc0JBQXNCLEVBQ3RCLGtCQUFrQixFQUNsQixZQUFZLEVBQ1osZUFBZSxFQUNmLFlBQVksR0FDYixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDOztBQVduRSxNQUFNLE9BQU8sMkJBQTJCO0lBc0J0QyxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUU7YUFDdEIsTUFBTSxDQUFD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O1FBQ3RCLElBQUksS0FBSyxHQUFHLElBQUk7WUFBRSxPQUFPLEdBQUcsS0FBSyxJQUFJLENBQUM7UUFDdEMsSUFBSSxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUk7WUFBRSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNqRSxPQUFPLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUNwRCxDQUFDOytHQXJKVSwyQkFBMkI7bUdBQTNCLDJCQUEyQix1ZENwQ3hDLGs1R0FpRkEsc3dFRGxEWSxTQUFTLG9QQUFFLE9BQU8sMkpBQUUsT0FBTyxnRkFBRSxVQUFVLHlHQUFFLGNBQWM7OzRGQUt0RCwyQkFBMkI7a0JBUnZDLFNBQVM7K0JBQ0UseUJBQXlCLGNBQ3ZCLElBQUksV0FDUCxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxjQUFjLENBQUMsaUJBR25ELGlCQUFpQixDQUFDLElBQUk7d0RBR1YsWUFBWTtzQkFBdEMsU0FBUzt1QkFBQyxjQUFjO2dCQUNDLFdBQVc7c0JBQXBDLFNBQVM7dUJBQUMsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDb21wcmVzc29yIGZyb20gJ2NvbXByZXNzb3Jqcyc7XG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGNvbXB1dGVkLFxuICBpbmplY3QsXG4gIGlucHV0LFxuICBvdXRwdXQsXG4gIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJb25CdXR0b24sIElvbkljb24sIElvbk5vdGUsIElvblNwaW5uZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhci9zdGFuZGFsb25lJztcbmltcG9ydCB7IGFkZEljb25zIH0gZnJvbSAnaW9uaWNvbnMnO1xuaW1wb3J0IHtcbiAgYXR0YWNoT3V0bGluZSxcbiAgY2FtZXJhT3V0bGluZSxcbiAgY2hlY2ttYXJrQ2lyY2xlT3V0bGluZSxcbiAgY2xvc2VDaXJjbGVPdXRsaW5lLFxuICBjbG9zZU91dGxpbmUsXG4gIGRvY3VtZW50T3V0bGluZSxcbiAgaW1hZ2VPdXRsaW5lLFxufSBmcm9tICdpb25pY29ucy9pY29ucyc7XG5pbXBvcnQgeyBGZWVkYmFja1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9mZWVkYmFjayc7XG5pbXBvcnQgeyBJMThuU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2kxOG4nO1xuaW1wb3J0IHsgVGl0bGVDb21wb25lbnQgfSBmcm9tICcuLi8uLi9hdG9tcy90aXRsZS90aXRsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQXR0YWNobWVudEl0ZW0sIEF0dGFjaG1lbnRVcGxvYWRlck1ldGFkYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbC1hdHRhY2htZW50LXVwbG9hZGVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0lvbkJ1dHRvbiwgSW9uSWNvbiwgSW9uTm90ZSwgSW9uU3Bpbm5lciwgVGl0bGVDb21wb25lbnRdLFxuICB0ZW1wbGF0ZVVybDogJy4vYXR0YWNobWVudC11cGxvYWRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9hdHRhY2htZW50LXVwbG9hZGVyLmNvbXBvbmVudC5zY3NzJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgQXR0YWNobWVudFVwbG9hZGVyQ29tcG9uZW50IHtcbiAgQFZpZXdDaGlsZCgnY2FtZXJhUGlja2VyJykgY2FtZXJhUGlja2VyITogRWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgnY2FtZXJhVmlkZW8nKSBjYW1lcmFWaWRlbyE6IEVsZW1lbnRSZWY8SFRNTFZpZGVvRWxlbWVudD47XG5cbiAgcHJvcHMgPSBpbnB1dDxBdHRhY2htZW50VXBsb2FkZXJNZXRhZGF0YT4oe30pO1xuXG4gIGF0dGFjaG1lbnRzQ2hhbmdlID0gb3V0cHV0PEF0dGFjaG1lbnRJdGVtW10+KCk7XG5cbiAgcHJvdGVjdGVkIGkxOG4gPSBpbmplY3QoSTE4blNlcnZpY2UpO1xuICBwcml2YXRlIGZlZWRiYWNrU2VydmljZSA9IGluamVjdChGZWVkYmFja1NlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgYXR0YWNobWVudHMgPSBzaWduYWw8QXR0YWNobWVudEl0ZW1bXT4oW10pO1xuICBzaG93Q2FtZXJhT3ZlcmxheSA9IHNpZ25hbChmYWxzZSk7XG5cbiAgcHJpdmF0ZSBjYW1lcmFTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG5cbiAgbWF4RmlsZXMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnByb3BzKCkubWF4RmlsZXMgPz8gNSk7XG4gIGFjY2VwdCA9IGNvbXB1dGVkKCgpID0+IHRoaXMucHJvcHMoKS5hY2NlcHQgPz8gJ2ltYWdlL2pwZWcsaW1hZ2UvcG5nLGltYWdlL3dlYnAsYXBwbGljYXRpb24vcGRmJyk7XG4gIG1heFJlYWNoZWQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmF0dGFjaG1lbnRzKCkubGVuZ3RoID49IHRoaXMubWF4RmlsZXMoKSk7XG4gIGlzRGlzYWJsZWQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnByb3BzKCkuZGlzYWJsZWQgPT09IHRydWUgfHwgdGhpcy5tYXhSZWFjaGVkKCkpO1xuICBpc1VwbG9hZGluZyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuYXR0YWNobWVudHMoKS5zb21lKGEgPT4gYS5zdGF0dXMgPT09ICd1cGxvYWRpbmcnKSk7XG5cbiAgZ2V0IHJlYWR5VXJscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuYXR0YWNobWVudHMoKVxuICAgICAgLmZpbHRlcihhID0+IGEuc3RhdHVzID09PSAncmVhZHknKVxuICAgICAgLm1hcChhID0+IGEudXJsISk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBhZGRJY29ucyh7XG4gICAgICBhdHRhY2hPdXRsaW5lLFxuICAgICAgY2FtZXJhT3V0bGluZSxcbiAgICAgIGNoZWNrbWFya0NpcmNsZU91dGxpbmUsXG4gICAgICBjbG9zZUNpcmNsZU91dGxpbmUsXG4gICAgICBjbG9zZU91dGxpbmUsXG4gICAgICBkb2N1bWVudE91dGxpbmUsXG4gICAgICBpbWFnZU91dGxpbmUsXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBvcGVuQ2FtZXJhKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghbmF2aWdhdG9yLm1lZGlhRGV2aWNlcz8uZ2V0VXNlck1lZGlhKSB7XG4gICAgICB0aGlzLmNhbWVyYVBpY2tlci5uYXRpdmVFbGVtZW50LmNsaWNrKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLmNhbWVyYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHtcbiAgICAgICAgdmlkZW86IHsgZmFjaW5nTW9kZTogeyBpZGVhbDogJ2Vudmlyb25tZW50JyB9LCB3aWR0aDogeyBpZGVhbDogMTkyMCB9LCBoZWlnaHQ6IHsgaWRlYWw6IDEwODAgfSB9LFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNob3dDYW1lcmFPdmVybGF5LnNldCh0cnVlKTtcbiAgICAgIC8vIEVsIHZpZGVvIGVsZW1lbnQgc2UgcmVuZGVyaXphIGRlc3B1w6lzIGRlbCBzaWduYWwg4oaSIGVzcGVyYXIgdW4gdGlja1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmNhbWVyYVZpZGVvPy5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5jYW1lcmFWaWRlby5uYXRpdmVFbGVtZW50LnNyY09iamVjdCA9IHRoaXMuY2FtZXJhU3RyZWFtO1xuICAgICAgICB9XG4gICAgICB9LCA1MCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBQZXJtaXNvIGRlbmVnYWRvIG8gZGlzcG9zaXRpdm8gc2luIGPDoW1hcmEg4oaSIGZhbGxiYWNrIGZpbGUgcGlja2VyXG4gICAgICB0aGlzLmNhbWVyYVBpY2tlci5uYXRpdmVFbGVtZW50LmNsaWNrKCk7XG4gICAgfVxuICB9XG5cbiAgY2FwdHVyZVBob3RvKCk6IHZvaWQge1xuICAgIGNvbnN0IHZpZGVvID0gdGhpcy5jYW1lcmFWaWRlbz8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIXZpZGVvKSByZXR1cm47XG5cbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjYW52YXMud2lkdGggPSB2aWRlby52aWRlb1dpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSB2aWRlby52aWRlb0hlaWdodDtcbiAgICBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSEuZHJhd0ltYWdlKHZpZGVvLCAwLCAwKTtcblxuICAgIGNhbnZhcy50b0Jsb2IoXG4gICAgICBibG9iID0+IHtcbiAgICAgICAgaWYgKCFibG9iKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGZpbGUgPSBuZXcgRmlsZShbYmxvYl0sIGBmb3RvXyR7RGF0ZS5ub3coKX0uanBnYCwgeyB0eXBlOiAnaW1hZ2UvanBlZycgfSk7XG4gICAgICAgIHRoaXMuY2xvc2VDYW1lcmEoKTtcbiAgICAgICAgdGhpcy5wcm9jZXNzRmlsZXMoW2ZpbGVdKTtcbiAgICAgIH0sXG4gICAgICAnaW1hZ2UvanBlZycsXG4gICAgICAwLjlcbiAgICApO1xuICB9XG5cbiAgY2xvc2VDYW1lcmEoKTogdm9pZCB7XG4gICAgdGhpcy5jYW1lcmFTdHJlYW0/LmdldFRyYWNrcygpLmZvckVhY2godCA9PiB0LnN0b3AoKSk7XG4gICAgdGhpcy5jYW1lcmFTdHJlYW0gPSBudWxsO1xuICAgIGlmICh0aGlzLmNhbWVyYVZpZGVvPy5uYXRpdmVFbGVtZW50KSB7XG4gICAgICB0aGlzLmNhbWVyYVZpZGVvLm5hdGl2ZUVsZW1lbnQuc3JjT2JqZWN0ID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5zaG93Q2FtZXJhT3ZlcmxheS5zZXQoZmFsc2UpO1xuICB9XG5cbiAgYXN5bmMgb25GaWxlc1NlbGVjdGVkKGV2ZW50OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgY29uc3QgZmlsZXMgPSBBcnJheS5mcm9tKGlucHV0LmZpbGVzID8/IFtdKTtcbiAgICBpbnB1dC52YWx1ZSA9ICcnO1xuICAgIHRoaXMucHJvY2Vzc0ZpbGVzKGZpbGVzKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc0ZpbGVzKGZpbGVzOiBGaWxlW10pOiB2b2lkIHtcbiAgICBjb25zdCBhdmFpbGFibGUgPSB0aGlzLm1heEZpbGVzKCkgLSB0aGlzLmF0dGFjaG1lbnRzKCkubGVuZ3RoO1xuICAgIGNvbnN0IHRvUHJvY2VzcyA9IGZpbGVzLnNsaWNlKDAsIGF2YWlsYWJsZSk7XG4gICAgZm9yIChjb25zdCBmaWxlIG9mIHRvUHJvY2Vzcykge1xuICAgICAgY29uc3QgaWQgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgICAgdGhpcy5hdHRhY2htZW50cy51cGRhdGUobGlzdCA9PiBbLi4ubGlzdCwgeyBpZCwgZmlsZSwgc3RhdHVzOiAndXBsb2FkaW5nJyB9XSk7XG4gICAgICB0aGlzLmF0dGFjaG1lbnRzQ2hhbmdlLmVtaXQodGhpcy5hdHRhY2htZW50cygpKTtcbiAgICAgIHRoaXMudXBsb2FkRmlsZShpZCwgZmlsZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wcmVzc0ltYWdlKGZpbGU6IEZpbGUpOiBQcm9taXNlPEZpbGU+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgbmV3IENvbXByZXNzb3IoZmlsZSwge1xuICAgICAgICBxdWFsaXR5OiAwLjgsXG4gICAgICAgIG1heFdpZHRoOiAxOTIwLFxuICAgICAgICBtYXhIZWlnaHQ6IDE5MjAsXG4gICAgICAgIGNvbnZlcnRTaXplOiAyICogMTAyNCAqIDEwMjQsXG4gICAgICAgIHN1Y2Nlc3MocmVzdWx0KSB7XG4gICAgICAgICAgcmVzb2x2ZShuZXcgRmlsZShbcmVzdWx0XSwgZmlsZS5uYW1lLCB7IHR5cGU6IHJlc3VsdC50eXBlIH0pKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IHJlamVjdCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGxvYWRGaWxlKGlkOiBzdHJpbmcsIGZpbGU6IEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc2hvdWxkQ29tcHJlc3MgPSB0aGlzLnByb3BzKCkuY29tcHJlc3NJbWFnZXMgIT09IGZhbHNlICYmIGZpbGUudHlwZS5zdGFydHNXaXRoKCdpbWFnZS8nKTtcbiAgICAgIGNvbnN0IGZpbGVUb1VwbG9hZCA9IHNob3VsZENvbXByZXNzID8gYXdhaXQgdGhpcy5jb21wcmVzc0ltYWdlKGZpbGUpIDogZmlsZTtcbiAgICAgIGNvbnN0IHVwbG9hZEZuID0gdGhpcy5wcm9wcygpLnVwbG9hZEZuID8/IHRoaXMuZmVlZGJhY2tTZXJ2aWNlPy51cGxvYWRBdHRhY2htZW50LmJpbmQodGhpcy5mZWVkYmFja1NlcnZpY2UpO1xuICAgICAgaWYgKCF1cGxvYWRGbikgdGhyb3cgbmV3IEVycm9yKCdObyB1cGxvYWQgZnVuY3Rpb24gY29uZmlndXJlZCcpO1xuICAgICAgY29uc3QgdXJsID0gYXdhaXQgdXBsb2FkRm4oZmlsZVRvVXBsb2FkKTtcbiAgICAgIHRoaXMuYXR0YWNobWVudHMudXBkYXRlKGxpc3QgPT4gbGlzdC5tYXAoYSA9PiAoYS5pZCA9PT0gaWQgPyB7IC4uLmEsIHN0YXR1czogJ3JlYWR5JywgdXJsIH0gOiBhKSkpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgY29uc3QgZXJyb3IgPSB0aGlzLmkxOG4udCgnYXR0YWNoVXBsb2FkRmFpbGVkJyk7XG4gICAgICB0aGlzLmF0dGFjaG1lbnRzLnVwZGF0ZShsaXN0ID0+IGxpc3QubWFwKGEgPT4gKGEuaWQgPT09IGlkID8geyAuLi5hLCBzdGF0dXM6ICdlcnJvcicsIGVycm9yIH0gOiBhKSkpO1xuICAgIH1cbiAgICB0aGlzLmF0dGFjaG1lbnRzQ2hhbmdlLmVtaXQodGhpcy5hdHRhY2htZW50cygpKTtcbiAgfVxuXG4gIHJlbW92ZShpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5hdHRhY2htZW50cy51cGRhdGUobGlzdCA9PiBsaXN0LmZpbHRlcihhID0+IGEuaWQgIT09IGlkKSk7XG4gICAgdGhpcy5hdHRhY2htZW50c0NoYW5nZS5lbWl0KHRoaXMuYXR0YWNobWVudHMoKSk7XG4gIH1cblxuICBmb3JtYXRTaXplKGJ5dGVzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmIChieXRlcyA8IDEwMjQpIHJldHVybiBgJHtieXRlc30gQmA7XG4gICAgaWYgKGJ5dGVzIDwgMTAyNCAqIDEwMjQpIHJldHVybiBgJHtNYXRoLnJvdW5kKGJ5dGVzIC8gMTAyNCl9IEtCYDtcbiAgICByZXR1cm4gYCR7KGJ5dGVzIC8gKDEwMjQgKiAxMDI0KSkudG9GaXhlZCgxKX0gTUJgO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiYXR0YWNobWVudC11cGxvYWRlclwiPlxuICBAaWYgKHByb3BzKCkudGl0bGUpIHtcbiAgPHZhbC10aXRsZSBjbGFzcz1cImF0dGFjaG1lbnQtdGl0bGVcIiBbcHJvcHNdPVwieyBjb250ZW50OiBwcm9wcygpLnRpdGxlLCBzaXplOiAnc21hbGwnLCBjb2xvcjogJ2RhcmsnLCBib2xkOiBmYWxzZSB9XCIgLz5cbiAgfVxuXG4gIDwhLS0gZmlsZSBwaWNrZXIgZXN0w6FuZGFyIC0tPlxuICA8aW5wdXQgI2ZpbGVQaWNrZXIgdHlwZT1cImZpbGVcIiBbYWNjZXB0XT1cImFjY2VwdCgpXCIgbXVsdGlwbGUgY2xhc3M9XCJoaWRkZW4taW5wdXRcIiAoY2hhbmdlKT1cIm9uRmlsZXNTZWxlY3RlZCgkZXZlbnQpXCIgLz5cbiAgPCEtLSBmYWxsYmFjayBjw6FtYXJhOiBzb2xvIHNlIGRpc3BhcmEgc2kgZ2V0VXNlck1lZGlhIGZhbGxhL2RlbmVnYWRvIC0tPlxuICA8aW5wdXRcbiAgICAjY2FtZXJhUGlja2VyXG4gICAgdHlwZT1cImZpbGVcIlxuICAgIGFjY2VwdD1cImltYWdlLypcIlxuICAgIGNhcHR1cmU9XCJlbnZpcm9ubWVudFwiXG4gICAgY2xhc3M9XCJoaWRkZW4taW5wdXRcIlxuICAgIChjaGFuZ2UpPVwib25GaWxlc1NlbGVjdGVkKCRldmVudClcIlxuICAvPlxuXG4gIDxkaXYgY2xhc3M9XCJhdHRhY2htZW50LWFjdGlvbnNcIj5cbiAgICA8aW9uLWJ1dHRvbiBmaWxsPVwib3V0bGluZVwiIGNvbG9yPVwiZGFya1wiIHNpemU9XCJzbWFsbFwiIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkKClcIiAoY2xpY2spPVwiZmlsZVBpY2tlci5jbGljaygpXCI+XG4gICAgICA8aW9uLWljb24gc2xvdD1cInN0YXJ0XCIgbmFtZT1cImF0dGFjaC1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgIHt7IGkxOG4udCgnYXR0YWNoQWRkJykgfX1cbiAgICA8L2lvbi1idXR0b24+XG4gICAgPGlvbi1idXR0b24gZmlsbD1cIm91dGxpbmVcIiBjb2xvcj1cImRhcmtcIiBzaXplPVwic21hbGxcIiBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZCgpXCIgKGNsaWNrKT1cIm9wZW5DYW1lcmEoKVwiPlxuICAgICAgPGlvbi1pY29uIHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJjYW1lcmEtb3V0bGluZVwiPjwvaW9uLWljb24+XG4gICAgICB7eyBpMThuLnQoJ2F0dGFjaENhbWVyYScpIH19XG4gICAgPC9pb24tYnV0dG9uPlxuICA8L2Rpdj5cblxuICBAaWYgKG1heFJlYWNoZWQoKSkge1xuICA8aW9uLW5vdGUgY29sb3I9XCJ3YXJuaW5nXCIgY2xhc3M9XCJtYXgtbm90ZVwiPlxuICAgIHt7IGkxOG4udCgnYXR0YWNoTWF4Q291bnQnLCAnX2dsb2JhbCcsIHsgY291bnQ6IG1heEZpbGVzKCkudG9TdHJpbmcoKSB9KSB9fVxuICA8L2lvbi1ub3RlPlxuICB9IEBpZiAoYXR0YWNobWVudHMoKS5sZW5ndGggPiAwKSB7XG4gIDxkaXYgY2xhc3M9XCJhdHRhY2htZW50LWxpc3RcIj5cbiAgICBAZm9yIChpdGVtIG9mIGF0dGFjaG1lbnRzKCk7IHRyYWNrIGl0ZW0uaWQpIHtcbiAgICA8ZGl2IGNsYXNzPVwiYXR0YWNobWVudC1pdGVtXCIgW2NsYXNzXT1cIidzdGF0dXMtJyArIGl0ZW0uc3RhdHVzXCI+XG4gICAgICA8aW9uLWljb25cbiAgICAgICAgY2xhc3M9XCJmaWxlLWljb25cIlxuICAgICAgICBbbmFtZV09XCJpdGVtLmZpbGUudHlwZS5zdGFydHNXaXRoKCdpbWFnZS8nKSA/ICdpbWFnZS1vdXRsaW5lJyA6ICdkb2N1bWVudC1vdXRsaW5lJ1wiXG4gICAgICA+PC9pb24taWNvbj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmaWxlLWluZm9cIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLW5hbWVcIj57eyBpdGVtLmZpbGUubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLXNpemVcIj57eyBmb3JtYXRTaXplKGl0ZW0uZmlsZS5zaXplKSB9fTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICBAaWYgKGl0ZW0uc3RhdHVzID09PSAndXBsb2FkaW5nJykge1xuICAgICAgPGlvbi1zcGlubmVyIGNsYXNzPVwic3RhdHVzLWljb25cIiBuYW1lPVwiY2lyY3VsYXJcIj48L2lvbi1zcGlubmVyPlxuICAgICAgfSBAZWxzZSBpZiAoaXRlbS5zdGF0dXMgPT09ICdyZWFkeScpIHtcbiAgICAgIDxpb24taWNvbiBjbGFzcz1cInN0YXR1cy1pY29uXCIgbmFtZT1cImNoZWNrbWFyay1jaXJjbGUtb3V0bGluZVwiIGNvbG9yPVwic3VjY2Vzc1wiPjwvaW9uLWljb24+XG4gICAgICB9IEBlbHNlIGlmIChpdGVtLnN0YXR1cyA9PT0gJ2Vycm9yJykge1xuICAgICAgPGlvbi1pY29uIGNsYXNzPVwic3RhdHVzLWljb25cIiBuYW1lPVwiY2xvc2UtY2lyY2xlLW91dGxpbmVcIiBjb2xvcj1cImRhbmdlclwiPjwvaW9uLWljb24+XG4gICAgICB9IEBpZiAoaXRlbS5zdGF0dXMgIT09ICd1cGxvYWRpbmcnKSB7XG4gICAgICA8aW9uLWJ1dHRvbiBmaWxsPVwiY2xlYXJcIiBzaXplPVwic21hbGxcIiBjb2xvcj1cImRhcmtcIiAoY2xpY2spPVwicmVtb3ZlKGl0ZW0uaWQpXCI+XG4gICAgICAgIDxpb24taWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgbmFtZT1cImNsb3NlLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgfSBAaWYgKGl0ZW0uc3RhdHVzID09PSAnZXJyb3InICYmIGl0ZW0uZXJyb3IpIHtcbiAgICAgIDxpb24tbm90ZSBjb2xvcj1cImRhbmdlclwiIGNsYXNzPVwiZXJyb3Itbm90ZVwiPnt7IGl0ZW0uZXJyb3IgfX08L2lvbi1ub3RlPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG4gIH0gQGlmIChwcm9wcygpLmhpbnQpIHtcbiAgPHAgY2xhc3M9XCJhdHRhY2htZW50LWhpbnRcIj57eyBwcm9wcygpLmhpbnQgfX08L3A+XG4gIH1cbjwvZGl2PlxuXG48IS0tIE92ZXJsYXkgZGUgY8OhbWFyYSAoZ2V0VXNlck1lZGlhKSAtLT5cbkBpZiAoc2hvd0NhbWVyYU92ZXJsYXkoKSkge1xuPGRpdiBjbGFzcz1cImNhbWVyYS1vdmVybGF5XCIgKGNsaWNrKT1cImNsb3NlQ2FtZXJhKClcIj5cbiAgPGRpdiBjbGFzcz1cImNhbWVyYS1tb2RhbFwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8dmlkZW8gI2NhbWVyYVZpZGVvIGF1dG9wbGF5IHBsYXlzaW5saW5lIGNsYXNzPVwiY2FtZXJhLXByZXZpZXdcIj48L3ZpZGVvPlxuICAgIDxkaXYgY2xhc3M9XCJjYW1lcmEtY29udHJvbHNcIj5cbiAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJvdXRsaW5lXCIgY29sb3I9XCJkYXJrXCIgKGNsaWNrKT1cImNsb3NlQ2FtZXJhKClcIj4ge3sgaTE4bi50KCdhdHRhY2hDYW5jZWwnKSB9fSA8L2lvbi1idXR0b24+XG4gICAgICA8aW9uLWJ1dHRvbiBjb2xvcj1cImRhcmtcIiBzaGFwZT1cInJvdW5kXCIgKGNsaWNrKT1cImNhcHR1cmVQaG90bygpXCI+XG4gICAgICAgIDxpb24taWNvbiBzbG90PVwic3RhcnRcIiBuYW1lPVwiY2FtZXJhLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgICB7eyBpMThuLnQoJ2F0dGFjaENhcHR1cmUnKSB9fVxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxufVxuIl19
|