@franzzemen/brokenstock-shell 0.0.40 → 0.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.
|
@@ -53,8 +53,10 @@ function provideShellConfig(config) {
|
|
|
53
53
|
|
|
54
54
|
class ThinkingService {
|
|
55
55
|
constructor() {
|
|
56
|
-
this.#activeCount = signal(0,
|
|
57
|
-
|
|
56
|
+
this.#activeCount = signal(0, /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "#activeCount" }] : /* istanbul ignore next */ []));
|
|
58
|
+
this.isThinking = computed(() => this.#activeCount() > 0, /* @ts-ignore */
|
|
59
|
+
...(ngDevMode ? [{ debugName: "isThinking" }] : /* istanbul ignore next */ []));
|
|
58
60
|
}
|
|
59
61
|
#activeCount;
|
|
60
62
|
startThinking() {
|
|
@@ -66,24 +68,31 @@ class ThinkingService {
|
|
|
66
68
|
reset() {
|
|
67
69
|
this.#activeCount.set(0);
|
|
68
70
|
}
|
|
69
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
70
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
71
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThinkingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
72
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThinkingService, providedIn: 'root' }); }
|
|
71
73
|
}
|
|
72
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThinkingService, decorators: [{
|
|
73
75
|
type: Injectable,
|
|
74
76
|
args: [{ providedIn: 'root' }]
|
|
75
77
|
}] });
|
|
76
78
|
|
|
77
79
|
class AuthenticationService {
|
|
78
80
|
constructor() {
|
|
79
|
-
this.authenticated = signal(false,
|
|
80
|
-
|
|
81
|
-
this.
|
|
82
|
-
|
|
81
|
+
this.authenticated = signal(false, /* @ts-ignore */
|
|
82
|
+
...(ngDevMode ? [{ debugName: "authenticated" }] : /* istanbul ignore next */ []));
|
|
83
|
+
this.authenticating = signal(false, /* @ts-ignore */
|
|
84
|
+
...(ngDevMode ? [{ debugName: "authenticating" }] : /* istanbul ignore next */ []));
|
|
85
|
+
this.userSession = signal(undefined, /* @ts-ignore */
|
|
86
|
+
...(ngDevMode ? [{ debugName: "userSession" }] : /* istanbul ignore next */ []));
|
|
87
|
+
this.effectivePermissions = signal({}, /* @ts-ignore */
|
|
88
|
+
...(ngDevMode ? [{ debugName: "effectivePermissions" }] : /* istanbul ignore next */ []));
|
|
83
89
|
/** First-class plan-feature grants for the current session (supersedes effectivePermissions). */
|
|
84
|
-
this.features = signal({},
|
|
85
|
-
|
|
86
|
-
this.
|
|
90
|
+
this.features = signal({}, /* @ts-ignore */
|
|
91
|
+
...(ngDevMode ? [{ debugName: "features" }] : /* istanbul ignore next */ []));
|
|
92
|
+
this.conflictSessions = signal(undefined, /* @ts-ignore */
|
|
93
|
+
...(ngDevMode ? [{ debugName: "conflictSessions" }] : /* istanbul ignore next */ []));
|
|
94
|
+
this.pendingCredentials = signal(undefined, /* @ts-ignore */
|
|
95
|
+
...(ngDevMode ? [{ debugName: "pendingCredentials" }] : /* istanbul ignore next */ []));
|
|
87
96
|
this.#refreshing = null;
|
|
88
97
|
this.#auth = 'Bearer ..';
|
|
89
98
|
this.#httpClient = inject(HttpClient);
|
|
@@ -254,10 +263,10 @@ class AuthenticationService {
|
|
|
254
263
|
this.#auth = 'Bearer ..';
|
|
255
264
|
this.#router.navigate(['/login']).catch(console.error);
|
|
256
265
|
}
|
|
257
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
258
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
266
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: AuthenticationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
267
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: AuthenticationService, providedIn: 'root' }); }
|
|
259
268
|
}
|
|
260
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
269
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: AuthenticationService, decorators: [{
|
|
261
270
|
type: Injectable,
|
|
262
271
|
args: [{ providedIn: 'root' }]
|
|
263
272
|
}] });
|
|
@@ -323,7 +332,8 @@ const authInterceptor = (req, next) => {
|
|
|
323
332
|
|
|
324
333
|
class RegexValidatorDirective {
|
|
325
334
|
constructor() {
|
|
326
|
-
this.regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i,
|
|
335
|
+
this.regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i, /* @ts-ignore */
|
|
336
|
+
...(ngDevMode ? [{ debugName: "regex" }] : /* istanbul ignore next */ []));
|
|
327
337
|
}
|
|
328
338
|
validate(control) {
|
|
329
339
|
if (!control.value || !this.regex().test(control.value)) {
|
|
@@ -331,10 +341,10 @@ class RegexValidatorDirective {
|
|
|
331
341
|
}
|
|
332
342
|
return null;
|
|
333
343
|
}
|
|
334
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
335
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
344
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RegexValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
345
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: RegexValidatorDirective, isStandalone: true, selector: "[regexValidator]", inputs: { regex: { classPropertyName: "regex", publicName: "regex", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }], ngImport: i0 }); }
|
|
336
346
|
}
|
|
337
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
347
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RegexValidatorDirective, decorators: [{
|
|
338
348
|
type: Directive,
|
|
339
349
|
args: [{
|
|
340
350
|
selector: '[regexValidator]',
|
|
@@ -423,10 +433,10 @@ class FaqMarkdownRendererService {
|
|
|
423
433
|
},
|
|
424
434
|
};
|
|
425
435
|
}
|
|
426
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
427
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
436
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqMarkdownRendererService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
437
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqMarkdownRendererService, providedIn: 'root' }); }
|
|
428
438
|
}
|
|
429
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
439
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqMarkdownRendererService, decorators: [{
|
|
430
440
|
type: Injectable,
|
|
431
441
|
args: [{ providedIn: 'root' }]
|
|
432
442
|
}] });
|
|
@@ -476,10 +486,10 @@ class HttpFaqContentLoader {
|
|
|
476
486
|
this.contentCache.set(key, fetchPromise);
|
|
477
487
|
return fetchPromise;
|
|
478
488
|
}
|
|
479
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
480
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
489
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: HttpFaqContentLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
490
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: HttpFaqContentLoader, providedIn: 'root' }); }
|
|
481
491
|
}
|
|
482
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
492
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: HttpFaqContentLoader, decorators: [{
|
|
483
493
|
type: Injectable,
|
|
484
494
|
args: [{ providedIn: 'root' }]
|
|
485
495
|
}] });
|
|
@@ -505,8 +515,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
505
515
|
*/
|
|
506
516
|
class FaqHistoryService {
|
|
507
517
|
constructor() {
|
|
508
|
-
this._stack = signal([],
|
|
509
|
-
|
|
518
|
+
this._stack = signal([], /* @ts-ignore */
|
|
519
|
+
...(ngDevMode ? [{ debugName: "_stack" }] : /* istanbul ignore next */ []));
|
|
520
|
+
this._position = signal(0, /* @ts-ignore */
|
|
521
|
+
...(ngDevMode ? [{ debugName: "_position" }] : /* istanbul ignore next */ []));
|
|
510
522
|
this.stack = this._stack.asReadonly();
|
|
511
523
|
this.position = this._position.asReadonly();
|
|
512
524
|
/** True when popstate is processing the unwind kicked off by closeAndUnwind(). */
|
|
@@ -631,10 +643,10 @@ class FaqHistoryService {
|
|
|
631
643
|
this.teardown();
|
|
632
644
|
exit?.();
|
|
633
645
|
}
|
|
634
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
635
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
646
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqHistoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
647
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqHistoryService, providedIn: 'root' }); }
|
|
636
648
|
}
|
|
637
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqHistoryService, decorators: [{
|
|
638
650
|
type: Injectable,
|
|
639
651
|
args: [{ providedIn: 'root' }]
|
|
640
652
|
}] });
|
|
@@ -655,28 +667,39 @@ class FaqService {
|
|
|
655
667
|
this.history = inject(FaqHistoryService);
|
|
656
668
|
this.auth = inject(AuthenticationService);
|
|
657
669
|
this.router = inject(Router);
|
|
658
|
-
this._currentFaqKey = signal(null,
|
|
670
|
+
this._currentFaqKey = signal(null, /* @ts-ignore */
|
|
671
|
+
...(ngDevMode ? [{ debugName: "_currentFaqKey" }] : /* istanbul ignore next */ []));
|
|
659
672
|
/** Component-set current key. Bare `faq` opens at this key. */
|
|
660
673
|
this.currentFaqKey = this._currentFaqKey.asReadonly();
|
|
661
|
-
this._manifest = signal(null,
|
|
674
|
+
this._manifest = signal(null, /* @ts-ignore */
|
|
675
|
+
...(ngDevMode ? [{ debugName: "_manifest" }] : /* istanbul ignore next */ []));
|
|
662
676
|
this.manifest = this._manifest.asReadonly();
|
|
663
|
-
this.entries = computed(() => this._manifest()?.entries ?? [],
|
|
677
|
+
this.entries = computed(() => this._manifest()?.entries ?? [], /* @ts-ignore */
|
|
678
|
+
...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
|
|
664
679
|
// Modal state (E3 + E8).
|
|
665
|
-
this._modalOpen = signal(false,
|
|
680
|
+
this._modalOpen = signal(false, /* @ts-ignore */
|
|
681
|
+
...(ngDevMode ? [{ debugName: "_modalOpen" }] : /* istanbul ignore next */ []));
|
|
666
682
|
this.modalOpen = this._modalOpen.asReadonly();
|
|
667
|
-
this._activeEntry = signal(null,
|
|
683
|
+
this._activeEntry = signal(null, /* @ts-ignore */
|
|
684
|
+
...(ngDevMode ? [{ debugName: "_activeEntry" }] : /* istanbul ignore next */ []));
|
|
668
685
|
this.activeEntry = this._activeEntry.asReadonly();
|
|
669
|
-
this._activeContent = signal(null,
|
|
686
|
+
this._activeContent = signal(null, /* @ts-ignore */
|
|
687
|
+
...(ngDevMode ? [{ debugName: "_activeContent" }] : /* istanbul ignore next */ []));
|
|
670
688
|
this.activeContent = this._activeContent.asReadonly();
|
|
671
|
-
this._activeAttempted = signal([],
|
|
689
|
+
this._activeAttempted = signal([], /* @ts-ignore */
|
|
690
|
+
...(ngDevMode ? [{ debugName: "_activeAttempted" }] : /* istanbul ignore next */ []));
|
|
672
691
|
this.activeAttempted = this._activeAttempted.asReadonly();
|
|
673
|
-
this._navigating = signal(false,
|
|
692
|
+
this._navigating = signal(false, /* @ts-ignore */
|
|
693
|
+
...(ngDevMode ? [{ debugName: "_navigating" }] : /* istanbul ignore next */ []));
|
|
674
694
|
this.navigating = this._navigating.asReadonly();
|
|
675
695
|
// Search pre-fill consumed by E4 search UI on modal open / navigateTo.
|
|
676
|
-
this._initialSearchTerm = signal(null,
|
|
696
|
+
this._initialSearchTerm = signal(null, /* @ts-ignore */
|
|
697
|
+
...(ngDevMode ? [{ debugName: "_initialSearchTerm" }] : /* istanbul ignore next */ []));
|
|
677
698
|
this.initialSearchTerm = this._initialSearchTerm.asReadonly();
|
|
678
|
-
this.canGoBack = computed(() => this.history.position() > 0,
|
|
679
|
-
|
|
699
|
+
this.canGoBack = computed(() => this.history.position() > 0, /* @ts-ignore */
|
|
700
|
+
...(ngDevMode ? [{ debugName: "canGoBack" }] : /* istanbul ignore next */ []));
|
|
701
|
+
this.canGoForward = computed(() => this.history.position() < this.history.stack().length - 1, /* @ts-ignore */
|
|
702
|
+
...(ngDevMode ? [{ debugName: "canGoForward" }] : /* istanbul ignore next */ []));
|
|
680
703
|
this.manifestPromise = null;
|
|
681
704
|
}
|
|
682
705
|
/** Called by the search UI once it has consumed the pre-fill term. */
|
|
@@ -836,10 +859,10 @@ class FaqService {
|
|
|
836
859
|
this._navigating.set(false);
|
|
837
860
|
}
|
|
838
861
|
}
|
|
839
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
840
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
862
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
863
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqService, providedIn: 'root' }); }
|
|
841
864
|
}
|
|
842
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
865
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqService, decorators: [{
|
|
843
866
|
type: Injectable,
|
|
844
867
|
args: [{ providedIn: 'root' }]
|
|
845
868
|
}] });
|
|
@@ -911,11 +934,16 @@ class FaqModal {
|
|
|
911
934
|
this.attempted = this.faq.activeAttempted;
|
|
912
935
|
this.canGoBack = this.faq.canGoBack;
|
|
913
936
|
this.canGoForward = this.faq.canGoForward;
|
|
914
|
-
this.sidebarCollapsed = signal(false,
|
|
915
|
-
|
|
916
|
-
this.
|
|
917
|
-
|
|
918
|
-
this.
|
|
937
|
+
this.sidebarCollapsed = signal(false, /* @ts-ignore */
|
|
938
|
+
...(ngDevMode ? [{ debugName: "sidebarCollapsed" }] : /* istanbul ignore next */ []));
|
|
939
|
+
this.searchMode = signal(false, /* @ts-ignore */
|
|
940
|
+
...(ngDevMode ? [{ debugName: "searchMode" }] : /* istanbul ignore next */ []));
|
|
941
|
+
this.searchQuery = signal('', /* @ts-ignore */
|
|
942
|
+
...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
|
|
943
|
+
this.searchLoading = signal(false, /* @ts-ignore */
|
|
944
|
+
...(ngDevMode ? [{ debugName: "searchLoading" }] : /* istanbul ignore next */ []));
|
|
945
|
+
this.searchResults = signal([], /* @ts-ignore */
|
|
946
|
+
...(ngDevMode ? [{ debugName: "searchResults" }] : /* istanbul ignore next */ []));
|
|
919
947
|
this.fuse = null;
|
|
920
948
|
this.fuseBuild = null;
|
|
921
949
|
this.renderedHtml = computed(() => {
|
|
@@ -928,7 +956,8 @@ class FaqModal {
|
|
|
928
956
|
context: 'modal',
|
|
929
957
|
imagePrefix: entry?.imagePrefix ?? parsed.frontmatter['image-prefix'],
|
|
930
958
|
});
|
|
931
|
-
},
|
|
959
|
+
}, /* @ts-ignore */
|
|
960
|
+
...(ngDevMode ? [{ debugName: "renderedHtml" }] : /* istanbul ignore next */ []));
|
|
932
961
|
this.toc = computed(() => {
|
|
933
962
|
const isAuth = this.auth.authenticated();
|
|
934
963
|
const entries = this.faq.entries().filter((e) => {
|
|
@@ -948,7 +977,8 @@ class FaqModal {
|
|
|
948
977
|
category,
|
|
949
978
|
entries: list.sort((a, b) => a.order - b.order || a.title.localeCompare(b.title)),
|
|
950
979
|
}));
|
|
951
|
-
},
|
|
980
|
+
}, /* @ts-ignore */
|
|
981
|
+
...(ngDevMode ? [{ debugName: "toc" }] : /* istanbul ignore next */ []));
|
|
952
982
|
// Scroll content pane to top on key change.
|
|
953
983
|
effect(() => {
|
|
954
984
|
this.activeEntry();
|
|
@@ -1121,10 +1151,13 @@ class FaqModal {
|
|
|
1121
1151
|
return;
|
|
1122
1152
|
}
|
|
1123
1153
|
}
|
|
1124
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1125
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: FaqModal, isStandalone: true, selector: "faq-modal", host: { listeners: { "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "contentPaneRef", first: true, predicate: ["contentPane"], descendants: true }], ngImport: i0, template: "@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >\u2630</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >\u2039</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >\u203A</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >\u2302</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >\u2315</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\u2715</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ\u2026\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index\u2026</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading\u2026</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' \u2192 ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel\u2026</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.faq-backdrop{position:fixed;inset:0;z-index:1100;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:5vh 5vw}.faq-modal{width:80vw;height:80vh;max-width:1600px;max-height:1100px;background:var(--shell-surface, #1d1f23);color:var(--shell-fg, #e6e6e6);border-radius:8px;box-shadow:0 12px 32px #00000080;display:grid;grid-template-rows:auto 1fr;overflow:hidden;font-family:var(--shell-font, system-ui, sans-serif)}.faq-toolbar{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--shell-border, rgba(255, 255, 255, .08));background:var(--shell-surface-2, rgba(255, 255, 255, .03))}.faq-toolbar-nav,.faq-toolbar-actions{display:flex;gap:.25rem}.faq-toolbar-title{text-align:center;font-size:.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.faq-category{opacity:.7;margin-right:.25rem}.faq-sep{opacity:.4;margin:0 .25rem}.faq-title{font-weight:600}.faq-icon-btn{background:transparent;border:1px solid transparent;color:inherit;width:2rem;height:2rem;border-radius:4px;cursor:pointer;font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}.faq-icon-btn:hover:not(:disabled){background:#ffffff14}.faq-icon-btn:disabled{opacity:.35;cursor:not-allowed}.faq-icon-btn.active{background:#ffffff1f;border-color:#ffffff2e}.faq-body{display:grid;grid-template-columns:260px 1fr;min-height:0}.faq-body.sidebar-collapsed{grid-template-columns:0 1fr}.faq-body.sidebar-collapsed .faq-sidebar{display:none}.faq-sidebar{border-right:1px solid var(--shell-border, rgba(255, 255, 255, .08));overflow-y:auto;padding:.75rem .5rem;background:var(--shell-surface, #1d1f23)}.faq-toc-group{margin-bottom:1rem}.faq-toc-category{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.6;margin:0 0 .4rem .4rem}.faq-toc ul{list-style:none;padding:0;margin:0}.faq-toc-link{display:block;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.35rem .5rem;border-radius:4px;cursor:pointer;font-size:.88rem}.faq-toc-link:hover{background:#ffffff0f}.faq-toc-link.active{background:#ffffff1f;font-weight:600}.faq-toc-empty{padding:1rem .5rem;opacity:.7;font-size:.85rem}.faq-search{display:flex;flex-direction:column;gap:.5rem;padding:.25rem}.faq-search-input{width:100%;padding:.5rem .6rem;border-radius:4px;border:1px solid rgba(255,255,255,.18);background:#00000040;color:inherit;font-size:.9rem;box-sizing:border-box}.faq-search-input:focus{outline:none;border-color:#fff6}.faq-search-status{padding:.5rem;opacity:.65;font-size:.82rem;margin:0}.faq-search-results{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}.faq-search-result{display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.45rem .5rem;border-radius:4px;cursor:pointer}.faq-search-result:hover{background:#ffffff0f}.faq-search-result.active{background:#ffffff1f}.faq-search-result-title{font-size:.9rem;font-weight:600}.faq-search-result-category{font-size:.72rem;opacity:.6;text-transform:uppercase;letter-spacing:.04em}.faq-search-result-snippet{font-size:.78rem;opacity:.75;line-height:1.35}.faq-content{overflow-y:auto;padding:1.25rem 2rem;min-width:0}.faq-loading,.faq-empty{opacity:.75;padding:1rem 0}.faq-empty-chain code{background:#ffffff14;padding:.1rem .4rem;border-radius:3px;font-size:.85rem}.faq-empty-hint{margin-top:1rem;opacity:.55;font-size:.85rem}.faq-article{max-width:70ch;line-height:1.55;font-size:.95rem}.faq-article h1,.faq-article h2,.faq-article h3{font-weight:600;margin:1.4rem 0 .6rem}.faq-article h1{font-size:1.4rem;margin-top:0}.faq-article h2{font-size:1.15rem}.faq-article h3{font-size:1rem}.faq-article p{margin:.6rem 0}.faq-article a{color:var(--shell-link, #6ea8fe);text-decoration:none}.faq-article a:hover{text-decoration:underline}.faq-article a[data-faq-kind=external]:after{content:\" \\2197\";opacity:.65;font-size:.85em}.faq-article .faq-app-arrow{opacity:.7;font-size:.9em}.faq-article code{background:#ffffff14;padding:.1rem .35rem;border-radius:3px;font-size:.88em}.faq-article pre{background:#00000059;padding:.75rem 1rem;border-radius:4px;overflow-x:auto}.faq-article pre code{background:transparent;padding:0}.faq-article img{max-width:100%;border-radius:4px;margin:.6rem 0}.faq-article ul,.faq-article ol{padding-left:1.4rem;margin:.6rem 0}.faq-article blockquote{border-left:3px solid var(--shell-border, rgba(255, 255, 255, .15));padding-left:.9rem;margin:.8rem 0;opacity:.85}@media(max-width:900px){.faq-modal{width:100vw;height:100vh;border-radius:0;max-width:none;max-height:none}.faq-backdrop{padding:0}.faq-body{grid-template-columns:1fr}.faq-sidebar{display:none}.faq-body:not(.sidebar-collapsed) .faq-sidebar{display:block;position:absolute;inset:0;z-index:1}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None, deferBlockDependencies: [() => [Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)], () => [Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)]] }); }
|
|
1154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqModal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1155
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: FaqModal, isStandalone: true, selector: "faq-modal", host: { listeners: { "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "contentPaneRef", first: true, predicate: ["contentPane"], descendants: true }], ngImport: i0, template: "@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >\u2630</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >\u2039</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >\u203A</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >\u2302</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >\u2315</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\u2715</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ\u2026\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index\u2026</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading\u2026</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' \u2192 ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel\u2026</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.faq-backdrop{position:fixed;inset:0;z-index:1100;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:5vh 5vw}.faq-modal{width:80vw;height:80vh;max-width:1600px;max-height:1100px;background:var(--shell-surface, #1d1f23);color:var(--shell-fg, #e6e6e6);border-radius:8px;box-shadow:0 12px 32px #00000080;display:grid;grid-template-rows:auto 1fr;overflow:hidden;font-family:var(--shell-font, system-ui, sans-serif)}.faq-toolbar{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--shell-border, rgba(255, 255, 255, .08));background:var(--shell-surface-2, rgba(255, 255, 255, .03))}.faq-toolbar-nav,.faq-toolbar-actions{display:flex;gap:.25rem}.faq-toolbar-title{text-align:center;font-size:.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.faq-category{opacity:.7;margin-right:.25rem}.faq-sep{opacity:.4;margin:0 .25rem}.faq-title{font-weight:600}.faq-icon-btn{background:transparent;border:1px solid transparent;color:inherit;width:2rem;height:2rem;border-radius:4px;cursor:pointer;font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}.faq-icon-btn:hover:not(:disabled){background:#ffffff14}.faq-icon-btn:disabled{opacity:.35;cursor:not-allowed}.faq-icon-btn.active{background:#ffffff1f;border-color:#ffffff2e}.faq-body{display:grid;grid-template-columns:260px 1fr;min-height:0}.faq-body.sidebar-collapsed{grid-template-columns:0 1fr}.faq-body.sidebar-collapsed .faq-sidebar{display:none}.faq-sidebar{border-right:1px solid var(--shell-border, rgba(255, 255, 255, .08));overflow-y:auto;padding:.75rem .5rem;background:var(--shell-surface, #1d1f23)}.faq-toc-group{margin-bottom:1rem}.faq-toc-category{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.6;margin:0 0 .4rem .4rem}.faq-toc ul{list-style:none;padding:0;margin:0}.faq-toc-link{display:block;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.35rem .5rem;border-radius:4px;cursor:pointer;font-size:.88rem}.faq-toc-link:hover{background:#ffffff0f}.faq-toc-link.active{background:#ffffff1f;font-weight:600}.faq-toc-empty{padding:1rem .5rem;opacity:.7;font-size:.85rem}.faq-search{display:flex;flex-direction:column;gap:.5rem;padding:.25rem}.faq-search-input{width:100%;padding:.5rem .6rem;border-radius:4px;border:1px solid rgba(255,255,255,.18);background:#00000040;color:inherit;font-size:.9rem;box-sizing:border-box}.faq-search-input:focus{outline:none;border-color:#fff6}.faq-search-status{padding:.5rem;opacity:.65;font-size:.82rem;margin:0}.faq-search-results{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}.faq-search-result{display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.45rem .5rem;border-radius:4px;cursor:pointer}.faq-search-result:hover{background:#ffffff0f}.faq-search-result.active{background:#ffffff1f}.faq-search-result-title{font-size:.9rem;font-weight:600}.faq-search-result-category{font-size:.72rem;opacity:.6;text-transform:uppercase;letter-spacing:.04em}.faq-search-result-snippet{font-size:.78rem;opacity:.75;line-height:1.35}.faq-content{overflow-y:auto;padding:1.25rem 2rem;min-width:0}.faq-loading,.faq-empty{opacity:.75;padding:1rem 0}.faq-empty-chain code{background:#ffffff14;padding:.1rem .4rem;border-radius:3px;font-size:.85rem}.faq-empty-hint{margin-top:1rem;opacity:.55;font-size:.85rem}.faq-article{max-width:70ch;line-height:1.55;font-size:.95rem}.faq-article h1,.faq-article h2,.faq-article h3{font-weight:600;margin:1.4rem 0 .6rem}.faq-article h1{font-size:1.4rem;margin-top:0}.faq-article h2{font-size:1.15rem}.faq-article h3{font-size:1rem}.faq-article p{margin:.6rem 0}.faq-article a{color:var(--shell-link, #6ea8fe);text-decoration:none}.faq-article a:hover{text-decoration:underline}.faq-article a[data-faq-kind=external]:after{content:\" \\2197\";opacity:.65;font-size:.85em}.faq-article .faq-app-arrow{opacity:.7;font-size:.9em}.faq-article code{background:#ffffff14;padding:.1rem .35rem;border-radius:3px;font-size:.88em}.faq-article pre{background:#00000059;padding:.75rem 1rem;border-radius:4px;overflow-x:auto}.faq-article pre code{background:transparent;padding:0}.faq-article img{max-width:100%;border-radius:4px;margin:.6rem 0}.faq-article ul,.faq-article ol{padding-left:1.4rem;margin:.6rem 0}.faq-article blockquote{border-left:3px solid var(--shell-border, rgba(255, 255, 255, .15));padding-left:.9rem;margin:.8rem 0;opacity:.85}@media(max-width:900px){.faq-modal{width:100vw;height:100vh;border-radius:0;max-width:none;max-height:none}.faq-backdrop{padding:0}.faq-body{grid-template-columns:1fr}.faq-sidebar{display:none}.faq-body:not(.sidebar-collapsed) .faq-sidebar{display:block;position:absolute;inset:0;z-index:1}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None, deferBlockDependencies: [() => [/* @ts-ignore */
|
|
1156
|
+
Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)], () => [/* @ts-ignore */
|
|
1157
|
+
Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)]] }); }
|
|
1126
1158
|
}
|
|
1127
|
-
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "
|
|
1159
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.4", ngImport: i0, type: FaqModal, resolveDeferredDeps: () => [/* @ts-ignore */
|
|
1160
|
+
Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)], resolveMetadata: FaqAuthoringPanel => ({ decorators: [{
|
|
1128
1161
|
type: Component,
|
|
1129
1162
|
args: [{ selector: 'faq-modal', standalone: true, imports: [FaqAuthoringPanel], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >\u2630</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >\u2039</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >\u203A</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >\u2302</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >\u2315</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\u2715</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ\u2026\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index\u2026</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading\u2026</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' \u2192 ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel\u2026</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.faq-backdrop{position:fixed;inset:0;z-index:1100;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:5vh 5vw}.faq-modal{width:80vw;height:80vh;max-width:1600px;max-height:1100px;background:var(--shell-surface, #1d1f23);color:var(--shell-fg, #e6e6e6);border-radius:8px;box-shadow:0 12px 32px #00000080;display:grid;grid-template-rows:auto 1fr;overflow:hidden;font-family:var(--shell-font, system-ui, sans-serif)}.faq-toolbar{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--shell-border, rgba(255, 255, 255, .08));background:var(--shell-surface-2, rgba(255, 255, 255, .03))}.faq-toolbar-nav,.faq-toolbar-actions{display:flex;gap:.25rem}.faq-toolbar-title{text-align:center;font-size:.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.faq-category{opacity:.7;margin-right:.25rem}.faq-sep{opacity:.4;margin:0 .25rem}.faq-title{font-weight:600}.faq-icon-btn{background:transparent;border:1px solid transparent;color:inherit;width:2rem;height:2rem;border-radius:4px;cursor:pointer;font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}.faq-icon-btn:hover:not(:disabled){background:#ffffff14}.faq-icon-btn:disabled{opacity:.35;cursor:not-allowed}.faq-icon-btn.active{background:#ffffff1f;border-color:#ffffff2e}.faq-body{display:grid;grid-template-columns:260px 1fr;min-height:0}.faq-body.sidebar-collapsed{grid-template-columns:0 1fr}.faq-body.sidebar-collapsed .faq-sidebar{display:none}.faq-sidebar{border-right:1px solid var(--shell-border, rgba(255, 255, 255, .08));overflow-y:auto;padding:.75rem .5rem;background:var(--shell-surface, #1d1f23)}.faq-toc-group{margin-bottom:1rem}.faq-toc-category{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.6;margin:0 0 .4rem .4rem}.faq-toc ul{list-style:none;padding:0;margin:0}.faq-toc-link{display:block;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.35rem .5rem;border-radius:4px;cursor:pointer;font-size:.88rem}.faq-toc-link:hover{background:#ffffff0f}.faq-toc-link.active{background:#ffffff1f;font-weight:600}.faq-toc-empty{padding:1rem .5rem;opacity:.7;font-size:.85rem}.faq-search{display:flex;flex-direction:column;gap:.5rem;padding:.25rem}.faq-search-input{width:100%;padding:.5rem .6rem;border-radius:4px;border:1px solid rgba(255,255,255,.18);background:#00000040;color:inherit;font-size:.9rem;box-sizing:border-box}.faq-search-input:focus{outline:none;border-color:#fff6}.faq-search-status{padding:.5rem;opacity:.65;font-size:.82rem;margin:0}.faq-search-results{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}.faq-search-result{display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.45rem .5rem;border-radius:4px;cursor:pointer}.faq-search-result:hover{background:#ffffff0f}.faq-search-result.active{background:#ffffff1f}.faq-search-result-title{font-size:.9rem;font-weight:600}.faq-search-result-category{font-size:.72rem;opacity:.6;text-transform:uppercase;letter-spacing:.04em}.faq-search-result-snippet{font-size:.78rem;opacity:.75;line-height:1.35}.faq-content{overflow-y:auto;padding:1.25rem 2rem;min-width:0}.faq-loading,.faq-empty{opacity:.75;padding:1rem 0}.faq-empty-chain code{background:#ffffff14;padding:.1rem .4rem;border-radius:3px;font-size:.85rem}.faq-empty-hint{margin-top:1rem;opacity:.55;font-size:.85rem}.faq-article{max-width:70ch;line-height:1.55;font-size:.95rem}.faq-article h1,.faq-article h2,.faq-article h3{font-weight:600;margin:1.4rem 0 .6rem}.faq-article h1{font-size:1.4rem;margin-top:0}.faq-article h2{font-size:1.15rem}.faq-article h3{font-size:1rem}.faq-article p{margin:.6rem 0}.faq-article a{color:var(--shell-link, #6ea8fe);text-decoration:none}.faq-article a:hover{text-decoration:underline}.faq-article a[data-faq-kind=external]:after{content:\" \\2197\";opacity:.65;font-size:.85em}.faq-article .faq-app-arrow{opacity:.7;font-size:.9em}.faq-article code{background:#ffffff14;padding:.1rem .35rem;border-radius:3px;font-size:.88em}.faq-article pre{background:#00000059;padding:.75rem 1rem;border-radius:4px;overflow-x:auto}.faq-article pre code{background:transparent;padding:0}.faq-article img{max-width:100%;border-radius:4px;margin:.6rem 0}.faq-article ul,.faq-article ol{padding-left:1.4rem;margin:.6rem 0}.faq-article blockquote{border-left:3px solid var(--shell-border, rgba(255, 255, 255, .15));padding-left:.9rem;margin:.8rem 0;opacity:.85}@media(max-width:900px){.faq-modal{width:100vw;height:100vh;border-radius:0;max-width:none;max-height:none}.faq-backdrop{padding:0}.faq-body{grid-template-columns:1fr}.faq-sidebar{display:none}.faq-body:not(.sidebar-collapsed) .faq-sidebar{display:block;position:absolute;inset:0;z-index:1}}\n"] }]
|
|
1130
1163
|
}], ctorParameters: () => [], propDecorators: { contentPaneRef: [{
|
|
@@ -1174,37 +1207,49 @@ class FaqAuthoringPanel {
|
|
|
1174
1207
|
this.workspaceRoot = inject(FAQ_DEV_WORKSPACE_ROOT);
|
|
1175
1208
|
this.editor = inject(FAQ_DEV_EDITOR);
|
|
1176
1209
|
/** `'missing'` shows the full scaffold; `'existing'` shows the collapsed strip. */
|
|
1177
|
-
this.mode = input.required(
|
|
1210
|
+
this.mode = input.required(/* @ts-ignore */
|
|
1211
|
+
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
1178
1212
|
/**
|
|
1179
1213
|
* The dot-notation key actually being authored. For `missing` mode this is
|
|
1180
1214
|
* the deepest attempted key (chain[0]); for `existing` it's the resolved key.
|
|
1181
1215
|
*/
|
|
1182
|
-
this.key = input.required(
|
|
1216
|
+
this.key = input.required(/* @ts-ignore */
|
|
1217
|
+
...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
|
|
1183
1218
|
/** Fallback chain that was attempted. For `missing` every entry is missing. */
|
|
1184
|
-
this.attempted = input([],
|
|
1219
|
+
this.attempted = input([], /* @ts-ignore */
|
|
1220
|
+
...(ngDevMode ? [{ debugName: "attempted" }] : /* istanbul ignore next */ []));
|
|
1185
1221
|
/** Resolved entry — only set in `existing` mode. */
|
|
1186
|
-
this.entry = input(null,
|
|
1187
|
-
|
|
1188
|
-
this.
|
|
1189
|
-
|
|
1222
|
+
this.entry = input(null, /* @ts-ignore */
|
|
1223
|
+
...(ngDevMode ? [{ debugName: "entry" }] : /* istanbul ignore next */ []));
|
|
1224
|
+
this.expanded = signal(false, /* @ts-ignore */
|
|
1225
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
1226
|
+
this.showAllFiles = signal(false, /* @ts-ignore */
|
|
1227
|
+
...(ngDevMode ? [{ debugName: "showAllFiles" }] : /* istanbul ignore next */ []));
|
|
1228
|
+
this.copyState = signal(null, /* @ts-ignore */
|
|
1229
|
+
...(ngDevMode ? [{ debugName: "copyState" }] : /* istanbul ignore next */ []));
|
|
1190
1230
|
this.relPath = computed(() => {
|
|
1191
1231
|
const e = this.entry();
|
|
1192
1232
|
if (e)
|
|
1193
1233
|
return `src/assets/faq/${e.file}.md`;
|
|
1194
1234
|
return `src/assets/faq/${keyToFilePath(this.key())}.md`;
|
|
1195
|
-
},
|
|
1235
|
+
}, /* @ts-ignore */
|
|
1236
|
+
...(ngDevMode ? [{ debugName: "relPath" }] : /* istanbul ignore next */ []));
|
|
1196
1237
|
this.absPath = computed(() => {
|
|
1197
1238
|
const rel = this.relPath();
|
|
1198
1239
|
return this.workspaceRoot ? joinPosix(this.workspaceRoot, rel) : rel;
|
|
1199
|
-
},
|
|
1240
|
+
}, /* @ts-ignore */
|
|
1241
|
+
...(ngDevMode ? [{ debugName: "absPath" }] : /* istanbul ignore next */ []));
|
|
1200
1242
|
this.editorHref = computed(() => {
|
|
1201
1243
|
const abs = this.absPath();
|
|
1202
1244
|
if (this.editor === 'vscode')
|
|
1203
1245
|
return `vscode://file/${abs}`;
|
|
1204
1246
|
return `webstorm://open?file=${encodeURI(abs)}`;
|
|
1205
|
-
},
|
|
1206
|
-
|
|
1207
|
-
this.
|
|
1247
|
+
}, /* @ts-ignore */
|
|
1248
|
+
...(ngDevMode ? [{ debugName: "editorHref" }] : /* istanbul ignore next */ []));
|
|
1249
|
+
this.editorLabel = computed(() => this.editor === 'vscode' ? 'Open in VS Code' : 'Open in WebStorm', /* @ts-ignore */
|
|
1250
|
+
...(ngDevMode ? [{ debugName: "editorLabel" }] : /* istanbul ignore next */ []));
|
|
1251
|
+
this.scaffoldCmd = computed(() => `npm run faq:new -- ${this.key()}`, /* @ts-ignore */
|
|
1252
|
+
...(ngDevMode ? [{ debugName: "scaffoldCmd" }] : /* istanbul ignore next */ []));
|
|
1208
1253
|
this.frontmatterScaffold = computed(() => {
|
|
1209
1254
|
const k = this.key();
|
|
1210
1255
|
const title = humanize(k);
|
|
@@ -1223,12 +1268,15 @@ class FaqAuthoringPanel {
|
|
|
1223
1268
|
`TODO: write content for "${title}".`,
|
|
1224
1269
|
'',
|
|
1225
1270
|
].join('\n');
|
|
1226
|
-
},
|
|
1227
|
-
|
|
1271
|
+
}, /* @ts-ignore */
|
|
1272
|
+
...(ngDevMode ? [{ debugName: "frontmatterScaffold" }] : /* istanbul ignore next */ []));
|
|
1273
|
+
this.allEntries = computed(() => this.faq.entries(), /* @ts-ignore */
|
|
1274
|
+
...(ngDevMode ? [{ debugName: "allEntries" }] : /* istanbul ignore next */ []));
|
|
1228
1275
|
this.missedChain = computed(() => {
|
|
1229
1276
|
const present = new Set(this.allEntries().map((e) => e.key));
|
|
1230
1277
|
return this.attempted().map((k) => ({ key: k, present: present.has(k) }));
|
|
1231
|
-
},
|
|
1278
|
+
}, /* @ts-ignore */
|
|
1279
|
+
...(ngDevMode ? [{ debugName: "missedChain" }] : /* istanbul ignore next */ []));
|
|
1232
1280
|
}
|
|
1233
1281
|
toggleExpanded() {
|
|
1234
1282
|
this.expanded.update((v) => !v);
|
|
@@ -1249,10 +1297,10 @@ class FaqAuthoringPanel {
|
|
|
1249
1297
|
this.copyState.set(`${label}:err`);
|
|
1250
1298
|
}
|
|
1251
1299
|
}
|
|
1252
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1253
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1300
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqAuthoringPanel, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1301
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: FaqAuthoringPanel, isStandalone: true, selector: "faq-authoring-panel", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, attempted: { classPropertyName: "attempted", publicName: "attempted", isSignal: true, isRequired: false, transformFunction: null }, entry: { classPropertyName: "entry", publicName: "entry", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (mode() === 'missing') {\n <section class=\"faq-authoring missing\" aria-label=\"FAQ authoring panel\">\n <header class=\"faq-authoring-header\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <h3>Start authoring this FAQ</h3>\n </header>\n\n <dl class=\"faq-authoring-meta\">\n <dt>Key</dt>\n <dd><code>{{ key() }}</code></dd>\n\n <dt>Fallback chain</dt>\n <dd>\n <ul class=\"faq-authoring-chain\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </dd>\n\n <dt>Target file</dt>\n <dd>\n <code>{{ relPath() }}</code>\n <a\n class=\"faq-authoring-editor\"\n [href]=\"editorHref()\"\n >{{ editorLabel() }} \u2197</a>\n </dd>\n </dl>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Scaffold via CLI</span>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ scaffoldCmd() }}</code></pre>\n </div>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Frontmatter scaffold</span>\n <button type=\"button\" (click)=\"copy(frontmatterScaffold(), 'fm')\">\n {{ copyState() === 'fm' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ frontmatterScaffold() }}</code></pre>\n </div>\n\n <details class=\"faq-authoring-cheat\">\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app (modal closes)</li>\n <li><code>[label](https://example.com)</code> \u2014 external (new tab)</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image (drop into <code>src/assets/faq/images/</code>)</li>\n </ul>\n </details>\n\n <details class=\"faq-authoring-all\" [open]=\"showAllFiles()\">\n <summary (click)=\"toggleAllFiles(); $event.preventDefault()\">\n Show all FAQ files ({{ allEntries().length }})\n </summary>\n <ul class=\"faq-authoring-file-list\">\n @for (e of allEntries(); track e.key) {\n <li>\n <code>{{ e.key }}</code>\n <span class=\"faq-authoring-file-path\">src/assets/faq/{{ e.file }}.md</span>\n </li>\n } @empty {\n <li class=\"empty\">Manifest is empty.</li>\n }\n </ul>\n </details>\n </section>\n} @else {\n <aside class=\"faq-authoring existing\" aria-label=\"FAQ source info\">\n <div class=\"faq-authoring-strip\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <span>Key: <code>{{ key() }}</code></span>\n <span class=\"sep\">\u2022</span>\n <span>Source: <code>{{ relPath() }}</code></span>\n <a class=\"faq-authoring-editor\" [href]=\"editorHref()\">{{ editorLabel() }} \u2197</a>\n <button type=\"button\" class=\"faq-authoring-more\" (click)=\"toggleExpanded()\">\n {{ expanded() ? '\u25B2 Less' : '\u25BC More' }}\n </button>\n </div>\n @if (expanded()) {\n <div class=\"faq-authoring-expanded\">\n <div>\n <strong>Fallback chain attempted:</strong>\n <ul class=\"faq-authoring-chain inline\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </div>\n <details class=\"faq-authoring-cheat\" open>\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app</li>\n <li><code>[label](https://example.com)</code> \u2014 external</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image</li>\n </ul>\n </details>\n <div class=\"faq-authoring-rescaffold\">\n <span>Re-scaffold (overwrites if you delete first):</span>\n <code>{{ scaffoldCmd() }}</code>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n </div>\n }\n </aside>\n}\n", styles: [":host{display:block;font-family:var(--shell-font, system-ui, sans-serif);font-size:.875rem;color:var(--shell-fg, #e6e6e6)}.faq-authoring{border:1px dashed var(--shell-accent, #6aa0ff);border-radius:6px;background:#6aa0ff0a}.faq-authoring.missing{padding:1rem 1.25rem;display:grid;gap:.85rem}.faq-authoring.existing{margin-top:1.5rem;padding:.5rem .75rem;background:#6aa0ff08;border-style:dotted}.faq-authoring-header{display:flex;align-items:baseline;gap:.5rem;margin:0}.faq-authoring-header h3{margin:0;font-size:1rem}.faq-authoring-tag{display:inline-block;padding:.05rem .4rem;background:var(--shell-accent, #6aa0ff);color:#0b0d11;border-radius:3px;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.faq-authoring-meta{display:grid;grid-template-columns:max-content 1fr;gap:.35rem .85rem;margin:0}.faq-authoring-meta dt{font-weight:600;opacity:.75}.faq-authoring-meta dd{margin:0}.faq-authoring code{font-family:var(--shell-mono, ui-monospace, monospace);background:#ffffff0f;padding:.05rem .3rem;border-radius:3px;font-size:.85em}.faq-authoring-chain{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:.4rem}.faq-authoring-chain.inline{display:inline-flex;margin-left:.5rem}.faq-authoring-chain li{display:inline-flex;align-items:center;gap:.25rem}.faq-authoring-chain .mark{font-weight:700}.faq-authoring-chain .missed .mark{color:#ff7676}.faq-authoring-chain .present .mark{color:#8ad27a}.faq-authoring-editor{margin-left:.75rem;color:var(--shell-accent, #6aa0ff);text-decoration:none}.faq-authoring-editor:hover{text-decoration:underline}.faq-authoring-block{border:1px solid var(--shell-border, rgba(255, 255, 255, .08));border-radius:4px;overflow:hidden}.faq-authoring-block-head{display:flex;justify-content:space-between;align-items:center;padding:.4rem .6rem;background:#ffffff0a;font-weight:600;font-size:.8rem}.faq-authoring-block-head button,.faq-authoring-more,.faq-authoring-rescaffold button{background:var(--shell-accent, #6aa0ff);color:#0b0d11;border:0;border-radius:3px;padding:.2rem .55rem;font-size:.75rem;cursor:pointer;font-family:inherit}.faq-authoring-block pre{margin:0;padding:.6rem .75rem;overflow-x:auto;background:#00000040;font-size:.8rem}.faq-authoring-cheat,.faq-authoring-all{font-size:.85rem}.faq-authoring-cheat summary,.faq-authoring-all summary{cursor:pointer;opacity:.85}.faq-authoring-cheat ul,.faq-authoring-file-list{margin:.4rem 0 0;padding-left:1.25rem}.faq-authoring-file-list{list-style:none;padding-left:0;max-height:200px;overflow-y:auto}.faq-authoring-file-list li{display:flex;justify-content:space-between;gap:.5rem;padding:.15rem 0;border-bottom:1px solid rgba(255,255,255,.04)}.faq-authoring-file-path{opacity:.6;font-family:var(--shell-mono, ui-monospace, monospace);font-size:.75rem}.faq-authoring-strip{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:.8rem}.faq-authoring-strip .sep{opacity:.4}.faq-authoring-more{margin-left:auto}.faq-authoring-expanded{margin-top:.6rem;padding-top:.5rem;border-top:1px solid rgba(255,255,255,.08);display:grid;gap:.6rem}.faq-authoring-rescaffold{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;font-size:.8rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1254
1302
|
}
|
|
1255
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqAuthoringPanel, decorators: [{
|
|
1256
1304
|
type: Component,
|
|
1257
1305
|
args: [{ selector: 'faq-authoring-panel', standalone: true, imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (mode() === 'missing') {\n <section class=\"faq-authoring missing\" aria-label=\"FAQ authoring panel\">\n <header class=\"faq-authoring-header\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <h3>Start authoring this FAQ</h3>\n </header>\n\n <dl class=\"faq-authoring-meta\">\n <dt>Key</dt>\n <dd><code>{{ key() }}</code></dd>\n\n <dt>Fallback chain</dt>\n <dd>\n <ul class=\"faq-authoring-chain\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </dd>\n\n <dt>Target file</dt>\n <dd>\n <code>{{ relPath() }}</code>\n <a\n class=\"faq-authoring-editor\"\n [href]=\"editorHref()\"\n >{{ editorLabel() }} \u2197</a>\n </dd>\n </dl>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Scaffold via CLI</span>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ scaffoldCmd() }}</code></pre>\n </div>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Frontmatter scaffold</span>\n <button type=\"button\" (click)=\"copy(frontmatterScaffold(), 'fm')\">\n {{ copyState() === 'fm' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ frontmatterScaffold() }}</code></pre>\n </div>\n\n <details class=\"faq-authoring-cheat\">\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app (modal closes)</li>\n <li><code>[label](https://example.com)</code> \u2014 external (new tab)</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image (drop into <code>src/assets/faq/images/</code>)</li>\n </ul>\n </details>\n\n <details class=\"faq-authoring-all\" [open]=\"showAllFiles()\">\n <summary (click)=\"toggleAllFiles(); $event.preventDefault()\">\n Show all FAQ files ({{ allEntries().length }})\n </summary>\n <ul class=\"faq-authoring-file-list\">\n @for (e of allEntries(); track e.key) {\n <li>\n <code>{{ e.key }}</code>\n <span class=\"faq-authoring-file-path\">src/assets/faq/{{ e.file }}.md</span>\n </li>\n } @empty {\n <li class=\"empty\">Manifest is empty.</li>\n }\n </ul>\n </details>\n </section>\n} @else {\n <aside class=\"faq-authoring existing\" aria-label=\"FAQ source info\">\n <div class=\"faq-authoring-strip\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <span>Key: <code>{{ key() }}</code></span>\n <span class=\"sep\">\u2022</span>\n <span>Source: <code>{{ relPath() }}</code></span>\n <a class=\"faq-authoring-editor\" [href]=\"editorHref()\">{{ editorLabel() }} \u2197</a>\n <button type=\"button\" class=\"faq-authoring-more\" (click)=\"toggleExpanded()\">\n {{ expanded() ? '\u25B2 Less' : '\u25BC More' }}\n </button>\n </div>\n @if (expanded()) {\n <div class=\"faq-authoring-expanded\">\n <div>\n <strong>Fallback chain attempted:</strong>\n <ul class=\"faq-authoring-chain inline\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </div>\n <details class=\"faq-authoring-cheat\" open>\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app</li>\n <li><code>[label](https://example.com)</code> \u2014 external</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image</li>\n </ul>\n </details>\n <div class=\"faq-authoring-rescaffold\">\n <span>Re-scaffold (overwrites if you delete first):</span>\n <code>{{ scaffoldCmd() }}</code>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n </div>\n }\n </aside>\n}\n", styles: [":host{display:block;font-family:var(--shell-font, system-ui, sans-serif);font-size:.875rem;color:var(--shell-fg, #e6e6e6)}.faq-authoring{border:1px dashed var(--shell-accent, #6aa0ff);border-radius:6px;background:#6aa0ff0a}.faq-authoring.missing{padding:1rem 1.25rem;display:grid;gap:.85rem}.faq-authoring.existing{margin-top:1.5rem;padding:.5rem .75rem;background:#6aa0ff08;border-style:dotted}.faq-authoring-header{display:flex;align-items:baseline;gap:.5rem;margin:0}.faq-authoring-header h3{margin:0;font-size:1rem}.faq-authoring-tag{display:inline-block;padding:.05rem .4rem;background:var(--shell-accent, #6aa0ff);color:#0b0d11;border-radius:3px;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.faq-authoring-meta{display:grid;grid-template-columns:max-content 1fr;gap:.35rem .85rem;margin:0}.faq-authoring-meta dt{font-weight:600;opacity:.75}.faq-authoring-meta dd{margin:0}.faq-authoring code{font-family:var(--shell-mono, ui-monospace, monospace);background:#ffffff0f;padding:.05rem .3rem;border-radius:3px;font-size:.85em}.faq-authoring-chain{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:.4rem}.faq-authoring-chain.inline{display:inline-flex;margin-left:.5rem}.faq-authoring-chain li{display:inline-flex;align-items:center;gap:.25rem}.faq-authoring-chain .mark{font-weight:700}.faq-authoring-chain .missed .mark{color:#ff7676}.faq-authoring-chain .present .mark{color:#8ad27a}.faq-authoring-editor{margin-left:.75rem;color:var(--shell-accent, #6aa0ff);text-decoration:none}.faq-authoring-editor:hover{text-decoration:underline}.faq-authoring-block{border:1px solid var(--shell-border, rgba(255, 255, 255, .08));border-radius:4px;overflow:hidden}.faq-authoring-block-head{display:flex;justify-content:space-between;align-items:center;padding:.4rem .6rem;background:#ffffff0a;font-weight:600;font-size:.8rem}.faq-authoring-block-head button,.faq-authoring-more,.faq-authoring-rescaffold button{background:var(--shell-accent, #6aa0ff);color:#0b0d11;border:0;border-radius:3px;padding:.2rem .55rem;font-size:.75rem;cursor:pointer;font-family:inherit}.faq-authoring-block pre{margin:0;padding:.6rem .75rem;overflow-x:auto;background:#00000040;font-size:.8rem}.faq-authoring-cheat,.faq-authoring-all{font-size:.85rem}.faq-authoring-cheat summary,.faq-authoring-all summary{cursor:pointer;opacity:.85}.faq-authoring-cheat ul,.faq-authoring-file-list{margin:.4rem 0 0;padding-left:1.25rem}.faq-authoring-file-list{list-style:none;padding-left:0;max-height:200px;overflow-y:auto}.faq-authoring-file-list li{display:flex;justify-content:space-between;gap:.5rem;padding:.15rem 0;border-bottom:1px solid rgba(255,255,255,.04)}.faq-authoring-file-path{opacity:.6;font-family:var(--shell-mono, ui-monospace, monospace);font-size:.75rem}.faq-authoring-strip{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:.8rem}.faq-authoring-strip .sep{opacity:.4}.faq-authoring-more{margin-left:auto}.faq-authoring-expanded{margin-top:.6rem;padding-top:.5rem;border-top:1px solid rgba(255,255,255,.08);display:grid;gap:.6rem}.faq-authoring-rescaffold{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;font-size:.8rem}\n"] }]
|
|
1258
1306
|
}], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], attempted: [{ type: i0.Input, args: [{ isSignal: true, alias: "attempted", required: false }] }], entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: false }] }] } });
|
|
@@ -1290,8 +1338,10 @@ class PublicFaqToc {
|
|
|
1290
1338
|
constructor() {
|
|
1291
1339
|
this.loader = inject(FAQ_CONTENT_LOADER);
|
|
1292
1340
|
/** Currently-active entry file path (e.g. `landing`). Empty/undefined on the index. */
|
|
1293
|
-
this.activeFile = input(undefined,
|
|
1294
|
-
|
|
1341
|
+
this.activeFile = input(undefined, /* @ts-ignore */
|
|
1342
|
+
...(ngDevMode ? [{ debugName: "activeFile" }] : /* istanbul ignore next */ []));
|
|
1343
|
+
this._entries = signal([], /* @ts-ignore */
|
|
1344
|
+
...(ngDevMode ? [{ debugName: "_entries" }] : /* istanbul ignore next */ []));
|
|
1295
1345
|
this.groups = computed(() => {
|
|
1296
1346
|
const visible = this._entries().filter((e) => e.audience === 'public' && e.seoReady);
|
|
1297
1347
|
const byCategory = new Map();
|
|
@@ -1307,14 +1357,15 @@ class PublicFaqToc {
|
|
|
1307
1357
|
}
|
|
1308
1358
|
groups.sort((a, b) => a.category.localeCompare(b.category));
|
|
1309
1359
|
return groups;
|
|
1310
|
-
},
|
|
1360
|
+
}, /* @ts-ignore */
|
|
1361
|
+
...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
|
|
1311
1362
|
}
|
|
1312
1363
|
async ngOnInit() {
|
|
1313
1364
|
const manifest = await this.loader.loadManifest();
|
|
1314
1365
|
this._entries.set(manifest.entries);
|
|
1315
1366
|
}
|
|
1316
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1317
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1367
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PublicFaqToc, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1368
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: PublicFaqToc, isStandalone: true, selector: "public-faq-toc", inputs: { activeFile: { classPropertyName: "activeFile", publicName: "activeFile", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1318
1369
|
<nav class="public-faq-toc" aria-label="Help contents">
|
|
1319
1370
|
<a
|
|
1320
1371
|
class="public-faq-toc__index"
|
|
@@ -1338,9 +1389,9 @@ class PublicFaqToc {
|
|
|
1338
1389
|
</div>
|
|
1339
1390
|
}
|
|
1340
1391
|
</nav>
|
|
1341
|
-
`, isInline: true, styles: [":host{display:block}.public-faq-toc{padding:1.25rem 1rem;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:.95rem;line-height:1.4}.public-faq-toc__index{display:block;font-weight:600;color:#cfd6e4;text-decoration:none;padding:.4rem .5rem;border-radius:4px;margin-bottom:.75rem}.public-faq-toc__index.active,.public-faq-toc__index:hover{background:#ffffff0f}.public-faq-toc__group{margin-bottom:1rem}.public-faq-toc__category{font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8a93a3;margin:0 0 .35rem;padding:0 .5rem}.public-faq-toc ul{list-style:none;padding:0;margin:0}.public-faq-toc li a{display:block;padding:.35rem .5rem;border-radius:4px;color:#cfd6e4;text-decoration:none}.public-faq-toc li a:hover{background:#ffffff0d}.public-faq-toc li a.active{background:#6ea8fe2e;color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] }); }
|
|
1392
|
+
`, isInline: true, styles: [":host{display:block}.public-faq-toc{padding:1.25rem 1rem;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:.95rem;line-height:1.4}.public-faq-toc__index{display:block;font-weight:600;color:#cfd6e4;text-decoration:none;padding:.4rem .5rem;border-radius:4px;margin-bottom:.75rem}.public-faq-toc__index.active,.public-faq-toc__index:hover{background:#ffffff0f}.public-faq-toc__group{margin-bottom:1rem}.public-faq-toc__category{font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8a93a3;margin:0 0 .35rem;padding:0 .5rem}.public-faq-toc ul{list-style:none;padding:0;margin:0}.public-faq-toc li a{display:block;padding:.35rem .5rem;border-radius:4px;color:#cfd6e4;text-decoration:none}.public-faq-toc li a:hover{background:#ffffff0d}.public-faq-toc li a.active{background:#6ea8fe2e;color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1342
1393
|
}
|
|
1343
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1394
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PublicFaqToc, decorators: [{
|
|
1344
1395
|
type: Component,
|
|
1345
1396
|
args: [{ selector: 'public-faq-toc', standalone: true, imports: [CommonModule, RouterLink, RouterLinkActive], template: `
|
|
1346
1397
|
<nav class="public-faq-toc" aria-label="Help contents">
|
|
@@ -1366,7 +1417,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1366
1417
|
</div>
|
|
1367
1418
|
}
|
|
1368
1419
|
</nav>
|
|
1369
|
-
`, styles: [":host{display:block}.public-faq-toc{padding:1.25rem 1rem;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:.95rem;line-height:1.4}.public-faq-toc__index{display:block;font-weight:600;color:#cfd6e4;text-decoration:none;padding:.4rem .5rem;border-radius:4px;margin-bottom:.75rem}.public-faq-toc__index.active,.public-faq-toc__index:hover{background:#ffffff0f}.public-faq-toc__group{margin-bottom:1rem}.public-faq-toc__category{font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8a93a3;margin:0 0 .35rem;padding:0 .5rem}.public-faq-toc ul{list-style:none;padding:0;margin:0}.public-faq-toc li a{display:block;padding:.35rem .5rem;border-radius:4px;color:#cfd6e4;text-decoration:none}.public-faq-toc li a:hover{background:#ffffff0d}.public-faq-toc li a.active{background:#6ea8fe2e;color:#fff}\n"] }]
|
|
1420
|
+
`, changeDetection: ChangeDetectionStrategy.Eager, styles: [":host{display:block}.public-faq-toc{padding:1.25rem 1rem;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:.95rem;line-height:1.4}.public-faq-toc__index{display:block;font-weight:600;color:#cfd6e4;text-decoration:none;padding:.4rem .5rem;border-radius:4px;margin-bottom:.75rem}.public-faq-toc__index.active,.public-faq-toc__index:hover{background:#ffffff0f}.public-faq-toc__group{margin-bottom:1rem}.public-faq-toc__category{font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8a93a3;margin:0 0 .35rem;padding:0 .5rem}.public-faq-toc ul{list-style:none;padding:0;margin:0}.public-faq-toc li a{display:block;padding:.35rem .5rem;border-radius:4px;color:#cfd6e4;text-decoration:none}.public-faq-toc li a:hover{background:#ffffff0d}.public-faq-toc li a.active{background:#6ea8fe2e;color:#fff}\n"] }]
|
|
1370
1421
|
}], propDecorators: { activeFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeFile", required: false }] }] } });
|
|
1371
1422
|
|
|
1372
1423
|
/**
|
|
@@ -1396,9 +1447,12 @@ class PublicFaqIndex {
|
|
|
1396
1447
|
this.meta = inject(Meta);
|
|
1397
1448
|
this.siteBase = inject(FAQ_PUBLIC_SITE_BASE_URL);
|
|
1398
1449
|
this.publisher = inject(FAQ_PUBLIC_PUBLISHER);
|
|
1399
|
-
this._entries = signal([],
|
|
1400
|
-
|
|
1401
|
-
this.
|
|
1450
|
+
this._entries = signal([], /* @ts-ignore */
|
|
1451
|
+
...(ngDevMode ? [{ debugName: "_entries" }] : /* istanbul ignore next */ []));
|
|
1452
|
+
this.loading = signal(true, /* @ts-ignore */
|
|
1453
|
+
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1454
|
+
this.visibleEntries = computed(() => this._entries().filter((e) => e.audience === 'public' && e.seoReady), /* @ts-ignore */
|
|
1455
|
+
...(ngDevMode ? [{ debugName: "visibleEntries" }] : /* istanbul ignore next */ []));
|
|
1402
1456
|
this.groups = computed(() => {
|
|
1403
1457
|
const visible = this.visibleEntries();
|
|
1404
1458
|
const byCategory = new Map();
|
|
@@ -1414,7 +1468,8 @@ class PublicFaqIndex {
|
|
|
1414
1468
|
}
|
|
1415
1469
|
groups.sort((a, b) => a.category.localeCompare(b.category));
|
|
1416
1470
|
return groups;
|
|
1417
|
-
},
|
|
1471
|
+
}, /* @ts-ignore */
|
|
1472
|
+
...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
|
|
1418
1473
|
this.jsonLd = computed(() => {
|
|
1419
1474
|
const entries = this.visibleEntries();
|
|
1420
1475
|
if (entries.length === 0)
|
|
@@ -1448,7 +1503,8 @@ class PublicFaqIndex {
|
|
|
1448
1503
|
ld['publisher'] = pub;
|
|
1449
1504
|
}
|
|
1450
1505
|
return serializeJsonLd$1(ld);
|
|
1451
|
-
},
|
|
1506
|
+
}, /* @ts-ignore */
|
|
1507
|
+
...(ngDevMode ? [{ debugName: "jsonLd" }] : /* istanbul ignore next */ []));
|
|
1452
1508
|
}
|
|
1453
1509
|
async ngOnInit() {
|
|
1454
1510
|
try {
|
|
@@ -1477,8 +1533,8 @@ class PublicFaqIndex {
|
|
|
1477
1533
|
this.meta.updateTag({ name: 'twitter:title', content: 'Help — Brokenstock' });
|
|
1478
1534
|
this.meta.updateTag({ name: 'twitter:description', content: description });
|
|
1479
1535
|
}
|
|
1480
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1481
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1536
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PublicFaqIndex, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1537
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: PublicFaqIndex, isStandalone: true, selector: "public-faq-index", ngImport: i0, template: `
|
|
1482
1538
|
<div class="public-faq-layout">
|
|
1483
1539
|
<aside class="public-faq-sidebar">
|
|
1484
1540
|
<public-faq-toc />
|
|
@@ -1514,9 +1570,9 @@ class PublicFaqIndex {
|
|
|
1514
1570
|
}
|
|
1515
1571
|
</article>
|
|
1516
1572
|
</div>
|
|
1517
|
-
`, isInline: true, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-index{max-width:860px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.55}header h1{font-size:2.25rem;margin:0 0 .5rem}.lead{color:#9aa3b3;margin:0 0 2rem;font-size:1.1rem}h2{font-size:1.35rem;margin:1.75rem 0 .5rem;border-bottom:1px solid rgba(255,255,255,.08);padding-bottom:.25rem}ul{list-style:none;padding:0;margin:0}li{padding:.4rem 0}.public-faq-index a{color:#6ea8fe;text-decoration:none;font-weight:500}.public-faq-index a:hover{text-decoration:underline}.desc{color:#8a93a3;font-weight:400}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: PublicFaqToc, selector: "public-faq-toc", inputs: ["activeFile"] }] }); }
|
|
1573
|
+
`, isInline: true, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-index{max-width:860px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.55}header h1{font-size:2.25rem;margin:0 0 .5rem}.lead{color:#9aa3b3;margin:0 0 2rem;font-size:1.1rem}h2{font-size:1.35rem;margin:1.75rem 0 .5rem;border-bottom:1px solid rgba(255,255,255,.08);padding-bottom:.25rem}ul{list-style:none;padding:0;margin:0}li{padding:.4rem 0}.public-faq-index a{color:#6ea8fe;text-decoration:none;font-weight:500}.public-faq-index a:hover{text-decoration:underline}.desc{color:#8a93a3;font-weight:400}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: PublicFaqToc, selector: "public-faq-toc", inputs: ["activeFile"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1518
1574
|
}
|
|
1519
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1575
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PublicFaqIndex, decorators: [{
|
|
1520
1576
|
type: Component,
|
|
1521
1577
|
args: [{ selector: 'public-faq-index', standalone: true, imports: [CommonModule, RouterLink, PublicFaqToc], template: `
|
|
1522
1578
|
<div class="public-faq-layout">
|
|
@@ -1554,7 +1610,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1554
1610
|
}
|
|
1555
1611
|
</article>
|
|
1556
1612
|
</div>
|
|
1557
|
-
`, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-index{max-width:860px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.55}header h1{font-size:2.25rem;margin:0 0 .5rem}.lead{color:#9aa3b3;margin:0 0 2rem;font-size:1.1rem}h2{font-size:1.35rem;margin:1.75rem 0 .5rem;border-bottom:1px solid rgba(255,255,255,.08);padding-bottom:.25rem}ul{list-style:none;padding:0;margin:0}li{padding:.4rem 0}.public-faq-index a{color:#6ea8fe;text-decoration:none;font-weight:500}.public-faq-index a:hover{text-decoration:underline}.desc{color:#8a93a3;font-weight:400}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"] }]
|
|
1613
|
+
`, changeDetection: ChangeDetectionStrategy.Eager, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-index{max-width:860px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.55}header h1{font-size:2.25rem;margin:0 0 .5rem}.lead{color:#9aa3b3;margin:0 0 2rem;font-size:1.1rem}h2{font-size:1.35rem;margin:1.75rem 0 .5rem;border-bottom:1px solid rgba(255,255,255,.08);padding-bottom:.25rem}ul{list-style:none;padding:0;margin:0}li{padding:.4rem 0}.public-faq-index a{color:#6ea8fe;text-decoration:none;font-weight:500}.public-faq-index a:hover{text-decoration:underline}.desc{color:#8a93a3;font-weight:400}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"] }]
|
|
1558
1614
|
}] });
|
|
1559
1615
|
function serializeJsonLd$1(obj) {
|
|
1560
1616
|
return JSON.stringify(obj).replace(/</g, '\\u003c');
|
|
@@ -1583,10 +1639,14 @@ class PublicFaqPage {
|
|
|
1583
1639
|
this.meta = inject(Meta);
|
|
1584
1640
|
this.siteBase = inject(FAQ_PUBLIC_SITE_BASE_URL);
|
|
1585
1641
|
this.publisher = inject(FAQ_PUBLIC_PUBLISHER);
|
|
1586
|
-
this.entry = signal(null,
|
|
1587
|
-
|
|
1588
|
-
this.
|
|
1589
|
-
|
|
1642
|
+
this.entry = signal(null, /* @ts-ignore */
|
|
1643
|
+
...(ngDevMode ? [{ debugName: "entry" }] : /* istanbul ignore next */ []));
|
|
1644
|
+
this.body = signal('', /* @ts-ignore */
|
|
1645
|
+
...(ngDevMode ? [{ debugName: "body" }] : /* istanbul ignore next */ []));
|
|
1646
|
+
this.loading = signal(true, /* @ts-ignore */
|
|
1647
|
+
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1648
|
+
this.activeFile = computed(() => this.entry()?.file, /* @ts-ignore */
|
|
1649
|
+
...(ngDevMode ? [{ debugName: "activeFile" }] : /* istanbul ignore next */ []));
|
|
1590
1650
|
this.renderedHtml = computed(() => {
|
|
1591
1651
|
const entry = this.entry();
|
|
1592
1652
|
const body = this.body();
|
|
@@ -1598,7 +1658,8 @@ class PublicFaqPage {
|
|
|
1598
1658
|
? `/assets/faq/${entry.imagePrefix}`
|
|
1599
1659
|
: undefined,
|
|
1600
1660
|
});
|
|
1601
|
-
},
|
|
1661
|
+
}, /* @ts-ignore */
|
|
1662
|
+
...(ngDevMode ? [{ debugName: "renderedHtml" }] : /* istanbul ignore next */ []));
|
|
1602
1663
|
this.jsonLd = computed(() => {
|
|
1603
1664
|
const entry = this.entry();
|
|
1604
1665
|
if (!entry)
|
|
@@ -1626,7 +1687,8 @@ class PublicFaqPage {
|
|
|
1626
1687
|
ld['author'] = pub;
|
|
1627
1688
|
}
|
|
1628
1689
|
return serializeJsonLd(ld);
|
|
1629
|
-
},
|
|
1690
|
+
}, /* @ts-ignore */
|
|
1691
|
+
...(ngDevMode ? [{ debugName: "jsonLd" }] : /* istanbul ignore next */ []));
|
|
1630
1692
|
}
|
|
1631
1693
|
async ngOnInit() {
|
|
1632
1694
|
try {
|
|
@@ -1681,8 +1743,8 @@ class PublicFaqPage {
|
|
|
1681
1743
|
const base = this.siteBase.replace(/\/+$/, '');
|
|
1682
1744
|
return `${base}/help/${entry.file}`;
|
|
1683
1745
|
}
|
|
1684
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1685
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1746
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PublicFaqPage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1747
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: PublicFaqPage, isStandalone: true, selector: "public-faq-page", ngImport: i0, template: `
|
|
1686
1748
|
<div class="public-faq-layout">
|
|
1687
1749
|
<aside class="public-faq-sidebar">
|
|
1688
1750
|
<public-faq-toc [activeFile]="activeFile()" />
|
|
@@ -1709,9 +1771,9 @@ class PublicFaqPage {
|
|
|
1709
1771
|
}
|
|
1710
1772
|
</article>
|
|
1711
1773
|
</div>
|
|
1712
|
-
`, isInline: true, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-page{font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.6;max-width:860px}header h1{font-size:2.1rem;margin:0 0 .5rem}.lead{color:#9aa3b3;font-size:1.1rem;margin:0 0 1.5rem}.body :is(h1,h2,h3,h4){margin-top:2rem}.body a{color:#6ea8fe}.body img{max-width:100%;height:auto}.body pre{background:#00000059;padding:.75rem 1rem;border-radius:6px;overflow-x:auto}.body code{background:#ffffff14;padding:.1rem .3rem;border-radius:3px;font-size:.9em}.body pre code{background:transparent;padding:0}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: PublicFaqToc, selector: "public-faq-toc", inputs: ["activeFile"] }] }); }
|
|
1774
|
+
`, isInline: true, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-page{font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.6;max-width:860px}header h1{font-size:2.1rem;margin:0 0 .5rem}.lead{color:#9aa3b3;font-size:1.1rem;margin:0 0 1.5rem}.body :is(h1,h2,h3,h4){margin-top:2rem}.body a{color:#6ea8fe}.body img{max-width:100%;height:auto}.body pre{background:#00000059;padding:.75rem 1rem;border-radius:6px;overflow-x:auto}.body code{background:#ffffff14;padding:.1rem .3rem;border-radius:3px;font-size:.9em}.body pre code{background:transparent;padding:0}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: PublicFaqToc, selector: "public-faq-toc", inputs: ["activeFile"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1713
1775
|
}
|
|
1714
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1776
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PublicFaqPage, decorators: [{
|
|
1715
1777
|
type: Component,
|
|
1716
1778
|
args: [{ selector: 'public-faq-page', standalone: true, imports: [CommonModule, RouterLink, PublicFaqToc], template: `
|
|
1717
1779
|
<div class="public-faq-layout">
|
|
@@ -1740,7 +1802,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1740
1802
|
}
|
|
1741
1803
|
</article>
|
|
1742
1804
|
</div>
|
|
1743
|
-
`, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-page{font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.6;max-width:860px}header h1{font-size:2.1rem;margin:0 0 .5rem}.lead{color:#9aa3b3;font-size:1.1rem;margin:0 0 1.5rem}.body :is(h1,h2,h3,h4){margin-top:2rem}.body a{color:#6ea8fe}.body img{max-width:100%;height:auto}.body pre{background:#00000059;padding:.75rem 1rem;border-radius:6px;overflow-x:auto}.body code{background:#ffffff14;padding:.1rem .3rem;border-radius:3px;font-size:.9em}.body pre code{background:transparent;padding:0}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"] }]
|
|
1805
|
+
`, changeDetection: ChangeDetectionStrategy.Eager, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-page{font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.6;max-width:860px}header h1{font-size:2.1rem;margin:0 0 .5rem}.lead{color:#9aa3b3;font-size:1.1rem;margin:0 0 1.5rem}.body :is(h1,h2,h3,h4){margin-top:2rem}.body a{color:#6ea8fe}.body img{max-width:100%;height:auto}.body pre{background:#00000059;padding:.75rem 1rem;border-radius:6px;overflow-x:auto}.body code{background:#ffffff14;padding:.1rem .3rem;border-radius:3px;font-size:.9em}.body pre code{background:transparent;padding:0}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"] }]
|
|
1744
1806
|
}] });
|
|
1745
1807
|
/**
|
|
1746
1808
|
* Serializes a JSON-LD object for safe inclusion in a
|
|
@@ -1755,28 +1817,31 @@ function serializeJsonLd(obj) {
|
|
|
1755
1817
|
|
|
1756
1818
|
class ThemeService {
|
|
1757
1819
|
constructor() {
|
|
1758
|
-
this.mode = signal('dark',
|
|
1759
|
-
|
|
1820
|
+
this.mode = signal('dark', /* @ts-ignore */
|
|
1821
|
+
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
1822
|
+
this.isDark = computed(() => this.mode() === 'dark', /* @ts-ignore */
|
|
1823
|
+
...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
|
|
1760
1824
|
}
|
|
1761
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1762
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1825
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1826
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
|
|
1763
1827
|
}
|
|
1764
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1828
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ThemeService, decorators: [{
|
|
1765
1829
|
type: Injectable,
|
|
1766
1830
|
args: [{ providedIn: 'root' }]
|
|
1767
1831
|
}] });
|
|
1768
1832
|
|
|
1769
1833
|
class TerminalFocusService {
|
|
1770
1834
|
constructor() {
|
|
1771
|
-
this.focusRequested = signal(0,
|
|
1835
|
+
this.focusRequested = signal(0, /* @ts-ignore */
|
|
1836
|
+
...(ngDevMode ? [{ debugName: "focusRequested" }] : /* istanbul ignore next */ []));
|
|
1772
1837
|
}
|
|
1773
1838
|
requestFocus() {
|
|
1774
1839
|
this.focusRequested.update(v => v + 1);
|
|
1775
1840
|
}
|
|
1776
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1777
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1841
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: TerminalFocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1842
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: TerminalFocusService, providedIn: 'root' }); }
|
|
1778
1843
|
}
|
|
1779
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1844
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: TerminalFocusService, decorators: [{
|
|
1780
1845
|
type: Injectable,
|
|
1781
1846
|
args: [{ providedIn: 'root' }]
|
|
1782
1847
|
}] });
|
|
@@ -1789,11 +1854,13 @@ class KeyboardShortcutService {
|
|
|
1789
1854
|
#focusService;
|
|
1790
1855
|
constructor() {
|
|
1791
1856
|
this.#groups = new Map();
|
|
1792
|
-
this.#activeGroupId = signal(null,
|
|
1857
|
+
this.#activeGroupId = signal(null, /* @ts-ignore */
|
|
1858
|
+
...(ngDevMode ? [{ debugName: "#activeGroupId" }] : /* istanbul ignore next */ []));
|
|
1793
1859
|
this.#document = inject(DOCUMENT);
|
|
1794
1860
|
this.#zone = inject(NgZone);
|
|
1795
1861
|
this.#focusService = inject(TerminalFocusService);
|
|
1796
|
-
this.helpVisible = signal(false,
|
|
1862
|
+
this.helpVisible = signal(false, /* @ts-ignore */
|
|
1863
|
+
...(ngDevMode ? [{ debugName: "helpVisible" }] : /* istanbul ignore next */ []));
|
|
1797
1864
|
this.activeShortcuts = computed(() => {
|
|
1798
1865
|
const groupId = this.#activeGroupId();
|
|
1799
1866
|
if (!groupId)
|
|
@@ -1802,7 +1869,8 @@ class KeyboardShortcutService {
|
|
|
1802
1869
|
if (!shortcuts)
|
|
1803
1870
|
return null;
|
|
1804
1871
|
return { groupId, shortcuts };
|
|
1805
|
-
},
|
|
1872
|
+
}, /* @ts-ignore */
|
|
1873
|
+
...(ngDevMode ? [{ debugName: "activeShortcuts" }] : /* istanbul ignore next */ []));
|
|
1806
1874
|
this.#zone.runOutsideAngular(() => {
|
|
1807
1875
|
this.#document.addEventListener('keydown', (event) => {
|
|
1808
1876
|
this.#handleKeydown(event);
|
|
@@ -1857,10 +1925,10 @@ class KeyboardShortcutService {
|
|
|
1857
1925
|
}
|
|
1858
1926
|
return false;
|
|
1859
1927
|
}
|
|
1860
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1861
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1928
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: KeyboardShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1929
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: KeyboardShortcutService, providedIn: 'root' }); }
|
|
1862
1930
|
}
|
|
1863
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1931
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: KeyboardShortcutService, decorators: [{
|
|
1864
1932
|
type: Injectable,
|
|
1865
1933
|
args: [{ providedIn: 'root' }]
|
|
1866
1934
|
}], ctorParameters: () => [] });
|
|
@@ -1912,10 +1980,10 @@ class FaqCommand {
|
|
|
1912
1980
|
void this.faqService.openModal(args[0]);
|
|
1913
1981
|
return { success: true, message: '', timestamp: ts() };
|
|
1914
1982
|
}
|
|
1915
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1916
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1983
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1984
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqCommand, providedIn: 'root' }); }
|
|
1917
1985
|
}
|
|
1918
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1986
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: FaqCommand, decorators: [{
|
|
1919
1987
|
type: Injectable,
|
|
1920
1988
|
args: [{ providedIn: 'root' }]
|
|
1921
1989
|
}] });
|
|
@@ -1957,10 +2025,10 @@ class CommandRegistryService {
|
|
|
1957
2025
|
.filter(name => name.startsWith(prefix) && name !== prefix)
|
|
1958
2026
|
.sort();
|
|
1959
2027
|
}
|
|
1960
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1961
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2028
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2029
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandRegistryService, providedIn: 'root' }); }
|
|
1962
2030
|
}
|
|
1963
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2031
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandRegistryService, decorators: [{
|
|
1964
2032
|
type: Injectable,
|
|
1965
2033
|
args: [{ providedIn: 'root' }]
|
|
1966
2034
|
}], ctorParameters: () => [] });
|
|
@@ -1983,16 +2051,21 @@ const HELP_USAGE = 'help [command]\n\n' +
|
|
|
1983
2051
|
const CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');
|
|
1984
2052
|
class CommandService {
|
|
1985
2053
|
constructor() {
|
|
1986
|
-
this.history = signal([],
|
|
1987
|
-
|
|
1988
|
-
this.
|
|
1989
|
-
|
|
2054
|
+
this.history = signal([], /* @ts-ignore */
|
|
2055
|
+
...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
|
|
2056
|
+
this.currentInput = signal('', /* @ts-ignore */
|
|
2057
|
+
...(ngDevMode ? [{ debugName: "currentInput" }] : /* istanbul ignore next */ []));
|
|
2058
|
+
this.isProcessing = signal(false, /* @ts-ignore */
|
|
2059
|
+
...(ngDevMode ? [{ debugName: "isProcessing" }] : /* istanbul ignore next */ []));
|
|
2060
|
+
this.helpOverlay = signal(null, /* @ts-ignore */
|
|
2061
|
+
...(ngDevMode ? [{ debugName: "helpOverlay" }] : /* istanbul ignore next */ []));
|
|
1990
2062
|
this.authService = inject(AuthenticationService);
|
|
1991
2063
|
this.registry = inject(CommandRegistryService);
|
|
1992
2064
|
this.lastResult = computed(() => {
|
|
1993
2065
|
const h = this.history();
|
|
1994
2066
|
return h.length > 0 ? h[h.length - 1].result : null;
|
|
1995
|
-
},
|
|
2067
|
+
}, /* @ts-ignore */
|
|
2068
|
+
...(ngDevMode ? [{ debugName: "lastResult" }] : /* istanbul ignore next */ []));
|
|
1996
2069
|
effect(() => {
|
|
1997
2070
|
if (!this.authService.authenticated()) {
|
|
1998
2071
|
this.history.set([]);
|
|
@@ -2158,10 +2231,10 @@ class CommandService {
|
|
|
2158
2231
|
return { success: false, message: `Unknown command: ${name}`, timestamp: new Date() };
|
|
2159
2232
|
return { success: true, message: def.usage, timestamp: new Date(), isHelp: true };
|
|
2160
2233
|
}
|
|
2161
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2162
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2234
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2235
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandService, providedIn: 'root' }); }
|
|
2163
2236
|
}
|
|
2164
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2237
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandService, decorators: [{
|
|
2165
2238
|
type: Injectable,
|
|
2166
2239
|
args: [{ providedIn: 'root' }]
|
|
2167
2240
|
}], ctorParameters: () => [] });
|
|
@@ -2176,7 +2249,8 @@ class StatusBar {
|
|
|
2176
2249
|
? 'Authenticating...'
|
|
2177
2250
|
: this.#authService.authenticated()
|
|
2178
2251
|
? 'Logged in'
|
|
2179
|
-
: 'Not logged in',
|
|
2252
|
+
: 'Not logged in', /* @ts-ignore */
|
|
2253
|
+
...(ngDevMode ? [{ debugName: "loginStatus" }] : /* istanbul ignore next */ []));
|
|
2180
2254
|
}
|
|
2181
2255
|
#authService;
|
|
2182
2256
|
#focusService;
|
|
@@ -2190,12 +2264,12 @@ class StatusBar {
|
|
|
2190
2264
|
this.#commandService.execute('faq');
|
|
2191
2265
|
this.#focusService.requestFocus();
|
|
2192
2266
|
}
|
|
2193
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2194
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2267
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: StatusBar, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2268
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: StatusBar, isStandalone: true, selector: "shell-status-bar", ngImport: i0, template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}.faq-button{margin-left:auto;background:none;border:1px solid var(--color-surface-border);border-radius:50%;width:22px;height:22px;font-size:.85rem;font-weight:600;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0}.faq-button:hover{opacity:.8}\n"], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2195
2269
|
}
|
|
2196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2270
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: StatusBar, decorators: [{
|
|
2197
2271
|
type: Component,
|
|
2198
|
-
args: [{ selector: 'shell-status-bar', template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}.faq-button{margin-left:auto;background:none;border:1px solid var(--color-surface-border);border-radius:50%;width:22px;height:22px;font-size:.85rem;font-weight:600;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0}.faq-button:hover{opacity:.8}\n"] }]
|
|
2272
|
+
args: [{ selector: 'shell-status-bar', changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}.faq-button{margin-left:auto;background:none;border:1px solid var(--color-surface-border);border-radius:50%;width:22px;height:22px;font-size:.85rem;font-weight:600;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0}.faq-button:hover{opacity:.8}\n"] }]
|
|
2199
2273
|
}] });
|
|
2200
2274
|
|
|
2201
2275
|
class SideMenu {
|
|
@@ -2205,7 +2279,8 @@ class SideMenu {
|
|
|
2205
2279
|
this.#shortcutService = inject(KeyboardShortcutService);
|
|
2206
2280
|
this.hasShortcuts = this.#shortcutService.activeShortcuts;
|
|
2207
2281
|
this.#allMenuItems = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];
|
|
2208
|
-
this.menuItems = computed(() => this.#allMenuItems.filter(item => !item.visible || item.visible()),
|
|
2282
|
+
this.menuItems = computed(() => this.#allMenuItems.filter(item => !item.visible || item.visible()), /* @ts-ignore */
|
|
2283
|
+
...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
2209
2284
|
}
|
|
2210
2285
|
#focusService;
|
|
2211
2286
|
#commandService;
|
|
@@ -2220,12 +2295,12 @@ class SideMenu {
|
|
|
2220
2295
|
toggleHelp() {
|
|
2221
2296
|
this.#shortcutService.toggleHelp();
|
|
2222
2297
|
}
|
|
2223
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2224
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2298
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SideMenu, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2299
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: SideMenu, isStandalone: true, selector: "shell-side-menu", ngImport: i0, template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-item.active,.menu-item.active:hover{background-color:var(--color-interactive, #00e5ff);color:var(--color-surface-dark, #0d1117)}.menu-spacer{flex:1}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2225
2300
|
}
|
|
2226
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2301
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SideMenu, decorators: [{
|
|
2227
2302
|
type: Component,
|
|
2228
|
-
args: [{ selector: 'shell-side-menu', imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule], template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-item.active,.menu-item.active:hover{background-color:var(--color-interactive, #00e5ff);color:var(--color-surface-dark, #0d1117)}.menu-spacer{flex:1}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"] }]
|
|
2303
|
+
args: [{ selector: 'shell-side-menu', imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n }\n <div class=\"menu-spacer\"></div>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-item.active,.menu-item.active:hover{background-color:var(--color-interactive, #00e5ff);color:var(--color-surface-dark, #0d1117)}.menu-spacer{flex:1}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"] }]
|
|
2229
2304
|
}] });
|
|
2230
2305
|
|
|
2231
2306
|
class MainContent {
|
|
@@ -2248,12 +2323,12 @@ class MainContent {
|
|
|
2248
2323
|
closeShortcutHelp() {
|
|
2249
2324
|
this.#shortcutService.helpVisible.set(false);
|
|
2250
2325
|
}
|
|
2251
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2252
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2326
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: MainContent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2327
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: MainContent, isStandalone: true, selector: "shell-main-content", ngImport: i0, template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2253
2328
|
}
|
|
2254
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2329
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: MainContent, decorators: [{
|
|
2255
2330
|
type: Component,
|
|
2256
|
-
args: [{ selector: 'shell-main-content', imports: [RouterOutlet, MatProgressSpinnerModule], template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"] }]
|
|
2331
|
+
args: [{ selector: 'shell-main-content', imports: [RouterOutlet, MatProgressSpinnerModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"] }]
|
|
2257
2332
|
}] });
|
|
2258
2333
|
|
|
2259
2334
|
class CommandTerminal {
|
|
@@ -2262,10 +2337,12 @@ class CommandTerminal {
|
|
|
2262
2337
|
this.registry = inject(CommandRegistryService);
|
|
2263
2338
|
this.authService = inject(AuthenticationService);
|
|
2264
2339
|
this.terminalFocusService = inject(TerminalFocusService);
|
|
2265
|
-
this.history = computed(() => [...this.commandService.history()].reverse(),
|
|
2340
|
+
this.history = computed(() => [...this.commandService.history()].reverse(), /* @ts-ignore */
|
|
2341
|
+
...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
|
|
2266
2342
|
this.currentInput = this.commandService.currentInput;
|
|
2267
2343
|
this.isProcessing = this.commandService.isProcessing;
|
|
2268
|
-
this.inputEl = viewChild('terminalInput',
|
|
2344
|
+
this.inputEl = viewChild('terminalInput', /* @ts-ignore */
|
|
2345
|
+
...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
|
|
2269
2346
|
this.tabCycleIndex = -1;
|
|
2270
2347
|
this.lastTabPrefix = '';
|
|
2271
2348
|
this.ghostText = computed(() => {
|
|
@@ -2275,7 +2352,8 @@ class CommandTerminal {
|
|
|
2275
2352
|
const prefix = input.toLowerCase();
|
|
2276
2353
|
const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());
|
|
2277
2354
|
return suggestions.length > 0 ? suggestions[0] : '';
|
|
2278
|
-
},
|
|
2355
|
+
}, /* @ts-ignore */
|
|
2356
|
+
...(ngDevMode ? [{ debugName: "ghostText" }] : /* istanbul ignore next */ []));
|
|
2279
2357
|
afterNextRender(() => this.focusInput());
|
|
2280
2358
|
effect(() => {
|
|
2281
2359
|
if (!this.isProcessing()) {
|
|
@@ -2346,12 +2424,12 @@ class CommandTerminal {
|
|
|
2346
2424
|
focusInput() {
|
|
2347
2425
|
this.inputEl()?.nativeElement.focus();
|
|
2348
2426
|
}
|
|
2349
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2350
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2427
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandTerminal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2428
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: CommandTerminal, isStandalone: true, selector: "shell-command-terminal", viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["terminalInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"dismissHelp()\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2351
2429
|
}
|
|
2352
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2430
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CommandTerminal, decorators: [{
|
|
2353
2431
|
type: Component,
|
|
2354
|
-
args: [{ selector: 'shell-command-terminal', imports: [FormsModule], template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"dismissHelp()\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"] }]
|
|
2432
|
+
args: [{ selector: 'shell-command-terminal', imports: [FormsModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"dismissHelp()\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"] }]
|
|
2355
2433
|
}], ctorParameters: () => [], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['terminalInput', { isSignal: true }] }] } });
|
|
2356
2434
|
|
|
2357
2435
|
const MIN_TERMINAL_HEIGHT = 80;
|
|
@@ -2365,8 +2443,10 @@ class Shell {
|
|
|
2365
2443
|
this.isThinking = this.#thinkingService.isThinking;
|
|
2366
2444
|
this.isAuthenticated = this.#authService.authenticated;
|
|
2367
2445
|
this.helpOverlay = this.#commandService.helpOverlay;
|
|
2368
|
-
this.terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`,
|
|
2369
|
-
|
|
2446
|
+
this.terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`, /* @ts-ignore */
|
|
2447
|
+
...(ngDevMode ? [{ debugName: "terminalHeight" }] : /* istanbul ignore next */ []));
|
|
2448
|
+
this.isDragging = signal(false, /* @ts-ignore */
|
|
2449
|
+
...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
|
|
2370
2450
|
this.#startY = 0;
|
|
2371
2451
|
this.#startHeight = DEFAULT_TERMINAL_HEIGHT;
|
|
2372
2452
|
this.#onMouseMove = (event) => {
|
|
@@ -2399,12 +2479,12 @@ class Shell {
|
|
|
2399
2479
|
document.addEventListener('mousemove', this.#onMouseMove);
|
|
2400
2480
|
document.addEventListener('mouseup', this.#onMouseUp);
|
|
2401
2481
|
}
|
|
2402
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2403
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2482
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: Shell, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2483
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: Shell, isStandalone: true, selector: "shell-root", ngImport: i0, template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">\u2715</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words \u2014 e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".shell{position:relative;display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-main.full-width{grid-column:1 / -1}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}.help-backdrop{position:absolute;inset:0;z-index:100;background-color:#000000a6;display:flex;align-items:center;justify-content:center}.help-panel{background-color:var(--color-surface, #161b22);border:2px solid var(--color-interactive, #00e5ff);border-radius:4px;width:70%;max-width:820px;max-height:75vh;display:flex;flex-direction:column;font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.help-panel-header{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:var(--color-surface-light, #21262d);border-bottom:1px solid var(--color-interactive, #00e5ff);border-radius:2px 2px 0 0;flex-shrink:0}.help-panel-title{color:var(--color-interactive, #00e5ff);font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-size:.75rem}.help-panel-close{background:none;border:1px solid var(--color-surface-border, #30363d);color:var(--color-secondary-info, #9e9e9e);cursor:pointer;padding:2px 8px;font-size:.9rem;line-height:1.4;border-radius:3px;transition:color .15s ease,border-color .15s ease}.help-panel-close:hover{color:var(--color-text-primary, #ffffff);border-color:var(--color-interactive, #00e5ff)}.help-panel-content{flex:1;overflow-y:auto;padding:16px 20px;color:var(--color-text-primary, #ffffff);white-space:pre-wrap;line-height:1.7}.help-panel-footer{padding:6px 16px;background-color:var(--color-surface-light, #21262d);border-top:1px solid var(--color-surface-border, #30363d);border-radius:0 0 2px 2px;color:var(--color-secondary-info, #9e9e9e);font-size:.75rem;flex-shrink:0;display:flex;flex-direction:column;gap:2px}.help-panel-footer-dismiss{opacity:.6}\n"], dependencies: [{ kind: "component", type: StatusBar, selector: "shell-status-bar" }, { kind: "component", type: SideMenu, selector: "shell-side-menu" }, { kind: "component", type: MainContent, selector: "shell-main-content" }, { kind: "component", type: CommandTerminal, selector: "shell-command-terminal" }, { kind: "component", type: FaqModal, selector: "faq-modal" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2404
2484
|
}
|
|
2405
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2485
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: Shell, decorators: [{
|
|
2406
2486
|
type: Component,
|
|
2407
|
-
args: [{ selector: 'shell-root', imports: [StatusBar, SideMenu, MainContent, CommandTerminal, FaqModal], template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">\u2715</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words \u2014 e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".shell{position:relative;display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-main.full-width{grid-column:1 / -1}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}.help-backdrop{position:absolute;inset:0;z-index:100;background-color:#000000a6;display:flex;align-items:center;justify-content:center}.help-panel{background-color:var(--color-surface, #161b22);border:2px solid var(--color-interactive, #00e5ff);border-radius:4px;width:70%;max-width:820px;max-height:75vh;display:flex;flex-direction:column;font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.help-panel-header{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:var(--color-surface-light, #21262d);border-bottom:1px solid var(--color-interactive, #00e5ff);border-radius:2px 2px 0 0;flex-shrink:0}.help-panel-title{color:var(--color-interactive, #00e5ff);font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-size:.75rem}.help-panel-close{background:none;border:1px solid var(--color-surface-border, #30363d);color:var(--color-secondary-info, #9e9e9e);cursor:pointer;padding:2px 8px;font-size:.9rem;line-height:1.4;border-radius:3px;transition:color .15s ease,border-color .15s ease}.help-panel-close:hover{color:var(--color-text-primary, #ffffff);border-color:var(--color-interactive, #00e5ff)}.help-panel-content{flex:1;overflow-y:auto;padding:16px 20px;color:var(--color-text-primary, #ffffff);white-space:pre-wrap;line-height:1.7}.help-panel-footer{padding:6px 16px;background-color:var(--color-surface-light, #21262d);border-top:1px solid var(--color-surface-border, #30363d);border-radius:0 0 2px 2px;color:var(--color-secondary-info, #9e9e9e);font-size:.75rem;flex-shrink:0;display:flex;flex-direction:column;gap:2px}.help-panel-footer-dismiss{opacity:.6}\n"] }]
|
|
2487
|
+
args: [{ selector: 'shell-root', imports: [StatusBar, SideMenu, MainContent, CommandTerminal, FaqModal], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">\u2715</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words \u2014 e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".shell{position:relative;display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-main.full-width{grid-column:1 / -1}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}.help-backdrop{position:absolute;inset:0;z-index:100;background-color:#000000a6;display:flex;align-items:center;justify-content:center}.help-panel{background-color:var(--color-surface, #161b22);border:2px solid var(--color-interactive, #00e5ff);border-radius:4px;width:70%;max-width:820px;max-height:75vh;display:flex;flex-direction:column;font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.help-panel-header{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:var(--color-surface-light, #21262d);border-bottom:1px solid var(--color-interactive, #00e5ff);border-radius:2px 2px 0 0;flex-shrink:0}.help-panel-title{color:var(--color-interactive, #00e5ff);font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-size:.75rem}.help-panel-close{background:none;border:1px solid var(--color-surface-border, #30363d);color:var(--color-secondary-info, #9e9e9e);cursor:pointer;padding:2px 8px;font-size:.9rem;line-height:1.4;border-radius:3px;transition:color .15s ease,border-color .15s ease}.help-panel-close:hover{color:var(--color-text-primary, #ffffff);border-color:var(--color-interactive, #00e5ff)}.help-panel-content{flex:1;overflow-y:auto;padding:16px 20px;color:var(--color-text-primary, #ffffff);white-space:pre-wrap;line-height:1.7}.help-panel-footer{padding:6px 16px;background-color:var(--color-surface-light, #21262d);border-top:1px solid var(--color-surface-border, #30363d);border-radius:0 0 2px 2px;color:var(--color-secondary-info, #9e9e9e);font-size:.75rem;flex-shrink:0;display:flex;flex-direction:column;gap:2px}.help-panel-footer-dismiss{opacity:.6}\n"] }]
|
|
2408
2488
|
}] });
|
|
2409
2489
|
|
|
2410
2490
|
class Login {
|
|
@@ -2417,8 +2497,10 @@ class Login {
|
|
|
2417
2497
|
this.router = router;
|
|
2418
2498
|
this.model = { username: '', password: '' };
|
|
2419
2499
|
this.submitted = false;
|
|
2420
|
-
this.hide = signal(true,
|
|
2421
|
-
|
|
2500
|
+
this.hide = signal(true, /* @ts-ignore */
|
|
2501
|
+
...(ngDevMode ? [{ debugName: "hide" }] : /* istanbul ignore next */ []));
|
|
2502
|
+
this.takeover = signal(true, /* @ts-ignore */
|
|
2503
|
+
...(ngDevMode ? [{ debugName: "takeover" }] : /* istanbul ignore next */ []));
|
|
2422
2504
|
this.errors = [];
|
|
2423
2505
|
this.USERNAME_REGEX = USERNAME_REGEX;
|
|
2424
2506
|
this.PASSWORD_REGEX = PASSWORD_REGEX;
|
|
@@ -2499,12 +2581,12 @@ class Login {
|
|
|
2499
2581
|
this.submitted = false;
|
|
2500
2582
|
});
|
|
2501
2583
|
}
|
|
2502
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2503
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2584
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: Login, deps: [{ token: AuthenticationService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2585
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: Login, isStandalone: true, selector: "shell-login", ngImport: i0, template: "@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox\n class=\"login-takeover\"\n name=\"takeover\"\n [checked]=\"takeover()\"\n (change)=\"takeover.set($event.checked)\"\n [disabled]=\"submitted\"\n >\n Takeover session if logged in elsewhere\n </mat-checkbox>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n", styles: [".login-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center}.login-header{margin-bottom:32px}.login-header h2{font-size:1.5rem;font-weight:300;margin-bottom:8px}.login-form{display:flex;flex-direction:column;align-items:center;gap:8px;width:320px}.login-field{width:100%;text-align:left}.login-takeover{align-self:flex-start;margin-top:4px}.login-button{margin-top:8px;width:100%}.login-errors{margin-top:16px;max-width:320px}.login-conflict{margin-top:16px;max-width:320px;padding:12px 16px;border-radius:4px;background-color:var(--color-surface-light);font-size:.85rem;text-align:left}.login-conflict p{margin:0 0 8px}.login-conflict-actions{display:flex;gap:8px;margin-top:12px;justify-content:flex-end}.login-error{padding:8px 12px;margin-bottom:4px;font-size:.85rem;border-radius:4px;background-color:var(--color-surface-light)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.CdkAutofill, selector: "[cdkAutofill]", outputs: ["cdkAutofill"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RegexValidatorDirective, selector: "[regexValidator]", inputs: ["regex"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2504
2586
|
}
|
|
2505
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2587
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: Login, decorators: [{
|
|
2506
2588
|
type: Component,
|
|
2507
|
-
args: [{ selector: 'shell-login', imports: [
|
|
2589
|
+
args: [{ selector: 'shell-login', changeDetection: ChangeDetectionStrategy.Eager, imports: [
|
|
2508
2590
|
FormsModule,
|
|
2509
2591
|
MatFormField,
|
|
2510
2592
|
MatLabel,
|
|
@@ -2524,8 +2606,8 @@ class ConfirmDialog {
|
|
|
2524
2606
|
this.data = inject(MAT_DIALOG_DATA);
|
|
2525
2607
|
this.dialogRef = inject((MatDialogRef));
|
|
2526
2608
|
}
|
|
2527
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2528
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2609
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2610
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: ConfirmDialog, isStandalone: true, selector: "shell-confirm-dialog", ngImport: i0, template: `
|
|
2529
2611
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
|
2530
2612
|
<mat-dialog-content>
|
|
2531
2613
|
<p>{{ data.message }}</p>
|
|
@@ -2537,9 +2619,9 @@ class ConfirmDialog {
|
|
|
2537
2619
|
<button mat-button (click)="dialogRef.close(false)">{{ data.cancelLabel ?? 'Cancel' }}</button>
|
|
2538
2620
|
<button mat-flat-button color="warn" (click)="dialogRef.close(true)">{{ data.confirmLabel ?? 'Confirm' }}</button>
|
|
2539
2621
|
</mat-dialog-actions>
|
|
2540
|
-
`, isInline: true, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
|
|
2622
|
+
`, isInline: true, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2541
2623
|
}
|
|
2542
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2624
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ConfirmDialog, decorators: [{
|
|
2543
2625
|
type: Component,
|
|
2544
2626
|
args: [{ selector: 'shell-confirm-dialog', imports: [MatDialogModule, MatButtonModule], template: `
|
|
2545
2627
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
|
@@ -2553,7 +2635,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2553
2635
|
<button mat-button (click)="dialogRef.close(false)">{{ data.cancelLabel ?? 'Cancel' }}</button>
|
|
2554
2636
|
<button mat-flat-button color="warn" (click)="dialogRef.close(true)">{{ data.confirmLabel ?? 'Confirm' }}</button>
|
|
2555
2637
|
</mat-dialog-actions>
|
|
2556
|
-
`, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"] }]
|
|
2638
|
+
`, changeDetection: ChangeDetectionStrategy.Eager, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"] }]
|
|
2557
2639
|
}] });
|
|
2558
2640
|
|
|
2559
2641
|
/*
|