@firestitch/system 18.0.39 → 18.0.41

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.
@@ -1,17 +1,20 @@
1
- import { OnInit } from '@angular/core';
2
1
  import * as i0 from "@angular/core";
3
- export declare class ServerLogComponent implements OnInit {
4
- data: any;
2
+ export declare class ServerLogComponent {
3
+ log: import("@angular/core").WritableSignal<any>;
4
+ backtrace: import("@angular/core").WritableSignal<string>;
5
+ logData: import("@angular/core").WritableSignal<string>;
6
+ server: import("@angular/core").WritableSignal<string>;
7
+ LogTypes: Record<string, string>;
8
+ private _data;
9
+ private _api;
5
10
  private _clipboard;
6
11
  private _message;
7
- log: any;
8
- backtrace: string;
9
- logData: string;
10
- server: string;
11
- LogTypes: Record<string, string>;
12
- ngOnInit(): void;
12
+ private _destroyRef;
13
+ constructor();
13
14
  copy(): void;
15
+ private _init;
14
16
  private _prettifyBacktrace;
17
+ private _parseBacktrace;
15
18
  private _formatArg;
16
19
  private _prettify;
17
20
  static ɵfac: i0.ɵɵFactoryDeclaration<ServerLogComponent, never>;
@@ -1,7 +1,9 @@
1
- import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core';
2
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
3
  import { MatButtonModule } from '@angular/material/button';
3
4
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
4
5
  import { MatTabsModule } from '@angular/material/tabs';
6
+ import { FsApi } from '@firestitch/api';
5
7
  import { FsClipboard } from '@firestitch/clipboard';
6
8
  import { index } from '@firestitch/common';
7
9
  import { FsDateModule } from '@firestitch/date';
@@ -9,6 +11,7 @@ import { FsDialogModule } from '@firestitch/dialog';
9
11
  import { FsLabelModule } from '@firestitch/label';
10
12
  import { FsMessage } from '@firestitch/message';
11
13
  import { FsSkeletonModule } from '@firestitch/skeleton';
14
+ import { tap } from 'rxjs/operators';
12
15
  import { LogTypes } from '../../../../../../consts';
13
16
  import * as i0 from "@angular/core";
14
17
  import * as i1 from "@angular/material/dialog";
@@ -19,40 +22,54 @@ import * as i5 from "@firestitch/date";
19
22
  import * as i6 from "@firestitch/skeleton";
20
23
  import * as i7 from "@firestitch/dialog";
21
24
  export class ServerLogComponent {
22
- data = inject(MAT_DIALOG_DATA);
25
+ log = signal(null);
26
+ backtrace = signal('');
27
+ logData = signal('');
28
+ server = signal('');
29
+ LogTypes = index(LogTypes, 'value', 'name');
30
+ _data = inject(MAT_DIALOG_DATA);
31
+ _api = inject(FsApi);
23
32
  _clipboard = inject(FsClipboard);
24
33
  _message = inject(FsMessage);
25
- log;
26
- backtrace;
27
- logData;
28
- server;
29
- LogTypes = index(LogTypes, 'value', 'name');
30
- ngOnInit() {
31
- if (this.data.log) {
32
- this.log = this.data.log;
33
- this.backtrace = this._prettifyBacktrace(this.log.backtrace);
34
- this.logData = this._prettify(this.log.data);
35
- this.server = this._prettify(this.log.server);
36
- }
34
+ _destroyRef = inject(DestroyRef);
35
+ constructor() {
36
+ this._init();
37
37
  }
38
38
  copy() {
39
- this._clipboard.copy(JSON.stringify(this.log, null, 2));
39
+ this._clipboard.copy(JSON.stringify(this.log(), null, 2));
40
40
  this._message.success('Copied to clipboard');
41
41
  }
42
+ _init() {
43
+ // The listing excludes the large columns — fetch the single log with them included
44
+ this._api
45
+ .get(`system/logs/server/${this._data.log.id}`, {
46
+ backtraces: true,
47
+ data: true,
48
+ servers: true,
49
+ }, { key: 'log' })
50
+ .pipe(tap((log) => {
51
+ this.log.set(log);
52
+ this.backtrace.set(this._prettifyBacktrace(log.backtrace));
53
+ this.logData.set(this._prettify(log.data));
54
+ this.server.set(this._prettify(log.server));
55
+ }), takeUntilDestroyed(this._destroyRef))
56
+ .subscribe();
57
+ }
42
58
  _prettifyBacktrace(value) {
59
+ let truncated = false;
43
60
  if (typeof value === 'string') {
44
61
  value = value.trim();
45
- try {
46
- value = JSON.parse(value);
47
- }
48
- catch (e) {
62
+ const parsed = this._parseBacktrace(value);
63
+ if (!parsed) {
49
64
  return value;
50
65
  }
66
+ truncated = parsed.truncated;
67
+ value = parsed.frames;
51
68
  }
52
69
  if (!Array.isArray(value)) {
53
70
  return this._prettify(value);
54
71
  }
55
- return value
72
+ const lines = value
56
73
  .map((frame, idx) => {
57
74
  const call = [frame.class, frame.type, frame.function]
58
75
  .filter((part) => !!part)
@@ -64,8 +81,31 @@ export class ServerLogComponent {
64
81
  ? `${frame.file}(${frame.line ?? '?'})`
65
82
  : '[internal function]';
66
83
  return `#${idx} ${location}: ${call}(${args})`;
67
- })
68
- .join('\n');
84
+ });
85
+ if (truncated) {
86
+ lines.push('… (backtrace truncated)');
87
+ }
88
+ return lines.join('\n');
89
+ }
90
+ _parseBacktrace(value) {
91
+ try {
92
+ return { frames: JSON.parse(value), truncated: false };
93
+ }
94
+ catch (e) {
95
+ // stored backtrace may be cut off mid-frame — recover the complete frames
96
+ }
97
+ let boundary = value.lastIndexOf('},{');
98
+ while (boundary > 0) {
99
+ try {
100
+ const frames = JSON.parse(`${value.substring(0, boundary + 1)}]`);
101
+ return { frames, truncated: true };
102
+ }
103
+ catch (e) {
104
+ // keep trying earlier frame boundaries
105
+ }
106
+ boundary = value.lastIndexOf('},{', boundary - 1);
107
+ }
108
+ return null;
69
109
  }
70
110
  _formatArg(arg) {
71
111
  if (typeof arg === 'string') {
@@ -97,7 +137,7 @@ export class ServerLogComponent {
97
137
  return JSON.stringify(value, null, 2);
98
138
  }
99
139
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
100
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} &#64; {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i4.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i5.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i7.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
140
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n @if (log().file) {\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} &#64; {{ log().line }}\n </fs-label-field>\n }\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>\n {{ backtrace() }}\n </pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>\n {{ logData() }}\n </pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>\n {{ server() }}\n </pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i4.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i5.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i7.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
101
141
  }
102
142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
103
143
  type: Component,
@@ -109,6 +149,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
109
149
  FsDateModule,
110
150
  FsSkeletonModule,
111
151
  FsDialogModule,
112
- ], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} &#64; {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
113
- }] });
114
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvc2VydmVyLWxvZ3MvY29tcG9uZW50cy9zZXJ2ZXItbG9nL3NlcnZlci1sb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NlcnZlci1sb2dzL2NvbXBvbmVudHMvc2VydmVyLWxvZy9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7OztBQWtC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SyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzdFLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7dUdBN0ZVLGtCQUFrQjsyRkFBbEIsa0JBQWtCLHdFQ2hDL0IsMHdEQTBFQSxnS0RuREksZUFBZSwrbkJBQ2YsZUFBZSwyTkFDZixhQUFhLDRvQkFDYixhQUFhLCtRQUNiLFlBQVksaUdBQ1osZ0JBQWdCLGlLQUNoQixjQUFjOzsyRkFHTCxrQkFBa0I7a0JBZjlCLFNBQVM7c0NBR1MsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxJQUFJLFdBQ1A7d0JBQ1AsZUFBZTt3QkFDZixlQUFlO3dCQUNmLGFBQWE7d0JBQ2IsYUFBYTt3QkFDYixZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsY0FBYztxQkFDZiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIE9uSW5pdCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRUYWJzTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5cbmltcG9ydCB7IEZzQ2xpcGJvYXJkIH0gZnJvbSAnQGZpcmVzdGl0Y2gvY2xpcGJvYXJkJztcbmltcG9ydCB7IGluZGV4IH0gZnJvbSAnQGZpcmVzdGl0Y2gvY29tbW9uJztcbmltcG9ydCB7IEZzRGF0ZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGUnO1xuaW1wb3J0IHsgRnNEaWFsb2dNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kaWFsb2cnO1xuaW1wb3J0IHsgRnNMYWJlbE1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2xhYmVsJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNTa2VsZXRvbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3NrZWxldG9uJztcblxuaW1wb3J0IHsgTG9nVHlwZXMgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9jb25zdHMnO1xuXG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZVVybDogJy4vc2VydmVyLWxvZy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NlcnZlci1sb2cuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBNYXREaWFsb2dNb2R1bGUsXG4gICAgTWF0QnV0dG9uTW9kdWxlLFxuICAgIE1hdFRhYnNNb2R1bGUsXG4gICAgRnNMYWJlbE1vZHVsZSxcbiAgICBGc0RhdGVNb2R1bGUsXG4gICAgRnNTa2VsZXRvbk1vZHVsZSxcbiAgICBGc0RpYWxvZ01vZHVsZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgU2VydmVyTG9nQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgZGF0YSA9IGluamVjdChNQVRfRElBTE9HX0RBVEEpO1xuXG4gIHByaXZhdGUgX2NsaXBib2FyZCA9IGluamVjdChGc0NsaXBib2FyZCk7XG4gIHByaXZhdGUgX21lc3NhZ2UgPSBpbmplY3QoRnNNZXNzYWdlKTtcblxuICBwdWJsaWMgbG9nO1xuICBwdWJsaWMgYmFja3RyYWNlOiBzdHJpbmc7XG4gIHB1YmxpYyBsb2dEYXRhOiBzdHJpbmc7XG4gIHB1YmxpYyBzZXJ2ZXI6IHN0cmluZztcbiAgcHVibGljIExvZ1R5cGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0gaW5kZXgoTG9nVHlwZXMsICd2YWx1ZScsICduYW1lJyk7XG5cbiAgcHVibGljIG5nT25Jbml0KCkge1xuICAgIGlmICh0aGlzLmRhdGEubG9nKSB7XG4gICAgICB0aGlzLmxvZyA9IHRoaXMuZGF0YS5sb2c7XG4gICAgICB0aGlzLmJhY2t0cmFjZSA9IHRoaXMuX3ByZXR0aWZ5QmFja3RyYWNlKHRoaXMubG9nLmJhY2t0cmFjZSk7XG4gICAgICB0aGlzLmxvZ0RhdGEgPSB0aGlzLl9wcmV0dGlmeSh0aGlzLmxvZy5kYXRhKTtcbiAgICAgIHRoaXMuc2VydmVyID0gdGhpcy5fcHJldHRpZnkodGhpcy5sb2cuc2VydmVyKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY29weSgpIHtcbiAgICB0aGlzLl9jbGlwYm9hcmQuY29weShKU09OLnN0cmluZ2lmeSh0aGlzLmxvZywgbnVsbCwgMikpO1xuICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnQ29waWVkIHRvIGNsaXBib2FyZCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJldHRpZnlCYWNrdHJhY2UodmFsdWUpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsdWUgPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9wcmV0dGlmeSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlXG4gICAgICAubWFwKChmcmFtZSwgaWR4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGwgPSBbZnJhbWUuY2xhc3MsIGZyYW1lLnR5cGUsIGZyYW1lLmZ1bmN0aW9uXVxuICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+ICEhcGFydClcbiAgICAgICAgICAuam9pbignJyk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSAoZnJhbWUuYXJncyB8fCBbXSlcbiAgICAgICAgICAubWFwKChhcmcpID0+IHRoaXMuX2Zvcm1hdEFyZyhhcmcpKVxuICAgICAgICAgIC5qb2luKCcsICcpO1xuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IGZyYW1lLmZpbGVcbiAgICAgICAgICA/IGAke2ZyYW1lLmZpbGV9KCR7ZnJhbWUubGluZSA/PyAnPyd9KWBcbiAgICAgICAgICA6ICdbaW50ZXJuYWwgZnVuY3Rpb25dJztcblxuICAgICAgICByZXR1cm4gYCMke2lkeH0gJHtsb2NhdGlvbn06ICR7Y2FsbH0oJHthcmdzfSlgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIHByaXZhdGUgX2Zvcm1hdEFyZyhhcmcpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgbWF4ID0gNjA7XG4gICAgICBjb25zdCB2YWx1ZSA9IGFyZy5yZXBsYWNlKC9cXHMrL2csICcgJyk7XG5cbiAgICAgIHJldHVybiBgJyR7dmFsdWUubGVuZ3RoID4gbWF4ID8gYCR7dmFsdWUuc3Vic3RyaW5nKDAsIG1heCl94oCmYCA6IHZhbHVlfSdgO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgIHJldHVybiAnQXJyYXknO1xuICAgIH1cblxuICAgIGlmIChhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiAnT2JqZWN0JztcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKGFyZyk7XG4gIH1cblxuICBwcml2YXRlIF9wcmV0dGlmeSh2YWx1ZSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgMik7XG4gIH1cbn1cbiIsIjxmcy1kaWFsb2cgKmZzU2tlbGV0b249XCJsb2dcIj5cbiAgPGRpdiBtYXQtZGlhbG9nLXRpdGxlPlxuICAgIExvZ1xuICA8L2Rpdj5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmNvbHVtbi1nYXAtbGcucm93LWdhcC1zbS53cmFwLmFsaWduLXN0YXJ0XCI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBFcnJvciBUeXBlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IExvZ1R5cGVzW2xvZy50eXBlXSB8fCBsb2cudHlwZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIE1lc3NhZ2VcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgbG9nLm1lc3NhZ2UgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICBAaWYgKGxvZy51cmwpIHtcbiAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgIFVSTFxuICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAge3sgbG9nLnVybCB9fVxuICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgfVxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgRGF0ZVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBsb2cuY3JlYXRlRGF0ZXxmc0RhdGVGb3JtYXQ6ICdmdWxsLWRhdGUtdGltZScgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBGaWxlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGxvZy5maWxlIH19ICYjNjQ7IHt7IGxvZy5saW5lIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIEBpZiAoYmFja3RyYWNlIHx8IGxvZ0RhdGEgfHwgc2VydmVyKSB7XG4gICAgICA8bWF0LXRhYi1ncm91cD5cbiAgICAgICAgQGlmIChiYWNrdHJhY2UpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkJhY2t0cmFjZVwiPlxuICAgICAgICAgICAgPHByZT57eyBiYWNrdHJhY2UgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChsb2dEYXRhKSB7XG4gICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJEYXRhXCI+XG4gICAgICAgICAgICA8cHJlPnt7IGxvZ0RhdGEgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChzZXJ2ZXIpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIiRfU0VSVkVSXCI+XG4gICAgICAgICAgICA8cHJlPnt7IHNlcnZlciB9fTwvcHJlPlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgfVxuICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIH1cbiAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cInRydWVcIlxuICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgIERvbmVcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJjb3B5KClcIj5cbiAgICAgIENvcHlcbiAgICA8L2J1dHRvbj5cbiAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG48L2ZzLWRpYWxvZz5cbiJdfQ==
152
+ ], template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n @if (log().file) {\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} &#64; {{ log().line }}\n </fs-label-field>\n }\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>\n {{ backtrace() }}\n </pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>\n {{ logData() }}\n </pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>\n {{ server() }}\n </pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
153
+ }], ctorParameters: () => [] });
154
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvc2VydmVyLWxvZ3MvY29tcG9uZW50cy9zZXJ2ZXItbG9nL3NlcnZlci1sb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NlcnZlci1sb2dzL2NvbXBvbmVudHMvc2VydmVyLWxvZy9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0YsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDNUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXZELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFB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Q1A7d0JBQ1AsZUFBZTt3QkFDZixlQUFlO3dCQUNmLGFBQWE7d0JBQ2IsYUFBYTt3QkFDYixZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsY0FBYztxQkFDZiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIERlc3Ryb3lSZWYsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRUYWJzTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5cbmltcG9ydCB7IEZzQXBpIH0gZnJvbSAnQGZpcmVzdGl0Y2gvYXBpJztcbmltcG9ydCB7IEZzQ2xpcGJvYXJkIH0gZnJvbSAnQGZpcmVzdGl0Y2gvY2xpcGJvYXJkJztcbmltcG9ydCB7IGluZGV4IH0gZnJvbSAnQGZpcmVzdGl0Y2gvY29tbW9uJztcbmltcG9ydCB7IEZzRGF0ZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGUnO1xuaW1wb3J0IHsgRnNEaWFsb2dNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kaWFsb2cnO1xuaW1wb3J0IHsgRnNMYWJlbE1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2xhYmVsJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNTa2VsZXRvbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3NrZWxldG9uJztcblxuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBMb2dUeXBlcyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2NvbnN0cyc7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2VydmVyLWxvZy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE1hdERpYWxvZ01vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0VGFic01vZHVsZSxcbiAgICBGc0xhYmVsTW9kdWxlLFxuICAgIEZzRGF0ZU1vZHVsZSxcbiAgICBGc1NrZWxldG9uTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTZXJ2ZXJMb2dDb21wb25lbnQge1xuXG4gIHB1YmxpYyBsb2cgPSBzaWduYWw8YW55PihudWxsKTtcbiAgcHVibGljIGJhY2t0cmFjZSA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgcHVibGljIGxvZ0RhdGEgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHB1YmxpYyBzZXJ2ZXIgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHB1YmxpYyBMb2dUeXBlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IGluZGV4KExvZ1R5cGVzLCAndmFsdWUnLCAnbmFtZScpO1xuXG4gIHByaXZhdGUgX2RhdGEgPSBpbmplY3QoTUFUX0RJQUxPR19EQVRBKTtcbiAgcHJpdmF0ZSBfYXBpID0gaW5qZWN0KEZzQXBpKTtcbiAgcHJpdmF0ZSBfY2xpcGJvYXJkID0gaW5qZWN0KEZzQ2xpcGJvYXJkKTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX2luaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBjb3B5KCkge1xuICAgIHRoaXMuX2NsaXBib2FyZC5jb3B5KEpTT04uc3RyaW5naWZ5KHRoaXMubG9nKCksIG51bGwsIDIpKTtcbiAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ0NvcGllZCB0byBjbGlwYm9hcmQnKTtcbiAgfVxuXG4gIHByaXZhdGUgX2luaXQoKTogdm9pZCB7XG4gICAgLy8gVGhlIGxpc3RpbmcgZXhjbHVkZXMgdGhlIGxhcmdlIGNvbHVtbnMg4oCUIGZldGNoIHRoZSBzaW5nbGUgbG9nIHdpdGggdGhlbSBpbmNsdWRlZFxuICAgIHRoaXMuX2FwaVxuICAgICAgLmdldChcbiAgICAgICAgYHN5c3RlbS9sb2dzL3NlcnZlci8ke3RoaXMuX2RhdGEubG9nLmlkfWAsXG4gICAgICAgIHtcbiAgICAgICAgICBiYWNrdHJhY2VzOiB0cnVlLFxuICAgICAgICAgIGRhdGE6IHRydWUsXG4gICAgICAgICAgc2VydmVyczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBrZXk6ICdsb2cnIH0sXG4gICAgICApXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKChsb2cpID0+IHtcbiAgICAgICAgICB0aGlzLmxvZy5zZXQobG9nKTtcbiAgICAgICAgICB0aGlzLmJhY2t0cmFjZS5zZXQodGhpcy5fcHJldHRpZnlCYWNrdHJhY2UobG9nLmJhY2t0cmFjZSkpO1xuICAgICAgICAgIHRoaXMubG9nRGF0YS5zZXQodGhpcy5fcHJldHRpZnkobG9nLmRhdGEpKTtcbiAgICAgICAgICB0aGlzLnNlcnZlci5zZXQodGhpcy5fcHJldHRpZnkobG9nLnNlcnZlcikpO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJldHRpZnlCYWNrdHJhY2UodmFsdWUpOiBzdHJpbmcge1xuICAgIGxldCB0cnVuY2F0ZWQgPSBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcblxuICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5fcGFyc2VCYWNrdHJhY2UodmFsdWUpO1xuXG4gICAgICBpZiAoIXBhcnNlZCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHRydW5jYXRlZCA9IHBhcnNlZC50cnVuY2F0ZWQ7XG4gICAgICB2YWx1ZSA9IHBhcnNlZC5mcmFtZXM7XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ByZXR0aWZ5KHZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdCBsaW5lcyA9IHZhbHVlXG4gICAgICAubWFwKChmcmFtZSwgaWR4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGwgPSBbZnJhbWUuY2xhc3MsIGZyYW1lLnR5cGUsIGZyYW1lLmZ1bmN0aW9uXVxuICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+ICEhcGFydClcbiAgICAgICAgICAuam9pbignJyk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSAoZnJhbWUuYXJncyB8fCBbXSlcbiAgICAgICAgICAubWFwKChhcmcpID0+IHRoaXMuX2Zvcm1hdEFyZyhhcmcpKVxuICAgICAgICAgIC5qb2luKCcsICcpO1xuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IGZyYW1lLmZpbGVcbiAgICAgICAgICA/IGAke2ZyYW1lLmZpbGV9KCR7ZnJhbWUubGluZSA/PyAnPyd9KWBcbiAgICAgICAgICA6ICdbaW50ZXJuYWwgZnVuY3Rpb25dJztcblxuICAgICAgICByZXR1cm4gYCMke2lkeH0gJHtsb2NhdGlvbn06ICR7Y2FsbH0oJHthcmdzfSlgO1xuICAgICAgfSk7XG5cbiAgICBpZiAodHJ1bmNhdGVkKSB7XG4gICAgICBsaW5lcy5wdXNoKCfigKYgKGJhY2t0cmFjZSB0cnVuY2F0ZWQpJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VCYWNrdHJhY2UodmFsdWU6IHN0cmluZyk6IHsgZnJhbWVzOiBhbnk7IHRydW5jYXRlZDogYm9vbGVhbiB9IHwgbnVsbCB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB7IGZyYW1lczogSlNPTi5wYXJzZSh2YWx1ZSksIHRydW5jYXRlZDogZmFsc2UgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBzdG9yZWQgYmFja3RyYWNlIG1heSBiZSBjdXQgb2ZmIG1pZC1mcmFtZSDigJQgcmVjb3ZlciB0aGUgY29tcGxldGUgZnJhbWVzXG4gICAgfVxuXG4gICAgbGV0IGJvdW5kYXJ5ID0gdmFsdWUubGFzdEluZGV4T2YoJ30seycpO1xuXG4gICAgd2hpbGUgKGJvdW5kYXJ5ID4gMCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZnJhbWVzID0gSlNPTi5wYXJzZShgJHt2YWx1ZS5zdWJzdHJpbmcoMCwgYm91bmRhcnkgKyAxKX1dYCk7XG5cbiAgICAgICAgcmV0dXJuIHsgZnJhbWVzLCB0cnVuY2F0ZWQ6IHRydWUgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8ga2VlcCB0cnlpbmcgZWFybGllciBmcmFtZSBib3VuZGFyaWVzXG4gICAgICB9XG5cbiAgICAgIGJvdW5kYXJ5ID0gdmFsdWUubGFzdEluZGV4T2YoJ30seycsIGJvdW5kYXJ5IC0gMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9mb3JtYXRBcmcoYXJnKTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IG1heCA9IDYwO1xuICAgICAgY29uc3QgdmFsdWUgPSBhcmcucmVwbGFjZSgvXFxzKy9nLCAnICcpO1xuXG4gICAgICByZXR1cm4gYCcke3ZhbHVlLmxlbmd0aCA+IG1heCA/IGAke3ZhbHVlLnN1YnN0cmluZygwLCBtYXgpfeKApmAgOiB2YWx1ZX0nYDtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcpKSB7XG4gICAgICByZXR1cm4gJ0FycmF5JztcbiAgICB9XG5cbiAgICBpZiAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gJ09iamVjdCc7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN0cmluZyhhcmcpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJldHRpZnkodmFsdWUpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsdWUgPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdmFsdWUgfHwgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMCkpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDIpO1xuICB9XG59XG4iLCI8ZnMtZGlhbG9nICpmc1NrZWxldG9uPVwibG9nKClcIj5cbiAgPGRpdiBtYXQtZGlhbG9nLXRpdGxlPlxuICAgIExvZ1xuICA8L2Rpdj5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmNvbHVtbi1nYXAtbGcucm93LWdhcC1zbS53cmFwLmFsaWduLXN0YXJ0XCI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBNZXNzYWdlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGxvZygpLm1lc3NhZ2UgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBFcnJvciBUeXBlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IExvZ1R5cGVzW2xvZygpLnR5cGVdIHx8IGxvZygpLnR5cGUgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICBAaWYgKGxvZygpLnVybCkge1xuICAgICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgICAgVVJMXG4gICAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAgICB7eyBsb2coKS51cmwgfX1cbiAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIH1cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIERhdGVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgbG9nKCkuY3JlYXRlRGF0ZXxmc0RhdGVGb3JtYXQ6ICdmdWxsLWRhdGUtdGltZScgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICBAaWYgKGxvZygpLmZpbGUpIHtcbiAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgIEZpbGVcbiAgICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICAgIHt7IGxvZygpLmZpbGUgfX0gJiM2NDsge3sgbG9nKCkubGluZSB9fVxuICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICAgIEBpZiAoYmFja3RyYWNlKCkgfHwgbG9nRGF0YSgpIHx8IHNlcnZlcigpKSB7XG4gICAgICA8bWF0LXRhYi1ncm91cD5cbiAgICAgICAgQGlmIChiYWNrdHJhY2UoKSkge1xuICAgICAgICAgIDxtYXQtdGFiIGxhYmVsPVwiQmFja3RyYWNlXCI+XG4gICAgICAgICAgICA8cHJlPlxuICAgICAgICAgICAgICB7eyBiYWNrdHJhY2UoKSB9fVxuICAgICAgICAgICAgPC9wcmU+XG4gICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICB9XG4gICAgICAgIEBpZiAobG9nRGF0YSgpKSB7XG4gICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJEYXRhXCI+XG4gICAgICAgICAgICA8cHJlPlxuICAgICAgICAgICAgICB7eyBsb2dEYXRhKCkgfX1cbiAgICAgICAgICAgIDwvcHJlPlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKHNlcnZlcigpKSB7XG4gICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCIkX1NFUlZFUlwiPlxuICAgICAgICAgICAgPHByZT5cbiAgICAgICAgICAgICAge3sgc2VydmVyKCkgfX1cbiAgICAgICAgICAgIDwvcHJlPlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgfVxuICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIH1cbiAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cInRydWVcIlxuICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgIERvbmVcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJjb3B5KClcIj5cbiAgICAgIENvcHlcbiAgICA8L2J1dHRvbj5cbiAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG48L2ZzLWRpYWxvZz4iXX0=
@@ -1,7 +1,7 @@
1
1
  import * as i1$2 from '@angular/common';
2
2
  import { JsonPipe, NgClass, NgStyle, CommonModule, NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { inject, Component, ChangeDetectionStrategy, ViewChild, Input, Injectable, ChangeDetectorRef, EventEmitter, Output, Pipe, InjectionToken, NgModule } from '@angular/core';
4
+ import { inject, Component, ChangeDetectionStrategy, ViewChild, Input, Injectable, ChangeDetectorRef, signal, DestroyRef, EventEmitter, Output, Pipe, InjectionToken, NgModule } from '@angular/core';
5
5
  import * as i1$4 from '@angular/forms';
6
6
  import { FormsModule } from '@angular/forms';
7
7
  import * as i2$2 from '@angular/material/button';
@@ -53,6 +53,7 @@ import { SelectionActionType } from '@firestitch/selection';
53
53
  import { FsBuildService } from '@firestitch/build';
54
54
  import * as i6 from '@firestitch/common';
55
55
  import { index, FsCommonModule } from '@firestitch/common';
56
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
56
57
  import * as i3$4 from '@firestitch/clipboard';
57
58
  import { FsClipboard, FsClipboardModule } from '@firestitch/clipboard';
58
59
  import { MatOption } from '@angular/material/core';
@@ -1266,40 +1267,54 @@ const LogTypes = [
1266
1267
  ];
1267
1268
 
1268
1269
  class ServerLogComponent {
1269
- data = inject(MAT_DIALOG_DATA);
1270
+ log = signal(null);
1271
+ backtrace = signal('');
1272
+ logData = signal('');
1273
+ server = signal('');
1274
+ LogTypes = index(LogTypes, 'value', 'name');
1275
+ _data = inject(MAT_DIALOG_DATA);
1276
+ _api = inject(FsApi);
1270
1277
  _clipboard = inject(FsClipboard);
1271
1278
  _message = inject(FsMessage);
1272
- log;
1273
- backtrace;
1274
- logData;
1275
- server;
1276
- LogTypes = index(LogTypes, 'value', 'name');
1277
- ngOnInit() {
1278
- if (this.data.log) {
1279
- this.log = this.data.log;
1280
- this.backtrace = this._prettifyBacktrace(this.log.backtrace);
1281
- this.logData = this._prettify(this.log.data);
1282
- this.server = this._prettify(this.log.server);
1283
- }
1279
+ _destroyRef = inject(DestroyRef);
1280
+ constructor() {
1281
+ this._init();
1284
1282
  }
1285
1283
  copy() {
1286
- this._clipboard.copy(JSON.stringify(this.log, null, 2));
1284
+ this._clipboard.copy(JSON.stringify(this.log(), null, 2));
1287
1285
  this._message.success('Copied to clipboard');
1288
1286
  }
1287
+ _init() {
1288
+ // The listing excludes the large columns — fetch the single log with them included
1289
+ this._api
1290
+ .get(`system/logs/server/${this._data.log.id}`, {
1291
+ backtraces: true,
1292
+ data: true,
1293
+ servers: true,
1294
+ }, { key: 'log' })
1295
+ .pipe(tap((log) => {
1296
+ this.log.set(log);
1297
+ this.backtrace.set(this._prettifyBacktrace(log.backtrace));
1298
+ this.logData.set(this._prettify(log.data));
1299
+ this.server.set(this._prettify(log.server));
1300
+ }), takeUntilDestroyed(this._destroyRef))
1301
+ .subscribe();
1302
+ }
1289
1303
  _prettifyBacktrace(value) {
1304
+ let truncated = false;
1290
1305
  if (typeof value === 'string') {
1291
1306
  value = value.trim();
1292
- try {
1293
- value = JSON.parse(value);
1294
- }
1295
- catch (e) {
1307
+ const parsed = this._parseBacktrace(value);
1308
+ if (!parsed) {
1296
1309
  return value;
1297
1310
  }
1311
+ truncated = parsed.truncated;
1312
+ value = parsed.frames;
1298
1313
  }
1299
1314
  if (!Array.isArray(value)) {
1300
1315
  return this._prettify(value);
1301
1316
  }
1302
- return value
1317
+ const lines = value
1303
1318
  .map((frame, idx) => {
1304
1319
  const call = [frame.class, frame.type, frame.function]
1305
1320
  .filter((part) => !!part)
@@ -1311,8 +1326,31 @@ class ServerLogComponent {
1311
1326
  ? `${frame.file}(${frame.line ?? '?'})`
1312
1327
  : '[internal function]';
1313
1328
  return `#${idx} ${location}: ${call}(${args})`;
1314
- })
1315
- .join('\n');
1329
+ });
1330
+ if (truncated) {
1331
+ lines.push('… (backtrace truncated)');
1332
+ }
1333
+ return lines.join('\n');
1334
+ }
1335
+ _parseBacktrace(value) {
1336
+ try {
1337
+ return { frames: JSON.parse(value), truncated: false };
1338
+ }
1339
+ catch (e) {
1340
+ // stored backtrace may be cut off mid-frame — recover the complete frames
1341
+ }
1342
+ let boundary = value.lastIndexOf('},{');
1343
+ while (boundary > 0) {
1344
+ try {
1345
+ const frames = JSON.parse(`${value.substring(0, boundary + 1)}]`);
1346
+ return { frames, truncated: true };
1347
+ }
1348
+ catch (e) {
1349
+ // keep trying earlier frame boundaries
1350
+ }
1351
+ boundary = value.lastIndexOf('},{', boundary - 1);
1352
+ }
1353
+ return null;
1316
1354
  }
1317
1355
  _formatArg(arg) {
1318
1356
  if (typeof arg === 'string') {
@@ -1344,7 +1382,7 @@ class ServerLogComponent {
1344
1382
  return JSON.stringify(value, null, 2);
1345
1383
  }
1346
1384
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1347
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} &#64; {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i3.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i4.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1385
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n @if (log().file) {\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} &#64; {{ log().line }}\n </fs-label-field>\n }\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>\n {{ backtrace() }}\n </pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>\n {{ logData() }}\n </pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>\n {{ server() }}\n </pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i3.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i4.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1348
1386
  }
1349
1387
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
1350
1388
  type: Component,
@@ -1356,8 +1394,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
1356
1394
  FsDateModule,
1357
1395
  FsSkeletonModule,
1358
1396
  FsDialogModule,
1359
- ], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} &#64; {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
1360
- }] });
1397
+ ], template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n @if (log().file) {\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} &#64; {{ log().line }}\n </fs-label-field>\n }\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>\n {{ backtrace() }}\n </pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>\n {{ logData() }}\n </pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>\n {{ server() }}\n </pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
1398
+ }], ctorParameters: () => [] });
1361
1399
 
1362
1400
  class ServerLogsComponent {
1363
1401
  _dialog = inject(MatDialog);