@sumaris-net/ngx-components 18.5.14 → 18.6.0

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.
Files changed (43) hide show
  1. package/doc/changelog.md +5 -0
  2. package/esm2022/public_api.mjs +10 -2
  3. package/esm2022/src/app/core/about/about.modal.mjs +5 -4
  4. package/esm2022/src/app/core/home/home.mjs +5 -5
  5. package/esm2022/src/app/core/home/home.module.mjs +7 -3
  6. package/esm2022/src/app/shared/file/url.utils.mjs +164 -0
  7. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +40 -28
  8. package/esm2022/src/app/shared/markdown/markdown.component.mjs +259 -0
  9. package/esm2022/src/app/shared/markdown/markdown.directive.mjs +34 -0
  10. package/esm2022/src/app/shared/markdown/markdown.modal.mjs +75 -0
  11. package/esm2022/src/app/shared/markdown/markdown.module.mjs +88 -0
  12. package/esm2022/src/app/shared/markdown/markdown.service.mjs +202 -0
  13. package/esm2022/src/app/shared/markdown/markdown.utils.mjs +78 -0
  14. package/esm2022/src/app/shared/markdown/testing/markdown.test.mjs +45 -0
  15. package/esm2022/src/app/shared/markdown/testing/markdown.testing.module.mjs +29 -0
  16. package/esm2022/src/app/shared/material/material.animations.mjs +31 -1
  17. package/esm2022/src/app/shared/pipes/pipes.module.mjs +5 -2
  18. package/esm2022/src/app/shared/pipes/string.pipes.mjs +17 -1
  19. package/esm2022/src/app/shared/shared.module.mjs +11 -9
  20. package/esm2022/src/app/shared/shared.testing.module.mjs +13 -5
  21. package/fesm2022/sumaris-net.ngx-components.mjs +6642 -5746
  22. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  23. package/package.json +2 -1
  24. package/public_api.d.ts +9 -1
  25. package/src/app/core/home/home.module.d.ts +2 -1
  26. package/src/app/shared/file/url.utils.d.ts +77 -0
  27. package/src/app/shared/image/gallery/image-gallery.component.d.ts +10 -1
  28. package/src/app/shared/inputs.d.ts +1 -1
  29. package/src/app/shared/markdown/markdown.component.d.ts +76 -0
  30. package/src/app/shared/markdown/markdown.directive.d.ts +13 -0
  31. package/src/app/shared/{help/help.modal.d.ts → markdown/markdown.modal.d.ts} +11 -12
  32. package/src/app/shared/markdown/markdown.module.d.ts +18 -0
  33. package/src/app/shared/markdown/markdown.service.d.ts +38 -0
  34. package/src/app/shared/markdown/markdown.utils.d.ts +25 -0
  35. package/src/app/shared/markdown/testing/markdown.test.d.ts +15 -0
  36. package/src/app/shared/markdown/testing/markdown.testing.module.d.ts +11 -0
  37. package/src/app/shared/material/material.animations.d.ts +1 -0
  38. package/src/app/shared/pipes/pipes.module.d.ts +1 -1
  39. package/src/app/shared/pipes/string.pipes.d.ts +5 -0
  40. package/src/app/shared/shared.module.d.ts +19 -19
  41. package/src/app/shared/shared.testing.module.d.ts +2 -1
  42. package/src/assets/manifest.json +1 -1
  43. package/esm2022/src/app/shared/help/help.modal.mjs +0 -86
@@ -1,86 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2
- import { HttpErrorResponse } from '@angular/common/http';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "@ionic/angular";
5
- import * as i2 from "../../core/services/platform.service";
6
- import * as i3 from "../../core/services/local-settings.service";
7
- import * as i4 from "@ngx-translate/core";
8
- import * as i5 from "../../core/services/network.service";
9
- import * as i6 from "@angular/common";
10
- import * as i7 from "ngx-markdown";
11
- import * as i8 from "../toolbar/modal-toolbar";
12
- export class AppHelpModalUtils {
13
- static async show(modalCtrl, options) {
14
- const modal = await modalCtrl.create({
15
- component: AppHelpModal,
16
- componentProps: options,
17
- keyboardClose: true,
18
- cssClass: 'modal-large',
19
- });
20
- await modal.present();
21
- }
22
- }
23
- export class AppHelpModal {
24
- injector;
25
- viewCtrl;
26
- platform;
27
- settings;
28
- translate;
29
- network;
30
- cd;
31
- debug;
32
- loading = true;
33
- error = undefined;
34
- title;
35
- showError = true;
36
- markdownContent;
37
- markdownUrl;
38
- constructor(injector, viewCtrl, platform, settings, translate, network, cd) {
39
- this.injector = injector;
40
- this.viewCtrl = viewCtrl;
41
- this.platform = platform;
42
- this.settings = settings;
43
- this.translate = translate;
44
- this.network = network;
45
- this.cd = cd;
46
- // TODO: for DEV only
47
- //this.debug = !environment.production;
48
- }
49
- close(_) {
50
- return this.viewCtrl.dismiss();
51
- }
52
- markAsLoaded() {
53
- this.loading = false;
54
- this.error = null;
55
- this.cd.markForCheck();
56
- }
57
- onLoadError(error) {
58
- console.error('[help-modal] Error loading help content: ', error);
59
- // Translate error
60
- if (error instanceof HttpErrorResponse && this.network.offline) {
61
- console.error('[help-modal] Error loading help content (offline: true): ', error);
62
- this.error = 'NETWORK.INFO.OFFLINE';
63
- }
64
- else {
65
- console.error('[help-modal] Error loading help content: ', error);
66
- this.error = 'ERROR.LOAD_DATA_ERROR';
67
- }
68
- this.loading = false;
69
- this.cd.markForCheck();
70
- }
71
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppHelpModal, deps: [{ token: i0.Injector }, { token: i1.ModalController }, { token: i2.PlatformService }, { token: i3.LocalSettingsService }, { token: i4.TranslateService }, { token: i5.NetworkService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
72
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AppHelpModal, selector: "app-help-modal", inputs: { title: "title", showError: "showError", markdownContent: "markdownContent", markdownUrl: "markdownUrl" }, ngImport: i0, template: "@if (title) {\n <app-modal-toolbar\n color=\"light\"\n [title]=\"title | translate\"\n (cancel)=\"close($event)\"\n [showSpinner]=\"loading\"\n ></app-modal-toolbar>\n}\n\n<ion-content class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"showError && error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n @if (markdownContent) {\n <markdown [data]=\"markdownContent\" (ready)=\"markAsLoaded()\" emoji></markdown>\n } @else if (markdownUrl) {\n <markdown [src]=\"markdownUrl\" (load)=\"markAsLoaded()\" (error)=\"onLoadError($event)\" emoji></markdown>\n }\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar>\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"close()\">{{ 'COMMON.BTN_CLOSE' | translate }}</ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1.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: i1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonRow, selector: "ion-row" }, { kind: "component", type: i1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i7.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: i8.ModalToolbarComponent, selector: "app-modal-toolbar", inputs: ["modalName", "title", "color", "showSpinner", "canValidate", "validateIcon"], outputs: ["cancel", "validate"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
73
- }
74
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppHelpModal, decorators: [{
75
- type: Component,
76
- args: [{ selector: 'app-help-modal', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (title) {\n <app-modal-toolbar\n color=\"light\"\n [title]=\"title | translate\"\n (cancel)=\"close($event)\"\n [showSpinner]=\"loading\"\n ></app-modal-toolbar>\n}\n\n<ion-content class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"showError && error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n @if (markdownContent) {\n <markdown [data]=\"markdownContent\" (ready)=\"markAsLoaded()\" emoji></markdown>\n } @else if (markdownUrl) {\n <markdown [src]=\"markdownUrl\" (load)=\"markAsLoaded()\" (error)=\"onLoadError($event)\" emoji></markdown>\n }\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar>\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"close()\">{{ 'COMMON.BTN_CLOSE' | translate }}</ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n</ion-footer>\n" }]
77
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.ModalController }, { type: i2.PlatformService }, { type: i3.LocalSettingsService }, { type: i4.TranslateService }, { type: i5.NetworkService }, { type: i0.ChangeDetectorRef }], propDecorators: { title: [{
78
- type: Input
79
- }], showError: [{
80
- type: Input
81
- }], markdownContent: [{
82
- type: Input
83
- }], markdownUrl: [{
84
- type: Input
85
- }] } });
86
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscC5tb2RhbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL2hlbHAvaGVscC5tb2RhbC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL2hlbHAvaGVscC5tb2RhbC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBcUIsU0FBUyxFQUFZLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQU12RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7Ozs7Ozs7OztBQVN6RCxNQUFNLE9BQU8saUJBQWlCO0lBQzVCLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQTBCLEVBQUUsT0FBNEI7UUFDeEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDO1lBQ25DLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLGNBQWMsRUFBRSxPQUFPO1lBQ3ZCLGFBQWEsRUFBRSxJQUFJO1lBQ25CLFFBQVEsRUFBRSxhQUFhO1NBQ3hCLENBQUMsQ0FBQztRQUVILE1BQU0sS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3hCLENBQUM7Q0FDRjtBQU1ELE1BQU0sT0FBTyxZQUFZO0lBV1g7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFoQkgsS0FBSyxDQUFVO0lBQ3hCLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFDZixLQUFLLEdBQVcsU0FBUyxDQUFDO0lBRWpCLEtBQUssQ0FBUztJQUNkLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDakIsZUFBZSxDQUFTO0lBQ3hCLFdBQVcsQ0FBUztJQUU3QixZQUNZLFFBQWtCLEVBQ2xCLFFBQXlCLEVBQ3pCLFFBQXlCLEVBQ3pCLFFBQThCLEVBQzlCLFNBQTJCLEVBQzNCLE9BQXVCLEVBQ3ZCLEVBQXFCO1FBTnJCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsYUFBUSxHQUFSLFFBQVEsQ0FBaUI7UUFDekIsYUFBUSxHQUFSLFFBQVEsQ0FBaUI7UUFDekIsYUFBUSxHQUFSLFFBQVEsQ0FBc0I7UUFDOUIsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFDM0IsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFDdkIsT0FBRSxHQUFGLEVBQUUsQ0FBbUI7UUFFL0IscUJBQXFCO1FBQ3JCLHVDQUF1QztJQUN6QyxDQUFDO0lBRUQsS0FBSyxDQUFDLENBQVM7UUFDYixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBc0I7UUFDaEMsT0FBTyxDQUFDLEtBQUssQ0FBQywyQ0FBMkMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVsRSxrQkFBa0I7UUFDbEIsSUFBSSxLQUFLLFlBQVksaUJBQWlCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMvRCxPQUFPLENBQUMsS0FBSyxDQUFDLDJEQUEyRCxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxLQUFLLEdBQUcsc0JBQXNCLENBQUM7UUFDdEMsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxLQUFLLEdBQUcsdUJBQXVCLENBQUM7UUFDdkMsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDekIsQ0FBQzt3R0EvQ1UsWUFBWTs0RkFBWixZQUFZLDBLQ2hDekIsaW5DQWlDQTs7NEZERGEsWUFBWTtrQkFMeEIsU0FBUzsrQkFDRSxnQkFBZ0IsbUJBRVQsdUJBQXVCLENBQUMsTUFBTTt3UUFPdEMsS0FBSztzQkFBYixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdG9yLCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTW9kYWxDb250cm9sbGVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgUGxhdGZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9wbGF0Zm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IExvY2FsU2V0dGluZ3NTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9sb2NhbC1zZXR0aW5ncy5zZXJ2aWNlJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IE5ldHdvcmtTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHsgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwSGVscE1vZGFsT3B0aW9ucyB7XG4gIHRpdGxlPzogc3RyaW5nO1xuICBtYXJrZG93bkNvbnRlbnQ/OiBzdHJpbmc7XG4gIG1hcmtkb3duVXJsPzogc3RyaW5nO1xuICBzaG93RXJyb3I/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgQXBwSGVscE1vZGFsVXRpbHMge1xuICBzdGF0aWMgYXN5bmMgc2hvdyhtb2RhbEN0cmw6IE1vZGFsQ29udHJvbGxlciwgb3B0aW9uczogQXBwSGVscE1vZGFsT3B0aW9ucykge1xuICAgIGNvbnN0IG1vZGFsID0gYXdhaXQgbW9kYWxDdHJsLmNyZWF0ZSh7XG4gICAgICBjb21wb25lbnQ6IEFwcEhlbHBNb2RhbCxcbiAgICAgIGNvbXBvbmVudFByb3BzOiBvcHRpb25zLFxuICAgICAga2V5Ym9hcmRDbG9zZTogdHJ1ZSxcbiAgICAgIGNzc0NsYXNzOiAnbW9kYWwtbGFyZ2UnLFxuICAgIH0pO1xuXG4gICAgYXdhaXQgbW9kYWwucHJlc2VudCgpO1xuICB9XG59XG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtaGVscC1tb2RhbCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9oZWxwLm1vZGFsLmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQXBwSGVscE1vZGFsIGltcGxlbWVudHMgQXBwSGVscE1vZGFsT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGRlYnVnOiBib29sZWFuO1xuICBsb2FkaW5nID0gdHJ1ZTtcbiAgZXJyb3I6IHN0cmluZyA9IHVuZGVmaW5lZDtcblxuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nO1xuICBASW5wdXQoKSBzaG93RXJyb3IgPSB0cnVlO1xuICBASW5wdXQoKSBtYXJrZG93bkNvbnRlbnQ6IHN0cmluZztcbiAgQElucHV0KCkgbWFya2Rvd25Vcmw6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCB2aWV3Q3RybDogTW9kYWxDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCBwbGF0Zm9ybTogUGxhdGZvcm1TZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBzZXR0aW5nczogTG9jYWxTZXR0aW5nc1NlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgbmV0d29yazogTmV0d29ya1NlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGNkOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHtcbiAgICAvLyBUT0RPOiBmb3IgREVWIG9ubHlcbiAgICAvL3RoaXMuZGVidWcgPSAhZW52aXJvbm1lbnQucHJvZHVjdGlvbjtcbiAgfVxuXG4gIGNsb3NlKF8/OiBFdmVudCkge1xuICAgIHJldHVybiB0aGlzLnZpZXdDdHJsLmRpc21pc3MoKTtcbiAgfVxuXG4gIG1hcmtBc0xvYWRlZCgpIHtcbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25Mb2FkRXJyb3IoZXJyb3I/OiBzdHJpbmcgfCBFcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1toZWxwLW1vZGFsXSBFcnJvciBsb2FkaW5nIGhlbHAgY29udGVudDogJywgZXJyb3IpO1xuXG4gICAgLy8gVHJhbnNsYXRlIGVycm9yXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UgJiYgdGhpcy5uZXR3b3JrLm9mZmxpbmUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1toZWxwLW1vZGFsXSBFcnJvciBsb2FkaW5nIGhlbHAgY29udGVudCAob2ZmbGluZTogdHJ1ZSk6ICcsIGVycm9yKTtcbiAgICAgIHRoaXMuZXJyb3IgPSAnTkVUV09SSy5JTkZPLk9GRkxJTkUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbaGVscC1tb2RhbF0gRXJyb3IgbG9hZGluZyBoZWxwIGNvbnRlbnQ6ICcsIGVycm9yKTtcbiAgICAgIHRoaXMuZXJyb3IgPSAnRVJST1IuTE9BRF9EQVRBX0VSUk9SJztcbiAgICB9XG5cbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCJAaWYgKHRpdGxlKSB7XG4gIDxhcHAtbW9kYWwtdG9vbGJhclxuICAgIGNvbG9yPVwibGlnaHRcIlxuICAgIFt0aXRsZV09XCJ0aXRsZSB8IHRyYW5zbGF0ZVwiXG4gICAgKGNhbmNlbCk9XCJjbG9zZSgkZXZlbnQpXCJcbiAgICBbc2hvd1NwaW5uZXJdPVwibG9hZGluZ1wiXG4gID48L2FwcC1tb2RhbC10b29sYmFyPlxufVxuXG48aW9uLWNvbnRlbnQgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuICA8IS0tIGVycm9yIC0tPlxuICA8aW9uLWl0ZW0gKm5nSWY9XCJzaG93RXJyb3IgJiYgZXJyb3JcIiBsaW5lcz1cIm5vbmVcIj5cbiAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3IgfCB0cmFuc2xhdGVcIj48L2lvbi1sYWJlbD5cbiAgPC9pb24taXRlbT5cblxuICBAaWYgKG1hcmtkb3duQ29udGVudCkge1xuICAgIDxtYXJrZG93biBbZGF0YV09XCJtYXJrZG93bkNvbnRlbnRcIiAocmVhZHkpPVwibWFya0FzTG9hZGVkKClcIiBlbW9qaT48L21hcmtkb3duPlxuICB9IEBlbHNlIGlmIChtYXJrZG93blVybCkge1xuICAgIDxtYXJrZG93biBbc3JjXT1cIm1hcmtkb3duVXJsXCIgKGxvYWQpPVwibWFya0FzTG9hZGVkKClcIiAoZXJyb3IpPVwib25Mb2FkRXJyb3IoJGV2ZW50KVwiIGVtb2ppPjwvbWFya2Rvd24+XG4gIH1cbjwvaW9uLWNvbnRlbnQ+XG5cbjxpb24tZm9vdGVyIGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgPGlvbi10b29sYmFyPlxuICAgIDxpb24tcm93IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBub3dyYXA+XG4gICAgICA8aW9uLWNvbD48L2lvbi1jb2w+XG4gICAgICA8aW9uLWNvbCBzaXplPVwiYXV0b1wiPlxuICAgICAgICA8aW9uLWJ1dHRvbiBmaWxsPVwic29saWRcIiBjb2xvcj1cInRlcnRpYXJ5XCIgKGNsaWNrKT1cImNsb3NlKClcIj57eyAnQ09NTU9OLkJUTl9DTE9TRScgfCB0cmFuc2xhdGUgfX08L2lvbi1idXR0b24+XG4gICAgICA8L2lvbi1jb2w+XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi10b29sYmFyPlxuPC9pb24tZm9vdGVyPlxuIl19